@ecomiq/storefront 2.1.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -103
  3. package/dist/account-Dx4e3syi.js +258 -0
  4. package/dist/account-forms-AVk71ko7.js +39 -0
  5. package/dist/account-forms.d.ts +13 -0
  6. package/dist/account.d.ts +240 -0
  7. package/dist/address-defaults-BqjRhS82.js +14 -0
  8. package/dist/address-defaults.d.ts +11 -0
  9. package/dist/analytics/analytics-CG1Qagwl.js +148 -0
  10. package/dist/analytics/analytics.d.ts +1 -0
  11. package/dist/analytics/config-DJr-GRhs.js +62 -0
  12. package/dist/analytics/config.d.ts +22 -0
  13. package/dist/analytics/consent-B13rBpBs.js +57 -0
  14. package/dist/analytics/consent-banner-9QvRRy8v.js +239 -0
  15. package/dist/analytics/consent-banner.d.ts +20 -0
  16. package/dist/analytics/cookies-pLozllyB.js +100 -0
  17. package/dist/analytics/cookies.d.ts +6 -0
  18. package/dist/analytics/destinations-iECrlLIr.js +144 -0
  19. package/dist/analytics/events-Dt81tIp1.js +102 -0
  20. package/dist/analytics/events.d.ts +51 -0
  21. package/dist/analytics/tracker-p4yaoOyk.js +51 -0
  22. package/dist/api-cache-DsuIn5hX.js +159 -0
  23. package/dist/bank-accounts-DlEczQQ5.js +81 -0
  24. package/dist/bank-accounts.d.ts +4 -0
  25. package/dist/captcha-DAqaIx8m.js +117 -0
  26. package/dist/captcha.d.ts +34 -0
  27. package/dist/cart-D7DxZ2lD.js +30 -0
  28. package/dist/cart-actions-Bsub_FFG.js +116 -0
  29. package/dist/cart-actions.d.ts +15 -0
  30. package/dist/cart-drawer-B7PPsR69.js +22 -0
  31. package/dist/cart-drawer.d.ts +9 -0
  32. package/dist/cart-form-y9P1r_EX.js +81 -0
  33. package/dist/cart-form.d.ts +24 -0
  34. package/dist/cart-summary-ur2VWKr-.js +89 -0
  35. package/dist/cart-summary.d.ts +31 -0
  36. package/dist/cart.d.ts +4 -0
  37. package/dist/catalog-7gJ-l5hW.js +67 -0
  38. package/dist/catalog-hooks-B7ZP4wYY.js +312 -0
  39. package/dist/catalog-hooks.d.ts +111 -0
  40. package/dist/catalog.d.ts +5 -0
  41. package/dist/checkout-DVWSXANi.js +474 -0
  42. package/dist/checkout-form-CbOIdENC.js +131 -0
  43. package/dist/checkout-form.d.ts +20 -0
  44. package/dist/checkout.d.ts +86 -0
  45. package/dist/complaint-book-BvwLvfx0.js +117 -0
  46. package/dist/complaint-book.d.ts +62 -0
  47. package/dist/culqi-authentication-BGr20vAJ.js +204 -0
  48. package/dist/culqi-authentication.d.ts +15 -0
  49. package/dist/culqi-checkout-CTXpKgp_.js +55 -0
  50. package/dist/culqi-three-ds-HP3mfrvV.js +33 -0
  51. package/dist/culqi-three-ds.d.ts +29 -0
  52. package/dist/customer-avatar-CJXSDroK.js +12 -0
  53. package/dist/customer-avatar.d.ts +5 -0
  54. package/dist/customer-cookies-DHOgFAMV.js +45 -0
  55. package/dist/customer-csrf-C1oDX-Py.js +17 -0
  56. package/dist/customer-csrf.d.ts +3 -0
  57. package/dist/customer-document-fields-C1K-_DAD.js +70 -0
  58. package/dist/customer-document-fields.d.ts +9 -0
  59. package/dist/customer-login-form-C7AC6vXd.js +144 -0
  60. package/dist/customer-login-form.d.ts +17 -0
  61. package/dist/customer-registration-form-BEm_NEfP.js +93 -0
  62. package/dist/customer-registration-form.d.ts +8 -0
  63. package/dist/document-url-CGsAl5Tf.js +9 -0
  64. package/dist/documents-T1mzc_j8.js +38 -0
  65. package/dist/documents.d.ts +16 -0
  66. package/dist/entries/account.d.ts +11 -0
  67. package/dist/entries/account.js +10 -0
  68. package/dist/entries/analytics.d.ts +6 -0
  69. package/dist/entries/analytics.js +5 -0
  70. package/dist/entries/cart.d.ts +8 -0
  71. package/dist/entries/cart.js +7 -0
  72. package/dist/entries/checkout.d.ts +12 -0
  73. package/dist/entries/checkout.js +11 -0
  74. package/dist/entries/order.d.ts +11 -0
  75. package/dist/entries/order.js +11 -0
  76. package/dist/favicon-YpyhVJ9H.js +28 -0
  77. package/dist/favicon.d.ts +4 -0
  78. package/dist/form-BtQcbXlJ.js +18 -0
  79. package/dist/form-contracts-BNpHaTGJ.js +166 -0
  80. package/dist/form-contracts.d.ts +42 -0
  81. package/dist/form.d.ts +3 -0
  82. package/dist/hidden-CCWtOWKR.js +3 -0
  83. package/dist/hidden.d.ts +4 -0
  84. package/dist/index.d.ts +50 -0
  85. package/dist/index.js +50 -0
  86. package/dist/invoice-fields-BG0HjL6T.js +103 -0
  87. package/dist/invoice-fields.d.ts +39 -0
  88. package/dist/links-kFxBZfdb.js +96 -0
  89. package/dist/links.d.ts +21 -0
  90. package/dist/mercadopago-checkout-DC7RXa8k.js +27 -0
  91. package/dist/mercadopago-dialog-UTQev0MG.js +180 -0
  92. package/dist/mercadopago-dialog.d.ts +21 -0
  93. package/dist/money-DtGOtDri.js +32 -0
  94. package/dist/money.d.ts +1 -0
  95. package/dist/optimistic-cart-BveVOHuh.js +53 -0
  96. package/dist/optimistic-cart.d.ts +16 -0
  97. package/dist/order-display-DTt5WBbc.js +112 -0
  98. package/dist/order-display.d.ts +20 -0
  99. package/dist/order-draft-DxV1Uhm3.js +38 -0
  100. package/dist/order-draft.d.ts +16 -0
  101. package/dist/order-pages-Dm6l5m0m.js +38 -0
  102. package/dist/order-pages.d.ts +12 -0
  103. package/dist/order-payment-continuation-D_d5PGA4.js +212 -0
  104. package/dist/order-payment-continuation.d.ts +10 -0
  105. package/dist/order-payment-in-review-x4gdLFHZ.js +65 -0
  106. package/dist/order-payment-in-review.d.ts +5 -0
  107. package/dist/order-status-BJXLJwxq.js +162 -0
  108. package/dist/order-status.d.ts +89 -0
  109. package/dist/order-view-9IlBg5AF.js +62 -0
  110. package/dist/order-view.d.ts +12 -0
  111. package/dist/page-action-Ctkf4xC6.js +7 -0
  112. package/dist/page-seo-a5FJl8x5.js +262 -0
  113. package/dist/page-seo.d.ts +34 -0
  114. package/dist/pages-Ca_Gt6mq.js +150 -0
  115. package/dist/pages.d.ts +45 -0
  116. package/dist/payment-dialog-frame-B-Q_xQ94.js +57 -0
  117. package/dist/payment-logo-BoPaGJc_.js +46 -0
  118. package/dist/payment-logo-svgs-By9lDTLK.js +20 -0
  119. package/dist/payment-logo.d.ts +11 -0
  120. package/dist/payment-logos-BYvdwYyJ.js +23 -0
  121. package/dist/payment-methods-B8ocTgFZ.js +73 -0
  122. package/dist/payment-methods.d.ts +58 -0
  123. package/dist/payment-return-5cjypwIw.js +7 -0
  124. package/dist/place-CmW4hBWY.js +13 -0
  125. package/dist/place.d.ts +4 -0
  126. package/dist/preview-BiIBif3C.js +427 -0
  127. package/dist/preview-address-Cf0sJ-9p.js +21 -0
  128. package/dist/preview-cart-Dg2CVktS.js +376 -0
  129. package/dist/product-preview-BspMAecJ.js +51 -0
  130. package/dist/product-preview.d.ts +5 -0
  131. package/dist/product-variants-BNDHvs1y.js +46 -0
  132. package/dist/product-variants.d.ts +12 -0
  133. package/dist/public-pages-XtwlaLwt.js +194 -0
  134. package/dist/public-pages.d.ts +67 -0
  135. package/dist/registration-CpDcv8ql.js +91 -0
  136. package/dist/registration.d.ts +12 -0
  137. package/dist/request-security-CRsRMgwj.js +76 -0
  138. package/dist/rich-text-M-Ju8RL4.js +9 -0
  139. package/dist/rich-text.d.ts +5 -0
  140. package/dist/route-text-DcJw2SsK.js +9 -0
  141. package/dist/route-text.d.ts +4 -0
  142. package/dist/section-preview-CmsMl3yu.js +83 -0
  143. package/dist/section-preview.d.ts +12 -0
  144. package/dist/sections/account-addresses.d.ts +18 -0
  145. package/dist/sections/account-addresses.js +375 -0
  146. package/dist/sections/account-order.d.ts +12 -0
  147. package/dist/sections/account-order.js +592 -0
  148. package/dist/sections/account-orders.d.ts +8 -0
  149. package/dist/sections/account-orders.js +359 -0
  150. package/dist/sections/account-profile.d.ts +16 -0
  151. package/dist/sections/account-profile.js +123 -0
  152. package/dist/sections/checkout.d.ts +24 -0
  153. package/dist/sections/checkout.js +963 -0
  154. package/dist/sections/complaint-book.d.ts +8 -0
  155. package/dist/sections/complaint-book.js +538 -0
  156. package/dist/sections/design-system.d.ts +1 -0
  157. package/dist/sections/design-system.js +310 -0
  158. package/dist/sections/draft-invoice.d.ts +20 -0
  159. package/dist/sections/draft-invoice.js +158 -0
  160. package/dist/sections/order-tracking.d.ts +19 -0
  161. package/dist/sections/order-tracking.js +141 -0
  162. package/dist/sections-CNUMWTF_.js +77 -0
  163. package/dist/sections.d.ts +19 -0
  164. package/dist/seo-GpDRhAAA.js +78 -0
  165. package/dist/session-CKvmFJyg.js +379 -0
  166. package/dist/session.d.ts +24 -0
  167. package/dist/settings-B0NO2A6Y.js +78 -0
  168. package/dist/settings.d.ts +51 -0
  169. package/dist/source-marker-DhqSkW7n.js +4 -0
  170. package/dist/sources-B-3JFJfb.js +46 -0
  171. package/dist/sources.d.ts +7 -0
  172. package/dist/store-8Q-_LFrQ.js +152 -0
  173. package/dist/store-contact--hY6CoFb.js +19 -0
  174. package/dist/store-contact.d.ts +6 -0
  175. package/dist/store.d.ts +17 -0
  176. package/dist/storefront-language-DrMjVbmk.js +29 -0
  177. package/dist/storefront-language.d.ts +14 -0
  178. package/dist/storefront-text-D25ae1qf.js +11 -0
  179. package/dist/storefront-text-en-ljjjSS4q.js +1030 -0
  180. package/dist/storefront-text-pt-BtHaJLcp.js +1030 -0
  181. package/dist/storefront-text.d.ts +4 -0
  182. package/dist/stripe-dialog-Ev9s3Z62.js +396 -0
  183. package/dist/stripe-dialog.d.ts +30 -0
  184. package/dist/telemetry-HuZXWBPi.js +114 -0
  185. package/dist/telemetry.d.ts +10 -0
  186. package/dist/templates-CAqoNyTW.js +40 -0
  187. package/dist/templates.d.ts +15 -0
  188. package/dist/urls-CpGQPxvf.js +71 -0
  189. package/dist/urls.d.ts +18 -0
  190. package/dist/use-checkout-CZcxXJXi.js +42 -0
  191. package/dist/use-checkout-payment-9R-zacrJ.js +80 -0
  192. package/dist/use-checkout-payment.d.ts +18 -0
  193. package/dist/use-checkout.d.ts +36 -0
  194. package/dist/use-culqi-checkout-CrjLAipU.js +109 -0
  195. package/dist/use-order-payment-BKIz_IO0.js +45 -0
  196. package/dist/use-order-payment.d.ts +18 -0
  197. package/dist/use-payment-token-CErx-tN-.js +105 -0
  198. package/dist/vite-payment-logos-kziu7wKb.js +27 -0
  199. package/dist/vite-payment-logos.d.ts +24 -0
  200. package/dist/vite-public-assets-DW2fgtVb.js +209 -0
  201. package/dist/vite-public-assets.d.ts +29 -0
  202. package/dist/vite-sections-DTBr0-Kg.js +464 -0
  203. package/dist/vite-sections.d.ts +21 -0
  204. package/dist/vite-theme-ui-BMO-CDi3.js +41 -0
  205. package/dist/vite-theme-ui.d.ts +10 -0
  206. package/dist/vite.d.ts +36 -0
  207. package/dist/vite.js +127 -0
  208. package/dist/voucher-payment-CVFDZ1L8.js +66 -0
  209. package/dist/worker-CNi-gzCu.js +86 -0
  210. package/dist/worker.d.ts +27 -0
  211. package/package.json +100 -76
  212. package/src/sections/account-addresses.tsx +215 -0
  213. package/src/sections/account-order.tsx +424 -0
  214. package/src/sections/account-orders.tsx +259 -0
  215. package/src/sections/account-profile.tsx +70 -0
  216. package/src/sections/checkout.tsx +586 -0
  217. package/src/sections/complaint-book.tsx +325 -0
  218. package/src/sections/design-system.tsx +146 -0
  219. package/src/sections/draft-invoice.tsx +105 -0
  220. package/src/sections/order-tracking.tsx +81 -0
  221. package/src/vite-client.d.ts +4 -0
  222. package/bin/ecomiq.mjs +0 -179
  223. package/public/design-bridge.js +0 -318
  224. package/src/api-proxy.ts +0 -194
  225. package/src/auth/create-storefront-auth.ts +0 -94
  226. package/src/auth/ecomiq-oauth-password-client.ts +0 -26
  227. package/src/auth/ecomiq-oauth-password-constants.ts +0 -24
  228. package/src/auth/ecomiq-oauth-password-plugin.ts +0 -294
  229. package/src/auth/ecomiq-oauth-password-types.ts +0 -24
  230. package/src/auth/ecomiq-storefront-sign-in.ts +0 -44
  231. package/src/auth/env.ts +0 -7
  232. package/src/auth/secure-cookies.ts +0 -23
  233. package/src/auth/storefront-auth-base-url.ts +0 -117
  234. package/src/auth/storefront-auth.ts +0 -7
  235. package/src/cart-session.ts +0 -239
  236. package/src/client.ts +0 -48
  237. package/src/codegen.mjs +0 -801
  238. package/src/components/account/customer-addresses-panel.tsx +0 -678
  239. package/src/components/account/customer-order-detail-panel.tsx +0 -285
  240. package/src/components/account/customer-orders-panel.tsx +0 -192
  241. package/src/components/account/customer-profile-panel.tsx +0 -379
  242. package/src/components/checkout/cart-sync.ts +0 -143
  243. package/src/components/checkout/checkout-contact-section.tsx +0 -76
  244. package/src/components/checkout/checkout-external-update-banner.tsx +0 -15
  245. package/src/components/checkout/checkout-form-controls.tsx +0 -139
  246. package/src/components/checkout/checkout-line-items.tsx +0 -43
  247. package/src/components/checkout/checkout-order-summary.tsx +0 -165
  248. package/src/components/checkout/checkout-payment-section.tsx +0 -212
  249. package/src/components/checkout/checkout-session-view.tsx +0 -564
  250. package/src/components/checkout/checkout-shipping-address-section.tsx +0 -400
  251. package/src/components/checkout/checkout-shipping-section.tsx +0 -98
  252. package/src/components/checkout/checkout-states.tsx +0 -73
  253. package/src/components/checkout/checkout-step-card.tsx +0 -101
  254. package/src/components/checkout/checkout-steps.ts +0 -111
  255. package/src/components/checkout/form-schema.ts +0 -281
  256. package/src/components/checkout/format.ts +0 -15
  257. package/src/components/checkout/index.ts +0 -5
  258. package/src/components/checkout/map-customer-to-checkout.ts +0 -188
  259. package/src/components/checkout/types.ts +0 -41
  260. package/src/components/checkout/use-checkout-customer-prefill.ts +0 -409
  261. package/src/components/checkout/use-checkout-geo.ts +0 -50
  262. package/src/components/checkout/use-checkout-session.ts +0 -640
  263. package/src/components/hero.tsx +0 -291
  264. package/src/config.d.ts +0 -94
  265. package/src/config.mjs +0 -146
  266. package/src/format-money.ts +0 -31
  267. package/src/health.ts +0 -90
  268. package/src/hooks/index.ts +0 -9
  269. package/src/hooks/recently-viewed.ts +0 -125
  270. package/src/index.ts +0 -349
  271. package/src/link.tsx +0 -2
  272. package/src/pages/account/account-page-skeleton.tsx +0 -69
  273. package/src/pages/account/account-page-view.tsx +0 -270
  274. package/src/pages/account/account-shell.tsx +0 -101
  275. package/src/pages/account/parse-account-route.ts +0 -36
  276. package/src/pages/account.tsx +0 -16
  277. package/src/pages/api.$.ts +0 -20
  278. package/src/pages/api.auth.$.ts +0 -16
  279. package/src/pages/checkout.$checkoutId.tsx +0 -60
  280. package/src/pages/checkout.tsx +0 -31
  281. package/src/pages/pages.$pageSlug.tsx +0 -74
  282. package/src/pages/thank-you.tsx +0 -53
  283. package/src/providers/auth.tsx +0 -96
  284. package/src/providers/cart.tsx +0 -275
  285. package/src/providers/ecomiq.ts +0 -137
  286. package/src/providers/index.ts +0 -26
  287. package/src/proxy-api.ts +0 -20
  288. package/src/public-config.ts +0 -24
  289. package/src/review-submission.ts +0 -89
  290. package/src/runtime/context.ts +0 -2
  291. package/src/runtime/default-layout.tsx +0 -64
  292. package/src/runtime/head.ts +0 -149
  293. package/src/runtime/page.tsx +0 -143
  294. package/src/runtime/postcss-browser-stub.mjs +0 -5
  295. package/src/server-config-store.ts +0 -35
  296. package/src/server.ts +0 -286
  297. package/src/styles.css +0 -76
  298. package/src/ui/badge.tsx +0 -32
  299. package/src/ui/button.tsx +0 -31
  300. package/src/ui/card.tsx +0 -31
  301. package/src/ui/carousel.tsx +0 -218
  302. package/src/ui/cn.ts +0 -6
  303. package/src/ui/index.ts +0 -8
  304. package/src/ui/separator.tsx +0 -6
  305. package/src/ui/skeleton.tsx +0 -6
  306. package/src/ui/storefront-error.tsx +0 -49
  307. package/src/utils.ts +0 -36
  308. package/src/vite-inline.mjs +0 -263
  309. package/templates/__root.tsx +0 -83
  310. package/templates/router.tsx +0 -19
@@ -0,0 +1,464 @@
1
+ import { SOURCE, SOURCES_PROP } from "./source-marker-DhqSkW7n.js";
2
+ import { existsSync, readFileSync, statSync } from "node:fs";
3
+ import { dirname, relative, resolve, sep } from "node:path";
4
+ import { parse } from "@babel/parser";
5
+ import { VISITOR_KEYS, traverseFast } from "@babel/types";
6
+ // src/vite-sections.ts
7
+ var SectionPropsError = class extends Error {};
8
+ function parseModule(code) {
9
+ return parse(code, {
10
+ sourceType: "module",
11
+ plugins: ["typescript", "jsx"]
12
+ });
13
+ }
14
+ function exportedLoad(program) {
15
+ return program.some((node) => {
16
+ if (node.type !== "ExportNamedDeclaration" || !node.declaration) return false;
17
+ const declaration = node.declaration;
18
+ if (declaration.type === "FunctionDeclaration") return declaration.id?.name === "load";
19
+ if (declaration.type === "VariableDeclaration") return declaration.declarations.some((item) => item.id.type === "Identifier" && item.id.name === "load");
20
+ return false;
21
+ });
22
+ }
23
+ function callsUseSection(body) {
24
+ let found = false;
25
+ traverseFast(body, (node) => {
26
+ if (node.type !== "CallExpression" || node.callee.type !== "Identifier" || node.callee.name !== "useSection") return;
27
+ const first = node.arguments[0];
28
+ if (first?.type === "Identifier" && first.name === "load") found = true;
29
+ });
30
+ return found;
31
+ }
32
+ function sectionsOf(code) {
33
+ const program = parseModule(code).program.body;
34
+ const sections = /* @__PURE__ */ new Set();
35
+ for (const node of program) {
36
+ if (node.type !== "ExportNamedDeclaration" || !node.declaration) continue;
37
+ const declaration = node.declaration;
38
+ if (declaration.type === "FunctionDeclaration" && declaration.id && callsUseSection(declaration.body)) sections.add(declaration.id.name);
39
+ if (declaration.type !== "VariableDeclaration") continue;
40
+ for (const item of declaration.declarations) if (item.id.type === "Identifier" && item.init && callsUseSection(item.init)) sections.add(item.id.name);
41
+ }
42
+ return {
43
+ load: exportedLoad(program),
44
+ sections
45
+ };
46
+ }
47
+ function unwrap(node) {
48
+ if (node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression" || node.type === "ParenthesizedExpression") return unwrap(node.expression);
49
+ return node;
50
+ }
51
+ function literal(input) {
52
+ const node = unwrap(input);
53
+ if (node.type === "StringLiteral" || node.type === "NumericLiteral" || node.type === "BooleanLiteral") return {
54
+ ok: true,
55
+ value: node.value
56
+ };
57
+ if (node.type === "NullLiteral") return {
58
+ ok: true,
59
+ value: null
60
+ };
61
+ if (node.type === "TemplateLiteral" && node.expressions.length === 0) return {
62
+ ok: true,
63
+ value: node.quasis[0]?.value.cooked ?? ""
64
+ };
65
+ if (node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "NumericLiteral") return {
66
+ ok: true,
67
+ value: -node.argument.value
68
+ };
69
+ if (node.type === "ArrayExpression") {
70
+ const values = [];
71
+ for (const element of node.elements) {
72
+ if (!element || element.type === "SpreadElement") return { ok: false };
73
+ const item = literal(element);
74
+ if (!item.ok) return item;
75
+ values.push(item.value);
76
+ }
77
+ return {
78
+ ok: true,
79
+ value: values
80
+ };
81
+ }
82
+ if (node.type === "ObjectExpression") {
83
+ const values = {};
84
+ for (const property of node.properties) {
85
+ if (property.type !== "ObjectProperty" || property.computed) return { ok: false };
86
+ let key;
87
+ if (property.key.type === "Identifier") key = property.key.name;
88
+ if (property.key.type === "StringLiteral") key = property.key.value;
89
+ if (key === void 0) return { ok: false };
90
+ const item = literal(property.value);
91
+ if (!item.ok) return item;
92
+ values[key] = item.value;
93
+ }
94
+ return {
95
+ ok: true,
96
+ value: values
97
+ };
98
+ }
99
+ return { ok: false };
100
+ }
101
+ function jsxProps(node, where, name) {
102
+ const props = {};
103
+ for (const attribute of node.attributes) {
104
+ if (attribute.type === "JSXSpreadAttribute") throw new SectionPropsError(`${where}: <${name}> carga sus datos y no acepta {...props}.`);
105
+ const key = attribute.name.type === "JSXIdentifier" ? attribute.name.name : `${attribute.name.namespace.name}:${attribute.name.name.name}`;
106
+ if (key === "key" || key.startsWith("data-")) continue;
107
+ const value = attribute.value;
108
+ if (value === null || value === void 0) {
109
+ props[key] = true;
110
+ continue;
111
+ }
112
+ if (value.type === "StringLiteral") {
113
+ if (!SOURCE.test(value.value)) props[key] = value.value;
114
+ continue;
115
+ }
116
+ const parsed = value.type === "JSXExpressionContainer" && value.expression.type !== "JSXEmptyExpression" ? literal(value.expression) : { ok: false };
117
+ if (!parsed.ok) throw new SectionPropsError(`${where}: <${name}> carga sus datos y solo acepta valores fijos; ${key} no lo es.`);
118
+ props[key] = parsed.value;
119
+ }
120
+ return props;
121
+ }
122
+ function resolveModule(source, importer, app) {
123
+ let base;
124
+ if (source.startsWith("~/")) base = resolve(app, source.slice(2));
125
+ if (source.startsWith("./") || source.startsWith("../")) base = resolve(dirname(importer), source);
126
+ if (base === void 0) return void 0;
127
+ for (const candidate of [
128
+ base,
129
+ `${base}.tsx`,
130
+ `${base}.ts`,
131
+ resolve(base, "index.tsx"),
132
+ resolve(base, "index.ts")
133
+ ]) if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;
134
+ }
135
+ function blank(text) {
136
+ return "\n".repeat(text.split("\n").length - 1);
137
+ }
138
+ function applyEdits(code, edits) {
139
+ let next = code;
140
+ for (const edit of [...edits].sort((a, b) => b.start - a.start)) next = `${next.slice(0, edit.start)}${edit.text}${next.slice(edit.end)}`;
141
+ return next;
142
+ }
143
+ const NOT_REFERENCES = {
144
+ MemberExpression: ["property"],
145
+ OptionalMemberExpression: ["property"],
146
+ ObjectProperty: ["key"],
147
+ ObjectMethod: ["key"],
148
+ ClassProperty: ["key"],
149
+ ClassMethod: ["key"],
150
+ TSPropertySignature: ["key"],
151
+ TSMethodSignature: ["key"],
152
+ TSQualifiedName: ["right"],
153
+ JSXAttribute: ["name"],
154
+ JSXMemberExpression: ["property"],
155
+ LabeledStatement: ["label"],
156
+ BreakStatement: ["label"],
157
+ ContinueStatement: ["label"]
158
+ };
159
+ function usedNames(program) {
160
+ const names = /* @__PURE__ */ new Set();
161
+ const visit = (node) => {
162
+ if (node.type === "Identifier" || node.type === "JSXIdentifier") names.add(node.name);
163
+ const skipped = node.computed ? [] : NOT_REFERENCES[node.type] ?? [];
164
+ for (const key of VISITOR_KEYS[node.type] ?? []) {
165
+ if (skipped.includes(key)) continue;
166
+ const child = node[key];
167
+ if (Array.isArray(child)) child.forEach((item) => item && visit(item));
168
+ else if (child) visit(child);
169
+ }
170
+ };
171
+ for (const node of program) if (node.type !== "ImportDeclaration") visit(node);
172
+ return names;
173
+ }
174
+ function clientSection(code) {
175
+ const edits = [];
176
+ for (const node of parseModule(code).program.body) {
177
+ if (node.type !== "ExportNamedDeclaration" || !node.declaration) continue;
178
+ const declaration = node.declaration;
179
+ if (declaration.type === "FunctionDeclaration" && declaration.id?.name === "load") {
180
+ const body = declaration.body;
181
+ edits.push({
182
+ start: body.start,
183
+ end: body.end,
184
+ text: `{ return undefined; }${blank(code.slice(body.start, body.end))}`
185
+ });
186
+ }
187
+ if (declaration.type !== "VariableDeclaration") continue;
188
+ for (const item of declaration.declarations) {
189
+ if (item.id.type !== "Identifier" || item.id.name !== "load" || !item.init) continue;
190
+ edits.push({
191
+ start: item.init.start,
192
+ end: item.init.end,
193
+ text: `async () => undefined${blank(code.slice(item.init.start, item.init.end))}`
194
+ });
195
+ }
196
+ }
197
+ if (edits.length === 0) return code;
198
+ const stripped = applyEdits(code, edits);
199
+ const program = parseModule(stripped).program.body;
200
+ const used = usedNames(program);
201
+ const imports = [];
202
+ for (const node of program) {
203
+ if (node.type !== "ImportDeclaration" || node.importKind === "type" || node.specifiers.length === 0) continue;
204
+ const keep = node.specifiers.filter((specifier) => specifier.type === "ImportSpecifier" && specifier.importKind === "type" || used.has(specifier.local.name));
205
+ if (keep.length === node.specifiers.length) continue;
206
+ const original = stripped.slice(node.start, node.end);
207
+ if (keep.length === 0) {
208
+ imports.push({
209
+ start: node.start,
210
+ end: node.end,
211
+ text: blank(original)
212
+ });
213
+ continue;
214
+ }
215
+ const named = keep.filter((specifier) => specifier.type === "ImportSpecifier").map((specifier) => stripped.slice(specifier.start, specifier.end));
216
+ const parts = [
217
+ ...keep.filter((specifier) => specifier.type === "ImportDefaultSpecifier").map((specifier) => specifier.local.name),
218
+ ...keep.filter((specifier) => specifier.type === "ImportNamespaceSpecifier").map((specifier) => `* as ${specifier.local.name}`),
219
+ ...named.length > 0 ? [`{ ${named.join(", ")} }`] : []
220
+ ];
221
+ imports.push({
222
+ start: node.start,
223
+ end: node.end,
224
+ text: `import ${parts.join(", ")} from ${stripped.slice(node.source.start, node.source.end)};${blank(original)}`
225
+ });
226
+ }
227
+ return applyEdits(stripped, imports);
228
+ }
229
+ function progressiveSections(code) {
230
+ const { sections } = sectionsOf(code);
231
+ const edits = [];
232
+ const exports = [];
233
+ for (const node of parseModule(code).program.body) {
234
+ if (node.type !== "ExportNamedDeclaration" || !node.declaration) continue;
235
+ const declaration = node.declaration;
236
+ if (declaration.type === "FunctionDeclaration" && declaration.id && sections.has(declaration.id.name)) {
237
+ const name = declaration.id.name;
238
+ const internal = `__ecomiqSection${name}`;
239
+ edits.push({
240
+ start: node.start,
241
+ end: declaration.start,
242
+ text: ""
243
+ });
244
+ edits.push({
245
+ start: declaration.id.start,
246
+ end: declaration.id.end,
247
+ text: internal
248
+ });
249
+ exports.push(`export const ${name} = __ecomiqWithSectionBoundary(${internal});`);
250
+ }
251
+ if (declaration.type !== "VariableDeclaration") continue;
252
+ for (const item of declaration.declarations) {
253
+ if (item.id.type !== "Identifier" || !sections.has(item.id.name) || !item.init) continue;
254
+ edits.push({
255
+ start: item.init.start,
256
+ end: item.init.end,
257
+ text: `__ecomiqWithSectionBoundary(${code.slice(item.init.start, item.init.end)})`
258
+ });
259
+ }
260
+ }
261
+ if (edits.length === 0) return code;
262
+ return `${applyEdits(code, edits)}\nimport { withSectionBoundary as __ecomiqWithSectionBoundary } from "@ecomiq/storefront";\n${exports.join("\n")}\n`;
263
+ }
264
+ function renameLoader(code, program) {
265
+ for (const node of program) {
266
+ if (node.type !== "ExportNamedDeclaration") continue;
267
+ if (node.specifiers.some((specifier) => specifier.exported.type === "Identifier" && specifier.exported.name === "loader")) throw new SectionPropsError("Declara el loader como export async function loader para que las secciones carguen sus datos.");
268
+ const declaration = node.declaration;
269
+ if (declaration?.type === "FunctionDeclaration" && declaration.id?.name === "loader") {
270
+ const head = `${declaration.async ? "async " : ""}function __ecomiqPageLoader`;
271
+ return {
272
+ code: `${code.slice(0, node.start)}${head}${code.slice(declaration.id.end)}`,
273
+ found: true
274
+ };
275
+ }
276
+ if (declaration?.type === "VariableDeclaration") {
277
+ const item = declaration.declarations.find((entry) => entry.id.type === "Identifier" && entry.id.name === "loader");
278
+ if (!item) continue;
279
+ const start = item.id.start;
280
+ const renamed = `${code.slice(0, start)}__ecomiqPageLoader${code.slice(start + 6)}`;
281
+ return {
282
+ code: `${renamed.slice(0, node.start)}${renamed.slice(declaration.start)}`,
283
+ found: true
284
+ };
285
+ }
286
+ }
287
+ return {
288
+ code,
289
+ found: false
290
+ };
291
+ }
292
+ const TEMPLATED = {
293
+ "app/routes/product.tsx": "product",
294
+ "app/routes/collection.tsx": "collection",
295
+ "app/routes/page.tsx": "page"
296
+ };
297
+ const DEFAULT_COMPONENT = "__ecomiqDefault";
298
+ function wrapper(kind, head) {
299
+ const page = `__ecomiqCreateElement(__ecomiqTemplateComponent(__ecomiqTemplates, ${JSON.stringify(kind)}, props.loaderData) ?? ${DEFAULT_COMPONENT}, props)`;
300
+ return [
301
+ `import { createElement as __ecomiqCreateElement } from "react";`,
302
+ `import { SourceProvider as __ecomiqSourceProvider, templateComponent as __ecomiqTemplateComponent } from "@ecomiq/storefront";`,
303
+ `const __ecomiqTemplates = import.meta.glob("/app/templates/${kind}.*.tsx", { eager: true });`,
304
+ `${head}(props) { return __ecomiqCreateElement(__ecomiqSourceProvider, { value: props.loaderData }, ${page}); }`
305
+ ].join("\n");
306
+ }
307
+ function sourcedProps(code) {
308
+ const edits = [];
309
+ traverseFast(parseModule(code), (node) => {
310
+ if (node.type !== "JSXOpeningElement") return;
311
+ const sourced = [];
312
+ for (const attribute of node.attributes) {
313
+ if (attribute.type !== "JSXAttribute" || attribute.name.type !== "JSXIdentifier" || attribute.value?.type !== "StringLiteral") continue;
314
+ const match = SOURCE.exec(attribute.value.value);
315
+ if (match === null) continue;
316
+ sourced.push(attribute.name.name);
317
+ edits.push({
318
+ start: attribute.value.start,
319
+ end: attribute.value.end,
320
+ text: `{__ecomiqSource(${JSON.stringify(match[1])})}`
321
+ });
322
+ }
323
+ if (sourced.length > 0) edits.push({
324
+ start: node.name.end,
325
+ end: node.name.end,
326
+ text: ` ${SOURCES_PROP}=${JSON.stringify(sourced.join(" "))}`
327
+ });
328
+ });
329
+ if (edits.length === 0) return void 0;
330
+ return `${applyEdits(code, edits)}\nimport { source as __ecomiqSource } from "@ecomiq/storefront";\n`;
331
+ }
332
+ function templatedComponent(code, kind) {
333
+ const program = parseModule(code).program.body;
334
+ const exported = program.find((node) => node.type === "ExportDefaultDeclaration");
335
+ if (exported?.type !== "ExportDefaultDeclaration") return void 0;
336
+ const declaration = exported.declaration;
337
+ if (declaration.type === "FunctionDeclaration") {
338
+ const name = declaration.id?.name ?? "__EcomiqTemplated";
339
+ const end = declaration.id?.end ?? declaration.start + 8;
340
+ return `${`${code.slice(0, exported.start)}function ${DEFAULT_COMPONENT}${code.slice(end)}`}\n${wrapper(kind, `export default function ${name}`)}\n`;
341
+ }
342
+ if (declaration.type !== "Identifier") return void 0;
343
+ const name = declaration.name;
344
+ for (const node of program) {
345
+ const own = node.type === "ExportNamedDeclaration" ? node.declaration : node;
346
+ if (own?.type !== "FunctionDeclaration" || own.id?.name !== name) continue;
347
+ return `${`${code.slice(0, own.id.start)}${DEFAULT_COMPONENT}${code.slice(own.id.end)}`}\n${wrapper(kind, node.type === "ExportNamedDeclaration" ? `export function ${name}` : `function ${name}`)}\n`;
348
+ }
349
+ }
350
+ function sectionLoaders() {
351
+ let root = "";
352
+ let app = "";
353
+ const modules = /* @__PURE__ */ new Map();
354
+ const moduleAt = (path) => {
355
+ const mtime = statSync(path).mtimeMs;
356
+ const cached = modules.get(path);
357
+ if (cached?.mtime === mtime) return cached;
358
+ try {
359
+ const read = sectionsOf(readFileSync(path, "utf8"));
360
+ const next = {
361
+ mtime,
362
+ load: read.load,
363
+ sections: read.sections
364
+ };
365
+ modules.set(path, next);
366
+ return next;
367
+ } catch {
368
+ return;
369
+ }
370
+ };
371
+ const fileOf = (path) => relative(root, path).split(sep).join("/");
372
+ function usagesOf(code, path, watch) {
373
+ const ast = parseModule(code);
374
+ const program = ast.program.body;
375
+ const imports = /* @__PURE__ */ new Map();
376
+ for (const node of program) {
377
+ if (node.type !== "ImportDeclaration" || node.importKind === "type") continue;
378
+ for (const specifier of node.specifiers) {
379
+ if (specifier.type === "ImportSpecifier" && specifier.importKind !== "type") imports.set(specifier.local.name, {
380
+ source: node.source.value,
381
+ imported: specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value
382
+ });
383
+ if (specifier.type === "ImportDefaultSpecifier") imports.set(specifier.local.name, {
384
+ source: node.source.value,
385
+ imported: "default"
386
+ });
387
+ }
388
+ }
389
+ const usages = [];
390
+ const file = fileOf(path);
391
+ traverseFast(ast, (node) => {
392
+ if (node.type !== "JSXOpeningElement" || node.name.type !== "JSXIdentifier") return;
393
+ const target = imports.get(node.name.name);
394
+ if (!target) return;
395
+ const resolved = resolveModule(target.source, path, app);
396
+ if (!resolved) return;
397
+ watch(resolved);
398
+ const module = moduleAt(resolved);
399
+ if (!module?.load || !module.sections.has(target.imported)) return;
400
+ usages.push({
401
+ source: target.source,
402
+ file: fileOf(resolved),
403
+ props: jsxProps(node, `${file}:${node.loc?.start.line ?? 0}`, node.name.name)
404
+ });
405
+ });
406
+ return {
407
+ usages,
408
+ program
409
+ };
410
+ }
411
+ function sectionsCode(usages, exported) {
412
+ const sources = [...new Set(usages.map((usage) => usage.source))];
413
+ return [...sources.map((source, index) => `import { load as __ecomiqLoad${index} } from ${JSON.stringify(source)};`), `${exported ? "export " : ""}const __ecomiqSections = [${usages.map((usage) => `{ section: ${JSON.stringify(usage.file)}, load: __ecomiqLoad${sources.indexOf(usage.source)}, props: ${JSON.stringify(usage.props)} }`).join(", ")}];`];
414
+ }
415
+ function transformRoute(code, path, watch, kind) {
416
+ const { usages, program } = usagesOf(code, path, watch);
417
+ if (usages.length === 0 && kind === void 0) return void 0;
418
+ const renamed = renameLoader(code, program);
419
+ const page = renamed.found ? "__ecomiqPageLoader(args)" : "undefined";
420
+ let finish = "return __ecomiqWithSections(page, sections);";
421
+ if (kind !== void 0) finish = `return __ecomiqTemplated(args, page, sections, __ecomiqTemplates, ${JSON.stringify(kind)});`;
422
+ const lines = [
423
+ `import { loadSections as __ecomiqLoadSections, templated as __ecomiqTemplated, withSections as __ecomiqWithSections } from "@ecomiq/storefront";`,
424
+ ...sectionsCode(usages, false),
425
+ `export async function loader(args) { const sections = __ecomiqLoadSections(args, __ecomiqSections); const page = await ${page}; ${finish} }`
426
+ ];
427
+ return `${renamed.code}\n${lines.join("\n")}\n`;
428
+ }
429
+ function transformTemplate(code, path, watch) {
430
+ const { usages } = usagesOf(code, path, watch);
431
+ return `${code}\n${sectionsCode(usages, true).join("\n")}\n`;
432
+ }
433
+ return {
434
+ name: "ecomiq:section-loaders",
435
+ enforce: "pre",
436
+ configResolved(config) {
437
+ root = config.root;
438
+ app = resolve(config.root, "app");
439
+ },
440
+ transform(code, id, options) {
441
+ const path = id.split("?")[0] ?? id;
442
+ if (!path.startsWith(`${app}${sep}`) || !path.endsWith(".tsx")) return void 0;
443
+ const file = fileOf(path);
444
+ const server = options?.ssr === true || this.environment?.config?.consumer === "server";
445
+ let next = code;
446
+ const watch = (watched) => this.addWatchFile(watched);
447
+ const kind = TEMPLATED[file];
448
+ if (server && (file === "app/root.tsx" || file.startsWith("app/routes/"))) next = transformRoute(code, path, watch, kind) ?? code;
449
+ if (server && file.startsWith("app/templates/")) next = transformTemplate(code, path, watch);
450
+ if (kind !== void 0) next = templatedComponent(next, kind) ?? next;
451
+ if (kind !== void 0 || file.startsWith("app/templates/")) next = sourcedProps(next) ?? next;
452
+ if (/export\s+(?:async\s+function\s+load\b|function\s+load\b|const\s+load\b)/.test(code) && sectionsOf(code).load) {
453
+ if (!server) next = clientSection(next);
454
+ next = progressiveSections(next);
455
+ next = `${next}\nload.section = ${JSON.stringify(file)};\n`;
456
+ }
457
+ return next === code ? void 0 : {
458
+ code: next,
459
+ map: null
460
+ };
461
+ }
462
+ };
463
+ }
464
+ export { SectionPropsError, clientSection, sectionLoaders, sectionsOf, sourcedProps, templatedComponent };
@@ -0,0 +1,21 @@
1
+ export declare class SectionPropsError extends Error {}
2
+ export declare function sectionLoaders(): {
3
+ name: string;
4
+ enforce: "pre";
5
+ configResolved(config: {
6
+ root: string;
7
+ }): void;
8
+ transform(this: {
9
+ addWatchFile(path: string): void;
10
+ environment?: {
11
+ config?: {
12
+ consumer?: string;
13
+ };
14
+ };
15
+ }, code: string, id: string, options?: {
16
+ ssr?: boolean;
17
+ }): {
18
+ code: string;
19
+ map: null;
20
+ } | undefined;
21
+ };
@@ -0,0 +1,41 @@
1
+ import { existsSync } from "node:fs";
2
+ import { basename, join } from "node:path";
3
+ // src/vite-theme-ui.ts
4
+ const PREFIX = "@theme/ui/";
5
+ const NAME = /^[a-z0-9-]+$/;
6
+ const EXTENSIONS = [
7
+ ".tsx",
8
+ ".ts",
9
+ ".jsx",
10
+ ".js"
11
+ ];
12
+ var ThemeUiError = class extends Error {};
13
+ function themeUiFile(root, source, importer) {
14
+ if (!source.startsWith(PREFIX)) return null;
15
+ const name = source.slice(10);
16
+ const user = importer === void 0 ? "Una sección de @ecomiq/storefront" : `${basename(importer.split("?")[0] ?? importer)} de @ecomiq/storefront`;
17
+ if (!NAME.test(name)) throw new ThemeUiError(`${user} importa ${source}, que no es un componente de app/components/ui.`);
18
+ const base = join(root, "app/components/ui", name);
19
+ const file = EXTENSIONS.map((extension) => `${base}${extension}`).find((candidate) => existsSync(candidate));
20
+ if (file === void 0) throw new ThemeUiError(`${user} usa ${source}, pero el tema no tiene app/components/ui/${name}.tsx. Agrega ese componente al tema o personaliza la sección.`);
21
+ return file;
22
+ }
23
+ function themeUi() {
24
+ let root = process.cwd();
25
+ return {
26
+ name: "ecomiq:theme-ui",
27
+ enforce: "pre",
28
+ configResolved(config) {
29
+ root = config.root;
30
+ },
31
+ resolveId(source, importer) {
32
+ try {
33
+ return themeUiFile(root, source, importer);
34
+ } catch (error) {
35
+ if (error instanceof ThemeUiError) this.error(error.message);
36
+ throw error;
37
+ }
38
+ }
39
+ };
40
+ }
41
+ export { ThemeUiError, themeUi, themeUiFile };
@@ -0,0 +1,10 @@
1
+ export declare function themeUi(): {
2
+ name: string;
3
+ enforce: "pre";
4
+ configResolved(config: {
5
+ root: string;
6
+ }): void;
7
+ resolveId(this: {
8
+ error(message: string): never;
9
+ }, source: string, importer: string | undefined): string | null;
10
+ };
package/dist/vite.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ import { SectionPropsError, sectionLoaders } from "./vite-sections.js";
2
+ import { paymentLogos } from "./vite-payment-logos.js";
3
+ import { themeUi } from "./vite-theme-ui.js";
4
+ import { publicAssets } from "./vite-public-assets.js";
5
+ import { CatalogLink } from "@ecomiq/core";
6
+ export declare function catalogLinksFromSource(source: string): CatalogLink[];
7
+ type HotModule = {
8
+ id: string | null;
9
+ };
10
+ type HotContext = {
11
+ file: string;
12
+ server: {
13
+ moduleGraph: {
14
+ getModuleById(id: string): HotModule | undefined;
15
+ invalidateModule(module: HotModule): void;
16
+ };
17
+ ws: {
18
+ send(message: {
19
+ type: "full-reload";
20
+ }): void;
21
+ };
22
+ };
23
+ };
24
+ export type CatalogLinksPlugin = {
25
+ name: string;
26
+ configResolved(config: {
27
+ root: string;
28
+ }): void;
29
+ resolveId(id: string): string | undefined;
30
+ load(this: {
31
+ addWatchFile(path: string): void;
32
+ }, id: string): string | undefined;
33
+ handleHotUpdate(context: HotContext): void;
34
+ };
35
+ export declare function catalogLinks(): CatalogLinksPlugin;
36
+ export { SectionPropsError, paymentLogos, publicAssets, sectionLoaders, themeUi };