1+ import chalk from 'chalk'
2+ import yargs from 'yargs'
3+ import { hideBin } from 'yargs/helpers'
4+ import { RESTHeartManager , msg } from './restheart.js'
5+
6+ /**
7+ * Initialize the CLI application
8+ */
9+ export function initCLI ( ) {
10+ const rh = new RESTHeartManager ( )
11+
12+ // Intercept CTRL-C and kill RESTHeart before exiting
13+ process . on ( 'SIGINT' , async ( ) => {
14+ console . log ( '\n' )
15+ if ( await rh . isRunning ( ) ) await rh . kill ( )
16+ process . exit ( )
17+ } )
18+
19+ // Register cleanup function to run on exit
20+ process . on ( 'exit' , ( ) => {
21+ msg ( chalk . green ( '\nDone.\n' ) )
22+ } )
23+
24+ // Print welcome message
25+ console . log ( '\n' )
26+ msg ( chalk . green ( ' ============================' ) )
27+ msg ( ' Welcome to RESTHeart CLI' )
28+ msg ( chalk . green ( ' ============================\n' ) )
29+
30+ // Command line arguments setup with command and options handling
31+ yargs ( hideBin ( process . argv ) )
32+ . strict ( )
33+ . parserConfiguration ( {
34+ 'populate--' : true ,
35+ } )
36+ . usage ( 'Usage: $0 [command] [options]' )
37+ . command (
38+ [ 'install [restheart-version]' , 'i' ] ,
39+ 'Install RESTHeart' ,
40+ ( yargs ) => {
41+ yargs
42+ . positional ( 'restheart-version' , {
43+ describe : 'RESTHeart version to install' ,
44+ type : 'string' ,
45+ default : 'latest' ,
46+ } )
47+ . option ( 'force' , {
48+ alias : 'f' ,
49+ type : 'boolean' ,
50+ description : 'Force reinstalling RESTHeart' ,
51+ } )
52+ } ,
53+ ( argv ) => runCommand ( 'install' , argv , rh )
54+ )
55+ . command (
56+ [ 'build' , 'b' ] ,
57+ 'Build and deploy the plugin, restarting RESTHeart (default)' ,
58+ { } ,
59+ ( argv ) => runCommand ( 'build' , argv , rh )
60+ )
61+ . command (
62+ [ 'run [restheart-options..]' , 'r' ] ,
63+ 'Start or restart RESTHeart' ,
64+ ( yargs ) => {
65+ yargs
66+ . option ( 'build' , {
67+ alias : 'b' ,
68+ type : 'boolean' ,
69+ description : 'Build and deploy the plugin before running RESTHeart' ,
70+ } )
71+ . option ( 'port' , {
72+ alias : 'p' ,
73+ type : 'number' ,
74+ description : 'HTTP port' ,
75+ } )
76+ . positional ( 'restheart-options' , {
77+ describe : 'Options to pass to RESTHeart' ,
78+ type : 'string' ,
79+ default : '' ,
80+ } )
81+ . example (
82+ 'rh run -- -o etc/localhost.yml' ,
83+ 'Start or restart RESTHeart with custom options'
84+ )
85+ } ,
86+ ( argv ) => {
87+ runCommand ( 'run' , argv , rh )
88+ }
89+ )
90+ . command (
91+ [ 'kill' , 'k' ] ,
92+ 'Kill RESTHeart' ,
93+ ( yargs ) => {
94+ yargs . option ( 'port' , {
95+ alias : 'p' ,
96+ type : 'number' ,
97+ description : 'HTTP port' ,
98+ } )
99+ } ,
100+ ( argv ) => runCommand ( 'kill' , argv , rh )
101+ )
102+ . command (
103+ [ 'watch' , 'w' ] ,
104+ 'Watch sources and build and deploy plugins on changes, restarting RESTHeart' ,
105+ ( yargs ) => {
106+ yargs
107+ . option ( 'build' , {
108+ alias : 'b' ,
109+ type : 'boolean' ,
110+ description : 'Build and deploy the plugin before running RESTHeart' ,
111+ } )
112+ . option ( 'port' , {
113+ alias : 'p' ,
114+ type : 'number' ,
115+ description : 'HTTP port' ,
116+ } )
117+ . example (
118+ 'rh watch -- -o etc/localhost.yml' ,
119+ 'Watch sources and build and deploy plugins on changes, restarting RESTHeart with custom options'
120+ )
121+ } ,
122+ ( argv ) => {
123+ runCommand ( 'watch' , argv , rh )
124+ }
125+ )
126+ . command (
127+ [ 'status' , 's' ] ,
128+ 'Show the status of RESTHeart' ,
129+ ( yargs ) => {
130+ yargs . option ( 'port' , {
131+ alias : 'p' ,
132+ type : 'number' ,
133+ description : 'HTTP port' ,
134+ } )
135+ } ,
136+ ( argv ) => runCommand ( 'status' , argv , rh )
137+ )
138+ . option ( 'debug' , {
139+ alias : 'd' ,
140+ type : 'boolean' ,
141+ description : 'Run in debug mode' ,
142+ } )
143+ . help ( 'h' )
144+ . alias ( 'h' , 'help' )
145+ . demandCommand ( 1 , 'You need at least one command before moving on' )
146+ . parse ( )
147+ }
148+
149+ /**
150+ * Run a command
151+ * @param {string } command Command to run
152+ * @param {Object } argv Command arguments
153+ * @param {RESTHeartManager } rh RESTHeart manager instance
154+ */
155+ async function runCommand ( command , argv , rh ) {
156+ const restheartOptions = ( argv [ '--' ] && argv [ '--' ] . join ( ' ' ) ) || ''
157+
158+ if ( argv . port ) {
159+ rh . setHttpPort ( argv . port )
160+ }
161+ if ( argv . debug ) {
162+ msg (
163+ chalk . cyan ( 'Running command: ' ) +
164+ command +
165+ chalk . cyan ( ' with options:\n' ) +
166+ JSON . stringify ( argv , null , 2 )
167+ )
168+ rh . setDebugMode ( argv . debug )
169+ rh . printConfiguration ( )
170+ }
171+
172+ switch ( command ) {
173+ case 'install' :
174+ rh . install ( argv . restheartVersion , argv . force )
175+ break
176+ case 'build' :
177+ rh . build ( 'clean package' )
178+ rh . deploy ( )
179+ break
180+ case 'run' :
181+ if ( ! rh . onlyPrintConfig ( restheartOptions ) ) {
182+ await rh . checkAndKill ( )
183+ if ( argv . build ) {
184+ rh . build ( 'clean package' , true )
185+ rh . deploy ( )
186+ }
187+ }
188+ await rh . run ( restheartOptions )
189+ break
190+ case 'kill' :
191+ await rh . checkAndKill ( )
192+ break
193+ case 'watch' :
194+ await rh . checkAndKill ( )
195+ if ( argv . build ) {
196+ rh . build ( 'clean package' , true )
197+ rh . deploy ( )
198+ }
199+ await rh . run ( restheartOptions )
200+ rh . watchFiles ( restheartOptions )
201+ break
202+ case 'status' :
203+ rh . status ( )
204+ break
205+ default :
206+ yargs . showHelp ( )
207+ break
208+ }
209+ }
0 commit comments