@actuate-media/cli 0.11.3 β 0.12.0
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +31 -31
- package/CHANGELOG.md +6 -0
- package/dist/commands/migrate-meta.d.ts +3 -0
- package/dist/commands/migrate-meta.d.ts.map +1 -0
- package/dist/commands/migrate-meta.js +81 -0
- package/dist/commands/migrate-meta.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/migrate-meta.ts +107 -0
- package/src/index.ts +2 -0
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
|
|
2
|
-
> @actuate-media/cli@0.
|
|
2
|
+
> @actuate-media/cli@0.12.0 test /home/runner/work/actuatecms/actuatecms/packages/cli
|
|
3
3
|
> vitest run
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
[1m[30m[46m RUN [49m[39m[22m [36mv4.1.8 [39m[90m/home/runner/work/actuatecms/actuatecms/packages/cli[39m
|
|
7
7
|
|
|
8
|
-
[32mβ[39m dist/__tests__/db-sync.test.js [2m([22m[2m10 tests[22m[2m)[22m[
|
|
9
|
-
[32mβ[39m dist/__tests__/seed.test.js [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
10
|
-
[32mβ[39m src/__tests__/db-sync.test.ts [2m([22m[2m10 tests[22m[2m)[22m[
|
|
11
|
-
[32mβ[39m dist/__tests__/deployment-diagnostics.test.js [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
12
|
-
[32mβ[39m src/__tests__/seed.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
13
|
-
[32mβ[39m src/__tests__/deployment-diagnostics.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m
|
|
8
|
+
[32mβ[39m dist/__tests__/db-sync.test.js [2m([22m[2m10 tests[22m[2m)[22m[32m 233[2mms[22m[39m
|
|
9
|
+
[32mβ[39m dist/__tests__/seed.test.js [2m([22m[2m10 tests[22m[2m)[22m[32m 128[2mms[22m[39m
|
|
10
|
+
[32mβ[39m src/__tests__/db-sync.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 219[2mms[22m[39m
|
|
11
|
+
[32mβ[39m dist/__tests__/deployment-diagnostics.test.js [2m([22m[2m9 tests[22m[2m)[22m[32m 35[2mms[22m[39m
|
|
12
|
+
[32mβ[39m src/__tests__/seed.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 164[2mms[22m[39m
|
|
13
|
+
[32mβ[39m src/__tests__/deployment-diagnostics.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 49[2mms[22m[39m
|
|
14
14
|
- Reading canonical Actuate schema...
|
|
15
15
|
β Actuate CMS models added to schema.
|
|
16
16
|
- Running prisma generate...
|
|
@@ -18,43 +18,43 @@
|
|
|
18
18
|
[22m[39mβ Prisma client generated.
|
|
19
19
|
βΉ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
20
20
|
|
|
21
|
+
[90mstdout[2m | dist/__tests__/db-init.test.js[2m > [22m[2mdb:init (WS-D D5 β canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mfails clearly when cms-core cannot be located
|
|
21
22
|
- Reading canonical Actuate schema...
|
|
22
23
|
β Could not locate @actuate-media/cms-core.
|
|
23
|
-
[90mstdout[2m | dist/__tests__/db-init.test.js[2m > [22m[2mdb:init (WS-D D5 β canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mfails clearly when cms-core cannot be located
|
|
24
24
|
[22m[39mβΉ Install it first: `npm install @actuate-media/cms-core`.
|
|
25
25
|
|
|
26
26
|
- Reading canonical Actuate schema...
|
|
27
27
|
β Actuate CMS models added to schema.
|
|
28
|
-
- Running prisma generate...
|
|
29
28
|
[90mstdout[2m | dist/__tests__/db-init.test.js[2m > [22m[2mdb:init (WS-D D5 β canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mis idempotent without --force
|
|
30
29
|
[22m[39mβ Prisma client generated.
|
|
30
|
+
- Running prisma generate...
|
|
31
31
|
βΉ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
32
32
|
|
|
33
33
|
- Reading canonical Actuate schema...
|
|
34
34
|
βΉ Actuate CMS models already present in schema. Use --force to overwrite.
|
|
35
|
-
[32mβ[39m dist/__tests__/db-init.test.js [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
35
|
+
[32mβ[39m dist/__tests__/db-init.test.js [2m([22m[2m4 tests[22m[2m)[22m[32m 228[2mms[22m[39m
|
|
36
36
|
- Reading canonical Actuate schema...
|
|
37
|
-
β Actuate CMS models added to schema.
|
|
38
|
-
- Running prisma generate...
|
|
39
37
|
[90mstdout[2m | src/__tests__/db-init.test.ts[2m > [22m[2mdb:init (WS-D D5 β canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2minjects canonical models with @@map and no duplicate datasource/generator
|
|
40
38
|
[22m[39mβ Prisma client generated.
|
|
41
39
|
βΉ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
42
40
|
|
|
41
|
+
β Actuate CMS models added to schema.
|
|
42
|
+
- Running prisma generate...
|
|
43
43
|
- Reading canonical Actuate schema...
|
|
44
|
-
β Could not locate @actuate-media/cms-core.
|
|
45
44
|
[90mstdout[2m | src/__tests__/db-init.test.ts[2m > [22m[2mdb:init (WS-D D5 β canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mfails clearly when cms-core cannot be located
|
|
45
|
+
β Could not locate @actuate-media/cms-core.
|
|
46
46
|
[22m[39mβΉ Install it first: `npm install @actuate-media/cms-core`.
|
|
47
47
|
|
|
48
48
|
- Reading canonical Actuate schema...
|
|
49
|
-
β Actuate CMS models added to schema.
|
|
50
|
-
- Running prisma generate...
|
|
51
49
|
[90mstdout[2m | src/__tests__/db-init.test.ts[2m > [22m[2mdb:init (WS-D D5 β canonical schema, no stale fragment)[2m > [22m[2mcommand[2m > [22m[2mis idempotent without --force
|
|
52
50
|
[22m[39mβ Prisma client generated.
|
|
51
|
+
β Actuate CMS models added to schema.
|
|
53
52
|
βΉ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
53
|
+
- Running prisma generate...
|
|
54
54
|
|
|
55
55
|
- Reading canonical Actuate schema...
|
|
56
56
|
βΉ Actuate CMS models already present in schema. Use --force to overwrite.
|
|
57
|
-
[32mβ[39m src/__tests__/db-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m
|
|
57
|
+
[32mβ[39m src/__tests__/db-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 246[2mms[22m[39m
|
|
58
58
|
[90mstdout[2m | dist/__tests__/mcp-init.test.js[2m > [22m[2mmcp:init[2m > [22m[2mcreates both editor configs with placeholder key and git-ignores them
|
|
59
59
|
[22m[39mβ Created .cursor/mcp.json
|
|
60
60
|
|
|
@@ -183,7 +183,7 @@ Next steps
|
|
|
183
183
|
3. Restart Cursor / VS Code so the MCP server is picked up
|
|
184
184
|
Tip: pass --url https://your-site.com to target a deployed CMS instead.
|
|
185
185
|
|
|
186
|
-
[32mβ[39m dist/__tests__/mcp-init.test.js [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
186
|
+
[32mβ[39m dist/__tests__/mcp-init.test.js [2m([22m[2m6 tests[22m[2m)[22m[32m 249[2mms[22m[39m
|
|
187
187
|
[90mstdout[2m | src/__tests__/mcp-init.test.ts[2m > [22m[2mmcp:init[2m > [22m[2mcreates both editor configs with placeholder key and git-ignores them
|
|
188
188
|
[22m[39mβ Created .cursor/mcp.json
|
|
189
189
|
|
|
@@ -312,13 +312,13 @@ Next steps
|
|
|
312
312
|
3. Restart Cursor / VS Code so the MCP server is picked up
|
|
313
313
|
Tip: pass --url https://your-site.com to target a deployed CMS instead.
|
|
314
314
|
|
|
315
|
-
[32mβ[39m src/__tests__/mcp-init.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
316
|
-
[32mβ[39m dist/__tests__/form-seed.test.js [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
317
|
-
[32mβ[39m src/__tests__/form-seed.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m
|
|
318
|
-
[32mβ[39m dist/__tests__/vercel-env-matrix.test.js [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
319
|
-
[32mβ[39m src/__tests__/vercel-env-matrix.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m
|
|
320
|
-
[32mβ[39m dist/__tests__/load-dotenv.test.js [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
321
|
-
[32mβ[39m src/__tests__/load-dotenv.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m
|
|
315
|
+
[32mβ[39m src/__tests__/mcp-init.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 134[2mms[22m[39m
|
|
316
|
+
[32mβ[39m dist/__tests__/form-seed.test.js [2m([22m[2m10 tests[22m[2m)[22m[32m 31[2mms[22m[39m
|
|
317
|
+
[32mβ[39m src/__tests__/form-seed.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 34[2mms[22m[39m
|
|
318
|
+
[32mβ[39m dist/__tests__/vercel-env-matrix.test.js [2m([22m[2m6 tests[22m[2m)[22m[32m 28[2mms[22m[39m
|
|
319
|
+
[32mβ[39m src/__tests__/vercel-env-matrix.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 30[2mms[22m[39m
|
|
320
|
+
[32mβ[39m dist/__tests__/load-dotenv.test.js [2m([22m[2m3 tests[22m[2m)[22m[32m 37[2mms[22m[39m
|
|
321
|
+
[32mβ[39m src/__tests__/load-dotenv.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 44[2mms[22m[39m
|
|
322
322
|
- Reading canonical Actuate schema...
|
|
323
323
|
β Actuate CMS models added to schema.
|
|
324
324
|
- Running prisma generate...
|
|
@@ -326,20 +326,20 @@ Next steps
|
|
|
326
326
|
[22m[39mβ Prisma client generated.
|
|
327
327
|
βΉ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
328
328
|
|
|
329
|
-
[32mβ[39m dist/__tests__/schema-fragment.test.js [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
329
|
+
[32mβ[39m dist/__tests__/schema-fragment.test.js [2m([22m[2m1 test[22m[2m)[22m[32m 80[2mms[22m[39m
|
|
330
330
|
- Reading canonical Actuate schema...
|
|
331
331
|
β Actuate CMS models added to schema.
|
|
332
|
-
- Running prisma generate...
|
|
333
332
|
[90mstdout[2m | src/__tests__/schema-fragment.test.ts[2m > [22m[2mdb:init schema fragment[2m > [22m[2minjects all deploy-critical Actuate models
|
|
334
333
|
[22m[39mβ Prisma client generated.
|
|
334
|
+
- Running prisma generate...
|
|
335
335
|
βΉ Run `npx prisma migrate dev --name actuate-cms` to create the migration.
|
|
336
336
|
|
|
337
|
-
[32mβ[39m src/__tests__/schema-fragment.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m
|
|
338
|
-
[32mβ[39m dist/__tests__/init.test.js [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
339
|
-
[32mβ[39m src/__tests__/init.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m
|
|
337
|
+
[32mβ[39m src/__tests__/schema-fragment.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 66[2mms[22m[39m
|
|
338
|
+
[32mβ[39m dist/__tests__/init.test.js [2m([22m[2m2 tests[22m[2m)[22m[32m 16[2mms[22m[39m
|
|
339
|
+
[32mβ[39m src/__tests__/init.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 15[2mms[22m[39m
|
|
340
340
|
|
|
341
341
|
[2m Test Files [22m [1m[32m20 passed[39m[22m[90m (20)[39m
|
|
342
342
|
[2m Tests [22m [1m[32m122 passed[39m[22m[90m (122)[39m
|
|
343
|
-
[2m Start at [22m
|
|
344
|
-
[2m Duration [22m
|
|
343
|
+
[2m Start at [22m 05:27:27
|
|
344
|
+
[2m Duration [22m 21.87s[2m (transform 2.20s, setup 0ms, import 5.83s, tests 2.07s, environment 21ms)[22m
|
|
345
345
|
|
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-meta.d.ts","sourceRoot":"","sources":["../../src/commands/migrate-meta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAgGnC,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUjE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { connectProjectDatabase } from '../utils/database.js';
|
|
5
|
+
import { loadProjectEnv } from '../utils/load-dotenv.js';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
async function loadProjectConfig(configPath) {
|
|
8
|
+
try {
|
|
9
|
+
const { setActuateConfig } = await import('@actuate-media/cms-core');
|
|
10
|
+
const { tsImport } = await import('tsx/esm/api');
|
|
11
|
+
const abs = pathToFileURL(resolve(configPath)).href;
|
|
12
|
+
const mod = (await tsImport(abs, import.meta.url));
|
|
13
|
+
const config = mod.default ?? mod.config;
|
|
14
|
+
if (config && typeof config === 'object') {
|
|
15
|
+
setActuateConfig(config);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
logger.warn(`Could not load ${configPath} β meta defaults will use collection slug heuristics only.`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** `actuate migrate:meta` β backfill metaTitle/metaDescription on content documents. */
|
|
23
|
+
async function runMigrateMeta(options) {
|
|
24
|
+
const dryRun = options.dryRun ?? false;
|
|
25
|
+
const batchSize = options.batchSize ? Number.parseInt(options.batchSize, 10) : undefined;
|
|
26
|
+
if (batchSize !== undefined && (!Number.isFinite(batchSize) || batchSize <= 0)) {
|
|
27
|
+
logger.error('--batch-size must be a positive integer.');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
await loadProjectEnv(process.cwd()).then((env) => {
|
|
31
|
+
for (const [key, value] of Object.entries(env)) {
|
|
32
|
+
if (value !== undefined && process.env[key] === undefined) {
|
|
33
|
+
process.env[key] = value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
await loadProjectConfig(options.config ?? 'actuate.config.ts');
|
|
38
|
+
let connection = null;
|
|
39
|
+
const spinner = ora(dryRun ? 'Scanning content documents (dry run)β¦' : 'Backfilling meta title/descriptionβ¦').start();
|
|
40
|
+
try {
|
|
41
|
+
connection = await connectProjectDatabase();
|
|
42
|
+
const db = connection.db;
|
|
43
|
+
const { migrateMetaFields } = await import('@actuate-media/cms-core');
|
|
44
|
+
const admin = await db.user.findFirst({ where: { role: 'ADMIN' } });
|
|
45
|
+
if (!admin) {
|
|
46
|
+
spinner.fail('No ADMIN user found. Create an admin (setup wizard or seed) first.');
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
const ctx = { userId: admin.id, role: 'ADMIN', db: connection.db, locale: 'en' };
|
|
50
|
+
const result = await migrateMetaFields(ctx, { dryRun, batchSize });
|
|
51
|
+
spinner.succeed(dryRun
|
|
52
|
+
? `Dry run complete β ${result.migrated} document(s) would be updated.`
|
|
53
|
+
: `Updated ${result.migrated} document(s).`);
|
|
54
|
+
logger.info(` Scanned: ${result.scanned}`);
|
|
55
|
+
logger.info(` Migrated: ${result.migrated}`);
|
|
56
|
+
logger.info(` Skipped: ${result.skipped}`);
|
|
57
|
+
if (result.migratedIds.length > 0) {
|
|
58
|
+
logger.info(` IDs: ${result.migratedIds.join(', ')}`);
|
|
59
|
+
}
|
|
60
|
+
logger.info('');
|
|
61
|
+
logger.info('Next: re-run the SEO audit in Settings β SEO β Audit.');
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
65
|
+
spinner.fail(`Meta migration failed: ${message}`);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
await connection?.disconnect();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function registerMigrateMetaCommand(program) {
|
|
73
|
+
program
|
|
74
|
+
.command('migrate:meta')
|
|
75
|
+
.description('Backfill metaTitle/metaDescription from title templates and key takeaways. Idempotent.')
|
|
76
|
+
.option('--dry-run', 'Report what would change without writing')
|
|
77
|
+
.option('--batch-size <n>', 'Documents to scan per DB page (default 100)')
|
|
78
|
+
.option('--config <path>', 'Path to actuate.config.ts', 'actuate.config.ts')
|
|
79
|
+
.action(runMigrateMeta);
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=migrate-meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-meta.js","sourceRoot":"","sources":["../../src/commands/migrate-meta.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAQ3C,KAAK,UAAU,iBAAiB,CAAC,UAAkB;IACjD,IAAI,CAAC;QACH,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAA;QACpE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;QAChD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAA;QACnD,MAAM,GAAG,GAAG,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAGhD,CAAA;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAA;QACxC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzC,gBAAgB,CAAC,MAAe,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CACT,kBAAkB,UAAU,4DAA4D,CACzF,CAAA;IACH,CAAC;AACH,CAAC;AAED,wFAAwF;AACxF,KAAK,UAAU,cAAc,CAAC,OAA2B;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAA;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACxF,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;YAC1B,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IACF,MAAM,iBAAiB,CAAC,OAAO,CAAC,MAAM,IAAI,mBAAmB,CAAC,CAAA;IAE9D,IAAI,UAAU,GAA4D,IAAI,CAAA;IAC9E,MAAM,OAAO,GAAG,GAAG,CACjB,MAAM,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,qCAAqC,CACzF,CAAC,KAAK,EAAE,CAAA;IAET,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,sBAAsB,EAAE,CAAA;QAC3C,MAAM,EAAE,GAAG,UAAU,CAAC,EAErB,CAAA;QAED,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAA;QAErE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAA;QACnE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAA;YAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;QAChF,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;QAElE,OAAO,CAAC,OAAO,CACb,MAAM;YACJ,CAAC,CAAC,sBAAsB,MAAM,CAAC,QAAQ,gCAAgC;YACvE,CAAC,CAAC,WAAW,MAAM,CAAC,QAAQ,eAAe,CAC9C,CAAA;QACD,MAAM,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;QAC5C,MAAM,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC7C,MAAM,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;QAC5C,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC7D,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACf,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAA;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAChE,OAAO,CAAC,IAAI,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAA;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;YAAS,CAAC;QACT,MAAM,UAAU,EAAE,UAAU,EAAE,CAAA;IAChC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAgB;IACzD,OAAO;SACJ,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CACV,wFAAwF,CACzF;SACA,MAAM,CAAC,WAAW,EAAE,0CAA0C,CAAC;SAC/D,MAAM,CAAC,kBAAkB,EAAE,6CAA6C,CAAC;SACzE,MAAM,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,mBAAmB,CAAC;SAC3E,MAAM,CAAC,cAAc,CAAC,CAAA;AAC3B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Command } from 'commander';
|
|
|
3
3
|
import { registerMigrateCommand } from './commands/migrate.js';
|
|
4
4
|
import { registerMigrateSectionsCommand } from './commands/migrate-sections.js';
|
|
5
5
|
import { registerMigrateSchemaCommand } from './commands/migrate-schema.js';
|
|
6
|
+
import { registerMigrateMetaCommand } from './commands/migrate-meta.js';
|
|
6
7
|
import { registerGenerateCommand } from './commands/generate.js';
|
|
7
8
|
import { registerSeedCommand } from './commands/seed.js';
|
|
8
9
|
import { registerImportCommand } from './commands/import.js';
|
|
@@ -24,6 +25,7 @@ program
|
|
|
24
25
|
registerMigrateCommand(program);
|
|
25
26
|
registerMigrateSectionsCommand(program);
|
|
26
27
|
registerMigrateSchemaCommand(program);
|
|
28
|
+
registerMigrateMetaCommand(program);
|
|
27
29
|
registerGenerateCommand(program);
|
|
28
30
|
registerSeedCommand(program);
|
|
29
31
|
registerImportCommand(program);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAA;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,6DAA6D,CAAC;KAC1E,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAC/B,8BAA8B,CAAC,OAAO,CAAC,CAAA;AACvC,4BAA4B,CAAC,OAAO,CAAC,CAAA;AACrC,uBAAuB,CAAC,OAAO,CAAC,CAAA;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAC/B,0BAA0B,CAAC,OAAO,CAAC,CAAA;AACnC,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAA;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,0BAA0B,CAAC,OAAO,CAAC,CAAA;AACnC,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,6BAA6B,CAAC,OAAO,CAAC,CAAA;AACtC,kBAAkB,CAAC,OAAO,CAAC,CAAA;AAE3B,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAA;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,6DAA6D,CAAC;KAC1E,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAC/B,8BAA8B,CAAC,OAAO,CAAC,CAAA;AACvC,4BAA4B,CAAC,OAAO,CAAC,CAAA;AACrC,0BAA0B,CAAC,OAAO,CAAC,CAAA;AACnC,uBAAuB,CAAC,OAAO,CAAC,CAAA;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAC/B,0BAA0B,CAAC,OAAO,CAAC,CAAA;AACnC,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAA;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,0BAA0B,CAAC,OAAO,CAAC,CAAA;AACnC,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,6BAA6B,CAAC,OAAO,CAAC,CAAA;AACtC,kBAAkB,CAAC,OAAO,CAAC,CAAA;AAE3B,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actuate-media/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "CLI for Actuate CMS β migrations, codegen, imports, exports, and upgrades",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"typescript": "^5.7.0",
|
|
30
30
|
"vitest": "^4.1.0",
|
|
31
|
-
"@actuate-media/cms-core": "0.
|
|
31
|
+
"@actuate-media/cms-core": "0.78.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "tsc",
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Command } from 'commander'
|
|
2
|
+
import { resolve } from 'node:path'
|
|
3
|
+
import { pathToFileURL } from 'node:url'
|
|
4
|
+
import ora from 'ora'
|
|
5
|
+
import { connectProjectDatabase } from '../utils/database.js'
|
|
6
|
+
import { loadProjectEnv } from '../utils/load-dotenv.js'
|
|
7
|
+
import { logger } from '../utils/logger.js'
|
|
8
|
+
|
|
9
|
+
interface MigrateMetaOptions {
|
|
10
|
+
dryRun?: boolean
|
|
11
|
+
batchSize?: string
|
|
12
|
+
config?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function loadProjectConfig(configPath: string): Promise<void> {
|
|
16
|
+
try {
|
|
17
|
+
const { setActuateConfig } = await import('@actuate-media/cms-core')
|
|
18
|
+
const { tsImport } = await import('tsx/esm/api')
|
|
19
|
+
const abs = pathToFileURL(resolve(configPath)).href
|
|
20
|
+
const mod = (await tsImport(abs, import.meta.url)) as {
|
|
21
|
+
default?: unknown
|
|
22
|
+
config?: unknown
|
|
23
|
+
}
|
|
24
|
+
const config = mod.default ?? mod.config
|
|
25
|
+
if (config && typeof config === 'object') {
|
|
26
|
+
setActuateConfig(config as never)
|
|
27
|
+
}
|
|
28
|
+
} catch {
|
|
29
|
+
logger.warn(
|
|
30
|
+
`Could not load ${configPath} β meta defaults will use collection slug heuristics only.`,
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** `actuate migrate:meta` β backfill metaTitle/metaDescription on content documents. */
|
|
36
|
+
async function runMigrateMeta(options: MigrateMetaOptions): Promise<void> {
|
|
37
|
+
const dryRun = options.dryRun ?? false
|
|
38
|
+
const batchSize = options.batchSize ? Number.parseInt(options.batchSize, 10) : undefined
|
|
39
|
+
if (batchSize !== undefined && (!Number.isFinite(batchSize) || batchSize <= 0)) {
|
|
40
|
+
logger.error('--batch-size must be a positive integer.')
|
|
41
|
+
process.exit(1)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
await loadProjectEnv(process.cwd()).then((env) => {
|
|
45
|
+
for (const [key, value] of Object.entries(env)) {
|
|
46
|
+
if (value !== undefined && process.env[key] === undefined) {
|
|
47
|
+
process.env[key] = value
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
await loadProjectConfig(options.config ?? 'actuate.config.ts')
|
|
52
|
+
|
|
53
|
+
let connection: { db: unknown; disconnect: () => Promise<void> } | null = null
|
|
54
|
+
const spinner = ora(
|
|
55
|
+
dryRun ? 'Scanning content documents (dry run)β¦' : 'Backfilling meta title/descriptionβ¦',
|
|
56
|
+
).start()
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
connection = await connectProjectDatabase()
|
|
60
|
+
const db = connection.db as {
|
|
61
|
+
user: { findFirst: (args: unknown) => Promise<{ id: string } | null> }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { migrateMetaFields } = await import('@actuate-media/cms-core')
|
|
65
|
+
|
|
66
|
+
const admin = await db.user.findFirst({ where: { role: 'ADMIN' } })
|
|
67
|
+
if (!admin) {
|
|
68
|
+
spinner.fail('No ADMIN user found. Create an admin (setup wizard or seed) first.')
|
|
69
|
+
process.exit(1)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const ctx = { userId: admin.id, role: 'ADMIN', db: connection.db, locale: 'en' }
|
|
73
|
+
const result = await migrateMetaFields(ctx, { dryRun, batchSize })
|
|
74
|
+
|
|
75
|
+
spinner.succeed(
|
|
76
|
+
dryRun
|
|
77
|
+
? `Dry run complete β ${result.migrated} document(s) would be updated.`
|
|
78
|
+
: `Updated ${result.migrated} document(s).`,
|
|
79
|
+
)
|
|
80
|
+
logger.info(` Scanned: ${result.scanned}`)
|
|
81
|
+
logger.info(` Migrated: ${result.migrated}`)
|
|
82
|
+
logger.info(` Skipped: ${result.skipped}`)
|
|
83
|
+
if (result.migratedIds.length > 0) {
|
|
84
|
+
logger.info(` IDs: ${result.migratedIds.join(', ')}`)
|
|
85
|
+
}
|
|
86
|
+
logger.info('')
|
|
87
|
+
logger.info('Next: re-run the SEO audit in Settings β SEO β Audit.')
|
|
88
|
+
} catch (err) {
|
|
89
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
90
|
+
spinner.fail(`Meta migration failed: ${message}`)
|
|
91
|
+
process.exit(1)
|
|
92
|
+
} finally {
|
|
93
|
+
await connection?.disconnect()
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function registerMigrateMetaCommand(program: Command): void {
|
|
98
|
+
program
|
|
99
|
+
.command('migrate:meta')
|
|
100
|
+
.description(
|
|
101
|
+
'Backfill metaTitle/metaDescription from title templates and key takeaways. Idempotent.',
|
|
102
|
+
)
|
|
103
|
+
.option('--dry-run', 'Report what would change without writing')
|
|
104
|
+
.option('--batch-size <n>', 'Documents to scan per DB page (default 100)')
|
|
105
|
+
.option('--config <path>', 'Path to actuate.config.ts', 'actuate.config.ts')
|
|
106
|
+
.action(runMigrateMeta)
|
|
107
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Command } from 'commander'
|
|
|
3
3
|
import { registerMigrateCommand } from './commands/migrate.js'
|
|
4
4
|
import { registerMigrateSectionsCommand } from './commands/migrate-sections.js'
|
|
5
5
|
import { registerMigrateSchemaCommand } from './commands/migrate-schema.js'
|
|
6
|
+
import { registerMigrateMetaCommand } from './commands/migrate-meta.js'
|
|
6
7
|
import { registerGenerateCommand } from './commands/generate.js'
|
|
7
8
|
import { registerSeedCommand } from './commands/seed.js'
|
|
8
9
|
import { registerImportCommand } from './commands/import.js'
|
|
@@ -31,6 +32,7 @@ program
|
|
|
31
32
|
registerMigrateCommand(program)
|
|
32
33
|
registerMigrateSectionsCommand(program)
|
|
33
34
|
registerMigrateSchemaCommand(program)
|
|
35
|
+
registerMigrateMetaCommand(program)
|
|
34
36
|
registerGenerateCommand(program)
|
|
35
37
|
registerSeedCommand(program)
|
|
36
38
|
registerImportCommand(program)
|