@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.
- package/package.json +2 -2
- package/scripts/generate-invoke.ts +10 -0
- package/scripts/generate-schema.ts +46 -15
- package/scripts/generate-sections.test.ts +67 -0
- package/scripts/generate-sections.ts +16 -2
- package/scripts/lib/codegenExclusions.test.ts +16 -6
- package/scripts/lib/codegenExclusions.ts +13 -1
- package/scripts/migrate/analyzers/loader-inventory.ts +1 -1
- package/scripts/migrate/phase-analyze.ts +3 -3
- package/scripts/migrate/phase-cleanup.test.ts +70 -1
- package/scripts/migrate/phase-cleanup.ts +47 -26
- package/scripts/migrate/phase-report.ts +7 -7
- package/scripts/migrate/phase-scaffold.ts +4 -4
- package/scripts/migrate/phase-transform.ts +1 -1
- package/scripts/migrate/phase-verify.ts +6 -5
- package/scripts/migrate/post-cleanup/rules.ts +55 -44
- package/scripts/migrate/post-cleanup/runner.test.ts +58 -34
- package/scripts/migrate/templates/cache-config.ts +4 -4
- package/scripts/migrate/templates/commerce-loaders.ts +10 -10
- package/scripts/migrate/templates/cursor-rules.test.ts +6 -0
- package/scripts/migrate/templates/cursor-rules.ts +12 -11
- package/scripts/migrate/templates/hooks.test.ts +7 -7
- package/scripts/migrate/templates/hooks.ts +10 -10
- package/scripts/migrate/templates/lib-utils.test.ts +2 -2
- package/scripts/migrate/templates/lib-utils.ts +4 -4
- package/scripts/migrate/templates/no-legacy-packages.test.ts +147 -0
- package/scripts/migrate/templates/package-json.ts +30 -10
- package/scripts/migrate/templates/routes.ts +8 -10
- package/scripts/migrate/templates/sdk-gen.ts +1 -1
- package/scripts/migrate/templates/section-loaders.ts +7 -7
- package/scripts/migrate/templates/server-entry.ts +37 -37
- package/scripts/migrate/templates/setup.ts +6 -6
- package/scripts/migrate/templates/types-gen.ts +2 -2
- package/scripts/migrate/templates/ui-components.ts +2 -2
- package/scripts/migrate/templates/vite-config.ts +12 -3
- package/scripts/migrate/transforms/fresh-apis.ts +5 -5
- package/scripts/migrate/transforms/imports.test.ts +138 -0
- package/scripts/migrate/transforms/imports.ts +65 -43
- package/scripts/migrate/transforms/jsx.ts +8 -0
- package/scripts/migrate/transforms/section-conventions.ts +1 -1
- package/scripts/migrate/types.ts +1 -1
- package/scripts/migrate-post-cleanup.ts +8 -8
- 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/
|
|
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/
|
|
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/
|
|
177
|
-
"@decocms/
|
|
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/
|
|
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/
|
|
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/
|
|
475
|
+
* pointing at `@decocms/blocks/sdk/invoke`).
|
|
475
476
|
*
|
|
476
|
-
* Both should be replaced with `import { invoke } from "@decocms/
|
|
477
|
-
* at every callsite, and the file deleted. The
|
|
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/
|
|
480
|
-
* we explicitly skip it via the "imports invoke from @decocms/
|
|
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\/
|
|
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
|
-
//
|
|
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/
|
|
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/
|
|
530
|
-
: "Move the inline `createNestedInvokeProxy` body to call @decocms/
|
|
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/
|
|
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/
|
|
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\/
|
|
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/
|
|
585
|
-
fix: "delete the local wrapper and import { withSiteGlobals } from '@decocms/
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
889
|
-
fix: 'rewrite imports to "@decocms/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
|
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)
|
|
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
|
|
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
|
];
|