@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,86 @@
1
+ import { AddressDefaults } from "./address-defaults.js";
2
+ import { PageAnalytics } from "./analytics/events.js";
3
+ import { readCountries } from "./store.js";
4
+ import { RouterContextProvider, ShouldRevalidateFunctionArgs } from "react-router";
5
+ import { CartCheckoutReadResponse, CustomerAddress, CustomerMe, ShippingOptionGroup, ShippingRate, StorefrontCart } from "@ecomiq/core";
6
+ import { z } from "zod";
7
+ export type CheckoutStep = "contact" | "delivery" | "shipping" | "payment";
8
+ export type CheckoutRate = ShippingRate & {
9
+ value: string;
10
+ };
11
+ export type CheckoutShippingGroup = Omit<ShippingOptionGroup, "rates"> & {
12
+ field: string;
13
+ rates: CheckoutRate[];
14
+ };
15
+ export type CheckoutPaymentMethod = CartCheckoutReadResponse["paymentMethods"]["methods"][number];
16
+ export type CheckoutData = {
17
+ countryCode: string;
18
+ documentCountries: {
19
+ code: string;
20
+ name: string;
21
+ }[];
22
+ language: string;
23
+ cart: StorefrontCart;
24
+ methods: CheckoutPaymentMethod[];
25
+ bumps: CartCheckoutReadResponse["orderBumps"];
26
+ signedIn: boolean;
27
+ me: CustomerMe | null;
28
+ address: CustomerAddress | null;
29
+ countries: Awaited<ReturnType<typeof readCountries>>;
30
+ shipping: CheckoutShippingGroup[];
31
+ analytics: PageAnalytics;
32
+ };
33
+ declare const CheckoutAuthenticationSchema: z.ZodObject<{
34
+ authentication: z.ZodObject<{
35
+ payment: z.ZodObject<{
36
+ actionUrl: z.ZodNullable<z.ZodString>;
37
+ isCaptured: z.ZodBoolean;
38
+ transactionId: z.ZodNullable<z.ZodString>;
39
+ externalId: z.ZodNullable<z.ZodString>;
40
+ actionKind: z.ZodEnum<{
41
+ embedded: "embedded";
42
+ none: "none";
43
+ qrCode: "qrCode";
44
+ redirect: "redirect";
45
+ threeDS: "threeDS";
46
+ voucher: "voucher";
47
+ }>;
48
+ providerId: z.ZodNullable<z.ZodString>;
49
+ publicConfiguration: z.ZodObject<{
50
+ publishableKey: z.ZodOptional<z.ZodString>;
51
+ publicKey: z.ZodOptional<z.ZodString>;
52
+ }, z.core.$strip>;
53
+ clientSecret: z.ZodNullable<z.ZodString>;
54
+ qrCode: z.ZodNullable<z.ZodString>;
55
+ receiptUrl: z.ZodNullable<z.ZodString>;
56
+ expiresAt: z.ZodNullable<z.ZodString>;
57
+ paymentMethodCode: z.ZodNullable<z.ZodString>;
58
+ amount: z.ZodNullable<z.ZodNumber>;
59
+ currencyCode: z.ZodNullable<z.ZodString>;
60
+ voucherCode: z.ZodNullable<z.ZodString>;
61
+ qrImageUrl: z.ZodNullable<z.ZodString>;
62
+ }, z.core.$strip>;
63
+ orderStatusUrl: z.ZodString;
64
+ }, z.core.$strip>;
65
+ }, z.core.$strip>;
66
+ export type CheckoutAuthenticationData = z.infer<typeof CheckoutAuthenticationSchema>;
67
+ export type CheckoutActionData = {
68
+ error: string;
69
+ promo: boolean;
70
+ code?: string;
71
+ traceId?: string;
72
+ } | CheckoutAuthenticationData;
73
+ export type CheckoutAddressDefaults = AddressDefaults;
74
+ export declare function shouldRevalidateCheckout({ actionResult, defaultShouldRevalidate }: ShouldRevalidateFunctionArgs): boolean;
75
+ export declare function needsShipping(cart: StorefrontCart): boolean;
76
+ export declare function checkoutProgress(cart: StorefrontCart): {
77
+ contact: boolean;
78
+ delivery: boolean;
79
+ shipping: boolean;
80
+ };
81
+ export declare function checkoutStep(cart: StorefrontCart, edit: string | null): CheckoutStep;
82
+ export declare function checkoutAddressDefaults(cart: StorefrontCart, address: CustomerAddress | null, countryCode: string): CheckoutAddressDefaults;
83
+ export declare function defaultPaymentMethod(cart: StorefrontCart, methods: CheckoutPaymentMethod[]): string | undefined;
84
+ export declare function loadCheckout(request: Request, context: Readonly<RouterContextProvider>): Promise<CheckoutData>;
85
+ export declare function checkoutAction(request: Request, context: Readonly<RouterContextProvider>): Promise<import("react-router").UNSAFE_DataWithResponseInit<CheckoutActionData> | Response>;
86
+ export {};
@@ -0,0 +1,117 @@
1
+ import { captchaResponse } from "./captcha-DAqaIx8m.js";
2
+ import { COMPLAINT_DOCUMENT_TYPES, identityDocumentError } from "./documents-T1mzc_j8.js";
3
+ import { optional, text } from "./form-BtQcbXlJ.js";
4
+ import { rejectCrossOriginAction } from "./request-security-CRsRMgwj.js";
5
+ import { found, readDocumentCountries, store } from "./store-8Q-_LFrQ.js";
6
+ import { data } from "react-router";
7
+ import { ApiError, COMPLAINT_BOOK_ATTACHMENT_TYPES, COMPLAINT_BOOK_MAX_ATTACHMENTS, COMPLAINT_BOOK_MAX_ATTACHMENT_BYTES, ComplaintBookEntryInputSchema } from "@ecomiq/core";
8
+ import { z } from "zod";
9
+ // src/complaint-book.ts
10
+ const TOO_MANY_ATTACHMENTS = "Adjunta hasta 3 archivos.";
11
+ const INVALID_ATTACHMENT = "Adjunta fotos (JPG, PNG o WebP) o PDF de hasta 5 MB.";
12
+ const COMPLAINT_BOOK_ERRORS = {
13
+ "ComplaintBook.Captcha": "Completa la verificación de seguridad.",
14
+ "ComplaintBook.Unavailable": "El Libro de Reclamaciones no está disponible en esta tienda.",
15
+ "ComplaintBook.TooManyAttachments": TOO_MANY_ATTACHMENTS,
16
+ "ComplaintBook.InvalidAttachment": INVALID_ATTACHMENT,
17
+ "ComplaintBook.AttachmentUploadFailed": "No pudimos guardar los adjuntos. Intenta de nuevo o envía sin ellos."
18
+ };
19
+ const ValidationProblemSchema = z.object({ fieldErrors: z.record(z.string(), z.array(z.string())) });
20
+ function complaintBookLinks(settings) {
21
+ if (settings.store.countryCode !== "PE") return [];
22
+ return [{
23
+ label: "Libro de Reclamaciones",
24
+ url: "/libro-de-reclamaciones"
25
+ }];
26
+ }
27
+ function complaintBookNumber(number) {
28
+ return `N.° ${String(number).padStart(6, "0")}`;
29
+ }
30
+ function complaintBookAttachmentError(files) {
31
+ if (files.length > COMPLAINT_BOOK_MAX_ATTACHMENTS) return TOO_MANY_ATTACHMENTS;
32
+ if (files.some((file) => file.size === 0 || file.size > COMPLAINT_BOOK_MAX_ATTACHMENT_BYTES || !COMPLAINT_BOOK_ATTACHMENT_TYPES.includes(file.type))) return INVALID_ATTACHMENT;
33
+ return null;
34
+ }
35
+ async function loadComplaintBook(context) {
36
+ const client = store(context);
37
+ const [book, settings] = await Promise.all([found(client.getComplaintBook()), client.getSettings()]);
38
+ return {
39
+ book,
40
+ countryCode: settings.store.countryCode,
41
+ language: settings.store.language,
42
+ timeZone: settings.store.timeZone,
43
+ countries: await readDocumentCountries(client)
44
+ };
45
+ }
46
+ function failure(error, status = 400) {
47
+ return data({ error }, { status });
48
+ }
49
+ function person(form, prefix) {
50
+ return {
51
+ name: text(form, `${prefix}Name`),
52
+ address: text(form, `${prefix}Address`),
53
+ phone: text(form, `${prefix}Phone`),
54
+ email: text(form, `${prefix}Email`)
55
+ };
56
+ }
57
+ function complaintEntry(form) {
58
+ if (form.get("confirmed") !== "on") return "Confirma que los datos son verdaderos.";
59
+ const amount = optional(form, "itemAmount");
60
+ const parsed = ComplaintBookEntryInputSchema.safeParse({
61
+ type: text(form, "type"),
62
+ consumer: {
63
+ ...person(form, "consumer"),
64
+ documentType: text(form, "documentType"),
65
+ documentNumber: text(form, "documentNumber"),
66
+ documentCountryCode: text(form, "documentCountryCode")
67
+ },
68
+ guardian: form.get("minor") === "on" ? person(form, "guardian") : null,
69
+ item: {
70
+ kind: text(form, "itemKind"),
71
+ description: text(form, "itemDescription"),
72
+ amount: amount === null ? null : Number(amount)
73
+ },
74
+ orderNumber: optional(form, "orderNumber"),
75
+ detail: text(form, "detail"),
76
+ request: text(form, "request"),
77
+ confirmed: true
78
+ });
79
+ if (!parsed.success) return "Completa los datos obligatorios.";
80
+ const { documentType, documentNumber, documentCountryCode } = parsed.data.consumer;
81
+ const documentError = identityDocumentError(COMPLAINT_DOCUMENT_TYPES[documentType], documentCountryCode, documentNumber);
82
+ if (documentError !== null) return documentError;
83
+ return parsed.data;
84
+ }
85
+ function apiErrorMessage(error) {
86
+ const problem = ValidationProblemSchema.safeParse(error.body);
87
+ const codes = problem.success ? Object.values(problem.data.fieldErrors).flat() : [];
88
+ if (error.code !== void 0) codes.unshift(error.code);
89
+ return codes.flatMap((code) => COMPLAINT_BOOK_ERRORS[code] ?? [])[0];
90
+ }
91
+ async function complaintBookAction(request, context) {
92
+ const rejected = rejectCrossOriginAction(request);
93
+ if (rejected) return rejected;
94
+ const client = store(context);
95
+ const form = await request.formData();
96
+ const book = await found(client.getComplaintBook());
97
+ const token = captchaResponse(form, book.captcha.provider);
98
+ if (!token) return failure("Completa la verificación de seguridad.");
99
+ const sheet = complaintEntry(form);
100
+ if (typeof sheet === "string") return failure(sheet);
101
+ const files = form.getAll("files").filter((file) => file instanceof File && file.size > 0);
102
+ const attachmentError = complaintBookAttachmentError(files);
103
+ if (attachmentError) return failure(attachmentError);
104
+ try {
105
+ return {
106
+ entry: await client.createComplaintBookEntry(sheet, files, token),
107
+ sheet,
108
+ attachments: files.map((file) => file.name)
109
+ };
110
+ } catch (error) {
111
+ if (!(error instanceof ApiError) || error.status === 0 || error.status >= 500) return failure("No pudimos registrar tu reclamo. Intenta de nuevo.", 503);
112
+ let message = "Revisa los datos e intenta de nuevo.";
113
+ if (error.status === 429) message = "Espera un momento antes de volver a intentar.";
114
+ return failure(apiErrorMessage(error) ?? message, error.status);
115
+ }
116
+ }
117
+ export { complaintBookAction, complaintBookAttachmentError, complaintBookLinks, complaintBookNumber, loadComplaintBook };
@@ -0,0 +1,62 @@
1
+ import { RouterContextProvider } from "react-router";
2
+ import { ComplaintBook, ComplaintBookEntry, ComplaintBookEntryInput, StorefrontSettings } from "@ecomiq/core";
3
+ export type ComplaintBookLink = {
4
+ label: string;
5
+ url: string;
6
+ };
7
+ export type ComplaintBookData = {
8
+ book: ComplaintBook;
9
+ countryCode: string;
10
+ language: string;
11
+ timeZone: string;
12
+ countries: {
13
+ code: string;
14
+ name: string;
15
+ }[];
16
+ };
17
+ export type ComplaintBookActionData = {
18
+ error: string;
19
+ } | {
20
+ entry: ComplaintBookEntry;
21
+ sheet: ComplaintBookEntryInput;
22
+ attachments: string[];
23
+ };
24
+ export declare function complaintBookLinks(settings: StorefrontSettings): ComplaintBookLink[];
25
+ export declare function complaintBookNumber(number: number): string;
26
+ export declare function complaintBookAttachmentError(files: readonly File[]): string | null;
27
+ export declare function loadComplaintBook(context: Readonly<RouterContextProvider>): Promise<ComplaintBookData>;
28
+ export declare function complaintBookAction(request: Request, context: Readonly<RouterContextProvider>): Promise<import("react-router").UNSAFE_DataWithResponseInit<ComplaintBookActionData> | Response | {
29
+ entry: {
30
+ number: number;
31
+ filedOn: string;
32
+ responseDueOn: string;
33
+ };
34
+ sheet: {
35
+ type: "claim" | "complaint";
36
+ consumer: {
37
+ name: string;
38
+ address: string;
39
+ phone: string;
40
+ email: string;
41
+ documentType: "foreignId" | "nationalId" | "passport" | "taxId";
42
+ documentNumber: string;
43
+ documentCountryCode: string;
44
+ };
45
+ guardian: {
46
+ name: string;
47
+ address: string;
48
+ phone: string;
49
+ email: string;
50
+ } | null;
51
+ item: {
52
+ kind: "product" | "service";
53
+ description: string;
54
+ amount: number | null;
55
+ };
56
+ orderNumber: string | null;
57
+ detail: string;
58
+ request: string;
59
+ confirmed: true;
60
+ };
61
+ attachments: string[];
62
+ }>;
@@ -0,0 +1,204 @@
1
+ import { useStorefrontLocale, useStorefrontText } from "./storefront-language-DrMjVbmk.js";
2
+ import { useCustomerCsrfToken } from "./customer-csrf-C1oDX-Py.js";
3
+ import { CulqiPaymentSourceSchema, culqiSourceKey, loadCulqiThreeDS } from "./culqi-three-ds-HP3mfrvV.js";
4
+ import { useNavigate, useSubmit } from "react-router";
5
+ import { PaymentAuthentication3DSSchema } from "@ecomiq/core";
6
+ import { z } from "zod";
7
+ import { useEffect, useRef, useState } from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
+ // src/culqi-authentication.tsx
10
+ const StoredSourceSchema = CulqiPaymentSourceSchema.extend({
11
+ expiresAt: z.string().datetime({ offset: true }),
12
+ orderStatusUrl: z.string()
13
+ });
14
+ const AuthenticationMessageSchema = z.union([z.object({ parameters3DS: PaymentAuthentication3DSSchema }), z.object({ error: z.string() })]);
15
+ function useOrderAuthentication({ result, payment, orderStatusUrl }) {
16
+ useEffect(() => {
17
+ let storage;
18
+ try {
19
+ storage = window.sessionStorage;
20
+ } catch {
21
+ return;
22
+ }
23
+ for (let index = storage.length - 1; index >= 0; index--) {
24
+ const key = storage.key(index);
25
+ if (key === null || !key.startsWith("ecomiq:culqi:")) continue;
26
+ let stored;
27
+ try {
28
+ stored = JSON.parse(storage.getItem(key) ?? "null");
29
+ } catch {
30
+ storage.removeItem(key);
31
+ continue;
32
+ }
33
+ const source = StoredSourceSchema.safeParse(stored);
34
+ if (!source.success || Date.parse(source.data.expiresAt) <= Date.now() || source.data.orderStatusUrl === orderStatusUrl && (payment?.actionKind !== "threeDS" || key !== culqiSourceKey(payment.transactionId ?? ""))) storage.removeItem(key);
35
+ }
36
+ if (result?.authenticatedTransactionId) storage.removeItem(culqiSourceKey(result.authenticatedTransactionId));
37
+ }, [
38
+ result?.authenticatedTransactionId,
39
+ payment?.actionKind,
40
+ payment?.transactionId,
41
+ orderStatusUrl
42
+ ]);
43
+ }
44
+ function CulqiAuthentication({ payment, orderStatusUrl, email, source, result }) {
45
+ const storefrontTranslate = useStorefrontText();
46
+ const { locale, timeZone } = useStorefrontLocale();
47
+ const expiry = new Intl.DateTimeFormat(locale, {
48
+ dateStyle: "medium",
49
+ timeStyle: "short",
50
+ timeZone
51
+ });
52
+ const submit = useSubmit();
53
+ const navigate = useNavigate();
54
+ const csrf = useCustomerCsrfToken();
55
+ const [error, setError] = useState(null);
56
+ const [retryable, setRetryable] = useState(false);
57
+ const [attempt, setAttempt] = useState(0);
58
+ const authenticationSubmission = useRef(null);
59
+ useEffect(() => {
60
+ authenticationSubmission.current = null;
61
+ let active = true;
62
+ let sent = false;
63
+ let reset;
64
+ let timer;
65
+ let receive;
66
+ const transactionId = payment.transactionId;
67
+ async function authenticate() {
68
+ if (transactionId === null || payment.expiresAt === null) throw new Error("No pudimos iniciar la autenticación de este pago.");
69
+ const key = culqiSourceKey(transactionId);
70
+ if (source !== null) window.sessionStorage.setItem(key, JSON.stringify({
71
+ ...source,
72
+ expiresAt: payment.expiresAt,
73
+ orderStatusUrl
74
+ }));
75
+ let storedValue;
76
+ try {
77
+ storedValue = JSON.parse(window.sessionStorage.getItem(key) ?? "null");
78
+ } catch {
79
+ storedValue = null;
80
+ }
81
+ const stored = StoredSourceSchema.safeParse(storedValue);
82
+ if (!stored.success || stored.data.orderStatusUrl !== orderStatusUrl) throw new Error("La sesión de tu tarjeta terminó. Espera a que venza esta autenticación y vuelve al estado del pedido para intentar el pago.");
83
+ const remaining = Date.parse(stored.data.expiresAt) - Date.now();
84
+ if (remaining <= 0) {
85
+ window.sessionStorage.removeItem(key);
86
+ throw new Error("La autenticación venció. Vuelve al pedido para consultar las opciones de pago.");
87
+ }
88
+ if (window.location.pathname !== new URL(orderStatusUrl, window.location.href).pathname) {
89
+ navigate(orderStatusUrl, { replace: true });
90
+ return;
91
+ }
92
+ if (!payment.publicConfiguration.publicKey || payment.amount === null || payment.currencyCode === null || !email) throw new Error("No pudimos iniciar la autenticación de este pago.");
93
+ setRetryable(true);
94
+ timer = window.setTimeout(() => {
95
+ active = false;
96
+ window.sessionStorage.removeItem(key);
97
+ reset?.();
98
+ setRetryable(false);
99
+ setError("La autenticación venció. Vuelve al pedido para consultar las opciones de pago.");
100
+ }, remaining);
101
+ const sdk = await loadCulqiThreeDS();
102
+ if (!active) return;
103
+ sdk.reset();
104
+ reset = () => sdk.reset();
105
+ sdk.publicKey = payment.publicConfiguration.publicKey;
106
+ sdk.settings = {
107
+ charge: {
108
+ totalAmount: Math.round(payment.amount * 100),
109
+ currency: payment.currencyCode,
110
+ returnUrl: window.location.href
111
+ },
112
+ card: { email }
113
+ };
114
+ receive = (event) => {
115
+ if (!active || sent || event.origin !== window.location.origin) return;
116
+ const response = AuthenticationMessageSchema.safeParse(event.data);
117
+ if (!response.success) return;
118
+ if ("error" in response.data) {
119
+ setError("No pudimos autenticar tu tarjeta. Intenta nuevamente.");
120
+ return;
121
+ }
122
+ sent = true;
123
+ const form = new FormData();
124
+ form.set("intent", "authenticate");
125
+ form.set("transactionId", transactionId);
126
+ form.set("token", stored.data.token);
127
+ form.set("deviceSessionId", stored.data.deviceSessionId);
128
+ form.set("authentication3DS", JSON.stringify(response.data.parameters3DS));
129
+ if (csrf) form.set("__customer_csrf", csrf);
130
+ authenticationSubmission.current = form;
131
+ submit(form, {
132
+ method: "post",
133
+ action: orderStatusUrl,
134
+ encType: "multipart/form-data"
135
+ });
136
+ };
137
+ window.addEventListener("message", receive);
138
+ sdk.initAuthentication(stored.data.token);
139
+ }
140
+ setError(null);
141
+ setRetryable(false);
142
+ authenticate().catch((error) => {
143
+ if (active) setError(error instanceof Error ? error.message : "No pudimos autenticar tu tarjeta.");
144
+ });
145
+ return () => {
146
+ active = false;
147
+ window.clearTimeout(timer);
148
+ if (receive) window.removeEventListener("message", receive);
149
+ reset?.();
150
+ };
151
+ }, [
152
+ payment.transactionId,
153
+ payment.expiresAt,
154
+ payment.publicConfiguration.publicKey,
155
+ payment.amount,
156
+ payment.currencyCode,
157
+ orderStatusUrl,
158
+ email,
159
+ source,
160
+ csrf,
161
+ submit,
162
+ navigate,
163
+ attempt
164
+ ]);
165
+ const failure = error ?? (result?.ok === false ? result.message : null);
166
+ return /* @__PURE__ */ jsxs("div", {
167
+ className: "flex flex-col gap-4 rounded-lg border p-6",
168
+ children: [
169
+ /* @__PURE__ */ jsx("p", {
170
+ role: "status",
171
+ children: storefrontTranslate("Confirma el pago con tu banco para completar el pedido.")
172
+ }),
173
+ payment.expiresAt ? /* @__PURE__ */ jsxs("p", { children: [
174
+ storefrontTranslate("La autenticación dura hasta 15 minutos y vence el"),
175
+ " ",
176
+ expiry.format(new Date(payment.expiresAt)),
177
+ "."
178
+ ] }) : null,
179
+ failure ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("p", {
180
+ role: "alert",
181
+ children: failure
182
+ }), retryable ? /* @__PURE__ */ jsx("button", {
183
+ type: "button",
184
+ onClick: () => {
185
+ const form = authenticationSubmission.current;
186
+ if (form !== null) submit(form, {
187
+ method: "post",
188
+ action: orderStatusUrl,
189
+ encType: "multipart/form-data"
190
+ });
191
+ else setAttempt((value) => value + 1);
192
+ },
193
+ className: "underline",
194
+ children: authenticationSubmission.current === null ? "Reintentar autenticación" : "Reintentar confirmación"
195
+ }) : null] }) : null,
196
+ /* @__PURE__ */ jsx("a", {
197
+ href: orderStatusUrl,
198
+ className: "underline",
199
+ children: storefrontTranslate("Ver estado del pedido")
200
+ })
201
+ ]
202
+ });
203
+ }
204
+ export { CulqiAuthentication, useOrderAuthentication };
@@ -0,0 +1,15 @@
1
+ import { CulqiPaymentSource } from "./culqi-three-ds.js";
2
+ import { OrderPaymentActionData } from "./order-status.js";
3
+ import { OrderPaymentStart } from "@ecomiq/core";
4
+ export declare function useOrderAuthentication({ result, payment, orderStatusUrl }: {
5
+ result: OrderPaymentActionData | undefined;
6
+ payment: OrderPaymentStart | null;
7
+ orderStatusUrl: string;
8
+ }): void;
9
+ export declare function CulqiAuthentication({ payment, orderStatusUrl, email, source, result }: {
10
+ payment: OrderPaymentStart;
11
+ orderStatusUrl: string;
12
+ email: string | null;
13
+ source: CulqiPaymentSource | null;
14
+ result?: OrderPaymentActionData;
15
+ }): import("react").JSX.Element;
@@ -0,0 +1,55 @@
1
+ // src/culqi-checkout.ts
2
+ const CULQI_TOKEN_METHODS = /* @__PURE__ */ new Map([["card", {
3
+ tarjeta: true,
4
+ yape: false,
5
+ billetera: false,
6
+ bancaMovil: false,
7
+ agente: false,
8
+ cuotealo: false
9
+ }], ["yape", {
10
+ tarjeta: false,
11
+ yape: true,
12
+ billetera: false,
13
+ bancaMovil: false,
14
+ agente: false,
15
+ cuotealo: false
16
+ }]]);
17
+ const CULQI_ORDER_METHODS = /* @__PURE__ */ new Map([["plin", {
18
+ tarjeta: false,
19
+ yape: false,
20
+ billetera: true,
21
+ bancaMovil: false,
22
+ agente: false,
23
+ cuotealo: false
24
+ }], ["pagoefectivo", {
25
+ tarjeta: false,
26
+ yape: false,
27
+ billetera: false,
28
+ bancaMovil: true,
29
+ agente: true,
30
+ cuotealo: false
31
+ }]]);
32
+ let loading;
33
+ function loadCulqiCheckout() {
34
+ if (window.CulqiCheckout) return Promise.resolve(window.CulqiCheckout);
35
+ if (loading) return loading;
36
+ loading = new Promise((resolve, reject) => {
37
+ const script = document.createElement("script");
38
+ script.src = "https://js.culqi.com/checkout-js";
39
+ script.async = true;
40
+ script.onload = () => {
41
+ if (window.CulqiCheckout) resolve(window.CulqiCheckout);
42
+ else reject(/* @__PURE__ */ new Error("No pudimos abrir el pago."));
43
+ };
44
+ script.onerror = () => {
45
+ script.remove();
46
+ reject(/* @__PURE__ */ new Error("No pudimos cargar el pago. Revisa tu conexión e intenta de nuevo."));
47
+ };
48
+ document.head.appendChild(script);
49
+ }).catch((error) => {
50
+ loading = void 0;
51
+ throw error;
52
+ });
53
+ return loading;
54
+ }
55
+ export { CULQI_ORDER_METHODS, CULQI_TOKEN_METHODS, loadCulqiCheckout };
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ // src/culqi-three-ds.ts
3
+ const CulqiPaymentSourceSchema = z.object({
4
+ token: z.string().min(1),
5
+ deviceSessionId: z.string().min(1)
6
+ });
7
+ let loading;
8
+ function loadCulqiThreeDS() {
9
+ if (window.Culqi3DS) return Promise.resolve(window.Culqi3DS);
10
+ if (loading) return loading;
11
+ loading = new Promise((resolve, reject) => {
12
+ const script = document.createElement("script");
13
+ script.src = "https://3ds.culqi.com";
14
+ script.async = true;
15
+ script.onload = () => {
16
+ if (window.Culqi3DS) resolve(window.Culqi3DS);
17
+ else reject(/* @__PURE__ */ new Error("No pudimos cargar la autenticación de tarjeta."));
18
+ };
19
+ script.onerror = () => {
20
+ script.remove();
21
+ reject(/* @__PURE__ */ new Error("No pudimos cargar la autenticación de tarjeta."));
22
+ };
23
+ document.head.appendChild(script);
24
+ }).catch((error) => {
25
+ loading = void 0;
26
+ throw error;
27
+ });
28
+ return loading;
29
+ }
30
+ function culqiSourceKey(transactionId) {
31
+ return `ecomiq:culqi:${transactionId}`;
32
+ }
33
+ export { CulqiPaymentSourceSchema, culqiSourceKey, loadCulqiThreeDS };
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ export declare const CulqiPaymentSourceSchema: z.ZodObject<{
3
+ token: z.ZodString;
4
+ deviceSessionId: z.ZodString;
5
+ }, z.core.$strip>;
6
+ export type CulqiPaymentSource = z.infer<typeof CulqiPaymentSourceSchema>;
7
+ type CulqiThreeDS = {
8
+ publicKey: string;
9
+ settings: {
10
+ charge: {
11
+ totalAmount: number;
12
+ currency: string;
13
+ returnUrl: string;
14
+ };
15
+ card: {
16
+ email: string;
17
+ };
18
+ };
19
+ generateDevice: () => Promise<string | null>;
20
+ initAuthentication: (token: string) => void;
21
+ reset: () => void;
22
+ };
23
+ declare global {
24
+ interface Window {
25
+ Culqi3DS?: CulqiThreeDS;
26
+ }
27
+ }
28
+ export declare function culqiSourceKey(transactionId: string): string;
29
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ // src/customer-avatar.tsx
3
+ /** The signed-in customer's initial, drawn in the header's text color. */
4
+ function CustomerAvatar({ name, className = "" }) {
5
+ const initial = name.trim().charAt(0).toLocaleUpperCase() || "?";
6
+ return /* @__PURE__ */ jsx("span", {
7
+ "aria-hidden": "true",
8
+ className: `inline-flex shrink-0 items-center justify-center rounded-full border-[1.5px] border-current font-semibold leading-none ${className}`,
9
+ children: initial
10
+ });
11
+ }
12
+ export { CustomerAvatar };
@@ -0,0 +1,5 @@
1
+ /** The signed-in customer's initial, drawn in the header's text color. */
2
+ export declare function CustomerAvatar({ name, className }: {
3
+ name: string;
4
+ className?: string;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { createCookie } from "react-router";
2
+ // src/customer-cookies.ts
3
+ const CUSTOMER_COOKIE = "__Host-ecomiq-customer";
4
+ const cookies = /* @__PURE__ */ new Map();
5
+ function customerCookies(env) {
6
+ const secret = env.SESSION_SECRET;
7
+ if (!secret) throw new Error("Falta SESSION_SECRET en el worker.");
8
+ let saved = cookies.get(secret);
9
+ if (!saved) {
10
+ const options = {
11
+ httpOnly: true,
12
+ sameSite: "lax",
13
+ secure: true,
14
+ path: "/",
15
+ secrets: [secret]
16
+ };
17
+ saved = {
18
+ session: createCookie(CUSTOMER_COOKIE, options),
19
+ transaction: createCookie("__Host-ecomiq-customer-login", {
20
+ ...options,
21
+ maxAge: 600
22
+ })
23
+ };
24
+ cookies.set(secret, saved);
25
+ }
26
+ return saved;
27
+ }
28
+ async function customerSessionId(request, env) {
29
+ const value = await customerCookies(env).session.parse(request.headers.get("Cookie"));
30
+ return typeof value === "string" && value.length > 0 && value.length <= 256 ? value : null;
31
+ }
32
+ function base64Url(bytes) {
33
+ return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
34
+ }
35
+ function base64UrlBytes(value) {
36
+ const base64 = value.replace(/-/g, "+").replace(/_/g, "/");
37
+ return Uint8Array.from(atob(base64 + "=".repeat((4 - base64.length % 4) % 4)), (character) => character.charCodeAt(0));
38
+ }
39
+ function equalSecret(left, right) {
40
+ if (left.length !== right.length) return false;
41
+ let difference = 0;
42
+ for (let index = 0; index < left.length; index += 1) difference |= left.charCodeAt(index) ^ right.charCodeAt(index);
43
+ return difference === 0;
44
+ }
45
+ export { CUSTOMER_COOKIE, base64Url, base64UrlBytes, customerCookies, customerSessionId, equalSecret };