@actuate-media/cli 0.7.0 → 0.10.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 +32 -28
- package/CHANGELOG.md +28 -0
- package/README.md +30 -0
- package/dist/__tests__/db-sync.test.js +32 -1
- package/dist/__tests__/db-sync.test.js.map +1 -1
- package/dist/__tests__/deployment-diagnostics.test.js +42 -1
- package/dist/__tests__/deployment-diagnostics.test.js.map +1 -1
- package/dist/__tests__/form-seed.test.d.ts +2 -0
- package/dist/__tests__/form-seed.test.d.ts.map +1 -0
- package/dist/__tests__/form-seed.test.js +79 -0
- package/dist/__tests__/form-seed.test.js.map +1 -0
- package/dist/__tests__/seed.test.js +73 -0
- package/dist/__tests__/seed.test.js.map +1 -1
- package/dist/__tests__/vercel-env-matrix.test.d.ts +2 -0
- package/dist/__tests__/vercel-env-matrix.test.d.ts.map +1 -0
- package/dist/__tests__/vercel-env-matrix.test.js +48 -0
- package/dist/__tests__/vercel-env-matrix.test.js.map +1 -0
- package/dist/commands/db-sync.d.ts +22 -0
- package/dist/commands/db-sync.d.ts.map +1 -1
- package/dist/commands/db-sync.js +94 -0
- package/dist/commands/db-sync.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +70 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/seed.d.ts +30 -1
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +146 -21
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/vercel-blob-link.d.ts +3 -0
- package/dist/commands/vercel-blob-link.d.ts.map +1 -0
- package/dist/commands/vercel-blob-link.js +82 -0
- package/dist/commands/vercel-blob-link.js.map +1 -0
- package/dist/deployment/diagnostics.d.ts +13 -0
- package/dist/deployment/diagnostics.d.ts.map +1 -1
- package/dist/deployment/diagnostics.js +55 -0
- package/dist/deployment/diagnostics.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/form-seed.d.ts +15 -0
- package/dist/utils/form-seed.d.ts.map +1 -0
- package/dist/utils/form-seed.js +97 -0
- package/dist/utils/form-seed.js.map +1 -0
- package/dist/vercel/client.d.ts +32 -0
- package/dist/vercel/client.d.ts.map +1 -0
- package/dist/vercel/client.js +74 -0
- package/dist/vercel/client.js.map +1 -0
- package/dist/vercel/env-matrix.d.ts +34 -0
- package/dist/vercel/env-matrix.d.ts.map +1 -0
- package/dist/vercel/env-matrix.js +57 -0
- package/dist/vercel/env-matrix.js.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/db-sync.test.ts +55 -1
- package/src/__tests__/deployment-diagnostics.test.ts +51 -0
- package/src/__tests__/form-seed.test.ts +91 -0
- package/src/__tests__/seed.test.ts +97 -0
- package/src/__tests__/vercel-env-matrix.test.ts +56 -0
- package/src/commands/db-sync.ts +116 -0
- package/src/commands/doctor.ts +118 -10
- package/src/commands/seed.ts +167 -21
- package/src/commands/vercel-blob-link.ts +115 -0
- package/src/deployment/diagnostics.ts +70 -0
- package/src/index.ts +2 -0
- package/src/utils/form-seed.ts +137 -0
- package/src/vercel/client.ts +112 -0
- package/src/vercel/env-matrix.ts +101 -0
|
@@ -13,6 +13,28 @@ export declare function buildConsumerSchema(coreSchemaSource: string): string;
|
|
|
13
13
|
export declare let resolveCmsCorePrismaDir: () => string | null;
|
|
14
14
|
export declare function setCmsCorePrismaDirResolver(resolver: typeof resolveCmsCorePrismaDir): void;
|
|
15
15
|
export declare function resetCmsCorePrismaDirResolver(): void;
|
|
16
|
+
export interface DriftDiffResult {
|
|
17
|
+
exitCode: number;
|
|
18
|
+
stdout: string;
|
|
19
|
+
stderr: string;
|
|
20
|
+
}
|
|
21
|
+
export type DriftRunner = (args: {
|
|
22
|
+
schemaPath: string;
|
|
23
|
+
url: string;
|
|
24
|
+
}) => Promise<DriftDiffResult>;
|
|
25
|
+
export interface DriftCheckResult {
|
|
26
|
+
status: 'no-drift' | 'drift' | 'skipped' | 'error';
|
|
27
|
+
detail?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Detect whether the live database differs from the canonical schema. Pure of
|
|
31
|
+
* I/O via the injectable `runner` so the decision logic is unit-testable. A
|
|
32
|
+
* non-pooled `DIRECT_DATABASE_URL` is preferred (migrations use it); falls back
|
|
33
|
+
* to `DATABASE_URL`. Skips gracefully when neither is set.
|
|
34
|
+
*/
|
|
35
|
+
export declare function checkSchemaDrift(schemaPath: string, env?: NodeJS.ProcessEnv, runner?: DriftRunner): Promise<DriftCheckResult>;
|
|
36
|
+
/** Human-readable next steps for a drift verdict (pure, for testing + reuse). */
|
|
37
|
+
export declare function driftGuidance(result: DriftCheckResult): string[];
|
|
16
38
|
export interface DbSyncResult {
|
|
17
39
|
schemaWritten: boolean;
|
|
18
40
|
migrationsAdded: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-sync.d.ts","sourceRoot":"","sources":["../../src/commands/db-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"db-sync.d.ts","sourceRoot":"","sources":["../../src/commands/db-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAoCnC;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAcpE;AAED;;;GAGG;AACH,eAAO,IAAI,uBAAuB,QAAO,MAAM,GAAG,IAajD,CAAA;AAID,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,OAAO,uBAAuB,GAAG,IAAI,CAE1F;AAED,wBAAgB,6BAA6B,IAAI,IAAI,CAEpD;AAiBD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;AAEjG,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAA;IAClD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAqCD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,MAAM,GAAE,WAAgC,GACvC,OAAO,CAAC,gBAAgB,CAAC,CAY3B;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAiBhE;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,OAAO,CAAA;IACtB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC,YAAY,CAAC,CAiDvB;AA2ED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQ5D"}
|
package/dist/commands/db-sync.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { access, cp, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
3
4
|
import { dirname, join, resolve } from 'node:path';
|
|
4
5
|
import { createRequire } from 'node:module';
|
|
5
6
|
import ora from 'ora';
|
|
@@ -83,6 +84,75 @@ async function listMigrationDirs(dir) {
|
|
|
83
84
|
return [];
|
|
84
85
|
}
|
|
85
86
|
}
|
|
87
|
+
const defaultDriftRunner = ({ schemaPath, url }) => new Promise((resolvePromise) => {
|
|
88
|
+
// `--exit-code` makes prisma return 2 when the database differs from the
|
|
89
|
+
// datamodel, 0 when in sync. `--script` prints the reconciling SQL.
|
|
90
|
+
const child = spawn('npx', [
|
|
91
|
+
'prisma',
|
|
92
|
+
'migrate',
|
|
93
|
+
'diff',
|
|
94
|
+
'--from-url',
|
|
95
|
+
url,
|
|
96
|
+
'--to-schema-datamodel',
|
|
97
|
+
schemaPath,
|
|
98
|
+
'--script',
|
|
99
|
+
'--exit-code',
|
|
100
|
+
], { shell: process.platform === 'win32' });
|
|
101
|
+
let stdout = '';
|
|
102
|
+
let stderr = '';
|
|
103
|
+
child.stdout?.on('data', (chunk) => {
|
|
104
|
+
stdout += String(chunk);
|
|
105
|
+
});
|
|
106
|
+
child.stderr?.on('data', (chunk) => {
|
|
107
|
+
stderr += String(chunk);
|
|
108
|
+
});
|
|
109
|
+
child.on('error', (err) => {
|
|
110
|
+
resolvePromise({ exitCode: 1, stdout, stderr: stderr || String(err) });
|
|
111
|
+
});
|
|
112
|
+
child.on('close', (code) => {
|
|
113
|
+
resolvePromise({ exitCode: code ?? 1, stdout, stderr });
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* Detect whether the live database differs from the canonical schema. Pure of
|
|
118
|
+
* I/O via the injectable `runner` so the decision logic is unit-testable. A
|
|
119
|
+
* non-pooled `DIRECT_DATABASE_URL` is preferred (migrations use it); falls back
|
|
120
|
+
* to `DATABASE_URL`. Skips gracefully when neither is set.
|
|
121
|
+
*/
|
|
122
|
+
export async function checkSchemaDrift(schemaPath, env = process.env, runner = defaultDriftRunner) {
|
|
123
|
+
const url = env.DIRECT_DATABASE_URL || env.DATABASE_URL;
|
|
124
|
+
if (!url) {
|
|
125
|
+
return {
|
|
126
|
+
status: 'skipped',
|
|
127
|
+
detail: 'Set DATABASE_URL (or DIRECT_DATABASE_URL) to let db:sync detect schema drift.',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const result = await runner({ schemaPath, url });
|
|
131
|
+
if (result.exitCode === 0)
|
|
132
|
+
return { status: 'no-drift' };
|
|
133
|
+
if (result.exitCode === 2)
|
|
134
|
+
return { status: 'drift', detail: result.stdout.trim() };
|
|
135
|
+
return { status: 'error', detail: (result.stderr || result.stdout).trim() };
|
|
136
|
+
}
|
|
137
|
+
/** Human-readable next steps for a drift verdict (pure, for testing + reuse). */
|
|
138
|
+
export function driftGuidance(result) {
|
|
139
|
+
switch (result.status) {
|
|
140
|
+
case 'drift':
|
|
141
|
+
return [
|
|
142
|
+
'Database schema differs from the canonical Actuate schema.',
|
|
143
|
+
'Apply the migrations shipped by db:sync (includes column renames):',
|
|
144
|
+
' npx prisma migrate deploy',
|
|
145
|
+
'If drift remains afterward, generate a reconciling migration:',
|
|
146
|
+
' npx prisma migrate dev --name actuate-schema-sync',
|
|
147
|
+
];
|
|
148
|
+
case 'error':
|
|
149
|
+
return ['Could not check schema drift (is the database reachable?).'];
|
|
150
|
+
case 'skipped':
|
|
151
|
+
return [result.detail ?? 'Drift check skipped.'];
|
|
152
|
+
case 'no-drift':
|
|
153
|
+
return ['Database schema matches the canonical Actuate schema.'];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
86
156
|
/**
|
|
87
157
|
* Core sync logic, separated from CLI plumbing for testing. Additive for
|
|
88
158
|
* migrations (never deletes existing ones — they are immutable history), and
|
|
@@ -183,6 +253,29 @@ async function runDbSync(options) {
|
|
|
183
253
|
if (result.schemaWritten || result.migrationsAdded.length > 0) {
|
|
184
254
|
logger.info('Next: run `npx prisma migrate deploy` then `npx prisma generate`.');
|
|
185
255
|
}
|
|
256
|
+
// Drift detection: compare the live DB against the canonical schema so a
|
|
257
|
+
// mismatch (e.g. a renamed column not yet migrated) surfaces an exact command
|
|
258
|
+
// rather than a silent runtime failure. Opt-out with --no-check-drift.
|
|
259
|
+
if (options.checkDrift !== false && !result.skippedReason) {
|
|
260
|
+
const driftSpinner = ora('Checking database for schema drift…').start();
|
|
261
|
+
const drift = await checkSchemaDrift(consumerSchemaPath);
|
|
262
|
+
if (drift.status === 'drift') {
|
|
263
|
+
driftSpinner.warn('Schema drift detected.');
|
|
264
|
+
if (drift.detail) {
|
|
265
|
+
logger.info('Reconciling SQL (review before applying):');
|
|
266
|
+
console.log(drift.detail);
|
|
267
|
+
}
|
|
268
|
+
for (const line of driftGuidance(drift))
|
|
269
|
+
logger.info(line);
|
|
270
|
+
process.exitCode = 1;
|
|
271
|
+
}
|
|
272
|
+
else if (drift.status === 'no-drift') {
|
|
273
|
+
driftSpinner.succeed('No schema drift detected.');
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
driftSpinner.info(driftGuidance(drift)[0] ?? 'Drift check skipped.');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
186
279
|
}
|
|
187
280
|
export function registerDbSyncCommand(program) {
|
|
188
281
|
program
|
|
@@ -190,6 +283,7 @@ export function registerDbSyncCommand(program) {
|
|
|
190
283
|
.description('Sync the canonical Prisma schema + migrations from the installed cms-core')
|
|
191
284
|
.option('--schema <path>', 'Path to schema.prisma', 'prisma/schema.prisma')
|
|
192
285
|
.option('--force', 'Overwrite schema.prisma even if it lacks the AUTO-SYNCED marker')
|
|
286
|
+
.option('--no-check-drift', 'Skip the post-sync database drift check')
|
|
193
287
|
.action(runDbSync);
|
|
194
288
|
}
|
|
195
289
|
//# sourceMappingURL=db-sync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-sync.js","sourceRoot":"","sources":["../../src/commands/db-sync.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"db-sync.js","sourceRoot":"","sources":["../../src/commands/db-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAuGnC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgB5D;AAsED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8CjE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqD5D"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { access, readdir, readFile } from 'node:fs/promises';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import { buildDeploymentManifest, createDiagnosticReport, detectPackageManager, } from '../deployment/diagnostics.js';
|
|
4
|
+
import { buildDeploymentManifest, createDiagnosticReport, detectPackageManager, VERCEL_MATRIX_OPTIONAL, VERCEL_MATRIX_REQUIRED, } from '../deployment/diagnostics.js';
|
|
5
|
+
import { createVercelClient, readVercelLink, resolveVercelToken, VercelApiError, VERCEL_TARGETS, } from '../vercel/client.js';
|
|
6
|
+
import { buildEnvMatrix } from '../vercel/env-matrix.js';
|
|
7
|
+
import { logger } from '../utils/logger.js';
|
|
5
8
|
async function fileExists(path) {
|
|
6
9
|
try {
|
|
7
10
|
await access(path);
|
|
@@ -95,24 +98,88 @@ export function registerDoctorCommand(program) {
|
|
|
95
98
|
process.exitCode = 1;
|
|
96
99
|
});
|
|
97
100
|
}
|
|
101
|
+
function printEnvMatrix(matrix) {
|
|
102
|
+
const cell = (present) => (present ? chalk.green(' Y ') : chalk.red(' . '));
|
|
103
|
+
const keyWidth = Math.max(24, ...matrix.rows.map((r) => `${r.key} (optional)`.length + 1));
|
|
104
|
+
console.log();
|
|
105
|
+
console.log(chalk.bold('Environment variable matrix (Vercel)'));
|
|
106
|
+
console.log(chalk.dim('─────────────────────────────────'));
|
|
107
|
+
console.log(`${'Variable'.padEnd(keyWidth)} Prod Prev Dev`);
|
|
108
|
+
for (const row of matrix.rows) {
|
|
109
|
+
const labelPlain = row.required ? row.key : `${row.key} (optional)`;
|
|
110
|
+
const label = row.required ? row.key : chalk.dim(labelPlain);
|
|
111
|
+
console.log(`${label}${' '.repeat(Math.max(1, keyWidth - labelPlain.length))}` +
|
|
112
|
+
`${cell(row.presence.production)} ${cell(row.presence.preview)} ${cell(row.presence.development)}`);
|
|
113
|
+
}
|
|
114
|
+
console.log(chalk.dim('─────────────────────────────────'));
|
|
115
|
+
console.log(chalk.dim('Y = set for that environment, . = missing'));
|
|
116
|
+
}
|
|
117
|
+
async function runVercelMatrix(opts) {
|
|
118
|
+
const token = resolveVercelToken(opts.token);
|
|
119
|
+
if (!token) {
|
|
120
|
+
logger.error('No Vercel token found. Pass --token or set VERCEL_TOKEN to use --vercel.');
|
|
121
|
+
return { ok: false };
|
|
122
|
+
}
|
|
123
|
+
const link = opts.project
|
|
124
|
+
? { projectId: opts.project, orgId: opts.org }
|
|
125
|
+
: await readVercelLink(process.cwd());
|
|
126
|
+
if (!link?.projectId) {
|
|
127
|
+
logger.error('No linked Vercel project. Run `vercel link` or pass --project <id>.');
|
|
128
|
+
return { ok: false };
|
|
129
|
+
}
|
|
130
|
+
const client = createVercelClient({ token, teamId: link.orgId ?? opts.org });
|
|
131
|
+
try {
|
|
132
|
+
const envVars = await client.listProjectEnv(link.projectId);
|
|
133
|
+
const matrix = buildEnvMatrix(envVars, VERCEL_MATRIX_REQUIRED, VERCEL_MATRIX_OPTIONAL);
|
|
134
|
+
if (!opts.json) {
|
|
135
|
+
printEnvMatrix(matrix);
|
|
136
|
+
if (matrix.missingCritical.length > 0) {
|
|
137
|
+
for (const m of matrix.missingCritical) {
|
|
138
|
+
logger.error(`${m.key} missing on: ${m.targets.join(', ')}`);
|
|
139
|
+
}
|
|
140
|
+
logger.info(`Add the missing variables in the Vercel dashboard (include Development for local \`vercel env pull\`). Targets checked: ${VERCEL_TARGETS.join(', ')}.`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return { ok: matrix.missingCritical.length === 0, matrix };
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
const message = error instanceof VercelApiError
|
|
147
|
+
? error.message
|
|
148
|
+
: error instanceof Error
|
|
149
|
+
? error.message
|
|
150
|
+
: String(error);
|
|
151
|
+
logger.error(`Could not read project environment from Vercel: ${message}`);
|
|
152
|
+
return { ok: false };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
98
155
|
export function registerDeployCheckCommand(program) {
|
|
99
156
|
program
|
|
100
157
|
.command('deploy:check')
|
|
101
158
|
.description('Check production deployment readiness for Actuate CMS')
|
|
102
159
|
.option('--schema <path>', 'Path to schema.prisma', 'prisma/schema.prisma')
|
|
103
160
|
.option('--config <path>', 'Path to actuate.config.ts', 'actuate.config.ts')
|
|
161
|
+
.option('--vercel', 'Read the linked Vercel project and print a per-environment matrix')
|
|
162
|
+
.option('--token <token>', 'Vercel access token (with --vercel; defaults to $VERCEL_TOKEN)')
|
|
163
|
+
.option('--project <id>', 'Vercel project id (with --vercel; defaults to .vercel/project.json)')
|
|
164
|
+
.option('--org <id>', 'Vercel team/org id (with --vercel)')
|
|
104
165
|
.option('--json', 'Print machine-readable JSON')
|
|
105
166
|
.action(async (opts) => {
|
|
106
167
|
const report = await buildReport(opts.schema, opts.config, 'deploy');
|
|
168
|
+
const vercelResult = opts.vercel ? await runVercelMatrix(opts) : null;
|
|
107
169
|
if (opts.json) {
|
|
108
|
-
console.log(JSON.stringify({
|
|
170
|
+
console.log(JSON.stringify({
|
|
171
|
+
...report,
|
|
172
|
+
manifest: buildDeploymentManifest(),
|
|
173
|
+
...(vercelResult ? { vercelMatrix: vercelResult.matrix ?? null } : {}),
|
|
174
|
+
}, null, 2));
|
|
109
175
|
}
|
|
110
176
|
else {
|
|
111
177
|
printReport('Actuate Deploy Check', report);
|
|
112
178
|
console.log(chalk.dim('Run `actuate verify --full` after deployment succeeds.'));
|
|
113
179
|
}
|
|
114
|
-
if (report.status === 'fail')
|
|
180
|
+
if (report.status === 'fail' || (vercelResult && !vercelResult.ok)) {
|
|
115
181
|
process.exitCode = 1;
|
|
182
|
+
}
|
|
116
183
|
});
|
|
117
184
|
}
|
|
118
185
|
export function registerVerifyCommand(program) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/seed.d.ts
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
+
export declare const DEMO_FORMS: {
|
|
3
|
+
name: string;
|
|
4
|
+
title: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
status: string;
|
|
7
|
+
fields: ({
|
|
8
|
+
id: string;
|
|
9
|
+
key: string;
|
|
10
|
+
label: string;
|
|
11
|
+
type: string;
|
|
12
|
+
required: boolean;
|
|
13
|
+
sortOrder: number;
|
|
14
|
+
options?: undefined;
|
|
15
|
+
} | {
|
|
16
|
+
id: string;
|
|
17
|
+
key: string;
|
|
18
|
+
label: string;
|
|
19
|
+
type: string;
|
|
20
|
+
required: boolean;
|
|
21
|
+
sortOrder: number;
|
|
22
|
+
options: {
|
|
23
|
+
label: string;
|
|
24
|
+
value: string;
|
|
25
|
+
}[];
|
|
26
|
+
})[];
|
|
27
|
+
successMessage: string;
|
|
28
|
+
}[];
|
|
2
29
|
export declare const DEMO_NAVIGATIONS: {
|
|
3
30
|
name: string;
|
|
4
31
|
slug: string;
|
|
@@ -26,6 +53,8 @@ export declare function normalizeSeedPayload(seedData: unknown): NormalizedSeedP
|
|
|
26
53
|
export declare function ensureSeedAdmin(db: any): Promise<{
|
|
27
54
|
id: string;
|
|
28
55
|
}>;
|
|
29
|
-
export declare function createSeedDocument(db: any, userId: string, doc: NormalizedSeedDocument
|
|
56
|
+
export declare function createSeedDocument(db: any, userId: string, doc: NormalizedSeedDocument, options?: {
|
|
57
|
+
upsert?: boolean;
|
|
58
|
+
}): Promise<'created' | 'updated'>;
|
|
30
59
|
export declare function registerSeedCommand(program: Command): void;
|
|
31
60
|
//# sourceMappingURL=seed.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/commands/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/commands/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA8HnC,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;GA6FtB,CAAA;AAKD,eAAO,MAAM,gBAAgB;;;;;;;;;GAoB5B,CAAA;AAcD,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,sBAAsB,EAAE,CAAA;IACnC,OAAO,EAAE,oBAAoB,EAAE,CAAA;CAChC;AAyBD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,qBAAqB,CAkC7E;AAwED,wBAAsB,eAAe,CAAC,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBtE;AAoBD,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,GAAG,EACP,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,sBAAsB,EAC3B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CA4EhC;AAgJD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuB1D"}
|
package/dist/commands/seed.js
CHANGED
|
@@ -6,6 +6,7 @@ import { pathToFileURL } from 'node:url';
|
|
|
6
6
|
import ora from 'ora';
|
|
7
7
|
import { logger } from '../utils/logger.js';
|
|
8
8
|
import { connectProjectDatabase } from '../utils/database.js';
|
|
9
|
+
import { validateFormSeeds } from '../utils/form-seed.js';
|
|
9
10
|
async function confirm(question) {
|
|
10
11
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
11
12
|
const answer = await rl.question(`${question} (y/N) `);
|
|
@@ -111,37 +112,101 @@ const DEMO_POSTS = [
|
|
|
111
112
|
status: 'DRAFT',
|
|
112
113
|
},
|
|
113
114
|
];
|
|
114
|
-
|
|
115
|
+
// Canonical form seed shape: the form definition lives in document `data`
|
|
116
|
+
// with its own lifecycle `status: 'active'` (gates the public endpoints) and
|
|
117
|
+
// `fields` keyed by { id, key, label, type, required, sortOrder }. See
|
|
118
|
+
// `validateFormSeeds` — these are validated by the same rules as user seeds.
|
|
119
|
+
export const DEMO_FORMS = [
|
|
115
120
|
{
|
|
121
|
+
name: 'Contact Form',
|
|
116
122
|
title: 'Contact Form',
|
|
117
123
|
slug: 'contact-form',
|
|
124
|
+
status: 'active',
|
|
118
125
|
fields: [
|
|
119
|
-
{
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
{
|
|
127
|
+
id: 'contact-name',
|
|
128
|
+
key: 'name',
|
|
129
|
+
label: 'Name',
|
|
130
|
+
type: 'text',
|
|
131
|
+
required: true,
|
|
132
|
+
sortOrder: 0,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 'contact-email',
|
|
136
|
+
key: 'email',
|
|
137
|
+
label: 'Email',
|
|
138
|
+
type: 'email',
|
|
139
|
+
required: true,
|
|
140
|
+
sortOrder: 1,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: 'contact-message',
|
|
144
|
+
key: 'message',
|
|
145
|
+
label: 'Message',
|
|
146
|
+
type: 'textarea',
|
|
147
|
+
required: true,
|
|
148
|
+
sortOrder: 2,
|
|
149
|
+
},
|
|
122
150
|
],
|
|
123
|
-
submitLabel: 'Send Message',
|
|
124
151
|
successMessage: "Thanks for reaching out! We'll get back to you soon.",
|
|
125
152
|
},
|
|
126
153
|
{
|
|
154
|
+
name: 'Newsletter Signup',
|
|
127
155
|
title: 'Newsletter Signup',
|
|
128
156
|
slug: 'newsletter',
|
|
157
|
+
status: 'active',
|
|
129
158
|
fields: [
|
|
130
|
-
{
|
|
131
|
-
|
|
159
|
+
{
|
|
160
|
+
id: 'newsletter-email',
|
|
161
|
+
key: 'email',
|
|
162
|
+
label: 'Email',
|
|
163
|
+
type: 'email',
|
|
164
|
+
required: true,
|
|
165
|
+
sortOrder: 0,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
id: 'newsletter-first-name',
|
|
169
|
+
key: 'firstName',
|
|
170
|
+
label: 'First name',
|
|
171
|
+
type: 'text',
|
|
172
|
+
required: false,
|
|
173
|
+
sortOrder: 1,
|
|
174
|
+
},
|
|
132
175
|
],
|
|
133
|
-
submitLabel: 'Subscribe',
|
|
134
176
|
successMessage: "You're subscribed! Check your inbox for confirmation.",
|
|
135
177
|
},
|
|
136
178
|
{
|
|
179
|
+
name: 'Feedback Form',
|
|
137
180
|
title: 'Feedback Form',
|
|
138
181
|
slug: 'feedback',
|
|
182
|
+
status: 'active',
|
|
139
183
|
fields: [
|
|
140
|
-
{
|
|
141
|
-
|
|
142
|
-
|
|
184
|
+
{
|
|
185
|
+
id: 'feedback-name',
|
|
186
|
+
key: 'name',
|
|
187
|
+
label: 'Name',
|
|
188
|
+
type: 'text',
|
|
189
|
+
required: false,
|
|
190
|
+
sortOrder: 0,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
id: 'feedback-rating',
|
|
194
|
+
key: 'rating',
|
|
195
|
+
label: 'Rating',
|
|
196
|
+
type: 'select',
|
|
197
|
+
required: true,
|
|
198
|
+
sortOrder: 1,
|
|
199
|
+
options: ['1', '2', '3', '4', '5'].map((v) => ({ label: v, value: v })),
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: 'feedback-comments',
|
|
203
|
+
key: 'comments',
|
|
204
|
+
label: 'Comments',
|
|
205
|
+
type: 'textarea',
|
|
206
|
+
required: false,
|
|
207
|
+
sortOrder: 2,
|
|
208
|
+
},
|
|
143
209
|
],
|
|
144
|
-
submitLabel: 'Submit Feedback',
|
|
145
210
|
successMessage: 'Thank you for your feedback!',
|
|
146
211
|
},
|
|
147
212
|
];
|
|
@@ -268,7 +333,7 @@ async function runSeed(options) {
|
|
|
268
333
|
await seedDemoData(db);
|
|
269
334
|
}
|
|
270
335
|
if (file) {
|
|
271
|
-
await seedFromFile(db, file);
|
|
336
|
+
await seedFromFile(db, file, { upsert: options.upsert });
|
|
272
337
|
}
|
|
273
338
|
}
|
|
274
339
|
catch (err) {
|
|
@@ -312,18 +377,56 @@ function sanitizeSeedData(value, sanitizeHtml) {
|
|
|
312
377
|
}
|
|
313
378
|
return value;
|
|
314
379
|
}
|
|
315
|
-
export async function createSeedDocument(db, userId, doc) {
|
|
380
|
+
export async function createSeedDocument(db, userId, doc, options = {}) {
|
|
316
381
|
const { extractPlainText, hashContent, sanitizeHtml } = await import('@actuate-media/cms-core');
|
|
317
382
|
const data = sanitizeSeedData(doc.data, sanitizeHtml);
|
|
318
383
|
const serialized = JSON.stringify(data);
|
|
319
384
|
const plainText = extractPlainText(serialized);
|
|
320
385
|
const contentHash = await hashContent(serialized);
|
|
386
|
+
const slug = typeof data.slug === 'string' ? data.slug : null;
|
|
387
|
+
const title = typeof data.title === 'string' ? data.title : null;
|
|
388
|
+
// Upsert key: collection + slug. Slugless documents can't be re-identified,
|
|
389
|
+
// so they always insert (same as a plain seed run).
|
|
390
|
+
const existing = options.upsert && slug
|
|
391
|
+
? await db.document.findFirst({
|
|
392
|
+
where: { collection: doc.collection, slug, deletedAt: null },
|
|
393
|
+
select: { id: true, status: true, publishedAt: true },
|
|
394
|
+
})
|
|
395
|
+
: null;
|
|
396
|
+
if (existing) {
|
|
397
|
+
await db.$transaction(async (tx) => {
|
|
398
|
+
await tx.document.update({
|
|
399
|
+
where: { id: existing.id },
|
|
400
|
+
data: {
|
|
401
|
+
title,
|
|
402
|
+
data,
|
|
403
|
+
status: doc.status,
|
|
404
|
+
// Stamp publishedAt only on the transition into PUBLISHED.
|
|
405
|
+
publishedAt: doc.status === 'PUBLISHED'
|
|
406
|
+
? (existing.publishedAt ?? new Date())
|
|
407
|
+
: existing.publishedAt,
|
|
408
|
+
updatedById: userId,
|
|
409
|
+
plainText,
|
|
410
|
+
contentHash,
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
await tx.version.create({
|
|
414
|
+
data: {
|
|
415
|
+
documentId: existing.id,
|
|
416
|
+
data,
|
|
417
|
+
changedById: userId,
|
|
418
|
+
changeType: 'UPDATE',
|
|
419
|
+
},
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
return 'updated';
|
|
423
|
+
}
|
|
321
424
|
await db.$transaction(async (tx) => {
|
|
322
425
|
const created = await tx.document.create({
|
|
323
426
|
data: {
|
|
324
427
|
collection: doc.collection,
|
|
325
|
-
title
|
|
326
|
-
slug
|
|
428
|
+
title,
|
|
429
|
+
slug,
|
|
327
430
|
data,
|
|
328
431
|
status: doc.status,
|
|
329
432
|
publishedAt: doc.status === 'PUBLISHED' ? new Date() : null,
|
|
@@ -342,6 +445,7 @@ export async function createSeedDocument(db, userId, doc) {
|
|
|
342
445
|
},
|
|
343
446
|
});
|
|
344
447
|
});
|
|
448
|
+
return 'created';
|
|
345
449
|
}
|
|
346
450
|
async function seedDemoData(db) {
|
|
347
451
|
const spinner = ora('Seeding demo data…').start();
|
|
@@ -407,7 +511,7 @@ async function seedDemoData(db) {
|
|
|
407
511
|
logger.info(` Navigations: ${navigationsCreated}`);
|
|
408
512
|
logger.info(` Users: ${usersCreated} (+ existing admin)`);
|
|
409
513
|
}
|
|
410
|
-
async function seedFromFile(db, filePath) {
|
|
514
|
+
async function seedFromFile(db, filePath, options = {}) {
|
|
411
515
|
if (!existsSync(filePath)) {
|
|
412
516
|
logger.error(`File not found: ${filePath}`);
|
|
413
517
|
process.exit(1);
|
|
@@ -428,19 +532,38 @@ async function seedFromFile(db, filePath) {
|
|
|
428
532
|
const adminUser = await ensureSeedAdmin(db);
|
|
429
533
|
const userId = adminUser.id;
|
|
430
534
|
const normalized = normalizeSeedPayload(seedData);
|
|
535
|
+
// Forms have a stricter shape than generic documents (data.status gates the
|
|
536
|
+
// public endpoints; fields need key/label/type). Fail loudly BEFORE writing
|
|
537
|
+
// anything — a malformed form seed used to insert fine and then 404 on
|
|
538
|
+
// /api/cms/public/forms/:slug with no hint why.
|
|
539
|
+
const formErrors = validateFormSeeds(normalized.documents);
|
|
540
|
+
if (formErrors.length > 0) {
|
|
541
|
+
spinner.fail('Form seed validation failed — nothing was written:');
|
|
542
|
+
for (const error of formErrors) {
|
|
543
|
+
logger.error(` ${error}`);
|
|
544
|
+
}
|
|
545
|
+
logger.info(' Expected shape: { "forms": [{ "status": "PUBLISHED", "data": { "name", "slug", "status": "active", "fields": [{ "key", "label", "type", … }] } }] }');
|
|
546
|
+
process.exit(1);
|
|
547
|
+
}
|
|
431
548
|
const { updateGlobal } = await import('@actuate-media/cms-core');
|
|
432
549
|
const ctx = { userId, role: 'ADMIN', db };
|
|
433
|
-
let
|
|
550
|
+
let createdCount = 0;
|
|
551
|
+
let updatedCount = 0;
|
|
434
552
|
for (const doc of normalized.documents) {
|
|
435
|
-
await createSeedDocument(db, userId, doc);
|
|
436
|
-
|
|
553
|
+
const result = await createSeedDocument(db, userId, doc, options);
|
|
554
|
+
if (result === 'updated')
|
|
555
|
+
updatedCount++;
|
|
556
|
+
else
|
|
557
|
+
createdCount++;
|
|
437
558
|
}
|
|
438
559
|
let globalCount = 0;
|
|
439
560
|
for (const global of normalized.globals) {
|
|
440
561
|
await updateGlobal(global.slug, global.data, ctx);
|
|
441
562
|
globalCount++;
|
|
442
563
|
}
|
|
443
|
-
spinner.succeed(
|
|
564
|
+
spinner.succeed(options.upsert
|
|
565
|
+
? `Seeded from ${filePath}: ${createdCount} created, ${updatedCount} updated, ${globalCount} globals.`
|
|
566
|
+
: `Seeded ${createdCount} documents and ${globalCount} globals from ${filePath}.`);
|
|
444
567
|
}
|
|
445
568
|
export function registerSeedCommand(program) {
|
|
446
569
|
program
|
|
@@ -449,12 +572,14 @@ export function registerSeedCommand(program) {
|
|
|
449
572
|
.option('--demo', 'Seed demo content (pages, posts, forms, users)')
|
|
450
573
|
.option('--file <path>', 'Seed from a JSON, JavaScript, or TypeScript file')
|
|
451
574
|
.option('--reset', 'Clear existing data before seeding')
|
|
575
|
+
.option('--upsert', 'Update existing documents matched by collection + slug instead of inserting duplicates')
|
|
452
576
|
.action(runSeed);
|
|
453
577
|
program
|
|
454
578
|
.command('populate')
|
|
455
579
|
.description('Populate the database from actuate.seed.json or a custom seed file')
|
|
456
580
|
.option('--file <path>', 'Seed from a JSON, JavaScript, or TypeScript file')
|
|
457
581
|
.option('--reset', 'Clear existing data before seeding')
|
|
582
|
+
.option('--upsert', 'Update existing documents matched by collection + slug instead of inserting duplicates')
|
|
458
583
|
.action(runSeed);
|
|
459
584
|
}
|
|
460
585
|
//# sourceMappingURL=seed.js.map
|