@decocms/blocks-cli 7.31.7 → 7.32.1
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-blocks.test.ts +76 -0
- package/scripts/generate-blocks.ts +12 -3
- package/scripts/generate-loaders.test.ts +55 -2
- package/scripts/generate-loaders.ts +5 -2
- package/scripts/generate-schema.test.ts +8 -1
- package/scripts/generate-schema.ts +7 -2
- package/scripts/generate-sections.test.ts +5 -1
- package/scripts/generate-sections.ts +5 -2
- package/scripts/lib/legacyArtifact.ts +15 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decocms/blocks-cli",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.32.1",
|
|
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.
|
|
34
|
+
"@decocms/blocks": "7.32.1",
|
|
35
35
|
"ts-morph": "^27.0.0",
|
|
36
36
|
"tsx": "^4.22.5"
|
|
37
37
|
},
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
+
import * as cp from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
1
3
|
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import * as os from "node:os";
|
|
2
5
|
import { tmpdir } from "node:os";
|
|
3
6
|
import path from "node:path";
|
|
4
7
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
8
|
import { readBlockDelta } from "./generate-blocks";
|
|
6
9
|
|
|
10
|
+
const SCRIPT = path.resolve(__dirname, "generate-blocks.ts");
|
|
11
|
+
|
|
12
|
+
function runGenerator(
|
|
13
|
+
args: string[],
|
|
14
|
+
opts: { cwd?: string } = {},
|
|
15
|
+
): { stdout: string; stderr: string; code: number } {
|
|
16
|
+
const r = cp.spawnSync("npx", ["tsx", SCRIPT, ...args], { encoding: "utf8", cwd: opts.cwd });
|
|
17
|
+
return { stdout: r.stdout || "", stderr: r.stderr || "", code: r.status ?? 0 };
|
|
18
|
+
}
|
|
19
|
+
|
|
7
20
|
describe("readBlockDelta", () => {
|
|
8
21
|
let dir: string;
|
|
9
22
|
|
|
@@ -92,3 +105,66 @@ describe("readBlockDelta", () => {
|
|
|
92
105
|
expect(delta).toEqual({});
|
|
93
106
|
});
|
|
94
107
|
});
|
|
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
|
+
});
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
singleDecodeBlockName,
|
|
50
50
|
} from "./lib/blocks-dedupe";
|
|
51
51
|
import { buildCsvRedirectBlocks } from "./lib/csv-redirects";
|
|
52
|
-
import { warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
52
|
+
import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
53
53
|
|
|
54
54
|
const TS_STUB = [
|
|
55
55
|
"// Auto-generated — thin wrapper around blocks.gen.json.",
|
|
@@ -325,11 +325,20 @@ if (isMainModule()) {
|
|
|
325
325
|
const NEW_DEFAULT_OUT_FILE = ".deco/blocks.gen.ts";
|
|
326
326
|
const OLD_DEFAULT_OUT_FILE = "src/server/cms/blocks.gen.ts";
|
|
327
327
|
const outFile = path.resolve(process.cwd(), arg("out-file", NEW_DEFAULT_OUT_FILE));
|
|
328
|
-
|
|
328
|
+
const oldFilePath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_FILE);
|
|
329
|
+
const hasLegacy = !OUT_FILE_EXPLICIT && fs.existsSync(oldFilePath);
|
|
330
|
+
if (hasLegacy) {
|
|
329
331
|
warnLegacyArtifact(OLD_DEFAULT_OUT_FILE, NEW_DEFAULT_OUT_FILE);
|
|
330
332
|
}
|
|
331
333
|
|
|
332
|
-
generateBlocks({ blocksDir, outFile }).
|
|
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) => {
|
|
333
342
|
console.error(err);
|
|
334
343
|
process.exit(1);
|
|
335
344
|
});
|
|
@@ -14,8 +14,8 @@ import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
|
14
14
|
|
|
15
15
|
const SCRIPT = path.resolve(__dirname, "generate-loaders.ts");
|
|
16
16
|
|
|
17
|
-
function run(cwd: string): { stdout: string; stderr: string; code: number } {
|
|
18
|
-
const r = cp.spawnSync("npx", ["tsx", SCRIPT], { encoding: "utf8", cwd });
|
|
17
|
+
function run(cwd: string, args: string[] = []): { stdout: string; stderr: string; code: number } {
|
|
18
|
+
const r = cp.spawnSync("npx", ["tsx", SCRIPT, ...args], { encoding: "utf8", cwd });
|
|
19
19
|
return { stdout: r.stdout || "", stderr: r.stderr || "", code: r.status ?? -1 };
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -62,3 +62,56 @@ 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 (not stale placeholder).
|
|
99
|
+
const oldContent = fs.readFileSync(path.join(oldDir, "loaders.gen.ts"), "utf-8");
|
|
100
|
+
expect(oldContent).not.toBe("// stale\n");
|
|
101
|
+
expect(oldContent).toContain("site/loaders/related");
|
|
102
|
+
}, 30_000);
|
|
103
|
+
|
|
104
|
+
it("does not warn and does not sync when an explicit --out-file is passed", () => {
|
|
105
|
+
const oldDir = path.join(tmpDir, "src", "server", "cms");
|
|
106
|
+
fs.mkdirSync(oldDir, { recursive: true });
|
|
107
|
+
fs.writeFileSync(path.join(oldDir, "loaders.gen.ts"), "// stale\n");
|
|
108
|
+
|
|
109
|
+
const explicitOut = path.join(tmpDir, "custom", "loaders.gen.ts");
|
|
110
|
+
const { code, stderr } = run(tmpDir, ["--out-file", explicitOut]);
|
|
111
|
+
expect(code).toBe(0);
|
|
112
|
+
|
|
113
|
+
expect(stderr).not.toContain("Generator default output moved");
|
|
114
|
+
expect(fs.existsSync(explicitOut)).toBe(true);
|
|
115
|
+
expect(fs.readFileSync(path.join(oldDir, "loaders.gen.ts"), "utf-8")).toBe("// stale\n");
|
|
116
|
+
}, 30_000);
|
|
117
|
+
});
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
*/
|
|
51
51
|
import fs from "node:fs";
|
|
52
52
|
import path from "node:path";
|
|
53
|
-
import { warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
53
|
+
import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
54
54
|
|
|
55
55
|
const args = process.argv.slice(2);
|
|
56
56
|
function arg(name: string, fallback: string): string {
|
|
@@ -64,7 +64,9 @@ const OUT_FILE_EXPLICIT = args.includes("--out-file");
|
|
|
64
64
|
const NEW_DEFAULT_OUT_FILE = ".deco/loaders.gen.ts";
|
|
65
65
|
const OLD_DEFAULT_OUT_FILE = "src/server/cms/loaders.gen.ts";
|
|
66
66
|
const outFile = path.resolve(process.cwd(), arg("out-file", NEW_DEFAULT_OUT_FILE));
|
|
67
|
-
|
|
67
|
+
const oldLoadersPath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_FILE);
|
|
68
|
+
const hasLegacy = !OUT_FILE_EXPLICIT && fs.existsSync(oldLoadersPath);
|
|
69
|
+
if (hasLegacy) {
|
|
68
70
|
warnLegacyArtifact(OLD_DEFAULT_OUT_FILE, NEW_DEFAULT_OUT_FILE);
|
|
69
71
|
}
|
|
70
72
|
const excludeRaw = arg("exclude", "");
|
|
@@ -254,6 +256,7 @@ lines.push("");
|
|
|
254
256
|
|
|
255
257
|
fs.mkdirSync(path.dirname(outFile), { recursive: true });
|
|
256
258
|
fs.writeFileSync(outFile, lines.join("\n"));
|
|
259
|
+
if (hasLegacy) syncLegacyArtifact(oldLoadersPath, outFile);
|
|
257
260
|
|
|
258
261
|
const filterNote = cmsReferences
|
|
259
262
|
? ` (filtered against ${cmsReferences.size} CMS __resolveType references; pruned ${prunedCount} dead entries)`
|
|
@@ -323,10 +323,17 @@ describe("generate-schema default output path (.deco/)", () => {
|
|
|
323
323
|
|
|
324
324
|
expect(stderr).toContain("src/server/admin/meta.gen.json");
|
|
325
325
|
expect(stderr).toContain(".deco/meta.gen.json");
|
|
326
|
-
expect(stderr).toContain("
|
|
326
|
+
expect(stderr).toContain("Update importers to use the new path");
|
|
327
327
|
|
|
328
328
|
const newDefault = path.join(tmpDir, ".deco", "meta.gen.json");
|
|
329
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);
|
|
330
337
|
}, 30_000);
|
|
331
338
|
|
|
332
339
|
it("does not warn when an explicit --out is passed, even if the OLD default file exists", () => {
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
type Type,
|
|
48
48
|
} from "ts-morph";
|
|
49
49
|
import { isExcludedCodegenFile } from "./lib/codegenExclusions";
|
|
50
|
-
import { warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
50
|
+
import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
51
51
|
|
|
52
52
|
// ---------------------------------------------------------------------------
|
|
53
53
|
// CLI arg parsing
|
|
@@ -90,6 +90,8 @@ let COMPOSE = false;
|
|
|
90
90
|
// Value written to the composed meta's `framework` field (only used with
|
|
91
91
|
// --compose). Defaults to composeMeta's historical "tanstack-start".
|
|
92
92
|
let FRAMEWORK = "tanstack-start";
|
|
93
|
+
let _hasLegacySchema = false;
|
|
94
|
+
let _oldSchemaPath = "";
|
|
93
95
|
|
|
94
96
|
if (isMainModule()) {
|
|
95
97
|
SITE_NAMESPACE = arg("namespace", SITE_NAMESPACE);
|
|
@@ -104,7 +106,9 @@ if (isMainModule()) {
|
|
|
104
106
|
PLATFORM = arg("platform", PLATFORM);
|
|
105
107
|
COMPOSE = argv.includes("--compose");
|
|
106
108
|
FRAMEWORK = arg("framework", FRAMEWORK);
|
|
107
|
-
|
|
109
|
+
_oldSchemaPath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_REL);
|
|
110
|
+
_hasLegacySchema = !outFileExplicit && fs.existsSync(_oldSchemaPath);
|
|
111
|
+
if (_hasLegacySchema) {
|
|
108
112
|
warnLegacyArtifact(OLD_DEFAULT_OUT_REL, NEW_DEFAULT_OUT_REL);
|
|
109
113
|
}
|
|
110
114
|
}
|
|
@@ -1537,6 +1541,7 @@ if (isMainModule()) {
|
|
|
1537
1541
|
const outPath = path.resolve(process.cwd(), OUT_REL);
|
|
1538
1542
|
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
1539
1543
|
fs.writeFileSync(outPath, JSON.stringify(meta, null, 2));
|
|
1544
|
+
if (_hasLegacySchema) syncLegacyArtifact(_oldSchemaPath, outPath);
|
|
1540
1545
|
|
|
1541
1546
|
const defCount = Object.keys(meta.schema.definitions).length;
|
|
1542
1547
|
const secCount = Object.keys(meta.manifest.blocks.sections || {}).length;
|
|
@@ -113,11 +113,15 @@ describe("generate-sections default output path (.deco/)", () => {
|
|
|
113
113
|
|
|
114
114
|
expect(stderr).toContain("src/server/cms/sections.gen.ts");
|
|
115
115
|
expect(stderr).toContain(".deco/sections.gen.ts");
|
|
116
|
-
expect(stderr).toContain("
|
|
116
|
+
expect(stderr).toContain("Update importers to use the new path");
|
|
117
117
|
|
|
118
118
|
const newDefault = path.join(tmpDir, ".deco", "sections.gen.ts");
|
|
119
119
|
expect(fs.existsSync(newDefault)).toBe(true);
|
|
120
120
|
expect(fs.readFileSync(newDefault, "utf-8")).toContain("site/sections/Hero.tsx");
|
|
121
|
+
|
|
122
|
+
// Old file must be kept in sync so mid-migration imports still work.
|
|
123
|
+
const oldDefault = path.join(tmpDir, "src", "server", "cms", "sections.gen.ts");
|
|
124
|
+
expect(fs.readFileSync(oldDefault, "utf-8")).toContain("site/sections/Hero.tsx");
|
|
121
125
|
}, 30_000);
|
|
122
126
|
|
|
123
127
|
it("does not warn when an explicit --out-file is passed, even if the OLD default file exists", () => {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
import fs from "node:fs";
|
|
37
37
|
import path from "node:path";
|
|
38
38
|
import { isExcludedCodegenFile } from "./lib/codegenExclusions";
|
|
39
|
-
import { warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
39
|
+
import { syncLegacyArtifact, warnLegacyArtifact } from "./lib/legacyArtifact";
|
|
40
40
|
|
|
41
41
|
const args = process.argv.slice(2);
|
|
42
42
|
function arg(name: string, fallback: string): string {
|
|
@@ -49,7 +49,9 @@ const OUT_FILE_EXPLICIT = args.includes("--out-file");
|
|
|
49
49
|
const NEW_DEFAULT_OUT_FILE = ".deco/sections.gen.ts";
|
|
50
50
|
const OLD_DEFAULT_OUT_FILE = "src/server/cms/sections.gen.ts";
|
|
51
51
|
const outFile = path.resolve(process.cwd(), arg("out-file", NEW_DEFAULT_OUT_FILE));
|
|
52
|
-
|
|
52
|
+
const oldSectionsPath = path.resolve(process.cwd(), OLD_DEFAULT_OUT_FILE);
|
|
53
|
+
const hasLegacy = !OUT_FILE_EXPLICIT && fs.existsSync(oldSectionsPath);
|
|
54
|
+
if (hasLegacy) {
|
|
53
55
|
warnLegacyArtifact(OLD_DEFAULT_OUT_FILE, NEW_DEFAULT_OUT_FILE);
|
|
54
56
|
}
|
|
55
57
|
const EMIT_REGISTRY = args.includes("--registry");
|
|
@@ -291,6 +293,7 @@ fs.writeFileSync(
|
|
|
291
293
|
outFile,
|
|
292
294
|
lines.join("\n").replace(/\n{3,}/g, "\n\n").replace(/\n*$/, "\n"),
|
|
293
295
|
);
|
|
296
|
+
if (hasLegacy) syncLegacyArtifact(oldSectionsPath, outFile);
|
|
294
297
|
|
|
295
298
|
console.log(
|
|
296
299
|
`Generated section metadata for ${entries.length} sections → ${path.relative(process.cwd(), outFile)}`,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Generator default output paths flipped from `src/server/{cms,admin}/` to
|
|
3
6
|
* `.deco/` (framework artifacts live in the framework's folder, not mixed
|
|
@@ -15,6 +18,17 @@
|
|
|
15
18
|
*/
|
|
16
19
|
export function warnLegacyArtifact(oldPath: string, newPath: string): void {
|
|
17
20
|
console.warn(
|
|
18
|
-
`[deco] Generator default output moved: ${oldPath} -> ${newPath}.
|
|
21
|
+
`[deco] Generator default output moved: ${oldPath} -> ${newPath}. Update importers to use the new path, then delete the old file.`,
|
|
19
22
|
);
|
|
20
23
|
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Copies the freshly-generated file at `newPath` back to `oldPath` so that
|
|
27
|
+
* sites mid-migration whose imports still point at the old location see
|
|
28
|
+
* up-to-date output without requiring a full migration first.
|
|
29
|
+
* Call this after generation completes, only when the old file was detected.
|
|
30
|
+
*/
|
|
31
|
+
export function syncLegacyArtifact(oldPath: string, newPath: string): void {
|
|
32
|
+
fs.mkdirSync(path.dirname(oldPath), { recursive: true });
|
|
33
|
+
fs.copyFileSync(newPath, oldPath);
|
|
34
|
+
}
|