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.
Files changed (44) hide show
  1. package/.github/copilot-instructions.md +96 -0
  2. package/README.md +212 -4
  3. package/docs/configuration.html +119 -0
  4. package/docs/examples.html +201 -0
  5. package/docs/getting-started.html +72 -0
  6. package/docs/index.html +53 -330
  7. package/docs/manifest.json +87 -0
  8. package/docs/media/hexagon.svg +22 -0
  9. package/docs/media/icon-maskable.png +0 -0
  10. package/docs/media/icon.svg +44 -0
  11. package/docs/media/icon128.png +0 -0
  12. package/docs/media/icon144.png +0 -0
  13. package/docs/media/icon152.png +0 -0
  14. package/docs/media/icon16-48.svg +21 -0
  15. package/docs/media/icon16.png +0 -0
  16. package/docs/media/icon192.png +0 -0
  17. package/docs/media/icon256.png +0 -0
  18. package/docs/media/icon32.png +0 -0
  19. package/docs/media/icon384.png +0 -0
  20. package/docs/media/icon48.png +0 -0
  21. package/docs/media/icon512.png +0 -0
  22. package/docs/media/icon64.png +0 -0
  23. package/docs/media/icon72.png +0 -0
  24. package/docs/media/icon96.png +0 -0
  25. package/docs/media/kempo-fist.svg +21 -0
  26. package/docs/middleware.html +147 -0
  27. package/docs/request-response.html +95 -0
  28. package/docs/routing.html +77 -0
  29. package/package.json +8 -3
  30. package/tests/builtinMiddleware-cors.node-test.js +17 -0
  31. package/tests/builtinMiddleware.node-test.js +74 -0
  32. package/tests/defaultConfig.node-test.js +13 -0
  33. package/tests/example-middleware.node-test.js +31 -0
  34. package/tests/findFile.node-test.js +46 -0
  35. package/tests/getFiles.node-test.js +25 -0
  36. package/tests/getFlags.node-test.js +30 -0
  37. package/tests/index.node-test.js +23 -0
  38. package/tests/middlewareRunner.node-test.js +18 -0
  39. package/tests/requestWrapper.node-test.js +51 -0
  40. package/tests/responseWrapper.node-test.js +74 -0
  41. package/tests/router-middleware.node-test.js +46 -0
  42. package/tests/router.node-test.js +88 -0
  43. package/tests/serveFile.node-test.js +52 -0
  44. 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
- ```json
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 6 properties, any property not defined will use the "Default Config".
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 rescan optimization
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>