clear-router 2.5.4 → 2.5.6
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 +5 -0
- package/dist/bindings-CV1e5jho.d.mts +20 -0
- package/dist/bindings-DIanvIVd.mjs +211 -0
- package/dist/bindings-DvV2DXWi.cjs +253 -0
- package/dist/bindings-NV0CdqGl.d.cts +20 -0
- package/dist/core/index.cjs +12 -2
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +9 -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 +308 -28
- package/dist/index.d.cts +112 -18
- package/dist/index.d.mts +112 -18
- package/dist/index.mjs +305 -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-BReOXz-F.mjs → router-B3QjblRX.mjs} +159 -48
- package/dist/{router-CS_2XQ7I.d.cts → router-BYZmNzrZ.d.cts} +97 -12
- package/dist/{router-CHg0pZUO.cjs → router-CU4V1kX0.cjs} +159 -48
- package/dist/{router-_w2VzMQF.d.mts → router-DCMtQ_Xi.d.mts} +96 -11
- 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
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
-
import { NextFunction, Request, Response as Response$
|
|
3
|
-
import { Middleware } from "h3";
|
|
2
|
+
import { NextFunction, Request as Request$1, Response as Response$2 } from "express";
|
|
3
|
+
import { Middleware as Middleware$1 } from "h3";
|
|
4
4
|
|
|
5
5
|
//#region types/basic.d.ts
|
|
6
6
|
/**
|
|
@@ -26,16 +26,37 @@ interface RouterConfig {
|
|
|
26
26
|
bodyKeys?: string[] | string; /** Keys in the request headers to check for method override */
|
|
27
27
|
headerKeys?: string[] | string;
|
|
28
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Optional method binding / container resolution support. Disabled by default.
|
|
31
|
+
*/
|
|
32
|
+
container?: {
|
|
33
|
+
/** Whether decorated handler parameter binding is enabled */enabled?: boolean; /** Whether unknown constructor tokens should be instantiated automatically */
|
|
34
|
+
autoDiscover?: boolean;
|
|
35
|
+
};
|
|
29
36
|
}
|
|
30
37
|
//#endregion
|
|
31
|
-
//#region
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
//#region src/core/Response.d.ts
|
|
39
|
+
declare class Response$1 {
|
|
40
|
+
body: any;
|
|
41
|
+
headers: Headers;
|
|
42
|
+
sent: boolean;
|
|
43
|
+
statusCode: number;
|
|
44
|
+
constructor(init?: Partial<Response$1>);
|
|
45
|
+
status(code: number): this;
|
|
46
|
+
code(code: number): this;
|
|
47
|
+
setHeader(name: string, value: string): this;
|
|
48
|
+
header(name: string, value: string): this;
|
|
49
|
+
set(name: string, value: string): this;
|
|
50
|
+
type(contentType: string): this;
|
|
51
|
+
send(body?: any): this;
|
|
52
|
+
json(body: any): this;
|
|
53
|
+
html(body: string): this;
|
|
54
|
+
text(body: string): this;
|
|
55
|
+
noContent(): this;
|
|
56
|
+
}
|
|
36
57
|
//#endregion
|
|
37
58
|
//#region src/Route.d.ts
|
|
38
|
-
declare class Route<X = any, M = Middleware | Middleware
|
|
59
|
+
declare class Route<X = any, M = Middleware$1 | Middleware, H = any> {
|
|
39
60
|
ctx: X;
|
|
40
61
|
body: RequestData;
|
|
41
62
|
query: RequestData;
|
|
@@ -52,8 +73,34 @@ declare class Route<X = any, M = Middleware | Middleware$1, H = any> {
|
|
|
52
73
|
constructor(methods: HttpMethod[], path: string, handler: H, middlewares?: M[]);
|
|
53
74
|
}
|
|
54
75
|
//#endregion
|
|
76
|
+
//#region src/core/Request.d.ts
|
|
77
|
+
declare class Request<X = any, M = any> extends ClearRequest<X, M> {
|
|
78
|
+
original?: any;
|
|
79
|
+
method: string;
|
|
80
|
+
path: string;
|
|
81
|
+
url: string;
|
|
82
|
+
headers: Headers | Record<string, any>;
|
|
83
|
+
constructor(init?: Partial<Request<X, M>> & {
|
|
84
|
+
body?: RequestData;
|
|
85
|
+
query?: RequestData;
|
|
86
|
+
params?: RequestData;
|
|
87
|
+
route?: Route<X, M>;
|
|
88
|
+
});
|
|
89
|
+
getBody(): RequestData;
|
|
90
|
+
header(name: string): string;
|
|
91
|
+
param(name: string): any;
|
|
92
|
+
input(name: string): any;
|
|
93
|
+
is(method: HttpMethod | string): boolean;
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region types/express.d.ts
|
|
97
|
+
/**
|
|
98
|
+
* Middleware function type
|
|
99
|
+
*/
|
|
100
|
+
type Middleware = (req: Request$1, res: Response$2, next: NextFunction) => any | Promise<any>;
|
|
101
|
+
//#endregion
|
|
55
102
|
//#region src/ClearRequest.d.ts
|
|
56
|
-
declare class ClearRequest<X = any, M = Middleware | Middleware
|
|
103
|
+
declare class ClearRequest<X = any, M = Middleware$1 | Middleware> {
|
|
57
104
|
[key: string]: any;
|
|
58
105
|
/**
|
|
59
106
|
* @param body - Parsed request body
|
|
@@ -81,6 +128,37 @@ declare abstract class Controller<X = any> {
|
|
|
81
128
|
clearRequest: ClearRequest;
|
|
82
129
|
}
|
|
83
130
|
//#endregion
|
|
131
|
+
//#region src/core/bindings.d.ts
|
|
132
|
+
type BindToken<T = any> = abstract new (...args: any[]) => T;
|
|
133
|
+
type BindFactory<T = any> = (ctx: any) => T | Promise<T>;
|
|
134
|
+
type BindValue<T = any> = T | BindFactory<T> | BindToken<T>;
|
|
135
|
+
declare class Container {
|
|
136
|
+
private static readonly registry;
|
|
137
|
+
static bind<T>(token: BindToken<T>, value: BindValue<T>): void;
|
|
138
|
+
static unbind<T>(token: BindToken<T>): void;
|
|
139
|
+
static clear(): void;
|
|
140
|
+
static has<T>(token: BindToken<T>): boolean;
|
|
141
|
+
static resolve<T>(token: BindToken<T>, ctx: any, autoDiscover?: boolean): Promise<T | undefined>;
|
|
142
|
+
private static resolveBinding;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/core/plugins.d.ts
|
|
146
|
+
type PluginSetupResult = void;
|
|
147
|
+
type PluginBind = <T>(token: BindToken<T>, value: BindValue<T>) => void;
|
|
148
|
+
interface ClearRouterPluginContext<Options = any> {
|
|
149
|
+
container: typeof Container;
|
|
150
|
+
bind: PluginBind;
|
|
151
|
+
configure: (options: RouterConfig) => void;
|
|
152
|
+
configureDefaults: (options: RouterConfig) => void;
|
|
153
|
+
options: Options;
|
|
154
|
+
}
|
|
155
|
+
interface ClearRouterPlugin<Options = any> {
|
|
156
|
+
name?: string;
|
|
157
|
+
setup: (ctx: ClearRouterPluginContext<Options>) => PluginSetupResult;
|
|
158
|
+
}
|
|
159
|
+
type ClearRouterPluginInput<Options = any> = ClearRouterPlugin<Options> | ((ctx: ClearRouterPluginContext<Options>) => PluginSetupResult);
|
|
160
|
+
declare function definePlugin<Options = any>(plugin: ClearRouterPlugin<Options>): ClearRouterPlugin<Options>;
|
|
161
|
+
//#endregion
|
|
84
162
|
//#region src/core/router.d.ts
|
|
85
163
|
/**
|
|
86
164
|
* @class clear-router CoreRouter
|
|
@@ -92,16 +170,16 @@ declare abstract class CoreRouter {
|
|
|
92
170
|
protected static routerStateNamespace: string;
|
|
93
171
|
private static readonly stateStoreKey;
|
|
94
172
|
private static readonly stateBoundKey;
|
|
173
|
+
private static readonly defaultConfigKey;
|
|
174
|
+
private static readonly pluginStoreKey;
|
|
175
|
+
protected static createBaseConfig(): RouterConfig;
|
|
176
|
+
protected static mergeConfig(target: RouterConfig, source?: RouterConfig): RouterConfig;
|
|
177
|
+
protected static getDefaultConfig(): RouterConfig;
|
|
95
178
|
protected static resolveStateNamespace(this: any): string;
|
|
96
179
|
protected static getStateStore(): Record<string, any>;
|
|
180
|
+
protected static getPluginStore(): Set<string>;
|
|
97
181
|
protected static createDefaultState(): {
|
|
98
|
-
config:
|
|
99
|
-
methodOverride: {
|
|
100
|
-
enabled: boolean;
|
|
101
|
-
bodyKeys: string[];
|
|
102
|
-
headerKeys: string[];
|
|
103
|
-
};
|
|
104
|
-
};
|
|
182
|
+
config: RouterConfig;
|
|
105
183
|
groupContext: AsyncLocalStorage<{
|
|
106
184
|
prefix: string;
|
|
107
185
|
groupMiddlewares: any[];
|
|
@@ -116,6 +194,16 @@ declare abstract class CoreRouter {
|
|
|
116
194
|
protected static bindStateAccessors(this: any): void;
|
|
117
195
|
protected static createDefaultOptionsHandler(): any;
|
|
118
196
|
static config: RouterConfig;
|
|
197
|
+
static configureDefaults(this: any, options?: RouterConfig): void;
|
|
198
|
+
/**
|
|
199
|
+
* Use a registered plugin
|
|
200
|
+
*
|
|
201
|
+
* @param this
|
|
202
|
+
* @param plugin
|
|
203
|
+
* @param options
|
|
204
|
+
* @returns
|
|
205
|
+
*/
|
|
206
|
+
static use<Options = any>(this: any, plugin: ClearRouterPluginInput<Options>, options?: Options): void;
|
|
119
207
|
protected static groupContext: AsyncLocalStorage<{
|
|
120
208
|
prefix: string;
|
|
121
209
|
groupMiddlewares: any[];
|
|
@@ -265,14 +353,20 @@ declare abstract class CoreRouter {
|
|
|
265
353
|
*/
|
|
266
354
|
static allRoutes(this: any, type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
|
|
267
355
|
protected static resolveHandler(route: Route<any, any, any>): {
|
|
268
|
-
handlerFunction: ((ctx: any, req:
|
|
356
|
+
handlerFunction: ((ctx: any, req: Request) => any | Promise<any>) | null;
|
|
269
357
|
instance: Controller<any> | null;
|
|
358
|
+
bindingTarget?: object;
|
|
359
|
+
bindingMethod?: PropertyKey;
|
|
360
|
+
bindingHandler?: object;
|
|
361
|
+
bindingMetadata?: object;
|
|
270
362
|
};
|
|
363
|
+
protected static callHandler(this: any, handlerFunction: (ctx: any, req: Request) => any | Promise<any>, ctx: any, bindingTarget?: object, bindingMethod?: PropertyKey, bindingHandler?: object, bindingMetadata?: object): Promise<any>;
|
|
271
364
|
protected static bindRequestToInstance(ctx: any, instance: Controller<any> | Route<any, any, any> | null, route: Route<any, any, any>, payload: {
|
|
272
365
|
body: Record<string, any>;
|
|
273
366
|
query: Record<string, any>;
|
|
274
367
|
params: Record<string, any>;
|
|
368
|
+
method?: HttpMethod | string;
|
|
275
369
|
}): void;
|
|
276
370
|
}
|
|
277
371
|
//#endregion
|
|
278
|
-
export { ClearRequest, Controller, CoreRouter, Route };
|
|
372
|
+
export { ClearRequest, ClearRouterPlugin, ClearRouterPluginContext, ClearRouterPluginInput, Controller, CoreRouter, PluginBind, PluginSetupResult, Request, Response$1 as Response, Route, definePlugin };
|
package/dist/index.mjs
CHANGED
|
@@ -58,6 +58,152 @@ var Route = class {
|
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/core/Request.ts
|
|
63
|
+
var Request = class extends ClearRequest {
|
|
64
|
+
original;
|
|
65
|
+
method = "GET";
|
|
66
|
+
path = "/";
|
|
67
|
+
url = "/";
|
|
68
|
+
headers = {};
|
|
69
|
+
constructor(init) {
|
|
70
|
+
super(init);
|
|
71
|
+
Object.assign(this, init);
|
|
72
|
+
}
|
|
73
|
+
getBody() {
|
|
74
|
+
return this.body ?? {};
|
|
75
|
+
}
|
|
76
|
+
header(name) {
|
|
77
|
+
if (typeof this.headers.get === "function") return this.headers.get(name) || "";
|
|
78
|
+
const headers = this.headers;
|
|
79
|
+
const value = headers[name] ?? headers[name.toLowerCase()];
|
|
80
|
+
return Array.isArray(value) ? String(value[0] ?? "") : String(value ?? "");
|
|
81
|
+
}
|
|
82
|
+
param(name) {
|
|
83
|
+
return this.params?.[name];
|
|
84
|
+
}
|
|
85
|
+
input(name) {
|
|
86
|
+
return this.body?.[name] ?? this.query?.[name] ?? this.params?.[name];
|
|
87
|
+
}
|
|
88
|
+
is(method) {
|
|
89
|
+
return this.method.toLowerCase() === String(method).toLowerCase();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/core/Response.ts
|
|
95
|
+
var Response = class {
|
|
96
|
+
body;
|
|
97
|
+
headers = new Headers();
|
|
98
|
+
sent = false;
|
|
99
|
+
statusCode = 200;
|
|
100
|
+
constructor(init) {
|
|
101
|
+
Object.assign(this, init);
|
|
102
|
+
if (init?.headers && !(init.headers instanceof Headers)) this.headers = new Headers(init.headers);
|
|
103
|
+
}
|
|
104
|
+
status(code) {
|
|
105
|
+
this.statusCode = code;
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
code(code) {
|
|
109
|
+
return this.status(code);
|
|
110
|
+
}
|
|
111
|
+
setHeader(name, value) {
|
|
112
|
+
this.headers.set(name, value);
|
|
113
|
+
return this;
|
|
114
|
+
}
|
|
115
|
+
header(name, value) {
|
|
116
|
+
return this.setHeader(name, value);
|
|
117
|
+
}
|
|
118
|
+
set(name, value) {
|
|
119
|
+
return this.setHeader(name, value);
|
|
120
|
+
}
|
|
121
|
+
type(contentType) {
|
|
122
|
+
return this.setHeader("Content-Type", contentType);
|
|
123
|
+
}
|
|
124
|
+
send(body) {
|
|
125
|
+
this.body = body;
|
|
126
|
+
this.sent = true;
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
json(body) {
|
|
130
|
+
return this.type("application/json; charset=utf-8").send(body);
|
|
131
|
+
}
|
|
132
|
+
html(body) {
|
|
133
|
+
return this.type("text/html; charset=utf-8").send(body);
|
|
134
|
+
}
|
|
135
|
+
text(body) {
|
|
136
|
+
return this.type("text/plain; charset=utf-8").send(body);
|
|
137
|
+
}
|
|
138
|
+
noContent() {
|
|
139
|
+
return this.status(204).send(null);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/core/plugins.ts
|
|
145
|
+
function definePlugin(plugin) {
|
|
146
|
+
return plugin;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/core/bindings.ts
|
|
151
|
+
const metadataKey = Symbol.for("clear-router:binding-metadata");
|
|
152
|
+
const bindings = /* @__PURE__ */ new WeakMap();
|
|
153
|
+
var Container = class {
|
|
154
|
+
static registry = /* @__PURE__ */ new Map();
|
|
155
|
+
static bind(token, value) {
|
|
156
|
+
this.registry.set(token, value);
|
|
157
|
+
}
|
|
158
|
+
static unbind(token) {
|
|
159
|
+
this.registry.delete(token);
|
|
160
|
+
}
|
|
161
|
+
static clear() {
|
|
162
|
+
this.registry.clear();
|
|
163
|
+
}
|
|
164
|
+
static has(token) {
|
|
165
|
+
return this.registry.has(token);
|
|
166
|
+
}
|
|
167
|
+
static async resolve(token, ctx, autoDiscover = false) {
|
|
168
|
+
if (token === Request) return ctx.clearRequest;
|
|
169
|
+
if (token === Response) return ctx.clearResponse;
|
|
170
|
+
if (this.registry.has(token)) return this.resolveBinding(this.registry.get(token), ctx, autoDiscover);
|
|
171
|
+
if (autoDiscover && typeof token === "function") return new token();
|
|
172
|
+
}
|
|
173
|
+
static async resolveBinding(binding, ctx, autoDiscover) {
|
|
174
|
+
if (!binding) return void 0;
|
|
175
|
+
if (typeof binding !== "function") return binding;
|
|
176
|
+
if (isClass(binding)) return new binding();
|
|
177
|
+
const resolved = await binding(ctx);
|
|
178
|
+
if (typeof resolved === "function" && autoDiscover && isClass(resolved)) return new resolved();
|
|
179
|
+
return resolved;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
function getStandardMetadata(metadata, propertyKey) {
|
|
183
|
+
const store = metadata && metadata[metadataKey];
|
|
184
|
+
if (!store) return void 0;
|
|
185
|
+
return propertyKey ? store[propertyKey] : void 0;
|
|
186
|
+
}
|
|
187
|
+
function getBindingMetadataFromTargets(targets) {
|
|
188
|
+
for (const { target, propertyKey } of targets) {
|
|
189
|
+
if (!target) continue;
|
|
190
|
+
const metadata = getBindingMetadata(target, propertyKey);
|
|
191
|
+
if (metadata) return metadata;
|
|
192
|
+
const standardMetadata = getStandardMetadata(target[Symbol.metadata], propertyKey);
|
|
193
|
+
if (standardMetadata) return standardMetadata;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function getBindingMetadata(target, propertyKey) {
|
|
197
|
+
if (propertyKey) return bindings.get(target)?.get(propertyKey);
|
|
198
|
+
return bindings.get(target)?.get("__route_handler__");
|
|
199
|
+
}
|
|
200
|
+
function getDesignParamTypes(target, propertyKey) {
|
|
201
|
+
return Reflect.getMetadata?.("design:paramtypes", target, propertyKey) ?? [];
|
|
202
|
+
}
|
|
203
|
+
function isClass(value) {
|
|
204
|
+
return typeof value === "function" && /^class\s/.test(Function.prototype.toString.call(value));
|
|
205
|
+
}
|
|
206
|
+
|
|
61
207
|
//#endregion
|
|
62
208
|
//#region src/core/router.ts
|
|
63
209
|
/**
|
|
@@ -70,6 +216,41 @@ var CoreRouter = class {
|
|
|
70
216
|
static routerStateNamespace = "clear-router:core";
|
|
71
217
|
static stateStoreKey = Symbol.for("clear-router:router-state");
|
|
72
218
|
static stateBoundKey = Symbol.for("clear-router:router-state-bound");
|
|
219
|
+
static defaultConfigKey = Symbol.for("clear-router:default-config");
|
|
220
|
+
static pluginStoreKey = Symbol.for("clear-router:plugins");
|
|
221
|
+
static createBaseConfig() {
|
|
222
|
+
return {
|
|
223
|
+
methodOverride: {
|
|
224
|
+
enabled: true,
|
|
225
|
+
bodyKeys: ["_method"],
|
|
226
|
+
headerKeys: ["x-http-method"]
|
|
227
|
+
},
|
|
228
|
+
container: {
|
|
229
|
+
enabled: false,
|
|
230
|
+
autoDiscover: false
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
static mergeConfig(target, source) {
|
|
235
|
+
if (!source) return target;
|
|
236
|
+
if (source.methodOverride) target.methodOverride = {
|
|
237
|
+
...target.methodOverride || {},
|
|
238
|
+
...source.methodOverride
|
|
239
|
+
};
|
|
240
|
+
if (source.container) target.container = {
|
|
241
|
+
...target.container || {},
|
|
242
|
+
...source.container
|
|
243
|
+
};
|
|
244
|
+
return target;
|
|
245
|
+
}
|
|
246
|
+
static getDefaultConfig() {
|
|
247
|
+
const g = globalThis;
|
|
248
|
+
if (!g[this.defaultConfigKey]) g[this.defaultConfigKey] = this.createBaseConfig();
|
|
249
|
+
return {
|
|
250
|
+
methodOverride: { ...g[this.defaultConfigKey].methodOverride },
|
|
251
|
+
container: { ...g[this.defaultConfigKey].container }
|
|
252
|
+
};
|
|
253
|
+
}
|
|
73
254
|
static resolveStateNamespace() {
|
|
74
255
|
return String(this.routerStateNamespace || this.name || "clear-router:core");
|
|
75
256
|
}
|
|
@@ -78,13 +259,14 @@ var CoreRouter = class {
|
|
|
78
259
|
if (!g[this.stateStoreKey]) g[this.stateStoreKey] = Object.create(null);
|
|
79
260
|
return g[this.stateStoreKey];
|
|
80
261
|
}
|
|
262
|
+
static getPluginStore() {
|
|
263
|
+
const g = globalThis;
|
|
264
|
+
if (!g[this.pluginStoreKey]) g[this.pluginStoreKey] = /* @__PURE__ */ new Set();
|
|
265
|
+
return g[this.pluginStoreKey];
|
|
266
|
+
}
|
|
81
267
|
static createDefaultState() {
|
|
82
268
|
return {
|
|
83
|
-
config:
|
|
84
|
-
enabled: true,
|
|
85
|
-
bodyKeys: ["_method"],
|
|
86
|
-
headerKeys: ["x-http-method"]
|
|
87
|
-
} },
|
|
269
|
+
config: this.getDefaultConfig(),
|
|
88
270
|
groupContext: new AsyncLocalStorage(),
|
|
89
271
|
routes: [],
|
|
90
272
|
routesByPathMethod: {},
|
|
@@ -161,11 +343,47 @@ var CoreRouter = class {
|
|
|
161
343
|
}
|
|
162
344
|
};
|
|
163
345
|
}
|
|
164
|
-
static config = {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
346
|
+
static config = {
|
|
347
|
+
methodOverride: {
|
|
348
|
+
enabled: true,
|
|
349
|
+
bodyKeys: ["_method"],
|
|
350
|
+
headerKeys: ["x-http-method"]
|
|
351
|
+
},
|
|
352
|
+
container: {
|
|
353
|
+
enabled: false,
|
|
354
|
+
autoDiscover: false
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
static configureDefaults(options) {
|
|
358
|
+
const g = globalThis;
|
|
359
|
+
const defaults = this.mergeConfig(g[this.defaultConfigKey] || this.createBaseConfig(), options);
|
|
360
|
+
g[this.defaultConfigKey] = defaults;
|
|
361
|
+
const store = this.getStateStore();
|
|
362
|
+
for (const state of Object.values(store)) state.config = this.mergeConfig(state.config || this.createBaseConfig(), options);
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Use a registered plugin
|
|
366
|
+
*
|
|
367
|
+
* @param this
|
|
368
|
+
* @param plugin
|
|
369
|
+
* @param options
|
|
370
|
+
* @returns
|
|
371
|
+
*/
|
|
372
|
+
static use(plugin, options) {
|
|
373
|
+
const name = typeof plugin === "function" ? plugin.name : plugin.name;
|
|
374
|
+
const store = this.getPluginStore();
|
|
375
|
+
if (name && store.has(name)) return;
|
|
376
|
+
const ctx = {
|
|
377
|
+
container: Container,
|
|
378
|
+
bind: Container.bind.bind(Container),
|
|
379
|
+
configure: this.configure.bind(this),
|
|
380
|
+
configureDefaults: this.configureDefaults.bind(this),
|
|
381
|
+
options
|
|
382
|
+
};
|
|
383
|
+
if (typeof plugin === "function") plugin(ctx);
|
|
384
|
+
else plugin.setup(ctx);
|
|
385
|
+
if (name) store.add(name);
|
|
386
|
+
}
|
|
169
387
|
static groupContext = new AsyncLocalStorage();
|
|
170
388
|
static routes = [];
|
|
171
389
|
static routesByPathMethod = {};
|
|
@@ -207,11 +425,12 @@ var CoreRouter = class {
|
|
|
207
425
|
*/
|
|
208
426
|
static configure(options) {
|
|
209
427
|
this.ensureState();
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
428
|
+
this.config = this.mergeConfig(this.getDefaultConfig(), this.config);
|
|
429
|
+
const container = options?.container;
|
|
430
|
+
if (container) {
|
|
431
|
+
if (typeof container.enabled === "boolean") this.config.container.enabled = container.enabled;
|
|
432
|
+
if (typeof container.autoDiscover === "boolean") this.config.container.autoDiscover = container.autoDiscover;
|
|
433
|
+
}
|
|
215
434
|
const override = options?.methodOverride;
|
|
216
435
|
if (!override) return;
|
|
217
436
|
if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
|
|
@@ -448,38 +667,96 @@ var CoreRouter = class {
|
|
|
448
667
|
static resolveHandler(route) {
|
|
449
668
|
let handlerFunction;
|
|
450
669
|
let instance = null;
|
|
451
|
-
|
|
452
|
-
|
|
670
|
+
let bindingTarget;
|
|
671
|
+
let bindingMethod;
|
|
672
|
+
let bindingHandler;
|
|
673
|
+
let bindingMetadata;
|
|
674
|
+
if (typeof route.handler === "function") {
|
|
675
|
+
handlerFunction = route.handler.bind(route);
|
|
676
|
+
bindingTarget = route.handler;
|
|
677
|
+
bindingHandler = route.handler;
|
|
678
|
+
} else if (Array.isArray(route.handler) && route.handler.length === 2) {
|
|
453
679
|
const [ControllerType, method] = route.handler;
|
|
454
680
|
if (["function", "object"].includes(typeof ControllerType) && typeof ControllerType[method] === "function") {
|
|
455
681
|
instance = ControllerType;
|
|
456
682
|
handlerFunction = ControllerType[method].bind(ControllerType);
|
|
683
|
+
bindingTarget = ControllerType;
|
|
684
|
+
bindingMethod = method;
|
|
685
|
+
bindingHandler = ControllerType[method];
|
|
686
|
+
bindingMetadata = ControllerType[Symbol.metadata];
|
|
457
687
|
} else if (typeof ControllerType === "function") {
|
|
458
688
|
instance = new ControllerType();
|
|
459
|
-
if (typeof instance[method] === "function")
|
|
460
|
-
|
|
689
|
+
if (typeof instance[method] === "function") {
|
|
690
|
+
handlerFunction = instance[method].bind(instance);
|
|
691
|
+
bindingTarget = ControllerType.prototype;
|
|
692
|
+
bindingMethod = method;
|
|
693
|
+
bindingHandler = instance[method];
|
|
694
|
+
bindingMetadata = ControllerType[Symbol.metadata];
|
|
695
|
+
} else throw new Error(`Method "${method}" not found in controller instance "${ControllerType.name}"`);
|
|
461
696
|
} else throw new Error(`Invalid controller type for route: ${route.path}`);
|
|
462
697
|
} else throw new Error(`Invalid handler format for route: ${route.path}`);
|
|
463
698
|
return {
|
|
464
699
|
handlerFunction,
|
|
465
|
-
instance
|
|
700
|
+
instance,
|
|
701
|
+
bindingTarget,
|
|
702
|
+
bindingMethod,
|
|
703
|
+
bindingHandler,
|
|
704
|
+
bindingMetadata
|
|
466
705
|
};
|
|
467
706
|
}
|
|
707
|
+
static async callHandler(handlerFunction, ctx, bindingTarget, bindingMethod, bindingHandler, bindingMetadata) {
|
|
708
|
+
if (!this.config.container?.enabled) return handlerFunction(ctx, ctx.clearRequest);
|
|
709
|
+
const metadata = getBindingMetadataFromTargets([
|
|
710
|
+
{
|
|
711
|
+
target: bindingTarget,
|
|
712
|
+
propertyKey: bindingMethod
|
|
713
|
+
},
|
|
714
|
+
{ target: bindingHandler },
|
|
715
|
+
{
|
|
716
|
+
target: bindingTarget,
|
|
717
|
+
propertyKey: "__class__"
|
|
718
|
+
}
|
|
719
|
+
]) ?? getStandardMetadata(bindingMetadata, bindingMethod) ?? getStandardMetadata(bindingMetadata, "__class__");
|
|
720
|
+
if (!metadata) return handlerFunction(ctx, ctx.clearRequest);
|
|
721
|
+
const designTokens = [...bindingTarget ? getDesignParamTypes(bindingTarget, bindingMethod) : [], ...bindingHandler ? getDesignParamTypes(bindingHandler) : []];
|
|
722
|
+
const tokens = metadata.tokens?.length ? metadata.tokens : designTokens;
|
|
723
|
+
if (!tokens.length) return handlerFunction(ctx, ctx.clearRequest);
|
|
724
|
+
const args = [];
|
|
725
|
+
for (const token of tokens) {
|
|
726
|
+
const resolved = await Container.resolve(token, ctx, Boolean(this.config.container?.autoDiscover));
|
|
727
|
+
if (typeof resolved === "undefined") return handlerFunction(ctx, ctx.clearRequest);
|
|
728
|
+
args.push(resolved);
|
|
729
|
+
}
|
|
730
|
+
return handlerFunction(...args);
|
|
731
|
+
}
|
|
468
732
|
static bindRequestToInstance(ctx, instance, route, payload) {
|
|
733
|
+
const clearRequest = ctx.clearRequest instanceof Request ? ctx.clearRequest : new Request({
|
|
734
|
+
ctx,
|
|
735
|
+
route,
|
|
736
|
+
body: payload.body,
|
|
737
|
+
query: payload.query,
|
|
738
|
+
params: payload.params,
|
|
739
|
+
method: String(payload.method || ctx.req?.method || ctx.method || "GET").toUpperCase(),
|
|
740
|
+
path: String(ctx.path || ctx.req?.path || ctx.req?.url || route.path),
|
|
741
|
+
url: String(ctx.url || ctx.req?.url || ctx.req?.originalUrl || route.path),
|
|
742
|
+
headers: ctx.req?.headers || ctx.headers || {},
|
|
743
|
+
original: ctx.req || ctx.request || ctx
|
|
744
|
+
});
|
|
745
|
+
clearRequest.ctx = ctx;
|
|
746
|
+
clearRequest.route = route;
|
|
747
|
+
clearRequest.body = payload.body;
|
|
748
|
+
clearRequest.query = payload.query;
|
|
749
|
+
clearRequest.params = payload.params;
|
|
750
|
+
ctx.clearRequest = clearRequest;
|
|
751
|
+
if (!(ctx.clearResponse instanceof Response)) ctx.clearResponse = new Response();
|
|
469
752
|
if (!instance) return;
|
|
470
753
|
instance.ctx = ctx;
|
|
471
754
|
instance.body = payload.body;
|
|
472
755
|
instance.query = payload.query;
|
|
473
756
|
instance.params = payload.params;
|
|
474
|
-
instance.clearRequest =
|
|
475
|
-
ctx,
|
|
476
|
-
route,
|
|
477
|
-
body: instance.body,
|
|
478
|
-
query: instance.query,
|
|
479
|
-
params: instance.params
|
|
480
|
-
});
|
|
757
|
+
instance.clearRequest = clearRequest;
|
|
481
758
|
}
|
|
482
759
|
};
|
|
483
760
|
|
|
484
761
|
//#endregion
|
|
485
|
-
export { ClearRequest, Controller, CoreRouter, Route };
|
|
762
|
+
export { ClearRequest, Controller, CoreRouter, Request, Response, Route, definePlugin };
|
package/dist/koa/index.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
|
|
3
|
-
const
|
|
2
|
+
require('../bindings-DvV2DXWi.cjs');
|
|
3
|
+
const require_router = require('../router-CU4V1kX0.cjs');
|
|
4
|
+
const require_responses = require('../responses-JzXstGU5.cjs');
|
|
4
5
|
|
|
5
6
|
//#region src/koa/router.ts
|
|
6
7
|
/**
|
|
@@ -44,6 +45,9 @@ var Router = class Router extends require_router.CoreRouter {
|
|
|
44
45
|
});
|
|
45
46
|
if (!meta) return void 0;
|
|
46
47
|
ctx.status = meta.status;
|
|
48
|
+
meta.headers?.forEach((headerValue, key) => {
|
|
49
|
+
ctx.set(key, headerValue);
|
|
50
|
+
});
|
|
47
51
|
if (require_responses.isFetchResponse(meta.body)) {
|
|
48
52
|
meta.body.headers.forEach((headerValue, key) => {
|
|
49
53
|
ctx.set(key, headerValue);
|
|
@@ -180,10 +184,18 @@ var Router = class Router extends require_router.CoreRouter {
|
|
|
180
184
|
for (const route of this.routes) {
|
|
181
185
|
let handlerFunction = null;
|
|
182
186
|
let instance = null;
|
|
187
|
+
let bindingTarget;
|
|
188
|
+
let bindingMethod;
|
|
189
|
+
let bindingHandler;
|
|
190
|
+
let bindingMetadata;
|
|
183
191
|
try {
|
|
184
192
|
const resolved = this.resolveHandler(route);
|
|
185
193
|
handlerFunction = resolved.handlerFunction;
|
|
186
194
|
instance = resolved.instance;
|
|
195
|
+
bindingTarget = resolved.bindingTarget;
|
|
196
|
+
bindingMethod = resolved.bindingMethod;
|
|
197
|
+
bindingHandler = resolved.bindingHandler;
|
|
198
|
+
bindingMetadata = resolved.bindingMetadata;
|
|
187
199
|
} catch (error) {
|
|
188
200
|
console.error(`[ROUTES] Error setting up route ${route.path}:`, error.message);
|
|
189
201
|
throw error;
|
|
@@ -210,11 +222,13 @@ var Router = class Router extends require_router.CoreRouter {
|
|
|
210
222
|
Router.bindRequestToInstance(ctx, inst, route, {
|
|
211
223
|
body: reqBody,
|
|
212
224
|
query: ctx.query,
|
|
213
|
-
params: ctx.params ?? {}
|
|
225
|
+
params: ctx.params ?? {},
|
|
226
|
+
method
|
|
214
227
|
});
|
|
215
|
-
const result = handlerFunction
|
|
228
|
+
const result = await Router.callHandler(handlerFunction, ctx, bindingTarget, bindingMethod, bindingHandler, bindingMetadata);
|
|
216
229
|
const resolved = await Promise.resolve(result);
|
|
217
|
-
|
|
230
|
+
const outgoing = typeof resolved === "undefined" && ctx.clearResponse?.sent ? ctx.clearResponse : resolved;
|
|
231
|
+
return Router.sendReturnValue(ctx, outgoing, method, route.path);
|
|
218
232
|
});
|
|
219
233
|
if ([
|
|
220
234
|
"put",
|
|
@@ -228,11 +242,13 @@ var Router = class Router extends require_router.CoreRouter {
|
|
|
228
242
|
Router.bindRequestToInstance(ctx, inst, route, {
|
|
229
243
|
body: reqBody,
|
|
230
244
|
query: ctx.query,
|
|
231
|
-
params: ctx.params ?? {}
|
|
245
|
+
params: ctx.params ?? {},
|
|
246
|
+
method
|
|
232
247
|
});
|
|
233
|
-
const result = handlerFunction
|
|
248
|
+
const result = await Router.callHandler(handlerFunction, ctx, bindingTarget, bindingMethod, bindingHandler, bindingMetadata);
|
|
234
249
|
const resolved = await Promise.resolve(result);
|
|
235
|
-
|
|
250
|
+
const outgoing = typeof resolved === "undefined" && ctx.clearResponse?.sent ? ctx.clearResponse : resolved;
|
|
251
|
+
return Router.sendReturnValue(ctx, outgoing, method, route.path);
|
|
236
252
|
});
|
|
237
253
|
}
|
|
238
254
|
}
|
package/dist/koa/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as ApiResourceMiddleware, b as HttpMethod, c as Request, l as Route, t as CoreRouter, v as ControllerAction, x as Response, y as ControllerHandler } from "../router-BYZmNzrZ.cjs";
|
|
2
2
|
import Koa from "koa";
|
|
3
3
|
import Router$1 from "@koa/router";
|
|
4
4
|
|
|
@@ -9,10 +9,12 @@ interface RequestWithGetBody extends Koa.Request {
|
|
|
9
9
|
}
|
|
10
10
|
interface HttpContext extends Koa.Context {
|
|
11
11
|
request: RequestWithGetBody;
|
|
12
|
+
clearRequest: Request;
|
|
13
|
+
clearResponse: Response;
|
|
12
14
|
params: Record<string, any>;
|
|
13
15
|
query: Record<string, any>;
|
|
14
16
|
}
|
|
15
|
-
type RouteHandler = (ctx: HttpContext, req:
|
|
17
|
+
type RouteHandler = (ctx: HttpContext, req: Request) => any | Promise<any>;
|
|
16
18
|
type Handler = RouteHandler | ControllerHandler;
|
|
17
19
|
type Middleware = Koa.Middleware<any, any>;
|
|
18
20
|
type KoaRouterApp = Router$1<any, any>;
|