@decocms/blocks-cli 7.37.0 → 7.37.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/blocks-cli",
3
- "version": "7.37.0",
3
+ "version": "7.37.2",
4
4
  "type": "module",
5
5
  "description": "Deco codegen (generate-blocks, generate-schema, generate-invoke) and Fresh-to-TanStack migration tooling",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  "lint:unused": "knip"
32
32
  },
33
33
  "dependencies": {
34
- "@decocms/blocks": "7.37.0",
34
+ "@decocms/blocks": "7.37.2",
35
35
  "ts-morph": "^27.0.0",
36
36
  "tsx": "^4.22.5"
37
37
  },
@@ -429,8 +429,7 @@ async function main() {
429
429
  console.log(`\n ${bold("Next steps:")}`);
430
430
  console.log(` cd ${outputDir}`);
431
431
  console.log(` npm install`);
432
- console.log(` npm run generate:blocks`);
433
- console.log(` npm run generate:schema`);
432
+ console.log(` npm run generate`);
434
433
  console.log(` npx tsr generate`);
435
434
  console.log(` npm run dev`);
436
435
  }
@@ -1,7 +1,5 @@
1
1
  import * as cp from "node:child_process";
2
- import * as fs from "node:fs";
3
2
  import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
4
- import * as os from "node:os";
5
3
  import { tmpdir } from "node:os";
6
4
  import path from "node:path";
7
5
  import { afterEach, beforeEach, describe, expect, it } from "vitest";
@@ -105,66 +103,3 @@ describe("readBlockDelta", () => {
105
103
  expect(delta).toEqual({});
106
104
  });
107
105
  });
108
-
109
- describe("generate-blocks legacy artifact sync", () => {
110
- let tmpDir: string;
111
-
112
- beforeEach(() => {
113
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "generate-blocks-legacy-"));
114
- // Minimal .deco/blocks/ dir with one block so output is non-empty.
115
- fs.mkdirSync(path.join(tmpDir, ".deco", "blocks"), { recursive: true });
116
- fs.writeFileSync(
117
- path.join(tmpDir, ".deco", "blocks", "pages-Home.json"),
118
- JSON.stringify({ path: "/" }),
119
- );
120
- });
121
-
122
- afterEach(() => {
123
- fs.rmSync(tmpDir, { recursive: true, force: true });
124
- });
125
-
126
- it("syncs .ts and .json to the old path when legacy file is detected", () => {
127
- const oldDir = path.join(tmpDir, "src", "server", "cms");
128
- fs.mkdirSync(oldDir, { recursive: true });
129
- fs.writeFileSync(path.join(oldDir, "blocks.gen.ts"), "// stale\n");
130
-
131
- const { code, stderr } = runGenerator([], { cwd: tmpDir });
132
- expect(code).toBe(0);
133
-
134
- expect(stderr).toContain("src/server/cms/blocks.gen.ts");
135
- expect(stderr).toContain(".deco/blocks.gen.ts");
136
- expect(stderr).toContain("Update importers to use the new path");
137
-
138
- // New path must exist.
139
- expect(fs.existsSync(path.join(tmpDir, ".deco", "blocks.gen.ts"))).toBe(true);
140
- expect(fs.existsSync(path.join(tmpDir, ".deco", "blocks.gen.json"))).toBe(true);
141
-
142
- // Old .ts must be synced (stub content, not the stale placeholder).
143
- const oldTs = fs.readFileSync(path.join(oldDir, "blocks.gen.ts"), "utf-8");
144
- expect(oldTs).not.toBe("// stale\n");
145
-
146
- // Old .json sibling must be synced — the Vite plugin reads it by suffix.
147
- const oldJson = path.join(oldDir, "blocks.gen.json");
148
- expect(fs.existsSync(oldJson)).toBe(true);
149
- const oldContent = JSON.parse(fs.readFileSync(oldJson, "utf-8"));
150
- const newContent = JSON.parse(
151
- fs.readFileSync(path.join(tmpDir, ".deco", "blocks.gen.json"), "utf-8"),
152
- );
153
- expect(oldContent).toEqual(newContent);
154
- }, 30_000);
155
-
156
- it("does not warn and does not sync when an explicit --out-file is passed", () => {
157
- const oldDir = path.join(tmpDir, "src", "server", "cms");
158
- fs.mkdirSync(oldDir, { recursive: true });
159
- fs.writeFileSync(path.join(oldDir, "blocks.gen.ts"), "// stale\n");
160
-
161
- const explicitOut = path.join(tmpDir, "custom", "blocks.gen.ts");
162
- const { code, stderr } = runGenerator(["--out-file", explicitOut], { cwd: tmpDir });
163
- expect(code).toBe(0);
164
-
165
- expect(stderr).not.toContain("Generator default output moved");
166
- expect(fs.existsSync(explicitOut)).toBe(true);
167
- // Old file must be untouched.
168
- expect(fs.readFileSync(path.join(oldDir, "blocks.gen.ts"), "utf-8")).toBe("// stale\n");
169
- }, 30_000);
170
- });
@@ -27,10 +27,6 @@
27
27
  * --out-file by swapping its extension, so passing --out-file
28
28
  * moves both artifacts together)
29
29
  *
30
- * If no `--out-file` is passed and the OLD default (src/server/cms/blocks.gen.ts)
31
- * still exists on disk, a one-line legacy warning is printed to stderr and the
32
- * NEW default is written anyway — see lib/legacyArtifact.ts.
33
- *
34
30
  * Programmatic:
35
31
  * import { generateBlocks } from "@decocms/blocks-cli/generate-blocks";
36
32
  * await generateBlocks({ blocksDir, outFile });
@@ -49,7 +45,6 @@ import {
49
45
  singleDecodeBlockName,
50
46
  } from "./lib/blocks-dedupe";
51
47
  import { buildCsvRedirectBlocks } from "./lib/csv-redirects";
52
- import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
53
48
 
54
49
  const TS_STUB = [
55
50
  "// Auto-generated — thin wrapper around blocks.gen.json.",
@@ -321,24 +316,10 @@ if (isMainModule()) {
321
316
  };
322
317
 
323
318
  const blocksDir = path.resolve(process.cwd(), arg("blocks-dir", ".deco/blocks"));
324
- const OUT_FILE_EXPLICIT = args.includes("--out-file");
325
319
  const NEW_DEFAULT_OUT_FILE = ".deco/blocks.gen.ts";
326
- const OLD_DEFAULT_OUT_FILE = "src/server/cms/blocks.gen.ts";
327
320
  const outFile = path.resolve(process.cwd(), arg("out-file", NEW_DEFAULT_OUT_FILE));
328
- const oldFilePath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_FILE);
329
- const hasLegacy = !OUT_FILE_EXPLICIT && fs.existsSync(oldFilePath);
330
- if (hasLegacy) {
331
- warnLegacyArtifact(OLD_DEFAULT_OUT_FILE, NEW_DEFAULT_OUT_FILE);
332
- }
333
321
 
334
- generateBlocks({ blocksDir, outFile }).then((result) => {
335
- if (hasLegacy) {
336
- syncLegacyArtifact(oldFilePath, result.outFile);
337
- // The .ts is a Vite stub — the plugin reads the .json sibling by suffix.
338
- // Sync the JSON too so the Vite interceptor at the old path finds it.
339
- syncLegacyArtifact(oldFilePath.replace(/\.ts$/, ".json"), result.jsonFile);
340
- }
341
- }).catch((err) => {
322
+ generateBlocks({ blocksDir, outFile }).catch((err) => {
342
323
  console.error(err);
343
324
  process.exit(1);
344
325
  });
@@ -62,58 +62,3 @@ describe("generate-loaders — loader vs action emit", () => {
62
62
  expect(out).not.toContain('createLoaderEntry("site/actions/addToCart"');
63
63
  });
64
64
  });
65
-
66
- describe("generate-loaders legacy artifact sync", () => {
67
- let tmpDir: string;
68
-
69
- beforeEach(() => {
70
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "generate-loaders-legacy-"));
71
- const write = (rel: string, content: string) => {
72
- const abs = path.join(tmpDir, rel);
73
- fs.mkdirSync(path.dirname(abs), { recursive: true });
74
- fs.writeFileSync(abs, content);
75
- };
76
- write("src/loaders/related.ts", "export default async () => [];\n");
77
- });
78
-
79
- afterEach(() => {
80
- fs.rmSync(tmpDir, { recursive: true, force: true });
81
- });
82
-
83
- it("syncs to the old path when legacy file is detected", () => {
84
- const oldDir = path.join(tmpDir, "src", "server", "cms");
85
- fs.mkdirSync(oldDir, { recursive: true });
86
- fs.writeFileSync(path.join(oldDir, "loaders.gen.ts"), "// stale\n");
87
-
88
- const { code, stderr } = run(tmpDir);
89
- expect(code).toBe(0);
90
-
91
- expect(stderr).toContain("src/server/cms/loaders.gen.ts");
92
- expect(stderr).toContain(".deco/loaders.gen.ts");
93
- expect(stderr).toContain("Update importers to use the new path");
94
-
95
- // New path must exist.
96
- expect(fs.existsSync(path.join(tmpDir, ".deco", "loaders.gen.ts"))).toBe(true);
97
-
98
- // Old file must be synced as a re-export shim (not the stale placeholder,
99
- // and not a verbatim copy — a byte copy would carry `.deco/`-relative
100
- // import paths that break at the deeper legacy location).
101
- const oldContent = fs.readFileSync(path.join(oldDir, "loaders.gen.ts"), "utf-8");
102
- expect(oldContent).not.toBe("// stale\n");
103
- expect(oldContent).toContain('export * from "../../../.deco/loaders.gen"');
104
- }, 30_000);
105
-
106
- it("does not warn and does not sync when an explicit --out-file is passed", () => {
107
- const oldDir = path.join(tmpDir, "src", "server", "cms");
108
- fs.mkdirSync(oldDir, { recursive: true });
109
- fs.writeFileSync(path.join(oldDir, "loaders.gen.ts"), "// stale\n");
110
-
111
- const explicitOut = path.join(tmpDir, "custom", "loaders.gen.ts");
112
- const { code, stderr } = run(tmpDir, ["--out-file", explicitOut]);
113
- expect(code).toBe(0);
114
-
115
- expect(stderr).not.toContain("Generator default output moved");
116
- expect(fs.existsSync(explicitOut)).toBe(true);
117
- expect(fs.readFileSync(path.join(oldDir, "loaders.gen.ts"), "utf-8")).toBe("// stale\n");
118
- }, 30_000);
119
- });
@@ -43,14 +43,9 @@
43
43
  * --exclude comma-separated list of loader keys to skip (they have custom wiring)
44
44
  * --prune-by-decofile only emit entries whose key appears as `__resolveType` in any JSON
45
45
  * --decofile-dir @deprecated alias for --prune-by-decofile
46
- *
47
- * If no `--out-file` is passed and the OLD default (src/server/cms/loaders.gen.ts)
48
- * still exists on disk, a one-line legacy warning is printed to stderr and the
49
- * NEW default is written anyway — see lib/legacyArtifact.ts.
50
46
  */
51
47
  import fs from "node:fs";
52
48
  import path from "node:path";
53
- import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
54
49
 
55
50
  const args = process.argv.slice(2);
56
51
  function arg(name: string, fallback: string): string {
@@ -60,15 +55,8 @@ function arg(name: string, fallback: string): string {
60
55
 
61
56
  const loadersDir = path.resolve(process.cwd(), arg("loaders-dir", "src/loaders"));
62
57
  const actionsDir = path.resolve(process.cwd(), arg("actions-dir", "src/actions"));
63
- const OUT_FILE_EXPLICIT = args.includes("--out-file");
64
58
  const NEW_DEFAULT_OUT_FILE = ".deco/loaders.gen.ts";
65
- const OLD_DEFAULT_OUT_FILE = "src/server/cms/loaders.gen.ts";
66
59
  const outFile = path.resolve(process.cwd(), arg("out-file", NEW_DEFAULT_OUT_FILE));
67
- const oldLoadersPath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_FILE);
68
- const hasLegacy = !OUT_FILE_EXPLICIT && fs.existsSync(oldLoadersPath);
69
- if (hasLegacy) {
70
- warnLegacyArtifact(OLD_DEFAULT_OUT_FILE, NEW_DEFAULT_OUT_FILE);
71
- }
72
60
  const excludeRaw = arg("exclude", "");
73
61
  const excludeSet = new Set(excludeRaw.split(",").map((s) => s.trim()).filter(Boolean));
74
62
 
@@ -256,7 +244,6 @@ lines.push("");
256
244
 
257
245
  fs.mkdirSync(path.dirname(outFile), { recursive: true });
258
246
  fs.writeFileSync(outFile, lines.join("\n"));
259
- if (hasLegacy) syncLegacyArtifact(oldLoadersPath, outFile);
260
247
 
261
248
  const filterNote = cmsReferences
262
249
  ? ` (filtered against ${cmsReferences.size} CMS __resolveType references; pruned ${prunedCount} dead entries)`
@@ -252,10 +252,10 @@ describe("typeToJsonSchema loader block-ref matching", () => {
252
252
  });
253
253
 
254
254
  // ---------------------------------------------------------------------------
255
- // Default output path (.deco/) + legacy warning — subprocess, mirrors the
256
- // pattern in generate-sections.test.ts. generate-schema.ts IS guarded by
257
- // isMainModule(), but it's still driven as a subprocess here so the CLI's
258
- // argv-parsed OUT_REL/legacy-check top-level code runs against a real cwd.
255
+ // Default output path (.deco/) — subprocess, mirrors the pattern in
256
+ // generate-sections.test.ts. generate-schema.ts IS guarded by isMainModule(),
257
+ // but it's still driven as a subprocess here so the CLI's argv-parsed OUT_REL
258
+ // top-level code runs against a real cwd.
259
259
  // ---------------------------------------------------------------------------
260
260
 
261
261
  const SCRIPT = path.resolve(__dirname, "generate-schema.ts");
@@ -313,39 +313,9 @@ describe("generate-schema default output path (.deco/)", () => {
313
313
  expect(meta.manifest.blocks.sections).toHaveProperty("site/sections/Hero.tsx");
314
314
  }, 30_000);
315
315
 
316
- it("warns once to stderr naming both paths when the OLD default file exists and no --out is passed, but still writes the NEW default", () => {
317
- const oldDefaultDir = path.join(tmpDir, "src", "server", "admin");
318
- fs.mkdirSync(oldDefaultDir, { recursive: true });
319
- fs.writeFileSync(path.join(oldDefaultDir, "meta.gen.json"), "{}");
320
-
316
+ it("does not warn about a legacy default path", () => {
321
317
  const { code, stderr } = runGenerator(["--skip-apps"], { cwd: tmpDir });
322
318
  expect(code).toBe(0);
323
-
324
- expect(stderr).toContain("src/server/admin/meta.gen.json");
325
- expect(stderr).toContain(".deco/meta.gen.json");
326
- expect(stderr).toContain("Update importers to use the new path");
327
-
328
- const newDefault = path.join(tmpDir, ".deco", "meta.gen.json");
329
- expect(fs.existsSync(newDefault)).toBe(true);
330
-
331
- // Old file must be kept in sync so mid-migration imports still work.
332
- const oldDefault = path.join(tmpDir, "src", "server", "admin", "meta.gen.json");
333
- expect(fs.existsSync(oldDefault)).toBe(true);
334
- const oldContent = JSON.parse(fs.readFileSync(oldDefault, "utf-8"));
335
- const newContent = JSON.parse(fs.readFileSync(newDefault, "utf-8"));
336
- expect(oldContent).toEqual(newContent);
337
- }, 30_000);
338
-
339
- it("does not warn when an explicit --out is passed, even if the OLD default file exists", () => {
340
- const oldDefaultDir = path.join(tmpDir, "src", "server", "admin");
341
- fs.mkdirSync(oldDefaultDir, { recursive: true });
342
- fs.writeFileSync(path.join(oldDefaultDir, "meta.gen.json"), "{}");
343
-
344
- const explicitOut = path.join(tmpDir, "custom", "meta.gen.json");
345
- const { code, stderr } = runGenerator(["--skip-apps", "--out", explicitOut], { cwd: tmpDir });
346
- expect(code).toBe(0);
347
-
348
319
  expect(stderr).not.toContain("Generator default output moved");
349
- expect(fs.existsSync(explicitOut)).toBe(true);
350
320
  }, 30_000);
351
321
  });
@@ -33,10 +33,6 @@ import { fileURLToPath } from "node:url";
33
33
  * from disk with no runtime (FS-based Studio / Eitri stack).
34
34
  * --framework With --compose, the value written to the `framework` field
35
35
  * (default: "tanstack-start").
36
- *
37
- * If no `--out` is passed and the OLD default (src/server/admin/meta.gen.json)
38
- * still exists on disk, a one-line legacy warning is printed to stderr and the
39
- * NEW default is written anyway — see lib/legacyArtifact.ts.
40
36
  */
41
37
  import {
42
38
  type Symbol as MorphSymbol,
@@ -47,7 +43,6 @@ import {
47
43
  type Type,
48
44
  } from "ts-morph";
49
45
  import { isExcludedCodegenFile } from "./lib/codegenExclusions";
50
- import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
51
46
 
52
47
  // ---------------------------------------------------------------------------
53
48
  // CLI arg parsing
@@ -56,12 +51,9 @@ import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
56
51
  // here) so that importing this module for its pure exports
57
52
  // (definitionIdForPath, applyWidgetFormat, typeToJsonSchema — see
58
53
  // generate-schema.test.ts) never reads argv or touches the filesystem.
59
- // Without the guard, every import used to run an `fs.existsSync` check
60
- // against the *importing process's* cwd and could print a legacy-artifact
61
- // warning to stderr as an import-time side effect, unrelated to whatever
62
- // the test actually wanted to exercise. generateMeta() (below) and the
63
- // final write are themselves only reached inside `if (isMainModule())`, so
64
- // these vars only need real values in that same case.
54
+ // generateMeta() (below) and the final write are themselves only reached
55
+ // inside `if (isMainModule())`, so these vars only need real values in that
56
+ // same case.
65
57
  // ---------------------------------------------------------------------------
66
58
  const argv = process.argv.slice(2);
67
59
  function arg(name: string, fallback: string): string {
@@ -70,7 +62,6 @@ function arg(name: string, fallback: string): string {
70
62
  }
71
63
 
72
64
  const NEW_DEFAULT_OUT_REL = ".deco/meta.gen.json";
73
- const OLD_DEFAULT_OUT_REL = "src/server/admin/meta.gen.json";
74
65
 
75
66
  let SITE_NAMESPACE = "site";
76
67
  let SITE_NAME = "storefront";
@@ -90,8 +81,6 @@ let COMPOSE = false;
90
81
  // Value written to the composed meta's `framework` field (only used with
91
82
  // --compose). Defaults to composeMeta's historical "tanstack-start".
92
83
  let FRAMEWORK = "tanstack-start";
93
- let _hasLegacySchema = false;
94
- let _oldSchemaPath = "";
95
84
 
96
85
  if (isMainModule()) {
97
86
  SITE_NAMESPACE = arg("namespace", SITE_NAMESPACE);
@@ -101,16 +90,10 @@ if (isMainModule()) {
101
90
  LOADERS_REL = arg("loaders", LOADERS_REL);
102
91
  APPS_REL = arg("apps", APPS_REL);
103
92
  SKIP_APPS = argv.includes("--skip-apps");
104
- const outFileExplicit = argv.includes("--out");
105
93
  OUT_REL = arg("out", NEW_DEFAULT_OUT_REL);
106
94
  PLATFORM = arg("platform", PLATFORM);
107
95
  COMPOSE = argv.includes("--compose");
108
96
  FRAMEWORK = arg("framework", FRAMEWORK);
109
- _oldSchemaPath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_REL);
110
- _hasLegacySchema = !outFileExplicit && fs.existsSync(_oldSchemaPath);
111
- if (_hasLegacySchema) {
112
- warnLegacyArtifact(OLD_DEFAULT_OUT_REL, NEW_DEFAULT_OUT_REL);
113
- }
114
97
  }
115
98
 
116
99
  // ---------------------------------------------------------------------------
@@ -1541,7 +1524,6 @@ if (isMainModule()) {
1541
1524
  const outPath = path.resolve(process.cwd(), OUT_REL);
1542
1525
  fs.mkdirSync(path.dirname(outPath), { recursive: true });
1543
1526
  fs.writeFileSync(outPath, JSON.stringify(meta, null, 2));
1544
- if (_hasLegacySchema) syncLegacyArtifact(_oldSchemaPath, outPath);
1545
1527
 
1546
1528
  const defCount = Object.keys(meta.schema.definitions).length;
1547
1529
  const secCount = Object.keys(meta.manifest.blocks.sections || {}).length;
@@ -115,48 +115,9 @@ describe("generate-sections default output path (.deco/)", () => {
115
115
  const newDefault = path.join(tmpDir, ".deco", "sections.gen.ts");
116
116
  expect(fs.existsSync(newDefault)).toBe(true);
117
117
  expect(fs.readFileSync(newDefault, "utf-8")).toContain("site/sections/Hero.tsx");
118
- // No legacy file present, so no warning is expected.
118
+ // No legacy default path is written anymore, so no warning is expected.
119
119
  expect(stderr).not.toContain("Generator default output moved");
120
120
  }, 30_000);
121
-
122
- it("warns once to stderr naming both paths when the OLD default file exists and no --out-file is passed, but still writes the NEW default", () => {
123
- const oldDefaultDir = path.join(tmpDir, "src", "server", "cms");
124
- fs.mkdirSync(oldDefaultDir, { recursive: true });
125
- fs.writeFileSync(path.join(oldDefaultDir, "sections.gen.ts"), "// stale\n");
126
-
127
- const { code, stderr } = runGenerator([], { cwd: tmpDir });
128
- expect(code).toBe(0);
129
-
130
- expect(stderr).toContain("src/server/cms/sections.gen.ts");
131
- expect(stderr).toContain(".deco/sections.gen.ts");
132
- expect(stderr).toContain("Update importers to use the new path");
133
-
134
- const newDefault = path.join(tmpDir, ".deco", "sections.gen.ts");
135
- expect(fs.existsSync(newDefault)).toBe(true);
136
- expect(fs.readFileSync(newDefault, "utf-8")).toContain("site/sections/Hero.tsx");
137
-
138
- // Old file is kept in sync as a re-export shim (NOT a verbatim copy — a
139
- // byte copy would carry `.deco/`-relative import paths that break at the
140
- // deeper legacy location). It re-exports the new file so mid-migration
141
- // imports still resolve at any depth.
142
- const oldDefault = path.join(tmpDir, "src", "server", "cms", "sections.gen.ts");
143
- const oldContent = fs.readFileSync(oldDefault, "utf-8");
144
- expect(oldContent).toContain('export * from "../../../.deco/sections.gen"');
145
- expect(oldContent).not.toContain("site/sections/Hero.tsx");
146
- }, 30_000);
147
-
148
- it("does not warn when an explicit --out-file is passed, even if the OLD default file exists", () => {
149
- const oldDefaultDir = path.join(tmpDir, "src", "server", "cms");
150
- fs.mkdirSync(oldDefaultDir, { recursive: true });
151
- fs.writeFileSync(path.join(oldDefaultDir, "sections.gen.ts"), "// stale\n");
152
-
153
- const explicitOut = path.join(tmpDir, "custom", "sections.gen.ts");
154
- const { code, stderr } = runGenerator(["--out-file", explicitOut], { cwd: tmpDir });
155
- expect(code).toBe(0);
156
-
157
- expect(stderr).not.toContain("Generator default output moved");
158
- expect(fs.existsSync(explicitOut)).toBe(true);
159
- }, 30_000);
160
121
  });
161
122
 
162
123
  describe("generate-sections --registry", () => {
@@ -28,15 +28,10 @@
28
28
  * Built from every scanned section file, not just the ones
29
29
  * carrying convention exports. Off by default so existing
30
30
  * Vite sites regenerating sections.gen.ts in CI see zero diff.
31
- *
32
- * If no `--out-file` is passed and the OLD default (src/server/cms/sections.gen.ts)
33
- * still exists on disk, a one-line legacy warning is printed to stderr and the
34
- * NEW default is written anyway — see lib/legacyArtifact.ts.
35
31
  */
36
32
  import fs from "node:fs";
37
33
  import path from "node:path";
38
34
  import { isExcludedCodegenFile } from "./lib/codegenExclusions";
39
- import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
40
35
 
41
36
  const args = process.argv.slice(2);
42
37
  function arg(name: string, fallback: string): string {
@@ -45,15 +40,8 @@ function arg(name: string, fallback: string): string {
45
40
  }
46
41
 
47
42
  const sectionsDir = path.resolve(process.cwd(), arg("sections-dir", "src/sections"));
48
- const OUT_FILE_EXPLICIT = args.includes("--out-file");
49
43
  const NEW_DEFAULT_OUT_FILE = ".deco/sections.gen.ts";
50
- const OLD_DEFAULT_OUT_FILE = "src/server/cms/sections.gen.ts";
51
44
  const outFile = path.resolve(process.cwd(), arg("out-file", NEW_DEFAULT_OUT_FILE));
52
- const oldSectionsPath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_FILE);
53
- const hasLegacy = !OUT_FILE_EXPLICIT && fs.existsSync(oldSectionsPath);
54
- if (hasLegacy) {
55
- warnLegacyArtifact(OLD_DEFAULT_OUT_FILE, NEW_DEFAULT_OUT_FILE);
56
- }
57
45
  const EMIT_REGISTRY = args.includes("--registry");
58
46
 
59
47
  interface SectionMeta {
@@ -295,7 +283,6 @@ fs.writeFileSync(
295
283
  outFile,
296
284
  lines.join("\n").replace(/\n{3,}/g, "\n\n").replace(/\n*$/, "\n"),
297
285
  );
298
- if (hasLegacy) syncLegacyArtifact(oldSectionsPath, outFile);
299
286
 
300
287
  console.log(
301
288
  `Generated section metadata for ${entries.length} sections → ${path.relative(process.cwd(), outFile)}`,
@@ -199,7 +199,7 @@ export function report(ctx: MigrationContext): void {
199
199
  lines.push("- [ ] `src/hooks/useCart.ts` — wire to actual server functions for your platform");
200
200
  lines.push("- [ ] `src/worker-entry.ts` — verify CSP, proxy, and segment builder");
201
201
  lines.push("- [ ] See the **CSS Migration** section above for DaisyUI v4→v5 / Tailwind v3→v4 findings specific to this site");
202
- lines.push("- [ ] Run `npm run generate:blocks` and `npm run generate:schema` after migration");
202
+ lines.push("- [ ] Run `npm run generate` (unified: blocks, sections, loaders, schema) after migration");
203
203
  lines.push("");
204
204
 
205
205
  // Known Issues
@@ -250,9 +250,8 @@ export function report(ctx: MigrationContext): void {
250
250
  lines.push("# 1. Install dependencies (bun is the canonical PM)");
251
251
  lines.push("bun install");
252
252
  lines.push("");
253
- lines.push("# 2. Generate CMS blocks and schema");
254
- lines.push("bun run generate:blocks");
255
- lines.push("bun run generate:schema");
253
+ lines.push("# 2. Generate CMS artifacts (blocks, sections, loaders, schema)");
254
+ lines.push("bun run generate");
256
255
  lines.push("");
257
256
  lines.push("# 3. Generate routes");
258
257
  lines.push("bunx tsr generate");
@@ -20,7 +20,6 @@ const REQUIRED_FILES = [
20
20
  // Deploy / preview / sync-secrets pipelines are owned by Cloudflare
21
21
  // Workers Builds (D6.3) -- configured in the CF dashboard, not via
22
22
  // GitHub workflow files in the site repo.
23
- ".github/workflows/regen-blocks.yml",
24
23
  ".github/workflows/lockfile-check.yml",
25
24
  "knip.config.ts",
26
25
  ".prettierrc",
@@ -1,64 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
-
4
- /**
5
- * Generator default output paths flipped from `src/server/{cms,admin}/` to
6
- * `.deco/` (framework artifacts live in the framework's folder, not mixed
7
- * into app source). Sites that never pass an explicit `--out`/`--out-file`
8
- * flag pick up the new default silently — except when the OLD default file
9
- * is still sitting on disk, which almost always means something (an
10
- * importer, a `.gitignore` entry, a stale CI cache check) still points at
11
- * it. In that case we warn once, to stderr, and then write to the NEW
12
- * default anyway: the artifact is regenerated code, so there's no reason to
13
- * block the run — the warning is just a nudge to go clean up the stale file
14
- * and its importers.
15
- *
16
- * An explicit flag means the caller made a deliberate choice about where
17
- * output goes; it gets no warning and no guard.
18
- */
19
- export function warnLegacyArtifact(oldPath: string, newPath: string): void {
20
- console.warn(
21
- `[deco] Generator default output moved: ${oldPath} -> ${newPath}. Update importers to use the new path, then delete the old file.`,
22
- );
23
- }
24
-
25
- /**
26
- * Keeps the legacy `oldPath` in sync with the freshly-generated `newPath` so
27
- * sites mid-migration whose imports still point at the old location keep
28
- * working without a full migration first. Call this after generation
29
- * completes, only when the old file was detected.
30
- *
31
- * For `.ts`/`.tsx` artifacts a verbatim copy would be broken: the generated
32
- * file's import specifiers are relative to `newPath`'s directory (`.deco/`,
33
- * one level deep), but `oldPath` lives deeper (`src/server/cms/`), so every
34
- * `../src/...` specifier would resolve to a nonexistent path and crash the
35
- * dev server on boot. Instead we write a re-export shim pointing at `newPath`
36
- * — one specifier, correct at any depth, and self-documenting the deprecation.
37
- * The generated `.gen.ts` files only have named exports, so `export *` forwards
38
- * everything (including type exports). Non-TS artifacts (e.g. `.json` schema)
39
- * have no import paths, so a byte copy is still correct.
40
- */
41
- export function syncLegacyArtifact(oldPath: string, newPath: string): void {
42
- fs.mkdirSync(path.dirname(oldPath), { recursive: true });
43
-
44
- if (!/\.tsx?$/.test(oldPath)) {
45
- fs.copyFileSync(newPath, oldPath);
46
- return;
47
- }
48
-
49
- const newRel = path.relative(process.cwd(), newPath).replace(/\\/g, "/");
50
- let specifier = path
51
- .relative(path.dirname(oldPath), newPath)
52
- .replace(/\\/g, "/")
53
- .replace(/\.tsx?$/, "");
54
- if (!specifier.startsWith(".")) specifier = `./${specifier}`;
55
-
56
- fs.writeFileSync(
57
- oldPath,
58
- `// AUTO-GENERATED — DO NOT EDIT.\n` +
59
- `// Deprecated path: the generator now writes to "${newRel}".\n` +
60
- `// This file only re-exports it so mid-migration imports keep working.\n` +
61
- `// Update your imports to the new path, then delete this file.\n` +
62
- `export * from "${specifier}";\n`,
63
- );
64
- }