@@ -24,6 +24,14 @@ import fs from 'fs';
2424import { createServer } from '../lib' ;
2525import { CliArgs , ServerOptions } from '../types' ;
2626import { fileExists } from '../utils/utils' ;
27+ import {
28+ styles ,
29+ createHeader ,
30+ createBox ,
31+ formatList ,
32+ formatHelp ,
33+ formatError ,
34+ } from '../utils/cli-styles' ;
2735
2836// Default server configuration
2937const DEFAULT_PORT = 3000 ;
@@ -80,10 +88,22 @@ function showVersion(): void {
8088 const packageJsonPath = path . join ( __dirname , '../../package.json' ) ;
8189 const packageJson = JSON . parse ( fs . readFileSync ( packageJsonPath , 'utf8' ) ) ;
8290
83- console . log ( `@webmasterdevlin/json-server v${ packageJson . version } ` ) ;
91+ console . log (
92+ createBox (
93+ '⚡️ @webmasterdevlin/json-server' ,
94+ [
95+ '' ,
96+ `${ styles . primary ( 'Version:' ) } ${ styles . highlight ( packageJson . version ) } ` ,
97+ '' ,
98+ `${ styles . secondary ( 'TypeScript-powered REST API mock server' ) } ` ,
99+ '' ,
100+ ] ,
101+ 'default'
102+ )
103+ ) ;
84104 } catch ( error ) {
85105 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
86- console . error ( ' Error reading package version:' , errorMessage ) ;
106+ console . error ( formatError ( 'Version Error' , `Error reading package version: ${ errorMessage } ` ) ) ;
87107 process . exit ( 1 ) ;
88108 }
89109}
@@ -92,50 +112,46 @@ function showVersion(): void {
92112 * Display help information with usage examples
93113 */
94114function showHelp ( ) : void {
95- console . log ( `
96- ╭───────────────────────────────────────────────────────────────────────────╮
97- │ │
98- │ @webmasterdevlin/json-server CLI │
99- │ │
100- ╰───────────────────────────────────────────────────────────────────────────╯
101-
102- A TypeScript implementation of json-server with additional features.
103-
104- Usage:
105- json-server [options] <source>
106-
107- Options:
108- --port, -p Set port [default: 3000]
109- --host, -H Set host [default: "localhost"]
110- --watch, -w Watch for changes [default: false]
111- --routes, -r Path to routes file [string]
112- --middlewares, -m Path to middlewares files [array]
113- --static, -s Path to static files [array]
114- --read-only, --ro Allow only GET requests [default: false]
115- --no-cors, --nc Disable CORS [default: false]
116- --no-gzip, --ng Disable GZIP compression [default: false]
117- --enable-api-prefix, --api Enable /api/* prefix [default: false]
118- --delay, -d Add delay to responses (ms) [number]
119- --id, -i Set database id field [default: "id"]
120- --foreignKeySuffix Set foreign key suffix [default: "_id"]
121- --quiet, -q Suppress log messages [default: false]
122- --help, -h Show help [boolean]
123- --version, -v Show version [boolean]
124-
125- Examples:
126- json-server db.json
127- json-server db.json --port 3001
128- json-server db.json --watch
129- json-server db.json --routes routes.json
130- json-server db.json --routes routes.js
131- json-server db.json --delay 1000
132- json-server db.json --id _id
133- json-server db.json --enable-api-prefix # Enable /api/* routes
134- json-server http://example.com/db.json
135-
136- For more information, visit:
137- https://github.com/webmasterdevlin/json-server
138- ` ) ;
115+ // Create sections for the help display
116+ const sections : Record < string , string > = {
117+ Usage : `${ styles . command ( 'json-server' ) } ${ styles . info ( '[options]' ) } ${ styles . highlight ( '<source>' ) } ` ,
118+
119+ Options : formatList ( [
120+ `${ styles . key ( '--port, -p' ) } ${ styles . value ( 'Set port' ) } ${ styles . muted ( ' [default: 3000]' ) } ` ,
121+ `${ styles . key ( '--host, -H' ) } ${ styles . value ( 'Set host' ) } ${ styles . muted ( ' [default: "localhost"]' ) } ` ,
122+ `${ styles . key ( '--watch, -w' ) } ${ styles . value ( 'Watch for changes' ) } ${ styles . muted ( ' [default: false]' ) } ` ,
123+ `${ styles . key ( '--routes, -r' ) } ${ styles . value ( 'Path to routes file' ) } ${ styles . muted ( ' [string]' ) } ` ,
124+ `${ styles . key ( '--middlewares, -m' ) } ${ styles . value ( 'Path to middlewares files' ) } ${ styles . muted ( ' [array]' ) } ` ,
125+ `${ styles . key ( '--static, -s' ) } ${ styles . value ( 'Path to static files' ) } ${ styles . muted ( ' [array]' ) } ` ,
126+ `${ styles . key ( '--read-only, --ro' ) } ${ styles . value ( 'Allow only GET requests' ) } ${ styles . muted ( ' [default: false]' ) } ` ,
127+ `${ styles . key ( '--no-cors, --nc' ) } ${ styles . value ( 'Disable CORS' ) } ${ styles . muted ( ' [default: false]' ) } ` ,
128+ `${ styles . key ( '--no-gzip, --ng' ) } ${ styles . value ( 'Disable GZIP compression' ) } ${ styles . muted ( ' [default: false]' ) } ` ,
129+ `${ styles . key ( '--enable-api-prefix, --api' ) } ${ styles . value ( 'Enable /api/* prefix' ) } ${ styles . muted ( ' [default: false]' ) } ` ,
130+ `${ styles . key ( '--delay, -d' ) } ${ styles . value ( 'Add delay to responses (ms)' ) } ${ styles . muted ( ' [number]' ) } ` ,
131+ `${ styles . key ( '--id, -i' ) } ${ styles . value ( 'Set database id field' ) } ${ styles . muted ( ' [default: "id"]' ) } ` ,
132+ `${ styles . key ( '--foreignKeySuffix' ) } ${ styles . value ( 'Set foreign key suffix' ) } ${ styles . muted ( ' [default: "_id"]' ) } ` ,
133+ `${ styles . key ( '--quiet, -q' ) } ${ styles . value ( 'Suppress log messages' ) } ${ styles . muted ( ' [default: false]' ) } ` ,
134+ `${ styles . key ( '--help, -h' ) } ${ styles . value ( 'Show help' ) } ${ styles . muted ( ' [boolean]' ) } ` ,
135+ `${ styles . key ( '--version, -v' ) } ${ styles . value ( 'Show version' ) } ${ styles . muted ( ' [boolean]' ) } ` ,
136+ ] ) ,
137+
138+ Examples : formatList ( [
139+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ` ,
140+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ${ styles . info ( '--port 3001' ) } ` ,
141+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ${ styles . info ( '--watch' ) } ` ,
142+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ${ styles . info ( '--routes routes.json' ) } ` ,
143+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ${ styles . info ( '--routes routes.js' ) } ` ,
144+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ${ styles . info ( '--delay 1000' ) } ` ,
145+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ${ styles . info ( '--id _id' ) } ` ,
146+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'db.json' ) } ${ styles . info ( '--enable-api-prefix' ) } ${ styles . muted ( '# Enable /api/* routes' ) } ` ,
147+ `${ styles . command ( 'json-server' ) } ${ styles . highlight ( 'http://example.com/db.json' ) } ` ,
148+ ] ) ,
149+
150+ 'More Information' : `${ styles . url ( 'https://github.com/webmasterdevlin/json-server' ) } ` ,
151+ } ;
152+
153+ // Display the help sections
154+ console . log ( formatHelp ( sections ) ) ;
139155}
140156
141157/**
@@ -158,19 +174,39 @@ async function main(): Promise<void> {
158174 const cliArgs = parseArgs ( ) ;
159175 const args = process . argv . slice ( 2 ) ;
160176
177+ // Show welcome banner
178+ if ( ! cliArgs . quiet ) {
179+ console . log ( createHeader ( ) ) ;
180+ }
181+
161182 // Get database source
162183 const source = getSourcePath ( args ) ;
163184 if ( ! source ) {
164- console . error ( 'Error: No database source provided' ) ;
185+ console . error (
186+ formatError (
187+ 'Missing Source' ,
188+ 'No database source provided.' ,
189+ 'Please specify a JSON file or URL to use as database.'
190+ )
191+ ) ;
165192 showHelp ( ) ;
166193 process . exit ( 1 ) ;
167194 }
168195
169196 // Check if source file exists (if it's a local file)
170197 if ( source . startsWith ( 'http://' ) || source . startsWith ( 'https://' ) ) {
171- console . log ( `Using remote database: ${ source } ` ) ;
198+ console . log (
199+ styles . icons . database ,
200+ styles . info ( `Using remote database: ${ styles . url ( source ) } ` )
201+ ) ;
172202 } else if ( ! fileExists ( source ) ) {
173- console . error ( `Error: Database file not found: ${ source } ` ) ;
203+ console . error (
204+ formatError (
205+ 'Database Error' ,
206+ `Database file not found: ${ source } ` ,
207+ 'Make sure the file exists and you have permissions to read it.'
208+ )
209+ ) ;
174210 process . exit ( 1 ) ;
175211 }
176212
@@ -201,9 +237,12 @@ async function main(): Promise<void> {
201237 // Load custom routes if specified
202238 if ( cliArgs . routes ) {
203239 if ( ! fileExists ( cliArgs . routes ) ) {
204- console . warn ( `Warning: Routes file not found: ${ cliArgs . routes } ` ) ;
240+ console . warn (
241+ styles . icons . warning ,
242+ styles . warning ( `Routes file not found: ${ styles . highlight ( cliArgs . routes ) } ` )
243+ ) ;
205244 } else {
206- server . loadRoutes ( cliArgs . routes ) ;
245+ await server . loadRoutes ( cliArgs . routes ) ;
207246 }
208247 }
209248
@@ -219,7 +258,7 @@ async function main(): Promise<void> {
219258 }
220259 } catch ( error ) {
221260 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
222- console . error ( ' Error starting server:' , errorMessage ) ;
261+ console . error ( formatError ( 'Server Error' , `Error starting server: ${ errorMessage } ` ) ) ;
223262 process . exit ( 1 ) ;
224263 }
225264}
@@ -235,37 +274,49 @@ function setupFileWatcher(dbPath: string, server: any): void {
235274 // Use Node's fs.watch API to monitor file changes
236275 fs . watch ( dbPath , ( eventType ) => {
237276 if ( eventType === 'change' ) {
238- console . log ( `Database file changed: ${ dbPath } ` ) ;
277+ console . log (
278+ styles . icons . watch ,
279+ styles . info ( `${ styles . highlight ( dbPath ) } changed, reloading database...` )
280+ ) ;
239281 try {
240282 server . loadDatabase ( dbPath ) ;
241- console . log ( 'Database reloaded' ) ;
283+ console . log ( styles . icons . success , styles . success ( 'Database reloaded successfully' ) ) ;
242284 } catch ( error ) {
243285 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
244- console . error ( 'Error reloading database:' , errorMessage ) ;
286+ console . error (
287+ styles . icons . error ,
288+ styles . error ( `Error reloading database: ${ errorMessage } ` )
289+ ) ;
245290 }
246291 }
247292 } ) ;
248293
249- console . log ( `Watching for changes: ${ dbPath } ` ) ;
294+ console . log (
295+ styles . icons . watch ,
296+ styles . info ( `Watching for changes: ${ styles . highlight ( dbPath ) } ` )
297+ ) ;
250298 } catch ( error ) {
251299 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
252- console . error ( 'Error setting up file watcher:' , errorMessage ) ;
300+ console . error (
301+ styles . icons . error ,
302+ styles . error ( `Error setting up file watcher: ${ errorMessage } ` )
303+ ) ;
253304 }
254305}
255306
256307// Handle process termination gracefully
257308process . on ( 'SIGINT' , ( ) => {
258- console . log ( '\nReceived SIGINT. Shutting down...' ) ;
309+ console . log ( '\n' + styles . icons . stop , styles . info ( 'Received SIGINT. Shutting down...') ) ;
259310 process . exit ( 0 ) ;
260311} ) ;
261312
262313process . on ( 'SIGTERM' , ( ) => {
263- console . log ( '\nReceived SIGTERM. Shutting down...' ) ;
314+ console . log ( '\n' + styles . icons . stop , styles . info ( 'Received SIGTERM. Shutting down...') ) ;
264315 process . exit ( 0 ) ;
265316} ) ;
266317
267318// Start the application
268319main ( ) . catch ( ( error ) => {
269- console . error ( 'Fatal error: ' , error . message ) ;
320+ console . error ( formatError ( 'Fatal Error ' , error . message ) ) ;
270321 process . exit ( 1 ) ;
271322} ) ;
0 commit comments