@ecomiq/storefront 2.1.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -103
  3. package/dist/account-Dx4e3syi.js +258 -0
  4. package/dist/account-forms-AVk71ko7.js +39 -0
  5. package/dist/account-forms.d.ts +13 -0
  6. package/dist/account.d.ts +240 -0
  7. package/dist/address-defaults-BqjRhS82.js +14 -0
  8. package/dist/address-defaults.d.ts +11 -0
  9. package/dist/analytics/analytics-CG1Qagwl.js +148 -0
  10. package/dist/analytics/analytics.d.ts +1 -0
  11. package/dist/analytics/config-DJr-GRhs.js +62 -0
  12. package/dist/analytics/config.d.ts +22 -0
  13. package/dist/analytics/consent-B13rBpBs.js +57 -0
  14. package/dist/analytics/consent-banner-9QvRRy8v.js +239 -0
  15. package/dist/analytics/consent-banner.d.ts +20 -0
  16. package/dist/analytics/cookies-pLozllyB.js +100 -0
  17. package/dist/analytics/cookies.d.ts +6 -0
  18. package/dist/analytics/destinations-iECrlLIr.js +144 -0
  19. package/dist/analytics/events-Dt81tIp1.js +102 -0
  20. package/dist/analytics/events.d.ts +51 -0
  21. package/dist/analytics/tracker-p4yaoOyk.js +51 -0
  22. package/dist/api-cache-DsuIn5hX.js +159 -0
  23. package/dist/bank-accounts-DlEczQQ5.js +81 -0
  24. package/dist/bank-accounts.d.ts +4 -0
  25. package/dist/captcha-DAqaIx8m.js +117 -0
  26. package/dist/captcha.d.ts +34 -0
  27. package/dist/cart-D7DxZ2lD.js +30 -0
  28. package/dist/cart-actions-Bsub_FFG.js +116 -0
  29. package/dist/cart-actions.d.ts +15 -0
  30. package/dist/cart-drawer-B7PPsR69.js +22 -0
  31. package/dist/cart-drawer.d.ts +9 -0
  32. package/dist/cart-form-y9P1r_EX.js +81 -0
  33. package/dist/cart-form.d.ts +24 -0
  34. package/dist/cart-summary-ur2VWKr-.js +89 -0
  35. package/dist/cart-summary.d.ts +31 -0
  36. package/dist/cart.d.ts +4 -0
  37. package/dist/catalog-7gJ-l5hW.js +67 -0
  38. package/dist/catalog-hooks-B7ZP4wYY.js +312 -0
  39. package/dist/catalog-hooks.d.ts +111 -0
  40. package/dist/catalog.d.ts +5 -0
  41. package/dist/checkout-DVWSXANi.js +474 -0
  42. package/dist/checkout-form-CbOIdENC.js +131 -0
  43. package/dist/checkout-form.d.ts +20 -0
  44. package/dist/checkout.d.ts +86 -0
  45. package/dist/complaint-book-BvwLvfx0.js +117 -0
  46. package/dist/complaint-book.d.ts +62 -0
  47. package/dist/culqi-authentication-BGr20vAJ.js +204 -0
  48. package/dist/culqi-authentication.d.ts +15 -0
  49. package/dist/culqi-checkout-CTXpKgp_.js +55 -0
  50. package/dist/culqi-three-ds-HP3mfrvV.js +33 -0
  51. package/dist/culqi-three-ds.d.ts +29 -0
  52. package/dist/customer-avatar-CJXSDroK.js +12 -0
  53. package/dist/customer-avatar.d.ts +5 -0
  54. package/dist/customer-cookies-DHOgFAMV.js +45 -0
  55. package/dist/customer-csrf-C1oDX-Py.js +17 -0
  56. package/dist/customer-csrf.d.ts +3 -0
  57. package/dist/customer-document-fields-C1K-_DAD.js +70 -0
  58. package/dist/customer-document-fields.d.ts +9 -0
  59. package/dist/customer-login-form-C7AC6vXd.js +144 -0
  60. package/dist/customer-login-form.d.ts +17 -0
  61. package/dist/customer-registration-form-BEm_NEfP.js +93 -0
  62. package/dist/customer-registration-form.d.ts +8 -0
  63. package/dist/document-url-CGsAl5Tf.js +9 -0
  64. package/dist/documents-T1mzc_j8.js +38 -0
  65. package/dist/documents.d.ts +16 -0
  66. package/dist/entries/account.d.ts +11 -0
  67. package/dist/entries/account.js +10 -0
  68. package/dist/entries/analytics.d.ts +6 -0
  69. package/dist/entries/analytics.js +5 -0
  70. package/dist/entries/cart.d.ts +8 -0
  71. package/dist/entries/cart.js +7 -0
  72. package/dist/entries/checkout.d.ts +12 -0
  73. package/dist/entries/checkout.js +11 -0
  74. package/dist/entries/order.d.ts +11 -0
  75. package/dist/entries/order.js +11 -0
  76. package/dist/favicon-YpyhVJ9H.js +28 -0
  77. package/dist/favicon.d.ts +4 -0
  78. package/dist/form-BtQcbXlJ.js +18 -0
  79. package/dist/form-contracts-BNpHaTGJ.js +166 -0
  80. package/dist/form-contracts.d.ts +42 -0
  81. package/dist/form.d.ts +3 -0
  82. package/dist/hidden-CCWtOWKR.js +3 -0
  83. package/dist/hidden.d.ts +4 -0
  84. package/dist/index.d.ts +50 -0
  85. package/dist/index.js +50 -0
  86. package/dist/invoice-fields-BG0HjL6T.js +103 -0
  87. package/dist/invoice-fields.d.ts +39 -0
  88. package/dist/links-kFxBZfdb.js +96 -0
  89. package/dist/links.d.ts +21 -0
  90. package/dist/mercadopago-checkout-DC7RXa8k.js +27 -0
  91. package/dist/mercadopago-dialog-UTQev0MG.js +180 -0
  92. package/dist/mercadopago-dialog.d.ts +21 -0
  93. package/dist/money-DtGOtDri.js +32 -0
  94. package/dist/money.d.ts +1 -0
  95. package/dist/optimistic-cart-BveVOHuh.js +53 -0
  96. package/dist/optimistic-cart.d.ts +16 -0
  97. package/dist/order-display-DTt5WBbc.js +112 -0
  98. package/dist/order-display.d.ts +20 -0
  99. package/dist/order-draft-DxV1Uhm3.js +38 -0
  100. package/dist/order-draft.d.ts +16 -0
  101. package/dist/order-pages-Dm6l5m0m.js +38 -0
  102. package/dist/order-pages.d.ts +12 -0
  103. package/dist/order-payment-continuation-D_d5PGA4.js +212 -0
  104. package/dist/order-payment-continuation.d.ts +10 -0
  105. package/dist/order-payment-in-review-x4gdLFHZ.js +65 -0
  106. package/dist/order-payment-in-review.d.ts +5 -0
  107. package/dist/order-status-BJXLJwxq.js +162 -0
  108. package/dist/order-status.d.ts +89 -0
  109. package/dist/order-view-9IlBg5AF.js +62 -0
  110. package/dist/order-view.d.ts +12 -0
  111. package/dist/page-action-Ctkf4xC6.js +7 -0
  112. package/dist/page-seo-a5FJl8x5.js +262 -0
  113. package/dist/page-seo.d.ts +34 -0
  114. package/dist/pages-Ca_Gt6mq.js +150 -0
  115. package/dist/pages.d.ts +45 -0
  116. package/dist/payment-dialog-frame-B-Q_xQ94.js +57 -0
  117. package/dist/payment-logo-BoPaGJc_.js +46 -0
  118. package/dist/payment-logo-svgs-By9lDTLK.js +20 -0
  119. package/dist/payment-logo.d.ts +11 -0
  120. package/dist/payment-logos-BYvdwYyJ.js +23 -0
  121. package/dist/payment-methods-B8ocTgFZ.js +73 -0
  122. package/dist/payment-methods.d.ts +58 -0
  123. package/dist/payment-return-5cjypwIw.js +7 -0
  124. package/dist/place-CmW4hBWY.js +13 -0
  125. package/dist/place.d.ts +4 -0
  126. package/dist/preview-BiIBif3C.js +427 -0
  127. package/dist/preview-address-Cf0sJ-9p.js +21 -0
  128. package/dist/preview-cart-Dg2CVktS.js +376 -0
  129. package/dist/product-preview-BspMAecJ.js +51 -0
  130. package/dist/product-preview.d.ts +5 -0
  131. package/dist/product-variants-BNDHvs1y.js +46 -0
  132. package/dist/product-variants.d.ts +12 -0
  133. package/dist/public-pages-XtwlaLwt.js +194 -0
  134. package/dist/public-pages.d.ts +67 -0
  135. package/dist/registration-CpDcv8ql.js +91 -0
  136. package/dist/registration.d.ts +12 -0
  137. package/dist/request-security-CRsRMgwj.js +76 -0
  138. package/dist/rich-text-M-Ju8RL4.js +9 -0
  139. package/dist/rich-text.d.ts +5 -0
  140. package/dist/route-text-DcJw2SsK.js +9 -0
  141. package/dist/route-text.d.ts +4 -0
  142. package/dist/section-preview-CmsMl3yu.js +83 -0
  143. package/dist/section-preview.d.ts +12 -0
  144. package/dist/sections/account-addresses.d.ts +18 -0
  145. package/dist/sections/account-addresses.js +375 -0
  146. package/dist/sections/account-order.d.ts +12 -0
  147. package/dist/sections/account-order.js +592 -0
  148. package/dist/sections/account-orders.d.ts +8 -0
  149. package/dist/sections/account-orders.js +359 -0
  150. package/dist/sections/account-profile.d.ts +16 -0
  151. package/dist/sections/account-profile.js +123 -0
  152. package/dist/sections/checkout.d.ts +24 -0
  153. package/dist/sections/checkout.js +963 -0
  154. package/dist/sections/complaint-book.d.ts +8 -0
  155. package/dist/sections/complaint-book.js +538 -0
  156. package/dist/sections/design-system.d.ts +1 -0
  157. package/dist/sections/design-system.js +310 -0
  158. package/dist/sections/draft-invoice.d.ts +20 -0
  159. package/dist/sections/draft-invoice.js +158 -0
  160. package/dist/sections/order-tracking.d.ts +19 -0
  161. package/dist/sections/order-tracking.js +141 -0
  162. package/dist/sections-CNUMWTF_.js +77 -0
  163. package/dist/sections.d.ts +19 -0
  164. package/dist/seo-GpDRhAAA.js +78 -0
  165. package/dist/session-CKvmFJyg.js +379 -0
  166. package/dist/session.d.ts +24 -0
  167. package/dist/settings-B0NO2A6Y.js +78 -0
  168. package/dist/settings.d.ts +51 -0
  169. package/dist/source-marker-DhqSkW7n.js +4 -0
  170. package/dist/sources-B-3JFJfb.js +46 -0
  171. package/dist/sources.d.ts +7 -0
  172. package/dist/store-8Q-_LFrQ.js +152 -0
  173. package/dist/store-contact--hY6CoFb.js +19 -0
  174. package/dist/store-contact.d.ts +6 -0
  175. package/dist/store.d.ts +17 -0
  176. package/dist/storefront-language-DrMjVbmk.js +29 -0
  177. package/dist/storefront-language.d.ts +14 -0
  178. package/dist/storefront-text-D25ae1qf.js +11 -0
  179. package/dist/storefront-text-en-ljjjSS4q.js +1030 -0
  180. package/dist/storefront-text-pt-BtHaJLcp.js +1030 -0
  181. package/dist/storefront-text.d.ts +4 -0
  182. package/dist/stripe-dialog-Ev9s3Z62.js +396 -0
  183. package/dist/stripe-dialog.d.ts +30 -0
  184. package/dist/telemetry-HuZXWBPi.js +114 -0
  185. package/dist/telemetry.d.ts +10 -0
  186. package/dist/templates-CAqoNyTW.js +40 -0
  187. package/dist/templates.d.ts +15 -0
  188. package/dist/urls-CpGQPxvf.js +71 -0
  189. package/dist/urls.d.ts +18 -0
  190. package/dist/use-checkout-CZcxXJXi.js +42 -0
  191. package/dist/use-checkout-payment-9R-zacrJ.js +80 -0
  192. package/dist/use-checkout-payment.d.ts +18 -0
  193. package/dist/use-checkout.d.ts +36 -0
  194. package/dist/use-culqi-checkout-CrjLAipU.js +109 -0
  195. package/dist/use-order-payment-BKIz_IO0.js +45 -0
  196. package/dist/use-order-payment.d.ts +18 -0
  197. package/dist/use-payment-token-CErx-tN-.js +105 -0
  198. package/dist/vite-payment-logos-kziu7wKb.js +27 -0
  199. package/dist/vite-payment-logos.d.ts +24 -0
  200. package/dist/vite-public-assets-DW2fgtVb.js +209 -0
  201. package/dist/vite-public-assets.d.ts +29 -0
  202. package/dist/vite-sections-DTBr0-Kg.js +464 -0
  203. package/dist/vite-sections.d.ts +21 -0
  204. package/dist/vite-theme-ui-BMO-CDi3.js +41 -0
  205. package/dist/vite-theme-ui.d.ts +10 -0
  206. package/dist/vite.d.ts +36 -0
  207. package/dist/vite.js +127 -0
  208. package/dist/voucher-payment-CVFDZ1L8.js +66 -0
  209. package/dist/worker-CNi-gzCu.js +86 -0
  210. package/dist/worker.d.ts +27 -0
  211. package/package.json +100 -76
  212. package/src/sections/account-addresses.tsx +215 -0
  213. package/src/sections/account-order.tsx +424 -0
  214. package/src/sections/account-orders.tsx +259 -0
  215. package/src/sections/account-profile.tsx +70 -0
  216. package/src/sections/checkout.tsx +586 -0
  217. package/src/sections/complaint-book.tsx +325 -0
  218. package/src/sections/design-system.tsx +146 -0
  219. package/src/sections/draft-invoice.tsx +105 -0
  220. package/src/sections/order-tracking.tsx +81 -0
  221. package/src/vite-client.d.ts +4 -0
  222. package/bin/ecomiq.mjs +0 -179
  223. package/public/design-bridge.js +0 -318
  224. package/src/api-proxy.ts +0 -194
  225. package/src/auth/create-storefront-auth.ts +0 -94
  226. package/src/auth/ecomiq-oauth-password-client.ts +0 -26
  227. package/src/auth/ecomiq-oauth-password-constants.ts +0 -24
  228. package/src/auth/ecomiq-oauth-password-plugin.ts +0 -294
  229. package/src/auth/ecomiq-oauth-password-types.ts +0 -24
  230. package/src/auth/ecomiq-storefront-sign-in.ts +0 -44
  231. package/src/auth/env.ts +0 -7
  232. package/src/auth/secure-cookies.ts +0 -23
  233. package/src/auth/storefront-auth-base-url.ts +0 -117
  234. package/src/auth/storefront-auth.ts +0 -7
  235. package/src/cart-session.ts +0 -239
  236. package/src/client.ts +0 -48
  237. package/src/codegen.mjs +0 -801
  238. package/src/components/account/customer-addresses-panel.tsx +0 -678
  239. package/src/components/account/customer-order-detail-panel.tsx +0 -285
  240. package/src/components/account/customer-orders-panel.tsx +0 -192
  241. package/src/components/account/customer-profile-panel.tsx +0 -379
  242. package/src/components/checkout/cart-sync.ts +0 -143
  243. package/src/components/checkout/checkout-contact-section.tsx +0 -76
  244. package/src/components/checkout/checkout-external-update-banner.tsx +0 -15
  245. package/src/components/checkout/checkout-form-controls.tsx +0 -139
  246. package/src/components/checkout/checkout-line-items.tsx +0 -43
  247. package/src/components/checkout/checkout-order-summary.tsx +0 -165
  248. package/src/components/checkout/checkout-payment-section.tsx +0 -212
  249. package/src/components/checkout/checkout-session-view.tsx +0 -564
  250. package/src/components/checkout/checkout-shipping-address-section.tsx +0 -400
  251. package/src/components/checkout/checkout-shipping-section.tsx +0 -98
  252. package/src/components/checkout/checkout-states.tsx +0 -73
  253. package/src/components/checkout/checkout-step-card.tsx +0 -101
  254. package/src/components/checkout/checkout-steps.ts +0 -111
  255. package/src/components/checkout/form-schema.ts +0 -281
  256. package/src/components/checkout/format.ts +0 -15
  257. package/src/components/checkout/index.ts +0 -5
  258. package/src/components/checkout/map-customer-to-checkout.ts +0 -188
  259. package/src/components/checkout/types.ts +0 -41
  260. package/src/components/checkout/use-checkout-customer-prefill.ts +0 -409
  261. package/src/components/checkout/use-checkout-geo.ts +0 -50
  262. package/src/components/checkout/use-checkout-session.ts +0 -640
  263. package/src/components/hero.tsx +0 -291
  264. package/src/config.d.ts +0 -94
  265. package/src/config.mjs +0 -146
  266. package/src/format-money.ts +0 -31
  267. package/src/health.ts +0 -90
  268. package/src/hooks/index.ts +0 -9
  269. package/src/hooks/recently-viewed.ts +0 -125
  270. package/src/index.ts +0 -349
  271. package/src/link.tsx +0 -2
  272. package/src/pages/account/account-page-skeleton.tsx +0 -69
  273. package/src/pages/account/account-page-view.tsx +0 -270
  274. package/src/pages/account/account-shell.tsx +0 -101
  275. package/src/pages/account/parse-account-route.ts +0 -36
  276. package/src/pages/account.tsx +0 -16
  277. package/src/pages/api.$.ts +0 -20
  278. package/src/pages/api.auth.$.ts +0 -16
  279. package/src/pages/checkout.$checkoutId.tsx +0 -60
  280. package/src/pages/checkout.tsx +0 -31
  281. package/src/pages/pages.$pageSlug.tsx +0 -74
  282. package/src/pages/thank-you.tsx +0 -53
  283. package/src/providers/auth.tsx +0 -96
  284. package/src/providers/cart.tsx +0 -275
  285. package/src/providers/ecomiq.ts +0 -137
  286. package/src/providers/index.ts +0 -26
  287. package/src/proxy-api.ts +0 -20
  288. package/src/public-config.ts +0 -24
  289. package/src/review-submission.ts +0 -89
  290. package/src/runtime/context.ts +0 -2
  291. package/src/runtime/default-layout.tsx +0 -64
  292. package/src/runtime/head.ts +0 -149
  293. package/src/runtime/page.tsx +0 -143
  294. package/src/runtime/postcss-browser-stub.mjs +0 -5
  295. package/src/server-config-store.ts +0 -35
  296. package/src/server.ts +0 -286
  297. package/src/styles.css +0 -76
  298. package/src/ui/badge.tsx +0 -32
  299. package/src/ui/button.tsx +0 -31
  300. package/src/ui/card.tsx +0 -31
  301. package/src/ui/carousel.tsx +0 -218
  302. package/src/ui/cn.ts +0 -6
  303. package/src/ui/index.ts +0 -8
  304. package/src/ui/separator.tsx +0 -6
  305. package/src/ui/skeleton.tsx +0 -6
  306. package/src/ui/storefront-error.tsx +0 -49
  307. package/src/utils.ts +0 -36
  308. package/src/vite-inline.mjs +0 -263
  309. package/templates/__root.tsx +0 -83
  310. package/templates/router.tsx +0 -19
@@ -0,0 +1,111 @@
1
+ import { GeoPlace } from "./public-pages.js";
2
+ import { SearchFilter } from "@ecomiq/core";
3
+ export declare const SORT_OPTIONS: readonly [{
4
+ readonly value: "relevance";
5
+ readonly label: "Relevancia";
6
+ }, {
7
+ readonly value: "newest";
8
+ readonly label: "Más nuevos";
9
+ }, {
10
+ readonly value: "price_asc";
11
+ readonly label: "Precio: menor a mayor";
12
+ }, {
13
+ readonly value: "price_desc";
14
+ readonly label: "Precio: mayor a menor";
15
+ }, {
16
+ readonly value: "name_asc";
17
+ readonly label: "Nombre: A–Z";
18
+ }];
19
+ export type PageItem = number | "gap";
20
+ export type SortValue = (typeof SORT_OPTIONS)[number]["value"];
21
+ export type SortLabels = Partial<Record<SortValue, string>>;
22
+ export type FilterLabels = {
23
+ filters?: Map<string, string>;
24
+ values?: Map<string, string>;
25
+ };
26
+ type FilterTranslate = (source: string, values?: Readonly<Record<string, string>>) => string;
27
+ export type FilterChipText = {
28
+ labels?: FilterLabels;
29
+ price?: (amount: string) => string;
30
+ translate?: FilterTranslate;
31
+ };
32
+ export declare function filterLabel(filter: SearchFilter, labels?: FilterLabels, translate?: FilterTranslate): string;
33
+ export declare function filterValueLabel(value: string, label: string | null | undefined, labels?: FilterLabels, translate?: FilterTranslate): string;
34
+ export declare function isSingleChoiceFilter(filter: SearchFilter): boolean;
35
+ export declare function selectedFacetCount(filters: SearchFilter[]): number;
36
+ export declare function activeFilterCount(filters: SearchFilter[], params: URLSearchParams): number;
37
+ export declare function clearedFiltersHref(params: URLSearchParams): string;
38
+ export type ActiveFilterChip = {
39
+ key: string;
40
+ value: string;
41
+ text: string;
42
+ href: string;
43
+ };
44
+ export declare function activeFilterChips(filters: SearchFilter[], params: URLSearchParams, text?: FilterChipText): ActiveFilterChip[];
45
+ export declare function pageItems(page: number, pages: number): PageItem[];
46
+ export declare function useFacets(): {
47
+ params: URLSearchParams;
48
+ navigate: (change: (next: URLSearchParams) => void) => void;
49
+ toggle: (filterId: string, value: string, checked: boolean) => void;
50
+ choose: (filterId: string, value: string) => void;
51
+ setPrice: (from: number | undefined, to: number | undefined, low: number, high: number) => void;
52
+ clearedHref: string;
53
+ };
54
+ export declare function useSort(labels?: SortLabels): {
55
+ value: string;
56
+ label: string;
57
+ options: {
58
+ value: "name_asc" | "newest" | "price_asc" | "price_desc" | "relevance";
59
+ label: string;
60
+ }[];
61
+ change: (next: string) => void;
62
+ };
63
+ export declare function usePagination(page: number, pages: number): {
64
+ items: PageItem[];
65
+ href: (target: number) => string;
66
+ hasPrevious: boolean;
67
+ hasNext: boolean;
68
+ };
69
+ export declare function useSearchSuggestions(initial?: string): {
70
+ q: string;
71
+ setQ: import("react").Dispatch<import("react").SetStateAction<string>>;
72
+ trimmed: string;
73
+ searching: boolean;
74
+ products: never[] | {
75
+ id: string;
76
+ name: string;
77
+ slug: string;
78
+ url: string;
79
+ imageUrl: string;
80
+ }[];
81
+ missing: boolean;
82
+ loading: boolean;
83
+ loaded: boolean;
84
+ current: boolean;
85
+ };
86
+ export declare function placeValue(place: GeoPlace | null): string;
87
+ export declare function useGeoCascade(defaults: {
88
+ country?: string | null;
89
+ department?: string | null;
90
+ province?: string | null;
91
+ district?: string | null;
92
+ }): {
93
+ country: string;
94
+ setCountry: (next: string) => void;
95
+ department: GeoPlace | null;
96
+ setDepartment: (next: GeoPlace | null) => void;
97
+ province: GeoPlace | null;
98
+ setProvince: (next: GeoPlace | null) => void;
99
+ district: GeoPlace | null;
100
+ setDistrict: import("react").Dispatch<import("react").SetStateAction<GeoPlace | null>>;
101
+ setDepartmentValue: (value: string) => void;
102
+ setProvinceValue: (value: string) => void;
103
+ setDistrictValue: (value: string) => void;
104
+ places: {
105
+ departments: GeoPlace[];
106
+ provinces: GeoPlace[];
107
+ districts: GeoPlace[];
108
+ };
109
+ structured: boolean;
110
+ };
111
+ export {};
@@ -0,0 +1,5 @@
1
+ import { ShouldRevalidateFunctionArgs } from "react-router";
2
+ import { ProductsParamsInput } from "@ecomiq/core";
3
+ /** Menus, customer and cart data do not depend on filters in the current catalog. */
4
+ export declare function shouldRevalidateCatalogRoot(args: ShouldRevalidateFunctionArgs): boolean;
5
+ export declare function readCatalog(url: URL, base?: ProductsParamsInput): ProductsParamsInput;
@@ -0,0 +1,474 @@
1
+ import { addressDefaults } from "./address-defaults-BqjRhS82.js";
2
+ import { trackingConsented } from "./analytics/config-DJr-GRhs.js";
3
+ import { purchaseCookie } from "./analytics/cookies-pLozllyB.js";
4
+ import { checkoutAnalytics } from "./analytics/events-Dt81tIp1.js";
5
+ import { cartCookie, cartToken } from "./cart-D7DxZ2lD.js";
6
+ import { optional, text } from "./form-BtQcbXlJ.js";
7
+ import { identityDocumentError, isIdentityDocumentType } from "./documents-T1mzc_j8.js";
8
+ import { CHECKOUT_INTENTS, isIntent } from "./form-contracts-BNpHaTGJ.js";
9
+ import { readPlace } from "./place-CmW4hBWY.js";
10
+ import { customer, customerHeaders, requireCustomerRegistration } from "./session-CKvmFJyg.js";
11
+ import { readCountries, readDocumentCountries, store } from "./store-8Q-_LFrQ.js";
12
+ import { data, redirect, replace } from "react-router";
13
+ import { ApiError, OrderPaymentStartSchema, StorefrontInvoiceTypeSchema } from "@ecomiq/core";
14
+ import { z } from "zod";
15
+ // src/checkout.ts
16
+ const UNSTRUCTURED_POSTAL_CODE = "00000";
17
+ const CheckoutAuthenticationSchema = z.object({ authentication: z.object({
18
+ payment: OrderPaymentStartSchema,
19
+ orderStatusUrl: z.string()
20
+ }) });
21
+ function shouldRevalidateCheckout({ actionResult, defaultShouldRevalidate }) {
22
+ const result = CheckoutAuthenticationSchema.safeParse(actionResult);
23
+ if (!result.success) return defaultShouldRevalidate;
24
+ const payment = result.data.authentication.payment;
25
+ if (payment.actionKind === "threeDS") return false;
26
+ if (payment.actionKind === "embedded" && payment.providerId === "stripe") return false;
27
+ return defaultShouldRevalidate;
28
+ }
29
+ function needsShipping(cart) {
30
+ return cart.items.some((item) => item.requiresShipping);
31
+ }
32
+ function checkoutProgress(cart) {
33
+ const contact = [
34
+ cart.email,
35
+ cart.firstName,
36
+ cart.lastName,
37
+ cart.phone
38
+ ].every((value) => value !== null && value !== "");
39
+ const delivery = contact && (!needsShipping(cart) || cart.shippingAddress !== null);
40
+ return {
41
+ contact,
42
+ delivery,
43
+ shipping: delivery && (!needsShipping(cart) || cart.shippingMethods.length > 0)
44
+ };
45
+ }
46
+ function checkoutStep(cart, edit) {
47
+ const done = checkoutProgress(cart);
48
+ if (edit === "contact" || !done.contact) return "contact";
49
+ if (edit === "delivery" || !done.delivery) return "delivery";
50
+ if (edit === "shipping" || !done.shipping) return "shipping";
51
+ return "payment";
52
+ }
53
+ function checkoutAddressDefaults(cart, address, countryCode) {
54
+ const saved = cart.shippingAddress;
55
+ if (saved) return {
56
+ country: countryCode,
57
+ department: saved.department,
58
+ province: saved.province,
59
+ district: saved.district,
60
+ line: saved.address1,
61
+ reference: saved.address2,
62
+ phone: saved.phone
63
+ };
64
+ if (address) return {
65
+ ...addressDefaults(address),
66
+ country: countryCode
67
+ };
68
+ return {
69
+ country: countryCode,
70
+ phone: cart.phone
71
+ };
72
+ }
73
+ function defaultPaymentMethod(cart, methods) {
74
+ return (methods.find((method) => method.code === cart.paymentMethodCode) ?? methods.find((method) => method.isDefault) ?? methods[0])?.code;
75
+ }
76
+ function shippingField(group) {
77
+ return `rate-${group.sellerId ?? "store"}-${group.shippingProfileId ?? "default"}`;
78
+ }
79
+ function rateValue(rate) {
80
+ if (rate.rateId) return rate.rateId;
81
+ return [
82
+ rate.shippingMethodId,
83
+ rate.target,
84
+ rate.targetId ?? "",
85
+ rate.serviceCode ?? ""
86
+ ].join(":");
87
+ }
88
+ function checkoutShipping(groups) {
89
+ return groups.map((group) => ({
90
+ ...group,
91
+ field: shippingField(group),
92
+ rates: group.rates.map((rate) => ({
93
+ ...rate,
94
+ value: rateValue(rate)
95
+ }))
96
+ }));
97
+ }
98
+ async function shippingOptions(client, cart) {
99
+ const postalCode = cart.shippingAddress?.postalCode;
100
+ if (!needsShipping(cart) || !postalCode) return [];
101
+ const options = await client.getShippingOptions({
102
+ cartToken: cart.token,
103
+ postalCode
104
+ });
105
+ if (options.groups.some((group) => group.rates.length === 0)) return [];
106
+ return options.groups;
107
+ }
108
+ async function loadCheckout(request, context) {
109
+ const token = await cartToken(request);
110
+ if (token === null) throw redirect("/cart");
111
+ const client = store(context);
112
+ const checkout = await client.getCartCheckout({ cartToken: token }).catch(async (error) => {
113
+ if (error instanceof ApiError && (error.status === 404 || error.code === "Carts.NotActive")) throw redirect("/cart", { headers: { "Set-Cookie": await cartCookie.serialize("", { maxAge: 0 }) } });
114
+ throw error;
115
+ });
116
+ if (checkout.cart.items.length === 0) throw redirect("/cart");
117
+ const { store: settings } = await client.getSettings();
118
+ const current = await customer(request, context);
119
+ if (current) await requireCustomerRegistration(request, context, current);
120
+ const step = checkoutStep(checkout.cart, new URL(request.url).searchParams.get("edit"));
121
+ const delivery = needsShipping(checkout.cart);
122
+ const placed = delivery && checkout.cart.shippingAddress !== null;
123
+ const [me, addresses, countries, shipping, documentCountries] = await Promise.all([
124
+ current && step === "contact" ? client.getCustomerMe(customerHeaders(current)) : null,
125
+ current && delivery && !placed ? client.getCustomerAddresses(customerHeaders(current)) : [],
126
+ delivery ? readCountries(client) : [],
127
+ placed ? shippingOptions(client, checkout.cart) : [],
128
+ readDocumentCountries(client)
129
+ ]);
130
+ const methods = checkout.paymentMethods.methods.filter((method) => method.isActive).sort((a, b) => a.sortOrder - b.sortOrder);
131
+ return {
132
+ countryCode: settings.countryCode,
133
+ documentCountries,
134
+ language: settings.language,
135
+ cart: checkout.cart,
136
+ methods,
137
+ bumps: checkout.orderBumps,
138
+ signedIn: current !== null,
139
+ me,
140
+ address: addresses.find((item) => item.isDefault) ?? addresses[0] ?? null,
141
+ countries,
142
+ shipping: checkoutShipping(shipping),
143
+ analytics: checkoutAnalytics(checkout.cart)
144
+ };
145
+ }
146
+ function failure(message) {
147
+ return data({
148
+ error: message,
149
+ promo: false
150
+ }, { status: 400 });
151
+ }
152
+ async function saveContact(client, token, form) {
153
+ let invoiceType;
154
+ if (form.has("invoiceType")) {
155
+ const selected = StorefrontInvoiceTypeSchema.safeParse(text(form, "invoiceType"));
156
+ if (!selected.success) return failure("Elige el comprobante.");
157
+ invoiceType = selected.data;
158
+ }
159
+ const identificationNumber = optional(form, "identificationNumber");
160
+ const entityTaxId = optional(form, "entityTaxId");
161
+ const input = {
162
+ cartToken: token,
163
+ email: text(form, "email"),
164
+ firstName: text(form, "firstName"),
165
+ lastName: text(form, "lastName"),
166
+ phone: text(form, "phone"),
167
+ identificationType: identificationNumber === null ? null : optional(form, "identificationType"),
168
+ identificationNumber,
169
+ identificationCountryCode: identificationNumber !== null || entityTaxId !== null || invoiceType === "invoice" ? optional(form, "identificationCountryCode") : null,
170
+ entityTaxId,
171
+ entityName: optional(form, "entityName"),
172
+ invoiceType
173
+ };
174
+ if (!input.email || !input.firstName || !input.lastName || !input.phone) return failure("Completa tus datos de contacto.");
175
+ if (invoiceType === "invoice" && (input.entityTaxId === null || identityDocumentError("TaxId", input.identificationCountryCode ?? "", input.entityTaxId) !== null || input.entityName === null)) return failure("Ingresa la identificación fiscal, el país emisor y la razón social para la factura.");
176
+ if (entityTaxId !== null && identityDocumentError("TaxId", input.identificationCountryCode ?? "", entityTaxId) !== null) return failure("Revisa el documento del comprador.");
177
+ if (identificationNumber !== null && !(isIdentityDocumentType(input.identificationType) && identityDocumentError(input.identificationType, input.identificationCountryCode ?? "", identificationNumber) === null)) return failure("Revisa el documento del comprador.");
178
+ await client.patchCartBuyer(input);
179
+ return redirect("/checkout");
180
+ }
181
+ async function saveDelivery(client, token, form) {
182
+ const { store: settings } = await client.getSettings();
183
+ const requestedCountry = text(form, "country");
184
+ if (requestedCountry !== "" && requestedCountry !== settings.countryCode) return failure("La entrega debe ser dentro del país de la tienda.");
185
+ const cart = await client.getCart({ cartToken: token });
186
+ const department = readPlace(text(form, "department"));
187
+ const province = readPlace(text(form, "province"));
188
+ const district = readPlace(text(form, "district"));
189
+ const line = text(form, "line");
190
+ if (!line || !district.name) return failure("Completa la dirección de entrega.");
191
+ const structured = department.code !== "" && province.code !== "";
192
+ let city = district.name;
193
+ let postalCode = optional(form, "postalCode") ?? UNSTRUCTURED_POSTAL_CODE;
194
+ if (structured) {
195
+ city = province.name;
196
+ postalCode = optional(form, "postalCode") ?? district.code;
197
+ }
198
+ const address = {
199
+ name: `${cart.firstName ?? ""} ${cart.lastName ?? ""}`.trim() || line,
200
+ address1: line,
201
+ address2: optional(form, "reference"),
202
+ city,
203
+ countryCode: settings.countryCode,
204
+ department: department.name || null,
205
+ province: structured ? province.name : null,
206
+ district: district.name,
207
+ postalCode,
208
+ phone: optional(form, "phone") ?? cart.phone,
209
+ latitude: null,
210
+ longitude: null
211
+ };
212
+ await client.patchCartAddresses({
213
+ cartToken: token,
214
+ shippingAddress: {
215
+ ...address,
216
+ departmentCode: structured ? department.code : null,
217
+ provinceCode: structured ? province.code : null,
218
+ districtCode: structured ? district.code : null
219
+ },
220
+ billingAddress: address
221
+ });
222
+ return redirect("/checkout");
223
+ }
224
+ async function saveShipping(client, token, form) {
225
+ const postalCode = (await client.getCart({ cartToken: token })).shippingAddress?.postalCode;
226
+ if (!postalCode) return failure("Primero indica la dirección de entrega.");
227
+ const { groups } = await client.getShippingOptions({
228
+ cartToken: token,
229
+ postalCode
230
+ });
231
+ if (groups.length === 0 || groups.some((group) => group.rates.length === 0)) return failure("No hay métodos de envío para esta dirección. Prueba con otra dirección.");
232
+ const choices = groups.map((group) => ({
233
+ group,
234
+ rate: group.rates.find((candidate) => rateValue(candidate) === text(form, shippingField(group)))
235
+ }));
236
+ if (choices.some((choice) => choice.rate === void 0)) return failure("Las opciones de envío cambiaron. Elige un método para cada paquete.");
237
+ for (const { group, rate } of choices) {
238
+ if (rate === void 0) continue;
239
+ await client.putCartShippingMethod({
240
+ cartToken: token,
241
+ rateId: rate.rateId ?? null,
242
+ shippingMethodId: rate.shippingMethodId,
243
+ target: rate.target,
244
+ targetId: rate.targetId ?? null,
245
+ serviceCode: rate.serviceCode ?? null,
246
+ sellerId: group.sellerId ?? null,
247
+ shippingProfileId: group.shippingProfileId ?? null,
248
+ scheduledDate: null,
249
+ scheduledTime: null
250
+ });
251
+ }
252
+ return redirect("/checkout");
253
+ }
254
+ async function savePaymentMethod(client, token, form) {
255
+ const method = text(form, "method");
256
+ if (!method) return failure("Elige un medio de pago.");
257
+ await client.putCartPaymentMethod({
258
+ cartToken: token,
259
+ paymentMethodCode: method
260
+ });
261
+ return replace("/checkout");
262
+ }
263
+ async function placeOrder(client, input, headers) {
264
+ try {
265
+ return await client.checkoutCart(input, headers);
266
+ } catch (error) {
267
+ if (error instanceof ApiError && error.status >= 400 && error.status < 500) throw error;
268
+ if ((await client.getCart({ cartToken: input.cartToken }).catch(() => null))?.status !== "completed") throw error;
269
+ return client.checkoutCart(input, headers);
270
+ }
271
+ }
272
+ async function pay(client, token, form, headers, tracked) {
273
+ const method = text(form, "method");
274
+ if (!method) return failure("Elige un medio de pago.");
275
+ if (method === "powerpay") {
276
+ const identificationNumber = text(form, "payerIdentificationNumber");
277
+ if (!/^\d{8}$/.test(identificationNumber)) return failure("Ingresa tu DNI de 8 dígitos para pagar con PowerPay.");
278
+ const cart = await client.getCart({ cartToken: token });
279
+ const matchingDocument = cart.identificationType === "NationalId" && cart.identificationCountryCode === "PE" && cart.identificationNumber === identificationNumber;
280
+ if ((cart.identificationType != null || cart.identificationNumber != null) && !matchingDocument || (cart.identificationCountryCode != null || cart.entityTaxId != null) && cart.identificationCountryCode !== "PE") return failure("PowerPay requiere un comprador con DNI peruano. Revisa tus datos o elige otro medio de pago.");
281
+ if (!matchingDocument) {
282
+ if (!cart.email || !cart.firstName || !cart.lastName || !cart.phone) return failure("Completa tus datos de contacto.");
283
+ await client.patchCartBuyer({
284
+ cartToken: token,
285
+ email: cart.email,
286
+ firstName: cart.firstName,
287
+ lastName: cart.lastName,
288
+ phone: cart.phone,
289
+ identificationType: "NationalId",
290
+ identificationCountryCode: "PE",
291
+ identificationNumber,
292
+ invoiceType: cart.invoiceType,
293
+ entityTaxId: cart.entityTaxId,
294
+ entityName: cart.entityName
295
+ });
296
+ }
297
+ }
298
+ const receipt = form.get("receipt");
299
+ let receiptUrl;
300
+ if (receipt instanceof File && receipt.size > 0) receiptUrl = (await client.uploadPaymentReceipt({
301
+ cartToken: token,
302
+ file: receipt,
303
+ fileName: receipt.name
304
+ })).url;
305
+ const paymentToken = text(form, "token") || void 0;
306
+ const providerPaymentMethodId = text(form, "providerPaymentMethodId") || void 0;
307
+ const deviceSessionId = text(form, "deviceSessionId") || void 0;
308
+ const result = await placeOrder(client, {
309
+ cartToken: token,
310
+ paymentMethodCode: method,
311
+ externalRef: `checkout-${token}`,
312
+ receiptUrl,
313
+ token: paymentToken,
314
+ providerPaymentMethodId,
315
+ deviceSessionId
316
+ }, headers);
317
+ const cookies = new Headers({ "Set-Cookie": await cartCookie.serialize("", { maxAge: 0 }) });
318
+ if (tracked) cookies.append("Set-Cookie", purchaseCookie(result));
319
+ if (result.payment?.actionKind === "threeDS") {
320
+ const payment = result.payment;
321
+ return data({ authentication: {
322
+ orderStatusUrl: result.orderStatusUrl,
323
+ payment: {
324
+ transactionId: payment.transactionId,
325
+ externalId: payment.externalId,
326
+ providerId: payment.providerId ?? null,
327
+ paymentMethodCode: payment.paymentMethodCode,
328
+ isCaptured: false,
329
+ actionKind: "threeDS",
330
+ amount: payment.amount,
331
+ currencyCode: result.cart.currencyCode,
332
+ expiresAt: payment.action?.expiresAt ?? null,
333
+ publicConfiguration: payment.action?.publicConfiguration ?? {},
334
+ actionUrl: null,
335
+ clientSecret: null,
336
+ qrCode: null,
337
+ receiptUrl: null,
338
+ voucherCode: null,
339
+ qrImageUrl: null
340
+ }
341
+ } }, { headers: cookies });
342
+ }
343
+ if (result.payment?.actionKind === "embedded" && result.payment.providerId === "stripe" && providerPaymentMethodId !== void 0) {
344
+ const payment = result.payment;
345
+ return data({ authentication: {
346
+ orderStatusUrl: result.orderStatusUrl,
347
+ payment: {
348
+ transactionId: payment.transactionId,
349
+ externalId: payment.externalId,
350
+ providerId: payment.providerId ?? null,
351
+ paymentMethodCode: payment.paymentMethodCode,
352
+ isCaptured: false,
353
+ actionKind: "embedded",
354
+ amount: payment.amount,
355
+ currencyCode: result.cart.currencyCode,
356
+ expiresAt: payment.action?.expiresAt ?? null,
357
+ publicConfiguration: payment.action?.publicConfiguration ?? {},
358
+ actionUrl: null,
359
+ clientSecret: payment.action?.clientSecret ?? null,
360
+ qrCode: null,
361
+ receiptUrl: null,
362
+ voucherCode: null,
363
+ qrImageUrl: null
364
+ }
365
+ } }, { headers: cookies });
366
+ }
367
+ const url = result.payment?.action?.url;
368
+ if (result.payment?.actionKind === "redirect" && url) return redirect(url, { headers: cookies });
369
+ if (result.payment && (result.payment.actionKind !== "none" || paysOutsideCheckout(result.payment))) return redirect(result.orderStatusUrl, { headers: cookies });
370
+ return redirect(`/checkout/done?order=${encodeURIComponent(result.orderId)}`, { headers: cookies });
371
+ }
372
+ function paysOutsideCheckout(payment) {
373
+ return payment.providerId === "manual" && payment.paymentMethodCode !== "cash_on_delivery";
374
+ }
375
+ async function saveDetails(client, token, form) {
376
+ const contact = await saveContact(client, token, form);
377
+ if (!(contact instanceof Response)) return contact;
378
+ if (needsShipping(await client.getCart({ cartToken: token }))) {
379
+ const delivery = await saveDelivery(client, token, form);
380
+ if (!(delivery instanceof Response)) return delivery;
381
+ const shipping = await saveShipping(client, token, form);
382
+ if (!(shipping instanceof Response)) return shipping;
383
+ }
384
+ return null;
385
+ }
386
+ async function checkoutAll(client, token, form, headers, tracked) {
387
+ const unsaved = await saveDetails(client, token, form);
388
+ if (unsaved !== null) return unsaved;
389
+ return pay(client, token, form, headers, tracked);
390
+ }
391
+ const CHECKOUT_ERRORS = {
392
+ "Catalog.InsufficientStock": "Ya no hay stock suficiente de un producto. Revisa tu carrito.",
393
+ "Inventory.InsufficientStock": "Ya no hay stock suficiente de un producto. Revisa tu carrito.",
394
+ "Checkout.InProgress": "Tu pago se está procesando. Espera un momento antes de volver a intentar.",
395
+ "Checkout.PaymentMethodChanged": "Este pedido se calculó con otro medio de pago. Paga con ese medio o empieza otra compra.",
396
+ "Checkout.OrderNotActive": "Este pedido ya no está activo. Empieza una compra nueva.",
397
+ "Payments.MethodNotAvailable": "Ese medio de pago ya no está disponible. Elige otro.",
398
+ "Payments.Rejected": "No pudimos cobrar tu pago. Prueba con otra tarjeta o elige otro medio de pago.",
399
+ "Payments.InvalidPayerEmail": "La pasarela de pago no pudo validar tu correo. Revisa que esté bien escrito o usa otro.",
400
+ "Carts.NotActive": "Esta compra ya terminó. Vuelve a la tienda para empezar otra.",
401
+ "Order.DomesticShippingRequired": "La entrega debe ser dentro del país de la tienda."
402
+ };
403
+ async function checkoutAction(request, context) {
404
+ const current = await customer(request, context);
405
+ if (current) await requireCustomerRegistration(request, context, current);
406
+ const token = await cartToken(request);
407
+ if (token === null) throw redirect("/cart");
408
+ const client = store(context);
409
+ const form = await request.formData();
410
+ const intent = text(form, "intent");
411
+ if (!isIntent(CHECKOUT_INTENTS, intent)) return failure("Acción no válida.");
412
+ try {
413
+ if (intent === "contact") return await saveContact(client, token, form);
414
+ if (intent === "delivery") return await saveDelivery(client, token, form);
415
+ if (intent === "shipping") return await saveShipping(client, token, form);
416
+ if (intent === "payment-method") return await savePaymentMethod(client, token, form);
417
+ if (intent === "promo") {
418
+ const code = text(form, "code");
419
+ if (code) await client.addCartPromotionCode({
420
+ cartToken: token,
421
+ code
422
+ });
423
+ return redirect("/checkout");
424
+ }
425
+ if (intent === "promo-remove") {
426
+ await client.removeCartPromotionCode({
427
+ cartToken: token,
428
+ code: text(form, "code")
429
+ });
430
+ return redirect("/checkout");
431
+ }
432
+ if (intent === "bump") {
433
+ await client.addCartItem({
434
+ cartToken: token,
435
+ variantId: text(form, "variantId"),
436
+ quantity: 1,
437
+ orderBumpId: text(form, "bumpId")
438
+ });
439
+ return redirect("/checkout");
440
+ }
441
+ if (intent === "pay" || intent === "checkout") {
442
+ const tracked = await client.getSettings().then((settings) => trackingConsented(request, settings), () => false);
443
+ const headers = current ? customerHeaders(current) : void 0;
444
+ if (intent === "checkout") return await checkoutAll(client, token, form, headers, tracked);
445
+ return await pay(client, token, form, headers, tracked);
446
+ }
447
+ return failure("Acción no válida.");
448
+ } catch (error) {
449
+ const apiError = error instanceof ApiError ? error : void 0;
450
+ const functional = apiError !== void 0 && apiError.status >= 400 && apiError.status < 500;
451
+ const promo = intent === "promo" && functional && [
452
+ 400,
453
+ 409,
454
+ 422
455
+ ].includes(apiError.status);
456
+ let message = "No pudimos continuar con la compra. Intenta de nuevo.";
457
+ if (functional) {
458
+ message = promo ? "Ese código no es válido para tu carrito." : "Revisa los datos e intenta de nuevo.";
459
+ if (apiError.status === 401) message = "Tu sesión venció. Vuelve a ingresar.";
460
+ if (apiError.status === 403) message = "No tienes acceso a esta compra.";
461
+ if (apiError.status === 404) message = "El carrito o la opción elegida ya no está disponible.";
462
+ if (apiError.status === 429) message = "Espera un momento antes de volver a intentar.";
463
+ if (apiError.code !== void 0) message = CHECKOUT_ERRORS[apiError.code] ?? message;
464
+ }
465
+ const status = functional ? apiError.status : apiError?.status === 0 ? 503 : 502;
466
+ return data({
467
+ error: message,
468
+ promo,
469
+ code: apiError?.code,
470
+ traceId: apiError?.traceId
471
+ }, { status });
472
+ }
473
+ }
474
+ export { checkoutAction, checkoutAddressDefaults, checkoutProgress, checkoutStep, defaultPaymentMethod, loadCheckout, needsShipping, shouldRevalidateCheckout };