kempo-server 1.7.3 → 1.7.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/CONFIG.md ADDED
@@ -0,0 +1,501 @@
1
+ # Configuration
2
+
3
+ To configure the server, create a configuration file (by default `.config.json`) within the root directory of your server (`public` in the start example). You can specify a different configuration file using the `--config` flag.
4
+
5
+ **Important:**
6
+ - When using a relative path for the `--config` flag, the config file must be located within the server root directory
7
+ - When using an absolute path for the `--config` flag, the config file can be located anywhere on the filesystem
8
+ - The server will throw an error if you attempt to use a relative config file path that points outside the root directory
9
+
10
+ ## Command Line Configuration
11
+
12
+ You can specify different configuration files for different environments using the `--config` flag:
13
+
14
+ ```bash
15
+ # Development
16
+ kempo-server --root public --config dev.config.json
17
+
18
+ # Staging
19
+ kempo-server --root public --config staging.config.json
20
+
21
+ # Production with absolute path
22
+ kempo-server --root public --config /etc/kempo/production.config.json
23
+
24
+ # Mix with other options
25
+ kempo-server --root dist --port 8080 --config production.config.json
26
+ ```
27
+
28
+ ## Configuration File Structure
29
+
30
+ This json file can have any of the following properties, any property not defined will use the "Default Config".
31
+
32
+ - [allowedMimes](#allowedmimes)
33
+ - [disallowedRegex](#disallowedregex)
34
+ - [customRoutes](#customroutes)
35
+ - [routeFiles](#routefiles)
36
+ - [noRescanPaths](#norescanpaths)
37
+ - [maxRescanAttempts](#maxrescanattempts)
38
+ - [cache](#cache)
39
+ - [middleware](#middleware)
40
+
41
+ ## Cache
42
+
43
+ Kempo Server includes an intelligent module caching system that dramatically improves performance by caching JavaScript route modules in memory. The cache combines multiple strategies:
44
+
45
+ - **LRU (Least Recently Used)** - Evicts oldest modules when cache fills
46
+ - **Time-based expiration** - Modules expire after configurable TTL
47
+ - **Memory monitoring** - Automatically clears cache if memory usage gets too high
48
+ - **File watching** - Instantly invalidates cache when files change (development)
49
+
50
+ ### Basic Cache Configuration
51
+
52
+ Enable caching in your `.config.json`:
53
+
54
+ ```json
55
+ {
56
+ "cache": {
57
+ "enabled": true,
58
+ "maxSize": 100,
59
+ "maxMemoryMB": 50,
60
+ "ttlMs": 300000,
61
+ "watchFiles": true
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### Cache Options
67
+
68
+ - `enabled` (boolean) - Enable/disable caching (default: `true`)
69
+ - `maxSize` (number) - Maximum cached modules (default: `100`)
70
+ - `maxMemoryMB` (number) - Memory limit in MB (default: `50`)
71
+ - `ttlMs` (number) - Cache lifetime in milliseconds (default: `300000` - 5 minutes)
72
+ - `maxHeapUsagePercent` (number) - Clear cache when heap exceeds % (default: `70`)
73
+ - `memoryCheckInterval` (number) - Memory check frequency in ms (default: `30000`)
74
+ - `watchFiles` (boolean) - Auto-invalidate on file changes (default: `true`)
75
+ - `enableMemoryMonitoring` (boolean) - Enable memory monitoring (default: `true`)
76
+
77
+ Run with specific config: `kempo-server --config prod.config.json`
78
+
79
+ ### Cache Monitoring
80
+
81
+ Monitor cache performance at runtime:
82
+
83
+ - **View stats:** `GET /_admin/cache` - Returns detailed cache statistics
84
+ - **Clear cache:** `DELETE /_admin/cache` - Clears entire cache
85
+
86
+ Example response:
87
+ ```json
88
+ {
89
+ "cache": {
90
+ "size": 45,
91
+ "maxSize": 100,
92
+ "memoryUsageMB": 12.5,
93
+ "hitRate": 87
94
+ }
95
+ }
96
+ ```
97
+
98
+ ## Middleware
99
+
100
+ Kempo Server includes a powerful middleware system that allows you to add functionality like authentication, logging, CORS, compression, and more. Middleware runs before your route handlers and can modify requests, responses, or handle requests entirely.
101
+
102
+ ### Built-in Middleware
103
+
104
+ #### CORS
105
+ Enable Cross-Origin Resource Sharing for your API:
106
+
107
+ ```json
108
+ {
109
+ "middleware": {
110
+ "cors": {
111
+ "enabled": true,
112
+ "origin": "*",
113
+ "methods": ["GET", "POST", "PUT", "DELETE"],
114
+ "headers": ["Content-Type", "Authorization"]
115
+ }
116
+ }
117
+ }
118
+ ```
119
+
120
+ #### Compression
121
+ Automatically compress responses with gzip:
122
+
123
+ ```json
124
+ {
125
+ "middleware": {
126
+ "compression": {
127
+ "enabled": true,
128
+ "threshold": 1024
129
+ }
130
+ }
131
+ }
132
+ ```
133
+
134
+ #### Rate Limiting
135
+ Limit requests per client to prevent abuse:
136
+
137
+ ```json
138
+ {
139
+ "middleware": {
140
+ "rateLimit": {
141
+ "enabled": true,
142
+ "maxRequests": 100,
143
+ "windowMs": 60000,
144
+ "message": "Too many requests"
145
+ }
146
+ }
147
+ }
148
+ ```
149
+
150
+ #### Security Headers
151
+ Add security headers to all responses:
152
+
153
+ ```json
154
+ {
155
+ "middleware": {
156
+ "security": {
157
+ "enabled": true,
158
+ "headers": {
159
+ "X-Content-Type-Options": "nosniff",
160
+ "X-Frame-Options": "DENY",
161
+ "X-XSS-Protection": "1; mode=block"
162
+ }
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ #### Request Logging
169
+ Log requests with configurable detail:
170
+
171
+ ```json
172
+ {
173
+ "middleware": {
174
+ "logging": {
175
+ "enabled": true,
176
+ "includeUserAgent": true,
177
+ "includeResponseTime": true
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ### Custom Middleware
184
+
185
+ Create your own middleware by writing JavaScript files and referencing them in your config:
186
+
187
+ ```json
188
+ {
189
+ "middleware": {
190
+ "custom": ["./middleware/auth.js", "./middleware/analytics.js"]
191
+ }
192
+ }
193
+ ```
194
+
195
+ #### Custom Middleware Example
196
+
197
+ ```javascript
198
+ // middleware/auth.js
199
+ export default (config) => {
200
+ return async (req, res, next) => {
201
+ const token = req.headers.authorization;
202
+
203
+ if (!token) {
204
+ req.user = null;
205
+ return await next();
206
+ }
207
+
208
+ try {
209
+ // Verify JWT token (example)
210
+ const user = verifyToken(token);
211
+ req.user = user;
212
+ req.permissions = await getUserPermissions(user.id);
213
+
214
+ // Add helper methods
215
+ req.hasPermission = (permission) => req.permissions.includes(permission);
216
+
217
+ } catch (error) {
218
+ req.user = null;
219
+ }
220
+
221
+ await next();
222
+ };
223
+ };
224
+ ```
225
+
226
+ #### Using Enhanced Requests in Routes
227
+
228
+ Your route files can now access the enhanced request object:
229
+
230
+ ```javascript
231
+ // api/user/profile/GET.js
232
+ export default async (req, res, params) => {
233
+ if (!req.user) {
234
+ return res.status(401).json({ error: 'Authentication required' });
235
+ }
236
+
237
+ if (!req.hasPermission('user:read')) {
238
+ return res.status(403).json({ error: 'Insufficient permissions' });
239
+ }
240
+
241
+ const profile = await getUserProfile(req.user.id);
242
+ res.json(profile);
243
+ };
244
+ ```
245
+
246
+ ### Middleware Order
247
+
248
+ Middleware executes in this order:
249
+ 1. Built-in middleware (cors, compression, rateLimit, security, logging)
250
+ 2. Custom middleware (in the order listed in config)
251
+ 3. Your route handlers
252
+
253
+ ### Route Interception
254
+
255
+ Middleware can intercept and handle routes completely, useful for authentication endpoints:
256
+
257
+ ```javascript
258
+ // middleware/auth-routes.js
259
+ export default (config) => {
260
+ return async (req, res, next) => {
261
+ const url = new URL(req.url, `http://${req.headers.host}`);
262
+
263
+ // Handle login endpoint
264
+ if (req.method === 'POST' && url.pathname === '/auth/login') {
265
+ const credentials = await req.json();
266
+ const token = await authenticateUser(credentials);
267
+
268
+ if (token) {
269
+ return res.json({ token, success: true });
270
+ } else {
271
+ return res.status(401).json({ error: 'Invalid credentials' });
272
+ }
273
+ }
274
+
275
+ await next();
276
+ };
277
+ };
278
+ ```
279
+
280
+ ## Configuration Options
281
+
282
+ ### allowedMimes
283
+
284
+ An object mapping file extensions to their MIME types. Files with extensions not in this list will not be served.
285
+
286
+ ```json
287
+ {
288
+ "allowedMimes": {
289
+ "html": "text/html",
290
+ "css": "text/css",
291
+ "js": "application/javascript",
292
+ "json": "application/json",
293
+ "png": "image/png",
294
+ "jpg": "image/jpeg"
295
+ }
296
+ }
297
+ ```
298
+
299
+ ### disallowedRegex
300
+
301
+ An array of regular expressions that match paths that should never be served. This provides security by preventing access to sensitive files.
302
+
303
+ ```json
304
+ {
305
+ "disallowedRegex": [
306
+ "^/\\..*",
307
+ "\\.env$",
308
+ "\\.config$",
309
+ "password"
310
+ ]
311
+ }
312
+ ```
313
+
314
+ ### routeFiles
315
+
316
+ An array of filenames that should be treated as route handlers and executed as JavaScript modules.
317
+
318
+ ```json
319
+ {
320
+ "routeFiles": [
321
+ "GET.js",
322
+ "POST.js",
323
+ "PUT.js",
324
+ "DELETE.js",
325
+ "index.js"
326
+ ]
327
+ }
328
+ ```
329
+
330
+ ### noRescanPaths
331
+
332
+ An array of regex patterns for paths that should not trigger a file system rescan. This improves performance for common static assets.
333
+
334
+ ```json
335
+ {
336
+ "noRescanPaths": [
337
+ "/favicon\\.ico$",
338
+ "/robots\\.txt$",
339
+ "\\.map$"
340
+ ]
341
+ }
342
+ ```
343
+
344
+ ### customRoutes
345
+
346
+ An object mapping custom route paths to file paths. Useful for aliasing or serving files from outside the document root.
347
+
348
+ **Note:** All file paths in customRoutes are resolved relative to the server root directory (the `--root` path). This allows you to reference files both inside and outside the document root.
349
+
350
+ **Basic Routes:**
351
+ ```json
352
+ {
353
+ "customRoutes": {
354
+ "/vendor/bootstrap.css": "../node_modules/bootstrap/dist/css/bootstrap.min.css",
355
+ "/api/status": "./status.js"
356
+ }
357
+ }
358
+ ```
359
+
360
+ **Wildcard Routes:**
361
+ Wildcard routes allow you to map entire directory structures using the `*` and `**` wildcards:
362
+
363
+ ```json
364
+ {
365
+ "customRoutes": {
366
+ "kempo/*": "../node_modules/kempo/dist/*",
367
+ "assets/*": "../static-files/*",
368
+ "docs/*": "../documentation/*",
369
+ "src/**": "../src/**"
370
+ }
371
+ }
372
+ ```
373
+
374
+ With wildcard routes:
375
+ - `kempo/styles.css` would serve `../node_modules/kempo/dist/styles.css`
376
+ - `assets/logo.png` would serve `../static-files/logo.png`
377
+ - `docs/readme.md` would serve `../documentation/readme.md`
378
+ - `src/components/Button.js` would serve `../src/components/Button.js`
379
+
380
+ The `*` wildcard matches any single path segment (anything between `/` characters).
381
+ The `**` wildcard matches any number of path segments, allowing you to map entire directory trees.
382
+ Multiple wildcards can be used in a single route pattern.
383
+
384
+ ### maxRescanAttempts
385
+
386
+ The maximum number of times to attempt rescanning the file system when a file is not found. Defaults to 3.
387
+
388
+ ```json
389
+ {
390
+ "maxRescanAttempts": 3
391
+ }
392
+ ```
393
+
394
+ ## Configuration Examples
395
+
396
+ ### Development Environment
397
+
398
+ **Focus: Fast iteration and debugging**
399
+ ```json
400
+ {
401
+ "cache": {
402
+ "enabled": true,
403
+ "maxSize": 50,
404
+ "ttlMs": 300000,
405
+ "watchFiles": true
406
+ },
407
+ "middleware": {
408
+ "cors": {
409
+ "enabled": true,
410
+ "origin": "*"
411
+ },
412
+ "logging": {
413
+ "enabled": true,
414
+ "includeUserAgent": true,
415
+ "includeResponseTime": true
416
+ }
417
+ }
418
+ }
419
+ ```
420
+
421
+ ### Production Environment
422
+
423
+ **Focus: Performance, security, and stability**
424
+ ```json
425
+ {
426
+ "cache": {
427
+ "enabled": true,
428
+ "maxSize": 1000,
429
+ "maxMemoryMB": 200,
430
+ "ttlMs": 3600000,
431
+ "maxHeapUsagePercent": 85,
432
+ "memoryCheckInterval": 60000,
433
+ "watchFiles": false
434
+ },
435
+ "middleware": {
436
+ "cors": {
437
+ "enabled": true,
438
+ "origin": ["https://myapp.com", "https://www.myapp.com"],
439
+ "credentials": true
440
+ },
441
+ "compression": {
442
+ "enabled": true,
443
+ "threshold": 1024
444
+ },
445
+ "security": {
446
+ "enabled": true,
447
+ "headers": {
448
+ "X-Content-Type-Options": "nosniff",
449
+ "X-Frame-Options": "DENY",
450
+ "X-XSS-Protection": "1; mode=block",
451
+ "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
452
+ }
453
+ },
454
+ "logging": {
455
+ "enabled": true,
456
+ "includeUserAgent": false,
457
+ "includeResponseTime": true
458
+ }
459
+ }
460
+ }
461
+ ```
462
+
463
+ ### Low-Memory Environment
464
+
465
+ **Focus: Minimal resource usage**
466
+ ```json
467
+ {
468
+ "cache": {
469
+ "enabled": true,
470
+ "maxSize": 20,
471
+ "maxMemoryMB": 5,
472
+ "ttlMs": 120000,
473
+ "maxHeapUsagePercent": 60,
474
+ "memoryCheckInterval": 10000
475
+ }
476
+ }
477
+ ```
478
+
479
+ ### Debugging Environment
480
+
481
+ **Focus: Cache disabled for troubleshooting**
482
+ ```json
483
+ {
484
+ "cache": {
485
+ "enabled": false
486
+ },
487
+ "middleware": {
488
+ "logging": {
489
+ "enabled": true,
490
+ "includeUserAgent": true,
491
+ "includeResponseTime": true
492
+ }
493
+ }
494
+ }
495
+ ```
496
+
497
+ ## Additional Resources
498
+
499
+ - **HTML Documentation**: See `docs/configuration.html` for detailed web-based documentation
500
+ - **Caching Guide**: See `docs/caching.html` for comprehensive caching documentation
501
+ - **Middleware Guide**: See `docs/middleware.html` for detailed middleware documentation