@decocms/blocks-cli 7.5.1 → 7.5.3

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 (43) hide show
  1. package/package.json +2 -2
  2. package/scripts/generate-invoke.ts +10 -0
  3. package/scripts/generate-schema.ts +46 -15
  4. package/scripts/generate-sections.test.ts +67 -0
  5. package/scripts/generate-sections.ts +16 -2
  6. package/scripts/lib/codegenExclusions.test.ts +16 -6
  7. package/scripts/lib/codegenExclusions.ts +13 -1
  8. package/scripts/migrate/analyzers/loader-inventory.ts +1 -1
  9. package/scripts/migrate/phase-analyze.ts +3 -3
  10. package/scripts/migrate/phase-cleanup.test.ts +70 -1
  11. package/scripts/migrate/phase-cleanup.ts +47 -26
  12. package/scripts/migrate/phase-report.ts +7 -7
  13. package/scripts/migrate/phase-scaffold.ts +4 -4
  14. package/scripts/migrate/phase-transform.ts +1 -1
  15. package/scripts/migrate/phase-verify.ts +6 -5
  16. package/scripts/migrate/post-cleanup/rules.ts +55 -44
  17. package/scripts/migrate/post-cleanup/runner.test.ts +58 -34
  18. package/scripts/migrate/templates/cache-config.ts +4 -4
  19. package/scripts/migrate/templates/commerce-loaders.ts +10 -10
  20. package/scripts/migrate/templates/cursor-rules.test.ts +6 -0
  21. package/scripts/migrate/templates/cursor-rules.ts +12 -11
  22. package/scripts/migrate/templates/hooks.test.ts +7 -7
  23. package/scripts/migrate/templates/hooks.ts +10 -10
  24. package/scripts/migrate/templates/lib-utils.test.ts +2 -2
  25. package/scripts/migrate/templates/lib-utils.ts +4 -4
  26. package/scripts/migrate/templates/no-legacy-packages.test.ts +147 -0
  27. package/scripts/migrate/templates/package-json.ts +30 -10
  28. package/scripts/migrate/templates/routes.ts +8 -10
  29. package/scripts/migrate/templates/sdk-gen.ts +1 -1
  30. package/scripts/migrate/templates/section-loaders.ts +7 -7
  31. package/scripts/migrate/templates/server-entry.ts +37 -37
  32. package/scripts/migrate/templates/setup.ts +6 -6
  33. package/scripts/migrate/templates/types-gen.ts +2 -2
  34. package/scripts/migrate/templates/ui-components.ts +2 -2
  35. package/scripts/migrate/templates/vite-config.ts +12 -3
  36. package/scripts/migrate/transforms/fresh-apis.ts +5 -5
  37. package/scripts/migrate/transforms/imports.test.ts +138 -0
  38. package/scripts/migrate/transforms/imports.ts +65 -43
  39. package/scripts/migrate/transforms/jsx.ts +8 -0
  40. package/scripts/migrate/transforms/section-conventions.ts +1 -1
  41. package/scripts/migrate/types.ts +1 -1
  42. package/scripts/migrate-post-cleanup.ts +8 -8
  43. package/scripts/migrate.ts +11 -11
@@ -155,7 +155,7 @@ export function transform(ctx: MigrationContext): void {
155
155
  // This file uses Deno-specific APIs (toFileUrl, import.meta.resolve)
156
156
  // and the HTMX-driven `useComponent(component, props)` pattern, which
157
157
  // do not run on Cloudflare Workers and have no equivalent in
158
- // @decocms/start. The whole file must be deleted.
158
+ // @decocms/blocks. The whole file must be deleted.
159
159
  if (
160
160
  /sections\/Component\.tsx?$/.test(record.path) ||
161
161
  /sections\/Component\.tsx?$/.test(targetPath)
@@ -35,7 +35,7 @@ const REQUIRED_FILES = [
35
35
  "src/hooks/useUser.ts",
36
36
  "src/hooks/useWishlist.ts",
37
37
  // src/types/widgets.ts intentionally omitted — provided by the
38
- // framework at `@decocms/start/types/widgets`; sites no longer
38
+ // framework at `@decocms/blocks/types/widgets`; sites no longer
39
39
  // shadow the file locally.
40
40
  "src/types/deco.ts",
41
41
  "src/types/commerce-app.ts",
@@ -173,8 +173,9 @@ export const checks: Check[] = [
173
173
  const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
174
174
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
175
175
  const required = [
176
- "@decocms/start",
177
- "@decocms/apps",
176
+ "@decocms/blocks",
177
+ "@decocms/tanstack",
178
+ "@decocms/apps-commerce",
178
179
  "react",
179
180
  "react-dom",
180
181
  "@tanstack/react-start",
@@ -382,7 +383,7 @@ export const checks: Check[] = [
382
383
  },
383
384
  },
384
385
  {
385
- name: "No apps/ imports in src/ (should be @decocms/apps or ~/)",
386
+ name: "No apps/ imports in src/ (should be @decocms/apps-* or ~/)",
386
387
  severity: "error",
387
388
  fn: (ctx) => {
388
389
  const srcDir = path.join(ctx.sourceDir, "src");
@@ -457,7 +458,7 @@ export const checks: Check[] = [
457
458
  severity: "warning",
458
459
  fn: (ctx) => {
459
460
  const typeFiles = [
460
- // widgets.ts is provided by @decocms/start/types/widgets, not
461
+ // widgets.ts is provided by @decocms/blocks/types/widgets, not
461
462
  // scaffolded locally.
462
463
  "src/types/deco.ts",
463
464
  "src/types/commerce-app.ts",
@@ -467,23 +467,30 @@ function findAttachedLeadingComments(content: string, openIdx: number): number {
467
467
  *
468
468
  * 1. Legacy inline proxy (pre-Wave 15-A migration template) — defines
469
469
  * `createNestedInvokeProxy` plus `invoke` and `Runtime` constants.
470
- * The whole 40-50 LOC body duplicates `@decocms/start/sdk`'s `invoke`.
470
+ * The whole 40-50 LOC body duplicates `@decocms/blocks/sdk/invoke`'s
471
+ * `invoke`.
471
472
  *
472
473
  * 2. Simple re-export shim — the file only re-exports `invoke` /
473
474
  * `createNestedInvokeProxy` (no inline proxy body, but also not yet
474
- * pointing at `@decocms/start/sdk`).
475
+ * pointing at `@decocms/blocks/sdk/invoke`).
475
476
  *
476
- * Both should be replaced with `import { invoke } from "@decocms/start/sdk"`
477
- * at every callsite, and the file deleted. The Wave 15-A migration template
477
+ * Both should be replaced with `import { invoke } from "@decocms/blocks/sdk/invoke"`
478
+ * at every callsite, and the file deleted. The current migration template
478
479
  * scaffolds a thin re-export form that's also acceptable (re-exports
479
- * `invoke` from `@decocms/start/sdk` and rebuilds `Runtime = { invoke }`);
480
- * we explicitly skip it via the "imports invoke from @decocms/start/sdk
480
+ * `invoke` from `@decocms/blocks/sdk/invoke` and rebuilds `Runtime = { invoke }`);
481
+ * we explicitly skip it via the "imports invoke from @decocms/blocks/sdk
481
482
  * AND no inline proxy" check below.
483
+ *
484
+ * Sites migrated before the 7.x package split may still import from the
485
+ * retired `@decocms/start/sdk` — that package no longer exists for 7.x
486
+ * consumers, so this is intentionally NOT treated as "already fixed"; it
487
+ * falls through to the flag-and-rewrite path below like any other stale
488
+ * shim.
482
489
  */
483
490
  const INLINE_PROXY_RE =
484
491
  /(?:function|const)\s+createNestedInvokeProxy\b|new\s+Proxy\s*\(\s*Object\.assign\s*\(\s*async\s*\(\s*props/;
485
492
  const FRAMEWORK_INVOKE_IMPORT_RE =
486
- /import\s+\{[^}]*\binvoke\b[^}]*\}\s+from\s+['"]@decocms\/start(?:\/sdk)?['"]/;
493
+ /import\s+\{[^}]*\binvoke\b[^}]*\}\s+from\s+['"]@decocms\/blocks\/sdk(?:\/invoke)?['"]/;
487
494
 
488
495
  const ALLOWED_RUNTIME_EXPORTS = new Set(["invoke", "createNestedInvokeProxy", "Runtime"]);
489
496
 
@@ -501,7 +508,7 @@ const ruleDeadRuntimeShim: Rule = {
501
508
  const onlyKnownInvokeExports =
502
509
  exports.length > 0 && exports.every((e) => ALLOWED_RUNTIME_EXPORTS.has(e));
503
510
 
504
- // Wave 15-A canonical template: re-exports invoke from @decocms/start/sdk
511
+ // Current canonical template: re-exports invoke from @decocms/blocks/sdk/invoke
505
512
  // and exposes `Runtime = { invoke }` for legacy callers. No inline proxy
506
513
  // body. This is the desired shape — skip.
507
514
  if (reExportsFromFramework && !hasInlineProxy) return [];
@@ -523,11 +530,11 @@ const ruleDeadRuntimeShim: Rule = {
523
530
  severity: "info",
524
531
  file: "src/runtime.ts",
525
532
  message: safeToAutoFix
526
- ? `${flavor} [${exportSummary}] — replace with @decocms/start/sdk`
533
+ ? `${flavor} [${exportSummary}] — replace with @decocms/blocks/sdk/invoke`
527
534
  : `${flavor} [${exportSummary}] — manual review: file mixes the runtime proxy with site-specific exports`,
528
535
  fix: safeToAutoFix
529
- ? 'rg -l "from \\"~/runtime\\"" src/ | xargs sed -i \'\' \'s|from "~/runtime"|from "@decocms/start/sdk"|g\' && rm src/runtime.ts'
530
- : "Move the inline `createNestedInvokeProxy` body to call @decocms/start/sdk's `invoke`; relocate site-specific helpers to a dedicated module before deleting src/runtime.ts",
536
+ ? 'rg -l "from \\"~/runtime\\"" src/ | xargs sed -i \'\' \'s|from "~/runtime"|from "@decocms/blocks/sdk/invoke"|g\' && rm src/runtime.ts'
537
+ : "Move the inline `createNestedInvokeProxy` body to call @decocms/blocks/sdk/invoke's `invoke`; relocate site-specific helpers to a dedicated module before deleting src/runtime.ts",
531
538
  meta: {
532
539
  hasInlineProxy,
533
540
  exports,
@@ -542,13 +549,13 @@ const ruleDeadRuntimeShim: Rule = {
542
549
  // a runtime.ts that mixes the proxy with site-specific helpers.
543
550
  const safe = findings.every((f) => f.meta?.safeToAutoFix !== false);
544
551
  if (!safe) return [];
545
- const updated = rewriteImportSpec(ctx, writer, "~/runtime", "@decocms/start/sdk");
552
+ const updated = rewriteImportSpec(ctx, writer, "~/runtime", "@decocms/blocks/sdk/invoke");
546
553
  writer.deleteFile(`${ctx.siteDir}/src/runtime.ts`);
547
554
  return [
548
555
  {
549
556
  file: "src/runtime.ts",
550
557
  kind: "rewrite-imports+delete",
551
- detail: `rewrote ${updated.length} import(s) → @decocms/start/sdk and deleted src/runtime.ts`,
558
+ detail: `rewrote ${updated.length} import(s) → @decocms/blocks/sdk/invoke and deleted src/runtime.ts`,
552
559
  },
553
560
  ];
554
561
  },
@@ -573,7 +580,7 @@ const ruleSiteLocalGlobals: Rule = {
573
580
  /(?:export\s+)?(?:function|const)\s+(?:withSiteGlobals|cmsRouteWithGlobals)\b/.test(
574
581
  content,
575
582
  );
576
- const reExportsFromFramework = /from\s+['"]@decocms\/start\/routes['"]/.test(content);
583
+ const reExportsFromFramework = /from\s+['"]@decocms\/tanstack['"]/.test(content);
577
584
  if (!definesWrapper || reExportsFromFramework) continue;
578
585
  const rel = abs.slice(siteDir.length + 1);
579
586
  const lineCount = content.split("\n").length;
@@ -581,8 +588,8 @@ const ruleSiteLocalGlobals: Rule = {
581
588
  rule: "site-local-with-globals",
582
589
  severity: "warning",
583
590
  file: rel,
584
- message: `Local wrapper (~${lineCount} LOC) — framework now exports withSiteGlobals from @decocms/start/routes`,
585
- fix: "delete the local wrapper and import { withSiteGlobals } from '@decocms/start/routes'",
591
+ message: `Local wrapper (~${lineCount} LOC) — framework now exports withSiteGlobals from @decocms/tanstack`,
592
+ fix: "delete the local wrapper and import { withSiteGlobals } from '@decocms/tanstack'",
586
593
  meta: { lineCount },
587
594
  });
588
595
  }
@@ -623,7 +630,7 @@ export const STUB_FIX_HINTS: Record<string, FixHint> = {
623
630
  // src/lib/vtex-transform
624
631
  toProduct: {
625
632
  kind: "swap",
626
- canonical: "@decocms/apps/vtex/utils/transform",
633
+ canonical: "@decocms/apps-vtex/utils/transform",
627
634
  note:
628
635
  "canonical signature is `toProduct(product, sku, level, options)`; " +
629
636
  "1-arg call sites need to expand args first — see skill § 5",
@@ -633,12 +640,12 @@ export const STUB_FIX_HINTS: Record<string, FixHint> = {
633
640
  kind: "refactor",
634
641
  note:
635
642
  "read cookies via `request.headers.get('cookie')` then call " +
636
- "`buildSegmentFromCookies()` from '@decocms/apps/vtex/utils/segment'. " +
643
+ "`buildSegmentFromCookies()` from '@decocms/apps-vtex/utils/segment'. " +
637
644
  "The bag-based lookup mechanism does not exist on TanStack Start.",
638
645
  },
639
646
  withSegmentCookie: {
640
647
  kind: "swap",
641
- canonical: "@decocms/apps/vtex/utils/segment",
648
+ canonical: "@decocms/apps-vtex/utils/segment",
642
649
  note:
643
650
  "canonical signature is `withSegmentCookie(segment, headers?)`; " +
644
651
  "if you currently pass only headers, also pass a segment object",
@@ -686,12 +693,12 @@ export function buildVtexShimFixMessage(stubsBySim: Map<string, string[]>): stri
686
693
  const parts: string[] = [...known];
687
694
  if (unknown.length > 0) {
688
695
  parts.push(
689
- `${unknown.join(", ")} → repoint to '@decocms/apps/vtex/...' or 'apps/commerce/utils/...'`,
696
+ `${unknown.join(", ")} → repoint to '@decocms/apps-vtex/...' or 'apps/commerce/utils/...'`,
690
697
  );
691
698
  }
692
699
  return parts.length > 0
693
700
  ? parts.join(" | ")
694
- : "Repoint imports to '@decocms/apps/vtex/...' or 'apps/commerce/utils/...'";
701
+ : "Repoint imports to '@decocms/apps-vtex/...' or 'apps/commerce/utils/...'";
695
702
  }
696
703
 
697
704
  /**
@@ -885,8 +892,8 @@ const ruleLocalWidgetsTypes: Rule = {
885
892
  rule: "local-widgets-types",
886
893
  severity: "info",
887
894
  file: "src/types/widgets.ts",
888
- message: `Local file shadows @decocms/start/types/widgets (used in ${importCount} place(s))`,
889
- fix: 'rewrite imports to "@decocms/start/types/widgets" and rm src/types/widgets.ts',
895
+ message: `Local file shadows @decocms/blocks/types/widgets (used in ${importCount} place(s))`,
896
+ fix: 'rewrite imports to "@decocms/blocks/types/widgets" and rm src/types/widgets.ts',
890
897
  meta: { importCount },
891
898
  },
892
899
  ];
@@ -897,14 +904,14 @@ const ruleLocalWidgetsTypes: Rule = {
897
904
  ctx,
898
905
  writer,
899
906
  "~/types/widgets",
900
- "@decocms/start/types/widgets",
907
+ "@decocms/blocks/types/widgets",
901
908
  );
902
909
  writer.deleteFile(`${ctx.siteDir}/src/types/widgets.ts`);
903
910
  return [
904
911
  {
905
912
  file: "src/types/widgets.ts",
906
913
  kind: "rewrite-imports+delete",
907
- detail: `rewrote ${updated.length} import(s) → @decocms/start/types/widgets and deleted src/types/widgets.ts`,
914
+ detail: `rewrote ${updated.length} import(s) → @decocms/blocks/types/widgets and deleted src/types/widgets.ts`,
908
915
  },
909
916
  ];
910
917
  },
@@ -949,7 +956,7 @@ const ruleFrameworkTodos: Rule = {
949
956
 
950
957
  /**
951
958
  * Registry of files we expect sites to NOT carry locally because the
952
- * canonical implementation already lives in `@decocms/start` (or a
959
+ * canonical implementation already lives in `@decocms/blocks` (or a
953
960
  * sibling apps package).
954
961
  *
955
962
  * Two flavours:
@@ -1000,7 +1007,7 @@ interface FrameworkDuplicate {
1000
1007
  /**
1001
1008
  * Add an entry here when:
1002
1009
  * - 1+ migrated sites carry their own copy of code that already
1003
- * exists in `@decocms/start` (or a sibling apps package), AND
1010
+ * exists in `@decocms/blocks` (or a sibling apps package), AND
1004
1011
  * - the canonical version is at least feature-equivalent.
1005
1012
  *
1006
1013
  * Per D4 in the migration tooling policy, the framework promotion
@@ -1011,18 +1018,18 @@ export const FRAMEWORK_DUPLICATES: FrameworkDuplicate[] = [
1011
1018
  {
1012
1019
  id: "clx",
1013
1020
  sitePath: "src/sdk/clx.ts",
1014
- canonicalImport: "@decocms/start/sdk/clx",
1021
+ canonicalImport: "@decocms/blocks/sdk/clx",
1015
1022
  contentSignature: [
1016
1023
  /export\s+const\s+clx\s*=/,
1017
1024
  /args\.filter\(Boolean\)\.join/,
1018
1025
  ],
1019
1026
  safeToAutoFix: true,
1020
- description: "src/sdk/clx.ts duplicates @decocms/start/sdk/clx",
1027
+ description: "src/sdk/clx.ts duplicates @decocms/blocks/sdk/clx",
1021
1028
  },
1022
1029
  {
1023
1030
  id: "use-send-event",
1024
1031
  sitePath: "src/sdk/useSendEvent.ts",
1025
- canonicalImport: "@decocms/start/sdk/analytics",
1032
+ canonicalImport: "@decocms/blocks/sdk/analytics",
1026
1033
  contentSignature: [
1027
1034
  /export\s+(?:const|function)\s+useSendEvent/,
1028
1035
  /data-event/,
@@ -1034,12 +1041,12 @@ export const FRAMEWORK_DUPLICATES: FrameworkDuplicate[] = [
1034
1041
  "Replacing 1:1 weakens type-safety. Either widen the framework export (preferred), or " +
1035
1042
  "rewrite call sites to drop the generic. Manual review required.",
1036
1043
  description:
1037
- "src/sdk/useSendEvent.ts overlaps with @decocms/start/sdk/analytics → useSendEvent",
1044
+ "src/sdk/useSendEvent.ts overlaps with @decocms/blocks/sdk/analytics → useSendEvent",
1038
1045
  },
1039
1046
  {
1040
1047
  id: "location-matcher",
1041
1048
  sitePath: "src/matchers/location.ts",
1042
- canonicalImport: "@decocms/start/matchers/builtins",
1049
+ canonicalImport: "@decocms/blocks/matchers/builtins",
1043
1050
  contentSignature: [
1044
1051
  /registerMatcher\(\s*['"]website\/matchers\/location\.ts['"]/,
1045
1052
  /__cf_geo/,
@@ -1051,12 +1058,12 @@ export const FRAMEWORK_DUPLICATES: FrameworkDuplicate[] = [
1051
1058
  "verify country-name lookup parity (resolveCountryCode vs site's inline table) and " +
1052
1059
  "swap setup.ts's customMatchers entry to call registerBuiltinMatchers().",
1053
1060
  description:
1054
- "src/matchers/location.ts overlaps with @decocms/start/matchers/builtins → registerBuiltinMatchers()",
1061
+ "src/matchers/location.ts overlaps with @decocms/blocks/matchers/builtins → registerBuiltinMatchers()",
1055
1062
  },
1056
1063
  {
1057
1064
  id: "url-relative",
1058
1065
  sitePath: "src/sdk/url.ts",
1059
- canonicalImport: "@decocms/apps/commerce/sdk/url",
1066
+ canonicalImport: "@decocms/apps-commerce/sdk/url",
1060
1067
  // Fingerprint: site fork carries a positional `removeIdSku?: boolean`
1061
1068
  // flag + hardcoded VTEX-specific keys (`idsku`, `skuId`). Canonical
1062
1069
  // apps export uses an options object — `{ stripSearchParams: string[] }`
@@ -1068,7 +1075,7 @@ export const FRAMEWORK_DUPLICATES: FrameworkDuplicate[] = [
1068
1075
  ],
1069
1076
  safeToAutoFix: false,
1070
1077
  reason:
1071
- "rewrite imports to '@decocms/apps/commerce/sdk/url'. " +
1078
+ "rewrite imports to '@decocms/apps-commerce/sdk/url'. " +
1072
1079
  "Each call site using the boolean form `relative(url, true)` becomes " +
1073
1080
  "`relative(url, { stripSearchParams: [\"idsku\", \"skuId\"] })`. " +
1074
1081
  "1-arg calls are unchanged. Then delete src/sdk/url.ts. " +
@@ -1076,12 +1083,12 @@ export const FRAMEWORK_DUPLICATES: FrameworkDuplicate[] = [
1076
1083
  "transformation (positional bool → options object), not pure import " +
1077
1084
  "rewrite.",
1078
1085
  description:
1079
- "src/sdk/url.ts overlaps with @decocms/apps/commerce/sdk/url → relative() (extended in @decocms/apps@1.9+)",
1086
+ "src/sdk/url.ts overlaps with @decocms/apps-commerce/sdk/url → relative()",
1080
1087
  },
1081
1088
  {
1082
1089
  id: "use-suggestions",
1083
1090
  sitePath: "src/sdk/useSuggestions.ts",
1084
- canonicalImport: "@decocms/start/sdk/useSuggestions",
1091
+ canonicalImport: "@decocms/blocks/sdk/useSuggestions",
1085
1092
  // Fingerprint: hand-rolled hook with the module-level signal +
1086
1093
  // serial-queue + latestQuery cancel pattern. Both casaevideo and
1087
1094
  // baggagio independently invented this exact shape. Sites that
@@ -1102,7 +1109,7 @@ export const FRAMEWORK_DUPLICATES: FrameworkDuplicate[] = [
1102
1109
  "the per-site type parameter and onError wiring need site-specific " +
1103
1110
  "decisions. See references/platform-hooks-factories.md § useSuggestions.",
1104
1111
  description:
1105
- "src/sdk/useSuggestions.ts duplicates @decocms/start/sdk/useSuggestions → createUseSuggestions() (added in @decocms/start@2.25+)",
1112
+ "src/sdk/useSuggestions.ts duplicates @decocms/blocks/sdk/useSuggestions → createUseSuggestions()",
1106
1113
  },
1107
1114
  ];
1108
1115
 
@@ -1175,7 +1182,7 @@ function stripExt(path: string): string {
1175
1182
 
1176
1183
  /**
1177
1184
  * Per D2 in the migration tooling policy, every `hx-*` attribute is
1178
- * rewritten on migration; nothing in `@decocms/start` ships an htmx
1185
+ * rewritten on migration; nothing in `@decocms/blocks` ships an htmx
1179
1186
  * runtime. This rule is the verification gate: a migrated site is
1180
1187
  * "rewrite-complete" when there are zero `hx-*` attributes left in
1181
1188
  * `src/`.
@@ -1427,7 +1434,7 @@ function satisfiesRange(version: string, range: string): boolean | null {
1427
1434
  * package name. Bun's lockfile format embeds the version inside the
1428
1435
  * package descriptor array, e.g.:
1429
1436
  *
1430
- * "@decocms/start": ["@decocms/start@2.1.1", ...]
1437
+ * "@decocms/blocks": ["@decocms/blocks@7.5.1", ...]
1431
1438
  *
1432
1439
  * We scan all such occurrences (a single package may appear multiple
1433
1440
  * times if the dep tree pulled different versions).
@@ -1583,7 +1590,7 @@ const rulePackageManagerMissing: Rule = {
1583
1590
  /* ------------------------------------------------------------------ */
1584
1591
 
1585
1592
  /**
1586
- * Every VTEX storefront on @decocms/start needs a reverse proxy for
1593
+ * Every VTEX storefront on @decocms/tanstack needs a reverse proxy for
1587
1594
  * `/checkout/*`, `/account/*`, `/api/*`, `/files/*`, etc. — those paths
1588
1595
  * must hit the VTEX origin (not TanStack Start) so the user lands on
1589
1596
  * the real checkout UI carrying their VTEX session cookies.
@@ -1614,11 +1621,14 @@ const ruleVtexProxyHandlerMissing: Rule = {
1614
1621
  title: "VTEX worker-entry missing the checkout/API proxy handler",
1615
1622
  run({ siteDir, fs }: RuleContext): Finding[] {
1616
1623
  // Only run when the site is actually VTEX. The cheapest signal is
1617
- // any import from `@decocms/apps/vtex/...` in src/ — every VTEX
1624
+ // any import from `@decocms/apps-vtex/...` in src/ — every VTEX
1618
1625
  // site has at least one (commerceLoaders, hooks, types, etc.).
1626
+ // Also matches the pre-7.x `@decocms/apps/vtex/...` monolith path,
1627
+ // since sites migrated before the package split still carry it.
1628
+ const VTEX_IMPORT_RE = /@decocms\/apps-vtex|@decocms\/apps\/vtex/;
1619
1629
  const srcFiles = fs.glob(siteDir, "src/**/*.{ts,tsx}", SRC_GLOB_EXCLUDES);
1620
1630
  const isVtex = srcFiles.some((abs) =>
1621
- fs.readText(abs).includes("@decocms/apps/vtex"),
1631
+ VTEX_IMPORT_RE.test(fs.readText(abs)),
1622
1632
  );
1623
1633
  if (!isVtex) return [];
1624
1634
 
@@ -1642,6 +1652,7 @@ const ruleVtexProxyHandlerMissing: Rule = {
1642
1652
  // either is a strong signal the proxy block exists; absence of
1643
1653
  // both means it was dropped.
1644
1654
  const hasProxyImport =
1655
+ /from\s+["']@decocms\/apps-vtex\/utils\/proxy["']/.test(content) ||
1645
1656
  /from\s+["']@decocms\/apps\/vtex\/utils\/proxy["']/.test(content);
1646
1657
  // Match both long form (`proxyHandler: async (...) => ...`) and
1647
1658
  // object-shorthand wiring (`{ proxyHandler }`, `{ proxyHandler, admin }`).
@@ -1659,7 +1670,7 @@ const ruleVtexProxyHandlerMissing: Rule = {
1659
1670
  file: "src/worker-entry.ts",
1660
1671
  message: hasProxyImport
1661
1672
  ? "imports proxy helpers but no `proxyHandler:` is wired into createDecoWorkerEntry — /checkout requests will fall through to TanStack and render the SPA shell"
1662
- : "no `@decocms/apps/vtex/utils/proxy` import — VTEX /checkout, /account, /api won't be proxied to the origin",
1673
+ : "no `@decocms/apps-vtex/utils/proxy` import — VTEX /checkout, /account, /api won't be proxied to the origin",
1663
1674
  fix: "Add `proxyHandler` to createDecoWorkerEntry; see scripts/migrate/templates/server-entry.ts (generateVtexWorkerEntry) for the canonical block",
1664
1675
  },
1665
1676
  ];