@actuate-media/cli 0.4.0 → 0.4.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +21 -10
- package/CHANGELOG.md +34 -0
- package/dist/__tests__/deployment-diagnostics.test.js +40 -0
- package/dist/__tests__/deployment-diagnostics.test.js.map +1 -1
- package/dist/__tests__/init.test.js.map +1 -1
- package/dist/__tests__/schema-fragment.test.js +1 -1
- package/dist/__tests__/schema-fragment.test.js.map +1 -1
- package/dist/__tests__/seed.test.js.map +1 -1
- package/dist/commands/db-init.d.ts +2 -2
- package/dist/commands/db-init.d.ts.map +1 -1
- package/dist/commands/db-init.js +32 -32
- package/dist/commands/db-init.js.map +1 -1
- package/dist/commands/db-status.d.ts +1 -1
- package/dist/commands/db-status.d.ts.map +1 -1
- package/dist/commands/db-status.js +33 -33
- package/dist/commands/db-status.js.map +1 -1
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +55 -38
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/export.d.ts +1 -1
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +32 -32
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/generate.d.ts +1 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +8 -8
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/import.d.ts +1 -1
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +55 -58
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrate.d.ts +1 -1
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +18 -24
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/seed.d.ts +1 -1
- package/dist/commands/seed.d.ts.map +1 -1
- package/dist/commands/seed.js +156 -157
- package/dist/commands/seed.js.map +1 -1
- package/dist/commands/update-check.d.ts +1 -1
- package/dist/commands/update-check.d.ts.map +1 -1
- package/dist/commands/update-check.js +34 -27
- package/dist/commands/update-check.js.map +1 -1
- package/dist/commands/upgrade.d.ts +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +41 -34
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/deployment/diagnostics.d.ts +2 -0
- package/dist/deployment/diagnostics.d.ts.map +1 -1
- package/dist/deployment/diagnostics.js +50 -1
- package/dist/deployment/diagnostics.js.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +5 -5
- package/dist/utils/logger.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/deployment-diagnostics.test.ts +100 -50
- package/src/__tests__/init.test.ts +17 -17
- package/src/__tests__/schema-fragment.test.ts +29 -25
- package/src/__tests__/seed.test.ts +25 -25
- package/src/commands/db-init.ts +59 -59
- package/src/commands/db-status.ts +70 -68
- package/src/commands/doctor.ts +110 -86
- package/src/commands/export.ts +65 -75
- package/src/commands/generate.ts +14 -16
- package/src/commands/import.ts +125 -140
- package/src/commands/init.ts +14 -14
- package/src/commands/migrate.ts +29 -35
- package/src/commands/seed.ts +294 -300
- package/src/commands/update-check.ts +77 -72
- package/src/commands/upgrade.ts +92 -85
- package/src/deployment/diagnostics.ts +124 -61
- package/src/index.ts +30 -30
- package/src/utils/logger.ts +10 -10
|
@@ -1,120 +1,122 @@
|
|
|
1
|
-
import { Command } from
|
|
2
|
-
import { execSync } from
|
|
3
|
-
import { readFile, access } from
|
|
4
|
-
import { resolve } from
|
|
5
|
-
import ora from
|
|
6
|
-
import chalk from
|
|
7
|
-
import { logger } from
|
|
8
|
-
import { REQUIRED_CMS_MODELS } from
|
|
1
|
+
import { Command } from 'commander'
|
|
2
|
+
import { execSync } from 'node:child_process'
|
|
3
|
+
import { readFile, access } from 'node:fs/promises'
|
|
4
|
+
import { resolve } from 'node:path'
|
|
5
|
+
import ora from 'ora'
|
|
6
|
+
import chalk from 'chalk'
|
|
7
|
+
import { logger } from '../utils/logger.js'
|
|
8
|
+
import { REQUIRED_CMS_MODELS } from '../deployment/diagnostics.js'
|
|
9
9
|
|
|
10
|
-
const CMS_SCHEMA_MARKER =
|
|
10
|
+
const CMS_SCHEMA_MARKER = '// ── Actuate CMS models'
|
|
11
11
|
|
|
12
12
|
async function fileExists(filePath: string): Promise<boolean> {
|
|
13
13
|
try {
|
|
14
|
-
await access(filePath)
|
|
15
|
-
return true
|
|
14
|
+
await access(filePath)
|
|
15
|
+
return true
|
|
16
16
|
} catch {
|
|
17
|
-
return false
|
|
17
|
+
return false
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function registerDbStatusCommand(program: Command): void {
|
|
22
22
|
program
|
|
23
|
-
.command(
|
|
24
|
-
.description(
|
|
25
|
-
.option(
|
|
23
|
+
.command('db:status')
|
|
24
|
+
.description('Check which Actuate CMS models are present in your Prisma schema')
|
|
25
|
+
.option('--schema <path>', 'Path to schema.prisma', 'prisma/schema.prisma')
|
|
26
26
|
.action(async (opts: { schema: string }) => {
|
|
27
|
-
const schemaPath = resolve(process.cwd(), opts.schema)
|
|
27
|
+
const schemaPath = resolve(process.cwd(), opts.schema)
|
|
28
28
|
|
|
29
29
|
if (!(await fileExists(schemaPath))) {
|
|
30
|
-
logger.error(`Schema file not found at ${schemaPath}`)
|
|
31
|
-
logger.info(
|
|
32
|
-
process.exitCode = 1
|
|
33
|
-
return
|
|
30
|
+
logger.error(`Schema file not found at ${schemaPath}`)
|
|
31
|
+
logger.info('Run `npx prisma init` first, or specify --schema <path>.')
|
|
32
|
+
process.exitCode = 1
|
|
33
|
+
return
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const spinner = ora(
|
|
36
|
+
const spinner = ora('Checking schema...').start()
|
|
37
37
|
|
|
38
|
-
let content: string
|
|
38
|
+
let content: string
|
|
39
39
|
try {
|
|
40
|
-
content = await readFile(schemaPath,
|
|
40
|
+
content = await readFile(schemaPath, 'utf-8')
|
|
41
41
|
} catch (err) {
|
|
42
|
-
spinner.fail(
|
|
43
|
-
logger.error(err instanceof Error ? err.message : String(err))
|
|
44
|
-
process.exitCode = 1
|
|
45
|
-
return
|
|
42
|
+
spinner.fail('Failed to read schema file.')
|
|
43
|
+
logger.error(err instanceof Error ? err.message : String(err))
|
|
44
|
+
process.exitCode = 1
|
|
45
|
+
return
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
spinner.stop()
|
|
48
|
+
spinner.stop()
|
|
49
49
|
|
|
50
|
-
const hasMarker = content.includes(CMS_SCHEMA_MARKER)
|
|
51
|
-
const modelRegex = /^model\s+(\w+)\s*\{/gm
|
|
52
|
-
const schemaModels = new Set<string>()
|
|
53
|
-
let match
|
|
50
|
+
const hasMarker = content.includes(CMS_SCHEMA_MARKER)
|
|
51
|
+
const modelRegex = /^model\s+(\w+)\s*\{/gm
|
|
52
|
+
const schemaModels = new Set<string>()
|
|
53
|
+
let match
|
|
54
54
|
while ((match = modelRegex.exec(content)) !== null) {
|
|
55
|
-
schemaModels.add(match[1]!)
|
|
55
|
+
schemaModels.add(match[1]!)
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
console.log()
|
|
59
|
-
console.log(chalk.bold(
|
|
60
|
-
console.log(chalk.dim(
|
|
61
|
-
console.log()
|
|
58
|
+
console.log()
|
|
59
|
+
console.log(chalk.bold(' Actuate CMS Model Status'))
|
|
60
|
+
console.log(chalk.dim(' ─────────────────────────────────'))
|
|
61
|
+
console.log()
|
|
62
62
|
|
|
63
|
-
let present = 0
|
|
64
|
-
let missing = 0
|
|
63
|
+
let present = 0
|
|
64
|
+
let missing = 0
|
|
65
65
|
|
|
66
66
|
for (const model of REQUIRED_CMS_MODELS) {
|
|
67
67
|
if (schemaModels.has(model)) {
|
|
68
|
-
console.log(` ${chalk.green(
|
|
69
|
-
present
|
|
68
|
+
console.log(` ${chalk.green('✓')} ${model}`)
|
|
69
|
+
present++
|
|
70
70
|
} else {
|
|
71
|
-
console.log(` ${chalk.red(
|
|
72
|
-
missing
|
|
71
|
+
console.log(` ${chalk.red('✗')} ${model} ${chalk.dim('— missing')}`)
|
|
72
|
+
missing++
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
console.log()
|
|
77
|
-
console.log(chalk.dim(
|
|
78
|
-
console.log(
|
|
76
|
+
console.log()
|
|
77
|
+
console.log(chalk.dim(' ─────────────────────────────────'))
|
|
78
|
+
console.log(
|
|
79
|
+
` ${chalk.green(present)} present, ${missing > 0 ? chalk.red(missing) : chalk.green(missing)} missing`,
|
|
80
|
+
)
|
|
79
81
|
|
|
80
82
|
if (!hasMarker) {
|
|
81
|
-
console.log()
|
|
82
|
-
logger.warn(
|
|
83
|
-
logger.info(
|
|
83
|
+
console.log()
|
|
84
|
+
logger.warn('CMS schema marker not found. Models may have been added manually.')
|
|
85
|
+
logger.info('Run `actuate db:init` to add CMS models with proper markers.')
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
if (missing > 0) {
|
|
87
|
-
console.log()
|
|
88
|
-
logger.info(
|
|
89
|
+
console.log()
|
|
90
|
+
logger.info('Run `actuate db:init` to add missing models.')
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
let dbConnected = false
|
|
93
|
+
let dbConnected = false
|
|
92
94
|
try {
|
|
93
|
-
spinner.start(
|
|
94
|
-
execSync(
|
|
95
|
-
input:
|
|
96
|
-
stdio: [
|
|
95
|
+
spinner.start('Checking database connection...')
|
|
96
|
+
execSync('npx prisma db execute --stdin --schema ' + JSON.stringify(schemaPath), {
|
|
97
|
+
input: 'SELECT 1;',
|
|
98
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
97
99
|
cwd: process.cwd(),
|
|
98
|
-
})
|
|
99
|
-
spinner.succeed(
|
|
100
|
-
dbConnected = true
|
|
100
|
+
})
|
|
101
|
+
spinner.succeed('Database connection OK.')
|
|
102
|
+
dbConnected = true
|
|
101
103
|
} catch {
|
|
102
|
-
spinner.warn(
|
|
104
|
+
spinner.warn('Could not connect to database. Check DATABASE_URL.')
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
if (dbConnected && missing === 0) {
|
|
106
108
|
try {
|
|
107
|
-
spinner.start(
|
|
108
|
-
spinner.stop()
|
|
109
|
-
execSync(
|
|
110
|
-
stdio:
|
|
109
|
+
spinner.start('Checking migration status...')
|
|
110
|
+
spinner.stop()
|
|
111
|
+
execSync('npx prisma migrate status', {
|
|
112
|
+
stdio: 'inherit',
|
|
111
113
|
cwd: process.cwd(),
|
|
112
|
-
})
|
|
114
|
+
})
|
|
113
115
|
} catch {
|
|
114
|
-
logger.warn(
|
|
116
|
+
logger.warn('Could not check migration status.')
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
console.log()
|
|
119
|
-
})
|
|
120
|
+
console.log()
|
|
121
|
+
})
|
|
120
122
|
}
|
package/src/commands/doctor.ts
CHANGED
|
@@ -1,159 +1,183 @@
|
|
|
1
|
-
import { Command } from
|
|
2
|
-
import { access, readdir, readFile } from
|
|
3
|
-
import { resolve } from
|
|
4
|
-
import chalk from
|
|
1
|
+
import { Command } from 'commander'
|
|
2
|
+
import { access, readdir, readFile } from 'node:fs/promises'
|
|
3
|
+
import { resolve } from 'node:path'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
5
|
import {
|
|
6
6
|
buildDeploymentManifest,
|
|
7
7
|
createDiagnosticReport,
|
|
8
8
|
detectPackageManager,
|
|
9
9
|
type DiagnosticReport,
|
|
10
|
-
} from
|
|
10
|
+
} from '../deployment/diagnostics.js'
|
|
11
11
|
|
|
12
12
|
async function fileExists(path: string): Promise<boolean> {
|
|
13
13
|
try {
|
|
14
|
-
await access(path)
|
|
15
|
-
return true
|
|
14
|
+
await access(path)
|
|
15
|
+
return true
|
|
16
16
|
} catch {
|
|
17
|
-
return false
|
|
17
|
+
return false
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async function readSchemaModels(schemaPath: string): Promise<Set<string>> {
|
|
22
|
-
if (!(await fileExists(schemaPath))) return new Set()
|
|
23
|
-
const schema = await readFile(schemaPath,
|
|
24
|
-
const models = new Set<string>()
|
|
25
|
-
const modelRegex = /^model\s+(\w+)\s*\{/gm
|
|
26
|
-
let match
|
|
22
|
+
if (!(await fileExists(schemaPath))) return new Set()
|
|
23
|
+
const schema = await readFile(schemaPath, 'utf-8')
|
|
24
|
+
const models = new Set<string>()
|
|
25
|
+
const modelRegex = /^model\s+(\w+)\s*\{/gm
|
|
26
|
+
let match
|
|
27
27
|
while ((match = modelRegex.exec(schema)) !== null) {
|
|
28
|
-
models.add(match[1]!)
|
|
28
|
+
models.add(match[1]!)
|
|
29
29
|
}
|
|
30
|
-
return models
|
|
30
|
+
return models
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
async function readSchemaContent(schemaPath: string): Promise<string> {
|
|
34
|
-
if (!(await fileExists(schemaPath))) return
|
|
35
|
-
return readFile(schemaPath,
|
|
34
|
+
if (!(await fileExists(schemaPath))) return ''
|
|
35
|
+
return readFile(schemaPath, 'utf-8')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function readOptionalFile(path: string): Promise<string> {
|
|
39
|
+
if (!(await fileExists(path))) return ''
|
|
40
|
+
return readFile(path, 'utf-8')
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
async function detectProjectPackageManager(): Promise<string> {
|
|
39
|
-
const entries = new Set(await readdir(process.cwd()))
|
|
40
|
-
return detectPackageManager(entries)
|
|
44
|
+
const entries = new Set(await readdir(process.cwd()))
|
|
45
|
+
return detectPackageManager(entries)
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
function printReport(title: string, report: DiagnosticReport): void {
|
|
44
|
-
console.log()
|
|
45
|
-
console.log(chalk.bold(title))
|
|
46
|
-
console.log(chalk.dim(
|
|
49
|
+
console.log()
|
|
50
|
+
console.log(chalk.bold(title))
|
|
51
|
+
console.log(chalk.dim('─────────────────────────────────'))
|
|
47
52
|
for (const check of report.checks) {
|
|
48
|
-
const icon =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
const icon =
|
|
54
|
+
check.status === 'pass'
|
|
55
|
+
? chalk.green('PASS')
|
|
56
|
+
: check.status === 'warn'
|
|
57
|
+
? chalk.yellow('WARN')
|
|
58
|
+
: chalk.red('FAIL')
|
|
59
|
+
console.log(`${icon} ${check.label}: ${check.message}`)
|
|
60
|
+
if (check.fix) console.log(chalk.dim(` Fix: ${check.fix}`))
|
|
61
|
+
if (check.docs) console.log(chalk.dim(` Docs: ${check.docs}`))
|
|
52
62
|
}
|
|
53
|
-
console.log(chalk.dim(
|
|
54
|
-
console.log(`Status: ${report.status.toUpperCase()}`)
|
|
55
|
-
console.log()
|
|
63
|
+
console.log(chalk.dim('─────────────────────────────────'))
|
|
64
|
+
console.log(`Status: ${report.status.toUpperCase()}`)
|
|
65
|
+
console.log()
|
|
56
66
|
}
|
|
57
67
|
|
|
58
|
-
async function buildReport(
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
async function buildReport(
|
|
69
|
+
schemaPath: string,
|
|
70
|
+
configPath: string,
|
|
71
|
+
mode: 'doctor' | 'deploy' = 'doctor',
|
|
72
|
+
) {
|
|
73
|
+
const resolvedSchema = resolve(process.cwd(), schemaPath)
|
|
74
|
+
const resolvedConfig = resolve(process.cwd(), configPath)
|
|
75
|
+
const [schemaModels, schemaContent, configContent, packageManager] = await Promise.all([
|
|
61
76
|
readSchemaModels(resolvedSchema),
|
|
62
77
|
readSchemaContent(resolvedSchema),
|
|
78
|
+
readOptionalFile(resolvedConfig),
|
|
63
79
|
detectProjectPackageManager(),
|
|
64
|
-
])
|
|
80
|
+
])
|
|
65
81
|
|
|
66
82
|
return createDiagnosticReport({
|
|
67
83
|
schemaModels,
|
|
68
84
|
schemaContent,
|
|
85
|
+
configContent,
|
|
69
86
|
env: process.env,
|
|
70
87
|
packageManager,
|
|
71
88
|
schemaPath,
|
|
72
89
|
mode,
|
|
73
|
-
})
|
|
90
|
+
})
|
|
74
91
|
}
|
|
75
92
|
|
|
76
93
|
export function registerDoctorCommand(program: Command): void {
|
|
77
94
|
program
|
|
78
|
-
.command(
|
|
79
|
-
.description(
|
|
80
|
-
.option(
|
|
81
|
-
.option(
|
|
82
|
-
.
|
|
83
|
-
|
|
95
|
+
.command('doctor')
|
|
96
|
+
.description('Run AI-friendly preflight checks for an Actuate CMS project')
|
|
97
|
+
.option('--schema <path>', 'Path to schema.prisma', 'prisma/schema.prisma')
|
|
98
|
+
.option('--config <path>', 'Path to actuate.config.ts', 'actuate.config.ts')
|
|
99
|
+
.option('--json', 'Print machine-readable JSON')
|
|
100
|
+
.action(async (opts: { schema: string; config: string; json?: boolean }) => {
|
|
101
|
+
const report = await buildReport(opts.schema, opts.config, 'doctor')
|
|
84
102
|
if (opts.json) {
|
|
85
|
-
console.log(JSON.stringify(report, null, 2))
|
|
103
|
+
console.log(JSON.stringify(report, null, 2))
|
|
86
104
|
} else {
|
|
87
|
-
printReport(
|
|
105
|
+
printReport('Actuate Doctor', report)
|
|
88
106
|
}
|
|
89
|
-
if (report.status ===
|
|
90
|
-
})
|
|
107
|
+
if (report.status === 'fail') process.exitCode = 1
|
|
108
|
+
})
|
|
91
109
|
}
|
|
92
110
|
|
|
93
111
|
export function registerDeployCheckCommand(program: Command): void {
|
|
94
112
|
program
|
|
95
|
-
.command(
|
|
96
|
-
.description(
|
|
97
|
-
.option(
|
|
98
|
-
.option(
|
|
99
|
-
.
|
|
100
|
-
|
|
113
|
+
.command('deploy:check')
|
|
114
|
+
.description('Check production deployment readiness for Actuate CMS')
|
|
115
|
+
.option('--schema <path>', 'Path to schema.prisma', 'prisma/schema.prisma')
|
|
116
|
+
.option('--config <path>', 'Path to actuate.config.ts', 'actuate.config.ts')
|
|
117
|
+
.option('--json', 'Print machine-readable JSON')
|
|
118
|
+
.action(async (opts: { schema: string; config: string; json?: boolean }) => {
|
|
119
|
+
const report = await buildReport(opts.schema, opts.config, 'deploy')
|
|
101
120
|
if (opts.json) {
|
|
102
|
-
console.log(JSON.stringify({ ...report, manifest: buildDeploymentManifest() }, null, 2))
|
|
121
|
+
console.log(JSON.stringify({ ...report, manifest: buildDeploymentManifest() }, null, 2))
|
|
103
122
|
} else {
|
|
104
|
-
printReport(
|
|
105
|
-
console.log(chalk.dim(
|
|
123
|
+
printReport('Actuate Deploy Check', report)
|
|
124
|
+
console.log(chalk.dim('Run `actuate verify --full` after deployment succeeds.'))
|
|
106
125
|
}
|
|
107
|
-
if (report.status ===
|
|
108
|
-
})
|
|
126
|
+
if (report.status === 'fail') process.exitCode = 1
|
|
127
|
+
})
|
|
109
128
|
}
|
|
110
129
|
|
|
111
130
|
export function registerVerifyCommand(program: Command): void {
|
|
112
131
|
program
|
|
113
|
-
.command(
|
|
114
|
-
.description(
|
|
115
|
-
.option(
|
|
116
|
-
.option(
|
|
117
|
-
.option(
|
|
132
|
+
.command('verify')
|
|
133
|
+
.description('Verify an installed or deployed Actuate CMS project')
|
|
134
|
+
.option('--full', 'Run the full verification checklist')
|
|
135
|
+
.option('--url <origin>', 'Deployed site origin to verify, for example https://example.com')
|
|
136
|
+
.option('--json', 'Print the deployment manifest as JSON')
|
|
118
137
|
.action(async (opts: { full?: boolean; url?: string; json?: boolean }) => {
|
|
119
|
-
const manifest = buildDeploymentManifest()
|
|
138
|
+
const manifest = buildDeploymentManifest()
|
|
120
139
|
if (opts.json) {
|
|
121
|
-
console.log(JSON.stringify(manifest, null, 2))
|
|
122
|
-
return
|
|
140
|
+
console.log(JSON.stringify(manifest, null, 2))
|
|
141
|
+
return
|
|
123
142
|
}
|
|
124
143
|
|
|
125
|
-
console.log()
|
|
126
|
-
console.log(chalk.bold(opts.full ?
|
|
127
|
-
console.log(chalk.dim(
|
|
128
|
-
console.log(`PASS Manifest generated for ${manifest.packageScope} packages.`)
|
|
144
|
+
console.log()
|
|
145
|
+
console.log(chalk.bold(opts.full ? 'Actuate Full Verification' : 'Actuate Verification'))
|
|
146
|
+
console.log(chalk.dim('─────────────────────────────────'))
|
|
147
|
+
console.log(`PASS Manifest generated for ${manifest.packageScope} packages.`)
|
|
129
148
|
if (!opts.url) {
|
|
130
|
-
console.log(
|
|
131
|
-
console.log(
|
|
132
|
-
|
|
133
|
-
|
|
149
|
+
console.log('WARN No --url provided, so remote health/admin endpoints were not checked.')
|
|
150
|
+
console.log(
|
|
151
|
+
chalk.dim('Run `actuate verify --full --url https://your-site.com` after deployment.'),
|
|
152
|
+
)
|
|
153
|
+
console.log()
|
|
154
|
+
return
|
|
134
155
|
}
|
|
135
156
|
|
|
136
|
-
const origin = opts.url.replace(/\/$/,
|
|
137
|
-
const healthUrl = `${origin}${manifest.routes.apiHealth}
|
|
138
|
-
const adminUrl = `${origin}${manifest.routes.adminDefault}
|
|
139
|
-
let failed = false
|
|
157
|
+
const origin = opts.url.replace(/\/$/, '')
|
|
158
|
+
const healthUrl = `${origin}${manifest.routes.apiHealth}`
|
|
159
|
+
const adminUrl = `${origin}${manifest.routes.adminDefault}`
|
|
160
|
+
let failed = false
|
|
140
161
|
|
|
141
|
-
for (const [label, url] of [
|
|
162
|
+
for (const [label, url] of [
|
|
163
|
+
['Health', healthUrl],
|
|
164
|
+
['Admin', adminUrl],
|
|
165
|
+
] as const) {
|
|
142
166
|
try {
|
|
143
|
-
const response = await fetch(url, { method: 'GET' })
|
|
167
|
+
const response = await fetch(url, { method: 'GET' })
|
|
144
168
|
if (response.ok || response.status === 302 || response.status === 401) {
|
|
145
|
-
console.log(`PASS ${label} route responded at ${url}.`)
|
|
169
|
+
console.log(`PASS ${label} route responded at ${url}.`)
|
|
146
170
|
} else {
|
|
147
|
-
failed = true
|
|
148
|
-
console.log(`FAIL ${label} route returned HTTP ${response.status} at ${url}.`)
|
|
171
|
+
failed = true
|
|
172
|
+
console.log(`FAIL ${label} route returned HTTP ${response.status} at ${url}.`)
|
|
149
173
|
}
|
|
150
174
|
} catch (error) {
|
|
151
|
-
failed = true
|
|
152
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
153
|
-
console.log(`FAIL ${label} route could not be reached at ${url}: ${message}`)
|
|
175
|
+
failed = true
|
|
176
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
177
|
+
console.log(`FAIL ${label} route could not be reached at ${url}: ${message}`)
|
|
154
178
|
}
|
|
155
179
|
}
|
|
156
|
-
console.log()
|
|
157
|
-
if (failed) process.exitCode = 1
|
|
158
|
-
})
|
|
180
|
+
console.log()
|
|
181
|
+
if (failed) process.exitCode = 1
|
|
182
|
+
})
|
|
159
183
|
}
|