11import chalk from 'chalk' ;
22import { execSync } from 'child_process' ;
3+ import ora from 'ora' ;
4+
5+ import { isDockerInstalled } from './docker.js' ;
6+ import { isGitInstalled } from './git.js' ;
37
48interface CheckResult {
59 passed : boolean ;
610 name : string ;
7- message ?: string ;
11+ required : boolean ;
12+ message : string ;
813}
914
1015function checkNodeVersion ( ) : CheckResult {
@@ -16,67 +21,124 @@ function checkNodeVersion(): CheckResult {
1621 return {
1722 passed : true ,
1823 name : 'Node.js' ,
24+ required : true ,
25+ message : nodeVersion ,
1926 } ;
2027 }
2128
2229 return {
2330 passed : false ,
2431 name : 'Node.js' ,
32+ required : true ,
2533 message : `Node.js >= 20.0.0 required (found ${ nodeVersion } )` ,
2634 } ;
2735 } catch {
2836 return {
2937 passed : false ,
3038 name : 'Node.js' ,
39+ required : true ,
3140 message : 'Failed to check Node.js version' ,
3241 } ;
3342 }
3443}
3544
3645function checkPnpmInstalled ( ) : CheckResult {
3746 try {
38- execSync ( 'pnpm --version' , { stdio : 'ignore' } ) ;
47+ const version = execSync ( 'pnpm --version' , {
48+ encoding : 'utf-8' ,
49+ stdio : [ 'ignore' , 'pipe' , 'ignore' ] ,
50+ } ) . trim ( ) ;
3951 return {
4052 passed : true ,
4153 name : 'pnpm' ,
54+ required : true ,
55+ message : `v${ version } ` ,
4256 } ;
4357 } catch {
4458 return {
4559 passed : false ,
4660 name : 'pnpm' ,
61+ required : true ,
4762 message : 'pnpm not found. Install: npm install -g pnpm' ,
4863 } ;
4964 }
5065}
5166
67+ function checkGit ( ) : CheckResult {
68+ const installed = isGitInstalled ( ) ;
69+ return {
70+ passed : installed ,
71+ name : 'git' ,
72+ required : false ,
73+ message : installed
74+ ? 'available (repository initialization supported)'
75+ : 'not found (git init step will be skipped)' ,
76+ } ;
77+ }
78+
79+ function checkDocker ( ) : CheckResult {
80+ const installed = isDockerInstalled ( ) ;
81+ return {
82+ passed : installed ,
83+ name : 'Docker' ,
84+ required : false ,
85+ message : installed
86+ ? 'available (automatic local DB setup supported)'
87+ : 'not found (start PostgreSQL separately)' ,
88+ } ;
89+ }
90+
5291export async function runPreflightChecks ( ) : Promise < boolean > {
5392 console . log ( ) ;
54- console . log ( chalk . bold ( ' Checking requirements...' ) ) ;
93+ console . log ( chalk . bold ( ' System readiness' ) ) ;
94+ console . log ( chalk . dim ( ' Validating required and optional local tooling...' ) ) ;
5595 console . log ( ) ;
5696
57- const checks : CheckResult [ ] = [ checkNodeVersion ( ) , checkPnpmInstalled ( ) ] ;
97+ const checks : CheckResult [ ] = [
98+ checkNodeVersion ( ) ,
99+ checkPnpmInstalled ( ) ,
100+ checkGit ( ) ,
101+ checkDocker ( ) ,
102+ ] ;
58103
59- let hasErrors = false ;
104+ const requiredFailures : CheckResult [ ] = [ ] ;
105+ const optionalWarnings : CheckResult [ ] = [ ] ;
60106
61107 for ( const check of checks ) {
108+ const spinner = ora ( `Checking ${ check . name } ...` ) . start ( ) ;
109+
62110 if ( check . passed ) {
63- console . log ( chalk . green ( ' ✔' ) , check . name ) ;
111+ spinner . succeed ( chalk . bold ( check . name ) ) ;
64112 } else {
65- hasErrors = true ;
66- console . log ( chalk . red ( ' ✖' ) , check . name ) ;
67- if ( check . message ) {
68- console . log ( chalk . dim ( ` ${ check . message } ` ) ) ;
113+ if ( check . required ) {
114+ requiredFailures . push ( check ) ;
115+ spinner . fail ( chalk . bold ( check . name ) ) ;
116+ } else {
117+ optionalWarnings . push ( check ) ;
118+ spinner . warn ( chalk . bold ( check . name ) ) ;
69119 }
120+ console . log ( chalk . dim ( ` ${ check . message } ` ) ) ;
70121 }
71122 }
72123
73124 console . log ( ) ;
74125
75- if ( hasErrors ) {
126+ if ( optionalWarnings . length > 0 ) {
127+ console . log ( chalk . yellow ( ' Optional tools missing:' ) ) ;
128+ for ( const warning of optionalWarnings ) {
129+ console . log ( chalk . dim ( ` • ${ warning . name } : ${ warning . message } ` ) ) ;
130+ }
131+ console . log ( ) ;
132+ }
133+
134+ if ( requiredFailures . length > 0 ) {
76135 console . log (
77136 chalk . red ( ' ✖' ) ,
78- 'Requirements not met. Please fix the errors above. '
137+ 'Required dependencies are missing. Fix the items below and try again: '
79138 ) ;
139+ for ( const failure of requiredFailures ) {
140+ console . log ( chalk . dim ( ` • ${ failure . name } : ${ failure . message } ` ) ) ;
141+ }
80142 console . log ( ) ;
81143 return false ;
82144 }
0 commit comments