shokupan 0.6.0 → 0.7.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 +4 -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 +72 -11
- package/dist/{server-adapter-0xH174zz.js → http-server-0xH174zz.js} +1 -1
- package/dist/http-server-0xH174zz.js.map +1 -0
- package/dist/{server-adapter-DFhwlK8e.cjs → http-server-DFhwlK8e.cjs} +1 -1
- package/dist/http-server-DFhwlK8e.cjs.map +1 -0
- package/dist/index.cjs +1022 -801
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +17 -17
- package/dist/index.js +1022 -800
- 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/{debugview → application/dashboard}/plugin.d.ts +13 -6
- 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/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 +99 -40
- package/dist/shokupan.d.ts +74 -4
- package/dist/util/async-hooks.d.ts +8 -2
- package/dist/{decorators.d.ts → util/decorators.d.ts} +1 -1
- package/dist/util/http-status.d.ts +2 -0
- package/dist/util/instrumentation.d.ts +1 -1
- package/dist/{router → util}/trie.d.ts +1 -1
- package/dist/{types.d.ts → util/types.d.ts} +41 -2
- package/package.json +5 -5
- 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/proxy.d.ts +0 -9
- package/dist/plugins/rate-limit.d.ts +0 -14
- 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/{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/{request.d.ts → util/request.d.ts} +0 -0
- /package/dist/{response.d.ts → util/response.d.ts} +0 -0
- /package/dist/{symbol.d.ts → util/symbol.d.ts} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Middleware } from '
|
|
1
|
+
import { Middleware } from '../../util/types';
|
|
2
2
|
export interface ValidationConfig {
|
|
3
3
|
body?: any;
|
|
4
4
|
query?: any;
|
|
@@ -15,4 +15,9 @@ export declare const valibot: (schema: any, parser: Function) => {
|
|
|
15
15
|
schema: any;
|
|
16
16
|
parser: Function;
|
|
17
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Validation middleware.
|
|
20
|
+
* @param config Validation configuration
|
|
21
|
+
* @returns Middleware function
|
|
22
|
+
*/
|
|
18
23
|
export declare function validate(config: ValidationConfig): Middleware;
|
package/dist/router.d.ts
CHANGED
|
@@ -1,10 +1,68 @@
|
|
|
1
1
|
import { ShokupanContext } from './context';
|
|
2
2
|
import { Shokupan } from './shokupan';
|
|
3
|
-
import { $appRoot, $childControllers, $childRouters, $isApplication, $isMounted, $isRouter, $mountPath, $parent, $routes } from './symbol';
|
|
4
|
-
import { GuardAPISpec, JSXRenderer, Method, MethodAPISpec, Middleware, OpenAPIOptions, ProcessResult, RequestOptions, RouteMetadata, ShokupanController, ShokupanHandler, ShokupanHooks, ShokupanRoute, ShokupanRouteConfig, StaticServeOptions } from './types';
|
|
5
|
-
type HeadersInit = Headers | Record<string, string> | [string, string][];
|
|
3
|
+
import { $appRoot, $childControllers, $childRouters, $isApplication, $isMounted, $isRouter, $mountPath, $parent, $routes } from './util/symbol';
|
|
4
|
+
import { GuardAPISpec, HeadersInit, JSXRenderer, Method, MethodAPISpec, Middleware, OpenAPIOptions, ProcessResult, RequestOptions, RouteMetadata, RouteParams, ShokupanController, ShokupanHandler, ShokupanHooks, ShokupanRoute, ShokupanRouteConfig, StaticServeOptions } from './util/types';
|
|
6
5
|
export declare const RouterRegistry: Map<string, ShokupanRouter<any>>;
|
|
7
6
|
export declare const ShokupanApplicationTree: {};
|
|
7
|
+
/**
|
|
8
|
+
* Shokupan Router
|
|
9
|
+
*
|
|
10
|
+
* A router for organizing and grouping routes with shared middleware and configuration.
|
|
11
|
+
*
|
|
12
|
+
* @template State - The shape of `ctx.state` for all routes in this router.
|
|
13
|
+
* Provides type safety for state management within the router's middleware and handlers.
|
|
14
|
+
*
|
|
15
|
+
* @example Basic Router
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const router = new ShokupanRouter();
|
|
18
|
+
* router.get('/users', (ctx) => ctx.json({ users: [] }));
|
|
19
|
+
*
|
|
20
|
+
* app.mount('/api', router);
|
|
21
|
+
* // Routes: GET /api/users
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example Typed State Router
|
|
25
|
+
* ```typescript
|
|
26
|
+
* interface AuthState {
|
|
27
|
+
* userId: string;
|
|
28
|
+
* isAuthenticated: boolean;
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* class AuthRouter extends ShokupanRouter<AuthState> {
|
|
32
|
+
* constructor() {
|
|
33
|
+
* super();
|
|
34
|
+
*
|
|
35
|
+
* // Router middleware has typed state
|
|
36
|
+
* this.use((ctx, next) => {
|
|
37
|
+
* ctx.state.userId = 'user-123';
|
|
38
|
+
* ctx.state.isAuthenticated = true;
|
|
39
|
+
* return next();
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* this.get('/me', (ctx) => {
|
|
43
|
+
* // State is fully typed
|
|
44
|
+
* return ctx.json({ userId: ctx.state.userId });
|
|
45
|
+
* });
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* app.mount('/auth', new AuthRouter());
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example Router with Middleware
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const apiRouter = new ShokupanRouter();
|
|
55
|
+
*
|
|
56
|
+
* // Router-level middleware
|
|
57
|
+
* apiRouter.use(async (ctx, next) => {
|
|
58
|
+
* console.log(`API request: ${ctx.method} ${ctx.path}`);
|
|
59
|
+
* return next();
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* apiRouter.get('/status', (ctx) => ctx.json({ status: 'ok' }));
|
|
63
|
+
* app.mount('/api', apiRouter);
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
8
66
|
export declare class ShokupanRouter<T extends Record<string, any> = Record<string, any>> {
|
|
9
67
|
readonly config?: ShokupanRouteConfig;
|
|
10
68
|
private [$isApplication];
|
|
@@ -34,7 +92,7 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
34
92
|
enableMiddlewareTracking?: boolean;
|
|
35
93
|
middlewareTrackingMaxCapacity?: number;
|
|
36
94
|
middlewareTrackingTTL?: number;
|
|
37
|
-
httpLogger?: (ctx: ShokupanContext<Record<string, any>>) => void;
|
|
95
|
+
httpLogger?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void;
|
|
38
96
|
logger?: {
|
|
39
97
|
verbose?: boolean;
|
|
40
98
|
info?: (msg: string, props: Record<string, any>) => void;
|
|
@@ -47,29 +105,29 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
47
105
|
requestTimeout?: number;
|
|
48
106
|
writeTimeout?: number;
|
|
49
107
|
renderer?: JSXRenderer;
|
|
50
|
-
serverFactory?: import('
|
|
108
|
+
serverFactory?: import('.').ServerFactory;
|
|
51
109
|
hooks?: {
|
|
52
|
-
onError?: (ctx: ShokupanContext<Record<string, any>>, error: unknown) => void | Promise<void>;
|
|
53
|
-
onRequestStart?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
54
|
-
onRequestEnd?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
55
|
-
onResponseStart?: (ctx: ShokupanContext<Record<string, any>>, response: Response) => void | Promise<void>;
|
|
56
|
-
onResponseEnd?: (ctx: ShokupanContext<Record<string, any>>, response: Response) => void | Promise<void>;
|
|
57
|
-
beforeValidate?: (ctx: ShokupanContext<Record<string, any>>, data: any) => void | Promise<void>;
|
|
58
|
-
afterValidate?: (ctx: ShokupanContext<Record<string, any>>, data: any) => void | Promise<void>;
|
|
59
|
-
onReadTimeout?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
60
|
-
onWriteTimeout?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
61
|
-
onRequestTimeout?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
110
|
+
onError?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, error: unknown) => void | Promise<void>;
|
|
111
|
+
onRequestStart?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
112
|
+
onRequestEnd?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
113
|
+
onResponseStart?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, response: Response) => void | Promise<void>;
|
|
114
|
+
onResponseEnd?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, response: Response) => void | Promise<void>;
|
|
115
|
+
beforeValidate?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, data: any) => void | Promise<void>;
|
|
116
|
+
afterValidate?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, data: any) => void | Promise<void>;
|
|
117
|
+
onReadTimeout?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
118
|
+
onWriteTimeout?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
119
|
+
onRequestTimeout?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
62
120
|
} | {
|
|
63
|
-
onError?: (ctx: ShokupanContext<Record<string, any>>, error: unknown) => void | Promise<void>;
|
|
64
|
-
onRequestStart?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
65
|
-
onRequestEnd?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
66
|
-
onResponseStart?: (ctx: ShokupanContext<Record<string, any>>, response: Response) => void | Promise<void>;
|
|
67
|
-
onResponseEnd?: (ctx: ShokupanContext<Record<string, any>>, response: Response) => void | Promise<void>;
|
|
68
|
-
beforeValidate?: (ctx: ShokupanContext<Record<string, any>>, data: any) => void | Promise<void>;
|
|
69
|
-
afterValidate?: (ctx: ShokupanContext<Record<string, any>>, data: any) => void | Promise<void>;
|
|
70
|
-
onReadTimeout?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
71
|
-
onWriteTimeout?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
72
|
-
onRequestTimeout?: (ctx: ShokupanContext<Record<string, any>>) => void | Promise<void>;
|
|
121
|
+
onError?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, error: unknown) => void | Promise<void>;
|
|
122
|
+
onRequestStart?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
123
|
+
onRequestEnd?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
124
|
+
onResponseStart?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, response: Response) => void | Promise<void>;
|
|
125
|
+
onResponseEnd?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, response: Response) => void | Promise<void>;
|
|
126
|
+
beforeValidate?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, data: any) => void | Promise<void>;
|
|
127
|
+
afterValidate?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, data: any) => void | Promise<void>;
|
|
128
|
+
onReadTimeout?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
129
|
+
onWriteTimeout?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
130
|
+
onRequestTimeout?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
73
131
|
}[];
|
|
74
132
|
validateStatusCodes?: boolean;
|
|
75
133
|
};
|
|
@@ -153,6 +211,8 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
153
211
|
*/
|
|
154
212
|
testRequest(options: RequestOptions): Promise<ProcessResult>;
|
|
155
213
|
private wrapWithHooks;
|
|
214
|
+
private mountRouter;
|
|
215
|
+
private scanControllerRoutes;
|
|
156
216
|
/**
|
|
157
217
|
* Find a route matching the given method and path.
|
|
158
218
|
* @param method HTTP method
|
|
@@ -196,7 +256,7 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
196
256
|
* @param path - URL path
|
|
197
257
|
* @param handlers - Route handler functions
|
|
198
258
|
*/
|
|
199
|
-
get(path:
|
|
259
|
+
get<Path extends string>(path: Path, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
200
260
|
/**
|
|
201
261
|
* Adds a GET route to the router.
|
|
202
262
|
*
|
|
@@ -204,14 +264,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
204
264
|
* @param spec - OpenAPI specification for the route
|
|
205
265
|
* @param handlers - Route handler functions
|
|
206
266
|
*/
|
|
207
|
-
get(path:
|
|
267
|
+
get<Path extends string>(path: Path, spec: MethodAPISpec, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
208
268
|
/**
|
|
209
269
|
* Adds a POST route to the router.
|
|
210
270
|
*
|
|
211
271
|
* @param path - URL path
|
|
212
272
|
* @param handlers - Route handler functions
|
|
213
273
|
*/
|
|
214
|
-
post(path:
|
|
274
|
+
post<Path extends string>(path: Path, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
215
275
|
/**
|
|
216
276
|
* Adds a POST route to the router.
|
|
217
277
|
*
|
|
@@ -219,14 +279,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
219
279
|
* @param spec - OpenAPI specification for the route
|
|
220
280
|
* @param handlers - Route handler functions
|
|
221
281
|
*/
|
|
222
|
-
post(path:
|
|
282
|
+
post<Path extends string>(path: Path, spec: MethodAPISpec, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
223
283
|
/**
|
|
224
284
|
* Adds a PUT route to the router.
|
|
225
285
|
*
|
|
226
286
|
* @param path - URL path
|
|
227
287
|
* @param handlers - Route handler functions
|
|
228
288
|
*/
|
|
229
|
-
put(path:
|
|
289
|
+
put<Path extends string>(path: Path, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
230
290
|
/**
|
|
231
291
|
* Adds a PUT route to the router.
|
|
232
292
|
*
|
|
@@ -234,14 +294,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
234
294
|
* @param spec - OpenAPI specification for the route
|
|
235
295
|
* @param handlers - Route handler functions
|
|
236
296
|
*/
|
|
237
|
-
put(path:
|
|
297
|
+
put<Path extends string>(path: Path, spec: MethodAPISpec, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
238
298
|
/**
|
|
239
299
|
* Adds a DELETE route to the router.
|
|
240
300
|
*
|
|
241
301
|
* @param path - URL path
|
|
242
302
|
* @param handlers - Route handler functions
|
|
243
303
|
*/
|
|
244
|
-
delete(path:
|
|
304
|
+
delete<Path extends string>(path: Path, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
245
305
|
/**
|
|
246
306
|
* Adds a DELETE route to the router.
|
|
247
307
|
*
|
|
@@ -249,14 +309,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
249
309
|
* @param spec - OpenAPI specification for the route
|
|
250
310
|
* @param handlers - Route handler functions
|
|
251
311
|
*/
|
|
252
|
-
delete(path:
|
|
312
|
+
delete<Path extends string>(path: Path, spec: MethodAPISpec, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
253
313
|
/**
|
|
254
314
|
* Adds a PATCH route to the router.
|
|
255
315
|
*
|
|
256
316
|
* @param path - URL path
|
|
257
317
|
* @param handlers - Route handler functions
|
|
258
318
|
*/
|
|
259
|
-
patch(path:
|
|
319
|
+
patch<Path extends string>(path: Path, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
260
320
|
/**
|
|
261
321
|
* Adds a PATCH route to the router.
|
|
262
322
|
*
|
|
@@ -264,14 +324,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
264
324
|
* @param spec - OpenAPI specification for the route
|
|
265
325
|
* @param handlers - Route handler functions
|
|
266
326
|
*/
|
|
267
|
-
patch(path:
|
|
327
|
+
patch<Path extends string>(path: Path, spec: MethodAPISpec, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
268
328
|
/**
|
|
269
329
|
* Adds a OPTIONS route to the router.
|
|
270
330
|
*
|
|
271
331
|
* @param path - URL path
|
|
272
332
|
* @param handlers - Route handler functions
|
|
273
333
|
*/
|
|
274
|
-
options(path:
|
|
334
|
+
options<Path extends string>(path: Path, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
275
335
|
/**
|
|
276
336
|
* Adds a OPTIONS route to the router.
|
|
277
337
|
*
|
|
@@ -279,14 +339,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
279
339
|
* @param spec - OpenAPI specification for the route
|
|
280
340
|
* @param handlers - Route handler functions
|
|
281
341
|
*/
|
|
282
|
-
options(path:
|
|
342
|
+
options<Path extends string>(path: Path, spec: MethodAPISpec, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
283
343
|
/**
|
|
284
344
|
* Adds a HEAD route to the router.
|
|
285
345
|
*
|
|
286
346
|
* @param path - URL path
|
|
287
347
|
* @param handlers - Route handler functions
|
|
288
348
|
*/
|
|
289
|
-
head(path:
|
|
349
|
+
head<Path extends string>(path: Path, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
290
350
|
/**
|
|
291
351
|
* Adds a HEAD route to the router.
|
|
292
352
|
*
|
|
@@ -294,7 +354,7 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
294
354
|
* @param spec - OpenAPI specification for the route
|
|
295
355
|
* @param handlers - Route handler functions
|
|
296
356
|
*/
|
|
297
|
-
head(path:
|
|
357
|
+
head<Path extends string>(path: Path, spec: MethodAPISpec, ...handlers: ShokupanHandler<T, RouteParams<Path>>[]): any;
|
|
298
358
|
/**
|
|
299
359
|
* Adds a guard to the router that applies to all routes added **after** this point.
|
|
300
360
|
* Guards must return true or call `ctx.next()` to allow the request to continue.
|
|
@@ -329,4 +389,3 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
329
389
|
private ensureHooksInitialized;
|
|
330
390
|
runHooks(name: keyof ShokupanHooks, ...args: any[]): Promise<void>;
|
|
331
391
|
}
|
|
332
|
-
export {};
|
package/dist/shokupan.d.ts
CHANGED
|
@@ -1,8 +1,72 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { $dispatch } from './symbol';
|
|
4
|
-
import { Middleware, ProcessResult, RequestOptions, ShokupanConfig } from './types';
|
|
1
|
+
import { $dispatch } from './util/symbol';
|
|
2
|
+
import { Middleware, ProcessResult, RequestOptions, ShokupanConfig, ShokupanPlugin } from './util/types';
|
|
5
3
|
import { Server } from 'bun';
|
|
4
|
+
import { ShokupanRouter } from './router';
|
|
5
|
+
import { ShokupanRequest } from './util/request';
|
|
6
|
+
/**
|
|
7
|
+
* Shokupan Application
|
|
8
|
+
*
|
|
9
|
+
* The main application class for creating a Shokupan web server.
|
|
10
|
+
*
|
|
11
|
+
* @template State - The shape of `ctx.state` for all routes in the application.
|
|
12
|
+
* Use this to provide type safety for state management across middleware and handlers.
|
|
13
|
+
*
|
|
14
|
+
* @example Basic Usage
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const app = new Shokupan();
|
|
17
|
+
* app.get('/hello', (ctx) => ctx.json({ message: 'Hello' }));
|
|
18
|
+
* await app.listen(3000);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @example Typed State
|
|
22
|
+
* ```typescript
|
|
23
|
+
* interface AppState {
|
|
24
|
+
* userId: string;
|
|
25
|
+
* tenant: string;
|
|
26
|
+
* requestId: string;
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* const app = new Shokupan<AppState>();
|
|
30
|
+
*
|
|
31
|
+
* // Middleware has typed state access
|
|
32
|
+
* app.use((ctx, next) => {
|
|
33
|
+
* ctx.state.userId = 'user-123'; // ✓ Type-safe
|
|
34
|
+
* ctx.state.requestId = crypto.randomUUID();
|
|
35
|
+
* return next();
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Handlers have typed state access
|
|
39
|
+
* app.get('/profile', (ctx) => {
|
|
40
|
+
* const { userId, tenant } = ctx.state; // ✓ TypeScript knows these exist
|
|
41
|
+
* return ctx.json({ userId, tenant });
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @example Empty State (No State Management)
|
|
46
|
+
* ```typescript
|
|
47
|
+
* import { EmptyState } from 'shokupan';
|
|
48
|
+
*
|
|
49
|
+
* const app = new Shokupan<EmptyState>();
|
|
50
|
+
* // ctx.state will be an empty object with no properties
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @example Combining Path Params and State
|
|
54
|
+
* ```typescript
|
|
55
|
+
* interface RequestState {
|
|
56
|
+
* userId: string;
|
|
57
|
+
* permissions: string[];
|
|
58
|
+
* }
|
|
59
|
+
*
|
|
60
|
+
* const app = new Shokupan<RequestState>();
|
|
61
|
+
*
|
|
62
|
+
* app.get('/users/:userId/posts/:postId', (ctx) => {
|
|
63
|
+
* // Both params and state are fully typed!
|
|
64
|
+
* const { userId, postId } = ctx.params; // ✓ Path params typed
|
|
65
|
+
* const { permissions } = ctx.state; // ✓ State typed
|
|
66
|
+
* return ctx.json({ userId, postId, permissions });
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
6
70
|
export declare class Shokupan<T = any> extends ShokupanRouter<T> {
|
|
7
71
|
readonly applicationConfig: ShokupanConfig;
|
|
8
72
|
openApiSpec?: any;
|
|
@@ -21,6 +85,12 @@ export declare class Shokupan<T = any> extends ShokupanRouter<T> {
|
|
|
21
85
|
* Adds middleware to the application.
|
|
22
86
|
*/
|
|
23
87
|
use(middleware: Middleware): this;
|
|
88
|
+
/**
|
|
89
|
+
* Registers a plugin.
|
|
90
|
+
*/
|
|
91
|
+
register(plugin: ShokupanPlugin, options?: {
|
|
92
|
+
path?: string;
|
|
93
|
+
}): this;
|
|
24
94
|
private startupHooks;
|
|
25
95
|
/**
|
|
26
96
|
* Registers a callback to be executed before the server starts listening.
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
|
|
3
|
-
export declare
|
|
2
|
+
import { Span } from '@opentelemetry/api';
|
|
3
|
+
export declare class RequestContextStore {
|
|
4
|
+
request?: Request;
|
|
5
|
+
span?: Span;
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
}
|
|
8
|
+
export declare const asyncContext: AsyncLocalStorage<RequestContextStore>;
|
|
9
|
+
export declare function runInContext<T>(callback: () => T, initialStore?: RequestContextStore): T;
|
|
@@ -1,11 +1,45 @@
|
|
|
1
1
|
import { OpenAPI } from '@scalar/openapi-types';
|
|
2
2
|
import { Server } from 'bun';
|
|
3
3
|
import { Server as NodeServer } from 'node:http';
|
|
4
|
-
import { ShokupanContext } from '
|
|
4
|
+
import { ShokupanContext } from '../context';
|
|
5
5
|
import { $isRouter } from './symbol';
|
|
6
|
+
export type HeadersInit = Headers | Record<string, string> | [string, string][];
|
|
7
|
+
export interface ShokupanPluginOptions {
|
|
8
|
+
path?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ShokupanPlugin {
|
|
11
|
+
onInit: (app: any, options?: ShokupanPluginOptions) => void | Promise<void>;
|
|
12
|
+
}
|
|
6
13
|
export type DeepPartial<T> = T extends Function ? T : T extends object ? {
|
|
7
14
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
8
15
|
} : T;
|
|
16
|
+
/**
|
|
17
|
+
* Helper type for applications that don't use ctx.state.
|
|
18
|
+
* Prevents accidental property access on state.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const app = new Shokupan<EmptyState>();
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export type EmptyState = Record<string, never>;
|
|
26
|
+
/**
|
|
27
|
+
* Default state type that allows any properties.
|
|
28
|
+
* This is the default if no state type is specified.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const app = new Shokupan<DefaultState>();
|
|
33
|
+
* // Equivalent to: new Shokupan();
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export type DefaultState = Record<string, any>;
|
|
37
|
+
type ParsePathParams<Path extends string> = Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? {
|
|
38
|
+
[K in Param | keyof ParsePathParams<`/${Rest}`>]: string;
|
|
39
|
+
} : Path extends `${infer _Start}:${infer Param}` ? {
|
|
40
|
+
[K in Param]: string;
|
|
41
|
+
} : {};
|
|
42
|
+
export type RouteParams<Path extends string> = string extends Path ? Record<string, string> : ParsePathParams<Path> extends Record<string, never> ? Record<string, string> : ParsePathParams<Path>;
|
|
9
43
|
export interface RouteMetadata {
|
|
10
44
|
file: string;
|
|
11
45
|
line: number;
|
|
@@ -49,7 +83,7 @@ export interface CookieOptions {
|
|
|
49
83
|
sameSite?: boolean | 'lax' | 'strict' | 'none' | 'Lax' | 'Strict' | 'None';
|
|
50
84
|
priority?: 'low' | 'medium' | 'high' | 'Low' | 'Medium' | 'High';
|
|
51
85
|
}
|
|
52
|
-
export type ShokupanHandler<
|
|
86
|
+
export type ShokupanHandler<State extends Record<string, any> = Record<string, any>, Params extends Record<string, string> = Record<string, string>> = (ctx: ShokupanContext<State, Params>, next?: NextFn) => Promise<any> | any;
|
|
53
87
|
export declare const HTTPMethods: string[];
|
|
54
88
|
export type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD" | "ALL";
|
|
55
89
|
export declare enum RouteParamType {
|
|
@@ -350,6 +384,10 @@ export interface StaticServeOptions<T extends Record<string, any>> {
|
|
|
350
384
|
root?: string;
|
|
351
385
|
/**
|
|
352
386
|
* Whether to list directory contents if no index file is found.
|
|
387
|
+
*
|
|
388
|
+
* Security Note: Directory listing is disabled by default to prevent information disclosure.
|
|
389
|
+
* Enable this only if you specifically need it and understand the security implications.
|
|
390
|
+
*
|
|
353
391
|
* @default false
|
|
354
392
|
*/
|
|
355
393
|
listDirectory?: boolean;
|
|
@@ -384,3 +422,4 @@ export interface StaticServeOptions<T extends Record<string, any>> {
|
|
|
384
422
|
*/
|
|
385
423
|
openapi?: MethodAPISpec;
|
|
386
424
|
}
|
|
425
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shokupan",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Shokupan is a low-lift modern web framework for Bun.",
|
|
5
5
|
"author": "Andrew G. Knackstedt",
|
|
6
6
|
"publishConfig": {
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
],
|
|
23
23
|
"type": "module",
|
|
24
24
|
"scripts": {
|
|
25
|
-
"dev": "bun --watch --inspect
|
|
25
|
+
"dev": "bun --watch --inspect examples/full/main.ts",
|
|
26
26
|
"debug:otel": "sh scripts/debug-otel.sh",
|
|
27
27
|
"docs": "cd docs && bun run dev",
|
|
28
28
|
"build": "vite build",
|
|
29
|
-
"bench": "cd
|
|
30
|
-
"bench:advanced": "cd
|
|
29
|
+
"bench": "cd benchmarking && bun runner.ts",
|
|
30
|
+
"bench:advanced": "cd benchmarking && bun advanced-runner.ts",
|
|
31
31
|
"retag": "git push origin :refs/tags/v$(node -p \"require('./package.json').version\") 2>/dev/null || true && git tag -d v$(node -p \"require('./package.json').version\") 2>/dev/null || true && git tag v$(node -p \"require('./package.json').version\") && git push origin v$(node -p \"require('./package.json').version\") --force"
|
|
32
32
|
},
|
|
33
33
|
"bin": {
|
|
@@ -152,4 +152,4 @@
|
|
|
152
152
|
"vite-plugin-dts": "^4.5.4",
|
|
153
153
|
"zod": "^4.2.1"
|
|
154
154
|
}
|
|
155
|
-
}
|
|
155
|
+
}
|