kempo-server 1.3.0 → 1.4.3
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/.github/copilot-instructions.md +96 -0
- package/README.md +212 -4
- package/docs/configuration.html +119 -0
- package/docs/examples.html +201 -0
- package/docs/getting-started.html +72 -0
- package/docs/index.html +53 -330
- package/docs/manifest.json +87 -0
- package/docs/media/hexagon.svg +22 -0
- package/docs/media/icon-maskable.png +0 -0
- package/docs/media/icon.svg +44 -0
- package/docs/media/icon128.png +0 -0
- package/docs/media/icon144.png +0 -0
- package/docs/media/icon152.png +0 -0
- package/docs/media/icon16-48.svg +21 -0
- package/docs/media/icon16.png +0 -0
- package/docs/media/icon192.png +0 -0
- package/docs/media/icon256.png +0 -0
- package/docs/media/icon32.png +0 -0
- package/docs/media/icon384.png +0 -0
- package/docs/media/icon48.png +0 -0
- package/docs/media/icon512.png +0 -0
- package/docs/media/icon64.png +0 -0
- package/docs/media/icon72.png +0 -0
- package/docs/media/icon96.png +0 -0
- package/docs/media/kempo-fist.svg +21 -0
- package/docs/middleware.html +147 -0
- package/docs/request-response.html +95 -0
- package/docs/routing.html +77 -0
- package/package.json +8 -3
- package/tests/builtinMiddleware-cors.node-test.js +17 -0
- package/tests/builtinMiddleware.node-test.js +74 -0
- package/tests/defaultConfig.node-test.js +13 -0
- package/tests/example-middleware.node-test.js +31 -0
- package/tests/findFile.node-test.js +46 -0
- package/tests/getFiles.node-test.js +25 -0
- package/tests/getFlags.node-test.js +30 -0
- package/tests/index.node-test.js +23 -0
- package/tests/middlewareRunner.node-test.js +18 -0
- package/tests/requestWrapper.node-test.js +51 -0
- package/tests/responseWrapper.node-test.js +74 -0
- package/tests/router-middleware.node-test.js +46 -0
- package/tests/router.node-test.js +88 -0
- package/tests/serveFile.node-test.js +52 -0
- package/tests/test-utils.js +106 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Code Contribution Guidelines
|
|
2
|
+
|
|
3
|
+
## Coding Style Guidelines
|
|
4
|
+
|
|
5
|
+
### Code Organization
|
|
6
|
+
Use multi-line comments to separate code into logical sections. Group related functionality together.
|
|
7
|
+
- Example: In Lit components, group lifecycle callbacks, event handlers, public methods, utility functions, and rendering logic separately.
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
/*
|
|
11
|
+
Lifecycle Callbacks
|
|
12
|
+
*/
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Avoid single-use variables/functions
|
|
16
|
+
Avoid defining a variable or function to only use it once; inline the logic where needed. Some exceptions include:
|
|
17
|
+
- recursion
|
|
18
|
+
- scope encapsulation (IIFE)
|
|
19
|
+
- context changes
|
|
20
|
+
|
|
21
|
+
### Minimal Comments, Empty Lines, and Spacing
|
|
22
|
+
|
|
23
|
+
Use minimal comments. Assume readers understand the language. Some exceptions include:
|
|
24
|
+
- complex logic
|
|
25
|
+
- anti-patterns
|
|
26
|
+
- code organization
|
|
27
|
+
|
|
28
|
+
Do not put random empty lines within code; put them where they make sense for readability, for example:
|
|
29
|
+
- above and below definitions for functions and classes.
|
|
30
|
+
- to help break up large sections of logic to be more readable. If there are 100 lines of code with no breaks, it gets hard to read.
|
|
31
|
+
- above multi-line comments to indicate the comment belongs to the code below
|
|
32
|
+
|
|
33
|
+
No empty lines in css.
|
|
34
|
+
|
|
35
|
+
End each file with an empty line.
|
|
36
|
+
|
|
37
|
+
End each line with a `;` when possible, even if it is optional.
|
|
38
|
+
|
|
39
|
+
Avoid unnecessary spacing, for example:
|
|
40
|
+
- after the word `if`
|
|
41
|
+
- within parentheses for conditional statements
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
let count = 1;
|
|
45
|
+
|
|
46
|
+
const incrementOdd = (n) => {
|
|
47
|
+
if(n % 2 !== 0){
|
|
48
|
+
return n++;
|
|
49
|
+
}
|
|
50
|
+
return n;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
count = incrementOdd(count);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Prefer Arrow Functions
|
|
57
|
+
Prefer the use of arrow functions when possible, especially for class methods to avoid binding. Use normal functions if needed for preserving the proper context.
|
|
58
|
+
- For very basic logic, use implicit returns
|
|
59
|
+
- If there is a single parameter, omit the parentheses.
|
|
60
|
+
```javascript
|
|
61
|
+
const addOne = n => n + 1;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Module Exports
|
|
65
|
+
- If a module has only one export, use the "default" export, not a named export.
|
|
66
|
+
- Do not declare the default export as a const or give it a name; just export the value.
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
export default (n) => n + 1;
|
|
70
|
+
```
|
|
71
|
+
- If a module has multiple exports, use named exports and do not use a "default" export.
|
|
72
|
+
|
|
73
|
+
### Code Reuse
|
|
74
|
+
Create utility functions for shared logic.
|
|
75
|
+
- If the shared logic is used in a single file, define a utility function in that file.
|
|
76
|
+
- If the shared logic is used in multiple files, create a utility function module file in `src/utils/`.
|
|
77
|
+
|
|
78
|
+
### Naming
|
|
79
|
+
Do not prefix identifiers with underscores.
|
|
80
|
+
- Never use leading underscores (`_`) for variable, property, method, or function names.
|
|
81
|
+
- Use clear, descriptive names without prefixes.
|
|
82
|
+
- When true privacy is needed inside classes, prefer native JavaScript private fields (e.g., `#myField`) instead of simulated privacy via underscores.
|
|
83
|
+
|
|
84
|
+
## Lit Components
|
|
85
|
+
|
|
86
|
+
### Component Architecture and Communication
|
|
87
|
+
|
|
88
|
+
- Use methods to cause actions; do not emit events to trigger logic. Events are for notifying that something already happened.
|
|
89
|
+
- Prefer `el.closest('ktf-test-framework')?.enqueueSuite({...})` over firing an `enqueue` event.
|
|
90
|
+
|
|
91
|
+
- Wrap dependent GUI components inside a parent `ktf-test-framework` element. Children find it via `closest('ktf-test-framework')` and call its methods. The framework can query its subtree to orchestrate children.
|
|
92
|
+
|
|
93
|
+
- Avoid `window` globals and global custom events for coordination. If broadcast is needed, scope events to the framework element; reserve window events for global, non-visual concerns (e.g., settings changes).
|
|
94
|
+
|
|
95
|
+
- Queued status must show the `scheduled` icon. Running may apply `animation="spin"`.
|
|
96
|
+
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ npm install kempo-server
|
|
|
12
12
|
|
|
13
13
|
2. Add it to your `package.json` scripts, use the `--root` flag to tell it where the root of your site is.
|
|
14
14
|
|
|
15
|
-
```
|
|
15
|
+
```
|
|
16
16
|
{
|
|
17
17
|
...
|
|
18
18
|
"scripts": {
|
|
@@ -213,7 +213,7 @@ export default async function(request, response) {
|
|
|
213
213
|
|
|
214
214
|
To configure the server create a `.config.json` within the root directory of your server (`public` in the start example [above](#getting-started)).
|
|
215
215
|
|
|
216
|
-
This json file can have any of the following
|
|
216
|
+
This json file can have any of the following properties, any property not defined will use the "Default Config".
|
|
217
217
|
|
|
218
218
|
- [allowedMimes](#allowedmimes)
|
|
219
219
|
- [disallowedRegex](#disallowedregex)
|
|
@@ -221,6 +221,189 @@ This json file can have any of the following 6 properties, any property not defi
|
|
|
221
221
|
- [routeFiles](#routefiles)
|
|
222
222
|
- [noRescanPaths](#norescanpaths)
|
|
223
223
|
- [maxRescanAttempts](#maxrescanattempts)
|
|
224
|
+
- [middleware](#middleware)
|
|
225
|
+
|
|
226
|
+
## Middleware
|
|
227
|
+
|
|
228
|
+
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.
|
|
229
|
+
|
|
230
|
+
### Built-in Middleware
|
|
231
|
+
|
|
232
|
+
#### CORS
|
|
233
|
+
Enable Cross-Origin Resource Sharing for your API:
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"middleware": {
|
|
238
|
+
"cors": {
|
|
239
|
+
"enabled": true,
|
|
240
|
+
"origin": "*",
|
|
241
|
+
"methods": ["GET", "POST", "PUT", "DELETE"],
|
|
242
|
+
"headers": ["Content-Type", "Authorization"]
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Compression
|
|
249
|
+
Automatically compress responses with gzip:
|
|
250
|
+
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"middleware": {
|
|
254
|
+
"compression": {
|
|
255
|
+
"enabled": true,
|
|
256
|
+
"threshold": 1024
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### Rate Limiting
|
|
263
|
+
Limit requests per client to prevent abuse:
|
|
264
|
+
|
|
265
|
+
```json
|
|
266
|
+
{
|
|
267
|
+
"middleware": {
|
|
268
|
+
"rateLimit": {
|
|
269
|
+
"enabled": true,
|
|
270
|
+
"maxRequests": 100,
|
|
271
|
+
"windowMs": 60000,
|
|
272
|
+
"message": "Too many requests"
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
#### Security Headers
|
|
279
|
+
Add security headers to all responses:
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
{
|
|
283
|
+
"middleware": {
|
|
284
|
+
"security": {
|
|
285
|
+
"enabled": true,
|
|
286
|
+
"headers": {
|
|
287
|
+
"X-Content-Type-Options": "nosniff",
|
|
288
|
+
"X-Frame-Options": "DENY",
|
|
289
|
+
"X-XSS-Protection": "1; mode=block"
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### Request Logging
|
|
297
|
+
Log requests with configurable detail:
|
|
298
|
+
|
|
299
|
+
```json
|
|
300
|
+
{
|
|
301
|
+
"middleware": {
|
|
302
|
+
"logging": {
|
|
303
|
+
"enabled": true,
|
|
304
|
+
"includeUserAgent": true,
|
|
305
|
+
"includeResponseTime": true
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Custom Middleware
|
|
312
|
+
|
|
313
|
+
Create your own middleware by writing JavaScript files and referencing them in your config:
|
|
314
|
+
|
|
315
|
+
```json
|
|
316
|
+
{
|
|
317
|
+
"middleware": {
|
|
318
|
+
"custom": ["./middleware/auth.js", "./middleware/analytics.js"]
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### Custom Middleware Example
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
// middleware/auth.js
|
|
327
|
+
export default (config) => {
|
|
328
|
+
return async (req, res, next) => {
|
|
329
|
+
const token = req.headers.authorization;
|
|
330
|
+
|
|
331
|
+
if (!token) {
|
|
332
|
+
req.user = null;
|
|
333
|
+
return await next();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
try {
|
|
337
|
+
// Verify JWT token (example)
|
|
338
|
+
const user = verifyToken(token);
|
|
339
|
+
req.user = user;
|
|
340
|
+
req.permissions = await getUserPermissions(user.id);
|
|
341
|
+
|
|
342
|
+
// Add helper methods
|
|
343
|
+
req.hasPermission = (permission) => req.permissions.includes(permission);
|
|
344
|
+
|
|
345
|
+
} catch (error) {
|
|
346
|
+
req.user = null;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
await next();
|
|
350
|
+
};
|
|
351
|
+
};
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
#### Using Enhanced Requests in Routes
|
|
355
|
+
|
|
356
|
+
Your route files can now access the enhanced request object:
|
|
357
|
+
|
|
358
|
+
```javascript
|
|
359
|
+
// api/user/profile/GET.js
|
|
360
|
+
export default async (req, res, params) => {
|
|
361
|
+
if (!req.user) {
|
|
362
|
+
return res.status(401).json({ error: 'Authentication required' });
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (!req.hasPermission('user:read')) {
|
|
366
|
+
return res.status(403).json({ error: 'Insufficient permissions' });
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const profile = await getUserProfile(req.user.id);
|
|
370
|
+
res.json(profile);
|
|
371
|
+
};
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Middleware Order
|
|
375
|
+
|
|
376
|
+
Middleware executes in this order:
|
|
377
|
+
1. Built-in middleware (cors, compression, rateLimit, security, logging)
|
|
378
|
+
2. Custom middleware (in the order listed in config)
|
|
379
|
+
3. Your route handlers
|
|
380
|
+
|
|
381
|
+
### Route Interception
|
|
382
|
+
|
|
383
|
+
Middleware can intercept and handle routes completely, useful for authentication endpoints:
|
|
384
|
+
|
|
385
|
+
```javascript
|
|
386
|
+
// middleware/auth-routes.js
|
|
387
|
+
export default (config) => {
|
|
388
|
+
return async (req, res, next) => {
|
|
389
|
+
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
390
|
+
|
|
391
|
+
// Handle login endpoint
|
|
392
|
+
if (req.method === 'POST' && url.pathname === '/auth/login') {
|
|
393
|
+
const credentials = await req.json();
|
|
394
|
+
const token = await authenticateUser(credentials);
|
|
395
|
+
|
|
396
|
+
if (token) {
|
|
397
|
+
return res.json({ token, success: true });
|
|
398
|
+
} else {
|
|
399
|
+
return res.status(401).json({ error: 'Invalid credentials' });
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
await next();
|
|
404
|
+
};
|
|
405
|
+
};
|
|
406
|
+
```
|
|
224
407
|
|
|
225
408
|
### allowedMimes
|
|
226
409
|
|
|
@@ -333,6 +516,8 @@ The maximum number of times to attempt rescanning the file system when a file is
|
|
|
333
516
|
- **Zero Dependencies** - No external dependencies required
|
|
334
517
|
- **File-based Routing** - Routes are defined by your directory structure
|
|
335
518
|
- **Dynamic Routes** - Support for parameterized routes with square bracket syntax
|
|
519
|
+
- **Wildcard Routes** - Map entire directory structures with wildcard patterns
|
|
520
|
+
- **Middleware System** - Built-in and custom middleware support for authentication, logging, CORS, and more
|
|
336
521
|
- **Request Object** - Request handling with built-in body parsing
|
|
337
522
|
- **Response Object** - Response handling with chainable methods
|
|
338
523
|
- **Multiple HTTP Methods** - Support for GET, POST, PUT, DELETE, and more
|
|
@@ -340,8 +525,8 @@ The maximum number of times to attempt rescanning the file system when a file is
|
|
|
340
525
|
- **HTML Routes** - Support for both JavaScript and HTML route handlers
|
|
341
526
|
- **Query Parameters** - Easy access to URL query parameters
|
|
342
527
|
- **Configurable** - Customize behavior with a simple JSON config file
|
|
343
|
-
- **Security** - Built-in protection against serving sensitive files
|
|
344
|
-
- **Performance** - Smart file system caching and
|
|
528
|
+
- **Security** - Built-in protection against serving sensitive files plus security headers middleware
|
|
529
|
+
- **Performance** - Smart file system caching, rescan optimization, and optional compression
|
|
345
530
|
|
|
346
531
|
## Examples
|
|
347
532
|
|
|
@@ -440,3 +625,26 @@ Kempo Server supports several command line options to customize its behavior:
|
|
|
440
625
|
```bash
|
|
441
626
|
kempo-server --root public --port 8080 --host 0.0.0.0 --verbose
|
|
442
627
|
```
|
|
628
|
+
|
|
629
|
+
## Testing
|
|
630
|
+
|
|
631
|
+
This project uses the Kempo Testing Framework. Tests live in the `tests/` folder and follow these naming conventions:
|
|
632
|
+
|
|
633
|
+
- `[name].node-test.js` — Node-only tests
|
|
634
|
+
- `[name].browser-test.js` — Browser-only tests
|
|
635
|
+
- `[name].test.js` — Runs in both environments
|
|
636
|
+
|
|
637
|
+
### Run tests
|
|
638
|
+
|
|
639
|
+
Using npm scripts:
|
|
640
|
+
|
|
641
|
+
```bash
|
|
642
|
+
npm run tests # Run all tests (Node + Browser)
|
|
643
|
+
npm run tests:node # Run Node tests only
|
|
644
|
+
npm run tests:browser # Run Browser tests only
|
|
645
|
+
npm run tests:gui # Start the GUI test runner
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
For advanced usage (filters, flags, GUI options), see:
|
|
649
|
+
https://github.com/dustinpoissant/kempo-testing-framework
|
|
650
|
+
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<html lang="en" theme="auto">
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset='utf-8'>
|
|
4
|
+
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
|
5
|
+
<title>Configuration - Kempo Server</title>
|
|
6
|
+
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
|
7
|
+
<link rel="icon" type="image/png" sizes="48x48" href="media/icon48.png">
|
|
8
|
+
<link rel="manifest" href="manifest.json">
|
|
9
|
+
<link rel="stylesheet" href="essential.css" />
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<main>
|
|
13
|
+
<a href="./" class="btn">Home</a>
|
|
14
|
+
<h1>Configuration</h1>
|
|
15
|
+
<p>Customize Kempo Server's behavior with a simple JSON configuration file.</p>
|
|
16
|
+
|
|
17
|
+
<h2>Configuration File</h2>
|
|
18
|
+
<p>To configure the server create a <code>.config.json</code> within the root directory of your server (<code>public</code> in the start example).</p>
|
|
19
|
+
<p>This json file can have any of the following properties. Any property not defined will use the default configuration.</p>
|
|
20
|
+
|
|
21
|
+
<h2>Configuration Options</h2>
|
|
22
|
+
<ul>
|
|
23
|
+
<li><a href="#allowedMimes">allowedMimes</a> - File types that can be served</li>
|
|
24
|
+
<li><a href="#disallowedRegex">disallowedRegex</a> - Patterns for paths that should be blocked</li>
|
|
25
|
+
<li><a href="#customRoutes">customRoutes</a> - Custom route mappings</li>
|
|
26
|
+
<li><a href="#routeFiles">routeFiles</a> - Files that should be treated as route handlers</li>
|
|
27
|
+
<li><a href="#noRescanPaths">noRescanPaths</a> - Paths that should not trigger file system rescans</li>
|
|
28
|
+
<li><a href="#maxRescanAttempts">maxRescanAttempts</a> - Maximum number of rescan attempts</li>
|
|
29
|
+
<li><a href="#middleware">middleware</a> - Middleware configuration</li>
|
|
30
|
+
</ul>
|
|
31
|
+
|
|
32
|
+
<h3 id="allowedMimes">allowedMimes</h3>
|
|
33
|
+
<p>An object mapping file extensions to their MIME types. Files with extensions not in this list will not be served.</p>
|
|
34
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"allowedMimes"</span>: {<br /> <span class="hljs-attr">"html"</span>: <span class="hljs-string">"text/html"</span>,<br /> <span class="hljs-attr">"css"</span>: <span class="hljs-string">"text/css"</span>,<br /> <span class="hljs-attr">"js"</span>: <span class="hljs-string">"application/javascript"</span>,<br /> <span class="hljs-attr">"json"</span>: <span class="hljs-string">"application/json"</span>,<br /> <span class="hljs-attr">"png"</span>: <span class="hljs-string">"image/png"</span>,<br /> <span class="hljs-attr">"jpg"</span>: <span class="hljs-string">"image/jpeg"</span>,<br /> <span class="hljs-attr">"jpeg"</span>: <span class="hljs-string">"image/jpeg"</span>,<br /> <span class="hljs-attr">"gif"</span>: <span class="hljs-string">"image/gif"</span>,<br /> <span class="hljs-attr">"svg"</span>: <span class="hljs-string">"image/svg+xml"</span>,<br /> <span class="hljs-attr">"woff"</span>: <span class="hljs-string">"font/woff"</span>,<br /> <span class="hljs-attr">"woff2"</span>: <span class="hljs-string">"font/woff2"</span><br /> }<br />}</code></pre>
|
|
35
|
+
|
|
36
|
+
<h3 id="disallowedRegex">disallowedRegex</h3>
|
|
37
|
+
<p>An array of regular expressions that match paths that should never be served. This provides security by preventing access to sensitive files.</p>
|
|
38
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"disallowedRegex"</span>: [<br /> <span class="hljs-string">"^/\\..*"</span>, <span class="hljs-comment">// Hidden files (starting with .)</span><br /> <span class="hljs-string">"\\.env$"</span>, <span class="hljs-comment">// Environment files</span><br /> <span class="hljs-string">"\\.config$"</span>, <span class="hljs-comment">// Configuration files</span><br /> <span class="hljs-string">"password"</span>, <span class="hljs-comment">// Files containing "password"</span><br /> <span class="hljs-string">"node_modules"</span>, <span class="hljs-comment">// Node modules directory</span><br /> <span class="hljs-string">"\\.git"</span> <span class="hljs-comment">// Git directory</span><br /> ]<br />}</code></pre>
|
|
39
|
+
|
|
40
|
+
<h3 id="routeFiles">routeFiles</h3>
|
|
41
|
+
<p>An array of filenames that should be treated as route handlers and executed as JavaScript modules.</p>
|
|
42
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"routeFiles"</span>: [<br /> <span class="hljs-string">"GET.js"</span>,<br /> <span class="hljs-string">"POST.js"</span>,<br /> <span class="hljs-string">"PUT.js"</span>,<br /> <span class="hljs-string">"DELETE.js"</span>,<br /> <span class="hljs-string">"PATCH.js"</span>,<br /> <span class="hljs-string">"HEAD.js"</span>,<br /> <span class="hljs-string">"OPTIONS.js"</span>,<br /> <span class="hljs-string">"index.js"</span><br /> ]<br />}</code></pre>
|
|
43
|
+
|
|
44
|
+
<h3 id="noRescanPaths">noRescanPaths</h3>
|
|
45
|
+
<p>An array of regex patterns for paths that should not trigger a file system rescan. This improves performance for common static assets.</p>
|
|
46
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"noRescanPaths"</span>: [<br /> <span class="hljs-string">"/favicon\\.ico$"</span>,<br /> <span class="hljs-string">"/robots\\.txt$"</span>,<br /> <span class="hljs-string">"\\.map$"</span>,<br /> <span class="hljs-string">"\\.css$"</span>,<br /> <span class="hljs-string">"\\.js$"</span>,<br /> <span class="hljs-string">"\\.png$"</span>,<br /> <span class="hljs-string">"\\.jpg$"</span>,<br /> <span class="hljs-string">"\\.jpeg$"</span>,<br /> <span class="hljs-string">"\\.gif$"</span><br /> ]<br />}</code></pre>
|
|
47
|
+
|
|
48
|
+
<h3 id="customRoutes">customRoutes</h3>
|
|
49
|
+
<p>An object mapping custom route paths to file paths. Useful for aliasing or serving files from outside the document root.</p>
|
|
50
|
+
|
|
51
|
+
<h4>Basic Routes</h4>
|
|
52
|
+
<p>Map specific paths to files:</p>
|
|
53
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"customRoutes"</span>: {<br /> <span class="hljs-attr">"/vendor/bootstrap.css"</span>: <span class="hljs-string">"./node_modules/bootstrap/dist/css/bootstrap.min.css"</span>,<br /> <span class="hljs-attr">"/api/status"</span>: <span class="hljs-string">"./status.js"</span>,<br /> <span class="hljs-attr">"/health"</span>: <span class="hljs-string">"./health-check.js"</span><br /> }<br />}</code></pre>
|
|
54
|
+
|
|
55
|
+
<h4>Wildcard Routes</h4>
|
|
56
|
+
<p>Wildcard routes allow you to map entire directory structures using the <code>*</code> wildcard:</p>
|
|
57
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"customRoutes"</span>: {<br /> <span class="hljs-attr">"kempo/*"</span>: <span class="hljs-string">"./node_modules/kempo/dist/*"</span>,<br /> <span class="hljs-attr">"assets/*"</span>: <span class="hljs-string">"./static-files/*"</span>,<br /> <span class="hljs-attr">"docs/*"</span>: <span class="hljs-string">"./documentation/*"</span>,<br /> <span class="hljs-attr">"lib/*"</span>: <span class="hljs-string">"./node_modules/my-library/build/*"</span><br /> }<br />}</code></pre>
|
|
58
|
+
|
|
59
|
+
<p>With wildcard routes:</p>
|
|
60
|
+
<ul>
|
|
61
|
+
<li><code>kempo/styles.css</code> would serve <code>./node_modules/kempo/dist/styles.css</code></li>
|
|
62
|
+
<li><code>assets/logo.png</code> would serve <code>./static-files/logo.png</code></li>
|
|
63
|
+
<li><code>docs/readme.md</code> would serve <code>./documentation/readme.md</code></li>
|
|
64
|
+
<li><code>lib/utils.js</code> would serve <code>./node_modules/my-library/build/utils.js</code></li>
|
|
65
|
+
</ul>
|
|
66
|
+
<p>The <code>*</code> wildcard matches any single path segment (anything between <code>/</code> characters). Multiple wildcards can be used in a single route pattern.</p>
|
|
67
|
+
|
|
68
|
+
<h3 id="maxRescanAttempts">maxRescanAttempts</h3>
|
|
69
|
+
<p>The maximum number of times to attempt rescanning the file system when a file is not found. Defaults to 3.</p>
|
|
70
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"maxRescanAttempts"</span>: <span class="hljs-number">3</span><br />}</code></pre>
|
|
71
|
+
|
|
72
|
+
<h3 id="middleware">middleware</h3>
|
|
73
|
+
<p>Configuration for built-in and custom middleware. Middleware runs before your route handlers and can modify requests, responses, or handle requests entirely.</p>
|
|
74
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"middleware"</span>: {<br /> <span class="hljs-attr">"cors"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"origin"</span>: <span class="hljs-string">"*"</span><br /> },<br /> <span class="hljs-attr">"compression"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span><br /> },<br /> <span class="hljs-attr">"custom"</span>: [<span class="hljs-string">"./middleware/auth.js"</span>]<br /> }<br />}</code></pre>
|
|
75
|
+
|
|
76
|
+
<h2>Complete Configuration Example</h2>
|
|
77
|
+
<p>Here's a complete example of a <code>.config.json</code> file:</p>
|
|
78
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"allowedMimes"</span>: {<br /> <span class="hljs-attr">"html"</span>: <span class="hljs-string">"text/html"</span>,<br /> <span class="hljs-attr">"css"</span>: <span class="hljs-string">"text/css"</span>,<br /> <span class="hljs-attr">"js"</span>: <span class="hljs-string">"application/javascript"</span>,<br /> <span class="hljs-attr">"json"</span>: <span class="hljs-string">"application/json"</span>,<br /> <span class="hljs-attr">"png"</span>: <span class="hljs-string">"image/png"</span>,<br /> <span class="hljs-attr">"jpg"</span>: <span class="hljs-string">"image/jpeg"</span>,<br /> <span class="hljs-attr">"jpeg"</span>: <span class="hljs-string">"image/jpeg"</span>,<br /> <span class="hljs-attr">"gif"</span>: <span class="hljs-string">"image/gif"</span>,<br /> <span class="hljs-attr">"svg"</span>: <span class="hljs-string">"image/svg+xml"</span>,<br /> <span class="hljs-attr">"woff"</span>: <span class="hljs-string">"font/woff"</span>,<br /> <span class="hljs-attr">"woff2"</span>: <span class="hljs-string">"font/woff2"</span><br /> },<br /> <span class="hljs-attr">"disallowedRegex"</span>: [<br /> <span class="hljs-string">"^/\\..*"</span>,<br /> <span class="hljs-string">"\\.env$"</span>,<br /> <span class="hljs-string">"\\.config$"</span>,<br /> <span class="hljs-string">"password"</span>,<br /> <span class="hljs-string">"node_modules"</span>,<br /> <span class="hljs-string">"\\.git"</span><br /> ],<br /> <span class="hljs-attr">"routeFiles"</span>: [<br /> <span class="hljs-string">"GET.js"</span>,<br /> <span class="hljs-string">"POST.js"</span>,<br /> <span class="hljs-string">"PUT.js"</span>,<br /> <span class="hljs-string">"DELETE.js"</span>,<br /> <span class="hljs-string">"PATCH.js"</span>,<br /> <span class="hljs-string">"HEAD.js"</span>,<br /> <span class="hljs-string">"OPTIONS.js"</span>,<br /> <span class="hljs-string">"index.js"</span><br /> ],<br /> <span class="hljs-attr">"noRescanPaths"</span>: [<br /> <span class="hljs-string">"/favicon\\.ico$"</span>,<br /> <span class="hljs-string">"/robots\\.txt$"</span>,<br /> <span class="hljs-string">"\\.map$"</span>,<br /> <span class="hljs-string">"\\.css$"</span>,<br /> <span class="hljs-string">"\\.js$"</span>,<br /> <span class="hljs-string">"\\.png$"</span>,<br /> <span class="hljs-string">"\\.jpg$"</span>,<br /> <span class="hljs-string">"\\.jpeg$"</span>,<br /> <span class="hljs-string">"\\.gif$"</span><br /> ],<br /> <span class="hljs-attr">"customRoutes"</span>: {<br /> <span class="hljs-attr">"/vendor/bootstrap.css"</span>: <span class="hljs-string">"./node_modules/bootstrap/dist/css/bootstrap.min.css"</span>,<br /> <span class="hljs-attr">"/vendor/jquery.js"</span>: <span class="hljs-string">"./node_modules/jquery/dist/jquery.min.js"</span>,<br /> <span class="hljs-attr">"assets/*"</span>: <span class="hljs-string">"./static-files/*"</span>,<br /> <span class="hljs-attr">"docs/*"</span>: <span class="hljs-string">"./documentation/*"</span><br /> },<br /> <span class="hljs-attr">"maxRescanAttempts"</span>: <span class="hljs-number">3</span>,<br /> <span class="hljs-attr">"middleware"</span>: {<br /> <span class="hljs-attr">"cors"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"origin"</span>: <span class="hljs-string">"*"</span>,<br /> <span class="hljs-attr">"methods"</span>: [<span class="hljs-string">"GET"</span>, <span class="hljs-string">"POST"</span>, <span class="hljs-string">"PUT"</span>, <span class="hljs-string">"DELETE"</span>],<br /> <span class="hljs-attr">"headers"</span>: [<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"Authorization"</span>]<br /> },<br /> <span class="hljs-attr">"compression"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"threshold"</span>: <span class="hljs-number">1024</span><br /> },<br /> <span class="hljs-attr">"security"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"headers"</span>: {<br /> <span class="hljs-attr">"X-Content-Type-Options"</span>: <span class="hljs-string">"nosniff"</span>,<br /> <span class="hljs-attr">"X-Frame-Options"</span>: <span class="hljs-string">"DENY"</span>,<br /> <span class="hljs-attr">"X-XSS-Protection"</span>: <span class="hljs-string">"1; mode=block"</span><br /> }<br /> },<br /> <span class="hljs-attr">"custom"</span>: [<br /> <span class="hljs-string">"./middleware/auth.js"</span>,<br /> <span class="hljs-string">"./middleware/logging.js"</span><br /> ]<br /> }<br />}</code></pre>
|
|
79
|
+
|
|
80
|
+
<h2>Environment-Specific Configuration</h2>
|
|
81
|
+
<p>You can create different configuration files for different environments:</p>
|
|
82
|
+
|
|
83
|
+
<h3>Development Configuration</h3>
|
|
84
|
+
<p>Create <code>.config.dev.json</code> for development:</p>
|
|
85
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"allowedMimes"</span>: {<br /> <span class="hljs-attr">"html"</span>: <span class="hljs-string">"text/html"</span>,<br /> <span class="hljs-attr">"css"</span>: <span class="hljs-string">"text/css"</span>,<br /> <span class="hljs-attr">"js"</span>: <span class="hljs-string">"application/javascript"</span>,<br /> <span class="hljs-attr">"json"</span>: <span class="hljs-string">"application/json"</span>,<br /> <span class="hljs-attr">"map"</span>: <span class="hljs-string">"application/json"</span><br /> },<br /> <span class="hljs-attr">"middleware"</span>: {<br /> <span class="hljs-attr">"cors"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"origin"</span>: <span class="hljs-string">"*"</span><br /> },<br /> <span class="hljs-attr">"compression"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">false</span><br /> }<br /> }<br />}</code></pre>
|
|
86
|
+
|
|
87
|
+
<h3>Production Configuration</h3>
|
|
88
|
+
<p>Create <code>.config.prod.json</code> for production:</p>
|
|
89
|
+
<pre><code class="hljs json">{<br /> <span class="hljs-attr">"allowedMimes"</span>: {<br /> <span class="hljs-attr">"html"</span>: <span class="hljs-string">"text/html"</span>,<br /> <span class="hljs-attr">"css"</span>: <span class="hljs-string">"text/css"</span>,<br /> <span class="hljs-attr">"js"</span>: <span class="hljs-string">"application/javascript"</span>,<br /> <span class="hljs-attr">"json"</span>: <span class="hljs-string">"application/json"</span>,<br /> <span class="hljs-attr">"png"</span>: <span class="hljs-string">"image/png"</span>,<br /> <span class="hljs-attr">"jpg"</span>: <span class="hljs-string">"image/jpeg"</span><br /> },<br /> <span class="hljs-attr">"disallowedRegex"</span>: [<br /> <span class="hljs-string">"^/\\..*"</span>,<br /> <span class="hljs-string">"\\.env$"</span>,<br /> <span class="hljs-string">"\\.config$"</span>,<br /> <span class="hljs-string">"password"</span>,<br /> <span class="hljs-string">"node_modules"</span>,<br /> <span class="hljs-string">"\\.git"</span>,<br /> <span class="hljs-string">"\\.map$"</span><br /> ],<br /> <span class="hljs-attr">"middleware"</span>: {<br /> <span class="hljs-attr">"cors"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"origin"</span>: <span class="hljs-string">"https://yourdomain.com"</span><br /> },<br /> <span class="hljs-attr">"compression"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"threshold"</span>: <span class="hljs-number">1024</span><br /> },<br /> <span class="hljs-attr">"security"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"headers"</span>: {<br /> <span class="hljs-attr">"X-Content-Type-Options"</span>: <span class="hljs-string">"nosniff"</span>,<br /> <span class="hljs-attr">"X-Frame-Options"</span>: <span class="hljs-string">"DENY"</span>,<br /> <span class="hljs-attr">"X-XSS-Protection"</span>: <span class="hljs-string">"1; mode=block"</span>,<br /> <span class="hljs-attr">"Strict-Transport-Security"</span>: <span class="hljs-string">"max-age=31536000; includeSubDomains"</span><br /> }<br /> }<br /> }<br />}</code></pre>
|
|
90
|
+
|
|
91
|
+
<h2>Configuration Tips</h2>
|
|
92
|
+
|
|
93
|
+
<h3>Security Best Practices</h3>
|
|
94
|
+
<ul>
|
|
95
|
+
<li>Always include patterns to block sensitive files in <code>disallowedRegex</code></li>
|
|
96
|
+
<li>Use strict CORS settings in production</li>
|
|
97
|
+
<li>Enable security headers middleware</li>
|
|
98
|
+
<li>Don't serve source maps in production</li>
|
|
99
|
+
</ul>
|
|
100
|
+
|
|
101
|
+
<h3>Performance Optimization</h3>
|
|
102
|
+
<ul>
|
|
103
|
+
<li>Use <code>noRescanPaths</code> for static assets to improve performance</li>
|
|
104
|
+
<li>Enable compression for larger files</li>
|
|
105
|
+
<li>Use custom routes to serve files from CDN or optimized locations</li>
|
|
106
|
+
<li>Limit <code>maxRescanAttempts</code> to prevent excessive file system scanning</li>
|
|
107
|
+
</ul>
|
|
108
|
+
|
|
109
|
+
<h3>Development vs Production</h3>
|
|
110
|
+
<ul>
|
|
111
|
+
<li>Enable source maps in development, disable in production</li>
|
|
112
|
+
<li>Use relaxed CORS in development, strict in production</li>
|
|
113
|
+
<li>Enable compression in production for better performance</li>
|
|
114
|
+
<li>Add more security headers in production</li>
|
|
115
|
+
</ul>
|
|
116
|
+
</main>
|
|
117
|
+
<div style="height:25vh"></div>
|
|
118
|
+
</body>
|
|
119
|
+
</html>
|