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
|
@@ -1,43 +1,124 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { ShokupanContext } from '
|
|
3
|
-
import { Middleware } from '
|
|
2
|
+
import { ShokupanContext } from '../../context';
|
|
3
|
+
import { Middleware } from '../../util/types';
|
|
4
4
|
export interface SessionData {
|
|
5
5
|
cookie: Cookie;
|
|
6
6
|
[key: string]: any;
|
|
7
7
|
}
|
|
8
8
|
export interface SessionCookieOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Maximum age of the session cookie in milliseconds.
|
|
11
|
+
*/
|
|
9
12
|
maxAge?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the session cookie should be signed.
|
|
15
|
+
*/
|
|
10
16
|
signed?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Expiration date of the session cookie.
|
|
19
|
+
*/
|
|
11
20
|
expires?: Date;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the session cookie should be HTTP-only.
|
|
23
|
+
*/
|
|
12
24
|
httpOnly?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Path of the session cookie.
|
|
27
|
+
*/
|
|
13
28
|
path?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Domain of the session cookie.
|
|
31
|
+
*/
|
|
14
32
|
domain?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the session cookie should be secure.
|
|
35
|
+
*/
|
|
15
36
|
secure?: boolean | 'auto';
|
|
37
|
+
/**
|
|
38
|
+
* SameSite attribute of the session cookie.
|
|
39
|
+
*/
|
|
16
40
|
sameSite?: boolean | 'lax' | 'strict' | 'none';
|
|
41
|
+
/**
|
|
42
|
+
* Priority of the session cookie.
|
|
43
|
+
*/
|
|
17
44
|
priority?: 'low' | 'medium' | 'high';
|
|
18
45
|
}
|
|
19
46
|
export interface SessionOptions {
|
|
47
|
+
/**
|
|
48
|
+
* Secret used to sign the session cookie.
|
|
49
|
+
*/
|
|
20
50
|
secret: string | string[];
|
|
51
|
+
/**
|
|
52
|
+
* Name of the session cookie.
|
|
53
|
+
*/
|
|
21
54
|
name?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Store to use for session data.
|
|
57
|
+
*/
|
|
22
58
|
store?: Store;
|
|
59
|
+
/**
|
|
60
|
+
* Options for the session cookie.
|
|
61
|
+
*/
|
|
23
62
|
cookie?: SessionCookieOptions;
|
|
63
|
+
/**
|
|
64
|
+
* Function to generate a session ID.
|
|
65
|
+
*/
|
|
24
66
|
genid?: (ctx: ShokupanContext) => string;
|
|
67
|
+
/**
|
|
68
|
+
* Whether to force a session identifier cookie to be set on every response.
|
|
69
|
+
*/
|
|
25
70
|
resave?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Whether to save the session on every request.
|
|
73
|
+
*/
|
|
26
74
|
saveUninitialized?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Whether to update the session cookie on every request.
|
|
77
|
+
*/
|
|
27
78
|
rolling?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Whether to destroy or keep the session on logout.
|
|
81
|
+
*/
|
|
28
82
|
unset?: 'destroy' | 'keep';
|
|
29
83
|
}
|
|
30
84
|
export interface Store extends EventEmitter {
|
|
85
|
+
/**
|
|
86
|
+
* Retrieves a session by ID.
|
|
87
|
+
*/
|
|
31
88
|
get(sid: string, callback: (err: any, session?: SessionData | null) => void): void;
|
|
89
|
+
/**
|
|
90
|
+
* Stores a session.
|
|
91
|
+
*/
|
|
32
92
|
set(sid: string, session: SessionData, callback?: (err?: any) => void): void;
|
|
93
|
+
/**
|
|
94
|
+
* Destroys a session.
|
|
95
|
+
*/
|
|
33
96
|
destroy(sid: string, callback?: (err?: any) => void): void;
|
|
97
|
+
/**
|
|
98
|
+
* Touches a session.
|
|
99
|
+
*/
|
|
34
100
|
touch?(sid: string, session: SessionData, callback?: (err?: any) => void): void;
|
|
101
|
+
/**
|
|
102
|
+
* Retrieves all sessions.
|
|
103
|
+
*/
|
|
35
104
|
all?(callback: (err: any, obj?: {
|
|
36
105
|
[sid: string]: SessionData;
|
|
37
106
|
} | null) => void): void;
|
|
107
|
+
/**
|
|
108
|
+
* Retrieves the number of sessions.
|
|
109
|
+
*/
|
|
38
110
|
length?(callback: (err: any, length?: number) => void): void;
|
|
111
|
+
/**
|
|
112
|
+
* Clears all sessions.
|
|
113
|
+
*/
|
|
39
114
|
clear?(callback?: (err?: any) => void): void;
|
|
115
|
+
/**
|
|
116
|
+
* Loads a session.
|
|
117
|
+
*/
|
|
40
118
|
load?(sid: string, fn: (err: any, session?: SessionData | null) => void): void;
|
|
119
|
+
/**
|
|
120
|
+
* Creates a session.
|
|
121
|
+
*/
|
|
41
122
|
createSession?(req: any, session: SessionData): SessionData;
|
|
42
123
|
}
|
|
43
124
|
declare class Cookie implements SessionCookieOptions {
|
|
@@ -76,12 +157,17 @@ export interface SessionContext {
|
|
|
76
157
|
sessionID: string;
|
|
77
158
|
sessionStore: Store;
|
|
78
159
|
}
|
|
79
|
-
declare module "
|
|
160
|
+
declare module "../../context" {
|
|
80
161
|
interface ShokupanContext {
|
|
81
162
|
session: SessionContext['session'];
|
|
82
163
|
sessionID: string;
|
|
83
164
|
sessionStore: Store;
|
|
84
165
|
}
|
|
85
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Session middleware.
|
|
169
|
+
* @param options Session options
|
|
170
|
+
* @returns Middleware function
|
|
171
|
+
*/
|
|
86
172
|
export declare function Session(options: SessionOptions): Middleware;
|
|
87
173
|
export {};
|
|
@@ -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,8 +1,7 @@
|
|
|
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, RouteParams, 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: {};
|
|
8
7
|
/**
|
|
@@ -92,6 +91,9 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
92
91
|
autoBackpressureLevel?: number;
|
|
93
92
|
enableMiddlewareTracking?: boolean;
|
|
94
93
|
middlewareTrackingMaxCapacity?: number;
|
|
94
|
+
enableHTTPBridge?: boolean;
|
|
95
|
+
websocketErrorHandler?: (err: any, ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
96
|
+
idGenerator?: () => string;
|
|
95
97
|
middlewareTrackingTTL?: number;
|
|
96
98
|
httpLogger?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void;
|
|
97
99
|
logger?: {
|
|
@@ -106,7 +108,7 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
106
108
|
requestTimeout?: number;
|
|
107
109
|
writeTimeout?: number;
|
|
108
110
|
renderer?: JSXRenderer;
|
|
109
|
-
serverFactory?: import('
|
|
111
|
+
serverFactory?: import('.').ServerFactory;
|
|
110
112
|
hooks?: {
|
|
111
113
|
onError?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>, error: unknown) => void | Promise<void>;
|
|
112
114
|
onRequestStart?: (ctx: ShokupanContext<Record<string, any>, Record<string, string>>) => void | Promise<void>;
|
|
@@ -137,6 +139,7 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
137
139
|
private trie;
|
|
138
140
|
metadata?: RouteMetadata;
|
|
139
141
|
private currentGuards;
|
|
142
|
+
private eventHandlers;
|
|
140
143
|
getComponentRegistry(): {
|
|
141
144
|
metadata: RouteMetadata;
|
|
142
145
|
middleware: {
|
|
@@ -175,6 +178,14 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
175
178
|
};
|
|
176
179
|
constructor(config?: ShokupanRouteConfig);
|
|
177
180
|
private isRouterInstance;
|
|
181
|
+
/**
|
|
182
|
+
* Registers an event handler for WebSocket.
|
|
183
|
+
*/
|
|
184
|
+
event(name: string, handler: ShokupanHandler<T>): this;
|
|
185
|
+
/**
|
|
186
|
+
* Finds an event handler(s) by name.
|
|
187
|
+
*/
|
|
188
|
+
findEvent(name: string): ShokupanHandler<T>[] | null;
|
|
178
189
|
/**
|
|
179
190
|
* Mounts a controller instance to a path prefix.
|
|
180
191
|
*
|
|
@@ -212,6 +223,8 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
212
223
|
*/
|
|
213
224
|
testRequest(options: RequestOptions): Promise<ProcessResult>;
|
|
214
225
|
private wrapWithHooks;
|
|
226
|
+
private mountRouter;
|
|
227
|
+
private scanControllerRoutes;
|
|
215
228
|
/**
|
|
216
229
|
* Find a route matching the given method and path.
|
|
217
230
|
* @param method HTTP method
|
|
@@ -388,4 +401,3 @@ export declare class ShokupanRouter<T extends Record<string, any> = Record<strin
|
|
|
388
401
|
private ensureHooksInitialized;
|
|
389
402
|
runHooks(name: keyof ShokupanHooks, ...args: any[]): Promise<void>;
|
|
390
403
|
}
|
|
391
|
-
export {};
|
package/dist/shokupan.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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
6
|
/**
|
|
7
7
|
* Shokupan Application
|
|
8
8
|
*
|
|
@@ -72,6 +72,7 @@ export declare class Shokupan<T = any> extends ShokupanRouter<T> {
|
|
|
72
72
|
openApiSpec?: any;
|
|
73
73
|
private composedMiddleware?;
|
|
74
74
|
private cpuMonitor?;
|
|
75
|
+
private server?;
|
|
75
76
|
get logger(): {
|
|
76
77
|
verbose?: boolean;
|
|
77
78
|
info?: (msg: string, props: Record<string, any>) => void;
|
|
@@ -85,6 +86,12 @@ export declare class Shokupan<T = any> extends ShokupanRouter<T> {
|
|
|
85
86
|
* Adds middleware to the application.
|
|
86
87
|
*/
|
|
87
88
|
use(middleware: Middleware): this;
|
|
89
|
+
/**
|
|
90
|
+
* Registers a plugin.
|
|
91
|
+
*/
|
|
92
|
+
register(plugin: ShokupanPlugin, options?: {
|
|
93
|
+
path?: string;
|
|
94
|
+
}): this;
|
|
88
95
|
private startupHooks;
|
|
89
96
|
/**
|
|
90
97
|
* Registers a callback to be executed before the server starts listening.
|
|
@@ -102,7 +109,26 @@ export declare class Shokupan<T = any> extends ShokupanRouter<T> {
|
|
|
102
109
|
* @param port - The port to listen on. If not specified, the port from the configuration is used. If that is not specified, port 3000 is used.
|
|
103
110
|
* @returns The server instance.
|
|
104
111
|
*/
|
|
105
|
-
listen(port?: number): Promise<Server
|
|
112
|
+
listen(port?: number): Promise<Server>;
|
|
113
|
+
/**
|
|
114
|
+
* Stops the application server.
|
|
115
|
+
*
|
|
116
|
+
* This method gracefully shuts down the server and stops any running monitors.
|
|
117
|
+
* Works transparently in both Bun and Node.js runtimes.
|
|
118
|
+
*
|
|
119
|
+
* @returns A promise that resolves when the server has been stopped.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const app = new Shokupan();
|
|
124
|
+
* const server = await app.listen(3000);
|
|
125
|
+
*
|
|
126
|
+
* // Later, when you want to stop the server
|
|
127
|
+
* await app.stop();
|
|
128
|
+
* ```
|
|
129
|
+
* @param closeActiveConnections — Immediately terminate in-flight requests, websockets, and stop accepting new connections.
|
|
130
|
+
*/
|
|
131
|
+
stop(closeActiveConnections?: boolean): Promise<void>;
|
|
106
132
|
[$dispatch](req: ShokupanRequest<T>): Promise<Response>;
|
|
107
133
|
/**
|
|
108
134
|
* Processes a request by wrapping the standard fetch method.
|
|
@@ -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;
|
package/dist/util/datastore.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { RecordId, Range, Table } from 'surrealdb';
|
|
1
2
|
export declare const datastore: {
|
|
2
|
-
get<T extends Record<string, any>>(
|
|
3
|
-
set(
|
|
4
|
-
query(query: string, vars?: Record<string, unknown>): Promise<
|
|
3
|
+
get<T extends Record<string, any>>(recordId: RecordId | Table | Range<any, any>): Promise<T>;
|
|
4
|
+
set(recordId: RecordId, value: Record<string, any>): Promise<any>;
|
|
5
|
+
query<T extends Record<string, any>>(query: string, vars?: Record<string, unknown>): Promise<T>;
|
|
5
6
|
readonly ready: Promise<any>;
|
|
6
7
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RateLimitOptions } from '
|
|
1
|
+
import { RateLimitOptions } from '../plugins/middleware/rate-limit';
|
|
2
2
|
import { GuardAPISpec, MethodAPISpec, Middleware } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Class Decorator: Defines the base path for a controller.
|
|
@@ -68,6 +68,11 @@ export declare const Head: (path?: string) => (target: any, propertyKey: string,
|
|
|
68
68
|
* Decorator: Binds a method to ANY HTTP verb.
|
|
69
69
|
*/
|
|
70
70
|
export declare const All: (path?: string) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
71
|
+
/**
|
|
72
|
+
* Decorator: Binds a method to the WebSocket event.
|
|
73
|
+
* @param eventName The name of the event to listen for.
|
|
74
|
+
*/
|
|
75
|
+
export declare function Event(eventName: string): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
71
76
|
/**
|
|
72
77
|
* Decorator: Applies a rate limit to a class or method.
|
|
73
78
|
*/
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard HTTP Error class with status code.
|
|
3
|
+
* This standardizes on the `status` property instead of dual `status`/`statusCode`.
|
|
4
|
+
*/
|
|
5
|
+
export declare class HttpError extends Error {
|
|
6
|
+
readonly status: number;
|
|
7
|
+
constructor(message: string, status: number);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Extracts HTTP status code from an error object.
|
|
11
|
+
* Supports both `status` and `statusCode` properties for backward compatibility.
|
|
12
|
+
* Defaults to 500 (Internal Server Error) if no status is found.
|
|
13
|
+
*
|
|
14
|
+
* @param err - Error object (may have `status` or `statusCode` property)
|
|
15
|
+
* @returns HTTP status code
|
|
16
|
+
*/
|
|
17
|
+
export declare function getErrorStatus(err: any): number;
|
|
18
|
+
/**
|
|
19
|
+
* Common HTTP Errors
|
|
20
|
+
*/
|
|
21
|
+
export declare class BadRequestError extends HttpError {
|
|
22
|
+
constructor(message?: string);
|
|
23
|
+
}
|
|
24
|
+
export declare class UnauthorizedError extends HttpError {
|
|
25
|
+
constructor(message?: string);
|
|
26
|
+
}
|
|
27
|
+
export declare class ForbiddenError extends HttpError {
|
|
28
|
+
constructor(message?: string);
|
|
29
|
+
}
|
|
30
|
+
export declare class NotFoundError extends HttpError {
|
|
31
|
+
constructor(message?: string);
|
|
32
|
+
}
|
|
33
|
+
export declare class InternalServerError extends HttpError {
|
|
34
|
+
constructor(message?: string);
|
|
35
|
+
}
|
|
36
|
+
export declare class EventError extends HttpError {
|
|
37
|
+
constructor(message?: string);
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common HTTP Status Codes
|
|
3
|
+
* Use these constants instead of magic numbers for better readability
|
|
4
|
+
*/
|
|
5
|
+
export declare const HTTP_STATUS: {
|
|
6
|
+
readonly OK: 200;
|
|
7
|
+
readonly CREATED: 201;
|
|
8
|
+
readonly ACCEPTED: 202;
|
|
9
|
+
readonly NO_CONTENT: 204;
|
|
10
|
+
readonly MOVED_PERMANENTLY: 301;
|
|
11
|
+
readonly FOUND: 302;
|
|
12
|
+
readonly SEE_OTHER: 303;
|
|
13
|
+
readonly NOT_MODIFIED: 304;
|
|
14
|
+
readonly TEMPORARY_REDIRECT: 307;
|
|
15
|
+
readonly PERMANENT_REDIRECT: 308;
|
|
16
|
+
readonly BAD_REQUEST: 400;
|
|
17
|
+
readonly UNAUTHORIZED: 401;
|
|
18
|
+
readonly FORBIDDEN: 403;
|
|
19
|
+
readonly NOT_FOUND: 404;
|
|
20
|
+
readonly METHOD_NOT_ALLOWED: 405;
|
|
21
|
+
readonly REQUEST_TIMEOUT: 408;
|
|
22
|
+
readonly CONFLICT: 409;
|
|
23
|
+
readonly UNPROCESSABLE_ENTITY: 422;
|
|
24
|
+
readonly TOO_MANY_REQUESTS: 429;
|
|
25
|
+
readonly INTERNAL_SERVER_ERROR: 500;
|
|
26
|
+
readonly NOT_IMPLEMENTED: 501;
|
|
27
|
+
readonly BAD_GATEWAY: 502;
|
|
28
|
+
readonly SERVICE_UNAVAILABLE: 503;
|
|
29
|
+
readonly GATEWAY_TIMEOUT: 504;
|
|
30
|
+
};
|
|
31
|
+
export declare const VALID_HTTP_STATUSES: Set<number>;
|
|
32
|
+
export declare const VALID_REDIRECT_STATUSES: Set<number>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const $isApplication: unique symbol;
|
|
2
|
+
export declare const $appRoot: unique symbol;
|
|
3
|
+
export declare const $isMounted: unique symbol;
|
|
4
|
+
export declare const $routeMethods: unique symbol;
|
|
5
|
+
export declare const $eventMethods: unique symbol;
|
|
6
|
+
export declare const $routeArgs: unique symbol;
|
|
7
|
+
export declare const $controllerPath: unique symbol;
|
|
8
|
+
export declare const $middleware: unique symbol;
|
|
9
|
+
export declare const $isRouter: unique symbol;
|
|
10
|
+
export declare const $parent: unique symbol;
|
|
11
|
+
export declare const $childRouters: unique symbol;
|
|
12
|
+
export declare const $childControllers: unique symbol;
|
|
13
|
+
export declare const $mountPath: unique symbol;
|
|
14
|
+
export declare const $dispatch: unique symbol;
|
|
15
|
+
export declare const $routes: unique symbol;
|
|
16
|
+
export declare const $routeSpec: unique symbol;
|
|
17
|
+
export declare const $url: unique symbol;
|
|
18
|
+
export declare const $requestId: unique symbol;
|
|
19
|
+
export declare const $debug: unique symbol;
|
|
20
|
+
export declare const $finalResponse: unique symbol;
|
|
21
|
+
export declare const $rawBody: unique symbol;
|
|
22
|
+
export declare const $cachedBody: unique symbol;
|
|
23
|
+
export declare const $bodyType: unique symbol;
|
|
24
|
+
export declare const $bodyParsed: unique symbol;
|
|
25
|
+
export declare const $bodyParseError: unique symbol;
|
|
26
|
+
export declare const $routeMatched: unique symbol;
|
|
27
|
+
export declare const $cachedHostname: unique symbol;
|
|
28
|
+
export declare const $cachedProtocol: unique symbol;
|
|
29
|
+
export declare const $cachedHost: unique symbol;
|
|
30
|
+
export declare const $cachedOrigin: unique symbol;
|
|
31
|
+
export declare const $cachedQuery: unique symbol;
|
|
32
|
+
export declare const $ws: unique symbol;
|
|
33
|
+
export declare const $socket: unique symbol;
|
|
34
|
+
export declare const $io: unique symbol;
|
|
@@ -1,8 +1,15 @@
|
|
|
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;
|
|
@@ -76,7 +83,9 @@ export interface CookieOptions {
|
|
|
76
83
|
sameSite?: boolean | 'lax' | 'strict' | 'none' | 'Lax' | 'Strict' | 'None';
|
|
77
84
|
priority?: 'low' | 'medium' | 'high' | 'Low' | 'Medium' | 'High';
|
|
78
85
|
}
|
|
79
|
-
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
|
|
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) & {
|
|
87
|
+
originalHandler?: ShokupanHandler<State, Params>;
|
|
88
|
+
};
|
|
80
89
|
export declare const HTTPMethods: string[];
|
|
81
90
|
export type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD" | "ALL";
|
|
82
91
|
export declare enum RouteParamType {
|
|
@@ -282,6 +291,33 @@ export type ShokupanConfig<T extends Record<string, any> = Record<string, any>>
|
|
|
282
291
|
* @default 10000
|
|
283
292
|
*/
|
|
284
293
|
middlewareTrackingMaxCapacity?: number;
|
|
294
|
+
/**
|
|
295
|
+
* Whether to enable the HTTP bridge for WebSocket.
|
|
296
|
+
* This enables websocket messages to run through the HTTP server.
|
|
297
|
+
* e.g.
|
|
298
|
+
* ```json
|
|
299
|
+
* {
|
|
300
|
+
* "method": "POST",
|
|
301
|
+
* "path": "/api/v1/myHttpEndpoint",
|
|
302
|
+
* "headers": {},
|
|
303
|
+
* "body": {
|
|
304
|
+
* "type": "text",
|
|
305
|
+
* "data": "Hello, world!"
|
|
306
|
+
* }
|
|
307
|
+
* }
|
|
308
|
+
* ```
|
|
309
|
+
* @default false
|
|
310
|
+
*/
|
|
311
|
+
enableHTTPBridge?: boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Handler for WebSocket events that throw an exception.
|
|
314
|
+
*/
|
|
315
|
+
websocketErrorHandler?: (err: any, ctx: ShokupanContext<T>) => void | Promise<void>;
|
|
316
|
+
/**
|
|
317
|
+
* Unique ID generator function for requests.
|
|
318
|
+
* @default nanoid
|
|
319
|
+
*/
|
|
320
|
+
idGenerator?: () => string;
|
|
285
321
|
/**
|
|
286
322
|
* Time-to-live for middleware tracking entries in milliseconds.
|
|
287
323
|
* Entries older than this will be cleaned up.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shokupan",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.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": {
|
|
@@ -65,9 +65,13 @@
|
|
|
65
65
|
"@opentelemetry/sdk-trace-node": "^2.2.0",
|
|
66
66
|
"@opentelemetry/semantic-conventions": "^1.38.0",
|
|
67
67
|
"@scalar/openapi-types": "^0.5.3",
|
|
68
|
+
"nanoid": "^5.1.6",
|
|
69
|
+
"socket.io": "^4.8.3",
|
|
68
70
|
"tslib": "^2.8.1"
|
|
69
71
|
},
|
|
70
72
|
"peerDependencies": {
|
|
73
|
+
"@scalar/api-reference": "^1.0.0",
|
|
74
|
+
"@surrealdb/node": "^2.4.0",
|
|
71
75
|
"ajv": "^8.0.0",
|
|
72
76
|
"ajv-formats": "^3.0.0",
|
|
73
77
|
"arctic": "^3",
|
|
@@ -78,8 +82,6 @@
|
|
|
78
82
|
"parse-json": "^8.0.0",
|
|
79
83
|
"reflect-metadata": "^0.2.0",
|
|
80
84
|
"secure-json-parse": "^4.0.0",
|
|
81
|
-
"@scalar/api-reference": "^1.0.0",
|
|
82
|
-
"@surrealdb/node": "^2.4.0",
|
|
83
85
|
"surrealdb": "^2.0.0-alpha.14"
|
|
84
86
|
},
|
|
85
87
|
"peerDependenciesMeta": {
|
|
@@ -150,6 +152,7 @@
|
|
|
150
152
|
"valibot": "^1.2.0",
|
|
151
153
|
"vite": "^7.3.0",
|
|
152
154
|
"vite-plugin-dts": "^4.5.4",
|
|
155
|
+
"vite-plugin-static-copy": "^3.1.4",
|
|
153
156
|
"zod": "^4.2.1"
|
|
154
157
|
}
|
|
155
158
|
}
|