@ecomiq/storefront 2.1.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -123
  3. package/dist/account-Dx4e3syi.js +258 -0
  4. package/dist/account-forms-AVk71ko7.js +39 -0
  5. package/dist/account-forms.d.ts +13 -0
  6. package/dist/account.d.ts +240 -0
  7. package/dist/address-defaults-BqjRhS82.js +14 -0
  8. package/dist/address-defaults.d.ts +11 -0
  9. package/dist/analytics/analytics-CG1Qagwl.js +148 -0
  10. package/dist/analytics/analytics.d.ts +1 -0
  11. package/dist/analytics/config-DJr-GRhs.js +62 -0
  12. package/dist/analytics/config.d.ts +22 -0
  13. package/dist/analytics/consent-B13rBpBs.js +57 -0
  14. package/dist/analytics/consent-banner-9QvRRy8v.js +239 -0
  15. package/dist/analytics/consent-banner.d.ts +20 -0
  16. package/dist/analytics/cookies-pLozllyB.js +100 -0
  17. package/dist/analytics/cookies.d.ts +6 -0
  18. package/dist/analytics/destinations-iECrlLIr.js +144 -0
  19. package/dist/analytics/events-Dt81tIp1.js +102 -0
  20. package/dist/analytics/events.d.ts +51 -0
  21. package/dist/analytics/tracker-p4yaoOyk.js +51 -0
  22. package/dist/api-cache-DsuIn5hX.js +159 -0
  23. package/dist/bank-accounts-DlEczQQ5.js +81 -0
  24. package/dist/bank-accounts.d.ts +4 -0
  25. package/dist/captcha-DAqaIx8m.js +117 -0
  26. package/dist/captcha.d.ts +34 -0
  27. package/dist/cart-D7DxZ2lD.js +30 -0
  28. package/dist/cart-actions-Bsub_FFG.js +116 -0
  29. package/dist/cart-actions.d.ts +15 -0
  30. package/dist/cart-drawer-B7PPsR69.js +22 -0
  31. package/dist/cart-drawer.d.ts +9 -0
  32. package/dist/cart-form-y9P1r_EX.js +81 -0
  33. package/dist/cart-form.d.ts +24 -0
  34. package/dist/cart-summary-ur2VWKr-.js +89 -0
  35. package/dist/cart-summary.d.ts +31 -0
  36. package/dist/cart.d.ts +4 -0
  37. package/dist/catalog-7gJ-l5hW.js +67 -0
  38. package/dist/catalog-hooks-B7ZP4wYY.js +312 -0
  39. package/dist/catalog-hooks.d.ts +111 -0
  40. package/dist/catalog.d.ts +5 -0
  41. package/dist/checkout-DVWSXANi.js +474 -0
  42. package/dist/checkout-form-CbOIdENC.js +131 -0
  43. package/dist/checkout-form.d.ts +20 -0
  44. package/dist/checkout.d.ts +86 -0
  45. package/dist/complaint-book-BvwLvfx0.js +117 -0
  46. package/dist/complaint-book.d.ts +62 -0
  47. package/dist/culqi-authentication-BGr20vAJ.js +204 -0
  48. package/dist/culqi-authentication.d.ts +15 -0
  49. package/dist/culqi-checkout-CTXpKgp_.js +55 -0
  50. package/dist/culqi-three-ds-HP3mfrvV.js +33 -0
  51. package/dist/culqi-three-ds.d.ts +29 -0
  52. package/dist/customer-avatar-CJXSDroK.js +12 -0
  53. package/dist/customer-avatar.d.ts +5 -0
  54. package/dist/customer-cookies-DHOgFAMV.js +45 -0
  55. package/dist/customer-csrf-C1oDX-Py.js +17 -0
  56. package/dist/customer-csrf.d.ts +3 -0
  57. package/dist/customer-document-fields-C1K-_DAD.js +70 -0
  58. package/dist/customer-document-fields.d.ts +9 -0
  59. package/dist/customer-login-form-C7AC6vXd.js +144 -0
  60. package/dist/customer-login-form.d.ts +17 -0
  61. package/dist/customer-registration-form-BEm_NEfP.js +93 -0
  62. package/dist/customer-registration-form.d.ts +8 -0
  63. package/dist/document-url-CGsAl5Tf.js +9 -0
  64. package/dist/documents-T1mzc_j8.js +38 -0
  65. package/dist/documents.d.ts +16 -0
  66. package/dist/entries/account.d.ts +11 -0
  67. package/dist/entries/account.js +10 -0
  68. package/dist/entries/analytics.d.ts +6 -0
  69. package/dist/entries/analytics.js +5 -0
  70. package/dist/entries/cart.d.ts +8 -0
  71. package/dist/entries/cart.js +7 -0
  72. package/dist/entries/checkout.d.ts +12 -0
  73. package/dist/entries/checkout.js +11 -0
  74. package/dist/entries/order.d.ts +11 -0
  75. package/dist/entries/order.js +11 -0
  76. package/dist/favicon-YpyhVJ9H.js +28 -0
  77. package/dist/favicon.d.ts +4 -0
  78. package/dist/form-BtQcbXlJ.js +18 -0
  79. package/dist/form-contracts-BNpHaTGJ.js +166 -0
  80. package/dist/form-contracts.d.ts +42 -0
  81. package/dist/form.d.ts +3 -0
  82. package/dist/hidden-CCWtOWKR.js +3 -0
  83. package/dist/hidden.d.ts +4 -0
  84. package/dist/index.d.ts +50 -0
  85. package/dist/index.js +50 -0
  86. package/dist/invoice-fields-BG0HjL6T.js +103 -0
  87. package/dist/invoice-fields.d.ts +39 -0
  88. package/dist/links-kFxBZfdb.js +96 -0
  89. package/dist/links.d.ts +21 -0
  90. package/dist/mercadopago-checkout-DC7RXa8k.js +27 -0
  91. package/dist/mercadopago-dialog-UTQev0MG.js +180 -0
  92. package/dist/mercadopago-dialog.d.ts +21 -0
  93. package/dist/money-DtGOtDri.js +32 -0
  94. package/dist/money.d.ts +1 -0
  95. package/dist/optimistic-cart-BveVOHuh.js +53 -0
  96. package/dist/optimistic-cart.d.ts +16 -0
  97. package/dist/order-display-DTt5WBbc.js +112 -0
  98. package/dist/order-display.d.ts +20 -0
  99. package/dist/order-draft-DxV1Uhm3.js +38 -0
  100. package/dist/order-draft.d.ts +16 -0
  101. package/dist/order-pages-Dm6l5m0m.js +38 -0
  102. package/dist/order-pages.d.ts +12 -0
  103. package/dist/order-payment-continuation-D_d5PGA4.js +212 -0
  104. package/dist/order-payment-continuation.d.ts +10 -0
  105. package/dist/order-payment-in-review-x4gdLFHZ.js +65 -0
  106. package/dist/order-payment-in-review.d.ts +5 -0
  107. package/dist/order-status-BJXLJwxq.js +162 -0
  108. package/dist/order-status.d.ts +89 -0
  109. package/dist/order-view-9IlBg5AF.js +62 -0
  110. package/dist/order-view.d.ts +12 -0
  111. package/dist/page-action-Ctkf4xC6.js +7 -0
  112. package/dist/page-seo-a5FJl8x5.js +262 -0
  113. package/dist/page-seo.d.ts +34 -0
  114. package/dist/pages-Ca_Gt6mq.js +150 -0
  115. package/dist/pages.d.ts +45 -0
  116. package/dist/payment-dialog-frame-B-Q_xQ94.js +57 -0
  117. package/dist/payment-logo-BoPaGJc_.js +46 -0
  118. package/dist/payment-logo-svgs-By9lDTLK.js +20 -0
  119. package/dist/payment-logo.d.ts +11 -0
  120. package/dist/payment-logos-BYvdwYyJ.js +23 -0
  121. package/dist/payment-methods-B8ocTgFZ.js +73 -0
  122. package/dist/payment-methods.d.ts +58 -0
  123. package/dist/payment-return-5cjypwIw.js +7 -0
  124. package/dist/place-CmW4hBWY.js +13 -0
  125. package/dist/place.d.ts +4 -0
  126. package/dist/preview-BiIBif3C.js +427 -0
  127. package/dist/preview-address-Cf0sJ-9p.js +21 -0
  128. package/dist/preview-cart-Dg2CVktS.js +376 -0
  129. package/dist/product-preview-BspMAecJ.js +51 -0
  130. package/dist/product-preview.d.ts +5 -0
  131. package/dist/product-variants-BNDHvs1y.js +46 -0
  132. package/dist/product-variants.d.ts +12 -0
  133. package/dist/public-pages-XtwlaLwt.js +194 -0
  134. package/dist/public-pages.d.ts +67 -0
  135. package/dist/registration-CpDcv8ql.js +91 -0
  136. package/dist/registration.d.ts +12 -0
  137. package/dist/request-security-CRsRMgwj.js +76 -0
  138. package/dist/rich-text-M-Ju8RL4.js +9 -0
  139. package/dist/rich-text.d.ts +5 -0
  140. package/dist/route-text-DcJw2SsK.js +9 -0
  141. package/dist/route-text.d.ts +4 -0
  142. package/dist/section-preview-CmsMl3yu.js +83 -0
  143. package/dist/section-preview.d.ts +12 -0
  144. package/dist/sections/account-addresses.d.ts +18 -0
  145. package/dist/sections/account-addresses.js +375 -0
  146. package/dist/sections/account-order.d.ts +12 -0
  147. package/dist/sections/account-order.js +592 -0
  148. package/dist/sections/account-orders.d.ts +8 -0
  149. package/dist/sections/account-orders.js +359 -0
  150. package/dist/sections/account-profile.d.ts +16 -0
  151. package/dist/sections/account-profile.js +123 -0
  152. package/dist/sections/checkout.d.ts +24 -0
  153. package/dist/sections/checkout.js +963 -0
  154. package/dist/sections/complaint-book.d.ts +8 -0
  155. package/dist/sections/complaint-book.js +538 -0
  156. package/dist/sections/design-system.d.ts +1 -0
  157. package/dist/sections/design-system.js +310 -0
  158. package/dist/sections/draft-invoice.d.ts +20 -0
  159. package/dist/sections/draft-invoice.js +158 -0
  160. package/dist/sections/order-tracking.d.ts +19 -0
  161. package/dist/sections/order-tracking.js +141 -0
  162. package/dist/sections-CNUMWTF_.js +77 -0
  163. package/dist/sections.d.ts +19 -0
  164. package/dist/seo-GpDRhAAA.js +78 -0
  165. package/dist/session-CKvmFJyg.js +379 -0
  166. package/dist/session.d.ts +24 -0
  167. package/dist/settings-B0NO2A6Y.js +78 -0
  168. package/dist/settings.d.ts +51 -0
  169. package/dist/source-marker-DhqSkW7n.js +4 -0
  170. package/dist/sources-B-3JFJfb.js +46 -0
  171. package/dist/sources.d.ts +7 -0
  172. package/dist/store-8Q-_LFrQ.js +152 -0
  173. package/dist/store-contact--hY6CoFb.js +19 -0
  174. package/dist/store-contact.d.ts +6 -0
  175. package/dist/store.d.ts +17 -0
  176. package/dist/storefront-language-DrMjVbmk.js +29 -0
  177. package/dist/storefront-language.d.ts +14 -0
  178. package/dist/storefront-text-D25ae1qf.js +11 -0
  179. package/dist/storefront-text-en-ljjjSS4q.js +1030 -0
  180. package/dist/storefront-text-pt-BtHaJLcp.js +1030 -0
  181. package/dist/storefront-text.d.ts +4 -0
  182. package/dist/stripe-dialog-Ev9s3Z62.js +396 -0
  183. package/dist/stripe-dialog.d.ts +30 -0
  184. package/dist/telemetry-HuZXWBPi.js +114 -0
  185. package/dist/telemetry.d.ts +10 -0
  186. package/dist/templates-CAqoNyTW.js +40 -0
  187. package/dist/templates.d.ts +15 -0
  188. package/dist/urls-CpGQPxvf.js +71 -0
  189. package/dist/urls.d.ts +18 -0
  190. package/dist/use-checkout-CZcxXJXi.js +42 -0
  191. package/dist/use-checkout-payment-9R-zacrJ.js +80 -0
  192. package/dist/use-checkout-payment.d.ts +18 -0
  193. package/dist/use-checkout.d.ts +36 -0
  194. package/dist/use-culqi-checkout-CrjLAipU.js +109 -0
  195. package/dist/use-order-payment-BKIz_IO0.js +45 -0
  196. package/dist/use-order-payment.d.ts +18 -0
  197. package/dist/use-payment-token-CErx-tN-.js +105 -0
  198. package/dist/vite-payment-logos-kziu7wKb.js +27 -0
  199. package/dist/vite-payment-logos.d.ts +24 -0
  200. package/dist/vite-public-assets-DW2fgtVb.js +209 -0
  201. package/dist/vite-public-assets.d.ts +29 -0
  202. package/dist/vite-sections-DTBr0-Kg.js +464 -0
  203. package/dist/vite-sections.d.ts +21 -0
  204. package/dist/vite-theme-ui-BMO-CDi3.js +41 -0
  205. package/dist/vite-theme-ui.d.ts +10 -0
  206. package/dist/vite.d.ts +36 -0
  207. package/dist/vite.js +127 -0
  208. package/dist/voucher-payment-CVFDZ1L8.js +66 -0
  209. package/dist/worker-CNi-gzCu.js +86 -0
  210. package/dist/worker.d.ts +27 -0
  211. package/package.json +100 -81
  212. package/src/sections/account-addresses.tsx +215 -0
  213. package/src/sections/account-order.tsx +424 -0
  214. package/src/sections/account-orders.tsx +259 -0
  215. package/src/sections/account-profile.tsx +70 -0
  216. package/src/sections/checkout.tsx +586 -0
  217. package/src/sections/complaint-book.tsx +325 -0
  218. package/src/sections/design-system.tsx +146 -0
  219. package/src/sections/draft-invoice.tsx +105 -0
  220. package/src/sections/order-tracking.tsx +81 -0
  221. package/src/vite-client.d.ts +4 -0
  222. package/bin/ecomiq.mjs +0 -179
  223. package/public/design-bridge.js +0 -318
  224. package/src/api-proxy.ts +0 -194
  225. package/src/auth/create-storefront-auth.ts +0 -94
  226. package/src/auth/ecomiq-oauth-password-client.ts +0 -26
  227. package/src/auth/ecomiq-oauth-password-constants.ts +0 -24
  228. package/src/auth/ecomiq-oauth-password-plugin.ts +0 -294
  229. package/src/auth/ecomiq-oauth-password-types.ts +0 -24
  230. package/src/auth/ecomiq-storefront-sign-in.ts +0 -44
  231. package/src/auth/env.ts +0 -7
  232. package/src/auth/secure-cookies.ts +0 -23
  233. package/src/auth/storefront-auth-base-url.ts +0 -117
  234. package/src/auth/storefront-auth.ts +0 -7
  235. package/src/cart-session.ts +0 -239
  236. package/src/client.ts +0 -48
  237. package/src/cloud-runtime-client.ts +0 -378
  238. package/src/codegen.mjs +0 -789
  239. package/src/components/account/customer-addresses-panel.tsx +0 -678
  240. package/src/components/account/customer-order-detail-panel.tsx +0 -285
  241. package/src/components/account/customer-orders-panel.tsx +0 -192
  242. package/src/components/account/customer-profile-panel.tsx +0 -379
  243. package/src/components/checkout/cart-sync.ts +0 -143
  244. package/src/components/checkout/checkout-contact-section.tsx +0 -76
  245. package/src/components/checkout/checkout-external-update-banner.tsx +0 -15
  246. package/src/components/checkout/checkout-form-controls.tsx +0 -139
  247. package/src/components/checkout/checkout-line-items.tsx +0 -43
  248. package/src/components/checkout/checkout-order-summary.tsx +0 -165
  249. package/src/components/checkout/checkout-payment-section.tsx +0 -212
  250. package/src/components/checkout/checkout-session-view.tsx +0 -564
  251. package/src/components/checkout/checkout-shipping-address-section.tsx +0 -400
  252. package/src/components/checkout/checkout-shipping-section.tsx +0 -98
  253. package/src/components/checkout/checkout-states.tsx +0 -73
  254. package/src/components/checkout/checkout-step-card.tsx +0 -101
  255. package/src/components/checkout/checkout-steps.ts +0 -111
  256. package/src/components/checkout/form-schema.ts +0 -281
  257. package/src/components/checkout/format.ts +0 -15
  258. package/src/components/checkout/index.ts +0 -5
  259. package/src/components/checkout/map-customer-to-checkout.ts +0 -188
  260. package/src/components/checkout/types.ts +0 -41
  261. package/src/components/checkout/use-checkout-customer-prefill.ts +0 -409
  262. package/src/components/checkout/use-checkout-geo.ts +0 -50
  263. package/src/components/checkout/use-checkout-session.ts +0 -640
  264. package/src/components/hero.tsx +0 -291
  265. package/src/config.d.ts +0 -94
  266. package/src/config.mjs +0 -146
  267. package/src/format-money.ts +0 -31
  268. package/src/health.ts +0 -90
  269. package/src/hooks/index.ts +0 -9
  270. package/src/hooks/recently-viewed.ts +0 -125
  271. package/src/index.ts +0 -354
  272. package/src/link.tsx +0 -2
  273. package/src/pages/account/account-page-skeleton.tsx +0 -69
  274. package/src/pages/account/account-page-view.tsx +0 -270
  275. package/src/pages/account/account-shell.tsx +0 -101
  276. package/src/pages/account/parse-account-route.ts +0 -36
  277. package/src/pages/account.tsx +0 -16
  278. package/src/pages/api.$.ts +0 -20
  279. package/src/pages/api.auth.$.ts +0 -16
  280. package/src/pages/checkout.$checkoutId.tsx +0 -60
  281. package/src/pages/checkout.tsx +0 -31
  282. package/src/pages/pages.$pageSlug.tsx +0 -111
  283. package/src/pages/thank-you.tsx +0 -53
  284. package/src/providers/auth.tsx +0 -96
  285. package/src/providers/cart.tsx +0 -275
  286. package/src/providers/ecomiq.ts +0 -137
  287. package/src/providers/index.ts +0 -26
  288. package/src/proxy-api.ts +0 -20
  289. package/src/public-config.ts +0 -24
  290. package/src/review-submission.ts +0 -89
  291. package/src/runtime/context.ts +0 -2
  292. package/src/runtime/default-layout.tsx +0 -64
  293. package/src/runtime/head.ts +0 -149
  294. package/src/runtime/page.tsx +0 -143
  295. package/src/runtime/postcss-browser-stub.mjs +0 -5
  296. package/src/server-config-store.ts +0 -35
  297. package/src/server.ts +0 -301
  298. package/src/storefront-definition/contract.ts +0 -1
  299. package/src/storefront-definition/data.ts +0 -188
  300. package/src/storefront-definition/index.ts +0 -2
  301. package/src/storefront-definition/renderer.tsx +0 -1481
  302. package/src/storefront-layout.ts +0 -59
  303. package/src/storefront-runtime.ts +0 -173
  304. package/src/styles.css +0 -97
  305. package/src/ui/badge.tsx +0 -32
  306. package/src/ui/button.tsx +0 -31
  307. package/src/ui/card.tsx +0 -31
  308. package/src/ui/carousel.tsx +0 -218
  309. package/src/ui/cn.ts +0 -6
  310. package/src/ui/index.ts +0 -8
  311. package/src/ui/separator.tsx +0 -6
  312. package/src/ui/skeleton.tsx +0 -6
  313. package/src/ui/storefront-error.tsx +0 -49
  314. package/src/utils.ts +0 -36
  315. package/src/vite-inline.mjs +0 -263
  316. package/templates/__root.tsx +0 -83
  317. package/templates/router.tsx +0 -19
@@ -0,0 +1,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 };