clear-router 2.5.4 → 2.5.5
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 -0
- package/dist/bindings-BL1d0dFY.d.cts +20 -0
- package/dist/bindings-DIanvIVd.mjs +211 -0
- package/dist/bindings-DqvZ9-YW.d.mts +20 -0
- package/dist/bindings-DvV2DXWi.cjs +253 -0
- package/dist/core/index.cjs +5 -2
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +3 -2
- package/dist/decorators/index.cjs +5 -0
- package/dist/decorators/index.d.cts +2 -0
- package/dist/decorators/index.d.mts +2 -0
- package/dist/decorators/index.mjs +3 -0
- package/dist/decorators/setup.cjs +15 -0
- package/dist/decorators/setup.d.cts +2 -0
- package/dist/decorators/setup.d.mts +2 -0
- package/dist/decorators/setup.mjs +13 -0
- package/dist/express/index.cjs +26 -9
- package/dist/express/index.d.cts +1 -1
- package/dist/express/index.d.mts +1 -1
- package/dist/express/index.mjs +26 -9
- package/dist/fastify/index.cjs +24 -8
- package/dist/fastify/index.d.cts +4 -2
- package/dist/fastify/index.d.mts +4 -2
- package/dist/fastify/index.mjs +24 -8
- package/dist/h3/index.cjs +26 -9
- package/dist/h3/index.d.cts +1 -1
- package/dist/h3/index.d.mts +1 -1
- package/dist/h3/index.mjs +26 -9
- package/dist/hono/index.cjs +28 -11
- package/dist/hono/index.d.cts +4 -2
- package/dist/hono/index.d.mts +4 -2
- package/dist/hono/index.mjs +28 -11
- package/dist/index.cjs +271 -27
- package/dist/index.d.cts +70 -18
- package/dist/index.d.mts +70 -18
- package/dist/index.mjs +270 -28
- package/dist/koa/index.cjs +24 -8
- package/dist/koa/index.d.cts +4 -2
- package/dist/koa/index.d.mts +4 -2
- package/dist/koa/index.mjs +24 -8
- package/dist/{responses-B-UirWFf.cjs → responses-JzXstGU5.cjs} +18 -1
- package/dist/{responses-CJaD0ugv.mjs → responses-_II3dOJ5.mjs} +19 -1
- package/dist/{router-CS_2XQ7I.d.cts → router-78fDk87B.d.cts} +68 -12
- package/dist/{router-BReOXz-F.mjs → router-BAWdklDQ.mjs} +130 -48
- package/dist/{router-_w2VzMQF.d.mts → router-BdfAh1me.d.mts} +67 -11
- package/dist/{router-CHg0pZUO.cjs → router-CCUF5FE7.cjs} +130 -48
- package/dist/types/basic.d.mts +7 -0
- package/dist/types/core/Request.d.mts +25 -0
- package/dist/types/core/Response.d.mts +21 -0
- package/dist/types/express.d.mts +5 -2
- package/dist/types/fastify.d.mts +5 -2
- package/dist/types/h3.d.mts +5 -2
- package/dist/types/hono.d.mts +5 -2
- package/dist/types/koa.d.mts +5 -2
- package/package.json +16 -2
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
const require_bindings = require('./bindings-DvV2DXWi.cjs');
|
|
1
2
|
|
|
2
3
|
//#region src/core/responses.ts
|
|
3
4
|
function isFetchResponse(value) {
|
|
4
|
-
return typeof Response !== "undefined" && value instanceof Response;
|
|
5
|
+
return typeof globalThis.Response !== "undefined" && value instanceof globalThis.Response;
|
|
6
|
+
}
|
|
7
|
+
function isCoreResponse(value) {
|
|
8
|
+
return value instanceof require_bindings.Response;
|
|
5
9
|
}
|
|
6
10
|
function isH3Response(value) {
|
|
7
11
|
return Boolean(value && typeof value === "object" && value.constructor?.name === "HTTPResponse");
|
|
8
12
|
}
|
|
9
13
|
function responseWasSent(target) {
|
|
14
|
+
if (isCoreResponse(target)) return false;
|
|
10
15
|
return Boolean(target?.headersSent || target?.sent || target?.raw?.headersSent);
|
|
11
16
|
}
|
|
12
17
|
function getHeader(headers, name) {
|
|
@@ -23,6 +28,17 @@ function isApiRequest(headers, path) {
|
|
|
23
28
|
}
|
|
24
29
|
function resolveResponseMeta(value, options = {}) {
|
|
25
30
|
if (typeof value === "undefined") return void 0;
|
|
31
|
+
if (isCoreResponse(value)) {
|
|
32
|
+
const contentType = value.headers.get("content-type") || void 0;
|
|
33
|
+
return {
|
|
34
|
+
body: value.body,
|
|
35
|
+
status: value.statusCode,
|
|
36
|
+
contentType,
|
|
37
|
+
headers: value.headers,
|
|
38
|
+
isEmpty: value.body === null || typeof value.body === "undefined",
|
|
39
|
+
isNativeResponse: false
|
|
40
|
+
};
|
|
41
|
+
}
|
|
26
42
|
if (isFetchResponse(value) || isH3Response(value)) return {
|
|
27
43
|
body: value,
|
|
28
44
|
status: getStatus(value, options.method, options.status),
|
|
@@ -59,6 +75,7 @@ function resolveResponseMeta(value, options = {}) {
|
|
|
59
75
|
};
|
|
60
76
|
}
|
|
61
77
|
function getStatus(value, method, explicitStatus) {
|
|
78
|
+
if (typeof value?.statusCode === "number" && value.statusCode >= 100 && value.statusCode <= 999) return value.statusCode;
|
|
62
79
|
if (typeof value?.status === "number" && value.status >= 100 && value.status <= 999) return value.status;
|
|
63
80
|
if (typeof explicitStatus === "number" && explicitStatus >= 100 && explicitStatus <= 999) return explicitStatus;
|
|
64
81
|
return String(method || "").toLowerCase() === "post" ? 201 : 200;
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
import { o as Response } from "./bindings-DIanvIVd.mjs";
|
|
2
|
+
|
|
1
3
|
//#region src/core/responses.ts
|
|
2
4
|
function isFetchResponse(value) {
|
|
3
|
-
return typeof Response !== "undefined" && value instanceof Response;
|
|
5
|
+
return typeof globalThis.Response !== "undefined" && value instanceof globalThis.Response;
|
|
6
|
+
}
|
|
7
|
+
function isCoreResponse(value) {
|
|
8
|
+
return value instanceof Response;
|
|
4
9
|
}
|
|
5
10
|
function isH3Response(value) {
|
|
6
11
|
return Boolean(value && typeof value === "object" && value.constructor?.name === "HTTPResponse");
|
|
7
12
|
}
|
|
8
13
|
function responseWasSent(target) {
|
|
14
|
+
if (isCoreResponse(target)) return false;
|
|
9
15
|
return Boolean(target?.headersSent || target?.sent || target?.raw?.headersSent);
|
|
10
16
|
}
|
|
11
17
|
function getHeader(headers, name) {
|
|
@@ -22,6 +28,17 @@ function isApiRequest(headers, path) {
|
|
|
22
28
|
}
|
|
23
29
|
function resolveResponseMeta(value, options = {}) {
|
|
24
30
|
if (typeof value === "undefined") return void 0;
|
|
31
|
+
if (isCoreResponse(value)) {
|
|
32
|
+
const contentType = value.headers.get("content-type") || void 0;
|
|
33
|
+
return {
|
|
34
|
+
body: value.body,
|
|
35
|
+
status: value.statusCode,
|
|
36
|
+
contentType,
|
|
37
|
+
headers: value.headers,
|
|
38
|
+
isEmpty: value.body === null || typeof value.body === "undefined",
|
|
39
|
+
isNativeResponse: false
|
|
40
|
+
};
|
|
41
|
+
}
|
|
25
42
|
if (isFetchResponse(value) || isH3Response(value)) return {
|
|
26
43
|
body: value,
|
|
27
44
|
status: getStatus(value, options.method, options.status),
|
|
@@ -58,6 +75,7 @@ function resolveResponseMeta(value, options = {}) {
|
|
|
58
75
|
};
|
|
59
76
|
}
|
|
60
77
|
function getStatus(value, method, explicitStatus) {
|
|
78
|
+
if (typeof value?.statusCode === "number" && value.statusCode >= 100 && value.statusCode <= 999) return value.statusCode;
|
|
61
79
|
if (typeof value?.status === "number" && value.status >= 100 && value.status <= 999) return value.status;
|
|
62
80
|
if (typeof explicitStatus === "number" && explicitStatus >= 100 && explicitStatus <= 999) return explicitStatus;
|
|
63
81
|
return String(method || "").toLowerCase() === "post" ? 201 : 200;
|
|
@@ -1,7 +1,27 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
1
|
import { NextFunction, Request, Response as Response$1 } from "express";
|
|
3
2
|
import { EventHandlerRequest, H3, H3Event, Middleware, TypedServerRequest } from "h3";
|
|
3
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
|
|
5
|
+
//#region src/core/Response.d.ts
|
|
6
|
+
declare class Response$2 {
|
|
7
|
+
body: any;
|
|
8
|
+
headers: Headers;
|
|
9
|
+
sent: boolean;
|
|
10
|
+
statusCode: number;
|
|
11
|
+
constructor(init?: Partial<Response$2>);
|
|
12
|
+
status(code: number): this;
|
|
13
|
+
code(code: number): this;
|
|
14
|
+
setHeader(name: string, value: string): this;
|
|
15
|
+
header(name: string, value: string): this;
|
|
16
|
+
set(name: string, value: string): this;
|
|
17
|
+
type(contentType: string): this;
|
|
18
|
+
send(body?: any): this;
|
|
19
|
+
json(body: any): this;
|
|
20
|
+
html(body: string): this;
|
|
21
|
+
text(body: string): this;
|
|
22
|
+
noContent(): this;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
5
25
|
//#region types/basic.d.ts
|
|
6
26
|
/**
|
|
7
27
|
* Controller method reference
|
|
@@ -30,6 +50,13 @@ interface RouterConfig {
|
|
|
30
50
|
bodyKeys?: string[] | string; /** Keys in the request headers to check for method override */
|
|
31
51
|
headerKeys?: string[] | string;
|
|
32
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* Optional method binding / container resolution support. Disabled by default.
|
|
55
|
+
*/
|
|
56
|
+
container?: {
|
|
57
|
+
/** Whether decorated handler parameter binding is enabled */enabled?: boolean; /** Whether unknown constructor tokens should be instantiated automatically */
|
|
58
|
+
autoDiscover?: boolean;
|
|
59
|
+
};
|
|
33
60
|
}
|
|
34
61
|
//#endregion
|
|
35
62
|
//#region types/express.d.ts
|
|
@@ -43,6 +70,8 @@ interface HttpContext$1 {
|
|
|
43
70
|
req: RequestWithGetBody;
|
|
44
71
|
res: Response$1;
|
|
45
72
|
next: NextFunction;
|
|
73
|
+
clearRequest: Request$1;
|
|
74
|
+
clearResponse: Response$2;
|
|
46
75
|
}
|
|
47
76
|
/**
|
|
48
77
|
* Route handler function type
|
|
@@ -57,7 +86,7 @@ ctx: HttpContext$1,
|
|
|
57
86
|
* ClearRequest instance
|
|
58
87
|
*/
|
|
59
88
|
|
|
60
|
-
req:
|
|
89
|
+
req: Request$1) => any | Promise<any>;
|
|
61
90
|
/**
|
|
62
91
|
* Handler can be either a function or controller reference
|
|
63
92
|
*/
|
|
@@ -80,6 +109,8 @@ type RequestlessH3Event = Omit<H3Event, 'req'>;
|
|
|
80
109
|
*/
|
|
81
110
|
interface HttpContext extends RequestlessH3Event {
|
|
82
111
|
req: HttpRequest;
|
|
112
|
+
clearRequest: Request$1;
|
|
113
|
+
clearResponse: Response$2;
|
|
83
114
|
}
|
|
84
115
|
/**
|
|
85
116
|
* Route handler function type
|
|
@@ -94,7 +125,7 @@ ctx: HttpContext,
|
|
|
94
125
|
* ClearRequest instance
|
|
95
126
|
*/
|
|
96
127
|
|
|
97
|
-
req:
|
|
128
|
+
req: Request$1) => any | Promise<any>;
|
|
98
129
|
/**
|
|
99
130
|
* Handler can be either a function or controller reference
|
|
100
131
|
*/
|
|
@@ -137,6 +168,26 @@ declare class ClearRequest<X = any, M = Middleware | Middleware$1> {
|
|
|
137
168
|
constructor(init?: Partial<ClearRequest>);
|
|
138
169
|
}
|
|
139
170
|
//#endregion
|
|
171
|
+
//#region src/core/Request.d.ts
|
|
172
|
+
declare class Request$1<X = any, M = any> extends ClearRequest<X, M> {
|
|
173
|
+
original?: any;
|
|
174
|
+
method: string;
|
|
175
|
+
path: string;
|
|
176
|
+
url: string;
|
|
177
|
+
headers: Headers | Record<string, any>;
|
|
178
|
+
constructor(init?: Partial<Request$1<X, M>> & {
|
|
179
|
+
body?: RequestData;
|
|
180
|
+
query?: RequestData;
|
|
181
|
+
params?: RequestData;
|
|
182
|
+
route?: Route<X, M>;
|
|
183
|
+
});
|
|
184
|
+
getBody(): RequestData;
|
|
185
|
+
header(name: string): string;
|
|
186
|
+
param(name: string): any;
|
|
187
|
+
input(name: string): any;
|
|
188
|
+
is(method: HttpMethod | string): boolean;
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
140
191
|
//#region src/Controller.d.ts
|
|
141
192
|
declare abstract class Controller<X = any> {
|
|
142
193
|
[x: string]: any;
|
|
@@ -158,16 +209,14 @@ declare abstract class CoreRouter {
|
|
|
158
209
|
protected static routerStateNamespace: string;
|
|
159
210
|
private static readonly stateStoreKey;
|
|
160
211
|
private static readonly stateBoundKey;
|
|
212
|
+
private static readonly defaultConfigKey;
|
|
213
|
+
protected static createBaseConfig(): RouterConfig;
|
|
214
|
+
protected static mergeConfig(target: RouterConfig, source?: RouterConfig): RouterConfig;
|
|
215
|
+
protected static getDefaultConfig(): RouterConfig;
|
|
161
216
|
protected static resolveStateNamespace(this: any): string;
|
|
162
217
|
protected static getStateStore(): Record<string, any>;
|
|
163
218
|
protected static createDefaultState(): {
|
|
164
|
-
config:
|
|
165
|
-
methodOverride: {
|
|
166
|
-
enabled: boolean;
|
|
167
|
-
bodyKeys: string[];
|
|
168
|
-
headerKeys: string[];
|
|
169
|
-
};
|
|
170
|
-
};
|
|
219
|
+
config: RouterConfig;
|
|
171
220
|
groupContext: AsyncLocalStorage<{
|
|
172
221
|
prefix: string;
|
|
173
222
|
groupMiddlewares: any[];
|
|
@@ -182,6 +231,7 @@ declare abstract class CoreRouter {
|
|
|
182
231
|
protected static bindStateAccessors(this: any): void;
|
|
183
232
|
protected static createDefaultOptionsHandler(): any;
|
|
184
233
|
static config: RouterConfig;
|
|
234
|
+
static configureDefaults(this: any, options?: RouterConfig): void;
|
|
185
235
|
protected static groupContext: AsyncLocalStorage<{
|
|
186
236
|
prefix: string;
|
|
187
237
|
groupMiddlewares: any[];
|
|
@@ -331,14 +381,20 @@ declare abstract class CoreRouter {
|
|
|
331
381
|
*/
|
|
332
382
|
static allRoutes(this: any, type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
|
|
333
383
|
protected static resolveHandler(route: Route<any, any, any>): {
|
|
334
|
-
handlerFunction: ((ctx: any, req:
|
|
384
|
+
handlerFunction: ((ctx: any, req: Request$1) => any | Promise<any>) | null;
|
|
335
385
|
instance: Controller<any> | null;
|
|
386
|
+
bindingTarget?: object;
|
|
387
|
+
bindingMethod?: PropertyKey;
|
|
388
|
+
bindingHandler?: object;
|
|
389
|
+
bindingMetadata?: object;
|
|
336
390
|
};
|
|
391
|
+
protected static callHandler(this: any, handlerFunction: (ctx: any, req: Request$1) => any | Promise<any>, ctx: any, bindingTarget?: object, bindingMethod?: PropertyKey, bindingHandler?: object, bindingMetadata?: object): Promise<any>;
|
|
337
392
|
protected static bindRequestToInstance(ctx: any, instance: Controller<any> | Route<any, any, any> | null, route: Route<any, any, any>, payload: {
|
|
338
393
|
body: Record<string, any>;
|
|
339
394
|
query: Record<string, any>;
|
|
340
395
|
params: Record<string, any>;
|
|
396
|
+
method?: HttpMethod | string;
|
|
341
397
|
}): void;
|
|
342
398
|
}
|
|
343
399
|
//#endregion
|
|
344
|
-
export { Handler as a, Handler$1 as c, ApiResourceMiddleware as d, ControllerAction as f, H3App as i, HttpContext$1 as l, HttpMethod as m,
|
|
400
|
+
export { Handler as a, Handler$1 as c, ApiResourceMiddleware as d, ControllerAction as f, Response$2 as h, H3App as i, HttpContext$1 as l, HttpMethod as m, Request$1 as n, HttpContext as o, ControllerHandler as p, Route as r, Middleware as s, CoreRouter as t, Middleware$1 as u };
|
|
@@ -1,26 +1,6 @@
|
|
|
1
|
+
import { a as getStandardMetadata, i as getDesignParamTypes, n as Container, o as Response, r as getBindingMetadataFromTargets, s as Request } from "./bindings-DIanvIVd.mjs";
|
|
1
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
3
|
|
|
3
|
-
//#region src/ClearRequest.ts
|
|
4
|
-
var ClearRequest = class {
|
|
5
|
-
/**
|
|
6
|
-
* @param body - Parsed request body
|
|
7
|
-
*/
|
|
8
|
-
body;
|
|
9
|
-
/**
|
|
10
|
-
* @param query - Parsed query parameters
|
|
11
|
-
*/
|
|
12
|
-
query;
|
|
13
|
-
/**
|
|
14
|
-
* @param params - Parsed route parameters
|
|
15
|
-
*/
|
|
16
|
-
params;
|
|
17
|
-
route;
|
|
18
|
-
constructor(init) {
|
|
19
|
-
Object.assign(this, init);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
4
|
//#region src/Route.ts
|
|
25
5
|
var Route = class {
|
|
26
6
|
ctx;
|
|
@@ -60,6 +40,40 @@ var CoreRouter = class {
|
|
|
60
40
|
static routerStateNamespace = "clear-router:core";
|
|
61
41
|
static stateStoreKey = Symbol.for("clear-router:router-state");
|
|
62
42
|
static stateBoundKey = Symbol.for("clear-router:router-state-bound");
|
|
43
|
+
static defaultConfigKey = Symbol.for("clear-router:default-config");
|
|
44
|
+
static createBaseConfig() {
|
|
45
|
+
return {
|
|
46
|
+
methodOverride: {
|
|
47
|
+
enabled: true,
|
|
48
|
+
bodyKeys: ["_method"],
|
|
49
|
+
headerKeys: ["x-http-method"]
|
|
50
|
+
},
|
|
51
|
+
container: {
|
|
52
|
+
enabled: false,
|
|
53
|
+
autoDiscover: false
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
static mergeConfig(target, source) {
|
|
58
|
+
if (!source) return target;
|
|
59
|
+
if (source.methodOverride) target.methodOverride = {
|
|
60
|
+
...target.methodOverride || {},
|
|
61
|
+
...source.methodOverride
|
|
62
|
+
};
|
|
63
|
+
if (source.container) target.container = {
|
|
64
|
+
...target.container || {},
|
|
65
|
+
...source.container
|
|
66
|
+
};
|
|
67
|
+
return target;
|
|
68
|
+
}
|
|
69
|
+
static getDefaultConfig() {
|
|
70
|
+
const g = globalThis;
|
|
71
|
+
if (!g[this.defaultConfigKey]) g[this.defaultConfigKey] = this.createBaseConfig();
|
|
72
|
+
return {
|
|
73
|
+
methodOverride: { ...g[this.defaultConfigKey].methodOverride },
|
|
74
|
+
container: { ...g[this.defaultConfigKey].container }
|
|
75
|
+
};
|
|
76
|
+
}
|
|
63
77
|
static resolveStateNamespace() {
|
|
64
78
|
return String(this.routerStateNamespace || this.name || "clear-router:core");
|
|
65
79
|
}
|
|
@@ -70,11 +84,7 @@ var CoreRouter = class {
|
|
|
70
84
|
}
|
|
71
85
|
static createDefaultState() {
|
|
72
86
|
return {
|
|
73
|
-
config:
|
|
74
|
-
enabled: true,
|
|
75
|
-
bodyKeys: ["_method"],
|
|
76
|
-
headerKeys: ["x-http-method"]
|
|
77
|
-
} },
|
|
87
|
+
config: this.getDefaultConfig(),
|
|
78
88
|
groupContext: new AsyncLocalStorage(),
|
|
79
89
|
routes: [],
|
|
80
90
|
routesByPathMethod: {},
|
|
@@ -151,11 +161,24 @@ var CoreRouter = class {
|
|
|
151
161
|
}
|
|
152
162
|
};
|
|
153
163
|
}
|
|
154
|
-
static config = {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
164
|
+
static config = {
|
|
165
|
+
methodOverride: {
|
|
166
|
+
enabled: true,
|
|
167
|
+
bodyKeys: ["_method"],
|
|
168
|
+
headerKeys: ["x-http-method"]
|
|
169
|
+
},
|
|
170
|
+
container: {
|
|
171
|
+
enabled: false,
|
|
172
|
+
autoDiscover: false
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
static configureDefaults(options) {
|
|
176
|
+
const g = globalThis;
|
|
177
|
+
const defaults = this.mergeConfig(g[this.defaultConfigKey] || this.createBaseConfig(), options);
|
|
178
|
+
g[this.defaultConfigKey] = defaults;
|
|
179
|
+
const store = this.getStateStore();
|
|
180
|
+
for (const state of Object.values(store)) state.config = this.mergeConfig(state.config || this.createBaseConfig(), options);
|
|
181
|
+
}
|
|
159
182
|
static groupContext = new AsyncLocalStorage();
|
|
160
183
|
static routes = [];
|
|
161
184
|
static routesByPathMethod = {};
|
|
@@ -197,11 +220,12 @@ var CoreRouter = class {
|
|
|
197
220
|
*/
|
|
198
221
|
static configure(options) {
|
|
199
222
|
this.ensureState();
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
223
|
+
this.config = this.mergeConfig(this.getDefaultConfig(), this.config);
|
|
224
|
+
const container = options?.container;
|
|
225
|
+
if (container) {
|
|
226
|
+
if (typeof container.enabled === "boolean") this.config.container.enabled = container.enabled;
|
|
227
|
+
if (typeof container.autoDiscover === "boolean") this.config.container.autoDiscover = container.autoDiscover;
|
|
228
|
+
}
|
|
205
229
|
const override = options?.methodOverride;
|
|
206
230
|
if (!override) return;
|
|
207
231
|
if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
|
|
@@ -438,36 +462,94 @@ var CoreRouter = class {
|
|
|
438
462
|
static resolveHandler(route) {
|
|
439
463
|
let handlerFunction;
|
|
440
464
|
let instance = null;
|
|
441
|
-
|
|
442
|
-
|
|
465
|
+
let bindingTarget;
|
|
466
|
+
let bindingMethod;
|
|
467
|
+
let bindingHandler;
|
|
468
|
+
let bindingMetadata;
|
|
469
|
+
if (typeof route.handler === "function") {
|
|
470
|
+
handlerFunction = route.handler.bind(route);
|
|
471
|
+
bindingTarget = route.handler;
|
|
472
|
+
bindingHandler = route.handler;
|
|
473
|
+
} else if (Array.isArray(route.handler) && route.handler.length === 2) {
|
|
443
474
|
const [ControllerType, method] = route.handler;
|
|
444
475
|
if (["function", "object"].includes(typeof ControllerType) && typeof ControllerType[method] === "function") {
|
|
445
476
|
instance = ControllerType;
|
|
446
477
|
handlerFunction = ControllerType[method].bind(ControllerType);
|
|
478
|
+
bindingTarget = ControllerType;
|
|
479
|
+
bindingMethod = method;
|
|
480
|
+
bindingHandler = ControllerType[method];
|
|
481
|
+
bindingMetadata = ControllerType[Symbol.metadata];
|
|
447
482
|
} else if (typeof ControllerType === "function") {
|
|
448
483
|
instance = new ControllerType();
|
|
449
|
-
if (typeof instance[method] === "function")
|
|
450
|
-
|
|
484
|
+
if (typeof instance[method] === "function") {
|
|
485
|
+
handlerFunction = instance[method].bind(instance);
|
|
486
|
+
bindingTarget = ControllerType.prototype;
|
|
487
|
+
bindingMethod = method;
|
|
488
|
+
bindingHandler = instance[method];
|
|
489
|
+
bindingMetadata = ControllerType[Symbol.metadata];
|
|
490
|
+
} else throw new Error(`Method "${method}" not found in controller instance "${ControllerType.name}"`);
|
|
451
491
|
} else throw new Error(`Invalid controller type for route: ${route.path}`);
|
|
452
492
|
} else throw new Error(`Invalid handler format for route: ${route.path}`);
|
|
453
493
|
return {
|
|
454
494
|
handlerFunction,
|
|
455
|
-
instance
|
|
495
|
+
instance,
|
|
496
|
+
bindingTarget,
|
|
497
|
+
bindingMethod,
|
|
498
|
+
bindingHandler,
|
|
499
|
+
bindingMetadata
|
|
456
500
|
};
|
|
457
501
|
}
|
|
502
|
+
static async callHandler(handlerFunction, ctx, bindingTarget, bindingMethod, bindingHandler, bindingMetadata) {
|
|
503
|
+
if (!this.config.container?.enabled) return handlerFunction(ctx, ctx.clearRequest);
|
|
504
|
+
const metadata = getBindingMetadataFromTargets([
|
|
505
|
+
{
|
|
506
|
+
target: bindingTarget,
|
|
507
|
+
propertyKey: bindingMethod
|
|
508
|
+
},
|
|
509
|
+
{ target: bindingHandler },
|
|
510
|
+
{
|
|
511
|
+
target: bindingTarget,
|
|
512
|
+
propertyKey: "__class__"
|
|
513
|
+
}
|
|
514
|
+
]) ?? getStandardMetadata(bindingMetadata, bindingMethod) ?? getStandardMetadata(bindingMetadata, "__class__");
|
|
515
|
+
if (!metadata) return handlerFunction(ctx, ctx.clearRequest);
|
|
516
|
+
const designTokens = [...bindingTarget ? getDesignParamTypes(bindingTarget, bindingMethod) : [], ...bindingHandler ? getDesignParamTypes(bindingHandler) : []];
|
|
517
|
+
const tokens = metadata.tokens?.length ? metadata.tokens : designTokens;
|
|
518
|
+
if (!tokens.length) return handlerFunction(ctx, ctx.clearRequest);
|
|
519
|
+
const args = [];
|
|
520
|
+
for (const token of tokens) {
|
|
521
|
+
const resolved = await Container.resolve(token, ctx, Boolean(this.config.container?.autoDiscover));
|
|
522
|
+
if (typeof resolved === "undefined") return handlerFunction(ctx, ctx.clearRequest);
|
|
523
|
+
args.push(resolved);
|
|
524
|
+
}
|
|
525
|
+
return handlerFunction(...args);
|
|
526
|
+
}
|
|
458
527
|
static bindRequestToInstance(ctx, instance, route, payload) {
|
|
528
|
+
const clearRequest = ctx.clearRequest instanceof Request ? ctx.clearRequest : new Request({
|
|
529
|
+
ctx,
|
|
530
|
+
route,
|
|
531
|
+
body: payload.body,
|
|
532
|
+
query: payload.query,
|
|
533
|
+
params: payload.params,
|
|
534
|
+
method: String(payload.method || ctx.req?.method || ctx.method || "GET").toUpperCase(),
|
|
535
|
+
path: String(ctx.path || ctx.req?.path || ctx.req?.url || route.path),
|
|
536
|
+
url: String(ctx.url || ctx.req?.url || ctx.req?.originalUrl || route.path),
|
|
537
|
+
headers: ctx.req?.headers || ctx.headers || {},
|
|
538
|
+
original: ctx.req || ctx.request || ctx
|
|
539
|
+
});
|
|
540
|
+
clearRequest.ctx = ctx;
|
|
541
|
+
clearRequest.route = route;
|
|
542
|
+
clearRequest.body = payload.body;
|
|
543
|
+
clearRequest.query = payload.query;
|
|
544
|
+
clearRequest.params = payload.params;
|
|
545
|
+
ctx.clearRequest = clearRequest;
|
|
546
|
+
if (!(ctx.clearResponse instanceof Response)) ctx.clearResponse = new Response();
|
|
459
547
|
if (!instance) return;
|
|
460
548
|
instance.ctx = ctx;
|
|
461
549
|
instance.body = payload.body;
|
|
462
550
|
instance.query = payload.query;
|
|
463
551
|
instance.params = payload.params;
|
|
464
|
-
instance.clearRequest =
|
|
465
|
-
ctx,
|
|
466
|
-
route,
|
|
467
|
-
body: instance.body,
|
|
468
|
-
query: instance.query,
|
|
469
|
-
params: instance.params
|
|
470
|
-
});
|
|
552
|
+
instance.clearRequest = clearRequest;
|
|
471
553
|
}
|
|
472
554
|
};
|
|
473
555
|
|
|
@@ -2,6 +2,26 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
2
2
|
import { EventHandlerRequest, H3, H3Event, Middleware, TypedServerRequest } from "h3";
|
|
3
3
|
import { NextFunction, Request, Response as Response$1 } from "express";
|
|
4
4
|
|
|
5
|
+
//#region src/core/Response.d.ts
|
|
6
|
+
declare class Response$2 {
|
|
7
|
+
body: any;
|
|
8
|
+
headers: Headers;
|
|
9
|
+
sent: boolean;
|
|
10
|
+
statusCode: number;
|
|
11
|
+
constructor(init?: Partial<Response$2>);
|
|
12
|
+
status(code: number): this;
|
|
13
|
+
code(code: number): this;
|
|
14
|
+
setHeader(name: string, value: string): this;
|
|
15
|
+
header(name: string, value: string): this;
|
|
16
|
+
set(name: string, value: string): this;
|
|
17
|
+
type(contentType: string): this;
|
|
18
|
+
send(body?: any): this;
|
|
19
|
+
json(body: any): this;
|
|
20
|
+
html(body: string): this;
|
|
21
|
+
text(body: string): this;
|
|
22
|
+
noContent(): this;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
5
25
|
//#region types/basic.d.ts
|
|
6
26
|
/**
|
|
7
27
|
* Controller method reference
|
|
@@ -30,6 +50,13 @@ interface RouterConfig {
|
|
|
30
50
|
bodyKeys?: string[] | string; /** Keys in the request headers to check for method override */
|
|
31
51
|
headerKeys?: string[] | string;
|
|
32
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* Optional method binding / container resolution support. Disabled by default.
|
|
55
|
+
*/
|
|
56
|
+
container?: {
|
|
57
|
+
/** Whether decorated handler parameter binding is enabled */enabled?: boolean; /** Whether unknown constructor tokens should be instantiated automatically */
|
|
58
|
+
autoDiscover?: boolean;
|
|
59
|
+
};
|
|
33
60
|
}
|
|
34
61
|
//#endregion
|
|
35
62
|
//#region types/express.d.ts
|
|
@@ -43,6 +70,8 @@ interface HttpContext$1 {
|
|
|
43
70
|
req: RequestWithGetBody;
|
|
44
71
|
res: Response$1;
|
|
45
72
|
next: NextFunction;
|
|
73
|
+
clearRequest: Request$1;
|
|
74
|
+
clearResponse: Response$2;
|
|
46
75
|
}
|
|
47
76
|
/**
|
|
48
77
|
* Route handler function type
|
|
@@ -57,7 +86,7 @@ ctx: HttpContext$1,
|
|
|
57
86
|
* ClearRequest instance
|
|
58
87
|
*/
|
|
59
88
|
|
|
60
|
-
req:
|
|
89
|
+
req: Request$1) => any | Promise<any>;
|
|
61
90
|
/**
|
|
62
91
|
* Handler can be either a function or controller reference
|
|
63
92
|
*/
|
|
@@ -80,6 +109,8 @@ type RequestlessH3Event = Omit<H3Event, 'req'>;
|
|
|
80
109
|
*/
|
|
81
110
|
interface HttpContext extends RequestlessH3Event {
|
|
82
111
|
req: HttpRequest;
|
|
112
|
+
clearRequest: Request$1;
|
|
113
|
+
clearResponse: Response$2;
|
|
83
114
|
}
|
|
84
115
|
/**
|
|
85
116
|
* Route handler function type
|
|
@@ -94,7 +125,7 @@ ctx: HttpContext,
|
|
|
94
125
|
* ClearRequest instance
|
|
95
126
|
*/
|
|
96
127
|
|
|
97
|
-
req:
|
|
128
|
+
req: Request$1) => any | Promise<any>;
|
|
98
129
|
/**
|
|
99
130
|
* Handler can be either a function or controller reference
|
|
100
131
|
*/
|
|
@@ -137,6 +168,26 @@ declare class ClearRequest<X = any, M = Middleware | Middleware$1> {
|
|
|
137
168
|
constructor(init?: Partial<ClearRequest>);
|
|
138
169
|
}
|
|
139
170
|
//#endregion
|
|
171
|
+
//#region src/core/Request.d.ts
|
|
172
|
+
declare class Request$1<X = any, M = any> extends ClearRequest<X, M> {
|
|
173
|
+
original?: any;
|
|
174
|
+
method: string;
|
|
175
|
+
path: string;
|
|
176
|
+
url: string;
|
|
177
|
+
headers: Headers | Record<string, any>;
|
|
178
|
+
constructor(init?: Partial<Request$1<X, M>> & {
|
|
179
|
+
body?: RequestData;
|
|
180
|
+
query?: RequestData;
|
|
181
|
+
params?: RequestData;
|
|
182
|
+
route?: Route<X, M>;
|
|
183
|
+
});
|
|
184
|
+
getBody(): RequestData;
|
|
185
|
+
header(name: string): string;
|
|
186
|
+
param(name: string): any;
|
|
187
|
+
input(name: string): any;
|
|
188
|
+
is(method: HttpMethod | string): boolean;
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
140
191
|
//#region src/Controller.d.ts
|
|
141
192
|
declare abstract class Controller<X = any> {
|
|
142
193
|
[x: string]: any;
|
|
@@ -158,16 +209,14 @@ declare abstract class CoreRouter {
|
|
|
158
209
|
protected static routerStateNamespace: string;
|
|
159
210
|
private static readonly stateStoreKey;
|
|
160
211
|
private static readonly stateBoundKey;
|
|
212
|
+
private static readonly defaultConfigKey;
|
|
213
|
+
protected static createBaseConfig(): RouterConfig;
|
|
214
|
+
protected static mergeConfig(target: RouterConfig, source?: RouterConfig): RouterConfig;
|
|
215
|
+
protected static getDefaultConfig(): RouterConfig;
|
|
161
216
|
protected static resolveStateNamespace(this: any): string;
|
|
162
217
|
protected static getStateStore(): Record<string, any>;
|
|
163
218
|
protected static createDefaultState(): {
|
|
164
|
-
config:
|
|
165
|
-
methodOverride: {
|
|
166
|
-
enabled: boolean;
|
|
167
|
-
bodyKeys: string[];
|
|
168
|
-
headerKeys: string[];
|
|
169
|
-
};
|
|
170
|
-
};
|
|
219
|
+
config: RouterConfig;
|
|
171
220
|
groupContext: AsyncLocalStorage<{
|
|
172
221
|
prefix: string;
|
|
173
222
|
groupMiddlewares: any[];
|
|
@@ -182,6 +231,7 @@ declare abstract class CoreRouter {
|
|
|
182
231
|
protected static bindStateAccessors(this: any): void;
|
|
183
232
|
protected static createDefaultOptionsHandler(): any;
|
|
184
233
|
static config: RouterConfig;
|
|
234
|
+
static configureDefaults(this: any, options?: RouterConfig): void;
|
|
185
235
|
protected static groupContext: AsyncLocalStorage<{
|
|
186
236
|
prefix: string;
|
|
187
237
|
groupMiddlewares: any[];
|
|
@@ -331,14 +381,20 @@ declare abstract class CoreRouter {
|
|
|
331
381
|
*/
|
|
332
382
|
static allRoutes(this: any, type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
|
|
333
383
|
protected static resolveHandler(route: Route<any, any, any>): {
|
|
334
|
-
handlerFunction: ((ctx: any, req:
|
|
384
|
+
handlerFunction: ((ctx: any, req: Request$1) => any | Promise<any>) | null;
|
|
335
385
|
instance: Controller<any> | null;
|
|
386
|
+
bindingTarget?: object;
|
|
387
|
+
bindingMethod?: PropertyKey;
|
|
388
|
+
bindingHandler?: object;
|
|
389
|
+
bindingMetadata?: object;
|
|
336
390
|
};
|
|
391
|
+
protected static callHandler(this: any, handlerFunction: (ctx: any, req: Request$1) => any | Promise<any>, ctx: any, bindingTarget?: object, bindingMethod?: PropertyKey, bindingHandler?: object, bindingMetadata?: object): Promise<any>;
|
|
337
392
|
protected static bindRequestToInstance(ctx: any, instance: Controller<any> | Route<any, any, any> | null, route: Route<any, any, any>, payload: {
|
|
338
393
|
body: Record<string, any>;
|
|
339
394
|
query: Record<string, any>;
|
|
340
395
|
params: Record<string, any>;
|
|
396
|
+
method?: HttpMethod | string;
|
|
341
397
|
}): void;
|
|
342
398
|
}
|
|
343
399
|
//#endregion
|
|
344
|
-
export { Handler as a, Handler$1 as c, ApiResourceMiddleware as d, ControllerAction as f, H3App as i, HttpContext$1 as l, HttpMethod as m,
|
|
400
|
+
export { Handler as a, Handler$1 as c, ApiResourceMiddleware as d, ControllerAction as f, Response$2 as h, H3App as i, HttpContext$1 as l, HttpMethod as m, Request$1 as n, HttpContext as o, ControllerHandler as p, Route as r, Middleware as s, CoreRouter as t, Middleware$1 as u };
|