@ecomiq/storefront 2.1.3 → 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 (317) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -123
  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 -81
  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/cloud-runtime-client.ts +0 -378
  238. package/src/codegen.mjs +0 -789
  239. package/src/components/account/customer-addresses-panel.tsx +0 -678
  240. package/src/components/account/customer-order-detail-panel.tsx +0 -285
  241. package/src/components/account/customer-orders-panel.tsx +0 -192
  242. package/src/components/account/customer-profile-panel.tsx +0 -379
  243. package/src/components/checkout/cart-sync.ts +0 -143
  244. package/src/components/checkout/checkout-contact-section.tsx +0 -76
  245. package/src/components/checkout/checkout-external-update-banner.tsx +0 -15
  246. package/src/components/checkout/checkout-form-controls.tsx +0 -139
  247. package/src/components/checkout/checkout-line-items.tsx +0 -43
  248. package/src/components/checkout/checkout-order-summary.tsx +0 -165
  249. package/src/components/checkout/checkout-payment-section.tsx +0 -212
  250. package/src/components/checkout/checkout-session-view.tsx +0 -564
  251. package/src/components/checkout/checkout-shipping-address-section.tsx +0 -400
  252. package/src/components/checkout/checkout-shipping-section.tsx +0 -98
  253. package/src/components/checkout/checkout-states.tsx +0 -73
  254. package/src/components/checkout/checkout-step-card.tsx +0 -101
  255. package/src/components/checkout/checkout-steps.ts +0 -111
  256. package/src/components/checkout/form-schema.ts +0 -281
  257. package/src/components/checkout/format.ts +0 -15
  258. package/src/components/checkout/index.ts +0 -5
  259. package/src/components/checkout/map-customer-to-checkout.ts +0 -188
  260. package/src/components/checkout/types.ts +0 -41
  261. package/src/components/checkout/use-checkout-customer-prefill.ts +0 -409
  262. package/src/components/checkout/use-checkout-geo.ts +0 -50
  263. package/src/components/checkout/use-checkout-session.ts +0 -640
  264. package/src/components/hero.tsx +0 -291
  265. package/src/config.d.ts +0 -94
  266. package/src/config.mjs +0 -146
  267. package/src/format-money.ts +0 -31
  268. package/src/health.ts +0 -90
  269. package/src/hooks/index.ts +0 -9
  270. package/src/hooks/recently-viewed.ts +0 -125
  271. package/src/index.ts +0 -354
  272. package/src/link.tsx +0 -2
  273. package/src/pages/account/account-page-skeleton.tsx +0 -69
  274. package/src/pages/account/account-page-view.tsx +0 -270
  275. package/src/pages/account/account-shell.tsx +0 -101
  276. package/src/pages/account/parse-account-route.ts +0 -36
  277. package/src/pages/account.tsx +0 -16
  278. package/src/pages/api.$.ts +0 -20
  279. package/src/pages/api.auth.$.ts +0 -16
  280. package/src/pages/checkout.$checkoutId.tsx +0 -60
  281. package/src/pages/checkout.tsx +0 -31
  282. package/src/pages/pages.$pageSlug.tsx +0 -111
  283. package/src/pages/thank-you.tsx +0 -53
  284. package/src/providers/auth.tsx +0 -96
  285. package/src/providers/cart.tsx +0 -275
  286. package/src/providers/ecomiq.ts +0 -137
  287. package/src/providers/index.ts +0 -26
  288. package/src/proxy-api.ts +0 -20
  289. package/src/public-config.ts +0 -24
  290. package/src/review-submission.ts +0 -89
  291. package/src/runtime/context.ts +0 -2
  292. package/src/runtime/default-layout.tsx +0 -64
  293. package/src/runtime/head.ts +0 -149
  294. package/src/runtime/page.tsx +0 -143
  295. package/src/runtime/postcss-browser-stub.mjs +0 -5
  296. package/src/server-config-store.ts +0 -35
  297. package/src/server.ts +0 -301
  298. package/src/storefront-definition/contract.ts +0 -1
  299. package/src/storefront-definition/data.ts +0 -188
  300. package/src/storefront-definition/index.ts +0 -2
  301. package/src/storefront-definition/renderer.tsx +0 -1481
  302. package/src/storefront-layout.ts +0 -59
  303. package/src/storefront-runtime.ts +0 -173
  304. package/src/styles.css +0 -97
  305. package/src/ui/badge.tsx +0 -32
  306. package/src/ui/button.tsx +0 -31
  307. package/src/ui/card.tsx +0 -31
  308. package/src/ui/carousel.tsx +0 -218
  309. package/src/ui/cn.ts +0 -6
  310. package/src/ui/index.ts +0 -8
  311. package/src/ui/separator.tsx +0 -6
  312. package/src/ui/skeleton.tsx +0 -6
  313. package/src/ui/storefront-error.tsx +0 -49
  314. package/src/utils.ts +0 -36
  315. package/src/vite-inline.mjs +0 -263
  316. package/templates/__root.tsx +0 -83
  317. package/templates/router.tsx +0 -19
@@ -0,0 +1,4 @@
1
+ export type StorefrontTranslations = Readonly<Record<string, string>>;
2
+ export type StorefrontTextValues = Readonly<Record<string, string | number | null | undefined>>;
3
+ export declare function loadStorefrontTranslations(language: string): Promise<StorefrontTranslations>;
4
+ export declare function storefrontText(translations: StorefrontTranslations, source: string, values?: StorefrontTextValues): string;
@@ -0,0 +1,396 @@
1
+ import { useStorefrontLocale, useStorefrontText } from "./storefront-language-DrMjVbmk.js";
2
+ import { money } from "./money-DtGOtDri.js";
3
+ import { PaymentDialogFrame } from "./payment-dialog-frame-B-Q_xQ94.js";
4
+ import { confirmingPaymentUrl } from "./payment-return-5cjypwIw.js";
5
+ import { useNavigate } from "react-router";
6
+ import { useEffect, useRef, useState } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ // src/stripe-dialog.tsx
9
+ const STRIPE_WALLET_BY_METHOD = {
10
+ apple_pay: "applePay",
11
+ google_pay: "googlePay"
12
+ };
13
+ const WALLET_TITLES = {
14
+ applePay: "Pagar con Apple Pay",
15
+ googlePay: "Pagar con Google Pay"
16
+ };
17
+ const WALLET_UNAVAILABLE = {
18
+ applePay: "Apple Pay no está disponible en este dispositivo. Elige otro medio de pago.",
19
+ googlePay: "Google Pay no está disponible en este navegador. Elige otro medio de pago."
20
+ };
21
+ const ZERO_DECIMAL_CURRENCIES = /* @__PURE__ */ new Set([
22
+ "BIF",
23
+ "CLP",
24
+ "DJF",
25
+ "GNF",
26
+ "JPY",
27
+ "KMF",
28
+ "KRW",
29
+ "MGA",
30
+ "PYG",
31
+ "RWF",
32
+ "VND",
33
+ "VUV",
34
+ "XAF",
35
+ "XOF",
36
+ "XPF"
37
+ ]);
38
+ const THREE_DECIMAL_CURRENCIES = /* @__PURE__ */ new Set([
39
+ "BHD",
40
+ "IQD",
41
+ "JOD",
42
+ "KWD",
43
+ "LYD",
44
+ "OMR",
45
+ "TND"
46
+ ]);
47
+ const CONFIRMED_INTENT_STATUSES = /* @__PURE__ */ new Set([
48
+ "succeeded",
49
+ "processing",
50
+ "requires_capture"
51
+ ]);
52
+ function findStripeWallet(method) {
53
+ if (method.providerId !== "stripe") return null;
54
+ return STRIPE_WALLET_BY_METHOD[method.code] ?? null;
55
+ }
56
+ function expressCheckoutPaymentMethods(wallet) {
57
+ let applePay = "never";
58
+ let googlePay = "never";
59
+ if (wallet === null || wallet === "applePay") applePay = "always";
60
+ if (wallet === null || wallet === "googlePay") googlePay = "always";
61
+ return {
62
+ applePay,
63
+ googlePay,
64
+ link: "never",
65
+ paypal: "never",
66
+ amazonPay: "never",
67
+ klarna: "never"
68
+ };
69
+ }
70
+ function useAvailableStripeWallets(methods, amount, currency) {
71
+ const { locale } = useStorefrontLocale();
72
+ const [wallets, setWallets] = useState(() => /* @__PURE__ */ new Set());
73
+ const publishableKey = methods.find((method) => findStripeWallet(method) !== null)?.publicConfiguration?.publishableKey;
74
+ useEffect(() => {
75
+ if (publishableKey === void 0) return;
76
+ const key = publishableKey;
77
+ let active = true;
78
+ let element;
79
+ const probe = document.createElement("div");
80
+ probe.setAttribute("aria-hidden", "true");
81
+ probe.style.cssText = "position:fixed;left:-10000px;top:0;width:320px;height:60px;";
82
+ async function detect() {
83
+ const client = await loadStripeClient(key, locale);
84
+ if (!active || client === null) return;
85
+ document.body.append(probe);
86
+ element = client.elements({
87
+ mode: "payment",
88
+ amount: toStripeMinorUnits(amount, currency),
89
+ currency: currency.toLowerCase(),
90
+ paymentMethodCreation: "manual",
91
+ paymentMethodTypes: ["card"]
92
+ }).create("expressCheckout", { paymentMethods: expressCheckoutPaymentMethods(null) });
93
+ element.on("ready", (event) => {
94
+ if (!active) return;
95
+ const available = /* @__PURE__ */ new Set();
96
+ if (event.availablePaymentMethods?.applePay === true) available.add("applePay");
97
+ if (event.availablePaymentMethods?.googlePay === true) available.add("googlePay");
98
+ setWallets(available);
99
+ });
100
+ element.mount(probe);
101
+ }
102
+ detect().catch(() => {
103
+ if (active) setWallets(/* @__PURE__ */ new Set());
104
+ });
105
+ return () => {
106
+ active = false;
107
+ element?.destroy();
108
+ probe.remove();
109
+ };
110
+ }, [
111
+ publishableKey,
112
+ amount,
113
+ currency,
114
+ locale
115
+ ]);
116
+ return wallets;
117
+ }
118
+ function toStripeMinorUnits(amount, currency) {
119
+ const code = currency.toUpperCase();
120
+ let factor = 100;
121
+ if (ZERO_DECIMAL_CURRENCIES.has(code)) factor = 1;
122
+ if (THREE_DECIMAL_CURRENCIES.has(code)) factor = 1e3;
123
+ return Math.round(amount * factor);
124
+ }
125
+ function stripeLocale(locale) {
126
+ if (locale.startsWith("en")) return "en";
127
+ if (locale.startsWith("pt")) return "pt-BR";
128
+ return "es";
129
+ }
130
+ async function loadStripeClient(publishableKey, locale) {
131
+ const { loadStripe } = await import("@stripe/stripe-js/pure");
132
+ return loadStripe(publishableKey, { locale: stripeLocale(locale) });
133
+ }
134
+ function StripeDialog({ dialog }) {
135
+ if (dialog === null) return null;
136
+ if (dialog.wallet !== null) return /* @__PURE__ */ jsx(StripeWalletDialog, {
137
+ dialog,
138
+ wallet: dialog.wallet
139
+ });
140
+ return /* @__PURE__ */ jsx(StripeCardDialog, { dialog });
141
+ }
142
+ function StripeCardDialog({ dialog }) {
143
+ const storefrontTranslate = useStorefrontText();
144
+ const { locale } = useStorefrontLocale();
145
+ const container = useRef(null);
146
+ const stripe = useRef(null);
147
+ const elements = useRef(null);
148
+ const latest = useRef(dialog);
149
+ latest.current = dialog;
150
+ const mounted = useRef(true);
151
+ const [ready, setReady] = useState(false);
152
+ const [busy, setBusy] = useState(false);
153
+ const [error, setError] = useState(null);
154
+ const { publishableKey, amount, currency } = dialog;
155
+ useEffect(() => {
156
+ mounted.current = true;
157
+ return () => {
158
+ mounted.current = false;
159
+ };
160
+ }, []);
161
+ useEffect(() => {
162
+ let active = true;
163
+ setReady(false);
164
+ setError(null);
165
+ async function mount() {
166
+ const client = await loadStripeClient(publishableKey, locale);
167
+ if (!active) return;
168
+ if (client === null || container.current === null) throw new Error("No pudimos cargar el pago con tarjeta.");
169
+ stripe.current = client;
170
+ elements.current = client.elements({
171
+ mode: "payment",
172
+ amount: toStripeMinorUnits(amount, currency),
173
+ currency: currency.toLowerCase(),
174
+ paymentMethodCreation: "manual",
175
+ paymentMethodTypes: ["card"]
176
+ });
177
+ const element = elements.current.create("payment", { wallets: {
178
+ applePay: "never",
179
+ googlePay: "never"
180
+ } });
181
+ element.on("ready", () => {
182
+ if (active) setReady(true);
183
+ });
184
+ element.on("loaderror", () => {
185
+ if (active) setError("No pudimos cargar el formulario. Revisa tu conexión e intenta de nuevo.");
186
+ });
187
+ element.mount(container.current);
188
+ }
189
+ mount().catch(() => {
190
+ if (active) setError("No pudimos cargar el pago con tarjeta.");
191
+ });
192
+ return () => {
193
+ active = false;
194
+ elements.current?.getElement("payment")?.destroy();
195
+ stripe.current = null;
196
+ elements.current = null;
197
+ };
198
+ }, [
199
+ publishableKey,
200
+ amount,
201
+ currency,
202
+ locale
203
+ ]);
204
+ async function pay() {
205
+ const client = stripe.current;
206
+ const current = elements.current;
207
+ if (client === null || current === null || busy) return;
208
+ setBusy(true);
209
+ setError(null);
210
+ try {
211
+ const submitted = await current.submit();
212
+ if (submitted.error) {
213
+ setError(submitted.error.message ?? "Revisa los datos de tu tarjeta.");
214
+ return;
215
+ }
216
+ const created = await client.createPaymentMethod({ elements: current });
217
+ if (created.error) {
218
+ setError(created.error.message ?? "No pudimos validar tu tarjeta. Intenta de nuevo.");
219
+ return;
220
+ }
221
+ latest.current.onTokenized(created.paymentMethod.id);
222
+ } catch {
223
+ setError("No pudimos validar tu tarjeta. Intenta de nuevo.");
224
+ } finally {
225
+ if (mounted.current) setBusy(false);
226
+ }
227
+ }
228
+ let label = storefrontTranslate("Pagar {value0}", { value0: money(amount, currency, locale) });
229
+ if (busy) label = storefrontTranslate("Procesando…");
230
+ return /* @__PURE__ */ jsxs(PaymentDialogFrame, {
231
+ title: storefrontTranslate("Pagar con tarjeta"),
232
+ onClose: () => latest.current.onClose(),
233
+ note: storefrontTranslate("Stripe procesa los datos de tu tarjeta de forma segura."),
234
+ children: [
235
+ ready ? null : /* @__PURE__ */ jsx("p", {
236
+ role: "status",
237
+ className: "py-8 text-center text-sm text-muted-foreground",
238
+ children: storefrontTranslate("Cargando el pago…")
239
+ }),
240
+ /* @__PURE__ */ jsx("div", { ref: container }),
241
+ error === null ? null : /* @__PURE__ */ jsx("p", {
242
+ role: "alert",
243
+ className: "mt-3 text-sm text-destructive",
244
+ children: storefrontTranslate(error)
245
+ }),
246
+ /* @__PURE__ */ jsx("button", {
247
+ type: "button",
248
+ onClick: () => {
249
+ pay();
250
+ },
251
+ disabled: !ready || busy,
252
+ className: "mt-4 w-full rounded-md bg-primary px-4 py-2.5 text-sm font-medium text-primary-foreground disabled:opacity-60",
253
+ children: label
254
+ })
255
+ ]
256
+ });
257
+ }
258
+ function StripeWalletDialog({ dialog, wallet }) {
259
+ const storefrontTranslate = useStorefrontText();
260
+ const { locale } = useStorefrontLocale();
261
+ const container = useRef(null);
262
+ const latest = useRef(dialog);
263
+ latest.current = dialog;
264
+ const [state, setState] = useState("loading");
265
+ const [error, setError] = useState(null);
266
+ const { publishableKey, amount, currency } = dialog;
267
+ useEffect(() => {
268
+ let active = true;
269
+ let element;
270
+ setState("loading");
271
+ setError(null);
272
+ async function confirm(client, elements, event) {
273
+ try {
274
+ const submitted = await elements.submit();
275
+ if (submitted.error) {
276
+ event.paymentFailed({ reason: "fail" });
277
+ if (active) setError(submitted.error.message ?? "No pudimos completar el pago. Intenta de nuevo.");
278
+ return;
279
+ }
280
+ const created = await client.createPaymentMethod({ elements });
281
+ if (created.error) {
282
+ event.paymentFailed({ reason: "fail" });
283
+ if (active) setError(created.error.message ?? "No pudimos completar el pago. Intenta de nuevo.");
284
+ return;
285
+ }
286
+ latest.current.onTokenized(created.paymentMethod.id);
287
+ } catch {
288
+ event.paymentFailed({ reason: "fail" });
289
+ if (active) setError("No pudimos completar el pago. Intenta de nuevo.");
290
+ }
291
+ }
292
+ async function mount() {
293
+ const client = await loadStripeClient(publishableKey, locale);
294
+ if (!active) return;
295
+ if (client === null || container.current === null) throw new Error("No pudimos cargar el pago.");
296
+ const elements = client.elements({
297
+ mode: "payment",
298
+ amount: toStripeMinorUnits(amount, currency),
299
+ currency: currency.toLowerCase(),
300
+ paymentMethodCreation: "manual",
301
+ paymentMethodTypes: ["card"]
302
+ });
303
+ element = elements.create("expressCheckout", {
304
+ buttonHeight: 48,
305
+ paymentMethods: expressCheckoutPaymentMethods(wallet)
306
+ });
307
+ element.on("ready", (event) => {
308
+ if (!active) return;
309
+ if (event.availablePaymentMethods?.[wallet] === true) setState("ready");
310
+ else setState("unavailable");
311
+ });
312
+ element.on("click", (event) => event.resolve());
313
+ element.on("confirm", (event) => {
314
+ confirm(client, elements, event);
315
+ });
316
+ element.mount(container.current);
317
+ }
318
+ mount().catch(() => {
319
+ if (active) setState("unavailable");
320
+ });
321
+ return () => {
322
+ active = false;
323
+ element?.destroy();
324
+ };
325
+ }, [
326
+ publishableKey,
327
+ amount,
328
+ currency,
329
+ locale,
330
+ wallet
331
+ ]);
332
+ return /* @__PURE__ */ jsxs(PaymentDialogFrame, {
333
+ title: storefrontTranslate(WALLET_TITLES[wallet]),
334
+ onClose: () => latest.current.onClose(),
335
+ note: storefrontTranslate("Stripe procesa tu pago de forma segura."),
336
+ children: [
337
+ state === "loading" ? /* @__PURE__ */ jsx("p", {
338
+ role: "status",
339
+ className: "py-8 text-center text-sm text-muted-foreground",
340
+ children: storefrontTranslate("Cargando el pago…")
341
+ }) : null,
342
+ state === "unavailable" ? /* @__PURE__ */ jsx("p", {
343
+ role: "alert",
344
+ className: "py-4 text-sm text-destructive",
345
+ children: storefrontTranslate(WALLET_UNAVAILABLE[wallet])
346
+ }) : null,
347
+ /* @__PURE__ */ jsx("p", {
348
+ className: "pb-3 text-center text-sm",
349
+ children: money(amount, currency, locale)
350
+ }),
351
+ /* @__PURE__ */ jsx("div", { ref: container }),
352
+ error === null ? null : /* @__PURE__ */ jsx("p", {
353
+ role: "alert",
354
+ className: "mt-3 text-sm text-destructive",
355
+ children: storefrontTranslate(error)
356
+ })
357
+ ]
358
+ });
359
+ }
360
+ function StripeAuthentication({ payment, orderStatusUrl }) {
361
+ const storefrontTranslate = useStorefrontText();
362
+ const { locale } = useStorefrontLocale();
363
+ const navigate = useNavigate();
364
+ const clientSecret = payment.clientSecret;
365
+ const publishableKey = payment.publicConfiguration.publishableKey;
366
+ useEffect(() => {
367
+ let active = true;
368
+ async function finish() {
369
+ if (clientSecret === null || publishableKey === void 0) return orderStatusUrl;
370
+ const client = await loadStripeClient(publishableKey, locale);
371
+ if (client === null) return orderStatusUrl;
372
+ let status = (await client.retrievePaymentIntent(clientSecret)).paymentIntent?.status;
373
+ if (status === "requires_action") status = (await client.handleNextAction({ clientSecret })).paymentIntent?.status;
374
+ if (status !== void 0 && CONFIRMED_INTENT_STATUSES.has(status)) return confirmingPaymentUrl(orderStatusUrl);
375
+ return orderStatusUrl;
376
+ }
377
+ finish().catch(() => orderStatusUrl).then((destination) => {
378
+ if (active) navigate(destination, { replace: true });
379
+ });
380
+ return () => {
381
+ active = false;
382
+ };
383
+ }, [
384
+ clientSecret,
385
+ publishableKey,
386
+ orderStatusUrl,
387
+ locale,
388
+ navigate
389
+ ]);
390
+ return /* @__PURE__ */ jsx("p", {
391
+ role: "status",
392
+ className: "py-16 text-center text-sm text-muted-foreground",
393
+ children: storefrontTranslate("Estamos confirmando tu pago.")
394
+ });
395
+ }
396
+ export { StripeAuthentication, StripeDialog, findStripeWallet, toStripeMinorUnits, useAvailableStripeWallets };
@@ -0,0 +1,30 @@
1
+ import { OrderPaymentStart } from "@ecomiq/core";
2
+ export type StripeWallet = "applePay" | "googlePay";
3
+ export type StripeDialogState = {
4
+ publishableKey: string;
5
+ amount: number;
6
+ currency: string;
7
+ wallet: StripeWallet | null;
8
+ onTokenized: (paymentMethodId: string) => void;
9
+ onClose: () => void;
10
+ };
11
+ export declare function findStripeWallet(method: {
12
+ code: string;
13
+ providerId?: string | null;
14
+ }): StripeWallet | null;
15
+ type StripeWalletMethod = {
16
+ code: string;
17
+ providerId?: string | null;
18
+ publicConfiguration?: {
19
+ readonly [key: string]: string;
20
+ } | null;
21
+ };
22
+ export declare function useAvailableStripeWallets(methods: ReadonlyArray<StripeWalletMethod>, amount: number, currency: string): ReadonlySet<StripeWallet>;
23
+ export declare function StripeDialog({ dialog }: {
24
+ dialog: StripeDialogState | null;
25
+ }): import("react").JSX.Element | null;
26
+ export declare function StripeAuthentication({ payment, orderStatusUrl }: {
27
+ payment: OrderPaymentStart;
28
+ orderStatusUrl: string;
29
+ }): import("react").JSX.Element;
30
+ export {};
@@ -0,0 +1,114 @@
1
+ // src/telemetry.ts
2
+ /** Timings for the storefront SDK calls completed before the SSR response headers. */
3
+ var StorefrontSdkTiming = class {
4
+ count = 0;
5
+ sumMs = 0;
6
+ slowestMs = 0;
7
+ slowestMethod = "";
8
+ subrequests = 0;
9
+ recordSubrequest() {
10
+ this.subrequests += 1;
11
+ }
12
+ record(method, durationMs) {
13
+ this.count += 1;
14
+ this.sumMs += durationMs;
15
+ if (durationMs > this.slowestMs) {
16
+ this.slowestMs = durationMs;
17
+ this.slowestMethod = method;
18
+ }
19
+ }
20
+ };
21
+ const timedClientMethods = /* @__PURE__ */ new Set([
22
+ "get",
23
+ "post",
24
+ "postForm",
25
+ "request",
26
+ "graphql",
27
+ "getSettings",
28
+ "getLayout",
29
+ "getStoreId",
30
+ "getCollections",
31
+ "getPaymentMethods",
32
+ "getCollectionBySlug",
33
+ "getPageBySlug",
34
+ "getCategoryBySlug",
35
+ "resolveUrl",
36
+ "getLinks",
37
+ "getSitemap",
38
+ "listArticles",
39
+ "getArticleBySlug",
40
+ "getSellers",
41
+ "getSellerBySlug",
42
+ "getProducts",
43
+ "getProductBySlug",
44
+ "getRelatedProducts",
45
+ "autocompleteProducts",
46
+ "listProductReviews",
47
+ "listStoreReviews",
48
+ "createProductReview",
49
+ "createCustomerProductReview",
50
+ "createCart",
51
+ "getCart",
52
+ "addCartItem",
53
+ "updateCartItemQuantity",
54
+ "removeCartItem",
55
+ "getCartCheckout",
56
+ "getShippingOptions",
57
+ "patchCartBuyer",
58
+ "patchCartAddresses",
59
+ "putCartShippingMethod",
60
+ "putCartPaymentMethod",
61
+ "removeCartPromotionCode",
62
+ "addCartPromotionCode",
63
+ "checkoutCart",
64
+ "uploadPaymentReceipt",
65
+ "getCountries",
66
+ "getDepartments",
67
+ "getDistricts",
68
+ "getProvinces",
69
+ "getCustomerAddresses",
70
+ "createCustomerAddress",
71
+ "updateCustomerAddress",
72
+ "deleteCustomerAddress",
73
+ "getCustomerMe",
74
+ "patchCustomer",
75
+ "getCustomerOrders",
76
+ "getCustomerOrder",
77
+ "requestCustomerOrderReturn",
78
+ "requestCustomerOrderCancellation",
79
+ "upsertCustomerAuthConfiguration",
80
+ "getCustomerSession",
81
+ "createCustomerSession",
82
+ "deleteCustomerSession",
83
+ "getCustomerRegistration",
84
+ "completeCustomerRegistration",
85
+ "getOrderStatus",
86
+ "startOrderPayment",
87
+ "authenticateOrderPayment",
88
+ "uploadOrderPaymentReceipt",
89
+ "getOrderDraft",
90
+ "checkoutOrderDraft",
91
+ "getComplaintBook",
92
+ "createComplaintBookEntry"
93
+ ]);
94
+ function observeStorefrontClient(client, timing) {
95
+ return new Proxy(client, { get(target, property, receiver) {
96
+ const value = Reflect.get(target, property, receiver);
97
+ if (typeof property !== "string" || !timedClientMethods.has(property) || typeof value !== "function") return value;
98
+ return (...args) => {
99
+ const started = performance.now();
100
+ try {
101
+ return Promise.resolve(Reflect.apply(value, target, args)).finally(() => {
102
+ timing.record(property, performance.now() - started);
103
+ });
104
+ } catch (error) {
105
+ timing.record(property, performance.now() - started);
106
+ throw error;
107
+ }
108
+ };
109
+ } });
110
+ }
111
+ function durationMetric(name, durationMs) {
112
+ return `${name};dur=${Math.max(0, durationMs).toFixed(1)}`;
113
+ }
114
+ export { StorefrontSdkTiming, durationMetric, observeStorefrontClient, timedClientMethods };
@@ -0,0 +1,10 @@
1
+ /** Timings for the storefront SDK calls completed before the SSR response headers. */
2
+ export declare class StorefrontSdkTiming {
3
+ count: number;
4
+ sumMs: number;
5
+ slowestMs: number;
6
+ slowestMethod: string;
7
+ subrequests: number;
8
+ recordSubrequest(): void;
9
+ record(method: string, durationMs: number): void;
10
+ }
@@ -0,0 +1,40 @@
1
+ import { loadSections, withSections } from "./sections-CNUMWTF_.js";
2
+ import { worker } from "./worker-CNi-gzCu.js";
3
+ // src/templates.ts
4
+ const TEMPLATE = "ecomiqTemplate";
5
+ const NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
6
+ function templatePath(kind, name) {
7
+ return `/app/templates/${kind}.${name}.tsx`;
8
+ }
9
+ function field(value, key) {
10
+ return typeof value === "object" && value !== null ? value[key] : void 0;
11
+ }
12
+ function ownTemplate(kind, page) {
13
+ if (kind === "product") return field(field(page, "product"), "template");
14
+ if (kind === "collection") return field(field(page, "collection"), "template");
15
+ const layout = field(page, "layout");
16
+ return layout === "default" ? null : layout;
17
+ }
18
+ function templateName(args, modules, kind, page) {
19
+ let name = ownTemplate(kind, page);
20
+ const { env } = args.context.get(worker);
21
+ const forced = env.ECOMIQ_PREVIEW === "1" ? new URL(args.request.url).searchParams.get("template") : null;
22
+ if (forced !== null) name = forced;
23
+ if (typeof name !== "string" || !NAME.test(name) || modules[templatePath(kind, name)] === void 0) return null;
24
+ return name;
25
+ }
26
+ async function templated(args, page, sections, modules, kind) {
27
+ const name = templateName(args, modules, kind, page);
28
+ if (name === null) return withSections(page, sections);
29
+ const own = loadSections(args, modules[templatePath(kind, name)]?.__ecomiqSections ?? []);
30
+ return withSections(page, {
31
+ ...sections,
32
+ ...own
33
+ }, { [TEMPLATE]: name });
34
+ }
35
+ function templateComponent(modules, kind, loaderData) {
36
+ const name = field(loaderData, TEMPLATE);
37
+ if (typeof name !== "string") return null;
38
+ return modules[templatePath(kind, name)]?.default ?? null;
39
+ }
40
+ export { templateComponent, templateName, templatePath, templated };
@@ -0,0 +1,15 @@
1
+ import { SectionData, SectionEntry } from "./sections.js";
2
+ import { LoaderFunctionArgs } from "react-router";
3
+ import { ComponentType } from "react";
4
+ export type TemplateKind = "product" | "collection" | "page";
5
+ export type TemplateModule = {
6
+ readonly default?: ComponentType<never>;
7
+ readonly __ecomiqSections?: readonly SectionEntry[];
8
+ };
9
+ export type TemplateModules = {
10
+ readonly [path: string]: TemplateModule;
11
+ };
12
+ export declare function templatePath(kind: TemplateKind, name: string): string;
13
+ export declare function templateName(args: LoaderFunctionArgs, modules: TemplateModules, kind: TemplateKind, page: unknown): string | null;
14
+ export declare function templated(args: LoaderFunctionArgs, page: unknown, sections: SectionData, modules: TemplateModules, kind: TemplateKind): Promise<unknown>;
15
+ export declare function templateComponent(modules: TemplateModules, kind: TemplateKind, loaderData: unknown): ComponentType<never> | null;
@@ -0,0 +1,71 @@
1
+ import { readCatalog } from "./catalog-7gJ-l5hW.js";
2
+ import { documentUrl } from "./document-url-CGsAl5Tf.js";
3
+ import { store } from "./store-8Q-_LFrQ.js";
4
+ import { data, redirect } from "react-router";
5
+ import { sanitizeHtml } from "@ecomiq/core";
6
+ // src/urls.ts
7
+ function requestUrl(request) {
8
+ return documentUrl(new URL(request.url));
9
+ }
10
+ function destination(current, url) {
11
+ const target = new URL(current);
12
+ target.pathname = url;
13
+ return target;
14
+ }
15
+ function moved(target) {
16
+ return redirect(`/${target.pathname.replace(/^\/+/, "")}${target.search}`, 301);
17
+ }
18
+ function requireCanonical(request, url) {
19
+ const current = requestUrl(request);
20
+ const target = destination(current, url);
21
+ if (target.pathname !== current.pathname) throw moved(target);
22
+ }
23
+ async function resolveUrl(request, context, options = {}) {
24
+ const current = requestUrl(request);
25
+ const client = store(context);
26
+ const resolved = await client.resolveUrl(current.pathname);
27
+ if (resolved === null) throw data(null, { status: 404 });
28
+ if (options.redirect === false) {
29
+ if (resolved.kind !== "redirect") return resolved;
30
+ const target = await client.resolveUrl(destination(current, resolved.url).pathname);
31
+ if (target === null || target.kind === "redirect") throw data(null, { status: 404 });
32
+ return target;
33
+ }
34
+ if (resolved.kind === "redirect") throw moved(destination(current, resolved.url));
35
+ requireCanonical(request, resolved.url);
36
+ return resolved;
37
+ }
38
+ async function loadProduct(request, context, options = {}) {
39
+ const resolved = await resolveUrl(request, context, options);
40
+ if (resolved.kind !== "product") throw data(null, { status: 404 });
41
+ return resolved.product;
42
+ }
43
+ function canonicalOrigin(request, settings) {
44
+ if (settings.store.domain) return `https://${settings.store.domain}`;
45
+ return requestUrl(request).origin;
46
+ }
47
+ function absoluteUrl(origin, url) {
48
+ return destination(new URL(origin), url).toString();
49
+ }
50
+ async function canonicalUrl(request, context, url) {
51
+ return absoluteUrl(canonicalOrigin(request, await store(context).getSettings()), url);
52
+ }
53
+ async function loadCategory(request, context, category) {
54
+ const client = store(context);
55
+ const query = readCatalog(requestUrl(request), { categoryId: category.id });
56
+ const result = await client.getProducts(query);
57
+ let description = null;
58
+ if (category.description !== null) description = sanitizeHtml(category.description);
59
+ return {
60
+ category: {
61
+ ...category,
62
+ description
63
+ },
64
+ page: query.page ?? 1,
65
+ result: {
66
+ ...result,
67
+ filters: result.filters.filter((filter) => filter.id !== "category")
68
+ }
69
+ };
70
+ }
71
+ export { absoluteUrl, canonicalOrigin, canonicalUrl, loadCategory, loadProduct, requestUrl, requireCanonical, resolveUrl };