@actuate-media/cli 0.4.1 → 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 +28 -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 +48 -41
- 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.map +1 -1
- package/dist/deployment/diagnostics.js +7 -2
- 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 +68 -60
- 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 +102 -88
- 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 +86 -72
- 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,74 +1,83 @@
|
|
|
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
36
|
}
|
|
37
37
|
|
|
38
38
|
async function readOptionalFile(path: string): Promise<string> {
|
|
39
|
-
if (!(await fileExists(path))) return
|
|
40
|
-
return readFile(path,
|
|
39
|
+
if (!(await fileExists(path))) return ''
|
|
40
|
+
return readFile(path, 'utf-8')
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
async function detectProjectPackageManager(): Promise<string> {
|
|
44
|
-
const entries = new Set(await readdir(process.cwd()))
|
|
45
|
-
return detectPackageManager(entries)
|
|
44
|
+
const entries = new Set(await readdir(process.cwd()))
|
|
45
|
+
return detectPackageManager(entries)
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function printReport(title: string, report: DiagnosticReport): void {
|
|
49
|
-
console.log()
|
|
50
|
-
console.log(chalk.bold(title))
|
|
51
|
-
console.log(chalk.dim(
|
|
49
|
+
console.log()
|
|
50
|
+
console.log(chalk.bold(title))
|
|
51
|
+
console.log(chalk.dim('─────────────────────────────────'))
|
|
52
52
|
for (const check of report.checks) {
|
|
53
|
-
const icon =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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}`))
|
|
57
62
|
}
|
|
58
|
-
console.log(chalk.dim(
|
|
59
|
-
console.log(`Status: ${report.status.toUpperCase()}`)
|
|
60
|
-
console.log()
|
|
63
|
+
console.log(chalk.dim('─────────────────────────────────'))
|
|
64
|
+
console.log(`Status: ${report.status.toUpperCase()}`)
|
|
65
|
+
console.log()
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
async function buildReport(
|
|
64
|
-
|
|
65
|
-
|
|
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)
|
|
66
75
|
const [schemaModels, schemaContent, configContent, packageManager] = await Promise.all([
|
|
67
76
|
readSchemaModels(resolvedSchema),
|
|
68
77
|
readSchemaContent(resolvedSchema),
|
|
69
78
|
readOptionalFile(resolvedConfig),
|
|
70
79
|
detectProjectPackageManager(),
|
|
71
|
-
])
|
|
80
|
+
])
|
|
72
81
|
|
|
73
82
|
return createDiagnosticReport({
|
|
74
83
|
schemaModels,
|
|
@@ -78,92 +87,97 @@ async function buildReport(schemaPath: string, configPath: string, mode: "doctor
|
|
|
78
87
|
packageManager,
|
|
79
88
|
schemaPath,
|
|
80
89
|
mode,
|
|
81
|
-
})
|
|
90
|
+
})
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
export function registerDoctorCommand(program: Command): void {
|
|
85
94
|
program
|
|
86
|
-
.command(
|
|
87
|
-
.description(
|
|
88
|
-
.option(
|
|
89
|
-
.option(
|
|
90
|
-
.option(
|
|
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')
|
|
91
100
|
.action(async (opts: { schema: string; config: string; json?: boolean }) => {
|
|
92
|
-
const report = await buildReport(opts.schema, opts.config,
|
|
101
|
+
const report = await buildReport(opts.schema, opts.config, 'doctor')
|
|
93
102
|
if (opts.json) {
|
|
94
|
-
console.log(JSON.stringify(report, null, 2))
|
|
103
|
+
console.log(JSON.stringify(report, null, 2))
|
|
95
104
|
} else {
|
|
96
|
-
printReport(
|
|
105
|
+
printReport('Actuate Doctor', report)
|
|
97
106
|
}
|
|
98
|
-
if (report.status ===
|
|
99
|
-
})
|
|
107
|
+
if (report.status === 'fail') process.exitCode = 1
|
|
108
|
+
})
|
|
100
109
|
}
|
|
101
110
|
|
|
102
111
|
export function registerDeployCheckCommand(program: Command): void {
|
|
103
112
|
program
|
|
104
|
-
.command(
|
|
105
|
-
.description(
|
|
106
|
-
.option(
|
|
107
|
-
.option(
|
|
108
|
-
.option(
|
|
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')
|
|
109
118
|
.action(async (opts: { schema: string; config: string; json?: boolean }) => {
|
|
110
|
-
const report = await buildReport(opts.schema, opts.config,
|
|
119
|
+
const report = await buildReport(opts.schema, opts.config, 'deploy')
|
|
111
120
|
if (opts.json) {
|
|
112
|
-
console.log(JSON.stringify({ ...report, manifest: buildDeploymentManifest() }, null, 2))
|
|
121
|
+
console.log(JSON.stringify({ ...report, manifest: buildDeploymentManifest() }, null, 2))
|
|
113
122
|
} else {
|
|
114
|
-
printReport(
|
|
115
|
-
console.log(chalk.dim(
|
|
123
|
+
printReport('Actuate Deploy Check', report)
|
|
124
|
+
console.log(chalk.dim('Run `actuate verify --full` after deployment succeeds.'))
|
|
116
125
|
}
|
|
117
|
-
if (report.status ===
|
|
118
|
-
})
|
|
126
|
+
if (report.status === 'fail') process.exitCode = 1
|
|
127
|
+
})
|
|
119
128
|
}
|
|
120
129
|
|
|
121
130
|
export function registerVerifyCommand(program: Command): void {
|
|
122
131
|
program
|
|
123
|
-
.command(
|
|
124
|
-
.description(
|
|
125
|
-
.option(
|
|
126
|
-
.option(
|
|
127
|
-
.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')
|
|
128
137
|
.action(async (opts: { full?: boolean; url?: string; json?: boolean }) => {
|
|
129
|
-
const manifest = buildDeploymentManifest()
|
|
138
|
+
const manifest = buildDeploymentManifest()
|
|
130
139
|
if (opts.json) {
|
|
131
|
-
console.log(JSON.stringify(manifest, null, 2))
|
|
132
|
-
return
|
|
140
|
+
console.log(JSON.stringify(manifest, null, 2))
|
|
141
|
+
return
|
|
133
142
|
}
|
|
134
143
|
|
|
135
|
-
console.log()
|
|
136
|
-
console.log(chalk.bold(opts.full ?
|
|
137
|
-
console.log(chalk.dim(
|
|
138
|
-
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.`)
|
|
139
148
|
if (!opts.url) {
|
|
140
|
-
console.log(
|
|
141
|
-
console.log(
|
|
142
|
-
|
|
143
|
-
|
|
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
|
|
144
155
|
}
|
|
145
156
|
|
|
146
|
-
const origin = opts.url.replace(/\/$/,
|
|
147
|
-
const healthUrl = `${origin}${manifest.routes.apiHealth}
|
|
148
|
-
const adminUrl = `${origin}${manifest.routes.adminDefault}
|
|
149
|
-
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
|
|
150
161
|
|
|
151
|
-
for (const [label, url] of [
|
|
162
|
+
for (const [label, url] of [
|
|
163
|
+
['Health', healthUrl],
|
|
164
|
+
['Admin', adminUrl],
|
|
165
|
+
] as const) {
|
|
152
166
|
try {
|
|
153
|
-
const response = await fetch(url, { method: 'GET' })
|
|
167
|
+
const response = await fetch(url, { method: 'GET' })
|
|
154
168
|
if (response.ok || response.status === 302 || response.status === 401) {
|
|
155
|
-
console.log(`PASS ${label} route responded at ${url}.`)
|
|
169
|
+
console.log(`PASS ${label} route responded at ${url}.`)
|
|
156
170
|
} else {
|
|
157
|
-
failed = true
|
|
158
|
-
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}.`)
|
|
159
173
|
}
|
|
160
174
|
} catch (error) {
|
|
161
|
-
failed = true
|
|
162
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
163
|
-
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}`)
|
|
164
178
|
}
|
|
165
179
|
}
|
|
166
|
-
console.log()
|
|
167
|
-
if (failed) process.exitCode = 1
|
|
168
|
-
})
|
|
180
|
+
console.log()
|
|
181
|
+
if (failed) process.exitCode = 1
|
|
182
|
+
})
|
|
169
183
|
}
|