@misterzik/espressojs 3.3.3 → 3.3.5

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/CHANGELOG.md CHANGED
@@ -2,6 +2,58 @@
2
2
 
3
3
  All notable changes to EspressoJS will be documented in this file.
4
4
 
5
+ ## [3.3.5] - 2024-12-25
6
+
7
+ ### Fixed
8
+ - **Critical**: CLI process management - added `process.stdin.resume()` to keep parent process alive
9
+ - Server now stays running properly when using `node cli run`
10
+ - Event loop properly maintained for child process management
11
+
12
+ ### Added
13
+ - Comprehensive CLI usage documentation (docs/CLI-USAGE.md)
14
+ - `start:watch` npm script for auto-restart with nodemon
15
+ - `dev:watch` npm script for development with auto-restart
16
+ - `validate` npm script for configuration validation
17
+ - Detailed process management documentation
18
+
19
+ ### Changed
20
+ - Enhanced signal handling (SIGINT/SIGTERM) for graceful shutdown
21
+ - Improved CLI process lifecycle management
22
+ - Updated README with npm scripts section and process management explanation
23
+
24
+ ### Dependencies
25
+ - Added nodemon ^3.0.2 as devDependency for development auto-restart
26
+
27
+ ## [3.3.4] - 2024-12-24
28
+
29
+ ### Added
30
+ - Modern landing page UI with gradient background and glassmorphism design
31
+ - Feature showcase grid with 6 interactive cards
32
+ - Animated coffee icon with floating effect
33
+ - Call-to-action buttons for GitHub and npm
34
+ - Version badge display on landing page
35
+ - Responsive design for mobile and tablet devices
36
+ - Comprehensive CLI usage documentation (docs/CLI-USAGE.md)
37
+ - `start:watch` and `dev:watch` npm scripts for auto-restart with nodemon
38
+ - `validate` npm script for config validation
39
+
40
+ ### Changed
41
+ - Completely redesigned public/index.html with modern aesthetics
42
+ - Enhanced CLI output with emoji indicators and cleaner formatting
43
+ - Improved CLI startup banner with better information display
44
+ - Updated demo/public/index.html to match new design
45
+ - Updated demo/config.json with new schema (publicDirectory, timeout, retries)
46
+ - Updated demo/espresso.js to use APIManager instead of direct axios
47
+
48
+ ### Fixed
49
+ - **Critical**: CLI process now stays alive after spawning server using `process.stdin.resume()`
50
+ - Server startup process properly maintains event loop
51
+ - Better signal handling (SIGINT/SIGTERM) for graceful shutdown
52
+ - CLI no longer exits prematurely when running `node cli run`
53
+
54
+ ### Dependencies
55
+ - Added nodemon ^3.0.2 as devDependency for development auto-restart
56
+
5
57
  ## [3.3.3] - 2024-12-24
6
58
 
7
59
  ### Fixed
package/README.md CHANGED
@@ -112,9 +112,15 @@ node cli show
112
112
  # Run the server
113
113
  node cli run
114
114
 
115
+ # Run with auto-restart (development)
116
+ npm run start:watch
117
+
115
118
  # Update environment settings
116
119
  node cli env --instance=production --port=3000
117
120
 
121
+ # Validate configuration
122
+ node cli validate
123
+
118
124
  # Initialize new config
119
125
  node cli init
120
126
 
@@ -128,6 +134,37 @@ node cli version
128
134
  node cli --help
129
135
  ```
130
136
 
137
+ ### npm Scripts
138
+
139
+ EspressoJS provides convenient npm scripts for common tasks:
140
+
141
+ ```bash
142
+ # Start server
143
+ npm start # Start with current config
144
+ npm run start:watch # Start with auto-restart (nodemon)
145
+
146
+ # Development
147
+ npm run dev # Start in development mode
148
+ npm run dev:watch # Dev mode with auto-restart
149
+
150
+ # Production
151
+ npm run prod # Start in production mode
152
+
153
+ # Configuration
154
+ npm run show # Display current config
155
+ npm run validate # Validate config.json
156
+ ```
157
+
158
+ **Process Management:**
159
+
160
+ The CLI uses a parent-child process model to keep your server running:
161
+ - Parent process (CLI) manages the server lifecycle
162
+ - Child process runs the Express application
163
+ - `process.stdin.resume()` keeps the event loop active
164
+ - Press `CTRL+C` for graceful shutdown
165
+
166
+ For more details, see [CLI Usage Documentation](./docs/CLI-USAGE.md).
167
+
131
168
  ## šŸ“ Project Structure
132
169
 
133
170
  ```
@@ -0,0 +1,369 @@
1
+ # EspressoJS CLI Usage Guide
2
+
3
+ ## Overview
4
+
5
+ The EspressoJS CLI provides a powerful command-line interface for managing your Express server. This guide covers all available commands and best practices.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @misterzik/espressojs
11
+ ```
12
+
13
+ ## Available Commands
14
+
15
+ ### `run` - Start the Server
16
+
17
+ Starts the Express server with the current configuration.
18
+
19
+ ```bash
20
+ node cli run
21
+ ```
22
+
23
+ **How it works:**
24
+ - The CLI spawns a child process running `index.js`
25
+ - The parent CLI process stays alive to manage the child
26
+ - Press `CTRL+C` to gracefully shut down the server
27
+
28
+ **npm scripts:**
29
+ ```bash
30
+ npm start # Start with current config
31
+ npm run start:watch # Start with auto-restart on file changes (nodemon)
32
+ ```
33
+
34
+ ### `show` - Display Configuration
35
+
36
+ Shows the current configuration from `config.json`.
37
+
38
+ ```bash
39
+ node cli show
40
+ ```
41
+
42
+ ### `env` - Update Environment Settings
43
+
44
+ Modify the instance type or port number.
45
+
46
+ ```bash
47
+ # Change instance
48
+ node cli env --instance=production
49
+
50
+ # Change port
51
+ node cli env --port=3000
52
+
53
+ # Change both
54
+ node cli env --instance=production --port=3000
55
+ ```
56
+
57
+ ### `validate` - Validate Configuration
58
+
59
+ Validates your `config.json` against the schema.
60
+
61
+ ```bash
62
+ node cli validate
63
+ ```
64
+
65
+ ### `init` - Initialize Configuration
66
+
67
+ Creates a new `config.json` file with default settings.
68
+
69
+ ```bash
70
+ node cli init
71
+
72
+ # Force overwrite existing config
73
+ node cli init --force
74
+ ```
75
+
76
+ ### `version` - Show Version
77
+
78
+ Displays the EspressoJS version.
79
+
80
+ ```bash
81
+ node cli version
82
+ ```
83
+
84
+ ## Process Management
85
+
86
+ ### Why the CLI Stays Alive
87
+
88
+ The CLI uses a parent-child process model:
89
+
90
+ 1. **Parent Process (CLI)**: Manages the server lifecycle
91
+ 2. **Child Process (Server)**: Runs the Express application
92
+
93
+ The parent process must stay alive to:
94
+ - Keep the child process running
95
+ - Handle graceful shutdown signals
96
+ - Monitor server health
97
+ - Provide process management
98
+
99
+ **Technical Implementation:**
100
+ ```javascript
101
+ // The CLI keeps the process alive using:
102
+ process.stdin.resume(); // Prevents event loop from exiting
103
+
104
+ // Signal handlers ensure graceful shutdown:
105
+ process.on('SIGINT', () => {
106
+ child.kill('SIGINT');
107
+ });
108
+ ```
109
+
110
+ ### Development vs Production
111
+
112
+ **Development (with auto-restart):**
113
+ ```bash
114
+ npm run dev:watch
115
+ # or
116
+ npm run start:watch
117
+ ```
118
+
119
+ Uses `nodemon` to automatically restart the server when files change.
120
+
121
+ **Production (stable):**
122
+ ```bash
123
+ npm start
124
+ # or
125
+ node cli run
126
+ ```
127
+
128
+ Runs the server without auto-restart for stability.
129
+
130
+ ## npm Scripts Reference
131
+
132
+ | Script | Command | Description |
133
+ |--------|---------|-------------|
134
+ | `start` | `node cli run` | Start server with current config |
135
+ | `start:watch` | `nodemon cli run` | Start with auto-restart |
136
+ | `dev` | Set dev config + run | Start in development mode |
137
+ | `dev:watch` | Set dev config + nodemon | Dev mode with auto-restart |
138
+ | `global` | Set global config + run | Start in global mode |
139
+ | `prod` | Set prod config + run | Start in production mode |
140
+ | `show` | `node cli show` | Display configuration |
141
+ | `validate` | `node cli validate` | Validate config.json |
142
+
143
+ ## Troubleshooting
144
+
145
+ ### Server Exits Immediately
146
+
147
+ **Problem:** Server starts but exits right away.
148
+
149
+ **Solution:** This is now fixed in v3.3.4+. The CLI uses `process.stdin.resume()` to keep the process alive.
150
+
151
+ **If still experiencing issues:**
152
+ ```bash
153
+ # Option 1: Use nodemon
154
+ npm run start:watch
155
+
156
+ # Option 2: Run server directly (bypasses CLI)
157
+ node index.js
158
+ ```
159
+
160
+ ### Port Already in Use
161
+
162
+ **Problem:** `EADDRINUSE` error.
163
+
164
+ **Solution:**
165
+ ```bash
166
+ # Change the port
167
+ node cli env --port=3001
168
+ node cli run
169
+ ```
170
+
171
+ ### Configuration Not Found
172
+
173
+ **Problem:** `config.json` missing.
174
+
175
+ **Solution:**
176
+ ```bash
177
+ # Create new config
178
+ node cli init
179
+ ```
180
+
181
+ ### Process Won't Stop
182
+
183
+ **Problem:** Server doesn't respond to `CTRL+C`.
184
+
185
+ **Solution:**
186
+ ```bash
187
+ # Force kill (find process ID first)
188
+ ps aux | grep node
189
+ kill -9 <PID>
190
+
191
+ # Or on Windows
192
+ tasklist | findstr node
193
+ taskkill /F /PID <PID>
194
+ ```
195
+
196
+ ## Best Practices
197
+
198
+ ### 1. Use npm Scripts
199
+
200
+ Instead of running CLI commands directly, use npm scripts:
201
+
202
+ ```bash
203
+ # Good
204
+ npm start
205
+
206
+ # Also good, but more verbose
207
+ node cli run
208
+ ```
209
+
210
+ ### 2. Development Workflow
211
+
212
+ ```bash
213
+ # Initial setup
214
+ npm install
215
+ node cli init
216
+
217
+ # Start development
218
+ npm run dev:watch
219
+
220
+ # Test production config
221
+ npm run prod
222
+ ```
223
+
224
+ ### 3. Environment-Specific Configs
225
+
226
+ Create separate config files:
227
+ - `config.development.json`
228
+ - `config.production.json`
229
+ - `config.test.json`
230
+
231
+ Load them based on `NODE_ENV`:
232
+ ```javascript
233
+ const env = process.env.NODE_ENV || 'development';
234
+ const config = require(`./config.${env}.json`);
235
+ ```
236
+
237
+ ### 4. Process Managers for Production
238
+
239
+ For production deployments, use a process manager:
240
+
241
+ **PM2:**
242
+ ```bash
243
+ npm install -g pm2
244
+ pm2 start cli.js --name "espresso-app" -- run
245
+ pm2 save
246
+ pm2 startup
247
+ ```
248
+
249
+ **Forever:**
250
+ ```bash
251
+ npm install -g forever
252
+ forever start cli.js run
253
+ ```
254
+
255
+ **Docker:**
256
+ ```dockerfile
257
+ FROM node:18-alpine
258
+ WORKDIR /app
259
+ COPY package*.json ./
260
+ RUN npm ci --only=production
261
+ COPY . .
262
+ CMD ["node", "cli", "run"]
263
+ ```
264
+
265
+ ## Advanced Usage
266
+
267
+ ### Custom CLI Scripts
268
+
269
+ You can extend the CLI in your own project:
270
+
271
+ ```javascript
272
+ // custom-cli.js
273
+ const { spawn } = require('child_process');
274
+
275
+ // Custom command
276
+ if (process.argv[2] === 'custom') {
277
+ console.log('Running custom command...');
278
+ // Your custom logic
279
+ }
280
+
281
+ // Fall back to EspressoJS CLI
282
+ require('@misterzik/espressojs/cli');
283
+ ```
284
+
285
+ ### Programmatic Usage
286
+
287
+ Use EspressoJS programmatically without the CLI:
288
+
289
+ ```javascript
290
+ const app = require('@misterzik/espressojs');
291
+ const config = require('@misterzik/espressojs/server');
292
+
293
+ // Your custom setup
294
+ app.use('/custom', (req, res) => {
295
+ res.json({ message: 'Custom route' });
296
+ });
297
+
298
+ // Start server
299
+ const PORT = config.port || 3000;
300
+ app.listen(PORT, () => {
301
+ console.log(`Server running on port ${PORT}`);
302
+ });
303
+ ```
304
+
305
+ ## Signal Handling
306
+
307
+ The CLI properly handles system signals:
308
+
309
+ | Signal | Behavior |
310
+ |--------|----------|
311
+ | `SIGINT` | Graceful shutdown (CTRL+C) |
312
+ | `SIGTERM` | Graceful shutdown (kill command) |
313
+ | `SIGKILL` | Immediate termination (cannot be caught) |
314
+
315
+ **Graceful Shutdown Process:**
316
+ 1. Signal received by CLI
317
+ 2. CLI forwards signal to child process
318
+ 3. Server closes HTTP connections
319
+ 4. MongoDB connections closed (if enabled)
320
+ 5. Process exits with appropriate code
321
+
322
+ ## FAQ
323
+
324
+ **Q: Why use the CLI instead of running `index.js` directly?**
325
+
326
+ A: The CLI provides:
327
+ - Configuration management
328
+ - Environment switching
329
+ - Validation
330
+ - Better error messages
331
+ - Process management
332
+
333
+ **Q: Can I use the CLI in production?**
334
+
335
+ A: Yes, but consider using a process manager (PM2, Forever) for:
336
+ - Auto-restart on crashes
337
+ - Load balancing
338
+ - Log management
339
+ - Monitoring
340
+
341
+ **Q: Does the CLI work on Windows?**
342
+
343
+ A: Yes, the CLI is cross-platform and works on Windows, macOS, and Linux.
344
+
345
+ **Q: How do I debug the CLI?**
346
+
347
+ A: Use Node.js debugging:
348
+ ```bash
349
+ node --inspect cli run
350
+ ```
351
+
352
+ Then open Chrome DevTools at `chrome://inspect`.
353
+
354
+ ## Support
355
+
356
+ - **GitHub Issues**: https://github.com/misterzik/Espresso.js/issues
357
+ - **npm Package**: https://www.npmjs.com/package/@misterzik/espressojs
358
+ - **Documentation**: https://github.com/misterzik/Espresso.js
359
+
360
+ ## Version History
361
+
362
+ - **v3.3.4**: Fixed CLI process management with `process.stdin.resume()`
363
+ - **v3.3.3**: Enhanced CLI output with emoji indicators
364
+ - **v3.3.2**: Improved error handling
365
+ - **v3.3.1**: Added multiple API support
366
+
367
+ ---
368
+
369
+ **Happy coding with EspressoJS!** ā˜•
package/index.js CHANGED
@@ -136,6 +136,8 @@ app.use(errorHandler);
136
136
  let server;
137
137
 
138
138
  const startServer = () => {
139
+ logger.info(`Attempting to start server on port ${Port}...`);
140
+
139
141
  server = app.listen(Port, () => {
140
142
  logger.info(`
141
143
  ╔═══════════════════════════════════════════════════════╗
@@ -150,6 +152,20 @@ const startServer = () => {
150
152
  ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•
151
153
  `);
152
154
  });
155
+
156
+ server.on('error', (error) => {
157
+ if (error.code === 'EADDRINUSE') {
158
+ logger.error(`Port ${Port} is already in use`);
159
+ } else {
160
+ logger.error(`Server error: ${error.message}`);
161
+ logger.error(`Stack: ${error.stack}`);
162
+ }
163
+ process.exit(1);
164
+ });
165
+
166
+ server.on('listening', () => {
167
+ logger.info(`Server is now listening on port ${Port}`);
168
+ });
153
169
  };
154
170
 
155
171
  const gracefulShutdown = (signal) => {
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "@misterzik/espressojs",
3
- "version": "3.3.3",
3
+ "version": "3.3.5",
4
4
  "description": "EspressoJS Introducing Espresso.JS, your ultimate Express configuration starting point and boilerplate. With its simplicity and lack of opinionation, EspressoJS offers plug-and-play configurations built on top of Express.",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\"",
8
8
  "start": "node cli run",
9
+ "start:watch": "nodemon cli run",
9
10
  "dev": "node cli env --instance=development --port=8080 && node cli run",
11
+ "dev:watch": "node cli env --instance=development --port=8080 && nodemon cli run",
10
12
  "global": "node cli env --instance=global --port=8081 && node cli run",
11
13
  "prod": "node cli env --instance=production --port=80 && node cli run",
12
14
  "show": "node cli show",
15
+ "validate": "node cli validate",
13
16
  "build-dev": "webpack --mode development",
14
17
  "build-prod": "webpack --mode production"
15
18
  },
@@ -60,7 +63,8 @@
60
63
  "@babel/core": "^7.23.7",
61
64
  "@babel/preset-env": "^7.23.7",
62
65
  "amd-define-factory-patcher-loader": "^1.0.0",
63
- "babel-loader": "^9.1.3"
66
+ "babel-loader": "^9.1.3",
67
+ "nodemon": "^3.0.2"
64
68
  },
65
69
  "engines": {
66
70
  "node": ">= 0.10.0"
@@ -26,28 +26,32 @@ function showCommand() {
26
26
 
27
27
  function runCommand() {
28
28
  if (cfgB !== undefined) {
29
- const cmd_ct = vmdLogo;
30
- console.log(`${cmd_ct}`);
31
- console.log(
32
- `Espresso CLI
33
- --------------
34
- Warming Up Configs..
35
- Running ....
36
-
37
- Instance Config:
38
- Configuration: ${cfgB.instance}
39
- Endpoint: http://localhost:${cfgB.port}
40
- JSON:`,
41
- JSON.stringify(cfgB, null, 2),
42
- `\n\nTo stop process press CTRL+C\n`
43
- );
29
+ console.log('\n╔═══════════════════════════════════════════════════════╗');
30
+ console.log('ā•‘ ESPRESSO.JS CLI ā•‘');
31
+ console.log('ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n');
32
+
33
+ console.log('šŸš€ Starting server...\n');
34
+ console.log(`šŸ“‹ Configuration:`);
35
+ console.log(` Environment: ${cfgB.instance}`);
36
+ console.log(` Port: ${cfgB.port}`);
37
+ console.log(` URL: http://localhost:${cfgB.port}`);
38
+ console.log(` MongoDB: ${cfgB.mongoDB?.enabled ? 'āœ“ Enabled' : 'āœ— Disabled'}`);
39
+ console.log(` API: ${cfgB.api?.enabled ? 'āœ“ Enabled' : 'āœ— Disabled'}`);
40
+
41
+ const apiCount = Object.keys(cfgB).filter(key => key.match(/^api\d*$/)).length;
42
+ if (apiCount > 1) {
43
+ console.log(` API Endpoints: ${apiCount} configured`);
44
+ }
45
+
46
+ console.log('\nšŸ’” Press CTRL+C to stop the server\n');
47
+ console.log('─'.repeat(55) + '\n');
44
48
 
45
49
  const child = spawn(
46
50
  "node",
47
51
  ["index.js"],
48
52
  {
49
53
  stdio: "inherit",
50
- shell: true,
54
+ shell: false,
51
55
  env: {
52
56
  ...process.env,
53
57
  NODE_ENV: cfgB.instance,
@@ -57,15 +61,34 @@ JSON:`,
57
61
  );
58
62
 
59
63
  child.on("error", (error) => {
60
- console.error(`Error: ${error.message}`);
64
+ console.error(`Error starting server: ${error.message}`);
65
+ process.exit(1);
61
66
  });
62
67
 
63
- child.on("exit", (code) => {
64
- if (code !== 0) {
65
- console.error(`Process exited with code ${code}`);
68
+ child.on("exit", (code, signal) => {
69
+ if (signal) {
70
+ console.log(`Server process killed with signal ${signal}`);
71
+ } else if (code !== 0) {
72
+ console.error(`Server process exited with code ${code}`);
73
+ } else {
74
+ console.log(`Server process exited cleanly`);
66
75
  }
67
- process.exit(code);
76
+ process.exit(code || 0);
68
77
  });
78
+
79
+ // Keep the CLI process alive by handling signals
80
+ process.on('SIGINT', () => {
81
+ console.log('\nShutting down server...');
82
+ child.kill('SIGINT');
83
+ });
84
+
85
+ process.on('SIGTERM', () => {
86
+ child.kill('SIGTERM');
87
+ });
88
+
89
+ // Prevent the process from exiting by keeping stdin open
90
+ // This ensures the CLI stays alive as long as the child process is running
91
+ process.stdin.resume();
69
92
  }
70
93
  }
71
94