kempo-server 2.2.0 → 3.0.1

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 (62) hide show
  1. package/CONFIG.md +295 -187
  2. package/README.md +5 -4
  3. package/SPA.md +14 -14
  4. package/dist/defaultConfig.js +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/render.js +2 -0
  7. package/dist/router.js +1 -1
  8. package/dist/serveFile.js +1 -1
  9. package/dist/templating/index.js +1 -0
  10. package/dist/templating/parse.js +1 -0
  11. package/docs/caching.html +103 -17
  12. package/docs/cli-utils.html +102 -16
  13. package/docs/configuration.html +104 -17
  14. package/docs/examples.html +104 -17
  15. package/docs/fs-utils.html +102 -16
  16. package/docs/getting-started.html +104 -17
  17. package/docs/index.html +176 -81
  18. package/docs/middleware.html +104 -17
  19. package/docs/request-response.html +104 -17
  20. package/docs/routing.html +104 -17
  21. package/docs/templating.html +292 -0
  22. package/docs-src/.config.js +11 -0
  23. package/docs-src/caching.page.html +220 -0
  24. package/docs-src/cli-utils.page.html +71 -0
  25. package/docs-src/configuration.page.html +310 -0
  26. package/docs-src/default.template.html +35 -0
  27. package/docs-src/examples.page.html +192 -0
  28. package/docs-src/fs-utils.page.html +102 -0
  29. package/docs-src/getting-started.page.html +63 -0
  30. package/docs-src/index.page.html +79 -0
  31. package/docs-src/middleware.page.html +133 -0
  32. package/docs-src/nav.fragment.html +73 -0
  33. package/docs-src/request-response.page.html +96 -0
  34. package/docs-src/routing.page.html +73 -0
  35. package/docs-src/templating.page.html +188 -0
  36. package/llms.txt +97 -31
  37. package/package.json +5 -2
  38. package/scripts/build.js +22 -1
  39. package/scripts/render.js +58 -0
  40. package/src/defaultConfig.js +14 -2
  41. package/src/index.js +1 -1
  42. package/src/router.js +69 -10
  43. package/src/serveFile.js +27 -0
  44. package/src/templating/index.js +132 -0
  45. package/src/templating/parse.js +285 -0
  46. package/tests/cacheConfig.node-test.js +2 -2
  47. package/tests/config-flag.node-test.js +61 -25
  48. package/tests/customRoute-outside-root.node-test.js +1 -1
  49. package/tests/router-wildcard.node-test.js +47 -2
  50. package/tests/templating-parse.node-test.js +243 -0
  51. package/tests/templating-render.node-test.js +188 -0
  52. package/tests/utils/test-scenario.js +4 -4
  53. package/docs/.config.json.example +0 -29
  54. package/docs/api/_admin/cache/DELETE.js +0 -28
  55. package/docs/api/_admin/cache/GET.js +0 -53
  56. package/docs/api/user/[id]/GET.js +0 -15
  57. package/docs/api/user/[id]/[info]/DELETE.js +0 -12
  58. package/docs/api/user/[id]/[info]/GET.js +0 -17
  59. package/docs/api/user/[id]/[info]/POST.js +0 -18
  60. package/docs/api/user/[id]/[info]/PUT.js +0 -19
  61. package/docs/init.js +0 -2
  62. package/docs/nav.inc.html +0 -70
@@ -0,0 +1,310 @@
1
+ <page pageName="Configuration" title="Configuration - Kempo Server">
2
+ <content>
3
+ <p>Customize Kempo Server's behavior with a simple JSON configuration file.</p>
4
+
5
+ <h2>Configuration File</h2>
6
+ <div class="callout warning">
7
+ <strong>Important:</strong> The configuration file must be placed <strong>inside the server root directory</strong> (the folder specified by <code>--root</code>). For example, if you run <code>kempo-server --root public</code>, your config file should be at <code>public/.config.json</code> or <code>public/dev.config.json</code>, not in the project root.
8
+ </div>
9
+ <p>To configure the server, create a configuration file (by default <code>.config.json</code>) within the root directory of your server (<code>public</code> in the start example). You can specify a different configuration file using the <code>--config</code> flag:</p>
10
+ <pre><code class="hljs bash"># Use default .config.json<br />kempo-server --root public<br /><br /># Use custom config file<br />kempo-server --root public --config staging.config.json<br /><br /># Use absolute path<br />kempo-server --root public --config /etc/kempo/production.config.json</code></pre>
11
+ <p>This json file can have any of the following properties. Any property not defined will use the default configuration.</p>
12
+
13
+ <h2>Configuration Options</h2>
14
+ <ul>
15
+ <li><a href="#allowedMimes">allowedMimes</a> - File types that can be served</li>
16
+ <li><a href="#disallowedRegex">disallowedRegex</a> - Patterns for paths that should be blocked</li>
17
+ <li><a href="#customRoutes">customRoutes</a> - Custom route mappings</li>
18
+ <li><a href="#routeFiles">routeFiles</a> - Files that should be treated as route handlers</li>
19
+ <li><a href="#noRescanPaths">noRescanPaths</a> - Paths that should not trigger file system rescans</li>
20
+ <li><a href="#maxRescanAttempts">maxRescanAttempts</a> - Maximum number of rescan attempts</li>
21
+ <li><a href="#maxBodySize">maxBodySize</a> - Maximum request body size in bytes</li>
22
+ <li><a href="#cache">cache</a> - Module caching configuration</li>
23
+ <li><a href="#middleware">middleware</a> - Middleware configuration</li>
24
+ </ul>
25
+
26
+ <h3 id="allowedMimes">allowedMimes</h3>
27
+ <p>An object mapping file extensions to their MIME types and encoding. Each value is an object with <code>mime</code> and <code>encoding</code> properties. Files with extensions not in this list will not be served.</p>
28
+ <pre><code class="hljs json">{
29
+ "allowedMimes": {
30
+ "html": { "mime": "text/html", "encoding": "utf8" },
31
+ "css": { "mime": "text/css", "encoding": "utf8" },
32
+ "js": { "mime": "application/javascript", "encoding": "utf8" },
33
+ "json": { "mime": "application/json", "encoding": "utf8" },
34
+ "png": { "mime": "image/png", "encoding": "binary" },
35
+ "jpg": { "mime": "image/jpeg", "encoding": "binary" },
36
+ "jpeg": { "mime": "image/jpeg", "encoding": "binary" },
37
+ "gif": { "mime": "image/gif", "encoding": "binary" },
38
+ "svg": { "mime": "image/svg+xml", "encoding": "utf8" },
39
+ "woff": { "mime": "font/woff", "encoding": "binary" },
40
+ "woff2": { "mime": "font/woff2", "encoding": "binary" }
41
+ }
42
+ }</code></pre>
43
+
44
+ <h3 id="disallowedRegex">disallowedRegex</h3>
45
+ <p>An array of regular expressions that match paths that should never be served. This provides security by preventing access to sensitive files.</p>
46
+ <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>
47
+
48
+ <h3 id="routeFiles">routeFiles</h3>
49
+ <p>An array of filenames that should be treated as route handlers and executed as JavaScript modules.</p>
50
+ <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>
51
+
52
+ <h3 id="noRescanPaths">noRescanPaths</h3>
53
+ <p>An array of regex patterns for paths that should not trigger a file system rescan. This improves performance for common static assets.</p>
54
+ <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>
55
+
56
+ <h3 id="customRoutes">customRoutes</h3>
57
+ <p>An object mapping custom route paths to file paths. Useful for aliasing or serving files from outside the document root.</p>
58
+
59
+ <div class="callout info">
60
+ <strong>Path Resolution:</strong> All paths in <code>customRoutes</code> are resolved <strong>relative to the config file's location</strong> (which is the server root). To reference files outside the server root (like <code>node_modules</code> or a <code>src</code> folder), use <code>../</code> to navigate up to the project root.
61
+ </div>
62
+
63
+ <div class="callout info">
64
+ <strong>Route Priority:</strong> Custom routes take priority over files that exist in the directory structure. If you have both <code>public/dist/app.js</code> and a custom route <code>"/dist/**": "../src/**"</code>, the custom route will be used and the file will be served from <code>src/</code>.
65
+ </div>
66
+
67
+ <h4>Basic Routes</h4>
68
+ <p>Map specific paths to files:</p>
69
+ <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>
70
+
71
+ <h4>Wildcard Routes</h4>
72
+ <p>Wildcard routes allow you to map entire directory structures using the <code>*</code> wildcard:</p>
73
+ <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>
74
+
75
+ <p>With wildcard routes:</p>
76
+ <ul>
77
+ <li><code>kempo/styles.css</code> would serve <code>./node_modules/kempo/dist/styles.css</code></li>
78
+ <li><code>assets/logo.png</code> would serve <code>./static-files/logo.png</code></li>
79
+ <li><code>docs/readme.md</code> would serve <code>./documentation/readme.md</code></li>
80
+ <li><code>lib/utils.js</code> would serve <code>./node_modules/my-library/build/utils.js</code></li>
81
+ </ul>
82
+ <h4>Wildcard Syntax</h4>
83
+ <ul>
84
+ <li><code>*</code> - Matches a single path segment (anything between <code>/</code> characters)</li>
85
+ <li><code>**</code> - Matches recursively (any depth of subdirectories)</li>
86
+ </ul>
87
+ <p>Use <code>**</code> when you want to redirect an entire directory tree. Multiple wildcards can be used in a single route pattern.</p>
88
+
89
+ <h4>Common Use Case: Dev vs Production Builds</h4>
90
+ <p>A common pattern is to serve source files during development but built/minified files in production. Given this project structure:</p>
91
+ <pre><code class="hljs">project/
92
+ ├── src/ # Source files
93
+ │ └── app.js
94
+ ├── node_modules/
95
+ ├── public/ # Server root (--root public)
96
+ │ ├── dev.config.json # Config lives HERE (inside server root)
97
+ │ ├── dist/ # Built files
98
+ │ │ └── app.js
99
+ │ └── index.html</code></pre>
100
+ <p>Your <code>dev.config.json</code> can redirect <code>/dist/**</code> requests to serve from <code>src/</code> instead:</p>
101
+ <pre><code class="hljs json">{
102
+ "customRoutes": {
103
+ "/dist/**": "../src/**",
104
+ "/kempo-ui/**": "../node_modules/kempo-ui/**"
105
+ }
106
+ }</code></pre>
107
+ <p>Now requests to <code>/dist/app.js</code> will serve <code>../src/app.js</code> (the unminified source), while production uses the actual <code>dist/</code> files.</p>
108
+
109
+ <h4>Directory Resolution</h4>
110
+ <p>When a custom route (basic or wildcard) resolves to a directory, the server looks for files inside it using the same priority as normal file-based routing:</p>
111
+ <ol>
112
+ <li><code>METHOD.js</code> (e.g. <code>GET.js</code>, <code>POST.js</code>) &mdash; executed as a route module</li>
113
+ <li><code>METHOD.html</code> (e.g. <code>GET.html</code>) &mdash; served as a static file</li>
114
+ <li><code>index.js</code> &mdash; executed as a route module</li>
115
+ <li><code>index.html</code> / <code>index.htm</code> &mdash; served as a static file</li>
116
+ </ol>
117
+ <p>This means wildcard routes like <code>"/api/**": "../api/**"</code> fully support API directories containing route files (<code>GET.js</code>, <code>POST.js</code>, etc.), not just static files.</p>
118
+ <p>If the resolved path is a file whose name matches <code>routeFiles</code> (e.g. <code>GET.js</code>), it will be executed as a route module rather than served as static content.</p>
119
+
120
+ <h3 id="maxRescanAttempts">maxRescanAttempts</h3>
121
+ <p>The maximum number of times to attempt rescanning the file system when a file is not found. Defaults to 3.</p>
122
+ <pre><code class="hljs json">{<br /> <span class="hljs-attr">"maxRescanAttempts"</span>: <span class="hljs-number">3</span><br />}</code></pre>
123
+
124
+ <h3 id="maxBodySize">maxBodySize</h3>
125
+ <p>Maximum allowed request body size in bytes. If a request body exceeds this limit, the server responds with <code>413 Payload Too Large</code> before the route handler runs. Defaults to <code>1048576</code> (1 MB).</p>
126
+ <pre><code class="hljs json">{<br /> <span class="hljs-attr">"maxBodySize"</span>: <span class="hljs-number">1048576</span><br />}</code></pre>
127
+
128
+ <h3 id="middleware">middleware</h3>
129
+ <p>Configuration for built-in and custom middleware. Middleware runs before your route handlers and can modify requests, responses, or handle requests entirely.</p>
130
+ <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>
131
+
132
+ <h2>Complete Configuration Example</h2>
133
+ <p>Here's a complete example of a <code>.config.json</code> file:</p>
134
+ <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>
135
+
136
+ <h2>Environment-Specific Configuration</h2>
137
+ <p>You can create different configuration files for different environments and specify them using the <code>--config</code> flag:</p>
138
+
139
+ <h3>Development Configuration</h3>
140
+ <p>Create <code>.config.dev.json</code> for development:</p>
141
+ <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>
142
+ <pre><code class="hljs json">{
143
+ "allowedMimes": {
144
+ "html": { "mime": "text/html", "encoding": "utf8" },
145
+ "css": { "mime": "text/css", "encoding": "utf8" },
146
+ "js": { "mime": "application/javascript", "encoding": "utf8" },
147
+ "json": { "mime": "application/json", "encoding": "utf8" },
148
+ "map": { "mime": "application/json", "encoding": "utf8" }
149
+ },
150
+ "middleware": {
151
+ "cors": {
152
+ "enabled": true,
153
+ "origin": "*"
154
+ },
155
+ "compression": {
156
+ "enabled": false
157
+ }
158
+ }
159
+ }</code></pre>
160
+ <pre><code class="hljs json">{
161
+ "allowedMimes": {
162
+ "html": { "mime": "text/html", "encoding": "utf8" },
163
+ "css": { "mime": "text/css", "encoding": "utf8" },
164
+ "js": { "mime": "application/javascript", "encoding": "utf8" },
165
+ "json": { "mime": "application/json", "encoding": "utf8" },
166
+ "png": { "mime": "image/png", "encoding": "binary" },
167
+ "jpg": { "mime": "image/jpeg", "encoding": "binary" }
168
+ },
169
+ "disallowedRegex": [
170
+ "^/\\..*",
171
+ "\\.env$",
172
+ "\\.config$",
173
+ "password",
174
+ "node_modules",
175
+ "\\.git",
176
+ "\\.map$"
177
+ ],
178
+ "middleware": {
179
+ "cors": {
180
+ "enabled": true,
181
+ "origin": "https://yourdomain.com"
182
+ },
183
+ "compression": {
184
+ "enabled": true,
185
+ "threshold": 1024
186
+ },
187
+ "security": {
188
+ "enabled": true,
189
+ "headers": {
190
+ "X-Content-Type-Options": "nosniff",
191
+ "X-Frame-Options": "DENY",
192
+ "X-XSS-Protection": "1; mode=block",
193
+ "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
194
+ }
195
+ }
196
+ }
197
+ }</code></pre>
198
+ <p>Use with: <code>kempo-server --root public --config .config.dev.json</code></p>
199
+
200
+ <h3>Production Configuration</h3>
201
+ <p>Create <code>.config.prod.json</code> for production:</p>
202
+ <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>
203
+ <p>Use with: <code>kempo-server --root public --config .config.prod.json</code></p>
204
+
205
+ <h3 id="cache">cache</h3>
206
+ <p>Module caching configuration to improve performance by keeping compiled JavaScript modules in memory. The cache supports LRU eviction, TTL expiration, memory monitoring, and automatic file watching.</p>
207
+ <pre><code class="hljs json">{<br /> <span class="hljs-attr">"cache"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"maxSize"</span>: <span class="hljs-number">1000</span>,<br /> <span class="hljs-attr">"ttlMs"</span>: <span class="hljs-number">3600000</span>,<br /> <span class="hljs-attr">"maxMemoryUsageMB"</span>: <span class="hljs-number">500</span>,<br /> <span class="hljs-attr">"checkIntervalMs"</span>: <span class="hljs-number">30000</span>,<br /> <span class="hljs-attr">"fileWatching"</span>: <span class="hljs-literal">true</span><br /> }<br />}</code></pre>
208
+
209
+ <h4>Cache Configuration Options</h4>
210
+ <table>
211
+ <thead>
212
+ <tr>
213
+ <th>Option</th>
214
+ <th>Type</th>
215
+ <th>Default</th>
216
+ <th>Description</th>
217
+ </tr>
218
+ </thead>
219
+ <tbody>
220
+ <tr>
221
+ <td><code>enabled</code></td>
222
+ <td>boolean</td>
223
+ <td>true</td>
224
+ <td>Enable/disable module caching system</td>
225
+ </tr>
226
+ <tr>
227
+ <td><code>maxSize</code></td>
228
+ <td>number</td>
229
+ <td>1000</td>
230
+ <td>Maximum number of modules to cache (LRU eviction)</td>
231
+ </tr>
232
+ <tr>
233
+ <td><code>ttlMs</code></td>
234
+ <td>number</td>
235
+ <td>3600000</td>
236
+ <td>Time-to-live in milliseconds (default: 1 hour)</td>
237
+ </tr>
238
+ <tr>
239
+ <td><code>maxMemoryUsageMB</code></td>
240
+ <td>number</td>
241
+ <td>500</td>
242
+ <td>Maximum memory usage in MB before triggering cleanup</td>
243
+ </tr>
244
+ <tr>
245
+ <td><code>checkIntervalMs</code></td>
246
+ <td>number</td>
247
+ <td>30000</td>
248
+ <td>Memory check interval in milliseconds (default: 30 seconds)</td>
249
+ </tr>
250
+ <tr>
251
+ <td><code>fileWatching</code></td>
252
+ <td>boolean</td>
253
+ <td>true</td>
254
+ <td>Watch files for changes and auto-invalidate cache</td>
255
+ </tr>
256
+ </tbody>
257
+ </table>
258
+
259
+ <h4>Environment-Specific Cache Settings</h4>
260
+ <h5>Development (.config.dev.json)</h5>
261
+ <pre><code class="hljs json">{<br /> <span class="hljs-attr">"cache"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"maxSize"</span>: <span class="hljs-number">100</span>,<br /> <span class="hljs-attr">"ttlMs"</span>: <span class="hljs-number">300000</span>,<br /> <span class="hljs-attr">"fileWatching"</span>: <span class="hljs-literal">true</span><br /> }<br />}</code></pre>
262
+
263
+ <h5>Production (.config.prod.json)</h5>
264
+ <pre><code class="hljs json">{<br /> <span class="hljs-attr">"cache"</span>: {<br /> <span class="hljs-attr">"enabled"</span>: <span class="hljs-literal">true</span>,<br /> <span class="hljs-attr">"maxSize"</span>: <span class="hljs-number">5000</span>,<br /> <span class="hljs-attr">"ttlMs"</span>: <span class="hljs-number">7200000</span>,<br /> <span class="hljs-attr">"maxMemoryUsageMB"</span>: <span class="hljs-number">1000</span>,<br /> <span class="hljs-attr">"fileWatching"</span>: <span class="hljs-literal">false</span><br /> }<br />}</code></pre>
265
+
266
+ <h4>Cache Monitoring</h4>
267
+ <p>Access cache statistics and management via admin endpoints:</p>
268
+ <ul>
269
+ <li><code>GET /_admin/cache</code> - View cache statistics (hits, misses, size, memory usage)</li>
270
+ <li><code>DELETE /_admin/cache</code> - Clear all cached modules</li>
271
+ </ul>
272
+
273
+ <p>For detailed cache usage and configuration examples, see the <a href="caching.html">Caching Guide</a>.</p>
274
+
275
+ <h3>Package.json Scripts</h3>
276
+ <p>Add environment-specific scripts to your <code>package.json</code>:</p>
277
+ <pre><code class="hljs json">{<br /> <span class="hljs-attr">"scripts"</span>: {<br /> <span class="hljs-attr">"start"</span>: <span class="hljs-string">"kempo-server --root public"</span>,<br /> <span class="hljs-attr">"start:dev"</span>: <span class="hljs-string">"kempo-server --root public --config .config.dev.json --verbose"</span>,<br /> <span class="hljs-attr">"start:staging"</span>: <span class="hljs-string">"kempo-server --root public --config .config.staging.json"</span>,<br /> <span class="hljs-attr">"start:prod"</span>: <span class="hljs-string">"kempo-server --root public --config .config.prod.json"</span><br /> }<br />}</code></pre>
278
+
279
+ <h2>Configuration Tips</h2>
280
+
281
+ <h3>Security Best Practices</h3>
282
+ <ul>
283
+ <li>Always include patterns to block sensitive files in <code>disallowedRegex</code></li>
284
+ <li>Use strict CORS settings in production</li>
285
+ <li>Enable security headers middleware</li>
286
+ <li>Don't serve source maps in production</li>
287
+ </ul>
288
+
289
+ <h3>Performance Optimization</h3>
290
+ <ul>
291
+ <li>Enable module caching with appropriate <code>maxSize</code> and <code>ttlMs</code> settings</li>
292
+ <li>Use <code>noRescanPaths</code> for static assets to improve performance</li>
293
+ <li>Enable compression for larger files</li>
294
+ <li>Use custom routes to serve files from CDN or optimized locations</li>
295
+ <li>Limit <code>maxRescanAttempts</code> to prevent excessive file system scanning</li>
296
+ <li>Configure <code>maxMemoryUsageMB</code> to prevent memory issues in production</li>
297
+ </ul>
298
+
299
+ <h3>Development vs Production</h3>
300
+ <ul>
301
+ <li>Enable source maps in development, disable in production</li>
302
+ <li>Use relaxed CORS in development, strict in production</li>
303
+ <li>Enable compression in production for better performance</li>
304
+ <li>Add more security headers in production</li>
305
+ <li>Use smaller cache sizes in development, larger in production</li>
306
+ <li>Enable file watching in development, disable in production for stability</li>
307
+ <li>Use shorter TTL in development for faster iteration</li>
308
+ </ul>
309
+ </content>
310
+ </page>
@@ -0,0 +1,35 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta
6
+ name="viewport"
7
+ content="width=device-width, initial-scale=1.0"
8
+ />
9
+ <title>{{title}}</title>
10
+ <link rel="icon" type="image/svg+xml" href="./media/icon.svg" />
11
+ <link rel="icon" type="image/png" sizes="32x32" href="./media/icon32.png" />
12
+ <link rel="manifest" href="./manifest.json" />
13
+ <link
14
+ rel="stylesheet"
15
+ href="https://cdn.jsdelivr.net/npm/kempo-css@2/dist/kempo.min.css"
16
+ />
17
+ <link rel="stylesheet" href="./theme.css" />
18
+ <script>
19
+ window.litDisableBundleWarning = true;
20
+ window.kempo = { pathsToIcons: ['https://cdn.jsdelivr.net/npm/kempo-ui@0.0.42/icons/'] };
21
+ </script>
22
+ </head>
23
+ <body>
24
+ <fragment name="nav" />
25
+ <main>
26
+ <h1 class="ta-center">{{pageName}}</h1>
27
+ <location />
28
+ </main>
29
+ <div style="height:25vh"></div>
30
+ <script
31
+ type="module"
32
+ src="https://cdn.jsdelivr.net/npm/kempo-ui@0.0.42/dist/components/Import.js"
33
+ ></script>
34
+ </body>
35
+ </html>