@misterzik/espressojs 3.3.5 → 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,37 @@
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
+
5
36
  ## [3.3.5] - 2024-12-25
6
37
 
7
38
  ### 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:
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,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,6 +1,6 @@
1
1
  {
2
2
  "name": "@misterzik/espressojs",
3
- "version": "3.3.5",
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": {
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) => {