@decocms/start 0.19.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 (185) hide show
  1. package/.cursor/skills/deco-api-call-dedup/SKILL.md +443 -0
  2. package/.cursor/skills/deco-apps-architecture/SKILL.md +255 -0
  3. package/.cursor/skills/deco-apps-architecture/app-pattern.md +288 -0
  4. package/.cursor/skills/deco-apps-architecture/commerce-types.md +239 -0
  5. package/.cursor/skills/deco-apps-architecture/new-app-guide.md +268 -0
  6. package/.cursor/skills/deco-apps-architecture/scripts-codegen.md +148 -0
  7. package/.cursor/skills/deco-apps-architecture/shared-utils.md +181 -0
  8. package/.cursor/skills/deco-apps-architecture/vtex-deep-structure.md +253 -0
  9. package/.cursor/skills/deco-apps-architecture/website-app.md +169 -0
  10. package/.cursor/skills/deco-apps-vtex-porting/SKILL.md +189 -0
  11. package/.cursor/skills/deco-apps-vtex-porting/adaptation-patterns.md +335 -0
  12. package/.cursor/skills/deco-apps-vtex-porting/commerce-porting.md +155 -0
  13. package/.cursor/skills/deco-apps-vtex-porting/cookie-auth-patterns.md +148 -0
  14. package/.cursor/skills/deco-apps-vtex-porting/structure-map.md +234 -0
  15. package/.cursor/skills/deco-apps-vtex-porting/transform-mapping.md +99 -0
  16. package/.cursor/skills/deco-apps-vtex-porting/website-porting.md +194 -0
  17. package/.cursor/skills/deco-apps-vtex-review/SKILL.md +234 -0
  18. package/.cursor/skills/deco-async-rendering-architecture/SKILL.md +270 -0
  19. package/.cursor/skills/deco-async-rendering-site-guide/SKILL.md +417 -0
  20. package/.cursor/skills/deco-cms-layout-caching/SKILL.md +293 -0
  21. package/.cursor/skills/deco-cms-route-config/SKILL.md +388 -0
  22. package/.cursor/skills/deco-core-architecture/SKILL.md +185 -0
  23. package/.cursor/skills/deco-core-architecture/blocks.md +196 -0
  24. package/.cursor/skills/deco-core-architecture/deco-vs-deco-start.md +191 -0
  25. package/.cursor/skills/deco-core-architecture/engine.md +220 -0
  26. package/.cursor/skills/deco-core-architecture/hooks-components.md +157 -0
  27. package/.cursor/skills/deco-core-architecture/plugins-clients.md +136 -0
  28. package/.cursor/skills/deco-core-architecture/runtime.md +116 -0
  29. package/.cursor/skills/deco-core-architecture/site-usage.md +165 -0
  30. package/.cursor/skills/deco-e2e-testing/SKILL.md +372 -0
  31. package/.cursor/skills/deco-e2e-testing/discovery.md +337 -0
  32. package/.cursor/skills/deco-e2e-testing/scripts/scaffold.sh +81 -0
  33. package/.cursor/skills/deco-e2e-testing/selectors.md +175 -0
  34. package/.cursor/skills/deco-e2e-testing/templates/package.json +18 -0
  35. package/.cursor/skills/deco-e2e-testing/templates/playwright.config.ts +65 -0
  36. package/.cursor/skills/deco-e2e-testing/templates/scripts/baseline.ts +279 -0
  37. package/.cursor/skills/deco-e2e-testing/templates/scripts/run-e2e.ts +194 -0
  38. package/.cursor/skills/deco-e2e-testing/templates/specs/ecommerce-flow.spec.ts +612 -0
  39. package/.cursor/skills/deco-e2e-testing/templates/tsconfig.json +12 -0
  40. package/.cursor/skills/deco-e2e-testing/templates/utils/metrics-collector.ts +918 -0
  41. package/.cursor/skills/deco-e2e-testing/troubleshooting.md +602 -0
  42. package/.cursor/skills/deco-edge-caching/SKILL.md +316 -0
  43. package/.cursor/skills/deco-full-analysis/SKILL.md +898 -0
  44. package/.cursor/skills/deco-full-analysis/checklists/asset-optimization.md +251 -0
  45. package/.cursor/skills/deco-full-analysis/checklists/bug-fix.md +189 -0
  46. package/.cursor/skills/deco-full-analysis/checklists/cache-strategy.md +144 -0
  47. package/.cursor/skills/deco-full-analysis/checklists/dependency-update.md +150 -0
  48. package/.cursor/skills/deco-full-analysis/checklists/hydration-fix.md +191 -0
  49. package/.cursor/skills/deco-full-analysis/checklists/image-optimization.md +180 -0
  50. package/.cursor/skills/deco-full-analysis/checklists/loader-optimization.md +165 -0
  51. package/.cursor/skills/deco-full-analysis/checklists/seo-fix.md +183 -0
  52. package/.cursor/skills/deco-full-analysis/checklists/site-cleanup.md +281 -0
  53. package/.cursor/skills/deco-full-analysis/discovery.md +548 -0
  54. package/.cursor/skills/deco-incident-debugging/SKILL.md +378 -0
  55. package/.cursor/skills/deco-incident-debugging/headless-mode.md +510 -0
  56. package/.cursor/skills/deco-incident-debugging/learnings-index.md +227 -0
  57. package/.cursor/skills/deco-incident-debugging/triage-workflow.md +312 -0
  58. package/.cursor/skills/deco-islands-migration/SKILL.md +251 -0
  59. package/.cursor/skills/deco-loader-n-plus-1-detector/SKILL.md +275 -0
  60. package/.cursor/skills/deco-performance-audit/SKILL.md +530 -0
  61. package/.cursor/skills/deco-performance-audit/tools-reference.md +428 -0
  62. package/.cursor/skills/deco-performance-audit/workflow.md +457 -0
  63. package/.cursor/skills/deco-server-functions-invoke/SKILL.md +92 -0
  64. package/.cursor/skills/deco-server-functions-invoke/architecture.md +166 -0
  65. package/.cursor/skills/deco-server-functions-invoke/generator.md +122 -0
  66. package/.cursor/skills/deco-server-functions-invoke/problem.md +98 -0
  67. package/.cursor/skills/deco-server-functions-invoke/troubleshooting.md +110 -0
  68. package/.cursor/skills/deco-site-deployment/SKILL.md +396 -0
  69. package/.cursor/skills/deco-site-memory-debugging/SKILL.md +121 -0
  70. package/.cursor/skills/deco-site-memory-debugging/cdp-connection.md +222 -0
  71. package/.cursor/skills/deco-site-memory-debugging/memory-analysis.md +362 -0
  72. package/.cursor/skills/deco-site-patterns/SKILL.md +124 -0
  73. package/.cursor/skills/deco-site-patterns/app-composition.md +337 -0
  74. package/.cursor/skills/deco-site-patterns/client-patterns.md +341 -0
  75. package/.cursor/skills/deco-site-patterns/cms-wiring.md +230 -0
  76. package/.cursor/skills/deco-site-patterns/section-patterns.md +340 -0
  77. package/.cursor/skills/deco-site-scaling-tuning/SKILL.md +240 -0
  78. package/.cursor/skills/deco-site-scaling-tuning/analysis-scripts.md +267 -0
  79. package/.cursor/skills/deco-start-architecture/SKILL.md +218 -0
  80. package/.cursor/skills/deco-start-architecture/admin-protocol.md +156 -0
  81. package/.cursor/skills/deco-start-architecture/cms-resolution.md +201 -0
  82. package/.cursor/skills/deco-start-architecture/code-quality.md +158 -0
  83. package/.cursor/skills/deco-start-architecture/gap-analysis.md +129 -0
  84. package/.cursor/skills/deco-start-architecture/sdk-utilities.md +197 -0
  85. package/.cursor/skills/deco-start-architecture/worker-entry-caching.md +154 -0
  86. package/.cursor/skills/deco-startup-analysis/SKILL.md +248 -0
  87. package/.cursor/skills/deco-storefront-test-checklist/SKILL.md +369 -0
  88. package/.cursor/skills/deco-tanstack-hydration-fixes/SKILL.md +468 -0
  89. package/.cursor/skills/deco-tanstack-navigation/SKILL.md +681 -0
  90. package/.cursor/skills/deco-tanstack-search/SKILL.md +411 -0
  91. package/.cursor/skills/deco-tanstack-storefront-patterns/SKILL.md +1013 -0
  92. package/.cursor/skills/deco-to-tanstack-migration/SKILL.md +518 -0
  93. package/.cursor/skills/deco-to-tanstack-migration/references/codemod-commands.md +174 -0
  94. package/.cursor/skills/deco-to-tanstack-migration/references/commerce/README.md +78 -0
  95. package/.cursor/skills/deco-to-tanstack-migration/references/deco-framework/README.md +128 -0
  96. package/.cursor/skills/deco-to-tanstack-migration/references/gotchas.md +719 -0
  97. package/.cursor/skills/deco-to-tanstack-migration/references/imports/README.md +70 -0
  98. package/.cursor/skills/deco-to-tanstack-migration/references/platform-hooks/README.md +154 -0
  99. package/.cursor/skills/deco-to-tanstack-migration/references/signals/README.md +220 -0
  100. package/.cursor/skills/deco-to-tanstack-migration/references/vite-config/README.md +78 -0
  101. package/.cursor/skills/deco-to-tanstack-migration/templates/package-json.md +55 -0
  102. package/.cursor/skills/deco-to-tanstack-migration/templates/root-route.md +110 -0
  103. package/.cursor/skills/deco-to-tanstack-migration/templates/router.md +96 -0
  104. package/.cursor/skills/deco-to-tanstack-migration/templates/setup-ts.md +167 -0
  105. package/.cursor/skills/deco-to-tanstack-migration/templates/vite-config.md +122 -0
  106. package/.cursor/skills/deco-to-tanstack-migration/templates/worker-entry.md +67 -0
  107. package/.cursor/skills/deco-typescript-fixes/SKILL.md +178 -0
  108. package/.cursor/skills/deco-typescript-fixes/common-fixes.md +330 -0
  109. package/.cursor/skills/deco-typescript-fixes/strategy.md +148 -0
  110. package/.cursor/skills/deco-variant-selection-perf/SKILL.md +272 -0
  111. package/.cursor/skills/deco-vtex-fetch-cache/SKILL.md +225 -0
  112. package/.cursor/skills/find-skills/SKILL.md +133 -0
  113. package/.cursor/skills/incident-report/SKILL.md +179 -0
  114. package/.cursor/skills/incident-report/references/5-whys.md +75 -0
  115. package/.cursor/skills/incident-report/templates/client-report.md +187 -0
  116. package/.cursor/skills/incident-report/templates/internal-report.md +206 -0
  117. package/.cursor/skills/template-skill/SKILL.md +38 -0
  118. package/.github/workflows/release.yml +32 -0
  119. package/.releaserc.json +25 -0
  120. package/CLAUDE.md +135 -0
  121. package/GAP_ANALYSIS.md +224 -0
  122. package/GAP_ANALYSIS_V2.md +1013 -0
  123. package/biome.json +39 -0
  124. package/knip.json +5 -0
  125. package/package.json +87 -0
  126. package/scripts/generate-blocks.ts +69 -0
  127. package/scripts/generate-invoke.ts +378 -0
  128. package/scripts/generate-schema.ts +657 -0
  129. package/src/admin/cors.ts +29 -0
  130. package/src/admin/decofile.ts +72 -0
  131. package/src/admin/index.ts +24 -0
  132. package/src/admin/invoke.ts +163 -0
  133. package/src/admin/liveControls.ts +29 -0
  134. package/src/admin/meta.ts +70 -0
  135. package/src/admin/render.ts +205 -0
  136. package/src/admin/schema.ts +686 -0
  137. package/src/admin/setup.ts +44 -0
  138. package/src/cms/index.ts +59 -0
  139. package/src/cms/loader.ts +180 -0
  140. package/src/cms/registry.ts +162 -0
  141. package/src/cms/resolve.ts +1005 -0
  142. package/src/cms/sectionLoaders.ts +294 -0
  143. package/src/hooks/DecoPageRenderer.tsx +444 -0
  144. package/src/hooks/LazySection.tsx +109 -0
  145. package/src/hooks/LiveControls.tsx +108 -0
  146. package/src/hooks/SectionErrorFallback.tsx +85 -0
  147. package/src/hooks/index.ts +8 -0
  148. package/src/index.ts +5 -0
  149. package/src/matchers/builtins.ts +184 -0
  150. package/src/matchers/posthog.ts +154 -0
  151. package/src/middleware/decoState.ts +55 -0
  152. package/src/middleware/healthMetrics.ts +131 -0
  153. package/src/middleware/index.ts +80 -0
  154. package/src/middleware/liveness.ts +21 -0
  155. package/src/middleware/observability.ts +205 -0
  156. package/src/routes/adminRoutes.ts +83 -0
  157. package/src/routes/cmsRoute.ts +302 -0
  158. package/src/routes/components.tsx +34 -0
  159. package/src/routes/index.ts +15 -0
  160. package/src/sdk/analytics.ts +72 -0
  161. package/src/sdk/cacheHeaders.ts +268 -0
  162. package/src/sdk/cachedLoader.ts +206 -0
  163. package/src/sdk/clx.ts +3 -0
  164. package/src/sdk/cookie.ts +39 -0
  165. package/src/sdk/createInvoke.ts +57 -0
  166. package/src/sdk/csp.ts +59 -0
  167. package/src/sdk/env.ts +27 -0
  168. package/src/sdk/index.ts +63 -0
  169. package/src/sdk/instrumentedFetch.ts +137 -0
  170. package/src/sdk/invoke.ts +133 -0
  171. package/src/sdk/mergeCacheControl.ts +150 -0
  172. package/src/sdk/redirects.ts +217 -0
  173. package/src/sdk/requestContext.ts +184 -0
  174. package/src/sdk/serverTimings.ts +68 -0
  175. package/src/sdk/signal.ts +41 -0
  176. package/src/sdk/sitemap.ts +143 -0
  177. package/src/sdk/urlUtils.ts +117 -0
  178. package/src/sdk/useDevice.ts +82 -0
  179. package/src/sdk/useId.ts +7 -0
  180. package/src/sdk/useScript.ts +101 -0
  181. package/src/sdk/workerEntry.ts +703 -0
  182. package/src/sdk/wrapCaughtErrors.ts +107 -0
  183. package/src/types/index.ts +39 -0
  184. package/src/types/widgets.ts +13 -0
  185. package/tsconfig.json +13 -0
@@ -0,0 +1,253 @@
1
+ # VTEX App — Deep Structure Reference
2
+
3
+ The VTEX app is the largest integration in deco-cx/apps (141 files). This document maps every subdirectory and key file.
4
+
5
+ ## `mod.ts` — App Factory
6
+
7
+ Creates 7 typed HTTP/GraphQL clients:
8
+
9
+ | Client | Base URL | Purpose |
10
+ |--------|----------|---------|
11
+ | `sp` | `https://sp.vtex.com` | Spark (analytics events) |
12
+ | `my` | `https://{account}.myvtex.com` | My Account APIs |
13
+ | `vcsDeprecated` | `{publicUrl}` | VTEXCommerceStable (checkout, catalog, auth) |
14
+ | `io` | `{publicUrl}/api/io/_v/private/graphql/v1` | IO GraphQL (wishlist, reviews) |
15
+ | `vcs` | `{publicUrl}` | VCS OpenAPI (typed) |
16
+ | `api` | `https://api.vtex.com/{account}` | VTEX API |
17
+ | `vpay` | `https://{account}.vtexpayments.com.br` | Payments |
18
+ | `sub` | `https://{account}.vtexcommercestable.com.br` | Subscriptions |
19
+
20
+ ### Props
21
+ ```typescript
22
+ interface Props {
23
+ account: string; // VTEX account name
24
+ publicUrl: string; // Public store URL (e.g., secure.mystore.com.br)
25
+ appKey?: Secret; // For admin API operations
26
+ appToken?: Secret;
27
+ salesChannel?: string; // Default: "1"
28
+ defaultSegment?: SegmentCulture;
29
+ setRefreshToken?: boolean;
30
+ usePortalSitemap?: boolean;
31
+ platform: "vtex";
32
+ advancedConfigs?: { doNotFetchVariantsForRelatedProducts?: boolean };
33
+ cachedSearchTerms?: { terms?: Suggestion; extraTerms?: string[] };
34
+ }
35
+ ```
36
+
37
+ ## Actions (43 files, 11 subdirectories)
38
+
39
+ ### `actions/cart/` (16 files)
40
+ | File | Endpoint | Method |
41
+ |------|----------|--------|
42
+ | `addItems.ts` | `/api/checkout/pub/orderForm/:id/items` | POST |
43
+ | `updateItems.ts` | `/api/checkout/pub/orderForm/:id/items/update` | POST |
44
+ | `removeItems.ts` | `/api/checkout/pub/orderForm/:id/items/removeAll` | POST |
45
+ | `updateCoupons.ts` | `/api/checkout/pub/orderForm/:id/coupons` | POST |
46
+ | `updateAttachment.ts` | `/api/checkout/pub/orderForm/:id/attachments/:att` | POST |
47
+ | `updateItemAttachment.ts` | `/api/checkout/pub/orderForm/:id/items/:idx/attachments/:att` | POST |
48
+ | `removeItemAttachment.ts` | `/api/checkout/pub/orderForm/:id/items/:idx/attachments/:att` | DELETE |
49
+ | `updateItemPrice.ts` | `/api/checkout/pub/orderForm/:id/items/:idx/price` | PUT |
50
+ | `updateProfile.ts` | `/api/checkout/pub/orderForm/:id/profile` | PATCH |
51
+ | `updateUser.ts` | `/api/checkout/changeToAnonymousUser/:id` | GET |
52
+ | `addOfferings.ts` | `/api/checkout/pub/orderForm/:id/items/:idx/offerings` | POST |
53
+ | `removeOffering.ts` | `/api/checkout/pub/orderForm/:id/items/:idx/offerings/:off/remove` | POST |
54
+ | `getInstallment.ts` | `/api/checkout/pub/orderForm/:id/installments` | GET |
55
+ | `updateGifts.ts` | `/api/checkout/pub/orderForm/:id/selectable-gifts/:giftId` | POST |
56
+ | `clearOrderformMessages.ts` | `/api/checkout/pub/orderForm/:id/messages/clear` | POST |
57
+ | `simulation.ts` | `/api/checkout/pub/orderForms/simulation` | POST |
58
+
59
+ All cart actions:
60
+ - Receive `orderFormId` from cookie parsing
61
+ - Pass `sc` (salesChannel) from segment
62
+ - Use `expectedOrderFormSections` in body
63
+ - Proxy `Set-Cookie` headers back
64
+ - Return `OrderForm`
65
+
66
+ ### `actions/authentication/` (8 files)
67
+ | File | Purpose |
68
+ |------|---------|
69
+ | `startAuthentication.ts` | Get auth token from VTEX ID |
70
+ | `classicSignIn.ts` | Email + password login |
71
+ | `accessKeySignIn.ts` | Magic link validation |
72
+ | `sendEmailVerification.ts` | Send magic link email |
73
+ | `recoveryPassword.ts` | Request password reset |
74
+ | `resetPassword.ts` | Set new password |
75
+ | `refreshToken.ts` | Refresh auth cookie |
76
+ | `logout.ts` | Clear auth cookies |
77
+
78
+ ### `actions/session/` (3 files)
79
+ | File | Endpoint |
80
+ |------|----------|
81
+ | `createSession.ts` | IO GraphQL — `newSession` mutation |
82
+ | `editSession.ts` | IO GraphQL — `updateSession` mutation |
83
+ | `deleteSession.ts` | IO GraphQL — `deleteSession` mutation |
84
+
85
+ ### Other Actions
86
+ | Directory | Files | Purpose |
87
+ |-----------|-------|---------|
88
+ | `address/` | 3 | CRUD user addresses (IO GraphQL) |
89
+ | `newsletter/` | 2 | Subscribe + update opt-in |
90
+ | `wishlist/` | 2 | Add/remove items (IO GraphQL) |
91
+ | `masterdata/` | 2 | Create/update documents |
92
+ | `orders/` | 1 | Cancel order |
93
+ | `payment/` | 1 | Delete payment token |
94
+ | `profile/` | 1 | Update user profile |
95
+ | `review/` | 1 | Submit product review |
96
+ | `analytics/` | 1 | Send SP event |
97
+ | `notifyme.ts` | 1 | Notify me when available |
98
+ | `trigger.ts` | 1 | Workflow trigger |
99
+
100
+ ## Loaders (50+ files, 15 subdirectories)
101
+
102
+ ### `loaders/intelligentSearch/` (6 files) — Primary search
103
+ | File | Returns | API |
104
+ |------|---------|-----|
105
+ | `productDetailsPage.ts` | `ProductDetailsPage` | IS product_search + facets |
106
+ | `productListingPage.ts` | `ProductListingPage` | IS product_search + facets |
107
+ | `productList.ts` | `Product[]` | IS product_search |
108
+ | `suggestions.ts` | `Suggestion` | IS search_suggestions |
109
+ | `topsearches.ts` | `Suggestion` | IS top_searches |
110
+ | `productSearchValidator.ts` | Validates search args | — |
111
+
112
+ ### `loaders/legacy/` (7 files) — Legacy Catalog API
113
+ | File | Returns | API |
114
+ |------|---------|-----|
115
+ | `productDetailsPage.ts` | `ProductDetailsPage` | `/products/search/:slug/p` |
116
+ | `productListingPage.ts` | `ProductListingPage` | `/products/search` + `/facets/search` |
117
+ | `productList.ts` | `Product[]` | `/products/search` |
118
+ | `suggestions.ts` | `Suggestion` | `/buscaautocomplete` |
119
+ | `relatedProductsLoader.ts` | `Product[]` | `/crossselling/:type/:id` |
120
+ | `brands.ts` | `Brand[]` | `/brand/list` |
121
+ | `pageType.ts` | `PageType` | `/portal/pagetype/:term` |
122
+
123
+ ### `loaders/logistics/` (5 files)
124
+ | File | Purpose |
125
+ |------|---------|
126
+ | `getSalesChannelById.ts` | Get sales channel details |
127
+ | `listSalesChannelById.ts` | List sales channels |
128
+ | `listPickupPoints.ts` | List pickup points |
129
+ | `listPickupPointsByLocation.ts` | Pickup points near location |
130
+ | `listStockByStore.ts` | Stock availability by store |
131
+
132
+ ### Other Loaders
133
+ | Directory | Files | Purpose |
134
+ |-----------|-------|---------|
135
+ | `cart.ts` | 1 | Get/create OrderForm |
136
+ | `user.ts` | 1 | Get current user (Person) |
137
+ | `wishlist.ts` | 1 | Get user wishlist |
138
+ | `navbar.ts` | 1 | Category tree for navigation |
139
+ | `proxy.ts` | 1 | VTEX checkout/API proxy handler |
140
+ | `config.ts` | 1 | Expose app config |
141
+ | `address/` | 2 | Get addresses, postal code lookup |
142
+ | `categories/` | 1 | Category tree |
143
+ | `collections/` | 1 | List collections |
144
+ | `orders/` | 3 | Get by ID, list, orderplaced |
145
+ | `payment/` | 2 | Payment systems, user payments |
146
+ | `profile/` | 2 | Get current profile, get by email |
147
+ | `session/` | 2 | Get session, get user sessions |
148
+ | `paths/` | 2 | PDP/PLP default path patterns |
149
+ | `product/` | 3 | Extend product, extensions, wishlist enrichment |
150
+ | `product/extensions/` | 4 | Enrich PDP, list, PLP, suggestions |
151
+ | `masterdata/` | 1 | Search documents |
152
+ | `options/` | 1 | Product ID by search term |
153
+ | `promotion/` | 1 | Get promotion by ID |
154
+ | `workflow/` | 2 | Product/products for workflow |
155
+
156
+ ## Utils (31 files)
157
+
158
+ ### Core Transform & Types
159
+ | File | Lines | Purpose |
160
+ |------|-------|---------|
161
+ | `transform.ts` | ~600 | THE canonical VTEX → schema.org mapping |
162
+ | `types.ts` | 1320 | All VTEX API types (OrderForm, Product, etc.) |
163
+ | `client.ts` | 317 | `VTEXCommerceStable` + `SP` typed interfaces |
164
+
165
+ ### Fetch & HTTP
166
+ | File | Purpose |
167
+ |------|---------|
168
+ | `fetchVTEX.ts` | VTEX-specific `fetchSafe`/`fetchAPI` with URL sanitization |
169
+
170
+ ### Cookies & Auth
171
+ | File | Purpose |
172
+ |------|---------|
173
+ | `cookies.ts` | `stringify`, `proxySetCookie`, cookie constants |
174
+ | `vtexId.ts` | `parseCookie` — extracts auth cookie + JWT decode |
175
+ | `orderForm.ts` | `parseCookie` — extracts checkout cookie + orderFormId |
176
+
177
+ ### Segment & Search
178
+ | File | Purpose |
179
+ |------|---------|
180
+ | `segment.ts` | Segment bag management, cookie serialization, `isAnonymous` |
181
+ | `intelligentSearch.ts` | IS cookie management, search params building |
182
+
183
+ ### Other Utils
184
+ | File | Purpose |
185
+ |------|---------|
186
+ | `legacy.ts` | Legacy API helpers |
187
+ | `similars.ts` | Similar products enrichment |
188
+ | `batch.ts` | Batch API calls |
189
+ | `cacheBySegment.ts` | Cache key generation per segment |
190
+ | `slugify.ts` | URL slug generation |
191
+ | `resourceRange.ts` | Range header parsing for pagination |
192
+ | `pickAndOmit.ts` | Object property picking/omitting |
193
+ | `login/getLoginCookies.ts` | Extract login-related cookies |
194
+ | `login/setLoginCookies.ts` | Set login cookies in response |
195
+ | `extensions/simulation.ts` | Price simulation enrichment |
196
+
197
+ ### OpenAPI Generated Types (12 files)
198
+ ```
199
+ openapi/
200
+ ├── api.openapi.json + api.openapi.gen.ts # VTEX API
201
+ ├── my.openapi.json + my.openapi.gen.ts # My Account
202
+ ├── orders.openapi.json + orders.openapi.gen.ts # Orders
203
+ ├── payments.openapi.json + payments.openapi.gen.ts
204
+ ├── subscriptions.openapi.json + subscriptions.openapi.gen.ts
205
+ └── vcs.openapi.json + vcs.openapi.gen.ts # VTEXCommerceStable
206
+ ```
207
+
208
+ ## Hooks (5 files)
209
+
210
+ | File | Framework | Purpose |
211
+ |------|-----------|---------|
212
+ | `context.ts` | Preact signals | Central state (cart, user, wishlist) + enqueue |
213
+ | `useCart.ts` | Preact signals | Cart operations via invoke proxy |
214
+ | `useUser.ts` | Preact signals | User state from context |
215
+ | `useWishlist.ts` | Preact signals | Wishlist CRUD via invoke proxy |
216
+ | `useAutocomplete.ts` | Preact signals | Search autocomplete |
217
+
218
+ ## Other
219
+
220
+ | Directory | Purpose |
221
+ |-----------|---------|
222
+ | `middleware.ts` | Sets segment + IS cookies in ctx.bag |
223
+ | `handlers/sitemap.ts` | VTEX sitemap proxy |
224
+ | `sections/Analytics/Vtex.tsx` | VTEX analytics pixel section |
225
+ | `components/VTEXPortalDataLayerCompatibility.tsx` | DataLayer compat |
226
+ | `workflows/events.ts` | Workflow event definitions |
227
+ | `workflows/product/index.ts` | Product sync workflow |
228
+ | `preview/Preview.tsx` | Admin preview component |
229
+
230
+ ## Key Data Flow
231
+
232
+ ```
233
+ Request → middleware.ts (parse cookies, set segment/IS in bag)
234
+ → loader/action (use ctx.bag for segment, cookies)
235
+ → client.ts (typed HTTP call to VTEX API)
236
+ → transform.ts (API response → schema.org)
237
+ ← Response (proxySetCookie back to client)
238
+ ```
239
+
240
+ ## `utils/client.ts` — Endpoint Map
241
+
242
+ The `VTEXCommerceStable` interface (317 lines) defines every endpoint:
243
+
244
+ | Category | Endpoints |
245
+ |----------|-----------|
246
+ | Auth | startAuthentication, classicValidate, accessKeyValidate, setPassword, sendAccessKey, refreshToken |
247
+ | Checkout | orderForm, items, update, removeAll, coupons, attachments, offerings, simulation, installments, profile, messages, gifts |
248
+ | Catalog (Legacy) | products/search, crossselling, facets/search, pagetype, brand/list, category/tree, buscaautocomplete |
249
+ | Catalog (IS) | product_search, facets, search_suggestions, top_searches |
250
+ | Orders | user/orders, cancel, order-group |
251
+ | Masterdata | documents (create) |
252
+ | Newsletter | Newsletter.aspx, AviseMe.aspx |
253
+ | IO GraphQL | Private graphql endpoint (sessions, wishlist, addresses, reviews) |
@@ -0,0 +1,169 @@
1
+ # Website App — Reference
2
+
3
+ The `website/` app is the base layer that all Deco storefronts use. It handles routing, SEO, analytics, image optimization, themes, and A/B testing.
4
+
5
+ ## Structure
6
+
7
+ ```
8
+ website/
9
+ ├── mod.ts # App factory (Props: routes, global sections, caching, abTesting, SEO, theme)
10
+ ├── manifest.gen.ts
11
+ ├── types.ts # Script type
12
+ ├── Preview.tsx # Admin preview
13
+ ├── pages/Page.tsx # Base page component
14
+ ├── actions/
15
+ │ └── secrets/encrypt.ts # Secret encryption
16
+ ├── components/
17
+ │ ├── Analytics.tsx # Analytics container
18
+ │ ├── Clickhouse.tsx # ClickHouse event collector
19
+ │ ├── Events.tsx # Event dispatching
20
+ │ ├── Image.tsx # Optimized image component
21
+ │ ├── Video.tsx # Video component
22
+ │ ├── Theme.tsx # Theme provider
23
+ │ ├── _Controls.tsx # Live controls
24
+ │ └── _seo/ # SEO meta tag components
25
+ │ ├── Facebook.tsx
26
+ │ ├── Google.tsx
27
+ │ ├── LinkedIn.tsx
28
+ │ └── Twitter.tsx
29
+ ├── flags/
30
+ │ ├── audience.ts # Audience-based routing
31
+ │ ├── everyone.ts # Match all visitors
32
+ │ ├── flag.ts # Feature flag
33
+ │ └── multivariate.ts # Multivariate testing
34
+ ├── functions/
35
+ │ └── requestToParam.ts # Extract request params
36
+ ├── handlers/
37
+ │ ├── fresh.ts # Fresh framework handler
38
+ │ ├── proxy.ts # Reverse proxy (VTEX checkout, etc.)
39
+ │ ├── redirect.ts # URL redirects
40
+ │ ├── router.ts # Main router (matches pages to URLs)
41
+ │ └── sitemap.ts # Sitemap generation
42
+ ├── loaders/
43
+ │ ├── asset.ts # Asset URL resolution
44
+ │ ├── environment.ts # Environment variables
45
+ │ ├── fonts/ # Font loading (GoogleFonts, etc.)
46
+ │ ├── image/ # Image optimization
47
+ │ ├── pages.ts # Page resolution
48
+ │ ├── redirects.ts # Redirect rules
49
+ │ ├── redirectsFromCsv.ts # Bulk redirects from CSV
50
+ │ └── secret.ts # Secret values (API keys, tokens)
51
+ ├── matchers/
52
+ │ ├── always.ts # Always match
53
+ │ ├── cookie.ts # Match by cookie value
54
+ │ ├── cron.ts # Match by cron schedule
55
+ │ ├── date.ts # Match by date range
56
+ │ ├── device.ts # Match by device type
57
+ │ ├── host.ts # Match by hostname
58
+ │ ├── location.ts # Match by geo-location
59
+ │ ├── multi.ts # Combine matchers
60
+ │ ├── nthRequest.ts # Match every Nth request
61
+ │ ├── queryString.ts # Match by query params
62
+ │ ├── random.ts # Random percentage
63
+ │ ├── site.ts # Match by site ID
64
+ │ └── userAgent.ts # Match by user agent
65
+ ├── sections/
66
+ │ ├── Analytics/ # GA, GTM, Pixel sections
67
+ │ ├── Rendering/ # Lazy, Deferred rendering sections
68
+ │ └── Seo/ # SEO meta sections
69
+ └── utils/
70
+ ├── crypto.ts # Encryption helpers
71
+ ├── html.ts # HTML manipulation
72
+ ├── image/ # Image engine implementations
73
+ ├── location.ts # IP-to-location
74
+ ├── multivariate.ts # A/B test utilities
75
+ └── unhandledRejection.ts # Global error handler
76
+ ```
77
+
78
+ ## `mod.ts` Props
79
+
80
+ ```typescript
81
+ interface Props {
82
+ routes?: Routes[]; // URL → page/handler mapping
83
+ global?: Section[]; // Sections included on every page (header, footer)
84
+ errorPage?: Page; // Custom error page
85
+ caching?: Caching; // Cache-Control directives
86
+ abTesting?: AbTesting; // A/B test against another URL
87
+ flavor?: Fresh | HTMX; // Framework selection
88
+ seo?: Seo; // Default SEO meta
89
+ theme?: Section; // Theme section (CSS variables)
90
+ disableProxy?: boolean; // Disable image/asset proxy
91
+ whilelistURLs?: string[]; // Allowed proxy URL patterns
92
+ }
93
+ ```
94
+
95
+ ## Routing
96
+
97
+ The `handlers/router.ts` matches incoming URLs against registered `routes` and `audiences`:
98
+
99
+ ```
100
+ Request URL → matchers (device, cookie, location, etc.)
101
+ → matching audience → handler (page, proxy, redirect)
102
+ → global sections prepended
103
+ → render page
104
+ ```
105
+
106
+ ## A/B Testing
107
+
108
+ Built into the website app:
109
+
110
+ ```typescript
111
+ interface AbTesting {
112
+ enabled?: boolean;
113
+ name?: string; // Cookie name for variant tracking
114
+ matcher?: Matcher; // Who sees the variant
115
+ urlToRunAgainst?: string; // Proxy target URL
116
+ replaces?: TextReplace[]; // String replacements in proxied HTML
117
+ includeScriptsToHead?: Script[];
118
+ includeScriptsToBody?: Script[];
119
+ }
120
+ ```
121
+
122
+ ## Matchers
123
+
124
+ Used for audience targeting and A/B testing:
125
+
126
+ | Matcher | Criteria |
127
+ |---------|----------|
128
+ | `always` | Always matches |
129
+ | `cookie` | Cookie name/value |
130
+ | `cron` | Cron expression |
131
+ | `date` | Date range |
132
+ | `device` | Desktop/mobile/tablet |
133
+ | `host` | Request hostname |
134
+ | `location` | Country/city/region |
135
+ | `queryString` | URL query params |
136
+ | `random` | Random percentage |
137
+ | `userAgent` | Browser/OS detection |
138
+ | `multi` | AND/OR combination of matchers |
139
+
140
+ ## Handlers
141
+
142
+ | Handler | Purpose |
143
+ |---------|---------|
144
+ | `router.ts` | Main router — resolves URL to page + sections |
145
+ | `proxy.ts` | Reverse proxy with HTML rewriting, script injection |
146
+ | `redirect.ts` | URL redirects (301/302) |
147
+ | `fresh.ts` | Fresh framework page handler |
148
+ | `sitemap.ts` | Dynamic sitemap.xml generation |
149
+
150
+ ## SEO Components
151
+
152
+ Located in `components/_seo/`:
153
+ - `Google.tsx` — Title, description, canonical, JSON-LD
154
+ - `Facebook.tsx` — Open Graph meta tags
155
+ - `Twitter.tsx` — Twitter card meta tags
156
+ - `LinkedIn.tsx` — LinkedIn meta tags
157
+
158
+ ## Caching
159
+
160
+ ```typescript
161
+ interface Caching {
162
+ enabled?: boolean;
163
+ directives?: CacheDirective[];
164
+ }
165
+
166
+ type CacheDirective =
167
+ | { name: "stale-while-revalidate"; value: number }
168
+ | { name: "max-age"; value: number };
169
+ ```
@@ -0,0 +1,189 @@
1
+ ---
2
+ name: deco-apps-vtex-porting
3
+ description: Port the VTEX commerce app from deco-cx/apps (Fresh/Deno) to @decocms/apps-start (TanStack Start/Node). The goal is to mirror the original production code that runs on thousands of stores, adapting only what is necessary for TanStack/Node. Covers full structural mapping (141 files → apps-start equivalent), adaptation patterns (Deno→Node, signals→react-query, manifest→exports, ctx.bag→configureVtex), schema.org compliance, and a file-by-file gap analysis. Use when porting VTEX code, fixing bugs in apps-start, or ensuring parity with the original.
4
+ globs:
5
+ - "**/apps-start/vtex/**"
6
+ - "**/apps-start/commerce/**"
7
+ - "**/apps-start/shopify/**"
8
+ ---
9
+
10
+ # Porting deco-cx/apps to @decocms/apps-start
11
+
12
+ ## Philosophy
13
+
14
+ **The original `deco-cx/apps` is the source of truth.** It runs on thousands of stores in production. The goal of `apps-start` is NOT to reinvent — it's to mirror the same logic, adapted only where the platform forces a change (Deno→Node, Fresh→TanStack, Preact signals→React/TanStack Query).
15
+
16
+ When in doubt about how something should work, look at the original first.
17
+
18
+ ## Sub-documents
19
+
20
+ | Document | Topic |
21
+ |----------|-------|
22
+ | [structure-map.md](./structure-map.md) | File-by-file mapping: original → apps-start (what exists, what's missing, what's wrong) |
23
+ | [adaptation-patterns.md](./adaptation-patterns.md) | How to convert each Deno/Fresh/Deco pattern to TanStack/Node |
24
+ | [commerce-porting.md](./commerce-porting.md) | Porting the commerce/ module (types, utils, SDK, components) |
25
+ | [website-porting.md](./website-porting.md) | Where website/ code goes (framework, storefront, worker entry) |
26
+ | [transform-mapping.md](./transform-mapping.md) | Field-by-field VTEX → schema.org mapping in transform.ts |
27
+ | [cookie-auth-patterns.md](./cookie-auth-patterns.md) | Cookie propagation, auth headers, session handling |
28
+
29
+ ## Architecture Comparison
30
+
31
+ ```
32
+ deco-cx/apps (Original) @decocms/apps-start (Port)
33
+ ═══════════════════════ ═════════════════════════
34
+ Deno + Fresh + Preact Node + TanStack Start + React
35
+ @deco/deco framework No framework (pure functions)
36
+ mod.ts (app factory) configureVtex() / index.ts
37
+ manifest.gen.ts (auto-gen) package.json exports (manual)
38
+ runtime.ts (invoke proxy) Direct imports
39
+ ctx (AppContext + bag) getVtexConfig() singleton
40
+ signals (@preact/signals) @tanstack/react-query mutations
41
+ middleware.ts (ctx.bag) middleware.ts (request-local)
42
+ OpenAPI codegen (*.gen.ts) Manual vtexFetch calls
43
+ proxySetCookie (Deno std) vtexFetchWithCookies (manual)
44
+ ```
45
+
46
+ ## What Changes, What Stays
47
+
48
+ ### STAYS THE SAME (copy/adapt minimally)
49
+ - `utils/transform.ts` — the entire VTEX→schema.org mapping
50
+ - `utils/types.ts` — all 1320 lines of VTEX API types
51
+ - `utils/segment.ts` — segment parsing/serialization logic
52
+ - `utils/intelligentSearch.ts` — IS param building
53
+ - `utils/cookies.ts` — cookie stringify, constants
54
+ - `utils/vtexId.ts` — auth cookie parsing
55
+ - `utils/orderForm.ts` — OrderForm cookie parsing
56
+ - `utils/similars.ts` — similar products enrichment
57
+ - `utils/batch.ts` — batch API calls
58
+ - `utils/slugify.ts` — URL slug generation
59
+ - Business logic in actions (the VTEX API calls)
60
+ - Business logic in loaders (the data fetching + transform)
61
+
62
+ ### MUST CHANGE (platform differences)
63
+ | Original Pattern | apps-start Pattern | Why |
64
+ |-----------------|-------------------|-----|
65
+ | `export default function(props, req, ctx)` | `export async function myLoader(props)` | No Deco framework, no AppContext |
66
+ | `ctx.account`, `ctx.salesChannel` | `getVtexConfig().account` | No ctx.bag |
67
+ | `ctx.vcsDeprecated["POST /path"]({}, opts)` | `vtexFetch<T>("/path", opts)` | No OpenAPI typed client |
68
+ | `createHttpClient<VCS>()` | `vtexFetch()` / `vtexFetchWithCookies()` | No Deno-style Proxy client |
69
+ | `ctx.io.query<D,V>({query, variables})` | `vtexIOGraphQL<T>({query, variables})` | No createGraphqlClient |
70
+ | `proxySetCookie(res.headers, ctx.response.headers)` | Return `{ data, setCookies }` from vtexFetchWithCookies | No ctx.response |
71
+ | `getSegmentFromBag(ctx)` | Read from middleware context or config | No ctx.bag |
72
+ | `signal<OrderForm\|null>(null)` | `useQuery` / `useMutation` from @tanstack/react-query | No @preact/signals |
73
+ | `invoke({ cart: { key, props } })` | Direct fetch to API routes or useMutation | No Deco invoke proxy |
74
+ | `import { getCookies } from "std/http/mod.ts"` | Parse cookies manually or use a cookie lib | No Deno std |
75
+
76
+ ## Key Concepts for Porters
77
+
78
+ ### 1. The Typed Client Is Gone
79
+
80
+ Original uses `createHttpClient<VTEXCommerceStable>()` which creates a Proxy object where property access like `client["POST /api/checkout/pub/orderForm"]({sc: "1"}, {body: ...})` is fully typed.
81
+
82
+ In apps-start, this is replaced by `vtexFetch<T>(path, init)` — a simpler wrapper:
83
+
84
+ ```typescript
85
+ // Original (apps)
86
+ const response = await ctx.vcsDeprecated["POST /api/checkout/pub/orderForm/:orderFormId/items"](
87
+ { orderFormId, sc, allowedOutdatedData: ["paymentData"] },
88
+ { body: { orderItems }, headers: { cookie } },
89
+ );
90
+ const orderForm = await response.json();
91
+
92
+ // Port (apps-start)
93
+ const orderForm = await vtexFetch<OrderForm>(
94
+ `/api/checkout/pub/orderForm/${orderFormId}/items?sc=${sc}&allowedOutdatedData=paymentData`,
95
+ { method: "POST", body: JSON.stringify({ orderItems }), headers: { cookie, "Content-Type": "application/json" } },
96
+ );
97
+ ```
98
+
99
+ ### 2. One Loader Per File → Consolidated Loaders
100
+
101
+ Original has one file per loader (e.g., `loaders/intelligentSearch/productDetailsPage.ts`). Apps-start consolidates:
102
+ - `loaders/intelligentSearch/*.ts` (6 files) → `loaders/search.ts` + `inline-loaders/productDetailsPage.ts` etc.
103
+ - `loaders/legacy/*.ts` (7 files) → `loaders/legacy.ts` + `loaders/catalog.ts`
104
+
105
+ This is fine but makes it harder to compare. Always check the ORIGINAL file to understand intended behavior.
106
+
107
+ ### 3. Actions Are Consolidated Too
108
+
109
+ Original: `actions/cart/addItems.ts`, `actions/cart/updateItems.ts`, etc. (16 files)
110
+ Apps-start: `actions/checkout.ts` (all cart actions in one file)
111
+
112
+ ### 4. Hooks Use React Query Instead of Signals
113
+
114
+ Original hooks use a serial queue pattern with `@preact/signals`:
115
+ ```typescript
116
+ const cart = signal<OrderForm | null>(null);
117
+ const enqueue = (key) => (props) => storeState.enqueue((signal) => invoke({ cart: { key, props } }));
118
+ ```
119
+
120
+ Apps-start hooks use `@tanstack/react-query`:
121
+ ```typescript
122
+ const { data: cart } = useQuery({ queryKey: ["cart"], queryFn: fetchCart });
123
+ const addItems = useMutation({ mutationFn: addItemsToCart, onSuccess: () => queryClient.invalidateQueries(["cart"]) });
124
+ ```
125
+
126
+ ### 5. Middleware Has No ctx.bag
127
+
128
+ Original middleware sets state in `ctx.bag` (per-request storage):
129
+ ```typescript
130
+ setSegmentBag(cookies, req, ctx); // ctx.bag.set(SEGMENT, data)
131
+ setISCookiesBag(cookies, ctx); // ctx.bag.set(IS_COOKIES, data)
132
+ ```
133
+
134
+ Apps-start uses `configureVtex()` singleton + request-level context:
135
+ ```typescript
136
+ const config = getVtexConfig(); // Global config
137
+ // Per-request: pass cookies/segment through function params
138
+ ```
139
+
140
+ ## The sellerId vs sellerName Pitfall
141
+
142
+ The #1 bug when porting. VTEX `Offer.seller` MUST be `sellerId` (e.g., `"1"`), NOT `sellerName`. If you see `ORD027: Item não encontrado ou indisponível`, this is almost certainly the cause.
143
+
144
+ The original `transform.ts` `buildOffer()` handles this correctly. **Never** create manual Offer mappings in loaders — always use `toProduct()` / `toProductPage()`.
145
+
146
+ ## salesChannel (sc) Injection
147
+
148
+ Missing `sc` = wrong prices, ORD027, or invisible products.
149
+
150
+ | Endpoint Type | How to inject |
151
+ |--------------|---------------|
152
+ | Checkout API (`/api/checkout/pub/orderForm/*`) | `?sc={salesChannel}` query param |
153
+ | Legacy Catalog (`/api/catalog_system/pub/products/search/*`) | `?sc={salesChannel}` query param |
154
+ | Buscaautocomplete (`/buscaautocomplete`) | `&sc={salesChannel}` query param |
155
+ | Intelligent Search | Handled automatically by `intelligentSearch()` in client.ts |
156
+ | Client-side hooks | Read `VTEXSC` cookie via `document.cookie` |
157
+
158
+ ## Quick Reference: transform.ts Functions
159
+
160
+ | Function | Input | Output |
161
+ |----------|-------|--------|
162
+ | `toProduct(product, sku, level, opts)` | VTEX Product/LegacyProduct | schema.org Product |
163
+ | `toProductPage(product, sku, breadcrumbs, opts)` | VTEX Product + SKU | ProductDetailsPage |
164
+ | `pickSku(product, skuId?)` | Product with items[] | Best SKU item |
165
+ | `aggregateOffers(offers)` | Offer[] | AggregateOffer |
166
+ | `buildOffer(seller, opts)` | VTEX Seller | schema.org Offer (with seller=sellerId) |
167
+ | `forceHttpsOnAssets(orderForm)` | OrderForm | OrderForm with https URLs |
168
+
169
+ ## Debugging Checklist
170
+
171
+ 1. **ORD027** → Check `seller` value (must be sellerId, not sellerName)
172
+ 2. **Wrong prices** → Check `sc` parameter on API calls
173
+ 3. **Empty cart** → Check `expectedOrderFormSections` in POST body
174
+ 4. **Auth fails** → Check `buildAuthCookieHeader` produces both cookie variants
175
+ 5. **IS returns nothing** → Check `vtex_is_session` / `vtex_is_anonymous` cookies
176
+ 6. **User always logged out** → Check `useUser` uses server-side session check, not client cookie
177
+ 7. **Missing product data** → Check transform.ts is being used (not manual mapping)
178
+
179
+ ## Local Development
180
+
181
+ ```json
182
+ // storefront package.json
183
+ "@decocms/apps": "file:../apps-start"
184
+ ```
185
+
186
+ After changes to apps-start:
187
+ ```bash
188
+ rm -rf node_modules/.vite && npm run dev
189
+ ```