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.
- package/README.md +55 -2
- package/dist/{openapi-analyzer-Bei1sVWp.cjs → analyzer-Bei1sVWp.cjs} +1 -1
- package/dist/analyzer-Bei1sVWp.cjs.map +1 -0
- package/dist/{openapi-analyzer-Ce_7JxZh.js → analyzer-Ce_7JxZh.js} +1 -1
- package/dist/analyzer-Ce_7JxZh.js.map +1 -0
- package/dist/cli.cjs +2 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/context.d.ts +58 -23
- package/dist/{server-adapter-DFhwlK8e.cjs → http-server-BEMPIs33.cjs} +4 -2
- package/dist/http-server-BEMPIs33.cjs.map +1 -0
- package/dist/{server-adapter-0xH174zz.js → http-server-CCeagTyU.js} +4 -2
- package/dist/http-server-CCeagTyU.js.map +1 -0
- package/dist/index.cjs +1940 -917
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -17
- package/dist/index.js +1948 -925
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +1 -1
- package/dist/plugins/{auth.d.ts → application/auth.d.ts} +72 -3
- package/dist/plugins/application/cluster.d.ts +33 -0
- package/dist/plugins/{failed-request-recorder.d.ts → application/dashboard/failed-request-recorder.d.ts} +1 -1
- package/dist/plugins/application/dashboard/metrics-collector.d.ts +12 -0
- package/dist/plugins/application/dashboard/plugin.d.ts +42 -0
- package/dist/plugins/application/dashboard/static/charts.js +328 -0
- package/dist/plugins/application/dashboard/static/failures.js +85 -0
- package/dist/plugins/application/dashboard/static/graph.mjs +523 -0
- package/dist/plugins/application/dashboard/static/poll.js +146 -0
- package/dist/plugins/application/dashboard/static/reactflow.css +18 -0
- package/dist/plugins/application/dashboard/static/registry.css +131 -0
- package/dist/plugins/application/dashboard/static/registry.js +269 -0
- package/dist/plugins/application/dashboard/static/requests.js +118 -0
- package/dist/plugins/application/dashboard/static/scrollbar.css +24 -0
- package/dist/plugins/application/dashboard/static/styles.css +175 -0
- package/dist/plugins/application/dashboard/static/tables.js +92 -0
- package/dist/plugins/application/dashboard/static/tabs.js +113 -0
- package/dist/plugins/application/dashboard/static/tabulator.css +66 -0
- package/dist/plugins/application/dashboard/template.eta +246 -0
- package/dist/plugins/{server-adapter.d.ts → application/http-server.d.ts} +1 -1
- package/dist/plugins/{idempotency → application/idempotency}/plugin.d.ts +7 -1
- package/dist/plugins/{openapi.d.ts → application/openapi/openapi.d.ts} +2 -2
- package/dist/plugins/application/scalar.d.ts +36 -0
- package/dist/plugins/application/socket-io.d.ts +14 -0
- package/dist/plugins/middleware/compression.d.ts +17 -0
- package/dist/plugins/middleware/cors.d.ts +34 -0
- package/dist/plugins/{express.d.ts → middleware/express.d.ts} +1 -1
- package/dist/plugins/{openapi-validator.d.ts → middleware/openapi-validator.d.ts} +2 -2
- package/dist/plugins/middleware/proxy.d.ts +37 -0
- package/dist/plugins/middleware/rate-limit.d.ts +58 -0
- package/dist/plugins/{security-headers.d.ts → middleware/security-headers.d.ts} +51 -1
- package/dist/plugins/{serve-static.d.ts → middleware/serve-static.d.ts} +1 -1
- package/dist/plugins/{session.d.ts → middleware/session.d.ts} +89 -3
- package/dist/plugins/{validation.d.ts → middleware/validation.d.ts} +6 -1
- package/dist/router.d.ts +17 -5
- package/dist/shokupan.d.ts +31 -5
- package/dist/util/async-hooks.d.ts +8 -2
- package/dist/util/datastore.d.ts +4 -3
- package/dist/{decorators.d.ts → util/decorators.d.ts} +6 -1
- package/dist/util/http-error.d.ts +38 -0
- package/dist/util/http-status.d.ts +32 -0
- package/dist/util/instrumentation.d.ts +1 -1
- package/dist/{request.d.ts → util/request.d.ts} +1 -1
- package/dist/util/symbol.d.ts +34 -0
- package/dist/{router → util}/trie.d.ts +1 -1
- package/dist/{types.d.ts → util/types.d.ts} +38 -2
- package/package.json +9 -6
- package/dist/openapi-analyzer-Bei1sVWp.cjs.map +0 -1
- package/dist/openapi-analyzer-Ce_7JxZh.js.map +0 -1
- package/dist/plugins/compression.d.ts +0 -5
- package/dist/plugins/cors.d.ts +0 -11
- package/dist/plugins/debugview/plugin.d.ts +0 -29
- package/dist/plugins/proxy.d.ts +0 -11
- package/dist/plugins/rate-limit.d.ts +0 -15
- package/dist/plugins/scalar.d.ts +0 -15
- package/dist/server-adapter-0xH174zz.js.map +0 -1
- package/dist/server-adapter-DFhwlK8e.cjs.map +0 -1
- package/dist/symbol.d.ts +0 -15
- /package/dist/{analysis/openapi-analyzer.d.ts → plugins/application/openapi/analyzer.d.ts} +0 -0
- /package/dist/{di.d.ts → util/di.d.ts} +0 -0
- /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 { Middleware } from '
|
|
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 '
|
|
2
|
-
import { OpenAPIOptions } from '
|
|
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 '
|
|
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('
|
|
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 '
|
|
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 '
|
|
1
|
+
import { Middleware, StaticServeOptions } from '../../util/types';
|
|
2
2
|
export declare function serveStatic<T extends Record<string, any>>(config: StaticServeOptions<T>, prefix: string): Middleware;
|