@ecomiq/storefront 2.1.4 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +377 -76
  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,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 };