@vtex/faststore 0.0.6 → 0.0.8

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 (488) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/dist/actions.json +152 -1
  3. package/dist/catalog.json +2541 -1278
  4. package/dist/cli/UnreachableCaseError-Crd168Vu.js +10 -0
  5. package/dist/cli/UnreachableCaseError-Crd168Vu.js.map +1 -0
  6. package/dist/cli/cacheControl-CEojH_TM.js +158 -0
  7. package/dist/cli/cacheControl-CEojH_TM.js.map +1 -0
  8. package/dist/cli/cachePolicy-m2vASMRW.js +26 -0
  9. package/dist/cli/cachePolicy-m2vASMRW.js.map +1 -0
  10. package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js +10 -0
  11. package/dist/cli/computeCoreSchemaHash-DPJZj-qJ.js.map +1 -0
  12. package/dist/cli/default-BCQHcwbL.js +253 -0
  13. package/dist/cli/default-BCQHcwbL.js.map +1 -0
  14. package/dist/cli/disableSuggestions-yO9UqiWn.js +21 -0
  15. package/dist/cli/disableSuggestions-yO9UqiWn.js.map +1 -0
  16. package/dist/cli/dist-C1JhdHfo.js +2001 -0
  17. package/dist/cli/dist-C1JhdHfo.js.map +1 -0
  18. package/dist/cli/graphql-DG9thCDG.js +14589 -0
  19. package/dist/cli/graphql-DG9thCDG.js.map +1 -0
  20. package/dist/cli/index.d.ts +799 -0
  21. package/dist/cli/index.js +36459 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/cli/index.min-BsIHDfFK.js +613 -0
  24. package/dist/cli/index.min-BsIHDfFK.js.map +1 -0
  25. package/dist/cli/inlineTrace-uLgOJ3TH.js +52 -0
  26. package/dist/cli/inlineTrace-uLgOJ3TH.js.map +1 -0
  27. package/dist/cli/internalPlugin-DnuwN4_4.js +11 -0
  28. package/dist/cli/internalPlugin-DnuwN4_4.js.map +1 -0
  29. package/dist/cli/packageVersion-DQAnIEil.js +6 -0
  30. package/dist/cli/packageVersion-DQAnIEil.js.map +1 -0
  31. package/dist/cli/rolldown-runtime-BMI-E3GI.js +44 -0
  32. package/dist/cli/schemaIsSubgraph-DoGh3OYj.js +17 -0
  33. package/dist/cli/schemaIsSubgraph-DoGh3OYj.js.map +1 -0
  34. package/dist/cli/schemaReporting-K-me-3-v.js +199 -0
  35. package/dist/cli/schemaReporting-K-me-3-v.js.map +1 -0
  36. package/dist/cli/server-runtime.js +49879 -0
  37. package/dist/cli/server-runtime.js.map +1 -0
  38. package/dist/cli/traceTreeBuilder-BIcV2U7b.js +9118 -0
  39. package/dist/cli/traceTreeBuilder-BIcV2U7b.js.map +1 -0
  40. package/dist/cli/usageReporting-Bpl8vSZX.js +10201 -0
  41. package/dist/cli/usageReporting-Bpl8vSZX.js.map +1 -0
  42. package/dist/cli/v4-CBhFvC49.js +42 -0
  43. package/dist/cli/v4-CBhFvC49.js.map +1 -0
  44. package/dist/client.d.ts +5 -1
  45. package/dist/client.js +5 -1
  46. package/dist/components.d.ts +38 -9
  47. package/dist/components.js +42 -13
  48. package/dist/content-types.json +616 -0
  49. package/dist/core/dist/define-component.d.ts +43 -1
  50. package/dist/core/dist/index.d.ts +2 -2
  51. package/dist/docs/account-access-gate.md +4 -4
  52. package/dist/docs/account-address-book.md +519 -0
  53. package/dist/docs/account-entry-point.md +1 -1
  54. package/dist/docs/account-menu-identity.md +160 -0
  55. package/dist/docs/account-menu.md +107 -24
  56. package/dist/docs/alert-dialog.md +2 -2
  57. package/dist/docs/avatar.md +103 -0
  58. package/dist/docs/billing-address.md +17 -9
  59. package/dist/docs/card-entry.md +37 -6
  60. package/dist/docs/cardholder-document.md +16 -14
  61. package/dist/docs/cart-item.md +1 -1
  62. package/dist/docs/cart.md +8 -8
  63. package/dist/docs/client-profile-fieldset.md +7 -5
  64. package/dist/docs/copy-text.md +84 -0
  65. package/dist/docs/document-field.md +8 -8
  66. package/dist/docs/footer-link-group.md +2 -2
  67. package/dist/docs/header-root.md +1 -1
  68. package/dist/docs/incentives.md +2 -2
  69. package/dist/docs/logo.md +5 -5
  70. package/dist/docs/my-account-profile.md +5 -5
  71. package/dist/docs/navigation-link-list.md +2 -2
  72. package/dist/docs/navigation-link.md +3 -3
  73. package/dist/docs/order-cancel.md +52 -0
  74. package/dist/docs/order-delivery-address.md +63 -0
  75. package/dist/docs/order-delivery-group.md +83 -0
  76. package/dist/docs/order-details-back.md +41 -0
  77. package/dist/docs/order-details-header.md +48 -0
  78. package/dist/docs/order-list-row.md +46 -0
  79. package/dist/docs/order-list-search.md +101 -0
  80. package/dist/docs/order-list-views.md +97 -0
  81. package/dist/docs/order-list.md +94 -0
  82. package/dist/docs/order-payment.md +94 -0
  83. package/dist/docs/order-placed-date.md +49 -0
  84. package/dist/docs/order-placed-payment-summary.md +13 -15
  85. package/dist/docs/order-placed.md +225 -0
  86. package/dist/docs/order-progress.md +88 -0
  87. package/dist/docs/order-status-badge.md +91 -0
  88. package/dist/docs/order-summary.md +53 -0
  89. package/dist/docs/payment-method-badges.md +14 -3
  90. package/dist/docs/place-order.md +13 -9
  91. package/dist/docs/product-shelf.md +20 -13
  92. package/dist/docs/saved-cards.md +2 -2
  93. package/dist/docs/select.md +19 -6
  94. package/dist/docs/session.md +1 -1
  95. package/dist/docs/shipping-address.md +1 -1
  96. package/dist/docs/sign-in-redirect.md +6 -6
  97. package/dist/docs/toast.md +7 -3
  98. package/dist/index.d.ts +7 -3
  99. package/dist/index.js +2 -1
  100. package/dist/internal/client.d.ts +6 -1
  101. package/dist/internal/client.js +8 -3
  102. package/dist/internal/content.d.ts +2 -2
  103. package/dist/internal/server.d.ts +8 -1
  104. package/dist/internal/server.js +8 -1
  105. package/dist/matter/account-access-gate/account-access-gate.d.ts +2 -1
  106. package/dist/matter/account-access-gate/account-access-gate.js +19 -16
  107. package/dist/matter/account-access-gate/account-access-gate.js.map +1 -1
  108. package/dist/matter/account-address-book/account-address-book-delete.d.ts +60 -0
  109. package/dist/matter/account-address-book/account-address-book-delete.js +184 -0
  110. package/dist/matter/account-address-book/account-address-book-delete.js.map +1 -0
  111. package/dist/matter/account-address-book/account-address-book-deliverability.d.ts +19 -0
  112. package/dist/matter/account-address-book/account-address-book-deliverability.js +50 -0
  113. package/dist/matter/account-address-book/account-address-book-deliverability.js.map +1 -0
  114. package/dist/matter/account-address-book/account-address-book-form-parts.d.ts +42 -0
  115. package/dist/matter/account-address-book/account-address-book-form-parts.js +146 -0
  116. package/dist/matter/account-address-book/account-address-book-form-parts.js.map +1 -0
  117. package/dist/matter/account-address-book/account-address-book-profile-notice.d.ts +25 -0
  118. package/dist/matter/account-address-book/account-address-book-profile-notice.js +72 -0
  119. package/dist/matter/account-address-book/account-address-book-profile-notice.js.map +1 -0
  120. package/dist/matter/account-address-book/account-address-book.d.ts +120 -0
  121. package/dist/matter/account-address-book/account-address-book.js +469 -0
  122. package/dist/matter/account-address-book/account-address-book.js.map +1 -0
  123. package/dist/matter/account-address-book/account-address-country-switch.js +59 -0
  124. package/dist/matter/account-address-book/account-address-country-switch.js.map +1 -0
  125. package/dist/matter/account-address-book/account-address-country.d.ts +36 -0
  126. package/dist/matter/account-address-book/account-address-country.js +151 -0
  127. package/dist/matter/account-address-book/account-address-country.js.map +1 -0
  128. package/dist/matter/account-address-book/account-address-first-line.js +11 -0
  129. package/dist/matter/account-address-book/account-address-first-line.js.map +1 -0
  130. package/dist/matter/account-address-book/account-address-form-context.d.ts +55 -0
  131. package/dist/matter/account-address-book/account-address-form-context.js +14 -0
  132. package/dist/matter/account-address-book/account-address-form-context.js.map +1 -0
  133. package/dist/matter/account-address-book/account-address-form.d.ts +85 -0
  134. package/dist/matter/account-address-book/account-address-form.js +946 -0
  135. package/dist/matter/account-address-book/account-address-form.js.map +1 -0
  136. package/dist/matter/account-address-book/account-address-postal-autofill.js +189 -0
  137. package/dist/matter/account-address-book/account-address-postal-autofill.js.map +1 -0
  138. package/dist/matter/account-address-book/account-address-record.d.ts +26 -0
  139. package/dist/matter/account-address-book/account-address-record.js +138 -0
  140. package/dist/matter/account-address-book/account-address-record.js.map +1 -0
  141. package/dist/matter/account-entry-point/account-entry-point.js +11 -11
  142. package/dist/matter/account-entry-point/account-entry-point.js.map +1 -1
  143. package/dist/matter/account-menu/account-menu.d.ts +77 -3
  144. package/dist/matter/account-menu/account-menu.js +252 -19
  145. package/dist/matter/account-menu/account-menu.js.map +1 -1
  146. package/dist/matter/account-menu/sign-out-failure.js +50 -0
  147. package/dist/matter/account-menu/sign-out-failure.js.map +1 -0
  148. package/dist/matter/account-menu-identity/account-menu-identity.d.ts +21 -0
  149. package/dist/matter/account-menu-identity/account-menu-identity.js +88 -0
  150. package/dist/matter/account-menu-identity/account-menu-identity.js.map +1 -0
  151. package/dist/matter/billing-address/billing-address.d.ts +30 -17
  152. package/dist/matter/billing-address/billing-address.js +128 -33
  153. package/dist/matter/billing-address/billing-address.js.map +1 -1
  154. package/dist/matter/breadcrumb/breadcrumb.js +2 -2
  155. package/dist/matter/breadcrumb/breadcrumb.js.map +1 -1
  156. package/dist/matter/card-entry/card-capture.js +4 -3
  157. package/dist/matter/card-entry/card-capture.js.map +1 -1
  158. package/dist/matter/card-entry/card-entry.d.ts +5 -3
  159. package/dist/matter/card-entry/card-entry.js +78 -27
  160. package/dist/matter/card-entry/card-entry.js.map +1 -1
  161. package/dist/matter/cardholder-document/cardholder-document.d.ts +10 -9
  162. package/dist/matter/cardholder-document/cardholder-document.js +36 -16
  163. package/dist/matter/cardholder-document/cardholder-document.js.map +1 -1
  164. package/dist/matter/cart/cart.d.ts +7 -2
  165. package/dist/matter/cart/cart.js +29 -26
  166. package/dist/matter/cart/cart.js.map +1 -1
  167. package/dist/matter/cart-item/cart-item.js +2 -2
  168. package/dist/matter/cart-item/cart-item.js.map +1 -1
  169. package/dist/matter/client-preferences/client-preferences-fieldset.js +2 -2
  170. package/dist/matter/client-profile-form/client-profile-fieldset.js +9 -6
  171. package/dist/matter/client-profile-form/client-profile-fieldset.js.map +1 -1
  172. package/dist/matter/identity-edit/identity-edit.js +3 -3
  173. package/dist/matter/identity-edit/identity-edit.js.map +1 -1
  174. package/dist/matter/identity-summary/identity-summary.js +4 -3
  175. package/dist/matter/identity-summary/identity-summary.js.map +1 -1
  176. package/dist/matter/my-account-profile/my-account-profile.d.ts +6 -3
  177. package/dist/matter/my-account-profile/my-account-profile.js +6 -5
  178. package/dist/matter/my-account-profile/my-account-profile.js.map +1 -1
  179. package/dist/matter/order-cancel/order-cancel.d.ts +110 -0
  180. package/dist/matter/order-cancel/order-cancel.js +344 -0
  181. package/dist/matter/order-cancel/order-cancel.js.map +1 -0
  182. package/dist/matter/order-delivery-address/order-delivery-address.d.ts +73 -0
  183. package/dist/matter/order-delivery-address/order-delivery-address.js +172 -0
  184. package/dist/matter/order-delivery-address/order-delivery-address.js.map +1 -0
  185. package/dist/matter/order-delivery-group/order-delivery-group.d.ts +128 -0
  186. package/dist/matter/order-delivery-group/order-delivery-group.js +408 -0
  187. package/dist/matter/order-delivery-group/order-delivery-group.js.map +1 -0
  188. package/dist/matter/order-details-header/order-details-header.d.ts +104 -0
  189. package/dist/matter/order-details-header/order-details-header.js +190 -0
  190. package/dist/matter/order-details-header/order-details-header.js.map +1 -0
  191. package/dist/matter/order-list/customer-orders-filter.d.ts +12 -0
  192. package/dist/matter/order-list/customer-orders-filter.js +30 -0
  193. package/dist/matter/order-list/customer-orders-filter.js.map +1 -0
  194. package/dist/matter/order-list/order-list.d.ts +121 -0
  195. package/dist/matter/order-list/order-list.js +395 -0
  196. package/dist/matter/order-list/order-list.js.map +1 -0
  197. package/dist/matter/order-list-row/order-list-row.d.ts +44 -0
  198. package/dist/matter/order-list-row/order-list-row.js +127 -0
  199. package/dist/matter/order-list-row/order-list-row.js.map +1 -0
  200. package/dist/matter/order-list-search/order-list-search.d.ts +72 -0
  201. package/dist/matter/order-list-search/order-list-search.js +296 -0
  202. package/dist/matter/order-list-search/order-list-search.js.map +1 -0
  203. package/dist/matter/order-list-views/order-list-views.d.ts +65 -0
  204. package/dist/matter/order-list-views/order-list-views.js +154 -0
  205. package/dist/matter/order-list-views/order-list-views.js.map +1 -0
  206. package/dist/matter/order-payment/order-payment.d.ts +83 -0
  207. package/dist/matter/order-payment/order-payment.js +258 -0
  208. package/dist/matter/order-payment/order-payment.js.map +1 -0
  209. package/dist/matter/order-placed/order-placed-deliveries.d.ts +145 -0
  210. package/dist/matter/order-placed/order-placed-deliveries.js +380 -0
  211. package/dist/matter/order-placed/order-placed-deliveries.js.map +1 -0
  212. package/dist/matter/order-placed/order-placed.d.ts +122 -0
  213. package/dist/matter/order-placed/order-placed.js +452 -0
  214. package/dist/matter/order-placed/order-placed.js.map +1 -0
  215. package/dist/matter/order-placed-date/order-placed-date.d.ts +45 -0
  216. package/dist/matter/order-placed-date/order-placed-date.js +92 -0
  217. package/dist/matter/order-placed-date/order-placed-date.js.map +1 -0
  218. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.d.ts +5 -8
  219. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js +29 -81
  220. package/dist/matter/order-placed-payment-summary/order-placed-payment-summary.js.map +1 -1
  221. package/dist/matter/order-progress/order-progress.d.ts +85 -0
  222. package/dist/matter/order-progress/order-progress.js +203 -0
  223. package/dist/matter/order-progress/order-progress.js.map +1 -0
  224. package/dist/matter/order-summary/order-summary.d.ts +81 -0
  225. package/dist/matter/order-summary/order-summary.js +192 -0
  226. package/dist/matter/order-summary/order-summary.js.map +1 -0
  227. package/dist/matter/payment/cardholder-document-rule.d.ts +35 -0
  228. package/dist/matter/payment/cardholder-document-rule.js +35 -0
  229. package/dist/matter/payment/cardholder-document-rule.js.map +1 -0
  230. package/dist/matter/payment/payment-card-capture.js +38 -23
  231. package/dist/matter/payment/payment-card-capture.js.map +1 -1
  232. package/dist/matter/payment/payment-controller.js +12 -0
  233. package/dist/matter/payment/payment-controller.js.map +1 -1
  234. package/dist/matter/payment/payment-method-badges.js +4 -2
  235. package/dist/matter/payment/payment-method-badges.js.map +1 -1
  236. package/dist/matter/payment/payment.js +12 -0
  237. package/dist/matter/payment/payment.js.map +1 -1
  238. package/dist/matter/payment/use-payment-method-selection.d.ts +39 -0
  239. package/dist/matter/payment/use-payment-method-selection.js +30 -2
  240. package/dist/matter/payment/use-payment-method-selection.js.map +1 -1
  241. package/dist/matter/payment/use-payment-submit-gate.d.ts +16 -2
  242. package/dist/matter/payment/use-payment-submit-gate.js +42 -14
  243. package/dist/matter/payment/use-payment-submit-gate.js.map +1 -1
  244. package/dist/matter/place-order/place-order.d.ts +12 -7
  245. package/dist/matter/place-order/place-order.js +126 -103
  246. package/dist/matter/place-order/place-order.js.map +1 -1
  247. package/dist/matter/pricing/pricing.js +5 -5
  248. package/dist/matter/pricing/pricing.js.map +1 -1
  249. package/dist/matter/product-shelf/product-shelf.d.ts +61 -31
  250. package/dist/matter/product-shelf/product-shelf.js +157 -57
  251. package/dist/matter/product-shelf/product-shelf.js.map +1 -1
  252. package/dist/matter/region/region.js +1 -1
  253. package/dist/matter/saved-cards/saved-cards.js +27 -15
  254. package/dist/matter/saved-cards/saved-cards.js.map +1 -1
  255. package/dist/matter/session/session.js +2 -2
  256. package/dist/matter/session/session.js.map +1 -1
  257. package/dist/matter/shipping-address/country-descriptors.d.ts +1 -0
  258. package/dist/matter/shipping-address/country-descriptors.js +23 -1
  259. package/dist/matter/shipping-address/country-descriptors.js.map +1 -1
  260. package/dist/matter/shipping-address/shipping-address.js +63 -15
  261. package/dist/matter/shipping-address/shipping-address.js.map +1 -1
  262. package/dist/matter/shipping-simulator/shipping-simulator.d.ts +1 -1
  263. package/dist/matter/shipping-simulator/shipping-simulator.js.map +1 -1
  264. package/dist/matter/sign-in-redirect/sign-in-redirect.js +48 -10
  265. package/dist/matter/sign-in-redirect/sign-in-redirect.js.map +1 -1
  266. package/dist/matter/variant-selector/variant-selector.js +2 -2
  267. package/dist/matter/variant-selector/variant-selector.js.map +1 -1
  268. package/dist/particles/address-summary/address-summary.js +2 -2
  269. package/dist/particles/address-summary/address-summary.js.map +1 -1
  270. package/dist/particles/alert-dialog/alert-dialog.d.ts +5 -1
  271. package/dist/particles/alert-dialog/alert-dialog.js +5 -2
  272. package/dist/particles/alert-dialog/alert-dialog.js.map +1 -1
  273. package/dist/particles/avatar/avatar.d.ts +17 -0
  274. package/dist/particles/avatar/avatar.js +65 -0
  275. package/dist/particles/avatar/avatar.js.map +1 -0
  276. package/dist/particles/copy-text/copy-text.d.ts +28 -0
  277. package/dist/particles/copy-text/copy-text.js +140 -0
  278. package/dist/particles/copy-text/copy-text.js.map +1 -0
  279. package/dist/particles/document-field/document-field.d.ts +34 -5
  280. package/dist/particles/document-field/document-field.js +115 -19
  281. package/dist/particles/document-field/document-field.js.map +1 -1
  282. package/dist/particles/field/field.js +1 -1
  283. package/dist/particles/field/field.js.map +1 -1
  284. package/dist/particles/footer-link-group/footer-link-group.d.ts +6 -2
  285. package/dist/particles/footer-link-group/footer-link-group.js +18 -7
  286. package/dist/particles/footer-link-group/footer-link-group.js.map +1 -1
  287. package/dist/particles/incentives/incentives.d.ts +6 -2
  288. package/dist/particles/incentives/incentives.js +7 -2
  289. package/dist/particles/incentives/incentives.js.map +1 -1
  290. package/dist/particles/logo/logo.d.ts +3 -2
  291. package/dist/particles/logo/logo.js +20 -8
  292. package/dist/particles/logo/logo.js.map +1 -1
  293. package/dist/particles/navigation-link/navigation-link.d.ts +2 -3
  294. package/dist/particles/navigation-link/navigation-link.js +4 -4
  295. package/dist/particles/navigation-link/navigation-link.js.map +1 -1
  296. package/dist/particles/navigation-link-list/navigation-link-list.d.ts +6 -2
  297. package/dist/particles/navigation-link-list/navigation-link-list.js +18 -7
  298. package/dist/particles/navigation-link-list/navigation-link-list.js.map +1 -1
  299. package/dist/particles/order-details-back/order-details-back.d.ts +28 -0
  300. package/dist/particles/order-details-back/order-details-back.js +52 -0
  301. package/dist/particles/order-details-back/order-details-back.js.map +1 -0
  302. package/dist/particles/order-status-badge/order-status-badge.d.ts +19 -0
  303. package/dist/particles/order-status-badge/order-status-badge.js +50 -0
  304. package/dist/particles/order-status-badge/order-status-badge.js.map +1 -0
  305. package/dist/particles/phone-field/phone-field.js +2 -2
  306. package/dist/particles/phone-field/phone-field.js.map +1 -1
  307. package/dist/particles/select/select.js +6 -6
  308. package/dist/particles/select/select.js.map +1 -1
  309. package/dist/particles/toast/toast.d.ts +1 -1
  310. package/dist/particles/toast/toast.js +32 -6
  311. package/dist/particles/toast/toast.js.map +1 -1
  312. package/dist/schema.graphql +1079 -54
  313. package/dist/sdk/actions/address-action-provider.d.ts +16 -0
  314. package/dist/sdk/actions/address-action-provider.js +20 -0
  315. package/dist/sdk/actions/address-action-provider.js.map +1 -0
  316. package/dist/sdk/actions/analytics-action-provider.js +1 -1
  317. package/dist/sdk/actions/index.d.ts +3 -1
  318. package/dist/sdk/actions/index.js +3 -1
  319. package/dist/sdk/actions/order-action-provider.d.ts +12 -0
  320. package/dist/sdk/actions/order-action-provider.js +16 -0
  321. package/dist/sdk/actions/order-action-provider.js.map +1 -0
  322. package/dist/sdk/actions/types.d.ts +6 -2
  323. package/dist/sdk/address/address-fields.js +38 -0
  324. package/dist/sdk/address/address-fields.js.map +1 -0
  325. package/dist/sdk/address/checkout-readiness.js +17 -0
  326. package/dist/sdk/address/checkout-readiness.js.map +1 -0
  327. package/dist/sdk/address/constants.js +60 -0
  328. package/dist/sdk/address/constants.js.map +1 -0
  329. package/dist/sdk/address/country-display.js +19 -0
  330. package/dist/sdk/address/country-display.js.map +1 -0
  331. package/dist/sdk/address/country-rules.js +30 -0
  332. package/dist/sdk/address/country-rules.js.map +1 -0
  333. package/dist/sdk/address/format-address.js +18 -0
  334. package/dist/sdk/address/format-address.js.map +1 -0
  335. package/dist/sdk/address/iso-countries.js +262 -0
  336. package/dist/sdk/address/iso-countries.js.map +1 -0
  337. package/dist/sdk/address/layouts.js +56 -0
  338. package/dist/sdk/address/layouts.js.map +1 -0
  339. package/dist/sdk/address/messages.js +97 -0
  340. package/dist/sdk/address/messages.js.map +1 -0
  341. package/dist/sdk/address/operations.d.ts +54 -0
  342. package/dist/sdk/address/operations.js +83 -0
  343. package/dist/sdk/address/operations.js.map +1 -0
  344. package/dist/sdk/address/postal-code-lookup-operations.js +23 -0
  345. package/dist/sdk/address/postal-code-lookup-operations.js.map +1 -0
  346. package/dist/sdk/address/postal-code.js +11 -0
  347. package/dist/sdk/address/postal-code.js.map +1 -0
  348. package/dist/sdk/address/schema.js +14 -0
  349. package/dist/sdk/address/schema.js.map +1 -0
  350. package/dist/sdk/address/server-fields.js +25 -0
  351. package/dist/sdk/address/server-fields.js.map +1 -0
  352. package/dist/sdk/address/switch-country.js +57 -0
  353. package/dist/sdk/address/switch-country.js.map +1 -0
  354. package/dist/sdk/address/types.d.ts +26 -0
  355. package/dist/sdk/address/use-address-actions.d.ts +29 -0
  356. package/dist/sdk/address/use-address-actions.js +247 -0
  357. package/dist/sdk/address/use-address-actions.js.map +1 -0
  358. package/dist/sdk/address/use-address-by-postal-code.js +57 -0
  359. package/dist/sdk/address/use-address-by-postal-code.js.map +1 -0
  360. package/dist/sdk/address/validate-address.js +62 -0
  361. package/dist/sdk/address/validate-address.js.map +1 -0
  362. package/dist/sdk/analytics/use-analytics-actions.js +2 -1
  363. package/dist/sdk/analytics/use-analytics-actions.js.map +1 -1
  364. package/dist/sdk/cache/storefront-cache.js +29 -4
  365. package/dist/sdk/cache/storefront-cache.js.map +1 -1
  366. package/dist/sdk/cart/use-cart-actions.js +9 -8
  367. package/dist/sdk/cart/use-cart-actions.js.map +1 -1
  368. package/dist/sdk/cart/use-cart-validate-on-open.js +2 -1
  369. package/dist/sdk/cart/use-cart-validate-on-open.js.map +1 -1
  370. package/dist/sdk/client/fetch-page-data.d.ts +11 -0
  371. package/dist/sdk/client/fetch-page-data.js +12 -1
  372. package/dist/sdk/client/fetch-page-data.js.map +1 -1
  373. package/dist/sdk/content/create-content-runtime.d.ts +22 -1
  374. package/dist/sdk/content/create-content-runtime.js +90 -9
  375. package/dist/sdk/content/create-content-runtime.js.map +1 -1
  376. package/dist/sdk/data/empty-content-value.js +16 -0
  377. package/dist/sdk/data/empty-content-value.js.map +1 -0
  378. package/dist/sdk/data/failed-fields.js +23 -0
  379. package/dist/sdk/data/failed-fields.js.map +1 -0
  380. package/dist/sdk/data/hot-data-provider.js +2 -1
  381. package/dist/sdk/data/hot-data-provider.js.map +1 -1
  382. package/dist/sdk/data/index.js +1 -1
  383. package/dist/sdk/data/page-reactive-data-root.d.ts +45 -7
  384. package/dist/sdk/data/page-reactive-data-root.js +88 -12
  385. package/dist/sdk/data/page-reactive-data-root.js.map +1 -1
  386. package/dist/sdk/data/variables-from-content.d.ts +43 -0
  387. package/dist/sdk/data/variables-from-content.js +57 -0
  388. package/dist/sdk/data/variables-from-content.js.map +1 -0
  389. package/dist/sdk/generated/fragment-types.js +2 -0
  390. package/dist/sdk/generated/fragment-types.js.map +1 -1
  391. package/dist/sdk/generated/gql.js +4 -1
  392. package/dist/sdk/generated/gql.js.map +1 -1
  393. package/dist/sdk/generated/graphql.d.ts +8 -0
  394. package/dist/sdk/generated/graphql.js +296 -1
  395. package/dist/sdk/generated/graphql.js.map +1 -1
  396. package/dist/sdk/i18n/messages/en-US.js +138 -1
  397. package/dist/sdk/i18n/messages/en-US.json +138 -1
  398. package/dist/sdk/i18n/messages/en-US.json.d.ts +137 -0
  399. package/dist/sdk/i18n/messages/es-ES.js +138 -1
  400. package/dist/sdk/i18n/messages/es-ES.json +138 -1
  401. package/dist/sdk/i18n/messages/pt-BR.js +138 -1
  402. package/dist/sdk/i18n/messages/pt-BR.json +138 -1
  403. package/dist/sdk/identity/use-identity-actions.js +5 -4
  404. package/dist/sdk/identity/use-identity-actions.js.map +1 -1
  405. package/dist/sdk/navigation/current-page.js +30 -0
  406. package/dist/sdk/navigation/current-page.js.map +1 -0
  407. package/dist/sdk/navigation/not-found-log.d.ts +28 -0
  408. package/dist/sdk/navigation/not-found-log.js +133 -0
  409. package/dist/sdk/navigation/not-found-log.js.map +1 -0
  410. package/dist/sdk/navigation/path.js +25 -0
  411. package/dist/sdk/navigation/path.js.map +1 -0
  412. package/dist/sdk/navigation/redirect.d.ts +11 -0
  413. package/dist/sdk/navigation/redirect.js +22 -0
  414. package/dist/sdk/navigation/redirect.js.map +1 -0
  415. package/dist/sdk/navigation/report.js +70 -0
  416. package/dist/sdk/navigation/report.js.map +1 -0
  417. package/dist/sdk/navigation/resolve-storefront-href.d.ts +12 -0
  418. package/dist/sdk/navigation/resolve-storefront-href.js +214 -0
  419. package/dist/sdk/navigation/resolve-storefront-href.js.map +1 -0
  420. package/dist/sdk/navigation/route-identity-provider.d.ts +11 -0
  421. package/dist/sdk/navigation/route-identity-provider.js +20 -0
  422. package/dist/sdk/navigation/route-identity-provider.js.map +1 -0
  423. package/dist/sdk/navigation/route-map-provider.d.ts +19 -0
  424. package/dist/sdk/navigation/route-map-provider.js +29 -0
  425. package/dist/sdk/navigation/route-map-provider.js.map +1 -0
  426. package/dist/sdk/navigation/storefront-link.d.ts +16 -0
  427. package/dist/sdk/navigation/storefront-link.js +66 -0
  428. package/dist/sdk/navigation/storefront-link.js.map +1 -0
  429. package/dist/sdk/navigation/types.d.ts +45 -0
  430. package/dist/sdk/navigation/use-storefront-navigation.d.ts +26 -0
  431. package/dist/sdk/navigation/use-storefront-navigation.js +73 -0
  432. package/dist/sdk/navigation/use-storefront-navigation.js.map +1 -0
  433. package/dist/sdk/navigation/use-storefront-route.d.ts +26 -0
  434. package/dist/sdk/navigation/use-storefront-route.js +87 -0
  435. package/dist/sdk/navigation/use-storefront-route.js.map +1 -0
  436. package/dist/sdk/navigation/use-storefront-search-params.d.ts +11 -0
  437. package/dist/sdk/navigation/use-storefront-search-params.js +16 -0
  438. package/dist/sdk/navigation/use-storefront-search-params.js.map +1 -0
  439. package/dist/sdk/orders/completion-badge.d.ts +8 -0
  440. package/dist/sdk/orders/completion-badge.js +47 -0
  441. package/dist/sdk/orders/completion-badge.js.map +1 -0
  442. package/dist/sdk/orders/order-operations.d.ts +19 -0
  443. package/dist/sdk/orders/order-operations.js +21 -0
  444. package/dist/sdk/orders/order-operations.js.map +1 -0
  445. package/dist/sdk/orders/use-order-actions.d.ts +23 -0
  446. package/dist/sdk/orders/use-order-actions.js +62 -0
  447. package/dist/sdk/orders/use-order-actions.js.map +1 -0
  448. package/dist/sdk/payment/gateway-origin.js +26 -13
  449. package/dist/sdk/payment/gateway-origin.js.map +1 -1
  450. package/dist/sdk/payment/gateway.d.ts +14 -2
  451. package/dist/sdk/payment/gateway.js +32 -14
  452. package/dist/sdk/payment/gateway.js.map +1 -1
  453. package/dist/sdk/payment/operations.js +11 -0
  454. package/dist/sdk/payment/operations.js.map +1 -1
  455. package/dist/sdk/payment/submission-registry.d.ts +2 -1
  456. package/dist/sdk/payment/submission-registry.js +12 -8
  457. package/dist/sdk/payment/submission-registry.js.map +1 -1
  458. package/dist/sdk/payment/use-payment-actions.d.ts +5 -3
  459. package/dist/sdk/payment/use-payment-actions.js +6 -3
  460. package/dist/sdk/payment/use-payment-actions.js.map +1 -1
  461. package/dist/sdk/payment/use-place-order.d.ts +6 -3
  462. package/dist/sdk/payment/use-place-order.js +334 -144
  463. package/dist/sdk/payment/use-place-order.js.map +1 -1
  464. package/dist/sdk/region/use-region-actions.js +2 -1
  465. package/dist/sdk/region/use-region-actions.js.map +1 -1
  466. package/dist/sdk/seo/page-alternates.d.ts +55 -0
  467. package/dist/sdk/seo/page-alternates.js +132 -0
  468. package/dist/sdk/seo/page-alternates.js.map +1 -0
  469. package/dist/sdk/session/read-server-session.d.ts +21 -0
  470. package/dist/sdk/session/read-server-session.js +61 -0
  471. package/dist/sdk/session/read-server-session.js.map +1 -0
  472. package/dist/sdk/session/use-session-actions.js +5 -4
  473. package/dist/sdk/session/use-session-actions.js.map +1 -1
  474. package/dist/sdk/session/use-session-revalidation.js +2 -1
  475. package/dist/sdk/session/use-session-revalidation.js.map +1 -1
  476. package/dist/sdk/shipping/use-shipping-actions.js +3 -2
  477. package/dist/sdk/shipping/use-shipping-actions.js.map +1 -1
  478. package/dist/utils/own-value.js +19 -0
  479. package/dist/utils/own-value.js.map +1 -0
  480. package/dist/utils/safe-href.d.ts +11 -0
  481. package/dist/utils/safe-href.js +31 -22
  482. package/dist/utils/safe-href.js.map +1 -1
  483. package/package.json +17 -2
  484. package/skills/storefront-asset/SKILL.md +111 -0
  485. package/skills/storefront-asset/references/api-side.md +153 -0
  486. package/skills/storefront-asset/references/findings.md +40 -0
  487. package/skills/storefront-asset/references/ui-side.md +94 -0
  488. package/src/styles/tailwind.css +27 -0
@@ -0,0 +1,247 @@
1
+ "use client";
2
+ import { defineActions } from "../../core/dist/actions/registry.js";
3
+ import "../../core/dist/index.js";
4
+ import { loggableErrorName } from "../../utils/loggable-error-name.js";
5
+ import { CUSTOMER_ADDRESS_BOOK_IDENTITY, CUSTOMER_ADDRESS_CREATE, CUSTOMER_ADDRESS_DELETE, CUSTOMER_ADDRESS_UPDATE } from "./operations.js";
6
+ import { useMutation } from "@apollo/client/react";
7
+ import { useCallback, useMemo } from "react";
8
+ import { CombinedGraphQLErrors } from "@apollo/client/errors";
9
+ //#region src/sdk/address/use-address-actions.ts
10
+ const NETWORK_ERROR = {
11
+ code: "NETWORK_ERROR",
12
+ message: "Unable to complete the request. Please try again.",
13
+ field: null
14
+ };
15
+ const UNAUTHORIZED_ERROR = {
16
+ code: "UNAUTHORIZED",
17
+ message: "Your session has expired. Please sign in again.",
18
+ field: null
19
+ };
20
+ /**
21
+ * The writes answer an expired session with a top-level `UNAUTHORIZED`, never a `userError`.
22
+ * Collapsing it into `NETWORK_ERROR` would offer a retry that cannot succeed, so it keeps its own
23
+ * code and the caller can send the shopper back to sign-in.
24
+ */
25
+ function toUserError(error) {
26
+ if (CombinedGraphQLErrors.is(error) && error.errors.some(({ extensions }) => extensions?.code === "UNAUTHORIZED")) return UNAUTHORIZED_ERROR;
27
+ return NETWORK_ERROR;
28
+ }
29
+ /**
30
+ * Takes the address out of the cached address book, then evicts its entity. Apollo hides a dangling
31
+ * reference when it reads a list, so the evict alone would empty the visible list; the explicit edit
32
+ * keeps the stored array free of references to an entity that is gone. With no book cached, only the
33
+ * evict runs.
34
+ */
35
+ function dropAddress(cache, id) {
36
+ const book = cache.readQuery({ query: CUSTOMER_ADDRESS_BOOK_IDENTITY })?.customerAddressBook;
37
+ if (book) cache.modify({
38
+ id: cache.identify(book),
39
+ fields: { addresses(existing, { readField }) {
40
+ return existing.filter((reference) => readField("id", reference) !== id);
41
+ } }
42
+ });
43
+ cache.evict({ id: cache.identify({
44
+ __typename: "CustomerAddress",
45
+ id
46
+ }) });
47
+ }
48
+ /** True when the server says the address is not among the shopper's own: gone, or never theirs. */
49
+ function isNotFound(userErrors) {
50
+ return userErrors?.some(({ code }) => code === "NOT_FOUND") ?? false;
51
+ }
52
+ /**
53
+ * The `address` namespace hook. Registered with the first-party action registry via `addressActions`
54
+ * below; the compiler-emitted `AddressActionProvider` calls it and threads the narrowed methods into
55
+ * each consumer's `$actions.address`.
56
+ */
57
+ function useAddressActions() {
58
+ const [createMutation] = useMutation(CUSTOMER_ADDRESS_CREATE, { update(cache, { data }) {
59
+ const address = data?.customerAddressCreate.customerAddress;
60
+ if (!address) return;
61
+ const book = cache.readQuery({ query: CUSTOMER_ADDRESS_BOOK_IDENTITY })?.customerAddressBook;
62
+ if (!book) return;
63
+ cache.modify({
64
+ id: cache.identify(book),
65
+ fields: { addresses(existing, { readField, toReference }) {
66
+ if (existing.some((reference) => readField("id", reference) === address.id)) return existing;
67
+ const created = toReference(address);
68
+ return created ? [...existing, created] : existing;
69
+ } }
70
+ });
71
+ } });
72
+ const [updateMutation] = useMutation(CUSTOMER_ADDRESS_UPDATE, { update(cache, { data }, { variables }) {
73
+ if (variables && isNotFound(data?.customerAddressUpdate.userErrors)) dropAddress(cache, variables.id);
74
+ } });
75
+ const [removeMutation] = useMutation(CUSTOMER_ADDRESS_DELETE, { update(cache, { data }, { variables }) {
76
+ const payload = data?.customerAddressDelete;
77
+ if (!payload) return;
78
+ if (payload.userErrors.length === 0 && payload.deletedCustomerAddressId) dropAddress(cache, payload.deletedCustomerAddressId);
79
+ else if (variables && isNotFound(payload.userErrors)) dropAddress(cache, variables.id);
80
+ } });
81
+ const create = useCallback(async (payload) => {
82
+ try {
83
+ return (await createMutation({ variables: { input: payload } })).data?.customerAddressCreate.userErrors ?? [];
84
+ } catch (error) {
85
+ console.error("[address.create] customerAddressCreate failed", loggableErrorName(error));
86
+ return [toUserError(error)];
87
+ }
88
+ }, [createMutation]);
89
+ const update = useCallback(async ({ id, ...input }) => {
90
+ try {
91
+ return (await updateMutation({ variables: {
92
+ id,
93
+ input
94
+ } })).data?.customerAddressUpdate.userErrors ?? [];
95
+ } catch (error) {
96
+ console.error("[address.update] customerAddressUpdate failed", loggableErrorName(error));
97
+ return [toUserError(error)];
98
+ }
99
+ }, [updateMutation]);
100
+ const remove = useCallback(async ({ id }) => {
101
+ try {
102
+ return (await removeMutation({ variables: { id } })).data?.customerAddressDelete.userErrors ?? [];
103
+ } catch (error) {
104
+ console.error("[address.remove] customerAddressDelete failed", loggableErrorName(error));
105
+ return [toUserError(error)];
106
+ }
107
+ }, [removeMutation]);
108
+ return useMemo(() => ({
109
+ create,
110
+ update,
111
+ remove
112
+ }), [
113
+ create,
114
+ update,
115
+ remove
116
+ ]);
117
+ }
118
+ defineActions({
119
+ namespace: "address",
120
+ description: "Mutation-backed writes against the shopper's saved addresses (create, update, remove).",
121
+ provider: {
122
+ name: "AddressActionProvider",
123
+ importPath: "@vtex/faststore/internal/client"
124
+ },
125
+ methods: {
126
+ create: {
127
+ description: "Save a new address and add it to the cached address book (async/pessimistic). Resolves the payload userErrors.",
128
+ payload: [
129
+ {
130
+ name: "country",
131
+ type: "string"
132
+ },
133
+ {
134
+ name: "recipientName",
135
+ type: "string",
136
+ optional: true
137
+ },
138
+ {
139
+ name: "street",
140
+ type: "string",
141
+ optional: true
142
+ },
143
+ {
144
+ name: "number",
145
+ type: "string",
146
+ optional: true
147
+ },
148
+ {
149
+ name: "complement",
150
+ type: "string",
151
+ optional: true
152
+ },
153
+ {
154
+ name: "neighborhood",
155
+ type: "string",
156
+ optional: true
157
+ },
158
+ {
159
+ name: "city",
160
+ type: "string",
161
+ optional: true
162
+ },
163
+ {
164
+ name: "state",
165
+ type: "string",
166
+ optional: true
167
+ },
168
+ {
169
+ name: "postalCode",
170
+ type: "string",
171
+ optional: true
172
+ },
173
+ {
174
+ name: "reference",
175
+ type: "string",
176
+ optional: true
177
+ }
178
+ ]
179
+ },
180
+ update: {
181
+ description: "Change a saved address (async/pessimistic). Omitted fields are kept; an empty string erases. Resolves the payload userErrors.",
182
+ payload: [
183
+ {
184
+ name: "id",
185
+ type: "string"
186
+ },
187
+ {
188
+ name: "recipientName",
189
+ type: "string",
190
+ optional: true
191
+ },
192
+ {
193
+ name: "street",
194
+ type: "string",
195
+ optional: true
196
+ },
197
+ {
198
+ name: "number",
199
+ type: "string",
200
+ optional: true
201
+ },
202
+ {
203
+ name: "complement",
204
+ type: "string",
205
+ optional: true
206
+ },
207
+ {
208
+ name: "neighborhood",
209
+ type: "string",
210
+ optional: true
211
+ },
212
+ {
213
+ name: "city",
214
+ type: "string",
215
+ optional: true
216
+ },
217
+ {
218
+ name: "state",
219
+ type: "string",
220
+ optional: true
221
+ },
222
+ {
223
+ name: "postalCode",
224
+ type: "string",
225
+ optional: true
226
+ },
227
+ {
228
+ name: "reference",
229
+ type: "string",
230
+ optional: true
231
+ }
232
+ ]
233
+ },
234
+ remove: {
235
+ description: "Remove a saved address once the server confirms (async/pessimistic). Resolves the payload userErrors.",
236
+ payload: [{
237
+ name: "id",
238
+ type: "string"
239
+ }]
240
+ }
241
+ },
242
+ use: useAddressActions
243
+ });
244
+ //#endregion
245
+ export { useAddressActions };
246
+
247
+ //# sourceMappingURL=use-address-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-address-actions.js","names":[],"sources":["../../../src/sdk/address/use-address-actions.ts"],"sourcesContent":["'use client';\n\nimport type { ApolloCache, Reference } from '@apollo/client';\nimport { CombinedGraphQLErrors } from '@apollo/client/errors';\nimport { useMutation } from '@apollo/client/react';\nimport { defineActions } from '@vtex/fs-core';\nimport { useCallback, useMemo } from 'react';\nimport { loggableErrorName } from '../../utils/loggable-error-name.js';\nimport {\n type AddressCreatePayload,\n type AddressRemovePayload,\n type AddressUpdatePayload,\n CUSTOMER_ADDRESS_BOOK_IDENTITY,\n CUSTOMER_ADDRESS_CREATE,\n CUSTOMER_ADDRESS_DELETE,\n CUSTOMER_ADDRESS_UPDATE,\n type CustomerAddressUserError,\n} from './operations.js';\n\nexport type {\n AddressCreatePayload,\n AddressRemovePayload,\n AddressUpdatePayload,\n CustomerAddressUserError,\n} from './operations.js';\n\n/**\n * The `address` action namespace: the one sanctioned client write surface for the shopper's saved\n * addresses (docs/storefront-core/adr-0010-actions-own-the-write-side.md,\n * docs/features/my-account-address-book/rfc.md § Address actions).\n *\n * Every method is async and pessimistic: the cache changes only after the server answers. Each\n * resolves to the payload's `userErrors` (empty on success), with their `field`, so the caller can\n * mark the field. None rejects for an expected outcome. ADR-0010 has handlers surface `userErrors`\n * through the `notifications` action; that action does not exist yet, so the caller presents them.\n */\nexport type AddressActions = Readonly<{\n /** Save a new address. Appends it to the cached address book on success. Never rejects. */\n create: (payload: AddressCreatePayload) => Promise<readonly CustomerAddressUserError[]>;\n /**\n * Change a saved address. Omit a field to keep it; an empty string erases it. Subscribers update\n * through the normalized cache. Never rejects.\n */\n update: (payload: AddressUpdatePayload) => Promise<readonly CustomerAddressUserError[]>;\n /**\n * Remove a saved address. The list changes only once the server confirms. A `NOT_FOUND` answer\n * means the server no longer has it, so it leaves the cache too. Never rejects.\n */\n remove: (payload: AddressRemovePayload) => Promise<readonly CustomerAddressUserError[]>;\n}>;\n\nconst NETWORK_ERROR: CustomerAddressUserError = {\n code: 'NETWORK_ERROR',\n message: 'Unable to complete the request. Please try again.',\n field: null,\n};\n\nconst UNAUTHORIZED_ERROR: CustomerAddressUserError = {\n code: 'UNAUTHORIZED',\n message: 'Your session has expired. Please sign in again.',\n field: null,\n};\n\n/**\n * The writes answer an expired session with a top-level `UNAUTHORIZED`, never a `userError`.\n * Collapsing it into `NETWORK_ERROR` would offer a retry that cannot succeed, so it keeps its own\n * code and the caller can send the shopper back to sign-in.\n */\nfunction toUserError(error: unknown): CustomerAddressUserError {\n if (CombinedGraphQLErrors.is(error) && error.errors.some(({ extensions }) => extensions?.code === 'UNAUTHORIZED')) {\n return UNAUTHORIZED_ERROR;\n }\n return NETWORK_ERROR;\n}\n\n/**\n * Takes the address out of the cached address book, then evicts its entity. Apollo hides a dangling\n * reference when it reads a list, so the evict alone would empty the visible list; the explicit edit\n * keeps the stored array free of references to an entity that is gone. With no book cached, only the\n * evict runs.\n */\nfunction dropAddress(cache: ApolloCache, id: string): void {\n const book = cache.readQuery({ query: CUSTOMER_ADDRESS_BOOK_IDENTITY })?.customerAddressBook;\n if (book) {\n cache.modify({\n id: cache.identify(book),\n fields: {\n addresses(existing: readonly Reference[], { readField }) {\n return existing.filter((reference) => readField('id', reference) !== id);\n },\n },\n });\n }\n cache.evict({ id: cache.identify({ __typename: 'CustomerAddress', id }) });\n}\n\n/** True when the server says the address is not among the shopper's own: gone, or never theirs. */\nfunction isNotFound(userErrors: readonly CustomerAddressUserError[] | undefined): boolean {\n return userErrors?.some(({ code }) => code === 'NOT_FOUND') ?? false;\n}\n\n/**\n * The `address` namespace hook. Registered with the first-party action registry via `addressActions`\n * below; the compiler-emitted `AddressActionProvider` calls it and threads the narrowed methods into\n * each consumer's `$actions.address`.\n */\nexport function useAddressActions(): AddressActions {\n const [createMutation] = useMutation(CUSTOMER_ADDRESS_CREATE, {\n update(cache, { data }) {\n const address = data?.customerAddressCreate.customerAddress;\n if (!address) return;\n // Read from the cache only: no mounted list means nothing to append to, and the entity the\n // payload just normalized is all this write leaves behind.\n const book = cache.readQuery({ query: CUSTOMER_ADDRESS_BOOK_IDENTITY })?.customerAddressBook;\n if (!book) return;\n cache.modify({\n id: cache.identify(book),\n fields: {\n addresses(existing: readonly Reference[], { readField, toReference }) {\n if (existing.some((reference) => readField('id', reference) === address.id)) {\n return existing;\n }\n const created = toReference(address);\n return created ? [...existing, created] : existing;\n },\n },\n });\n },\n });\n\n const [updateMutation] = useMutation(CUSTOMER_ADDRESS_UPDATE, {\n update(cache, { data }, { variables }) {\n if (variables && isNotFound(data?.customerAddressUpdate.userErrors)) dropAddress(cache, variables.id);\n },\n });\n\n const [removeMutation] = useMutation(CUSTOMER_ADDRESS_DELETE, {\n update(cache, { data }, { variables }) {\n const payload = data?.customerAddressDelete;\n if (!payload) return;\n if (payload.userErrors.length === 0 && payload.deletedCustomerAddressId) {\n dropAddress(cache, payload.deletedCustomerAddressId);\n } else if (variables && isNotFound(payload.userErrors)) {\n dropAddress(cache, variables.id);\n }\n },\n });\n\n const create = useCallback<AddressActions['create']>(\n async (payload) => {\n try {\n const result = await createMutation({ variables: { input: payload } });\n return result.data?.customerAddressCreate.userErrors ?? [];\n } catch (error) {\n // Log only the error name: the message can echo a submitted address value (PII).\n console.error('[address.create] customerAddressCreate failed', loggableErrorName(error));\n return [toUserError(error)];\n }\n },\n [createMutation],\n );\n\n const update = useCallback<AddressActions['update']>(\n async ({ id, ...input }) => {\n try {\n // Forwarded unmapped: an empty string is an explicit erase and must survive to the wire.\n const result = await updateMutation({ variables: { id, input } });\n return result.data?.customerAddressUpdate.userErrors ?? [];\n } catch (error) {\n console.error('[address.update] customerAddressUpdate failed', loggableErrorName(error));\n return [toUserError(error)];\n }\n },\n [updateMutation],\n );\n\n const remove = useCallback<AddressActions['remove']>(\n async ({ id }) => {\n try {\n const result = await removeMutation({ variables: { id } });\n return result.data?.customerAddressDelete.userErrors ?? [];\n } catch (error) {\n console.error('[address.remove] customerAddressDelete failed', loggableErrorName(error));\n return [toUserError(error)];\n }\n },\n [removeMutation],\n );\n\n return useMemo(() => ({ create, update, remove }), [create, update, remove]);\n}\n\n/**\n * Declares the `address` action namespace: the single source of truth for its method/payload\n * metadata, runtime provider, and `use` hook. The native catalog builder\n * (`scripts/build-catalog.mjs`) statically reads this call to emit `actions.json`; at runtime\n * `AddressActionProvider` calls `useAddressActions` directly.\n */\nexport const addressActions = defineActions({\n namespace: 'address',\n description: \"Mutation-backed writes against the shopper's saved addresses (create, update, remove).\",\n provider: { name: 'AddressActionProvider', importPath: '@vtex/faststore/internal/client' },\n methods: {\n create: {\n description:\n 'Save a new address and add it to the cached address book (async/pessimistic). Resolves the payload userErrors.',\n payload: [\n { name: 'country', type: 'string' },\n { name: 'recipientName', type: 'string', optional: true },\n { name: 'street', type: 'string', optional: true },\n { name: 'number', type: 'string', optional: true },\n { name: 'complement', type: 'string', optional: true },\n { name: 'neighborhood', type: 'string', optional: true },\n { name: 'city', type: 'string', optional: true },\n { name: 'state', type: 'string', optional: true },\n { name: 'postalCode', type: 'string', optional: true },\n { name: 'reference', type: 'string', optional: true },\n ],\n },\n update: {\n description:\n 'Change a saved address (async/pessimistic). Omitted fields are kept; an empty string erases. Resolves the payload userErrors.',\n payload: [\n { name: 'id', type: 'string' },\n { name: 'recipientName', type: 'string', optional: true },\n { name: 'street', type: 'string', optional: true },\n { name: 'number', type: 'string', optional: true },\n { name: 'complement', type: 'string', optional: true },\n { name: 'neighborhood', type: 'string', optional: true },\n { name: 'city', type: 'string', optional: true },\n { name: 'state', type: 'string', optional: true },\n { name: 'postalCode', type: 'string', optional: true },\n { name: 'reference', type: 'string', optional: true },\n ],\n },\n remove: {\n description:\n 'Remove a saved address once the server confirms (async/pessimistic). Resolves the payload userErrors.',\n payload: [{ name: 'id', type: 'string' }],\n },\n },\n use: useAddressActions,\n});\n"],"mappings":";;;;;;;;;AAmDA,MAAM,gBAA0C;CAC9C,MAAM;CACN,SAAS;CACT,OAAO;AACT;AAEA,MAAM,qBAA+C;CACnD,MAAM;CACN,SAAS;CACT,OAAO;AACT;;;;;;AAOA,SAAS,YAAY,OAA0C;CAC7D,IAAI,sBAAsB,GAAG,KAAK,KAAK,MAAM,OAAO,MAAM,EAAE,iBAAiB,YAAY,SAAS,cAAc,GAC9G,OAAO;CAET,OAAO;AACT;;;;;;;AAQA,SAAS,YAAY,OAAoB,IAAkB;CACzD,MAAM,OAAO,MAAM,UAAU,EAAE,OAAO,+BAA+B,CAAC,CAAC,EAAE;CACzE,IAAI,MACF,MAAM,OAAO;EACX,IAAI,MAAM,SAAS,IAAI;EACvB,QAAQ,EACN,UAAU,UAAgC,EAAE,aAAa;GACvD,OAAO,SAAS,QAAQ,cAAc,UAAU,MAAM,SAAS,MAAM,EAAE;EACzE,EACF;CACF,CAAC;CAEH,MAAM,MAAM,EAAE,IAAI,MAAM,SAAS;EAAE,YAAY;EAAmB;CAAG,CAAC,EAAE,CAAC;AAC3E;;AAGA,SAAS,WAAW,YAAsE;CACxF,OAAO,YAAY,MAAM,EAAE,WAAW,SAAS,WAAW,KAAK;AACjE;;;;;;AAOA,SAAgB,oBAAoC;CAClD,MAAM,CAAC,kBAAkB,YAAY,yBAAyB,EAC5D,OAAO,OAAO,EAAE,QAAQ;EACtB,MAAM,UAAU,MAAM,sBAAsB;EAC5C,IAAI,CAAC,SAAS;EAGd,MAAM,OAAO,MAAM,UAAU,EAAE,OAAO,+BAA+B,CAAC,CAAC,EAAE;EACzE,IAAI,CAAC,MAAM;EACX,MAAM,OAAO;GACX,IAAI,MAAM,SAAS,IAAI;GACvB,QAAQ,EACN,UAAU,UAAgC,EAAE,WAAW,eAAe;IACpE,IAAI,SAAS,MAAM,cAAc,UAAU,MAAM,SAAS,MAAM,QAAQ,EAAE,GACxE,OAAO;IAET,MAAM,UAAU,YAAY,OAAO;IACnC,OAAO,UAAU,CAAC,GAAG,UAAU,OAAO,IAAI;GAC5C,EACF;EACF,CAAC;CACH,EACF,CAAC;CAED,MAAM,CAAC,kBAAkB,YAAY,yBAAyB,EAC5D,OAAO,OAAO,EAAE,QAAQ,EAAE,aAAa;EACrC,IAAI,aAAa,WAAW,MAAM,sBAAsB,UAAU,GAAG,YAAY,OAAO,UAAU,EAAE;CACtG,EACF,CAAC;CAED,MAAM,CAAC,kBAAkB,YAAY,yBAAyB,EAC5D,OAAO,OAAO,EAAE,QAAQ,EAAE,aAAa;EACrC,MAAM,UAAU,MAAM;EACtB,IAAI,CAAC,SAAS;EACd,IAAI,QAAQ,WAAW,WAAW,KAAK,QAAQ,0BAC7C,YAAY,OAAO,QAAQ,wBAAwB;OAC9C,IAAI,aAAa,WAAW,QAAQ,UAAU,GACnD,YAAY,OAAO,UAAU,EAAE;CAEnC,EACF,CAAC;CAED,MAAM,SAAS,YACb,OAAO,YAAY;EACjB,IAAI;GAEF,QAAO,MADc,eAAe,EAAE,WAAW,EAAE,OAAO,QAAQ,EAAE,CAAC,EAAA,CACvD,MAAM,sBAAsB,cAAc,CAAC;EAC3D,SAAS,OAAO;GAEd,QAAQ,MAAM,iDAAiD,kBAAkB,KAAK,CAAC;GACvF,OAAO,CAAC,YAAY,KAAK,CAAC;EAC5B;CACF,GACA,CAAC,cAAc,CACjB;CAEA,MAAM,SAAS,YACb,OAAO,EAAE,IAAI,GAAG,YAAY;EAC1B,IAAI;GAGF,QAAO,MADc,eAAe,EAAE,WAAW;IAAE;IAAI;GAAM,EAAE,CAAC,EAAA,CAClD,MAAM,sBAAsB,cAAc,CAAC;EAC3D,SAAS,OAAO;GACd,QAAQ,MAAM,iDAAiD,kBAAkB,KAAK,CAAC;GACvF,OAAO,CAAC,YAAY,KAAK,CAAC;EAC5B;CACF,GACA,CAAC,cAAc,CACjB;CAEA,MAAM,SAAS,YACb,OAAO,EAAE,SAAS;EAChB,IAAI;GAEF,QAAO,MADc,eAAe,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,EAAA,CAC3C,MAAM,sBAAsB,cAAc,CAAC;EAC3D,SAAS,OAAO;GACd,QAAQ,MAAM,iDAAiD,kBAAkB,KAAK,CAAC;GACvF,OAAO,CAAC,YAAY,KAAK,CAAC;EAC5B;CACF,GACA,CAAC,cAAc,CACjB;CAEA,OAAO,eAAe;EAAE;EAAQ;EAAQ;CAAO,IAAI;EAAC;EAAQ;EAAQ;CAAM,CAAC;AAC7E;AAQ8B,cAAc;CAC1C,WAAW;CACX,aAAa;CACb,UAAU;EAAE,MAAM;EAAyB,YAAY;CAAkC;CACzF,SAAS;EACP,QAAQ;GACN,aACE;GACF,SAAS;IACP;KAAE,MAAM;KAAW,MAAM;IAAS;IAClC;KAAE,MAAM;KAAiB,MAAM;KAAU,UAAU;IAAK;IACxD;KAAE,MAAM;KAAU,MAAM;KAAU,UAAU;IAAK;IACjD;KAAE,MAAM;KAAU,MAAM;KAAU,UAAU;IAAK;IACjD;KAAE,MAAM;KAAc,MAAM;KAAU,UAAU;IAAK;IACrD;KAAE,MAAM;KAAgB,MAAM;KAAU,UAAU;IAAK;IACvD;KAAE,MAAM;KAAQ,MAAM;KAAU,UAAU;IAAK;IAC/C;KAAE,MAAM;KAAS,MAAM;KAAU,UAAU;IAAK;IAChD;KAAE,MAAM;KAAc,MAAM;KAAU,UAAU;IAAK;IACrD;KAAE,MAAM;KAAa,MAAM;KAAU,UAAU;IAAK;GACtD;EACF;EACA,QAAQ;GACN,aACE;GACF,SAAS;IACP;KAAE,MAAM;KAAM,MAAM;IAAS;IAC7B;KAAE,MAAM;KAAiB,MAAM;KAAU,UAAU;IAAK;IACxD;KAAE,MAAM;KAAU,MAAM;KAAU,UAAU;IAAK;IACjD;KAAE,MAAM;KAAU,MAAM;KAAU,UAAU;IAAK;IACjD;KAAE,MAAM;KAAc,MAAM;KAAU,UAAU;IAAK;IACrD;KAAE,MAAM;KAAgB,MAAM;KAAU,UAAU;IAAK;IACvD;KAAE,MAAM;KAAQ,MAAM;KAAU,UAAU;IAAK;IAC/C;KAAE,MAAM;KAAS,MAAM;KAAU,UAAU;IAAK;IAChD;KAAE,MAAM;KAAc,MAAM;KAAU,UAAU;IAAK;IACrD;KAAE,MAAM;KAAa,MAAM;KAAU,UAAU;IAAK;GACtD;EACF;EACA,QAAQ;GACN,aACE;GACF,SAAS,CAAC;IAAE,MAAM;IAAM,MAAM;GAAS,CAAC;EAC1C;CACF;CACA,KAAK;AACP,CAAC"}
@@ -0,0 +1,57 @@
1
+ "use client";
2
+ import { withRequestTimeout } from "../shipping/request-timeout.js";
3
+ import { loggableErrorName } from "../../utils/loggable-error-name.js";
4
+ import { ADDRESS_BY_POSTAL_CODE } from "./postal-code-lookup-operations.js";
5
+ import { getApolloContext } from "@apollo/client/react";
6
+ import { useCallback, useContext } from "react";
7
+ //#region src/sdk/address/use-address-by-postal-code.ts
8
+ const FAILED = { status: "failed" };
9
+ /**
10
+ * Postal-code lookup SDK hook (specs/sfs-3430-address-by-postal-code.md).
11
+ *
12
+ * Returns a callback that runs the `AddressByPostalCode` query once per call and never rejects. It
13
+ * reads the client from `getApolloContext()` (a non-throwing read, like `useShippingSimulation`), and
14
+ * skips the cache: a lookup is a shopper's postal code, so it is neither read from nor written to the
15
+ * normalized cache. The hook does not check `hasPostalCodeLookup(country)`; the caller decides
16
+ * whether a country is worth a request, and when to ask and which reply is stale.
17
+ *
18
+ * A failure logs the error's name, as the address actions do, and never the country, the postal
19
+ * code, or a message.
20
+ */
21
+ function useAddressByPostalCode() {
22
+ const { client } = useContext(getApolloContext());
23
+ return useCallback(async ({ country, postalCode }) => {
24
+ try {
25
+ if (!client) throw new Error("No Apollo client is available.");
26
+ const result = await withRequestTimeout((signal) => client.query({
27
+ query: ADDRESS_BY_POSTAL_CODE,
28
+ variables: {
29
+ country,
30
+ postalCode
31
+ },
32
+ fetchPolicy: "no-cache",
33
+ context: { fetchOptions: { signal } }
34
+ }));
35
+ if (result.error) throw result.error;
36
+ if (!result.data) throw new Error("The lookup returned no data.");
37
+ const address = result.data.addressByPostalCode;
38
+ if (!address) return { status: "notFound" };
39
+ return {
40
+ status: "found",
41
+ address: {
42
+ city: address.city ?? null,
43
+ state: address.state ?? null,
44
+ street: address.street ?? null,
45
+ neighborhood: address.neighborhood ?? null
46
+ }
47
+ };
48
+ } catch (error) {
49
+ console.error("[address.postalCodeLookup] addressByPostalCode failed", loggableErrorName(error));
50
+ return FAILED;
51
+ }
52
+ }, [client]);
53
+ }
54
+ //#endregion
55
+ export { useAddressByPostalCode };
56
+
57
+ //# sourceMappingURL=use-address-by-postal-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-address-by-postal-code.js","names":[],"sources":["../../../src/sdk/address/use-address-by-postal-code.ts"],"sourcesContent":["'use client';\n\nimport { getApolloContext } from '@apollo/client/react';\nimport { useCallback, useContext } from 'react';\nimport { loggableErrorName } from '../../utils/loggable-error-name.js';\nimport { withRequestTimeout } from '../shipping/request-timeout.js';\nimport { ADDRESS_BY_POSTAL_CODE } from './postal-code-lookup-operations.js';\n\n/**\n * The fields the platform resolves for a postal code. Each is `null` where the platform left it\n * blank, and the state is as the platform codes it, so it may not match a select's option values.\n */\nexport type PostalCodeLookupFields = Readonly<{\n city: string | null;\n state: string | null;\n street: string | null;\n neighborhood: string | null;\n}>;\n\n/**\n * The three things a lookup can come to. `notFound` is a code the platform does not know; `failed`\n * is a lookup that could not run (no client, a GraphQL error, a transport error, a timeout). The two\n * never look alike, so a caller can show an outage differently from a typo.\n */\nexport type PostalCodeLookupResult =\n | Readonly<{ status: 'found'; address: PostalCodeLookupFields }>\n | Readonly<{ status: 'notFound' }>\n | Readonly<{ status: 'failed' }>;\n\nconst FAILED: PostalCodeLookupResult = { status: 'failed' };\n\n/**\n * Postal-code lookup SDK hook (specs/sfs-3430-address-by-postal-code.md).\n *\n * Returns a callback that runs the `AddressByPostalCode` query once per call and never rejects. It\n * reads the client from `getApolloContext()` (a non-throwing read, like `useShippingSimulation`), and\n * skips the cache: a lookup is a shopper's postal code, so it is neither read from nor written to the\n * normalized cache. The hook does not check `hasPostalCodeLookup(country)`; the caller decides\n * whether a country is worth a request, and when to ask and which reply is stale.\n *\n * A failure logs the error's name, as the address actions do, and never the country, the postal\n * code, or a message.\n */\nexport function useAddressByPostalCode(): (input: {\n country: string;\n postalCode: string;\n}) => Promise<PostalCodeLookupResult> {\n const { client } = useContext(getApolloContext());\n\n return useCallback(\n async ({ country, postalCode }): Promise<PostalCodeLookupResult> => {\n try {\n if (!client) {\n throw new Error('No Apollo client is available.');\n }\n const result = await withRequestTimeout((signal) =>\n client.query({\n query: ADDRESS_BY_POSTAL_CODE,\n variables: { country, postalCode },\n fetchPolicy: 'no-cache',\n context: { fetchOptions: { signal } },\n }),\n );\n\n if (result.error) {\n throw result.error;\n }\n if (!result.data) {\n throw new Error('The lookup returned no data.');\n }\n\n const address = result.data.addressByPostalCode;\n if (!address) {\n return { status: 'notFound' };\n }\n return {\n status: 'found',\n address: {\n city: address.city ?? null,\n state: address.state ?? null,\n street: address.street ?? null,\n neighborhood: address.neighborhood ?? null,\n },\n };\n } catch (error) {\n console.error('[address.postalCodeLookup] addressByPostalCode failed', loggableErrorName(error));\n return FAILED;\n }\n },\n [client],\n );\n}\n"],"mappings":";;;;;;;AA6BA,MAAM,SAAiC,EAAE,QAAQ,SAAS;;;;;;;;;;;;;AAc1D,SAAgB,yBAGsB;CACpC,MAAM,EAAE,WAAW,WAAW,iBAAiB,CAAC;CAEhD,OAAO,YACL,OAAO,EAAE,SAAS,iBAAkD;EAClE,IAAI;GACF,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,gCAAgC;GAElD,MAAM,SAAS,MAAM,oBAAoB,WACvC,OAAO,MAAM;IACX,OAAO;IACP,WAAW;KAAE;KAAS;IAAW;IACjC,aAAa;IACb,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE;GACtC,CAAC,CACH;GAEA,IAAI,OAAO,OACT,MAAM,OAAO;GAEf,IAAI,CAAC,OAAO,MACV,MAAM,IAAI,MAAM,8BAA8B;GAGhD,MAAM,UAAU,OAAO,KAAK;GAC5B,IAAI,CAAC,SACH,OAAO,EAAE,QAAQ,WAAW;GAE9B,OAAO;IACL,QAAQ;IACR,SAAS;KACP,MAAM,QAAQ,QAAQ;KACtB,OAAO,QAAQ,SAAS;KACxB,QAAQ,QAAQ,UAAU;KAC1B,cAAc,QAAQ,gBAAgB;IACxC;GACF;EACF,SAAS,OAAO;GACd,QAAQ,MAAM,yDAAyD,kBAAkB,KAAK,CAAC;GAC/F,OAAO;EACT;CACF,GACA,CAAC,MAAM,CACT;AACF"}
@@ -0,0 +1,62 @@
1
+ import { ACCOUNT_MAX_LENGTH } from "./constants.js";
2
+ import { resolveLibraryError } from "./messages.js";
3
+ import { declaredMaxLength, toFormValues } from "./schema.js";
4
+ import { createFormState, getVisibleFields, resolveFieldOptions, validate } from "@vtex/country-forms";
5
+ //#region src/sdk/address/validate-address.ts
6
+ const REQUIRED = {
7
+ code: "required",
8
+ messageId: "fs/address.error.required"
9
+ };
10
+ const INVALID = {
11
+ code: "invalid",
12
+ messageId: "fs/address.error.invalid"
13
+ };
14
+ function isAddressField(name) {
15
+ return Object.hasOwn(ACCOUNT_MAX_LENGTH, name);
16
+ }
17
+ function isOutsideOptions(field, values, fields) {
18
+ const value = values[field.name] ?? "";
19
+ if (field.type !== "select" || value === "") return false;
20
+ const controller = fields.find(({ name }) => name === field.dependsOn);
21
+ if (controller && ((values[controller.name] ?? "") === "" || isOutsideOptions(controller, values, fields))) return false;
22
+ return !(resolveFieldOptions(field, values) ?? []).some((option) => option.value === value);
23
+ }
24
+ /**
25
+ * Checks a draft or a stored address against its country's rules and the account's own rules, and
26
+ * returns at most one error per field. A field's first error wins, in this order: the library's,
27
+ * a select value outside its options, then the account's maximum length.
28
+ *
29
+ * The account's rules cover what the library does not: `recipientName` must not be blank,
30
+ * `reference` and the address name may be empty, every free-text field has a maximum length, and a
31
+ * select's value must be one of the options the library resolves. Keys outside the ten address
32
+ * fields are ignored, so a merged record can carry `geoCoordinate` as it is.
33
+ */
34
+ function validateAddress(values, rules) {
35
+ const text = toFormValues(values);
36
+ const fields = getVisibleFields(rules.schema, text);
37
+ const errors = {};
38
+ const declared = new Map(rules.schema.fields.map((field) => [field.name, field]));
39
+ const libraryErrors = validate(createFormState(rules.schema, text), rules.schema);
40
+ for (const [name, key] of Object.entries(libraryErrors)) {
41
+ const field = declared.get(name);
42
+ if (isAddressField(name) && field) errors[name] = resolveLibraryError(key, {
43
+ country: rules.country,
44
+ maxLength: declaredMaxLength(field)
45
+ });
46
+ }
47
+ for (const field of fields) if (isAddressField(field.name) && !errors[field.name] && isOutsideOptions(field, text, fields)) errors[field.name] = INVALID;
48
+ if ((values.recipientName ?? "").trim() === "" && !errors.recipientName) errors.recipientName = REQUIRED;
49
+ for (const name of Object.keys(ACCOUNT_MAX_LENGTH).filter(isAddressField)) {
50
+ const maxLength = ACCOUNT_MAX_LENGTH[name];
51
+ if (!errors[name] && (values[name] ?? "").length > maxLength) errors[name] = {
52
+ code: "tooLong",
53
+ messageId: "fs/address.error.too-long",
54
+ values: { maxLength }
55
+ };
56
+ }
57
+ return errors;
58
+ }
59
+ //#endregion
60
+ export { validateAddress };
61
+
62
+ //# sourceMappingURL=validate-address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-address.js","names":[],"sources":["../../../src/sdk/address/validate-address.ts"],"sourcesContent":["import {\n createFormState,\n type FieldDefinition,\n type FormValues,\n getVisibleFields,\n resolveFieldOptions,\n validate,\n} from '@vtex/country-forms';\nimport { ACCOUNT_MAX_LENGTH } from './constants.js';\nimport { resolveLibraryError } from './messages.js';\nimport { declaredMaxLength, toFormValues } from './schema.js';\nimport type { AddressErrors, AddressFieldError, AddressFieldName, AddressValues, CountryRules } from './types.js';\n\nconst REQUIRED: AddressFieldError = { code: 'required', messageId: 'fs/address.error.required' };\nconst INVALID: AddressFieldError = { code: 'invalid', messageId: 'fs/address.error.invalid' };\n\nfunction isAddressField(name: string): name is AddressFieldName {\n return Object.hasOwn(ACCOUNT_MAX_LENGTH, name);\n}\n\nfunction isOutsideOptions(field: FieldDefinition, values: FormValues, fields: readonly FieldDefinition[]): boolean {\n const value = values[field.name] ?? '';\n if (field.type !== 'select' || value === '') {\n return false;\n }\n\n // A dependent list exists only for a valid controller; the controller carries its own error.\n const controller = fields.find(({ name }) => name === field.dependsOn);\n if (controller && ((values[controller.name] ?? '') === '' || isOutsideOptions(controller, values, fields))) {\n return false;\n }\n\n return !(resolveFieldOptions(field, values) ?? []).some((option) => option.value === value);\n}\n\n/**\n * Checks a draft or a stored address against its country's rules and the account's own rules, and\n * returns at most one error per field. A field's first error wins, in this order: the library's,\n * a select value outside its options, then the account's maximum length.\n *\n * The account's rules cover what the library does not: `recipientName` must not be blank,\n * `reference` and the address name may be empty, every free-text field has a maximum length, and a\n * select's value must be one of the options the library resolves. Keys outside the ten address\n * fields are ignored, so a merged record can carry `geoCoordinate` as it is.\n */\nexport function validateAddress(values: AddressValues, rules: CountryRules): AddressErrors {\n const text = toFormValues(values);\n const fields = getVisibleFields(rules.schema, text);\n const errors: Partial<Record<AddressFieldName, AddressFieldError>> = {};\n\n const declared = new Map(rules.schema.fields.map((field) => [field.name, field]));\n const libraryErrors = validate(createFormState(rules.schema, text), rules.schema);\n for (const [name, key] of Object.entries(libraryErrors)) {\n const field = declared.get(name);\n if (isAddressField(name) && field) {\n errors[name] = resolveLibraryError(key, { country: rules.country, maxLength: declaredMaxLength(field) });\n }\n }\n\n for (const field of fields) {\n if (isAddressField(field.name) && !errors[field.name] && isOutsideOptions(field, text, fields)) {\n errors[field.name] = INVALID;\n }\n }\n\n if ((values.recipientName ?? '').trim() === '' && !errors.recipientName) {\n errors.recipientName = REQUIRED;\n }\n\n for (const name of Object.keys(ACCOUNT_MAX_LENGTH).filter(isAddressField)) {\n const maxLength = ACCOUNT_MAX_LENGTH[name];\n if (!errors[name] && (values[name] ?? '').length > maxLength) {\n errors[name] = { code: 'tooLong', messageId: 'fs/address.error.too-long', values: { maxLength } };\n }\n }\n\n return errors;\n}\n"],"mappings":";;;;;AAaA,MAAM,WAA8B;CAAE,MAAM;CAAY,WAAW;AAA4B;AAC/F,MAAM,UAA6B;CAAE,MAAM;CAAW,WAAW;AAA2B;AAE5F,SAAS,eAAe,MAAwC;CAC9D,OAAO,OAAO,OAAO,oBAAoB,IAAI;AAC/C;AAEA,SAAS,iBAAiB,OAAwB,QAAoB,QAA6C;CACjH,MAAM,QAAQ,OAAO,MAAM,SAAS;CACpC,IAAI,MAAM,SAAS,YAAY,UAAU,IACvC,OAAO;CAIT,MAAM,aAAa,OAAO,MAAM,EAAE,WAAW,SAAS,MAAM,SAAS;CACrE,IAAI,gBAAgB,OAAO,WAAW,SAAS,QAAQ,MAAM,iBAAiB,YAAY,QAAQ,MAAM,IACtG,OAAO;CAGT,OAAO,EAAE,oBAAoB,OAAO,MAAM,KAAK,CAAC,EAAA,CAAG,MAAM,WAAW,OAAO,UAAU,KAAK;AAC5F;;;;;;;;;;;AAYA,SAAgB,gBAAgB,QAAuB,OAAoC;CACzF,MAAM,OAAO,aAAa,MAAM;CAChC,MAAM,SAAS,iBAAiB,MAAM,QAAQ,IAAI;CAClD,MAAM,SAA+D,CAAC;CAEtE,MAAM,WAAW,IAAI,IAAI,MAAM,OAAO,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;CAChF,MAAM,gBAAgB,SAAS,gBAAgB,MAAM,QAAQ,IAAI,GAAG,MAAM,MAAM;CAChF,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,aAAa,GAAG;EACvD,MAAM,QAAQ,SAAS,IAAI,IAAI;EAC/B,IAAI,eAAe,IAAI,KAAK,OAC1B,OAAO,QAAQ,oBAAoB,KAAK;GAAE,SAAS,MAAM;GAAS,WAAW,kBAAkB,KAAK;EAAE,CAAC;CAE3G;CAEA,KAAK,MAAM,SAAS,QAClB,IAAI,eAAe,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,SAAS,iBAAiB,OAAO,MAAM,MAAM,GAC3F,OAAO,MAAM,QAAQ;CAIzB,KAAK,OAAO,iBAAiB,GAAA,CAAI,KAAK,MAAM,MAAM,CAAC,OAAO,eACxD,OAAO,gBAAgB;CAGzB,KAAK,MAAM,QAAQ,OAAO,KAAK,kBAAkB,CAAC,CAAC,OAAO,cAAc,GAAG;EACzE,MAAM,YAAY,mBAAmB;EACrC,IAAI,CAAC,OAAO,UAAU,OAAO,SAAS,GAAA,CAAI,SAAS,WACjD,OAAO,QAAQ;GAAE,MAAM;GAAW,WAAW;GAA6B,QAAQ,EAAE,UAAU;EAAE;CAEpG;CAEA,OAAO;AACT"}
@@ -2,6 +2,7 @@
2
2
  import { defineActions } from "../../core/dist/actions/registry.js";
3
3
  import "../../core/dist/index.js";
4
4
  import { DEFAULT_ANALYTICS_DESTINATION, resolveAnalyticsDestination, useAnalyticsDestination } from "./analytics-destination.js";
5
+ import { loggableErrorName } from "../../utils/loggable-error-name.js";
5
6
  import { useCallback, useMemo, useRef } from "react";
6
7
  //#region src/sdk/analytics/use-analytics-actions.ts
7
8
  function toEcommerceItems(items) {
@@ -61,7 +62,7 @@ function useAnalyticsActions() {
61
62
  });
62
63
  pushToDataLayer(event, destination);
63
64
  } catch (error) {
64
- console.error(`[analytics.track] window.${destination} push failed`, error);
65
+ console.error(`[analytics.track] window.${destination} push failed`, loggableErrorName(error));
65
66
  }
66
67
  }, [override]);
67
68
  return useMemo(() => ({ track }), [track]);
@@ -1 +1 @@
1
- {"version":3,"file":"use-analytics-actions.js","names":[],"sources":["../../../src/sdk/analytics/use-analytics-actions.ts"],"sourcesContent":["'use client';\n\nimport { defineActions } from '@vtex/fs-core';\nimport { useCallback, useMemo, useRef } from 'react';\nimport {\n type AnalyticsDestination,\n DEFAULT_ANALYTICS_DESTINATION,\n resolveAnalyticsDestination,\n useAnalyticsDestination,\n} from './analytics-destination.js';\n\n/**\n * The `analytics` action namespace (specs/analytics-events.md) — a dispatcher-flavor namespace\n * (docs/storefront-core/adr-0010-actions-own-the-write-side.md; docs/storefront-core/rfc-actions.md\n * § \"Three binding flavors\") that pushes the two standard payment analytics events,\n * `add_payment_info` and `purchase`, to a `window` array — `window.dataLayer` by default, the\n * GTM/GA4-recognizable event convention. It never touches the Apollo cache, never issues a GraphQL\n * operation, and never throws: a broken tag-manager script can never block payment submission or\n * order placement.\n *\n * The destination array is configurable at build time\n * (specs/make-the-analytics-destination-configurable-for.md; T120) — see\n * `./analytics-destination.js` for the resolution precedence, validation, and the\n * `AnalyticsDestinationProvider`. The pushed entry's shape is a data *contract* (a well-known\n * browser-global array shape), not a *provider* — no vendor SDK, no server call. A future\n * platform/foundation epic may replace this sink with a real `AnalyticsContext`; the\n * `track(event: AnalyticsEvent): void` signature and `AnalyticsActions` type are the stable public\n * contract every call site depends on until then (US-4).\n */\n\nexport type AnalyticsMoney = Readonly<{\n amount: number;\n currencyCode: string;\n}>;\n\nexport type AnalyticsLineItem = Readonly<{\n sku: string;\n name: string;\n price: AnalyticsMoney;\n quantity: number;\n}>;\n\n/** Dispatched by T7's CardEntry, before opening the transaction. */\nexport type AddPaymentInfoEvent = Readonly<{\n name: 'add_payment_info';\n value: AnalyticsMoney;\n /**\n * Derived from the selected method's `groupName` at the moment this fires (T140, Decision 5).\n * Optional because the event fires on the cart total, before a method is necessarily selected —\n * omitted rather than a guessed literal, so a downstream consumer never reads a false payment kind.\n * `toEcommercePayload` below drops the corresponding key entirely when this is absent.\n */\n paymentType?: 'Credit Card' | 'Debit Card';\n items?: readonly AnalyticsLineItem[];\n}>;\n\n/** Dispatched by T13's usePlaceOrder, after a successful gateway callback. */\nexport type PurchaseEvent = Readonly<{\n name: 'purchase';\n transactionId: string;\n value: AnalyticsMoney;\n items?: readonly AnalyticsLineItem[];\n}>;\n\nexport type AnalyticsEvent = AddPaymentInfoEvent | PurchaseEvent;\n\nexport type AnalyticsActions = Readonly<{\n /** Push a standard analytics event to window.dataLayer. Fire-and-forget; never throws. */\n track: (event: AnalyticsEvent) => void;\n}>;\n\n/** The shape pushed onto window.dataLayer — GTM/GA4's own event convention. */\nexport type AnalyticsDataLayerEvent = Readonly<{\n event: 'add_payment_info' | 'purchase';\n ecommerce: Record<string, unknown>;\n}>;\n\nfunction toEcommerceItems(items: readonly AnalyticsLineItem[] | undefined) {\n return (items ?? []).map((item) => ({\n item_id: item.sku,\n item_name: item.name,\n price: item.price.amount,\n quantity: item.quantity,\n }));\n}\n\nfunction toEcommercePayload(event: AnalyticsEvent): Record<string, unknown> {\n if (event.name === 'add_payment_info') {\n return {\n currency: event.value.currencyCode,\n value: event.value.amount,\n // T140, Decision 5: the key itself must be absent when `paymentType` is, not merely `undefined`\n // — `pushToDataLayer` pushes this object as-is with no serialization step to strip it, and\n // `'payment_type' in ecommerce` would otherwise still report true.\n ...(event.paymentType !== undefined ? { payment_type: event.paymentType } : {}),\n items: toEcommerceItems(event.items),\n };\n }\n return {\n transaction_id: event.transactionId,\n currency: event.value.currencyCode,\n value: event.value.amount,\n items: toEcommerceItems(event.items),\n };\n}\n\n// `Reflect.get`/`Reflect.set` below match `storefront-provider.tsx`'s existing pattern for a\n// dynamic `window` key — they are not a security mechanism. `Reflect.set(target, k, v)` invokes\n// an inherited setter and creates no own property, exactly like `window[k] = v` would; it adds no\n// hardening on its own. What actually blocks prototype pollution is\n// `isValidAnalyticsDestination`'s denylist and identifier pattern, checked by the caller before\n// `destination` ever reaches this function, plus the non-array guard immediately below.\n//\n// The cast below, not a `declare global` augmentation of `Window`, is what keeps this typed: a\n// global augmentation here would ship inside this package's own `.d.ts` output and hand every\n// consumer's `window.dataLayer` this package's narrow event union, wrong for a store that also\n// pushes its own GTM events (packages/components/scripts/dist-type-boundary.test.ts). `destination`\n// is a runtime string anyway — `Window` has nothing to look up a dynamic key against — so the local\n// cast is also the only type-safe option, not merely the non-leaking one.\nfunction pushToDataLayer(event: AnalyticsEvent, destination: AnalyticsDestination): void {\n if (typeof window === 'undefined') return;\n\n let layer = Reflect.get(window, destination) as AnalyticsDataLayerEvent[] | undefined;\n if (layer === undefined) {\n layer = [];\n Reflect.set(window, destination, layer);\n } else if (!Array.isArray(layer)) {\n console.error(`[analytics.track] window.${destination} already exists and is not an array; the event was dropped`);\n return;\n }\n\n layer.push({ event: event.name, ecommerce: toEcommercePayload(event) });\n}\n\n/**\n * The `analytics` namespace hook. Registered with the first-party action registry via\n * `analyticsActions` below; the compiler-emitted `AnalyticsActionProvider` calls it and threads\n * the narrowed methods into each consumer's `$actions.analytics`. Dispatcher flavor: no\n * `useMutation`, no cache read or write (ADR-0010). Fire-and-forget — `track` never throws, so a\n * broken tag-manager script can never block payment submission or order placement.\n */\nexport function useAnalyticsActions(): AnalyticsActions {\n const override = useAnalyticsDestination();\n // Scoped to this hook instance, not the module: \"logs once\" means once per mounted\n // `useAnalyticsActions()`, so two independent call sites each still get their own first warning.\n const hasLoggedRejectionRef = useRef(false);\n\n const track = useCallback<AnalyticsActions['track']>(\n (event) => {\n // The SSR guard runs before any destination resolution is attempted — not just before the\n // write. Preserved from the pre-T120 behaviour (US-3, \"SSR — no destination resolution\n // attempted at all\").\n if (typeof window === 'undefined') return;\n let destination: AnalyticsDestination = DEFAULT_ANALYTICS_DESTINATION;\n try {\n destination = resolveAnalyticsDestination({\n override,\n hasLoggedRejection: hasLoggedRejectionRef,\n });\n pushToDataLayer(event, destination);\n } catch (error) {\n console.error(`[analytics.track] window.${destination} push failed`, error);\n }\n },\n [override],\n );\n\n return useMemo(() => ({ track }), [track]);\n}\n\n/**\n * Declares the `analytics` action namespace — the single source of truth for its method/payload\n * metadata, runtime provider, and `use` hook (mirrors `cartActions`, `shippingActions`). The\n * native catalog builder (`scripts/build-catalog.mjs`) statically reads this call to emit\n * `actions.json`; at runtime `AnalyticsActionProvider` calls `useAnalyticsActions` directly.\n *\n * The `payload` below is a flattened, best-effort scalar approximation of `AnalyticsEvent` for\n * catalog/docs tooling: `ActionPayloadField.type` supports only scalar primitives and cannot\n * express a discriminated union or a nested `items` array. The TS `AnalyticsEvent` union above is\n * the source of truth for the real call shape.\n */\nexport const analyticsActions = defineActions({\n namespace: 'analytics',\n description:\n 'Dispatcher-flavor namespace that pushes standard add_payment_info / purchase events to window.dataLayer. Never touches the Apollo cache.',\n provider: { name: 'AnalyticsActionProvider', importPath: '@vtex/faststore/internal/client' },\n methods: {\n track: {\n description:\n 'Push a standard analytics event (add_payment_info | purchase) to window.dataLayer. Fire-and-forget; never throws.',\n payload: [\n { name: 'name', type: 'string' },\n { name: 'currencyCode', type: 'string' },\n { name: 'amount', type: 'number' },\n { name: 'paymentType', type: 'string', optional: true },\n { name: 'transactionId', type: 'string', optional: true },\n ],\n },\n },\n use: useAnalyticsActions,\n});\n"],"mappings":";;;;;;AA6EA,SAAS,iBAAiB,OAAiD;CACzE,QAAQ,SAAS,CAAC,EAAA,CAAG,KAAK,UAAU;EAClC,SAAS,KAAK;EACd,WAAW,KAAK;EAChB,OAAO,KAAK,MAAM;EAClB,UAAU,KAAK;CACjB,EAAE;AACJ;AAEA,SAAS,mBAAmB,OAAgD;CAC1E,IAAI,MAAM,SAAS,oBACjB,OAAO;EACL,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EAInB,GAAI,MAAM,gBAAgB,KAAA,IAAY,EAAE,cAAc,MAAM,YAAY,IAAI,CAAC;EAC7E,OAAO,iBAAiB,MAAM,KAAK;CACrC;CAEF,OAAO;EACL,gBAAgB,MAAM;EACtB,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EACnB,OAAO,iBAAiB,MAAM,KAAK;CACrC;AACF;AAeA,SAAS,gBAAgB,OAAuB,aAAyC;CACvF,IAAI,OAAO,WAAW,aAAa;CAEnC,IAAI,QAAQ,QAAQ,IAAI,QAAQ,WAAW;CAC3C,IAAI,UAAU,KAAA,GAAW;EACvB,QAAQ,CAAC;EACT,QAAQ,IAAI,QAAQ,aAAa,KAAK;CACxC,OAAO,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;EAChC,QAAQ,MAAM,4BAA4B,YAAY,2DAA2D;EACjH;CACF;CAEA,MAAM,KAAK;EAAE,OAAO,MAAM;EAAM,WAAW,mBAAmB,KAAK;CAAE,CAAC;AACxE;;;;;;;;AASA,SAAgB,sBAAwC;CACtD,MAAM,WAAW,wBAAwB;CAGzC,MAAM,wBAAwB,OAAO,KAAK;CAE1C,MAAM,QAAQ,aACX,UAAU;EAIT,IAAI,OAAO,WAAW,aAAa;EACnC,IAAI,cAAoC;EACxC,IAAI;GACF,cAAc,4BAA4B;IACxC;IACA,oBAAoB;GACtB,CAAC;GACD,gBAAgB,OAAO,WAAW;EACpC,SAAS,OAAO;GACd,QAAQ,MAAM,4BAA4B,YAAY,eAAe,KAAK;EAC5E;CACF,GACA,CAAC,QAAQ,CACX;CAEA,OAAO,eAAe,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC;AAC3C;AAagC,cAAc;CAC5C,WAAW;CACX,aACE;CACF,UAAU;EAAE,MAAM;EAA2B,YAAY;CAAkC;CAC3F,SAAS,EACP,OAAO;EACL,aACE;EACF,SAAS;GACP;IAAE,MAAM;IAAQ,MAAM;GAAS;GAC/B;IAAE,MAAM;IAAgB,MAAM;GAAS;GACvC;IAAE,MAAM;IAAU,MAAM;GAAS;GACjC;IAAE,MAAM;IAAe,MAAM;IAAU,UAAU;GAAK;GACtD;IAAE,MAAM;IAAiB,MAAM;IAAU,UAAU;GAAK;EAC1D;CACF,EACF;CACA,KAAK;AACP,CAAC"}
1
+ {"version":3,"file":"use-analytics-actions.js","names":[],"sources":["../../../src/sdk/analytics/use-analytics-actions.ts"],"sourcesContent":["'use client';\n\nimport { defineActions } from '@vtex/fs-core';\nimport { useCallback, useMemo, useRef } from 'react';\nimport { loggableErrorName } from '../../utils/loggable-error-name.js';\nimport {\n type AnalyticsDestination,\n DEFAULT_ANALYTICS_DESTINATION,\n resolveAnalyticsDestination,\n useAnalyticsDestination,\n} from './analytics-destination.js';\n\n/**\n * The `analytics` action namespace (specs/analytics-events.md) — a dispatcher-flavor namespace\n * (docs/storefront-core/adr-0010-actions-own-the-write-side.md; docs/storefront-core/rfc-actions.md\n * § \"Three binding flavors\") that pushes the two standard payment analytics events,\n * `add_payment_info` and `purchase`, to a `window` array — `window.dataLayer` by default, the\n * GTM/GA4-recognizable event convention. It never touches the Apollo cache, never issues a GraphQL\n * operation, and never throws: a broken tag-manager script can never block payment submission or\n * order placement.\n *\n * The destination array is configurable at build time\n * (specs/make-the-analytics-destination-configurable-for.md; T120) — see\n * `./analytics-destination.js` for the resolution precedence, validation, and the\n * `AnalyticsDestinationProvider`. The pushed entry's shape is a data *contract* (a well-known\n * browser-global array shape), not a *provider* — no vendor SDK, no server call. A future\n * platform/foundation epic may replace this sink with a real `AnalyticsContext`; the\n * `track(event: AnalyticsEvent): void` signature and `AnalyticsActions` type are the stable public\n * contract every call site depends on until then (US-4).\n */\n\nexport type AnalyticsMoney = Readonly<{\n amount: number;\n currencyCode: string;\n}>;\n\nexport type AnalyticsLineItem = Readonly<{\n sku: string;\n name: string;\n price: AnalyticsMoney;\n quantity: number;\n}>;\n\n/** Dispatched by T7's CardEntry, before opening the transaction. */\nexport type AddPaymentInfoEvent = Readonly<{\n name: 'add_payment_info';\n value: AnalyticsMoney;\n /**\n * Derived from the selected method's `groupName` at the moment this fires (T140, Decision 5).\n * Optional because the event fires on the cart total, before a method is necessarily selected —\n * omitted rather than a guessed literal, so a downstream consumer never reads a false payment kind.\n * `toEcommercePayload` below drops the corresponding key entirely when this is absent.\n */\n paymentType?: 'Credit Card' | 'Debit Card';\n items?: readonly AnalyticsLineItem[];\n}>;\n\n/** Dispatched by T13's usePlaceOrder, after a successful gateway callback. */\nexport type PurchaseEvent = Readonly<{\n name: 'purchase';\n transactionId: string;\n value: AnalyticsMoney;\n items?: readonly AnalyticsLineItem[];\n}>;\n\nexport type AnalyticsEvent = AddPaymentInfoEvent | PurchaseEvent;\n\nexport type AnalyticsActions = Readonly<{\n /** Push a standard analytics event to window.dataLayer. Fire-and-forget; never throws. */\n track: (event: AnalyticsEvent) => void;\n}>;\n\n/** The shape pushed onto window.dataLayer — GTM/GA4's own event convention. */\nexport type AnalyticsDataLayerEvent = Readonly<{\n event: 'add_payment_info' | 'purchase';\n ecommerce: Record<string, unknown>;\n}>;\n\nfunction toEcommerceItems(items: readonly AnalyticsLineItem[] | undefined) {\n return (items ?? []).map((item) => ({\n item_id: item.sku,\n item_name: item.name,\n price: item.price.amount,\n quantity: item.quantity,\n }));\n}\n\nfunction toEcommercePayload(event: AnalyticsEvent): Record<string, unknown> {\n if (event.name === 'add_payment_info') {\n return {\n currency: event.value.currencyCode,\n value: event.value.amount,\n // T140, Decision 5: the key itself must be absent when `paymentType` is, not merely `undefined`\n // — `pushToDataLayer` pushes this object as-is with no serialization step to strip it, and\n // `'payment_type' in ecommerce` would otherwise still report true.\n ...(event.paymentType !== undefined ? { payment_type: event.paymentType } : {}),\n items: toEcommerceItems(event.items),\n };\n }\n return {\n transaction_id: event.transactionId,\n currency: event.value.currencyCode,\n value: event.value.amount,\n items: toEcommerceItems(event.items),\n };\n}\n\n// `Reflect.get`/`Reflect.set` below match `storefront-provider.tsx`'s existing pattern for a\n// dynamic `window` key — they are not a security mechanism. `Reflect.set(target, k, v)` invokes\n// an inherited setter and creates no own property, exactly like `window[k] = v` would; it adds no\n// hardening on its own. What actually blocks prototype pollution is\n// `isValidAnalyticsDestination`'s denylist and identifier pattern, checked by the caller before\n// `destination` ever reaches this function, plus the non-array guard immediately below.\n//\n// The cast below, not a `declare global` augmentation of `Window`, is what keeps this typed: a\n// global augmentation here would ship inside this package's own `.d.ts` output and hand every\n// consumer's `window.dataLayer` this package's narrow event union, wrong for a store that also\n// pushes its own GTM events (packages/components/scripts/dist-type-boundary.test.ts). `destination`\n// is a runtime string anyway — `Window` has nothing to look up a dynamic key against — so the local\n// cast is also the only type-safe option, not merely the non-leaking one.\nfunction pushToDataLayer(event: AnalyticsEvent, destination: AnalyticsDestination): void {\n if (typeof window === 'undefined') return;\n\n let layer = Reflect.get(window, destination) as AnalyticsDataLayerEvent[] | undefined;\n if (layer === undefined) {\n layer = [];\n Reflect.set(window, destination, layer);\n } else if (!Array.isArray(layer)) {\n console.error(`[analytics.track] window.${destination} already exists and is not an array; the event was dropped`);\n return;\n }\n\n layer.push({ event: event.name, ecommerce: toEcommercePayload(event) });\n}\n\n/**\n * The `analytics` namespace hook. Registered with the first-party action registry via\n * `analyticsActions` below; the compiler-emitted `AnalyticsActionProvider` calls it and threads\n * the narrowed methods into each consumer's `$actions.analytics`. Dispatcher flavor: no\n * `useMutation`, no cache read or write (ADR-0010). Fire-and-forget — `track` never throws, so a\n * broken tag-manager script can never block payment submission or order placement.\n */\nexport function useAnalyticsActions(): AnalyticsActions {\n const override = useAnalyticsDestination();\n // Scoped to this hook instance, not the module: \"logs once\" means once per mounted\n // `useAnalyticsActions()`, so two independent call sites each still get their own first warning.\n const hasLoggedRejectionRef = useRef(false);\n\n const track = useCallback<AnalyticsActions['track']>(\n (event) => {\n // The SSR guard runs before any destination resolution is attempted — not just before the\n // write. Preserved from the pre-T120 behaviour (US-3, \"SSR — no destination resolution\n // attempted at all\").\n if (typeof window === 'undefined') return;\n let destination: AnalyticsDestination = DEFAULT_ANALYTICS_DESTINATION;\n try {\n destination = resolveAnalyticsDestination({\n override,\n hasLoggedRejection: hasLoggedRejectionRef,\n });\n pushToDataLayer(event, destination);\n } catch (error) {\n console.error(`[analytics.track] window.${destination} push failed`, loggableErrorName(error));\n }\n },\n [override],\n );\n\n return useMemo(() => ({ track }), [track]);\n}\n\n/**\n * Declares the `analytics` action namespace — the single source of truth for its method/payload\n * metadata, runtime provider, and `use` hook (mirrors `cartActions`, `shippingActions`). The\n * native catalog builder (`scripts/build-catalog.mjs`) statically reads this call to emit\n * `actions.json`; at runtime `AnalyticsActionProvider` calls `useAnalyticsActions` directly.\n *\n * The `payload` below is a flattened, best-effort scalar approximation of `AnalyticsEvent` for\n * catalog/docs tooling: `ActionPayloadField.type` supports only scalar primitives and cannot\n * express a discriminated union or a nested `items` array. The TS `AnalyticsEvent` union above is\n * the source of truth for the real call shape.\n */\nexport const analyticsActions = defineActions({\n namespace: 'analytics',\n description:\n 'Dispatcher-flavor namespace that pushes standard add_payment_info / purchase events to window.dataLayer. Never touches the Apollo cache.',\n provider: { name: 'AnalyticsActionProvider', importPath: '@vtex/faststore/internal/client' },\n methods: {\n track: {\n description:\n 'Push a standard analytics event (add_payment_info | purchase) to window.dataLayer. Fire-and-forget; never throws.',\n payload: [\n { name: 'name', type: 'string' },\n { name: 'currencyCode', type: 'string' },\n { name: 'amount', type: 'number' },\n { name: 'paymentType', type: 'string', optional: true },\n { name: 'transactionId', type: 'string', optional: true },\n ],\n },\n },\n use: useAnalyticsActions,\n});\n"],"mappings":";;;;;;;AA8EA,SAAS,iBAAiB,OAAiD;CACzE,QAAQ,SAAS,CAAC,EAAA,CAAG,KAAK,UAAU;EAClC,SAAS,KAAK;EACd,WAAW,KAAK;EAChB,OAAO,KAAK,MAAM;EAClB,UAAU,KAAK;CACjB,EAAE;AACJ;AAEA,SAAS,mBAAmB,OAAgD;CAC1E,IAAI,MAAM,SAAS,oBACjB,OAAO;EACL,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EAInB,GAAI,MAAM,gBAAgB,KAAA,IAAY,EAAE,cAAc,MAAM,YAAY,IAAI,CAAC;EAC7E,OAAO,iBAAiB,MAAM,KAAK;CACrC;CAEF,OAAO;EACL,gBAAgB,MAAM;EACtB,UAAU,MAAM,MAAM;EACtB,OAAO,MAAM,MAAM;EACnB,OAAO,iBAAiB,MAAM,KAAK;CACrC;AACF;AAeA,SAAS,gBAAgB,OAAuB,aAAyC;CACvF,IAAI,OAAO,WAAW,aAAa;CAEnC,IAAI,QAAQ,QAAQ,IAAI,QAAQ,WAAW;CAC3C,IAAI,UAAU,KAAA,GAAW;EACvB,QAAQ,CAAC;EACT,QAAQ,IAAI,QAAQ,aAAa,KAAK;CACxC,OAAO,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;EAChC,QAAQ,MAAM,4BAA4B,YAAY,2DAA2D;EACjH;CACF;CAEA,MAAM,KAAK;EAAE,OAAO,MAAM;EAAM,WAAW,mBAAmB,KAAK;CAAE,CAAC;AACxE;;;;;;;;AASA,SAAgB,sBAAwC;CACtD,MAAM,WAAW,wBAAwB;CAGzC,MAAM,wBAAwB,OAAO,KAAK;CAE1C,MAAM,QAAQ,aACX,UAAU;EAIT,IAAI,OAAO,WAAW,aAAa;EACnC,IAAI,cAAoC;EACxC,IAAI;GACF,cAAc,4BAA4B;IACxC;IACA,oBAAoB;GACtB,CAAC;GACD,gBAAgB,OAAO,WAAW;EACpC,SAAS,OAAO;GACd,QAAQ,MAAM,4BAA4B,YAAY,eAAe,kBAAkB,KAAK,CAAC;EAC/F;CACF,GACA,CAAC,QAAQ,CACX;CAEA,OAAO,eAAe,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC;AAC3C;AAagC,cAAc;CAC5C,WAAW;CACX,aACE;CACF,UAAU;EAAE,MAAM;EAA2B,YAAY;CAAkC;CAC3F,SAAS,EACP,OAAO;EACL,aACE;EACF,SAAS;GACP;IAAE,MAAM;IAAQ,MAAM;GAAS;GAC/B;IAAE,MAAM;IAAgB,MAAM;GAAS;GACvC;IAAE,MAAM;IAAU,MAAM;GAAS;GACjC;IAAE,MAAM;IAAe,MAAM;IAAU,UAAU;GAAK;GACtD;IAAE,MAAM;IAAiB,MAAM;IAAU,UAAU;GAAK;EAC1D;CACF,EACF;CACA,KAAK;AACP,CAAC"}
@@ -4,11 +4,36 @@ import { InMemoryCache } from "@apollo/client";
4
4
  /**
5
5
  * Per-entity normalization and field-merge rules for the Storefront cache.
6
6
  *
7
- * Empty in T1. Domain entries (Product, Cart, OrderForm, …) arrive with the
8
- * particles that need them — see docs/storefront-core/reference-free-particle-model.md § Typed documents and the shared cache,
9
- * "Out of Scope".
7
+ * The cart and the order share three types whose ids neither can scope
8
+ * (docs/features/order-placed/rfc.md, 3.4): a totalizer's id is its category
9
+ * ("Items"), which the cart's totalizer line selects by; an address's id is the
10
+ * saved address itself, masked on the order and not on the cart; and a
11
+ * customization's id is the assembly ("Engraving"), which two lines of one cart
12
+ * already share. Normalized, one record would overwrite the other, so each is
13
+ * stored inside the record that holds it, and replaced on every write: safe
14
+ * while every fragment selects the same subfields of each.
15
+ *
16
+ * The lists that hold them are the server's whole answer, so each write
17
+ * replaces the list (`merge: false`). Apollo does the same by default, but warns
18
+ * that data may be lost whenever such a list shrinks, as when a discount line
19
+ * leaves the cart's totalizers; a merge by id would keep that stale line.
20
+ *
21
+ * Other domain entries arrive with the particles that need them — see
22
+ * docs/storefront-core/reference-free-particle-model.md § Typed documents and the shared cache.
10
23
  */
11
- const typePolicies = {};
24
+ const replaceList = { merge: false };
25
+ const typePolicies = {
26
+ CartTotalizer: { keyFields: false },
27
+ Address: { keyFields: false },
28
+ CartItemCustomization: { keyFields: false },
29
+ Cart: { fields: { totalizers: replaceList } },
30
+ CartItem: { fields: { customizations: replaceList } },
31
+ CartItemComposition: { fields: { customizations: replaceList } },
32
+ Shipping: { fields: { savedAddresses: replaceList } },
33
+ Order: { fields: { totals: replaceList } },
34
+ SellerOrder: { fields: { totals: replaceList } },
35
+ OrderItem: { fields: { customizations: replaceList } }
36
+ };
12
37
  /**
13
38
  * The single source of truth for InMemoryCache configuration. Both the
14
39
  * server-side `createClient` and the client-side `StorefrontProvider`
@@ -1 +1 @@
1
- {"version":3,"file":"storefront-cache.js","names":[],"sources":["../../../src/sdk/cache/storefront-cache.ts"],"sourcesContent":["import { InMemoryCache, type InMemoryCacheConfig, type TypePolicies } from '@apollo/client';\nimport { possibleTypes } from '../generated/fragment-types.js';\n\n/**\n * Per-entity normalization and field-merge rules for the Storefront cache.\n *\n * Empty in T1. Domain entries (Product, Cart, OrderForm, …) arrive with the\n * particles that need them — see docs/storefront-core/reference-free-particle-model.md § Typed documents and the shared cache,\n * \"Out of Scope\".\n */\nexport const typePolicies: TypePolicies = {};\n\nexport { possibleTypes };\n\n/**\n * The single source of truth for InMemoryCache configuration. Both the\n * server-side `createClient` and the client-side `StorefrontProvider`\n * consume this so SSR and CSR normalize entities identically.\n */\nexport function getCacheConfig(): InMemoryCacheConfig {\n return {\n typePolicies,\n possibleTypes,\n };\n}\n\n/**\n * The only place an `InMemoryCache` is constructed on the server path.\n * The client-side provider builds its cache from `getCacheConfig()` so the\n * config is shared verbatim without coupling to a specific InMemoryCache\n * subclass (the Next.js integration ships its own SSR-aware variant).\n */\nexport function buildCache(): InMemoryCache {\n return new InMemoryCache(getCacheConfig());\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAa,eAA6B,CAAC;;;;;;AAS3C,SAAgB,iBAAsC;CACpD,OAAO;EACL;EACA;CACF;AACF;;;;;;;AAQA,SAAgB,aAA4B;CAC1C,OAAO,IAAI,cAAc,eAAe,CAAC;AAC3C"}
1
+ {"version":3,"file":"storefront-cache.js","names":[],"sources":["../../../src/sdk/cache/storefront-cache.ts"],"sourcesContent":["import { InMemoryCache, type InMemoryCacheConfig, type TypePolicies } from '@apollo/client';\nimport { possibleTypes } from '../generated/fragment-types.js';\n\n/**\n * Per-entity normalization and field-merge rules for the Storefront cache.\n *\n * The cart and the order share three types whose ids neither can scope\n * (docs/features/order-placed/rfc.md, 3.4): a totalizer's id is its category\n * (\"Items\"), which the cart's totalizer line selects by; an address's id is the\n * saved address itself, masked on the order and not on the cart; and a\n * customization's id is the assembly (\"Engraving\"), which two lines of one cart\n * already share. Normalized, one record would overwrite the other, so each is\n * stored inside the record that holds it, and replaced on every write: safe\n * while every fragment selects the same subfields of each.\n *\n * The lists that hold them are the server's whole answer, so each write\n * replaces the list (`merge: false`). Apollo does the same by default, but warns\n * that data may be lost whenever such a list shrinks, as when a discount line\n * leaves the cart's totalizers; a merge by id would keep that stale line.\n *\n * Other domain entries arrive with the particles that need them — see\n * docs/storefront-core/reference-free-particle-model.md § Typed documents and the shared cache.\n */\nconst replaceList = { merge: false } as const;\n\nexport const typePolicies: TypePolicies = {\n CartTotalizer: { keyFields: false },\n Address: { keyFields: false },\n CartItemCustomization: { keyFields: false },\n Cart: { fields: { totalizers: replaceList } },\n CartItem: { fields: { customizations: replaceList } },\n CartItemComposition: { fields: { customizations: replaceList } },\n Shipping: { fields: { savedAddresses: replaceList } },\n Order: { fields: { totals: replaceList } },\n SellerOrder: { fields: { totals: replaceList } },\n OrderItem: { fields: { customizations: replaceList } },\n};\n\nexport { possibleTypes };\n\n/**\n * The single source of truth for InMemoryCache configuration. Both the\n * server-side `createClient` and the client-side `StorefrontProvider`\n * consume this so SSR and CSR normalize entities identically.\n */\nexport function getCacheConfig(): InMemoryCacheConfig {\n return {\n typePolicies,\n possibleTypes,\n };\n}\n\n/**\n * The only place an `InMemoryCache` is constructed on the server path.\n * The client-side provider builds its cache from `getCacheConfig()` so the\n * config is shared verbatim without coupling to a specific InMemoryCache\n * subclass (the Next.js integration ships its own SSR-aware variant).\n */\nexport function buildCache(): InMemoryCache {\n return new InMemoryCache(getCacheConfig());\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,cAAc,EAAE,OAAO,MAAM;AAEnC,MAAa,eAA6B;CACxC,eAAe,EAAE,WAAW,MAAM;CAClC,SAAS,EAAE,WAAW,MAAM;CAC5B,uBAAuB,EAAE,WAAW,MAAM;CAC1C,MAAM,EAAE,QAAQ,EAAE,YAAY,YAAY,EAAE;CAC5C,UAAU,EAAE,QAAQ,EAAE,gBAAgB,YAAY,EAAE;CACpD,qBAAqB,EAAE,QAAQ,EAAE,gBAAgB,YAAY,EAAE;CAC/D,UAAU,EAAE,QAAQ,EAAE,gBAAgB,YAAY,EAAE;CACpD,OAAO,EAAE,QAAQ,EAAE,QAAQ,YAAY,EAAE;CACzC,aAAa,EAAE,QAAQ,EAAE,QAAQ,YAAY,EAAE;CAC/C,WAAW,EAAE,QAAQ,EAAE,gBAAgB,YAAY,EAAE;AACvD;;;;;;AASA,SAAgB,iBAAsC;CACpD,OAAO;EACL;EACA;CACF;AACF;;;;;;;AAQA,SAAgB,aAA4B;CAC1C,OAAO,IAAI,cAAc,eAAe,CAAC;AAC3C"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { defineActions } from "../../core/dist/actions/registry.js";
3
3
  import "../../core/dist/index.js";
4
+ import { loggableErrorName } from "../../utils/loggable-error-name.js";
4
5
  import { CART_COUPON_APPLY, CART_COUPON_REMOVE, CART_ITEMS_REMOVE, CART_ITEM_ADD, CART_ITEM_QUANTITY_DECREASE, CART_ITEM_QUANTITY_INCREASE, CART_ITEM_REMOVE, CART_VALIDATE, CartFragment } from "./operations.js";
5
6
  import { cartCouponErrorsVar, cartLastAddVar, cartUserErrorsVar, orderFormIdVar } from "../state/cart.js";
6
7
  import { buildOptimisticDecrease, buildOptimisticIncrease, buildOptimisticRemove, buildOptimisticRemoveItems } from "./optimistic.js";
@@ -134,7 +135,7 @@ function useCartActions() {
134
135
  if (errors.length === 0) cartLastAddVar(cartLastAddVar() + 1);
135
136
  return publishWrite(errors);
136
137
  } catch (error) {
137
- console.error("[cart.addItem] cartItemAdd failed", error);
138
+ console.error("[cart.addItem] cartItemAdd failed", loggableErrorName(error));
138
139
  return publish([NETWORK_USER_ERROR]);
139
140
  }
140
141
  }, [addMutation]);
@@ -148,7 +149,7 @@ function useCartActions() {
148
149
  optimisticResponse: buildOptimisticRemove(found.cart, found.line)
149
150
  }))).data?.cartItemRemove?.userErrors ?? []);
150
151
  } catch (error) {
151
- console.error("[cart.removeItem] cartItemRemove failed", error);
152
+ console.error("[cart.removeItem] cartItemRemove failed", loggableErrorName(error));
152
153
  return publish([NETWORK_USER_ERROR]);
153
154
  }
154
155
  }, [requireLine, removeMutation]);
@@ -165,7 +166,7 @@ function useCartActions() {
165
166
  optimisticResponse: buildOptimisticRemoveItems(cart, lines)
166
167
  }))).data?.cartItemsRemove?.userErrors ?? []);
167
168
  } catch (error) {
168
- console.error("[cart.removeItems] cartItemsRemove failed", error);
169
+ console.error("[cart.removeItems] cartItemsRemove failed", loggableErrorName(error));
169
170
  return publish([NETWORK_USER_ERROR]);
170
171
  }
171
172
  }, [readCart, removeItemsMutation]);
@@ -183,7 +184,7 @@ function useCartActions() {
183
184
  optimisticResponse: buildOptimisticIncrease(found.cart, found.line, by)
184
185
  }))).data?.cartItemQuantityIncrease?.userErrors ?? []);
185
186
  } catch (error) {
186
- console.error("[cart.increaseQuantity] cartItemQuantityIncrease failed", error);
187
+ console.error("[cart.increaseQuantity] cartItemQuantityIncrease failed", loggableErrorName(error));
187
188
  return publish([NETWORK_USER_ERROR]);
188
189
  }
189
190
  }, [requireLine, increaseMutation]);
@@ -201,7 +202,7 @@ function useCartActions() {
201
202
  optimisticResponse: buildOptimisticDecrease(found.cart, found.line, by)
202
203
  }))).data?.cartItemQuantityDecrease?.userErrors ?? []);
203
204
  } catch (error) {
204
- console.error("[cart.decreaseQuantity] cartItemQuantityDecrease failed", error);
205
+ console.error("[cart.decreaseQuantity] cartItemQuantityDecrease failed", loggableErrorName(error));
205
206
  return publish([NETWORK_USER_ERROR]);
206
207
  }
207
208
  }, [requireLine, decreaseMutation]);
@@ -212,7 +213,7 @@ function useCartActions() {
212
213
  hydrateCartId(result.data?.cartCouponApply?.cart?.id ?? null);
213
214
  return publishCouponWrite(result.data?.cartCouponApply?.userErrors ?? []);
214
215
  } catch (error) {
215
- console.error("[cart.applyCoupon] cartCouponApply failed", error);
216
+ console.error("[cart.applyCoupon] cartCouponApply failed", loggableErrorName(error));
216
217
  return publishCoupon([NETWORK_USER_ERROR]);
217
218
  }
218
219
  }, [applyCouponMutation]);
@@ -223,7 +224,7 @@ function useCartActions() {
223
224
  hydrateCartId(result.data?.cartCouponRemove?.cart?.id ?? null);
224
225
  return publishCouponWrite(result.data?.cartCouponRemove?.userErrors ?? []);
225
226
  } catch (error) {
226
- console.error("[cart.removeCoupon] cartCouponRemove failed", error);
227
+ console.error("[cart.removeCoupon] cartCouponRemove failed", loggableErrorName(error));
227
228
  return publishCoupon([NETWORK_USER_ERROR]);
228
229
  }
229
230
  }, [removeCouponMutation]);
@@ -235,7 +236,7 @@ function useCartActions() {
235
236
  if (errors.length === 0) markAvailabilityFresh();
236
237
  return errors;
237
238
  } catch (error) {
238
- console.error("[cart.validate] cartValidate failed", error);
239
+ console.error("[cart.validate] cartValidate failed", loggableErrorName(error));
239
240
  return [NETWORK_USER_ERROR];
240
241
  }
241
242
  }, [validateMutation]);