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