@decocms/blocks-cli 7.5.0 → 7.5.2

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 (37) hide show
  1. package/package.json +3 -3
  2. package/scripts/generate-invoke.ts +10 -0
  3. package/scripts/generate-schema.test.ts +4 -4
  4. package/scripts/generate-sections.test.ts +6 -6
  5. package/scripts/migrate/analyzers/loader-inventory.ts +1 -1
  6. package/scripts/migrate/phase-analyze.ts +3 -3
  7. package/scripts/migrate/phase-cleanup.ts +29 -23
  8. package/scripts/migrate/phase-report.ts +7 -7
  9. package/scripts/migrate/phase-scaffold.ts +4 -4
  10. package/scripts/migrate/phase-transform.ts +1 -1
  11. package/scripts/migrate/phase-verify.ts +6 -5
  12. package/scripts/migrate/post-cleanup/rules.ts +55 -44
  13. package/scripts/migrate/post-cleanup/runner.test.ts +58 -34
  14. package/scripts/migrate/templates/cache-config.ts +4 -4
  15. package/scripts/migrate/templates/commerce-loaders.ts +10 -10
  16. package/scripts/migrate/templates/cursor-rules.test.ts +6 -0
  17. package/scripts/migrate/templates/cursor-rules.ts +12 -11
  18. package/scripts/migrate/templates/hooks.test.ts +7 -7
  19. package/scripts/migrate/templates/hooks.ts +10 -10
  20. package/scripts/migrate/templates/lib-utils.test.ts +2 -2
  21. package/scripts/migrate/templates/lib-utils.ts +4 -4
  22. package/scripts/migrate/templates/no-legacy-packages.test.ts +147 -0
  23. package/scripts/migrate/templates/package-json.ts +24 -10
  24. package/scripts/migrate/templates/routes.ts +8 -10
  25. package/scripts/migrate/templates/sdk-gen.ts +1 -1
  26. package/scripts/migrate/templates/section-loaders.ts +7 -7
  27. package/scripts/migrate/templates/server-entry.ts +37 -37
  28. package/scripts/migrate/templates/setup.ts +6 -6
  29. package/scripts/migrate/templates/types-gen.ts +2 -2
  30. package/scripts/migrate/templates/ui-components.ts +2 -2
  31. package/scripts/migrate/templates/vite-config.ts +12 -3
  32. package/scripts/migrate/transforms/fresh-apis.ts +5 -5
  33. package/scripts/migrate/transforms/imports.ts +49 -43
  34. package/scripts/migrate/transforms/section-conventions.ts +1 -1
  35. package/scripts/migrate/types.ts +1 -1
  36. package/scripts/migrate-post-cleanup.ts +8 -8
  37. package/scripts/migrate.ts +11 -11
@@ -43,7 +43,7 @@ function generateWorkerEntry(ctx: MigrationContext): string {
43
43
  * Cloudflare Worker entry point.
44
44
  *
45
45
  * Wraps TanStack Start with admin protocol handlers, edge caching, and
46
- * the @decocms/start observability stack (5.0+, Cloudflare-native):
46
+ * the @decocms/blocks observability stack (5.0+, Cloudflare-native):
47
47
  * - logs: console.* -> CF Workers Logs (captured by the platform
48
48
  * when wrangler.jsonc has \`observability.enabled: true\`).
49
49
  * View in the CF dashboard -> Workers & Pages -> <site> ->
@@ -57,27 +57,27 @@ function generateWorkerEntry(ctx: MigrationContext): string {
57
57
  *
58
58
  * No in-Worker OTLP exporter ships with 5.x — the CF dashboard is the
59
59
  * destination. A ClickHouse-collector adapter is scaffolded at
60
- * @decocms/start/sdk/otelAdapters/clickhouseCollector but throws if
60
+ * @decocms/blocks/sdk/otelAdapters/clickhouseCollector but throws if
61
61
  * called; it'll get a real implementation once the OTel collector
62
62
  * gateway lands.
63
63
  *
64
64
  * To wire wrangler.jsonc with the canonical observability block, run:
65
- * npx -p @decocms/start deco-cf-observability --write
65
+ * npx -p @decocms/blocks-cli deco-cf-observability --write
66
66
  */
67
67
  import "./setup";
68
68
  import handler, { createServerEntry } from "@tanstack/react-start/server-entry";
69
- import { createDecoWorkerEntry } from "@decocms/start/sdk/workerEntry";
70
- import { instrumentWorker } from "@decocms/start/sdk/observability";
69
+ import { createDecoWorkerEntry } from "@decocms/tanstack";
70
+ import { instrumentWorker } from "@decocms/blocks/sdk/observability";
71
71
  import {
72
72
  handleMeta,
73
73
  handleDecofileRead,
74
74
  handleDecofileReload,
75
75
  handleRender,
76
76
  corsHeaders,
77
- } from "@decocms/start/admin";
77
+ } from "@decocms/blocks-admin";
78
78
  ${isCommerce ? `
79
79
  // TODO: Uncomment and wire proxy for ${platformLabel}
80
- // import { shouldProxyTo${capitalize(platformLabel!)}, proxyTo${capitalize(platformLabel!)} } from "@decocms/apps/${platformLabel}/utils/proxy";
80
+ // import { shouldProxyTo${capitalize(platformLabel!)}, proxyTo${capitalize(platformLabel!)} } from "@decocms/apps-${platformLabel}/utils/proxy";
81
81
  ` : ""}
82
82
  const serverEntry = createServerEntry({ fetch: handler.fetch });
83
83
 
@@ -110,23 +110,23 @@ function generateVtexWorkerEntry(ctx: MigrationContext): string {
110
110
 
111
111
  return `import "./setup";
112
112
  import handler, { createServerEntry } from "@tanstack/react-start/server-entry";
113
- import { createDecoWorkerEntry } from "@decocms/start/sdk/workerEntry";
114
- import { instrumentWorker } from "@decocms/start/sdk/observability";
113
+ import { createDecoWorkerEntry } from "@decocms/tanstack";
114
+ import { instrumentWorker } from "@decocms/blocks/sdk/observability";
115
115
  import {
116
116
  handleMeta,
117
117
  handleDecofileRead,
118
118
  handleDecofileReload,
119
119
  handleRender,
120
120
  corsHeaders,
121
- } from "@decocms/start/admin";
122
- import { shouldProxyToVtex, createVtexCheckoutProxy } from "@decocms/apps/vtex/utils/proxy";
123
- import { extractVtexContext } from "@decocms/apps/vtex/middleware";
124
- import { loadRedirects, matchRedirect } from "@decocms/start/sdk/redirects";
125
- import { withABTesting } from "@decocms/start/sdk/abTesting";
126
- import { loadBlocks } from "@decocms/start/cms";
121
+ } from "@decocms/blocks-admin";
122
+ import { shouldProxyToVtex, createVtexCheckoutProxy } from "@decocms/apps-vtex/utils/proxy";
123
+ import { extractVtexContext } from "@decocms/apps-vtex/middleware";
124
+ import { loadRedirects, matchRedirect } from "@decocms/blocks/sdk/redirects";
125
+ import { withABTesting } from "@decocms/blocks/sdk/abTesting";
126
+ import { loadBlocks } from "@decocms/blocks/cms";
127
127
 
128
128
  // ---------------------------------------------------------------------------
129
- // VTEX checkout proxy — configured via @decocms/apps factory
129
+ // VTEX checkout proxy — configured via @decocms/apps-vtex factory
130
130
  // ---------------------------------------------------------------------------
131
131
 
132
132
  const proxyCheckout = createVtexCheckoutProxy({
@@ -226,7 +226,7 @@ const abTestedWorker = withABTesting(decoWorker, {
226
226
  // ---------------------------------------------------------------------------
227
227
  // Observability wrap (outermost layer)
228
228
  //
229
- // @decocms/start 5.0+ converged on Cloudflare-native observability:
229
+ // @decocms/blocks 5.0+ converged on Cloudflare-native observability:
230
230
  // - logs: console.* -> CF Workers Logs (dashboard captures, no
231
231
  // app-side OTLP exporter)
232
232
  // - traces: @opentelemetry/api global tracer (bridged from
@@ -236,7 +236,7 @@ const abTestedWorker = withABTesting(decoWorker, {
236
236
  // src/sdk/otelAdapters/clickhouseCollector.ts)
237
237
  //
238
238
  // Wire wrangler.jsonc with the canonical observability block via:
239
- // npx -p @decocms/start deco-cf-observability --write
239
+ // npx -p @decocms/blocks-cli deco-cf-observability --write
240
240
  // ---------------------------------------------------------------------------
241
241
  export default instrumentWorker(abTestedWorker, {
242
242
  serviceName: "${ctx.siteName}",
@@ -246,7 +246,7 @@ export default instrumentWorker(abTestedWorker, {
246
246
 
247
247
  function generateRouter(): string {
248
248
  return `import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
249
- import { createDecoRouter } from "@decocms/start/sdk/router";
249
+ import { createDecoRouter } from "@decocms/tanstack";
250
250
  import { routeTree } from "./routeTree.gen";
251
251
  import "./setup";
252
252
 
@@ -274,16 +274,16 @@ declare module "@tanstack/react-router" {
274
274
 
275
275
  function generateRuntime(): string {
276
276
  return `/**
277
- * Runtime invoke proxy — re-exports the framework canonical from @decocms/start/sdk.
277
+ * Runtime invoke proxy — re-exports the framework canonical from @decocms/blocks/sdk/invoke.
278
278
  *
279
279
  * The implementation (typed RPC over /deco/invoke, dotted-path proxy, .ts
280
- * suffix fallback) lives in @decocms/start/sdk/invoke. This file exists so
280
+ * suffix fallback) lives in @decocms/blocks/sdk/invoke. This file exists so
281
281
  * existing site code can keep \`import { invoke } from "~/runtime"\` and
282
282
  * \`Runtime.invoke\` shapes without churn.
283
283
  *
284
- * Don't reimplement here — extend @decocms/start/sdk/invoke instead.
284
+ * Don't reimplement here — extend @decocms/blocks/sdk/invoke instead.
285
285
  */
286
- import { invoke } from "@decocms/start/sdk";
286
+ import { invoke } from "@decocms/blocks/sdk/invoke";
287
287
 
288
288
  export { invoke };
289
289
 
@@ -328,14 +328,14 @@ export const invoke = {} as const;
328
328
  */
329
329
  import { createServerFn } from "@tanstack/react-start";
330
330
  import { getRequestHeader } from "@tanstack/react-start/server";
331
- import { forwardResponseCookies } from "@decocms/start/sdk/cookiePassthrough";
331
+ import { forwardResponseCookies } from "@decocms/tanstack/sdk/cookiePassthrough";
332
332
  import { vtexActions } from "./invoke.gen";
333
333
  ${hasVtexAuthLoader ? `import vtexAuthLoader from "../loaders/vtex-auth-loader";\n` : ""}import {
334
334
  extractVtexCookiesFromHeader,
335
335
  stripCookieDomain,
336
336
  performVtexLogout,
337
337
  parseVtexAuthJwt,
338
- } from "@decocms/apps/vtex/utils/authHelpers";
338
+ } from "@decocms/apps-vtex/utils/authHelpers";
339
339
 
340
340
  export type { OrderForm } from "./invoke.gen";
341
341
 
@@ -398,17 +398,17 @@ export const vtexActions = {} as const;
398
398
  // Each server function is a top-level const so TanStack Start's compiler
399
399
  // can transform createServerFn().handler() into RPC stubs on the client.
400
400
  import { createServerFn } from "@tanstack/react-start";
401
- import { getOrCreateCart, addItemsToCart, updateCartItems, addCouponToCart, simulateCart, getSellersByRegion, setShippingPostalCode, updateOrderFormAttachment } from "@decocms/apps/vtex/actions/checkout";
402
- import { createSession, editSession } from "@decocms/apps/vtex/actions/session";
403
- import { createDocument, getDocument, patchDocument, searchDocuments, uploadAttachment } from "@decocms/apps/vtex/actions/masterData";
404
- import { subscribe } from "@decocms/apps/vtex/actions/newsletter";
405
- import { notifyMe } from "@decocms/apps/vtex/actions/misc";
406
- import type { OrderForm } from "@decocms/apps/vtex/types";
407
- import type { SimulationItem, RegionResult } from "@decocms/apps/vtex/actions/checkout";
408
- import type { SessionData } from "@decocms/apps/vtex/actions/session";
409
- import type { CreateDocumentResult, UploadAttachmentOpts } from "@decocms/apps/vtex/actions/masterData";
410
- import type { SubscribeProps } from "@decocms/apps/vtex/actions/newsletter";
411
- import type { NotifyMeProps } from "@decocms/apps/vtex/actions/misc";
401
+ import { getOrCreateCart, addItemsToCart, updateCartItems, addCouponToCart, simulateCart, getSellersByRegion, setShippingPostalCode, updateOrderFormAttachment } from "@decocms/apps-vtex/actions/checkout";
402
+ import { createSession, editSession } from "@decocms/apps-vtex/actions/session";
403
+ import { createDocument, getDocument, patchDocument, searchDocuments, uploadAttachment } from "@decocms/apps-vtex/actions/masterData";
404
+ import { subscribe } from "@decocms/apps-vtex/actions/newsletter";
405
+ import { notifyMe } from "@decocms/apps-vtex/actions/misc";
406
+ import type { OrderForm } from "@decocms/apps-vtex/types";
407
+ import type { SimulationItem, RegionResult } from "@decocms/apps-vtex/actions/checkout";
408
+ import type { SessionData } from "@decocms/apps-vtex/actions/session";
409
+ import type { CreateDocumentResult, UploadAttachmentOpts } from "@decocms/apps-vtex/actions/masterData";
410
+ import type { SubscribeProps } from "@decocms/apps-vtex/actions/newsletter";
411
+ import type { NotifyMeProps } from "@decocms/apps-vtex/actions/misc";
412
412
 
413
413
  function unwrapResult<T>(result: unknown): T {
414
414
  if (result && typeof result === "object" && "data" in result) {
@@ -549,7 +549,7 @@ export const vtexActions = {
549
549
  notifyMe: $notifyMe as unknown as (ctx: { data: NotifyMeProps }) => Promise<void>,
550
550
  } as const;
551
551
 
552
- export type { OrderForm } from "@decocms/apps/vtex/types";
552
+ export type { OrderForm } from "@decocms/apps-vtex/types";
553
553
 
554
554
  export const invoke = {
555
555
  vtex: {
@@ -93,15 +93,15 @@ import "./cache-config";
93
93
  import {
94
94
  registerCommerceLoaders,
95
95
  applySectionConventions,
96
- } from "@decocms/start/cms";
97
- import { createSiteSetup } from "@decocms/start/setup";
98
- import { setInvokeLoaders } from "@decocms/start/admin";${isVtex ? `
99
- import { createInstrumentedFetch } from "@decocms/start/sdk/instrumentedFetch";
100
- import { initVtexFromBlocks, setVtexFetch } from "@decocms/apps/vtex";` : ""}${hasLocationMatcher ? `
96
+ } from "@decocms/blocks/cms";
97
+ import { createSiteSetup } from "@decocms/blocks/setup";
98
+ import { setInvokeLoaders } from "@decocms/blocks-admin";${isVtex ? `
99
+ import { createInstrumentedFetch } from "@decocms/blocks/sdk/instrumentedFetch";
100
+ import { initVtexFromBlocks, setVtexFetch } from "@decocms/apps-vtex";` : ""}${hasLocationMatcher ? `
101
101
  import { registerLocationMatcher } from "./matchers/location";` : ""}
102
102
  import { blocks as generatedBlocks } from "../.deco/blocks.gen";
103
103
  import { sectionMeta, syncComponents, loadingFallbacks } from "../.deco/sections.gen";
104
- import { PreviewProviders } from "@decocms/start/hooks";
104
+ import { PreviewProviders } from "@decocms/tanstack";
105
105
  // @ts-ignore Vite ?url import
106
106
  import appCss from "./styles/app.css?url";
107
107
 
@@ -5,7 +5,7 @@ export function generateTypeFiles(ctx: MigrationContext): Record<string, string>
5
5
 
6
6
  // src/types/widgets.ts is no longer generated — the framework owns these
7
7
  // string aliases (`ImageWidget`, `HTMLWidget`, …) at
8
- // `@decocms/start/types/widgets`, and `transforms/imports.ts` rewrites
8
+ // `@decocms/blocks/types/widgets`, and `transforms/imports.ts` rewrites
9
9
  // `apps/admin/widgets.ts` directly to that path. Schema generation
10
10
  // works the same way: the generator matches by type *text*, not module
11
11
  // identity (see scripts/generate-schema.ts:WIDGET_TYPE_FORMATS).
@@ -99,7 +99,7 @@ export type AppContext = {
99
99
  export type LegacyAppContext = AppContext;
100
100
  `;
101
101
 
102
- files["src/types/vtex-loaders.ts"] = `import type { Product, ProductListingPage } from "@decocms/apps/commerce/types";
102
+ files["src/types/vtex-loaders.ts"] = `import type { Product, ProductListingPage } from "@decocms/apps-commerce/types";
103
103
 
104
104
  export interface ProductListProps {
105
105
  page: ProductListingPage | null;
@@ -13,7 +13,7 @@ export function generateUiComponents(_ctx: MigrationContext): Record<string, str
13
13
  FACTORS,
14
14
  type ImageProps,
15
15
  type FitOptions,
16
- } from "@decocms/apps/commerce/components/Image";
16
+ } from "@decocms/blocks/hooks";
17
17
  `;
18
18
 
19
19
  files["src/components/ui/Picture.tsx"] = `import type { ReactNode } from "react";
@@ -22,7 +22,7 @@ import {
22
22
  getSrcSet,
23
23
  type FitOptions,
24
24
  type ImageProps,
25
- } from "@decocms/apps/commerce/components/Image";
25
+ } from "@decocms/blocks/hooks";
26
26
 
27
27
  export interface PictureSourceProps {
28
28
  src: string;
@@ -1,7 +1,14 @@
1
1
  import type { MigrationContext } from "../types";
2
2
 
3
+ const PLATFORM_PACKAGE: Partial<Record<MigrationContext["platform"], string>> = {
4
+ vtex: "@decocms/apps-vtex",
5
+ shopify: "@decocms/apps-shopify",
6
+ magento: "@decocms/apps-magento",
7
+ };
8
+
3
9
  export function generateViteConfig(ctx: MigrationContext): string {
4
10
  const isVtex = ctx.platform === "vtex";
11
+ const platformDep = PLATFORM_PACKAGE[ctx.platform];
5
12
 
6
13
  const vtexAccount = ctx.vtexAccount || ctx.siteName.replace(/-migrated$/, "").replace(/-storefront$/, "");
7
14
 
@@ -29,7 +36,7 @@ const VTEX_ORIGIN = \`https://\${VTEX_ACCOUNT}.\${VTEX_ENVIRONMENT}.\${VTEX_DOMA
29
36
 
30
37
  return `import { cloudflare } from "@cloudflare/vite-plugin";
31
38
  import { tanstackStart } from "@tanstack/react-start/plugin/vite";
32
- import { decoVitePlugin } from "@decocms/start/vite";
39
+ import { decoVitePlugin } from "@decocms/tanstack/vite";
33
40
  import react from "@vitejs/plugin-react";
34
41
  import tailwindcss from "@tailwindcss/vite";
35
42
  import { defineConfig } from "vite";
@@ -80,8 +87,10 @@ export default defineConfig({
80
87
  },
81
88
  resolve: {
82
89
  dedupe: [
83
- "@decocms/start",
84
- "@decocms/apps",
90
+ "@decocms/blocks",
91
+ "@decocms/blocks-admin",
92
+ "@decocms/tanstack",
93
+ "@decocms/apps-commerce",${platformDep ? `\n "${platformDep}",` : ""}
85
94
  "@tanstack/react-start",
86
95
  "@tanstack/react-router",
87
96
  "@tanstack/react-start-server",
@@ -165,10 +165,10 @@ export function transformFreshApis(content: string): TransformResult {
165
165
  if (result.includes("scriptAsDataURI")) {
166
166
  // Ensure useScript is imported
167
167
  if (
168
- !result.includes('"@decocms/start/sdk/useScript"') &&
169
- !result.includes("'@decocms/start/sdk/useScript'")
168
+ !result.includes('"@decocms/blocks/sdk/useScript"') &&
169
+ !result.includes("'@decocms/blocks/sdk/useScript'")
170
170
  ) {
171
- result = `import { useScript } from "@decocms/start/sdk/useScript";\n${result}`;
171
+ result = `import { useScript } from "@decocms/blocks/sdk/useScript";\n${result}`;
172
172
  }
173
173
 
174
174
  // Transform src={scriptAsDataURI(...)} into dangerouslySetInnerHTML={{ __html: useScript(...) }}
@@ -190,7 +190,7 @@ export function transformFreshApis(content: string): TransformResult {
190
190
  notes.push("Replaced scriptAsDataURI with useScript + dangerouslySetInnerHTML");
191
191
  }
192
192
 
193
- // allowCorsFor — not available in @decocms/start, remove usage
193
+ // allowCorsFor — not available in @decocms/blocks, remove usage
194
194
  if (result.includes("allowCorsFor")) {
195
195
  result = result.replace(
196
196
  /^import\s+\{[^}]*\ballowCorsFor\b[^}]*\}\s+from\s+["'][^"']+["'];?\s*\n?/gm,
@@ -204,7 +204,7 @@ export function transformFreshApis(content: string): TransformResult {
204
204
 
205
205
  // ctx.response.headers → not available, flag
206
206
  if (result.includes("ctx.response")) {
207
- notes.push("MANUAL: ctx.response usage found — FnContext in @decocms/start does not have response object");
207
+ notes.push("MANUAL: ctx.response usage found — FnContext in @decocms/blocks does not have response object");
208
208
  }
209
209
 
210
210
  // { crypto } from "@std/crypto" → use globalThis.crypto (Web Crypto API)
@@ -20,7 +20,7 @@ const IMPORT_RULES: Array<[RegExp, string | null]> = [
20
20
  [/^"@preact\/signals"$/, `"~/sdk/signal"`],
21
21
 
22
22
  // Deco framework — hooks need splitting (useDevice, useScript, useSection)
23
- [/^"@deco\/deco\/hooks"$/, `"@decocms/start/sdk/useScript"`],
23
+ [/^"@deco\/deco\/hooks"$/, `"@decocms/blocks/sdk/useScript"`],
24
24
  [/^"@deco\/deco\/blocks"$/, `"~/types/deco"`],
25
25
  [/^"@deco\/deco\/o11y"$/, null], // logger — use console.log/warn/error instead
26
26
  [/^"@deco\/deco\/web"$/, null], // runtime.ts is rewritten
@@ -32,66 +32,66 @@ const IMPORT_RULES: Array<[RegExp, string | null]> = [
32
32
  // Widget aliases (ImageWidget, HTMLWidget, ...) are framework-owned —
33
33
  // every site has the same type set, and the schema generator detects
34
34
  // them via type-text matching, not module identity. Re-export from
35
- // @decocms/start/types/widgets so we don't keep a duplicated 8-line
35
+ // @decocms/blocks/types/widgets so we don't keep a duplicated 8-line
36
36
  // file in every site.
37
- [/^"apps\/admin\/widgets\.ts"$/, `"@decocms/start/types/widgets"`],
37
+ [/^"apps\/admin\/widgets\.ts"$/, `"@decocms/blocks/types/widgets"`],
38
38
  [/^"apps\/website\/components\/Image\.tsx"$/, `"~/components/ui/Image"`],
39
39
  [/^"apps\/website\/components\/Picture\.tsx"$/, `"~/components/ui/Picture"`],
40
40
  [/^"apps\/website\/components\/Video\.tsx"$/, `"~/components/ui/Video"`],
41
41
  [/^"apps\/website\/components\/Theme\.tsx"$/, `"~/components/ui/Theme"`],
42
42
  [/^"apps\/website\/components\/_seo\/[^"]+?"$/, null], // SEO preview — framework-only, remove
43
43
  [/^"apps\/website\/components\/([^"]+?)(?:\.tsx?)?"$/, `"~/components/ui/$1"`],
44
- [/^"apps\/commerce\/types\.ts"$/, `"@decocms/apps/commerce/types"`],
44
+ [/^"apps\/commerce\/types\.ts"$/, `"@decocms/apps-commerce/types"`],
45
45
  [/^"apps\/commerce\/mod\.ts"$/, `"~/types/commerce-app"`],
46
- [/^"apps\/commerce\/types"$/, `"@decocms/apps/commerce/types"`],
46
+ [/^"apps\/commerce\/types"$/, `"@decocms/apps-commerce/types"`],
47
47
 
48
- // Apps — VTEX hooks: useUser/useCart/useWishlist → local hooks (react-query based @decocms/apps hooks crash Workers SSR)
48
+ // Apps — VTEX hooks: useUser/useCart/useWishlist → local hooks (react-query based @decocms/apps-vtex hooks crash Workers SSR)
49
49
  [/^"apps\/vtex\/hooks\/useUser(?:\.ts)?"$/, `"~/hooks/useUser"`],
50
50
  [/^"apps\/vtex\/hooks\/useCart(?:\.ts)?"$/, `"~/hooks/useCart"`],
51
51
  [/^"apps\/vtex\/hooks\/useWishlist(?:\.ts)?"$/, `"~/hooks/useWishlist"`],
52
- [/^"apps\/vtex\/hooks\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/vtex/hooks/$1"`],
53
- // Specific VTEX utils that moved to different paths in @decocms/apps
52
+ [/^"apps\/vtex\/hooks\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-vtex/hooks/$1"`],
53
+ // Specific VTEX utils that moved to different paths in @decocms/apps-vtex
54
54
  // fetchVTEX (generic fetchSafe + QS sanitization) lives at vtex/utils/fetch in apps-start.
55
- [/^"apps\/vtex\/utils\/fetchVTEX(?:\.ts)?"$/, `"@decocms/apps/vtex/utils/fetch"`],
56
- [/^"apps\/vtex\/utils\/client(?:\.ts)?"$/, `"@decocms/apps/vtex/client"`],
57
- [/^"apps\/vtex\/utils\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/vtex/utils/$1"`],
58
- [/^"apps\/vtex\/actions\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/vtex/actions/$1"`],
55
+ [/^"apps\/vtex\/utils\/fetchVTEX(?:\.ts)?"$/, `"@decocms/apps-vtex/utils/fetch"`],
56
+ [/^"apps\/vtex\/utils\/client(?:\.ts)?"$/, `"@decocms/apps-vtex/client"`],
57
+ [/^"apps\/vtex\/utils\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-vtex/utils/$1"`],
58
+ [/^"apps\/vtex\/actions\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-vtex/actions/$1"`],
59
59
  // Tier B loader path rewrites (apps-start has no `intelligentSearch/`, `legacy/<file>`, or `paths/` subdirs).
60
60
  // Intelligent Search loaders moved to inline-loaders/.
61
61
  [
62
62
  /^"apps\/vtex\/loaders\/intelligentSearch\/productList(?:\.ts)?"$/,
63
- `"@decocms/apps/vtex/inline-loaders/productList"`,
63
+ `"@decocms/apps-vtex/inline-loaders/productList"`,
64
64
  ],
65
65
  [
66
66
  /^"apps\/vtex\/loaders\/intelligentSearch\/productListingPage(?:\.ts)?"$/,
67
- `"@decocms/apps/vtex/inline-loaders/productListingPage"`,
67
+ `"@decocms/apps-vtex/inline-loaders/productListingPage"`,
68
68
  ],
69
69
  [
70
70
  /^"apps\/vtex\/loaders\/intelligentSearch\/productDetailsPage(?:\.ts)?"$/,
71
- `"@decocms/apps/vtex/inline-loaders/productDetailsPage"`,
71
+ `"@decocms/apps-vtex/inline-loaders/productDetailsPage"`,
72
72
  ],
73
73
  [
74
74
  /^"apps\/vtex\/loaders\/intelligentSearch\/suggestions(?:\.ts)?"$/,
75
- `"@decocms/apps/vtex/inline-loaders/suggestions"`,
75
+ `"@decocms/apps-vtex/inline-loaders/suggestions"`,
76
76
  ],
77
77
  // Legacy product loaders are consolidated into a single file (named exports).
78
78
  [
79
79
  /^"apps\/vtex\/loaders\/legacy\/(?:productList|productListingPage|productDetailsPage|search|category)(?:\.ts)?"$/,
80
- `"@decocms/apps/vtex/loaders/legacy"`,
80
+ `"@decocms/apps-vtex/loaders/legacy"`,
81
81
  ],
82
82
  // Path-default loaders (sitemap seeds) don't exist in TanStack Start — paths resolve at request time.
83
83
  [/^"apps\/vtex\/loaders\/paths\/(?:[^"]+)(?:\.ts)?"$/, null],
84
- [/^"apps\/vtex\/loaders\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/vtex/loaders/$1"`],
85
- [/^"apps\/vtex\/types(?:\.ts)?"$/, `"@decocms/apps/vtex/types"`],
84
+ [/^"apps\/vtex\/loaders\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-vtex/loaders/$1"`],
85
+ [/^"apps\/vtex\/types(?:\.ts)?"$/, `"@decocms/apps-vtex/types"`],
86
86
  [/^"apps\/vtex\/mod(?:\.ts)?"$/, `"~/types/vtex-app"`],
87
87
  // Apps — Shopify (hooks, utils, actions, loaders)
88
- [/^"apps\/shopify\/hooks\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/shopify/hooks/$1"`],
89
- [/^"apps\/shopify\/utils\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/shopify/utils/$1"`],
90
- [/^"apps\/shopify\/actions\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/shopify/actions/$1"`],
91
- [/^"apps\/shopify\/loaders\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/shopify/loaders/$1"`],
88
+ [/^"apps\/shopify\/hooks\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-shopify/hooks/$1"`],
89
+ [/^"apps\/shopify\/utils\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-shopify/utils/$1"`],
90
+ [/^"apps\/shopify\/actions\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-shopify/actions/$1"`],
91
+ [/^"apps\/shopify\/loaders\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-shopify/loaders/$1"`],
92
92
  // Apps — commerce (types, SDK, utils)
93
- [/^"apps\/commerce\/sdk\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/commerce/sdk/$1"`],
94
- [/^"apps\/commerce\/utils\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps/commerce/utils/$1"`],
93
+ [/^"apps\/commerce\/sdk\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-commerce/sdk/$1"`],
94
+ [/^"apps\/commerce\/utils\/([^"]+?)(?:\.ts)?"$/, `"@decocms/apps-commerce/utils/$1"`],
95
95
 
96
96
  // Apps — shared utils (STALE, fetchSafe, createHttpClient, etc.)
97
97
  [/^"apps\/utils\/fetch(?:\.ts)?"$/, `"~/lib/fetch-utils"`],
@@ -116,7 +116,7 @@ const IMPORT_RULES: Array<[RegExp, string | null]> = [
116
116
  [/^"@std\/crypto"$/, null], // Use globalThis.crypto instead
117
117
 
118
118
  // site/sdk/* → framework equivalents (before the catch-all site/ → ~/ rule)
119
- [/^"site\/sdk\/clx(?:\.tsx?)?.*"$/, `"@decocms/start/sdk/clx"`],
119
+ [/^"site\/sdk\/clx(?:\.tsx?)?.*"$/, `"@decocms/blocks/sdk/clx"`],
120
120
  [/^"site\/sdk\/useId(?:\.tsx?)?.*"$/, `"react"`],
121
121
  // useOffer and useVariantPossiblities kept as site files (~/sdk/)
122
122
  [/^"site\/sdk\/usePlatform(?:\.tsx?)?.*"$/, null],
@@ -127,10 +127,10 @@ const IMPORT_RULES: Array<[RegExp, string | null]> = [
127
127
  [/^"~\/account\.json"$/, `"~/constants/account"`],
128
128
 
129
129
  // $store/ → ~/ (common Deno import map alias for project root)
130
- [/^"\$store\/sdk\/clx(?:\.tsx?)?.*"$/, `"@decocms/start/sdk/clx"`],
130
+ [/^"\$store\/sdk\/clx(?:\.tsx?)?.*"$/, `"@decocms/blocks/sdk/clx"`],
131
131
  [/^"\$store\/sdk\/useId(?:\.tsx?)?.*"$/, `"react"`],
132
132
  // useOffer and useVariantPossiblities kept as site files (~/sdk/)
133
- [/^"\$store\/sdk\/format(?:\.tsx?)?.*"$/, `"@decocms/apps/commerce/sdk/formatPrice"`],
133
+ [/^"\$store\/sdk\/format(?:\.tsx?)?.*"$/, `"@decocms/apps-commerce/sdk/formatPrice"`],
134
134
  [/^"\$store\/sdk\/usePlatform(?:\.tsx?)?.*"$/, null],
135
135
  // islands → components (must be before $store catch-all)
136
136
  [/^"\$store\/islands\/ui\/([^"]+?)(?:\.tsx?)?"$/, `"~/components/ui/$1"`],
@@ -141,10 +141,10 @@ const IMPORT_RULES: Array<[RegExp, string | null]> = [
141
141
  [/^"\$home\/(.+)"$/, `"~/$1"`],
142
142
 
143
143
  // site/ → ~/
144
- [/^"site\/sdk\/clx(?:\.tsx?)?.*"$/, `"@decocms/start/sdk/clx"`],
144
+ [/^"site\/sdk\/clx(?:\.tsx?)?.*"$/, `"@decocms/blocks/sdk/clx"`],
145
145
  [/^"site\/sdk\/useId(?:\.tsx?)?.*"$/, `"react"`],
146
146
  // useOffer and useVariantPossiblities kept as site files (~/sdk/)
147
- [/^"site\/sdk\/format(?:\.tsx?)?.*"$/, `"@decocms/apps/commerce/sdk/formatPrice"`],
147
+ [/^"site\/sdk\/format(?:\.tsx?)?.*"$/, `"@decocms/apps-commerce/sdk/formatPrice"`],
148
148
  [/^"site\/sdk\/usePlatform(?:\.tsx?)?.*"$/, null],
149
149
  // islands → components (must be before site/ catch-all)
150
150
  [/^"site\/islands\/ui\/([^"]+?)(?:\.tsx?)?"$/, `"~/components/ui/$1"`],
@@ -155,10 +155,16 @@ const IMPORT_RULES: Array<[RegExp, string | null]> = [
155
155
  [/^"~\/islands\/ui\/([^"]+?)(?:\.tsx?)?"$/, `"~/components/ui/$1"`],
156
156
  [/^"~\/islands\/([^"]+?)(?:\.tsx?)?"$/, `"~/components/$1"`],
157
157
 
158
- // @decocms/apps hooks → local hooks (react-query hooks crash Workers SSR at module eval)
158
+ // @decocms/apps-vtex hooks → local hooks (react-query hooks crash Workers SSR at module eval)
159
+ // Pre-7.x monolith path — kept for sites whose Deno import map already
160
+ // aliased directly to the npm specifier instead of the "apps/vtex/..." form.
159
161
  [/^"@decocms\/apps\/vtex\/hooks\/useUser"$/, `"~/hooks/useUser"`],
160
162
  [/^"@decocms\/apps\/vtex\/hooks\/useCart"$/, `"~/hooks/useCart"`],
161
163
  [/^"@decocms\/apps\/vtex\/hooks\/useWishlist"$/, `"~/hooks/useWishlist"`],
164
+ // Post-7.x split package path — same rationale, current package name.
165
+ [/^"@decocms\/apps-vtex\/hooks\/useUser"$/, `"~/hooks/useUser"`],
166
+ [/^"@decocms\/apps-vtex\/hooks\/useCart"$/, `"~/hooks/useCart"`],
167
+ [/^"@decocms\/apps-vtex\/hooks\/useWishlist"$/, `"~/hooks/useWishlist"`],
162
168
  ];
163
169
 
164
170
  /**
@@ -167,14 +173,14 @@ const IMPORT_RULES: Array<[RegExp, string | null]> = [
167
173
  * The key is the ending of the import path, the value is the replacement specifier.
168
174
  */
169
175
  const RELATIVE_SDK_REWRITES: Array<[RegExp, string]> = [
170
- // sdk/clx → @decocms/start/sdk/clx (framework utility)
171
- [/(?:\.\.\/)*sdk\/clx(?:\.tsx?)?$/, "@decocms/start/sdk/clx"],
176
+ // sdk/clx → @decocms/blocks/sdk/clx (framework utility)
177
+ [/(?:\.\.\/)*sdk\/clx(?:\.tsx?)?$/, "@decocms/blocks/sdk/clx"],
172
178
  // sdk/useId → react (useId is built-in in React 19)
173
179
  [/(?:\.\.\/)*sdk\/useId(?:\.tsx?)?$/, "react"],
174
180
  // sdk/useOffer — kept as-is (sites customize offer logic)
175
181
  // sdk/useVariantPossiblities — kept as-is (sites customize variant logic)
176
- // sdk/format → @decocms/apps/commerce/sdk/formatPrice
177
- [/(?:\.\.\/)*sdk\/format(?:\.tsx?)?$/, "@decocms/apps/commerce/sdk/formatPrice"],
182
+ // sdk/format → @decocms/apps-commerce/sdk/formatPrice
183
+ [/(?:\.\.\/)*sdk\/format(?:\.tsx?)?$/, "@decocms/apps-commerce/sdk/formatPrice"],
178
184
  // sdk/usePlatform → remove entirely
179
185
  [/(?:\.\.\/)*sdk\/usePlatform(?:\.tsx?)?$/, ""],
180
186
  // static/adminIcons → deleted (icon loaders need rewriting)
@@ -234,16 +240,16 @@ export function transformImports(
234
240
  /**
235
241
  * Post-process: split @deco/deco/hooks imports.
236
242
  * In the old stack, @deco/deco/hooks exported useDevice, useScript, useSection, etc.
237
- * In @decocms/start, useDevice is at @decocms/start/sdk/useDevice.
243
+ * In @decocms/blocks, useDevice is at @decocms/blocks/sdk/useDevice.
238
244
  * After import rewriting, we need to split lines like:
239
- * import { useDevice, useScript } from "@decocms/start/sdk/useScript"
245
+ * import { useDevice, useScript } from "@decocms/blocks/sdk/useScript"
240
246
  * into:
241
- * import { useDevice } from "@decocms/start/sdk/useDevice"
242
- * import { useScript } from "@decocms/start/sdk/useScript"
247
+ * import { useDevice } from "@decocms/blocks/sdk/useDevice"
248
+ * import { useScript } from "@decocms/blocks/sdk/useScript"
243
249
  */
244
250
  function splitDecoHooksImports(code: string): string {
245
251
  return code.replace(
246
- /^(import\s+(?:type\s+)?\{)([^}]*\buseDevice\b[^}]*)(\}\s+from\s+["']@decocms\/start\/sdk\/useScript["'];?)$/gm,
252
+ /^(import\s+(?:type\s+)?\{)([^}]*\buseDevice\b[^}]*)(\}\s+from\s+["']@decocms\/blocks\/sdk\/useScript["'];?)$/gm,
247
253
  (_match, _prefix, importList, _suffix) => {
248
254
  const items = importList.split(",").map((s: string) => s.trim()).filter(Boolean);
249
255
  const deviceItems = items.filter((s: string) => s.includes("useDevice"));
@@ -251,10 +257,10 @@ export function transformImports(
251
257
 
252
258
  const lines: string[] = [];
253
259
  if (deviceItems.length > 0) {
254
- lines.push(`import { ${deviceItems.join(", ")} } from "@decocms/start/sdk/useDevice";`);
260
+ lines.push(`import { ${deviceItems.join(", ")} } from "@decocms/blocks/sdk/useDevice";`);
255
261
  }
256
262
  if (otherItems.length > 0) {
257
- lines.push(`import { ${otherItems.join(", ")} } from "@decocms/start/sdk/useScript";`);
263
+ lines.push(`import { ${otherItems.join(", ")} } from "@decocms/blocks/sdk/useScript";`);
258
264
  }
259
265
  return lines.join("\n");
260
266
  },
@@ -356,7 +362,7 @@ export function transformImports(
356
362
  if (afterSplit !== result) {
357
363
  result = afterSplit;
358
364
  changed = true;
359
- notes.push("Split useDevice into separate import from @decocms/start/sdk/useDevice");
365
+ notes.push("Split useDevice into separate import from @decocms/blocks/sdk/useDevice");
360
366
  }
361
367
 
362
368
  // Rewrite dynamic imports: route through rewriteSpecifier so sdk-specific
@@ -8,7 +8,7 @@ import type { SectionMeta, TransformResult } from "../types";
8
8
  * Adds section convention exports (sync, eager, layout, cache)
9
9
  * to section files based on metadata extracted during analysis.
10
10
  *
11
- * These exports are read by generate-sections.ts in @decocms/start
11
+ * These exports are read by generate-sections.ts in @decocms/blocks-cli
12
12
  * to build the sections.gen.ts registry.
13
13
  *
14
14
  * The set of section *names* that get hints applied is configurable
@@ -122,7 +122,7 @@ export interface LoaderInfo {
122
122
  hasCache: boolean;
123
123
  /** Has export const cacheKey */
124
124
  hasCacheKey: boolean;
125
- /** Maps to a known @decocms/apps equivalent */
125
+ /** Maps to a known @decocms/apps-* equivalent */
126
126
  appsEquivalent: string | null;
127
127
  /** Is a custom loader that needs dynamic import in commerce-loaders */
128
128
  isCustom: boolean;
@@ -8,8 +8,8 @@
8
8
  * but turns it into something CI can actually run.
9
9
  *
10
10
  * Usage (from a migrated site directory):
11
- * npx -p @decocms/start deco-post-cleanup
12
- * npx -p @decocms/start deco-post-cleanup --json
11
+ * npx -p @decocms/blocks-cli deco-post-cleanup
12
+ * npx -p @decocms/blocks-cli deco-post-cleanup --json
13
13
  *
14
14
  * Options:
15
15
  * --source <dir> Site directory to audit (default: current directory)
@@ -65,13 +65,13 @@ function parseArgs(args: string[]): CliOpts {
65
65
 
66
66
  function showHelp() {
67
67
  console.log(`
68
- @decocms/start — Post-Migration Cleanup Audit
68
+ @decocms/blocks-cli — Post-Migration Cleanup Audit
69
69
 
70
70
  Scans a migrated site for dead code and obsolete boilerplate that the
71
71
  framework now owns. Read-only — prints findings, does not modify files.
72
72
 
73
73
  Usage:
74
- npx -p @decocms/start deco-post-cleanup [options]
74
+ npx -p @decocms/blocks-cli deco-post-cleanup [options]
75
75
 
76
76
  Options:
77
77
  --source <dir> Site directory to audit (default: .)
@@ -88,10 +88,10 @@ function showHelp() {
88
88
  --help, -h Show this help
89
89
 
90
90
  Examples:
91
- npx -p @decocms/start deco-post-cleanup
92
- npx -p @decocms/start deco-post-cleanup --source ./my-site --json
93
- npx -p @decocms/start deco-post-cleanup --fix
94
- npx -p @decocms/start deco-post-cleanup --fix --strict # fail CI if anything left
91
+ npx -p @decocms/blocks-cli deco-post-cleanup
92
+ npx -p @decocms/blocks-cli deco-post-cleanup --source ./my-site --json
93
+ npx -p @decocms/blocks-cli deco-post-cleanup --fix
94
+ npx -p @decocms/blocks-cli deco-post-cleanup --fix --strict # fail CI if anything left
95
95
 
96
96
  See: .agents/skills/deco-to-tanstack-migration/references/post-migration-cleanup.md
97
97
  `);