shokupan 0.6.1 → 0.9.0

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 (81) hide show
  1. package/README.md +55 -2
  2. package/dist/{openapi-analyzer-Bei1sVWp.cjs → analyzer-Bei1sVWp.cjs} +1 -1
  3. package/dist/analyzer-Bei1sVWp.cjs.map +1 -0
  4. package/dist/{openapi-analyzer-Ce_7JxZh.js → analyzer-Ce_7JxZh.js} +1 -1
  5. package/dist/analyzer-Ce_7JxZh.js.map +1 -0
  6. package/dist/cli.cjs +2 -2
  7. package/dist/cli.cjs.map +1 -1
  8. package/dist/cli.js +1 -1
  9. package/dist/cli.js.map +1 -1
  10. package/dist/context.d.ts +58 -23
  11. package/dist/{server-adapter-DFhwlK8e.cjs → http-server-BEMPIs33.cjs} +4 -2
  12. package/dist/http-server-BEMPIs33.cjs.map +1 -0
  13. package/dist/{server-adapter-0xH174zz.js → http-server-CCeagTyU.js} +4 -2
  14. package/dist/http-server-CCeagTyU.js.map +1 -0
  15. package/dist/index.cjs +1940 -917
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.ts +18 -17
  18. package/dist/index.js +1948 -925
  19. package/dist/index.js.map +1 -1
  20. package/dist/middleware.d.ts +1 -1
  21. package/dist/plugins/{auth.d.ts → application/auth.d.ts} +72 -3
  22. package/dist/plugins/application/cluster.d.ts +33 -0
  23. package/dist/plugins/{failed-request-recorder.d.ts → application/dashboard/failed-request-recorder.d.ts} +1 -1
  24. package/dist/plugins/application/dashboard/metrics-collector.d.ts +12 -0
  25. package/dist/plugins/application/dashboard/plugin.d.ts +42 -0
  26. package/dist/plugins/application/dashboard/static/charts.js +328 -0
  27. package/dist/plugins/application/dashboard/static/failures.js +85 -0
  28. package/dist/plugins/application/dashboard/static/graph.mjs +523 -0
  29. package/dist/plugins/application/dashboard/static/poll.js +146 -0
  30. package/dist/plugins/application/dashboard/static/reactflow.css +18 -0
  31. package/dist/plugins/application/dashboard/static/registry.css +131 -0
  32. package/dist/plugins/application/dashboard/static/registry.js +269 -0
  33. package/dist/plugins/application/dashboard/static/requests.js +118 -0
  34. package/dist/plugins/application/dashboard/static/scrollbar.css +24 -0
  35. package/dist/plugins/application/dashboard/static/styles.css +175 -0
  36. package/dist/plugins/application/dashboard/static/tables.js +92 -0
  37. package/dist/plugins/application/dashboard/static/tabs.js +113 -0
  38. package/dist/plugins/application/dashboard/static/tabulator.css +66 -0
  39. package/dist/plugins/application/dashboard/template.eta +246 -0
  40. package/dist/plugins/{server-adapter.d.ts → application/http-server.d.ts} +1 -1
  41. package/dist/plugins/{idempotency → application/idempotency}/plugin.d.ts +7 -1
  42. package/dist/plugins/{openapi.d.ts → application/openapi/openapi.d.ts} +2 -2
  43. package/dist/plugins/application/scalar.d.ts +36 -0
  44. package/dist/plugins/application/socket-io.d.ts +14 -0
  45. package/dist/plugins/middleware/compression.d.ts +17 -0
  46. package/dist/plugins/middleware/cors.d.ts +34 -0
  47. package/dist/plugins/{express.d.ts → middleware/express.d.ts} +1 -1
  48. package/dist/plugins/{openapi-validator.d.ts → middleware/openapi-validator.d.ts} +2 -2
  49. package/dist/plugins/middleware/proxy.d.ts +37 -0
  50. package/dist/plugins/middleware/rate-limit.d.ts +58 -0
  51. package/dist/plugins/{security-headers.d.ts → middleware/security-headers.d.ts} +51 -1
  52. package/dist/plugins/{serve-static.d.ts → middleware/serve-static.d.ts} +1 -1
  53. package/dist/plugins/{session.d.ts → middleware/session.d.ts} +89 -3
  54. package/dist/plugins/{validation.d.ts → middleware/validation.d.ts} +6 -1
  55. package/dist/router.d.ts +17 -5
  56. package/dist/shokupan.d.ts +31 -5
  57. package/dist/util/async-hooks.d.ts +8 -2
  58. package/dist/util/datastore.d.ts +4 -3
  59. package/dist/{decorators.d.ts → util/decorators.d.ts} +6 -1
  60. package/dist/util/http-error.d.ts +38 -0
  61. package/dist/util/http-status.d.ts +32 -0
  62. package/dist/util/instrumentation.d.ts +1 -1
  63. package/dist/{request.d.ts → util/request.d.ts} +1 -1
  64. package/dist/util/symbol.d.ts +34 -0
  65. package/dist/{router → util}/trie.d.ts +1 -1
  66. package/dist/{types.d.ts → util/types.d.ts} +38 -2
  67. package/package.json +9 -6
  68. package/dist/openapi-analyzer-Bei1sVWp.cjs.map +0 -1
  69. package/dist/openapi-analyzer-Ce_7JxZh.js.map +0 -1
  70. package/dist/plugins/compression.d.ts +0 -5
  71. package/dist/plugins/cors.d.ts +0 -11
  72. package/dist/plugins/debugview/plugin.d.ts +0 -29
  73. package/dist/plugins/proxy.d.ts +0 -11
  74. package/dist/plugins/rate-limit.d.ts +0 -15
  75. package/dist/plugins/scalar.d.ts +0 -15
  76. package/dist/server-adapter-0xH174zz.js.map +0 -1
  77. package/dist/server-adapter-DFhwlK8e.cjs.map +0 -1
  78. package/dist/symbol.d.ts +0 -15
  79. /package/dist/{analysis/openapi-analyzer.d.ts → plugins/application/openapi/analyzer.d.ts} +0 -0
  80. /package/dist/{di.d.ts → util/di.d.ts} +0 -0
  81. /package/dist/{response.d.ts → util/response.d.ts} +0 -0
@@ -0,0 +1,246 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Shokupan Debug Dashboard</title>
8
+ <link href="https://unpkg.com/tabulator-tables@5.5.0/dist/css/tabulator_bootstrap5.min.css" rel="stylesheet">
9
+ <link rel="stylesheet" href="https://esm.sh/@xyflow/react@12.3.6/dist/style.css" />
10
+ <style id="styles"><%~ include("styles.css") %></style>
11
+ <style id="reactflow"><%~ include("reactflow.css") %></style>
12
+ <style id="registry"><%~ include("registry.css") %></style>
13
+ <style id="scrollbar"><%~ include("scrollbar.css") %></style>
14
+ <style id="tabulator"><%~ include("tabulator.css") %></style>
15
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
16
+ <script type="text/javascript" src="https://unpkg.com/tabulator-tables@5.5.0/dist/js/tabulator.min.js"></script>
17
+ </head>
18
+ <body>
19
+ <div class="container">
20
+ <header>
21
+ <div>
22
+ <h1>Debug Dashboard</h1>
23
+ <div style="color: var(--text-secondary)">Uptime: <span id="uptime"><%= it.uptime %></span></div>
24
+ </div>
25
+ <div class="tabs">
26
+ <button class="tab-btn active" onclick="switchTab('overview')">Overview</button>
27
+ <button class="tab-btn" onclick="switchTab('registry')">Registry</button>
28
+ <button class="tab-btn" onclick="switchTab('graph')">Graph</button>
29
+ <button class="tab-btn" onclick="switchTab('requests')">Requests</button>
30
+ <button class="tab-btn" onclick="switchTab('failures')">Failures</button>
31
+ </div>
32
+ </header>
33
+
34
+ <!-- Overview Tab -->
35
+ <div id="tab-overview" class="tab-content active">
36
+
37
+ <div class="metrics-grid">
38
+ <div class="card">
39
+ <div class="card-title">Total Requests</div>
40
+ <div class="card-value" id="total-requests">
41
+ <%= it.metrics.totalRequests %>
42
+ </div>
43
+ </div>
44
+
45
+ <div class="card">
46
+ <div class="card-title">Active Requests</div>
47
+ <div class="card-value" style="color: var(--accent)" id="active-requests">
48
+ <%= it.metrics.activeRequests %>
49
+ </div>
50
+ </div>
51
+
52
+ <div class="card">
53
+ <div class="card-title">Success Rate</div>
54
+ <div class="card-value text-success">
55
+ <span id="success-rate">
56
+ <%= (it.metrics.totalRequests - it.metrics.activeRequests) ?
57
+ Math.round((it.metrics.successfulRequests / (it.metrics.totalRequests -
58
+ it.metrics.activeRequests)) * 100) : 100 %>%
59
+ </span>
60
+ </div>
61
+ <div style="color: var(--text-secondary); margin-top: 0.5rem">
62
+ <span id="successful-requests">
63
+ <%= it.metrics.successfulRequests %>
64
+ </span> successful
65
+ </div>
66
+ </div>
67
+
68
+ <div class="card">
69
+ <div class="card-title">Fail Rate</div>
70
+ <div class="card-value text-error">
71
+ <span id="fail-rate">
72
+ <%= (it.metrics.totalRequests - it.metrics.activeRequests) ?
73
+ Math.round((it.metrics.failedRequests / (it.metrics.totalRequests -
74
+ it.metrics.activeRequests)) * 100) : 0 %>%
75
+ </span>
76
+ </div>
77
+ <div style="color: var(--text-secondary); margin-top: 0.5rem">
78
+ <span id="failed-requests">
79
+ <%= it.metrics.failedRequests %>
80
+ </span> failed
81
+ </div>
82
+ </div>
83
+
84
+ <div class="card">
85
+ <div class="card-title">Avg Latency</div>
86
+ <div class="card-value">
87
+ <span id="avg-latency">
88
+ <%= it.metrics.averageTotalTime_ms.toFixed(2) %>
89
+ </span> <span style="font-size: 1rem; color: var(--text-secondary)">ms</span>
90
+ </div>
91
+ </div>
92
+ </div>
93
+
94
+ <div id="chart-container" style="display: flex; flex-direction: column; gap: 1rem;">
95
+ <div style="display: flex; justify-content: flex-end;">
96
+ <select id="time-range-selector" onchange="updateCharts(); updateDashboard(); fetchTopStats();" style="background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 5px; border-radius: 4px;">
97
+ <option value="1m">1 Minute</option>
98
+ <option value="5m">5 Minutes</option>
99
+ <option value="30m">30 Minutes</option>
100
+ <option value="1h">1 Hour</option>
101
+ <option value="2h">2 Hours</option>
102
+ <option value="6h">6 Hours</option>
103
+ <option value="12h">12 Hours</option>
104
+ <option value="1d">1 Day</option>
105
+ <option value="3d">3 Days</option>
106
+ <option value="7d">7 Days</option>
107
+ <option value="30d">30 Days</option>
108
+ </select>
109
+ </div>
110
+
111
+
112
+ <div class="card-container" >
113
+ <div class="card" style="height: 300px;">
114
+ <div class="card-title">Response Time</div>
115
+ <div class="card-chart">
116
+ <canvas id="latencyChart"></canvas>
117
+ </div>
118
+ </div>
119
+ <div class="card" style="height: 300px;">
120
+ <div class="card-title">Requests / Second</div>
121
+ <div class="card-chart">
122
+ <canvas id="rpsChart"></canvas>
123
+ </div>
124
+ </div>
125
+ <div class="card" style="height: 300px;">
126
+ <div class="card-title">CPU & Load</div>
127
+ <div class="card-chart">
128
+ <canvas id="cpuChart"></canvas>
129
+ </div>
130
+ </div>
131
+ <div class="card" style="height: 300px;">
132
+ <div class="card-title">Memory</div>
133
+ <div class="card-chart">
134
+ <canvas id="memoryChart"></canvas>
135
+ </div>
136
+ </div>
137
+ <div class="card" style="height: 300px;">
138
+ <div class="card-title">Heap Usage</div>
139
+ <div class="card-chart">
140
+ <canvas id="heapChart"></canvas>
141
+ </div>
142
+ </div>
143
+ <div class="card" style="height: 300px;">
144
+ <div class="card-title">Event Loop Latency</div>
145
+ <div class="card-chart">
146
+ <canvas id="eventLoopChart"></canvas>
147
+ </div>
148
+ </div>
149
+ <div class="card" style="height: 300px;">
150
+ <div class="card-title">Error Rate</div>
151
+ <div class="card-chart">
152
+ <canvas id="errorRateChart"></canvas>
153
+ </div>
154
+ </div>
155
+ </div>
156
+
157
+ <div class="card-title" style="margin-top: 1rem;">Top Statistics</div>
158
+ <div class="card-container">
159
+ <div class="card">
160
+ <div class="card-title">Top Requests</div>
161
+ <div id="top-requests-table"></div>
162
+ </div>
163
+ <div class="card">
164
+ <div class="card-title">Top Errors</div>
165
+ <div id="top-errors-table"></div>
166
+ </div>
167
+ <div class="card">
168
+ <div class="card-title">Most Frequent Failures</div>
169
+ <div id="failing-requests-table"></div>
170
+ </div>
171
+ <div class="card">
172
+ <div class="card-title">Slowest Requests</div>
173
+ <div id="slowest-requests-table"></div>
174
+ </div>
175
+ </div>
176
+
177
+ <div id="table-container" style="padding: 0; margin-top: 1rem;">
178
+ <div id="requests-table" class="table-dark"></div>
179
+ </div>
180
+ </div>
181
+ </div>
182
+
183
+ <!-- Registry Tab -->
184
+ <div id="tab-registry" class="tab-content">
185
+ <div id="registry-container" class="card" style="margin-top: 2rem;">
186
+ <div class="card-title">Component Registry</div>
187
+ <div id="registry-tree" style="padding: 0 1rem 1rem 1rem; font-family: monospace; font-size: 0.9rem;"></div>
188
+ </div>
189
+ </div>
190
+
191
+ <!-- Graph Tab -->
192
+ <div id="tab-graph" class="tab-content">
193
+ <div class="card" style="margin-bottom: 1rem;">
194
+ <div style="display: flex; gap: 1rem;">
195
+ <input type="text" id="graph-search" placeholder="Search routes or middleware..." style="flex:1; padding: 0.5rem; border-radius: 0.5rem; background: var(--bg-primary); border: 1px solid var(--card-border); color: var(--text-primary);">
196
+ </div>
197
+ </div>
198
+ <div id="cy"></div>
199
+ </div>
200
+
201
+ <!-- Requests Tab -->
202
+ <div id="tab-requests" class="tab-content">
203
+ <div class="card" style="margin-bottom: 1rem; display: flex; justify-content: space-between; align-items: center;">
204
+ <div class="card-title">Recent Requests (Last 100)</div>
205
+ <div>
206
+ <button onclick="fetchRequests()" style="background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 5px 10px; border-radius: 4px; cursor: pointer;">Refresh</button>
207
+ </div>
208
+ </div>
209
+ <div id="requests-list-container" style="height: calc(100vh - 300px); margin-bottom: 2rem;"></div>
210
+
211
+ <div id="request-details-container" class="card" style="display: none;">
212
+ <div class="card-title">Request Details</div>
213
+ <div id="request-details-content"></div>
214
+ <div class="card-title" style="margin-top: 1rem;">Middleware Trace</div>
215
+ <div id="middleware-trace-container"></div>
216
+ </div>
217
+ </div>
218
+
219
+ <!-- Failures Tab -->
220
+ <div id="tab-failures" class="tab-content">
221
+ <div class="card" style="margin-bottom: 1rem; display: flex; justify-content: space-between; align-items: center;">
222
+ <div class="card-title">Failed Requests (Last 50)</div>
223
+ <div>
224
+ <button onclick="importFailure()" style="background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 5px 10px; border-radius: 4px; cursor: pointer; margin-right: 8px;">Import</button>
225
+ <button onclick="fetchFailures()" style="background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--card-border); padding: 5px 10px; border-radius: 4px; cursor: pointer;">Refresh</button>
226
+ </div>
227
+ </div>
228
+ <div id="failures-table-container"></div>
229
+ </div>
230
+ </div>
231
+
232
+ <script>
233
+ // Injected function from server config
234
+ const getRequestHeaders = <%~ it.getRequestHeaders || "undefined" %>;
235
+ </script>
236
+ <script id="poll.js"><%~ include("poll.js") %></script>
237
+ <script id="graph.mjs" type="module"><%~ include("graph.mjs") %></script>
238
+ <script id="charts.js"><%~ include("charts.js") %></script>
239
+ <script id="tables.js"><%~ include("tables.js") %></script>
240
+ <script id="registry.js"><%~ include("registry.js") %></script>
241
+ <script id="failures.js"><%~ include("failures.js") %></script>
242
+ <script id="requests.js"><%~ include("requests.js") %></script>
243
+ <script id="tabs.js"><%~ include("tabs.js") %></script>
244
+ </body>
245
+
246
+ </html>
@@ -1,4 +1,4 @@
1
- import { ServerFactory } from '../types';
1
+ import { ServerFactory } from '../../util/types';
2
2
  import * as https from "node:https";
3
3
  /**
4
4
  * Creates a server factory that uses the standard Node.js `http` module.
@@ -1,4 +1,4 @@
1
- import { Middleware } from '../../types';
1
+ import { Middleware } from '../../../util/types';
2
2
  export interface IdempotencyOptions {
3
3
  /**
4
4
  * Header name to use for the idempotency key.
@@ -11,4 +11,10 @@ export interface IdempotencyOptions {
11
11
  */
12
12
  ttl?: number;
13
13
  }
14
+ /**
15
+ * Idempotency middleware. This middleware will cache responses based on the idempotency key
16
+ * to prevent duplicate server processing of requests.
17
+ * @param options Idempotency options
18
+ * @returns Middleware
19
+ */
14
20
  export declare function Idempotency(options?: IdempotencyOptions): Middleware;
@@ -1,5 +1,5 @@
1
- import { ShokupanRouter } from '../router';
2
- import { OpenAPIOptions } from '../types';
1
+ import { ShokupanRouter } from '../../../router';
2
+ import { OpenAPIOptions } from '../../../util/types';
3
3
  /**
4
4
  * Statically generate an OpenAPI spec from a ShokupanRouter instance.
5
5
  *
@@ -0,0 +1,36 @@
1
+ import { ApiReferenceConfiguration } from '@scalar/api-reference';
2
+ import { OpenAPI } from '@scalar/openapi-types';
3
+ import { ShokupanRouter } from '../../router';
4
+ import { Shokupan } from '../../shokupan';
5
+ import { DeepPartial, ShokupanPlugin, ShokupanPluginOptions } from '../../util/types';
6
+ export type ScalarPluginOptions = {
7
+ /**
8
+ * Base document to use for API reference.
9
+ */
10
+ baseDocument?: DeepPartial<OpenAPI.Document>;
11
+ /**
12
+ * Configuration for API reference.
13
+ */
14
+ config?: Partial<ApiReferenceConfiguration>;
15
+ /**
16
+ * Whether to enable static analysis.
17
+ * When this is enabled, the plugin will run static analysis on the entrypoint
18
+ * and generate an OpenAPI document. This is useful for when you want to generate
19
+ * an OpenAPI document without having to manually define it.
20
+ *
21
+ * Only works with TypeScript entrypoints.
22
+ */
23
+ enableStaticAnalysis?: boolean;
24
+ };
25
+ /**
26
+ * Scalar plugin. This plugin provides an API reference interface for your API.
27
+ * @param options Scalar plugin options
28
+ * @returns Scalar plugin instance
29
+ */
30
+ export declare class ScalarPlugin extends ShokupanRouter<any> implements ShokupanPlugin {
31
+ private readonly pluginOptions;
32
+ constructor(pluginOptions?: ScalarPluginOptions);
33
+ onInit(app: Shokupan, options?: ShokupanPluginOptions): void;
34
+ private init;
35
+ onMount(parent: ShokupanRouter<any>): void;
36
+ }
@@ -0,0 +1,14 @@
1
+ import { Server } from 'socket.io';
2
+ import { Shokupan } from '../../shokupan';
3
+ /**
4
+ * Attaches the Shokupan HTTP Bridge and Event System to a Socket.IO server.
5
+ * This makes the Shokupan HTTP APIs accessible via Socket.IO events.
6
+ *
7
+ * Send events as `shokupan:request` events with the payload { type: "http", id: "123", body: {} }.
8
+ *
9
+ * Responses are emitted as `shokupan:response` events with the payload { id, status, body }
10
+ *
11
+ * @param io The Socket.IO server instance
12
+ * @param app The Shokupan application instance
13
+ */
14
+ export declare function attachSocketIOBridge(io: Server, app: Shokupan): void;
@@ -0,0 +1,17 @@
1
+ import { Middleware } from '../../util/types';
2
+ export interface CompressionOptions {
3
+ /**
4
+ * Minimum byte size to compress
5
+ */
6
+ threshold?: number;
7
+ /**
8
+ * Allowed algorithms
9
+ */
10
+ allowedAlgorithms?: string[];
11
+ }
12
+ /**
13
+ * Compression middleware.
14
+ * @param options Compression options
15
+ * @returns Middleware function
16
+ */
17
+ export declare function Compression(options?: CompressionOptions): Middleware;
@@ -0,0 +1,34 @@
1
+ import { ShokupanContext } from '../../context';
2
+ import { Middleware } from '../../util/types';
3
+ export interface CorsOptions {
4
+ /**
5
+ * Origin to allow. Can be a string, array of strings, or function that returns a string.
6
+ */
7
+ origin?: string | string[] | ((ctx: ShokupanContext) => string | undefined | null | boolean);
8
+ /**
9
+ * HTTP methods to allow.
10
+ */
11
+ methods?: string | string[];
12
+ /**
13
+ * HTTP headers to allow.
14
+ */
15
+ allowedHeaders?: string | string[];
16
+ /**
17
+ * HTTP headers to expose.
18
+ */
19
+ exposedHeaders?: string | string[];
20
+ /**
21
+ * Whether to allow credentials.
22
+ */
23
+ credentials?: boolean;
24
+ /**
25
+ * Maximum age of preflight request.
26
+ */
27
+ maxAge?: number;
28
+ }
29
+ /**
30
+ * CORS middleware.
31
+ * @param options CORS options
32
+ * @returns Middleware function
33
+ */
34
+ export declare function Cors(options?: CorsOptions): Middleware;
@@ -1,4 +1,4 @@
1
- import { Middleware } from '../types';
1
+ import { Middleware } from '../../util/types';
2
2
  /**
3
3
  * Adapter to use legacy Express middleware.
4
4
  * NOTE: This provides a PARTIAL mock of req/res.
@@ -1,4 +1,4 @@
1
- import { Middleware } from '../types';
1
+ import { Middleware } from '../../util/types';
2
2
  type ValidatorCache = Map<string, {
3
3
  [method: string]: {
4
4
  body?: import('ajv').ValidateFunction;
@@ -26,5 +26,5 @@ export declare function precompileValidators(app: any, spec: any): void;
26
26
  *
27
27
  * @param app The Shokupan application instance
28
28
  */
29
- export declare function enableOpenApiValidation(app: import('../shokupan').Shokupan): void;
29
+ export declare function enableOpenApiValidation(app: import('../../shokupan').Shokupan): void;
30
30
  export {};
@@ -0,0 +1,37 @@
1
+ import { Middleware } from '../../util/types';
2
+ export interface ProxyOptions {
3
+ /**
4
+ * Target URL to proxy requests to.
5
+ */
6
+ target: string;
7
+ /**
8
+ * Function to rewrite the path of the request.
9
+ */
10
+ pathRewrite?: (path: string) => string;
11
+ /**
12
+ * Whether to change the origin of the request.
13
+ */
14
+ changeOrigin?: boolean;
15
+ /**
16
+ * Whether to proxy WebSocket connections.
17
+ */
18
+ ws?: boolean;
19
+ /**
20
+ * Additional headers to send with the request.
21
+ */
22
+ headers?: Record<string, string>;
23
+ /**
24
+ * Whitelist of allowed target hosts.
25
+ */
26
+ allowedHosts?: string[];
27
+ /**
28
+ * Whether to allow private IPs (disabled by default).
29
+ */
30
+ allowPrivateIPs?: boolean;
31
+ }
32
+ /**
33
+ * Proxy middleware. This will proxy requests that match the path to the target URL.
34
+ * @param options Proxy options
35
+ * @returns Middleware function
36
+ */
37
+ export declare function Proxy(options: ProxyOptions): Middleware;
@@ -0,0 +1,58 @@
1
+ import { ShokupanContext } from '../../context';
2
+ import { Middleware } from '../../util/types';
3
+ export interface RateLimitOptions {
4
+ /**
5
+ * Window in milliseconds
6
+ */
7
+ windowMs?: number;
8
+ /**
9
+ * Maximum number of requests allowed in the window
10
+ */
11
+ max?: number;
12
+ /**
13
+ * Alias for max
14
+ */
15
+ limit?: number;
16
+ /**
17
+ * Message to send when rate limited
18
+ */
19
+ message?: string | object | ((ctx: ShokupanContext, key: string) => string | object);
20
+ /**
21
+ * Status code to send when rate limited
22
+ */
23
+ statusCode?: number;
24
+ /**
25
+ * Whether to include X-RateLimit headers in the response
26
+ */
27
+ headers?: boolean;
28
+ /**
29
+ * Function to generate a unique key for each request
30
+ * This is used to identify the user or source of the request
31
+ * Defaults to the request's ip address.
32
+ */
33
+ keyGenerator?: (ctx: ShokupanContext) => string;
34
+ /**
35
+ * Function to execute when a request is rate limited
36
+ */
37
+ onRateLimited?: (ctx: ShokupanContext, key: string) => void | Response | Promise<void | Response>;
38
+ /**
39
+ * Function to determine whether to skip rate limiting
40
+ */
41
+ skip?: (ctx: ShokupanContext) => boolean;
42
+ /**
43
+ * Mode to use for rate limiting
44
+ * - user: Rate limit per user (generated key, defaults to ip address)
45
+ * - absolute: Rate limit for all users
46
+ */
47
+ mode?: 'user' | 'absolute';
48
+ /**
49
+ * List of trusted proxy IPs
50
+ */
51
+ trustedProxies?: string[];
52
+ }
53
+ /**
54
+ * Rate limit middleware.
55
+ * @param options Rate limit options
56
+ * @returns Middleware function
57
+ */
58
+ export declare function RateLimitMiddleware(options?: RateLimitOptions): Middleware;
@@ -1,36 +1,86 @@
1
- import { Middleware } from '../types';
1
+ import { Middleware } from '../../util/types';
2
2
  export interface SecurityHeadersOptions {
3
+ /**
4
+ * Content Security Policy
5
+ */
3
6
  contentSecurityPolicy?: boolean | Record<string, any>;
7
+ /**
8
+ * Cross-Origin Embedder Policy
9
+ */
4
10
  crossOriginEmbedderPolicy?: boolean;
11
+ /**
12
+ * Cross-Origin Opener Policy
13
+ */
5
14
  crossOriginOpenerPolicy?: boolean;
15
+ /**
16
+ * Cross-Origin Resource Policy
17
+ */
6
18
  crossOriginResourcePolicy?: boolean;
19
+ /**
20
+ * DNS Prefetch Control
21
+ */
7
22
  dnsPrefetchControl?: boolean | {
8
23
  allow: boolean;
9
24
  };
25
+ /**
26
+ * Expect CT
27
+ */
10
28
  expectCt?: boolean | {
11
29
  maxAge?: number;
12
30
  enforce?: boolean;
13
31
  reportUri?: string;
14
32
  };
33
+ /**
34
+ * Frameguard
35
+ */
15
36
  frameguard?: boolean | {
16
37
  action: 'deny' | 'sameorigin' | 'allow-from';
17
38
  domain?: string;
18
39
  };
40
+ /**
41
+ * Hide Powered By
42
+ */
19
43
  hidePoweredBy?: boolean;
44
+ /**
45
+ * HTTP Strict Transport Security
46
+ */
20
47
  hsts?: boolean | {
21
48
  maxAge?: number;
22
49
  includeSubDomains?: boolean;
23
50
  preload?: boolean;
24
51
  };
52
+ /**
53
+ * IE No Open
54
+ */
25
55
  ieNoOpen?: boolean;
56
+ /**
57
+ * No Sniff
58
+ */
26
59
  noSniff?: boolean;
60
+ /**
61
+ * Origin Agent Cluster
62
+ */
27
63
  originAgentCluster?: boolean;
64
+ /**
65
+ * Permitted Cross Domain Policies
66
+ */
28
67
  permittedCrossDomainPolicies?: boolean | {
29
68
  permittedPolicies: 'none' | 'master-only' | 'by-content-type' | 'all';
30
69
  };
70
+ /**
71
+ * Referrer Policy
72
+ */
31
73
  referrerPolicy?: boolean | {
32
74
  policy: string | string[];
33
75
  };
76
+ /**
77
+ * X-XSS-Protection
78
+ */
34
79
  xssFilter?: boolean;
35
80
  }
81
+ /**
82
+ * Security headers middleware.
83
+ * @param options Security headers options
84
+ * @returns Middleware function
85
+ */
36
86
  export declare function SecurityHeaders(options?: SecurityHeadersOptions): Middleware;
@@ -1,2 +1,2 @@
1
- import { Middleware, StaticServeOptions } from '../types';
1
+ import { Middleware, StaticServeOptions } from '../../util/types';
2
2
  export declare function serveStatic<T extends Record<string, any>>(config: StaticServeOptions<T>, prefix: string): Middleware;