@misterzik/espressojs 3.3.4 → 3.3.6

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,89 @@
2
2
 
3
3
  All notable changes to EspressoJS will be documented in this file.
4
4
 
5
+ ## [3.3.6] - 2024-12-25
6
+
7
+ ### Fixed
8
+ - **Critical**: API routes now load correctly from `routes/api/index.js`
9
+ - API routes properly mounted at root level to support `/v1/` endpoints
10
+ - Catch-all route moved to end to prevent intercepting API routes
11
+ - Route loading path corrected to use proper file structure
12
+ - Programmatic usage now properly supported with exported `startServer()` function
13
+
14
+ ### Changed
15
+ - Replaced static version badge with dynamic npm version shield badge
16
+ - Updated landing page to show live npm version from shields.io
17
+ - Improved code formatting and whitespace consistency in HTML files
18
+ - Updated default API URI to use swapi.info instead of swapi.dev
19
+ - Enhanced module exports for better programmatic usage
20
+
21
+ ### Added
22
+ - Dynamic version badge using shields.io npm API
23
+ - Better visual indication of current package version on landing page
24
+ - Exported `startServer()` function for programmatic usage
25
+ - Exported `gracefulShutdown()` function for custom shutdown handling
26
+ - Exported `server` instance for advanced use cases
27
+ - Comprehensive usage patterns documentation (docs/USAGE-PATTERNS.md)
28
+ - README section explaining different server startup methods
29
+
30
+ ### Documentation
31
+ - Added detailed guide explaining why some users need manual `app.listen()`
32
+ - Documented three usage patterns: CLI, Direct Execution, and Programmatic
33
+ - Explained `require.main === module` behavior and implications
34
+ - Migration guide from manual listen to `startServer()` function
35
+
36
+ ## [3.3.5] - 2024-12-25
37
+
38
+ ### Fixed
39
+ - **Critical**: CLI process management - added `process.stdin.resume()` to keep parent process alive
40
+ - Server now stays running properly when using `node cli run`
41
+ - Event loop properly maintained for child process management
42
+
43
+ ### Added
44
+ - Comprehensive CLI usage documentation (docs/CLI-USAGE.md)
45
+ - `start:watch` npm script for auto-restart with nodemon
46
+ - `dev:watch` npm script for development with auto-restart
47
+ - `validate` npm script for configuration validation
48
+ - Detailed process management documentation
49
+
50
+ ### Changed
51
+ - Enhanced signal handling (SIGINT/SIGTERM) for graceful shutdown
52
+ - Improved CLI process lifecycle management
53
+ - Updated README with npm scripts section and process management explanation
54
+
55
+ ### Dependencies
56
+ - Added nodemon ^3.0.2 as devDependency for development auto-restart
57
+
58
+ ## [3.3.4] - 2024-12-24
59
+
60
+ ### Added
61
+ - Modern landing page UI with gradient background and glassmorphism design
62
+ - Feature showcase grid with 6 interactive cards
63
+ - Animated coffee icon with floating effect
64
+ - Call-to-action buttons for GitHub and npm
65
+ - Version badge display on landing page
66
+ - Responsive design for mobile and tablet devices
67
+ - Comprehensive CLI usage documentation (docs/CLI-USAGE.md)
68
+ - `start:watch` and `dev:watch` npm scripts for auto-restart with nodemon
69
+ - `validate` npm script for config validation
70
+
71
+ ### Changed
72
+ - Completely redesigned public/index.html with modern aesthetics
73
+ - Enhanced CLI output with emoji indicators and cleaner formatting
74
+ - Improved CLI startup banner with better information display
75
+ - Updated demo/public/index.html to match new design
76
+ - Updated demo/config.json with new schema (publicDirectory, timeout, retries)
77
+ - Updated demo/espresso.js to use APIManager instead of direct axios
78
+
79
+ ### Fixed
80
+ - **Critical**: CLI process now stays alive after spawning server using `process.stdin.resume()`
81
+ - Server startup process properly maintains event loop
82
+ - Better signal handling (SIGINT/SIGTERM) for graceful shutdown
83
+ - CLI no longer exits prematurely when running `node cli run`
84
+
85
+ ### Dependencies
86
+ - Added nodemon ^3.0.2 as devDependency for development auto-restart
87
+
5
88
  ## [3.3.3] - 2024-12-24
6
89
 
7
90
  ### Fixed
package/README.md CHANGED
@@ -93,6 +93,8 @@ require('@misterzik/espressojs/cli');
93
93
 
94
94
  ### 5. Run Your Server
95
95
 
96
+ **Method 1: Using CLI (Recommended)**
97
+
96
98
  ```bash
97
99
  # Using the CLI
98
100
  node cli run
@@ -101,6 +103,31 @@ node cli run
101
103
  npm start
102
104
  ```
103
105
 
106
+ **Method 2: Direct Execution**
107
+
108
+ ```bash
109
+ node index.js
110
+ ```
111
+
112
+ **Method 3: Programmatic Usage (v3.3.6+)**
113
+
114
+ If you're requiring EspressoJS as a module in your own code:
115
+
116
+ ```javascript
117
+ // Option A: Use built-in startServer (recommended)
118
+ const { startServer } = require('@misterzik/espressojs');
119
+ startServer();
120
+
121
+ // Option B: Manual control
122
+ const app = require('@misterzik/espressojs');
123
+ const config = require('@misterzik/espressojs/server');
124
+ app.listen(config.port, () => {
125
+ console.log(`Server running on port ${config.port}`);
126
+ });
127
+ ```
128
+
129
+ > **Note:** If you're using EspressoJS programmatically (requiring it as a module), the server won't auto-start. You must either call `startServer()` or manually use `app.listen()`. See [Usage Patterns Guide](./docs/USAGE-PATTERNS.md) for details.
130
+
104
131
  ## 🛠️ CLI Commands
105
132
 
106
133
  EspressoJS comes with a powerful CLI for managing your application:
@@ -112,9 +139,15 @@ node cli show
112
139
  # Run the server
113
140
  node cli run
114
141
 
142
+ # Run with auto-restart (development)
143
+ npm run start:watch
144
+
115
145
  # Update environment settings
116
146
  node cli env --instance=production --port=3000
117
147
 
148
+ # Validate configuration
149
+ node cli validate
150
+
118
151
  # Initialize new config
119
152
  node cli init
120
153
 
@@ -128,6 +161,37 @@ node cli version
128
161
  node cli --help
129
162
  ```
130
163
 
164
+ ### npm Scripts
165
+
166
+ EspressoJS provides convenient npm scripts for common tasks:
167
+
168
+ ```bash
169
+ # Start server
170
+ npm start # Start with current config
171
+ npm run start:watch # Start with auto-restart (nodemon)
172
+
173
+ # Development
174
+ npm run dev # Start in development mode
175
+ npm run dev:watch # Dev mode with auto-restart
176
+
177
+ # Production
178
+ npm run prod # Start in production mode
179
+
180
+ # Configuration
181
+ npm run show # Display current config
182
+ npm run validate # Validate config.json
183
+ ```
184
+
185
+ **Process Management:**
186
+
187
+ The CLI uses a parent-child process model to keep your server running:
188
+ - Parent process (CLI) manages the server lifecycle
189
+ - Child process runs the Express application
190
+ - `process.stdin.resume()` keeps the event loop active
191
+ - Press `CTRL+C` for graceful shutdown
192
+
193
+ For more details, see [CLI Usage Documentation](./docs/CLI-USAGE.md).
194
+
131
195
  ## 📁 Project Structure
132
196
 
133
197
  ```
package/config.json CHANGED
@@ -2,6 +2,7 @@
2
2
  "instance": "development",
3
3
  "port": 8080,
4
4
  "hostname": "",
5
+ "publicDirectory": "/public",
5
6
  "mongoDB": {
6
7
  "enabled": false,
7
8
  "port": null,
@@ -10,11 +11,13 @@
10
11
  },
11
12
  "api": {
12
13
  "enabled": false,
13
- "uri": "https://swapi.dev/api/people/",
14
+ "uri": "https://swapi.info/api",
14
15
  "url": "",
15
16
  "method": "GET",
16
17
  "headers": {
17
18
  "Content-Type": "application/json"
18
- }
19
+ },
20
+ "timeout": 30000,
21
+ "retries": 0
19
22
  }
20
23
  }
@@ -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!** ☕
@@ -0,0 +1,429 @@
1
+ # EspressoJS Usage Patterns
2
+
3
+ This guide explains the different ways to use EspressoJS and why some users need to manually call `app.listen()`.
4
+
5
+ ## 📖 Table of Contents
6
+
7
+ - [Understanding the Issue](#understanding-the-issue)
8
+ - [Usage Pattern 1: CLI (Recommended)](#usage-pattern-1-cli-recommended)
9
+ - [Usage Pattern 2: Direct Execution](#usage-pattern-2-direct-execution)
10
+ - [Usage Pattern 3: Programmatic Usage](#usage-pattern-3-programmatic-usage)
11
+ - [Usage Pattern 4: Custom Entry Point](#usage-pattern-4-custom-entry-point)
12
+ - [Troubleshooting](#troubleshooting)
13
+
14
+ ## Understanding the Issue
15
+
16
+ EspressoJS uses a conditional check to automatically start the server:
17
+
18
+ ```javascript
19
+ if (require.main === module) {
20
+ startServer();
21
+ }
22
+ ```
23
+
24
+ **This check determines:**
25
+ - `true` = File is run directly → Server auto-starts
26
+ - `false` = File is required as module → Server does NOT auto-start
27
+
28
+ **When users report needing to add `app.listen()`:**
29
+ - They're using EspressoJS programmatically (Pattern 3 or 4)
30
+ - The `require.main === module` check is `false`
31
+ - The server doesn't auto-start
32
+ - They must manually start it
33
+
34
+ ## Usage Pattern 1: CLI (Recommended)
35
+
36
+ **Best for:** Production deployments, standard usage
37
+
38
+ ### Setup
39
+
40
+ ```javascript
41
+ // cli.js
42
+ require('@misterzik/espressojs/cli');
43
+ ```
44
+
45
+ ```javascript
46
+ // index.js or espresso.js
47
+ require('@misterzik/espressojs');
48
+ ```
49
+
50
+ ### Run
51
+
52
+ ```bash
53
+ node cli run
54
+ # or
55
+ npm start
56
+ ```
57
+
58
+ ### How It Works
59
+
60
+ 1. CLI spawns: `node index.js`
61
+ 2. `require.main === module` is `true`
62
+ 3. Server auto-starts via `startServer()`
63
+ 4. CLI keeps process alive
64
+
65
+ **✅ Advantages:**
66
+ - Automatic server startup
67
+ - Process management handled
68
+ - Configuration commands available
69
+ - Graceful shutdown built-in
70
+
71
+ **❌ Disadvantages:**
72
+ - Extra CLI layer
73
+ - Slightly more complex setup
74
+
75
+ ## Usage Pattern 2: Direct Execution
76
+
77
+ **Best for:** Simple deployments, quick testing
78
+
79
+ ### Setup
80
+
81
+ ```javascript
82
+ // index.js
83
+ require('@misterzik/espressojs');
84
+ ```
85
+
86
+ ### Run
87
+
88
+ ```bash
89
+ node index.js
90
+ ```
91
+
92
+ ### How It Works
93
+
94
+ 1. Node runs `index.js` directly
95
+ 2. `require.main === module` is `true`
96
+ 3. Server auto-starts
97
+
98
+ **✅ Advantages:**
99
+ - Simple and direct
100
+ - No CLI needed
101
+ - Automatic startup
102
+
103
+ **❌ Disadvantages:**
104
+ - No CLI commands
105
+ - Manual configuration management
106
+
107
+ ## Usage Pattern 3: Programmatic Usage
108
+
109
+ **Best for:** Custom applications, advanced integrations
110
+
111
+ ### Setup (OLD - Requires Manual Listen)
112
+
113
+ ```javascript
114
+ // server.js
115
+ const app = require('@misterzik/espressojs');
116
+ const config = require('@misterzik/espressojs/server');
117
+
118
+ // require.main === module is FALSE
119
+ // Server does NOT auto-start
120
+ // Must manually start:
121
+ app.listen(config.port, () => {
122
+ console.log(`Server running on port ${config.port}`);
123
+ });
124
+ ```
125
+
126
+ ### Setup (NEW - v3.3.6+ - Use startServer)
127
+
128
+ ```javascript
129
+ // server.js
130
+ const { startServer } = require('@misterzik/espressojs');
131
+
132
+ // Use the exported startServer function
133
+ startServer();
134
+ ```
135
+
136
+ ### How It Works
137
+
138
+ **OLD Method:**
139
+ 1. User requires EspressoJS as module
140
+ 2. `require.main === module` is `false`
141
+ 3. Server doesn't auto-start
142
+ 4. User must call `app.listen()` manually
143
+
144
+ **NEW Method (v3.3.6+):**
145
+ 1. User requires EspressoJS
146
+ 2. Calls exported `startServer()` function
147
+ 3. Server starts with all built-in features
148
+ 4. Graceful shutdown and error handling included
149
+
150
+ **✅ Advantages:**
151
+ - Full control over server lifecycle
152
+ - Can add custom middleware before starting
153
+ - Integration with existing apps
154
+
155
+ **❌ Disadvantages:**
156
+ - More code required
157
+ - Must understand module system
158
+
159
+ ## Usage Pattern 4: Custom Entry Point
160
+
161
+ **Best for:** Complex applications, microservices
162
+
163
+ ### Setup
164
+
165
+ ```javascript
166
+ // app.js (custom entry point)
167
+ const express = require('@misterzik/espressojs');
168
+ const { apiManager, config, startServer } = require('@misterzik/espressojs');
169
+
170
+ // Add custom middleware
171
+ express.use('/custom', (req, res) => {
172
+ res.json({ message: 'Custom route' });
173
+ });
174
+
175
+ // Add custom error handling
176
+ express.use((err, req, res, next) => {
177
+ console.error('Custom error handler:', err);
178
+ res.status(500).json({ error: err.message });
179
+ });
180
+
181
+ // Start server with built-in features
182
+ startServer();
183
+ ```
184
+
185
+ ### Alternative: Manual Control
186
+
187
+ ```javascript
188
+ // app.js (full manual control)
189
+ const app = require('@misterzik/espressojs');
190
+ const config = require('@misterzik/espressojs/server');
191
+
192
+ // Add custom routes
193
+ app.use('/health', (req, res) => {
194
+ res.json({ status: 'ok', version: '1.0.0' });
195
+ });
196
+
197
+ // Manual server start
198
+ const PORT = process.env.PORT || config.port;
199
+ const server = app.listen(PORT, () => {
200
+ console.log(`Custom server on port ${PORT}`);
201
+ });
202
+
203
+ // Manual graceful shutdown
204
+ process.on('SIGTERM', () => {
205
+ server.close(() => {
206
+ console.log('Server closed');
207
+ process.exit(0);
208
+ });
209
+ });
210
+ ```
211
+
212
+ **✅ Advantages:**
213
+ - Maximum flexibility
214
+ - Full control over everything
215
+ - Custom error handling
216
+
217
+ **❌ Disadvantages:**
218
+ - Most complex
219
+ - Must implement shutdown logic
220
+ - More maintenance
221
+
222
+ ## Exported Functions (v3.3.6+)
223
+
224
+ EspressoJS now exports these functions for programmatic usage:
225
+
226
+ ```javascript
227
+ const {
228
+ startServer, // Start server with all features
229
+ gracefulShutdown, // Graceful shutdown handler
230
+ apiManager, // API request manager
231
+ config, // Configuration object
232
+ server // HTTP server instance (after start)
233
+ } = require('@misterzik/espressojs');
234
+ ```
235
+
236
+ ### startServer()
237
+
238
+ Starts the Express server with all built-in features:
239
+ - Port binding
240
+ - Error handling
241
+ - Graceful shutdown
242
+ - Logging
243
+
244
+ ```javascript
245
+ const { startServer } = require('@misterzik/espressojs');
246
+ startServer();
247
+ ```
248
+
249
+ ### gracefulShutdown(signal)
250
+
251
+ Manually trigger graceful shutdown:
252
+
253
+ ```javascript
254
+ const { gracefulShutdown } = require('@misterzik/espressojs');
255
+
256
+ // Custom shutdown trigger
257
+ setTimeout(() => {
258
+ gracefulShutdown('CUSTOM_SHUTDOWN');
259
+ }, 60000);
260
+ ```
261
+
262
+ ## Troubleshooting
263
+
264
+ ### Server Doesn't Start
265
+
266
+ **Symptom:** No output, server not listening
267
+
268
+ **Cause:** Using programmatic pattern without calling `startServer()` or `app.listen()`
269
+
270
+ **Solution:**
271
+
272
+ ```javascript
273
+ // Option 1: Use exported startServer
274
+ const { startServer } = require('@misterzik/espressojs');
275
+ startServer();
276
+
277
+ // Option 2: Manual listen
278
+ const app = require('@misterzik/espressojs');
279
+ const config = require('@misterzik/espressojs/server');
280
+ app.listen(config.port);
281
+ ```
282
+
283
+ ### Port Not Exposed
284
+
285
+ **Symptom:** Server starts but port not accessible
286
+
287
+ **Cause:** Server started but not bound to correct interface
288
+
289
+ **Solution:**
290
+
291
+ ```javascript
292
+ // Bind to all interfaces (0.0.0.0)
293
+ const app = require('@misterzik/espressojs');
294
+ app.listen(8080, '0.0.0.0', () => {
295
+ console.log('Server accessible on all interfaces');
296
+ });
297
+ ```
298
+
299
+ ### Server Exits Immediately
300
+
301
+ **Symptom:** Server starts then exits
302
+
303
+ **Cause:** No event loop keeping process alive
304
+
305
+ **Solution:**
306
+
307
+ Use CLI method or ensure `app.listen()` is called:
308
+
309
+ ```bash
310
+ # Use CLI (recommended)
311
+ node cli run
312
+
313
+ # Or ensure listen is called in code
314
+ node index.js # Must have app.listen() somewhere
315
+ ```
316
+
317
+ ### "Cannot find module" Error
318
+
319
+ **Symptom:** Module not found when requiring EspressoJS
320
+
321
+ **Cause:** Package not installed or wrong path
322
+
323
+ **Solution:**
324
+
325
+ ```bash
326
+ # Install package
327
+ npm install @misterzik/espressojs
328
+
329
+ # Verify installation
330
+ npm list @misterzik/espressojs
331
+ ```
332
+
333
+ ## Best Practices
334
+
335
+ ### 1. Use CLI for Standard Deployments
336
+
337
+ ```bash
338
+ npm start
339
+ ```
340
+
341
+ ### 2. Use startServer() for Programmatic Usage
342
+
343
+ ```javascript
344
+ const { startServer } = require('@misterzik/espressojs');
345
+ startServer();
346
+ ```
347
+
348
+ ### 3. Use Manual Listen for Maximum Control
349
+
350
+ ```javascript
351
+ const app = require('@misterzik/espressojs');
352
+ // Add custom middleware
353
+ app.listen(3000);
354
+ ```
355
+
356
+ ### 4. Always Handle Errors
357
+
358
+ ```javascript
359
+ const { startServer } = require('@misterzik/espressojs');
360
+
361
+ try {
362
+ startServer();
363
+ } catch (error) {
364
+ console.error('Failed to start:', error);
365
+ process.exit(1);
366
+ }
367
+ ```
368
+
369
+ ### 5. Use Environment Variables
370
+
371
+ ```javascript
372
+ const PORT = process.env.PORT || 8080;
373
+ app.listen(PORT, () => {
374
+ console.log(`Server on port ${PORT}`);
375
+ });
376
+ ```
377
+
378
+ ## Migration Guide
379
+
380
+ ### From Manual Listen to startServer()
381
+
382
+ **Before (v3.3.5 and earlier):**
383
+
384
+ ```javascript
385
+ const app = require('@misterzik/espressojs');
386
+ const config = require('@misterzik/espressojs/server');
387
+
388
+ app.listen(config.port, () => {
389
+ console.log(`Server running on ${config.port}`);
390
+ });
391
+ ```
392
+
393
+ **After (v3.3.6+):**
394
+
395
+ ```javascript
396
+ const { startServer } = require('@misterzik/espressojs');
397
+
398
+ startServer();
399
+ // Logging and error handling included automatically
400
+ ```
401
+
402
+ ### Benefits of Migration
403
+
404
+ - ✅ Built-in error handling
405
+ - ✅ Graceful shutdown
406
+ - ✅ Consistent logging
407
+ - ✅ Less boilerplate code
408
+
409
+ ## Summary
410
+
411
+ | Pattern | Auto-Start | Use Case | Complexity |
412
+ |---------|-----------|----------|------------|
413
+ | CLI | ✅ Yes | Production | Low |
414
+ | Direct | ✅ Yes | Testing | Low |
415
+ | Programmatic | ❌ No* | Integration | Medium |
416
+ | Custom | ❌ No* | Advanced | High |
417
+
418
+ *Use `startServer()` in v3.3.6+ for auto-start with full features
419
+
420
+ ## Support
421
+
422
+ - **GitHub Issues**: https://github.com/misterzik/Espresso.js/issues
423
+ - **Documentation**: https://github.com/misterzik/Espresso.js
424
+ - **npm Package**: https://www.npmjs.com/package/@misterzik/espressojs
425
+
426
+ ---
427
+
428
+ **Version:** 3.3.6+
429
+ **Last Updated:** 2024-12-25
package/index.js CHANGED
@@ -203,6 +203,7 @@ process.on("uncaughtException", (error) => {
203
203
  gracefulShutdown("UNCAUGHT_EXCEPTION");
204
204
  });
205
205
 
206
+ // Auto-start server if run directly (not required as module)
206
207
  if (require.main === module) {
207
208
  try {
208
209
  startServer();
@@ -213,6 +214,10 @@ if (require.main === module) {
213
214
  }
214
215
  }
215
216
 
217
+ // Export app and utilities for programmatic usage
216
218
  module.exports = app;
217
219
  module.exports.apiManager = apiManager;
218
220
  module.exports.config = configData;
221
+ module.exports.startServer = startServer;
222
+ module.exports.gracefulShutdown = gracefulShutdown;
223
+ module.exports.server = server;
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "@misterzik/espressojs",
3
- "version": "3.3.4",
3
+ "version": "3.3.6",
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"
package/routes/index.js CHANGED
@@ -38,8 +38,8 @@ module.exports = (app) => {
38
38
 
39
39
  if (configuration.api && configuration.api.enabled === true) {
40
40
  try {
41
- const apiRoutes = require(path.join(rootDir, "routes", "api.js"));
42
- app.use("/api", apiRoutes);
41
+ const apiRoutes = require(path.join(rootDir, "routes", "api", "index.js"));
42
+ app.use("/", apiRoutes.router);
43
43
  logger.info("API routes loaded successfully");
44
44
  } catch (error) {
45
45
  logger.warn(`API routes not found or failed to load: ${error.message}`);
@@ -56,6 +56,7 @@ module.exports = (app) => {
56
56
  }
57
57
  }
58
58
 
59
+ // Catch-all route must be last to avoid intercepting API routes
59
60
  app.get(
60
61
  "/*",
61
62
  asyncHandler(async (req, res) => {
@@ -76,7 +76,7 @@ function runCommand() {
76
76
  process.exit(code || 0);
77
77
  });
78
78
 
79
- // Keep the CLI process alive
79
+ // Keep the CLI process alive by handling signals
80
80
  process.on('SIGINT', () => {
81
81
  console.log('\nShutting down server...');
82
82
  child.kill('SIGINT');
@@ -85,6 +85,10 @@ function runCommand() {
85
85
  process.on('SIGTERM', () => {
86
86
  child.kill('SIGTERM');
87
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();
88
92
  }
89
93
  }
90
94