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.
Files changed (56) hide show
  1. package/README.md +5 -0
  2. package/dist/bindings-CV1e5jho.d.mts +20 -0
  3. package/dist/bindings-DIanvIVd.mjs +211 -0
  4. package/dist/bindings-DvV2DXWi.cjs +253 -0
  5. package/dist/bindings-NV0CdqGl.d.cts +20 -0
  6. package/dist/core/index.cjs +12 -2
  7. package/dist/core/index.d.cts +2 -2
  8. package/dist/core/index.d.mts +2 -2
  9. package/dist/core/index.mjs +9 -2
  10. package/dist/decorators/index.cjs +5 -0
  11. package/dist/decorators/index.d.cts +2 -0
  12. package/dist/decorators/index.d.mts +2 -0
  13. package/dist/decorators/index.mjs +3 -0
  14. package/dist/decorators/setup.cjs +15 -0
  15. package/dist/decorators/setup.d.cts +2 -0
  16. package/dist/decorators/setup.d.mts +2 -0
  17. package/dist/decorators/setup.mjs +13 -0
  18. package/dist/express/index.cjs +26 -9
  19. package/dist/express/index.d.cts +1 -1
  20. package/dist/express/index.d.mts +1 -1
  21. package/dist/express/index.mjs +26 -9
  22. package/dist/fastify/index.cjs +24 -8
  23. package/dist/fastify/index.d.cts +4 -2
  24. package/dist/fastify/index.d.mts +4 -2
  25. package/dist/fastify/index.mjs +24 -8
  26. package/dist/h3/index.cjs +26 -9
  27. package/dist/h3/index.d.cts +1 -1
  28. package/dist/h3/index.d.mts +1 -1
  29. package/dist/h3/index.mjs +26 -9
  30. package/dist/hono/index.cjs +28 -11
  31. package/dist/hono/index.d.cts +4 -2
  32. package/dist/hono/index.d.mts +4 -2
  33. package/dist/hono/index.mjs +28 -11
  34. package/dist/index.cjs +308 -28
  35. package/dist/index.d.cts +112 -18
  36. package/dist/index.d.mts +112 -18
  37. package/dist/index.mjs +305 -28
  38. package/dist/koa/index.cjs +24 -8
  39. package/dist/koa/index.d.cts +4 -2
  40. package/dist/koa/index.d.mts +4 -2
  41. package/dist/koa/index.mjs +24 -8
  42. package/dist/{responses-B-UirWFf.cjs → responses-JzXstGU5.cjs} +18 -1
  43. package/dist/{responses-CJaD0ugv.mjs → responses-_II3dOJ5.mjs} +19 -1
  44. package/dist/{router-BReOXz-F.mjs → router-B3QjblRX.mjs} +159 -48
  45. package/dist/{router-CS_2XQ7I.d.cts → router-BYZmNzrZ.d.cts} +97 -12
  46. package/dist/{router-CHg0pZUO.cjs → router-CU4V1kX0.cjs} +159 -48
  47. package/dist/{router-_w2VzMQF.d.mts → router-DCMtQ_Xi.d.mts} +96 -11
  48. package/dist/types/basic.d.mts +7 -0
  49. package/dist/types/core/Request.d.mts +25 -0
  50. package/dist/types/core/Response.d.mts +21 -0
  51. package/dist/types/express.d.mts +5 -2
  52. package/dist/types/fastify.d.mts +5 -2
  53. package/dist/types/h3.d.mts +5 -2
  54. package/dist/types/hono.d.mts +5 -2
  55. package/dist/types/koa.d.mts +5 -2
  56. package/package.json +16 -2
@@ -1,26 +1,6 @@
1
+ const require_bindings = require('./bindings-DvV2DXWi.cjs');
1
2
  let node_async_hooks = require("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,41 @@ 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 pluginStoreKey = Symbol.for("clear-router:plugins");
45
+ static createBaseConfig() {
46
+ return {
47
+ methodOverride: {
48
+ enabled: true,
49
+ bodyKeys: ["_method"],
50
+ headerKeys: ["x-http-method"]
51
+ },
52
+ container: {
53
+ enabled: false,
54
+ autoDiscover: false
55
+ }
56
+ };
57
+ }
58
+ static mergeConfig(target, source) {
59
+ if (!source) return target;
60
+ if (source.methodOverride) target.methodOverride = {
61
+ ...target.methodOverride || {},
62
+ ...source.methodOverride
63
+ };
64
+ if (source.container) target.container = {
65
+ ...target.container || {},
66
+ ...source.container
67
+ };
68
+ return target;
69
+ }
70
+ static getDefaultConfig() {
71
+ const g = globalThis;
72
+ if (!g[this.defaultConfigKey]) g[this.defaultConfigKey] = this.createBaseConfig();
73
+ return {
74
+ methodOverride: { ...g[this.defaultConfigKey].methodOverride },
75
+ container: { ...g[this.defaultConfigKey].container }
76
+ };
77
+ }
63
78
  static resolveStateNamespace() {
64
79
  return String(this.routerStateNamespace || this.name || "clear-router:core");
65
80
  }
@@ -68,13 +83,14 @@ var CoreRouter = class {
68
83
  if (!g[this.stateStoreKey]) g[this.stateStoreKey] = Object.create(null);
69
84
  return g[this.stateStoreKey];
70
85
  }
86
+ static getPluginStore() {
87
+ const g = globalThis;
88
+ if (!g[this.pluginStoreKey]) g[this.pluginStoreKey] = /* @__PURE__ */ new Set();
89
+ return g[this.pluginStoreKey];
90
+ }
71
91
  static createDefaultState() {
72
92
  return {
73
- config: { methodOverride: {
74
- enabled: true,
75
- bodyKeys: ["_method"],
76
- headerKeys: ["x-http-method"]
77
- } },
93
+ config: this.getDefaultConfig(),
78
94
  groupContext: new node_async_hooks.AsyncLocalStorage(),
79
95
  routes: [],
80
96
  routesByPathMethod: {},
@@ -151,11 +167,47 @@ var CoreRouter = class {
151
167
  }
152
168
  };
153
169
  }
154
- static config = { methodOverride: {
155
- enabled: true,
156
- bodyKeys: ["_method"],
157
- headerKeys: ["x-http-method"]
158
- } };
170
+ static config = {
171
+ methodOverride: {
172
+ enabled: true,
173
+ bodyKeys: ["_method"],
174
+ headerKeys: ["x-http-method"]
175
+ },
176
+ container: {
177
+ enabled: false,
178
+ autoDiscover: false
179
+ }
180
+ };
181
+ static configureDefaults(options) {
182
+ const g = globalThis;
183
+ const defaults = this.mergeConfig(g[this.defaultConfigKey] || this.createBaseConfig(), options);
184
+ g[this.defaultConfigKey] = defaults;
185
+ const store = this.getStateStore();
186
+ for (const state of Object.values(store)) state.config = this.mergeConfig(state.config || this.createBaseConfig(), options);
187
+ }
188
+ /**
189
+ * Use a registered plugin
190
+ *
191
+ * @param this
192
+ * @param plugin
193
+ * @param options
194
+ * @returns
195
+ */
196
+ static use(plugin, options) {
197
+ const name = typeof plugin === "function" ? plugin.name : plugin.name;
198
+ const store = this.getPluginStore();
199
+ if (name && store.has(name)) return;
200
+ const ctx = {
201
+ container: require_bindings.Container,
202
+ bind: require_bindings.Container.bind.bind(require_bindings.Container),
203
+ configure: this.configure.bind(this),
204
+ configureDefaults: this.configureDefaults.bind(this),
205
+ options
206
+ };
207
+ if (typeof plugin === "function") plugin(ctx);
208
+ else plugin.setup(ctx);
209
+ if (name) store.add(name);
210
+ }
159
211
  static groupContext = new node_async_hooks.AsyncLocalStorage();
160
212
  static routes = [];
161
213
  static routesByPathMethod = {};
@@ -197,11 +249,12 @@ var CoreRouter = class {
197
249
  */
198
250
  static configure(options) {
199
251
  this.ensureState();
200
- if (!this.config.methodOverride) this.config.methodOverride = {
201
- enabled: true,
202
- bodyKeys: ["_method"],
203
- headerKeys: ["x-http-method"]
204
- };
252
+ this.config = this.mergeConfig(this.getDefaultConfig(), this.config);
253
+ const container = options?.container;
254
+ if (container) {
255
+ if (typeof container.enabled === "boolean") this.config.container.enabled = container.enabled;
256
+ if (typeof container.autoDiscover === "boolean") this.config.container.autoDiscover = container.autoDiscover;
257
+ }
205
258
  const override = options?.methodOverride;
206
259
  if (!override) return;
207
260
  if (typeof override.enabled === "boolean") this.config.methodOverride.enabled = override.enabled;
@@ -438,36 +491,94 @@ var CoreRouter = class {
438
491
  static resolveHandler(route) {
439
492
  let handlerFunction;
440
493
  let instance = null;
441
- if (typeof route.handler === "function") handlerFunction = route.handler.bind(route);
442
- else if (Array.isArray(route.handler) && route.handler.length === 2) {
494
+ let bindingTarget;
495
+ let bindingMethod;
496
+ let bindingHandler;
497
+ let bindingMetadata;
498
+ if (typeof route.handler === "function") {
499
+ handlerFunction = route.handler.bind(route);
500
+ bindingTarget = route.handler;
501
+ bindingHandler = route.handler;
502
+ } else if (Array.isArray(route.handler) && route.handler.length === 2) {
443
503
  const [ControllerType, method] = route.handler;
444
504
  if (["function", "object"].includes(typeof ControllerType) && typeof ControllerType[method] === "function") {
445
505
  instance = ControllerType;
446
506
  handlerFunction = ControllerType[method].bind(ControllerType);
507
+ bindingTarget = ControllerType;
508
+ bindingMethod = method;
509
+ bindingHandler = ControllerType[method];
510
+ bindingMetadata = ControllerType[Symbol.metadata];
447
511
  } else if (typeof ControllerType === "function") {
448
512
  instance = new ControllerType();
449
- if (typeof instance[method] === "function") handlerFunction = instance[method].bind(instance);
450
- else throw new Error(`Method "${method}" not found in controller instance "${ControllerType.name}"`);
513
+ if (typeof instance[method] === "function") {
514
+ handlerFunction = instance[method].bind(instance);
515
+ bindingTarget = ControllerType.prototype;
516
+ bindingMethod = method;
517
+ bindingHandler = instance[method];
518
+ bindingMetadata = ControllerType[Symbol.metadata];
519
+ } else throw new Error(`Method "${method}" not found in controller instance "${ControllerType.name}"`);
451
520
  } else throw new Error(`Invalid controller type for route: ${route.path}`);
452
521
  } else throw new Error(`Invalid handler format for route: ${route.path}`);
453
522
  return {
454
523
  handlerFunction,
455
- instance
524
+ instance,
525
+ bindingTarget,
526
+ bindingMethod,
527
+ bindingHandler,
528
+ bindingMetadata
456
529
  };
457
530
  }
531
+ static async callHandler(handlerFunction, ctx, bindingTarget, bindingMethod, bindingHandler, bindingMetadata) {
532
+ if (!this.config.container?.enabled) return handlerFunction(ctx, ctx.clearRequest);
533
+ const metadata = require_bindings.getBindingMetadataFromTargets([
534
+ {
535
+ target: bindingTarget,
536
+ propertyKey: bindingMethod
537
+ },
538
+ { target: bindingHandler },
539
+ {
540
+ target: bindingTarget,
541
+ propertyKey: "__class__"
542
+ }
543
+ ]) ?? require_bindings.getStandardMetadata(bindingMetadata, bindingMethod) ?? require_bindings.getStandardMetadata(bindingMetadata, "__class__");
544
+ if (!metadata) return handlerFunction(ctx, ctx.clearRequest);
545
+ const designTokens = [...bindingTarget ? require_bindings.getDesignParamTypes(bindingTarget, bindingMethod) : [], ...bindingHandler ? require_bindings.getDesignParamTypes(bindingHandler) : []];
546
+ const tokens = metadata.tokens?.length ? metadata.tokens : designTokens;
547
+ if (!tokens.length) return handlerFunction(ctx, ctx.clearRequest);
548
+ const args = [];
549
+ for (const token of tokens) {
550
+ const resolved = await require_bindings.Container.resolve(token, ctx, Boolean(this.config.container?.autoDiscover));
551
+ if (typeof resolved === "undefined") return handlerFunction(ctx, ctx.clearRequest);
552
+ args.push(resolved);
553
+ }
554
+ return handlerFunction(...args);
555
+ }
458
556
  static bindRequestToInstance(ctx, instance, route, payload) {
557
+ const clearRequest = ctx.clearRequest instanceof require_bindings.Request ? ctx.clearRequest : new require_bindings.Request({
558
+ ctx,
559
+ route,
560
+ body: payload.body,
561
+ query: payload.query,
562
+ params: payload.params,
563
+ method: String(payload.method || ctx.req?.method || ctx.method || "GET").toUpperCase(),
564
+ path: String(ctx.path || ctx.req?.path || ctx.req?.url || route.path),
565
+ url: String(ctx.url || ctx.req?.url || ctx.req?.originalUrl || route.path),
566
+ headers: ctx.req?.headers || ctx.headers || {},
567
+ original: ctx.req || ctx.request || ctx
568
+ });
569
+ clearRequest.ctx = ctx;
570
+ clearRequest.route = route;
571
+ clearRequest.body = payload.body;
572
+ clearRequest.query = payload.query;
573
+ clearRequest.params = payload.params;
574
+ ctx.clearRequest = clearRequest;
575
+ if (!(ctx.clearResponse instanceof require_bindings.Response)) ctx.clearResponse = new require_bindings.Response();
459
576
  if (!instance) return;
460
577
  instance.ctx = ctx;
461
578
  instance.body = payload.body;
462
579
  instance.query = payload.query;
463
580
  instance.params = payload.params;
464
- instance.clearRequest = new ClearRequest({
465
- ctx,
466
- route,
467
- body: instance.body,
468
- query: instance.query,
469
- params: instance.params
470
- });
581
+ instance.clearRequest = clearRequest;
471
582
  }
472
583
  };
473
584
 
@@ -1,7 +1,28 @@
1
+ import { a as BindValue, i as BindToken, o as Container } from "./bindings-CV1e5jho.mjs";
1
2
  import { AsyncLocalStorage } from "node:async_hooks";
2
3
  import { EventHandlerRequest, H3, H3Event, Middleware, TypedServerRequest } from "h3";
3
4
  import { NextFunction, Request, Response as Response$1 } from "express";
4
5
 
6
+ //#region src/core/Response.d.ts
7
+ declare class Response$2 {
8
+ body: any;
9
+ headers: Headers;
10
+ sent: boolean;
11
+ statusCode: number;
12
+ constructor(init?: Partial<Response$2>);
13
+ status(code: number): this;
14
+ code(code: number): this;
15
+ setHeader(name: string, value: string): this;
16
+ header(name: string, value: string): this;
17
+ set(name: string, value: string): this;
18
+ type(contentType: string): this;
19
+ send(body?: any): this;
20
+ json(body: any): this;
21
+ html(body: string): this;
22
+ text(body: string): this;
23
+ noContent(): this;
24
+ }
25
+ //#endregion
5
26
  //#region types/basic.d.ts
6
27
  /**
7
28
  * Controller method reference
@@ -30,6 +51,13 @@ interface RouterConfig {
30
51
  bodyKeys?: string[] | string; /** Keys in the request headers to check for method override */
31
52
  headerKeys?: string[] | string;
32
53
  };
54
+ /**
55
+ * Optional method binding / container resolution support. Disabled by default.
56
+ */
57
+ container?: {
58
+ /** Whether decorated handler parameter binding is enabled */enabled?: boolean; /** Whether unknown constructor tokens should be instantiated automatically */
59
+ autoDiscover?: boolean;
60
+ };
33
61
  }
34
62
  //#endregion
35
63
  //#region types/express.d.ts
@@ -43,6 +71,8 @@ interface HttpContext$1 {
43
71
  req: RequestWithGetBody;
44
72
  res: Response$1;
45
73
  next: NextFunction;
74
+ clearRequest: Request$1;
75
+ clearResponse: Response$2;
46
76
  }
47
77
  /**
48
78
  * Route handler function type
@@ -57,7 +87,7 @@ ctx: HttpContext$1,
57
87
  * ClearRequest instance
58
88
  */
59
89
 
60
- req: ClearRequest) => any | Promise<any>;
90
+ req: Request$1) => any | Promise<any>;
61
91
  /**
62
92
  * Handler can be either a function or controller reference
63
93
  */
@@ -80,6 +110,8 @@ type RequestlessH3Event = Omit<H3Event, 'req'>;
80
110
  */
81
111
  interface HttpContext extends RequestlessH3Event {
82
112
  req: HttpRequest;
113
+ clearRequest: Request$1;
114
+ clearResponse: Response$2;
83
115
  }
84
116
  /**
85
117
  * Route handler function type
@@ -94,7 +126,7 @@ ctx: HttpContext,
94
126
  * ClearRequest instance
95
127
  */
96
128
 
97
- req: ClearRequest) => any | Promise<any>;
129
+ req: Request$1) => any | Promise<any>;
98
130
  /**
99
131
  * Handler can be either a function or controller reference
100
132
  */
@@ -137,6 +169,43 @@ declare class ClearRequest<X = any, M = Middleware | Middleware$1> {
137
169
  constructor(init?: Partial<ClearRequest>);
138
170
  }
139
171
  //#endregion
172
+ //#region src/core/Request.d.ts
173
+ declare class Request$1<X = any, M = any> extends ClearRequest<X, M> {
174
+ original?: any;
175
+ method: string;
176
+ path: string;
177
+ url: string;
178
+ headers: Headers | Record<string, any>;
179
+ constructor(init?: Partial<Request$1<X, M>> & {
180
+ body?: RequestData;
181
+ query?: RequestData;
182
+ params?: RequestData;
183
+ route?: Route<X, M>;
184
+ });
185
+ getBody(): RequestData;
186
+ header(name: string): string;
187
+ param(name: string): any;
188
+ input(name: string): any;
189
+ is(method: HttpMethod | string): boolean;
190
+ }
191
+ //#endregion
192
+ //#region src/core/plugins.d.ts
193
+ type PluginSetupResult = void;
194
+ type PluginBind = <T>(token: BindToken<T>, value: BindValue<T>) => void;
195
+ interface ClearRouterPluginContext<Options = any> {
196
+ container: typeof Container;
197
+ bind: PluginBind;
198
+ configure: (options: RouterConfig) => void;
199
+ configureDefaults: (options: RouterConfig) => void;
200
+ options: Options;
201
+ }
202
+ interface ClearRouterPlugin<Options = any> {
203
+ name?: string;
204
+ setup: (ctx: ClearRouterPluginContext<Options>) => PluginSetupResult;
205
+ }
206
+ type ClearRouterPluginInput<Options = any> = ClearRouterPlugin<Options> | ((ctx: ClearRouterPluginContext<Options>) => PluginSetupResult);
207
+ declare function definePlugin<Options = any>(plugin: ClearRouterPlugin<Options>): ClearRouterPlugin<Options>;
208
+ //#endregion
140
209
  //#region src/Controller.d.ts
141
210
  declare abstract class Controller<X = any> {
142
211
  [x: string]: any;
@@ -158,16 +227,16 @@ declare abstract class CoreRouter {
158
227
  protected static routerStateNamespace: string;
159
228
  private static readonly stateStoreKey;
160
229
  private static readonly stateBoundKey;
230
+ private static readonly defaultConfigKey;
231
+ private static readonly pluginStoreKey;
232
+ protected static createBaseConfig(): RouterConfig;
233
+ protected static mergeConfig(target: RouterConfig, source?: RouterConfig): RouterConfig;
234
+ protected static getDefaultConfig(): RouterConfig;
161
235
  protected static resolveStateNamespace(this: any): string;
162
236
  protected static getStateStore(): Record<string, any>;
237
+ protected static getPluginStore(): Set<string>;
163
238
  protected static createDefaultState(): {
164
- config: {
165
- methodOverride: {
166
- enabled: boolean;
167
- bodyKeys: string[];
168
- headerKeys: string[];
169
- };
170
- };
239
+ config: RouterConfig;
171
240
  groupContext: AsyncLocalStorage<{
172
241
  prefix: string;
173
242
  groupMiddlewares: any[];
@@ -182,6 +251,16 @@ declare abstract class CoreRouter {
182
251
  protected static bindStateAccessors(this: any): void;
183
252
  protected static createDefaultOptionsHandler(): any;
184
253
  static config: RouterConfig;
254
+ static configureDefaults(this: any, options?: RouterConfig): void;
255
+ /**
256
+ * Use a registered plugin
257
+ *
258
+ * @param this
259
+ * @param plugin
260
+ * @param options
261
+ * @returns
262
+ */
263
+ static use<Options = any>(this: any, plugin: ClearRouterPluginInput<Options>, options?: Options): void;
185
264
  protected static groupContext: AsyncLocalStorage<{
186
265
  prefix: string;
187
266
  groupMiddlewares: any[];
@@ -331,14 +410,20 @@ declare abstract class CoreRouter {
331
410
  */
332
411
  static allRoutes(this: any, type: 'method'): { [method in Uppercase<HttpMethod>]?: Array<Route<any, any, any>> };
333
412
  protected static resolveHandler(route: Route<any, any, any>): {
334
- handlerFunction: ((ctx: any, req: ClearRequest) => any | Promise<any>) | null;
413
+ handlerFunction: ((ctx: any, req: Request$1) => any | Promise<any>) | null;
335
414
  instance: Controller<any> | null;
415
+ bindingTarget?: object;
416
+ bindingMethod?: PropertyKey;
417
+ bindingHandler?: object;
418
+ bindingMetadata?: object;
336
419
  };
420
+ 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
421
  protected static bindRequestToInstance(ctx: any, instance: Controller<any> | Route<any, any, any> | null, route: Route<any, any, any>, payload: {
338
422
  body: Record<string, any>;
339
423
  query: Record<string, any>;
340
424
  params: Record<string, any>;
425
+ method?: HttpMethod | string;
341
426
  }): void;
342
427
  }
343
428
  //#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, ClearRequest as n, HttpContext as o, ControllerHandler as p, Route as r, Middleware as s, CoreRouter as t, Middleware$1 as u };
429
+ export { ApiResourceMiddleware as _, PluginBind as a, HttpMethod as b, Request$1 as c, Handler as d, HttpContext as f, Middleware$1 as g, HttpContext$1 as h, ClearRouterPluginInput as i, Route as l, Handler$1 as m, ClearRouterPlugin as n, PluginSetupResult as o, Middleware as p, ClearRouterPluginContext as r, definePlugin as s, CoreRouter as t, H3App as u, ControllerAction as v, Response$2 as x, ControllerHandler as y };
@@ -26,6 +26,13 @@ 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
38
  export { ApiResourceMiddleware, ControllerAction, ControllerHandler, HttpMethod, RequestData, RouterConfig };
@@ -0,0 +1,25 @@
1
+ import { HttpMethod, RequestData } from "../../types/basic.mjs";
2
+ import { Route } from "../Route.mjs";
3
+ import { ClearRequest } from "../ClearRequest.mjs";
4
+
5
+ //#region src/core/Request.d.ts
6
+ declare class Request<X = any, M = any> extends ClearRequest<X, M> {
7
+ original?: any;
8
+ method: string;
9
+ path: string;
10
+ url: string;
11
+ headers: Headers | Record<string, any>;
12
+ constructor(init?: Partial<Request<X, M>> & {
13
+ body?: RequestData;
14
+ query?: RequestData;
15
+ params?: RequestData;
16
+ route?: Route<X, M>;
17
+ });
18
+ getBody(): RequestData;
19
+ header(name: string): string;
20
+ param(name: string): any;
21
+ input(name: string): any;
22
+ is(method: HttpMethod | string): boolean;
23
+ }
24
+ //#endregion
25
+ export { Request };
@@ -0,0 +1,21 @@
1
+ //#region src/core/Response.d.ts
2
+ declare class Response {
3
+ body: any;
4
+ headers: Headers;
5
+ sent: boolean;
6
+ statusCode: number;
7
+ constructor(init?: Partial<Response>);
8
+ status(code: number): this;
9
+ code(code: number): this;
10
+ setHeader(name: string, value: string): this;
11
+ header(name: string, value: string): this;
12
+ set(name: string, value: string): this;
13
+ type(contentType: string): this;
14
+ send(body?: any): this;
15
+ json(body: any): this;
16
+ html(body: string): this;
17
+ text(body: string): this;
18
+ noContent(): this;
19
+ }
20
+ //#endregion
21
+ export { Response };
@@ -1,5 +1,6 @@
1
1
  import { ControllerHandler } from "./basic.mjs";
2
- import { ClearRequest } from "./ClearRequest.mjs";
2
+ import { Response as Response$1 } from "./core/Response.mjs";
3
+ import { Request as Request$1 } from "./core/Request.mjs";
3
4
  import { NextFunction, Request, Response } from "express";
4
5
 
5
6
  //#region types/express.d.ts
@@ -13,6 +14,8 @@ interface HttpContext {
13
14
  req: RequestWithGetBody;
14
15
  res: Response;
15
16
  next: NextFunction;
17
+ clearRequest: Request$1;
18
+ clearResponse: Response$1;
16
19
  }
17
20
  /**
18
21
  * Route handler function type
@@ -27,7 +30,7 @@ ctx: HttpContext,
27
30
  * ClearRequest instance
28
31
  */
29
32
 
30
- req: ClearRequest) => any | Promise<any>;
33
+ req: Request$1) => any | Promise<any>;
31
34
  /**
32
35
  * Handler can be either a function or controller reference
33
36
  */
@@ -1,5 +1,6 @@
1
1
  import { ControllerHandler } from "./basic.mjs";
2
- import { ClearRequest } from "./ClearRequest.mjs";
2
+ import { Response } from "./core/Response.mjs";
3
+ import { Request } from "./core/Request.mjs";
3
4
  import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
4
5
 
5
6
  //#region types/fastify.d.ts
@@ -9,8 +10,10 @@ interface RequestWithGetBody extends FastifyRequest {
9
10
  interface HttpContext {
10
11
  req: RequestWithGetBody;
11
12
  reply: FastifyReply;
13
+ clearRequest: Request;
14
+ clearResponse: Response;
12
15
  }
13
- type RouteHandler = (ctx: HttpContext, req: ClearRequest) => any | Promise<any>;
16
+ type RouteHandler = (ctx: HttpContext, req: Request) => any | Promise<any>;
14
17
  type Handler = RouteHandler | ControllerHandler;
15
18
  type NextFunction = (err?: Error) => void;
16
19
  type Middleware = (req: RequestWithGetBody, reply: FastifyReply, next: NextFunction) => any | Promise<any>;
@@ -1,5 +1,6 @@
1
1
  import { ControllerHandler } from "./basic.mjs";
2
- import { ClearRequest } from "./ClearRequest.mjs";
2
+ import { Response as Response$1 } from "./core/Response.mjs";
3
+ import { Request } from "./core/Request.mjs";
3
4
  import { EventHandlerRequest, H3, H3Event, Middleware, TypedServerRequest } from "h3";
4
5
 
5
6
  //#region types/h3.d.ts
@@ -16,6 +17,8 @@ type RequestlessH3Event = Omit<H3Event, 'req'>;
16
17
  */
17
18
  interface HttpContext extends RequestlessH3Event {
18
19
  req: HttpRequest;
20
+ clearRequest: Request;
21
+ clearResponse: Response$1;
19
22
  }
20
23
  /**
21
24
  * Route handler function type
@@ -30,7 +33,7 @@ ctx: HttpContext,
30
33
  * ClearRequest instance
31
34
  */
32
35
 
33
- req: ClearRequest) => any | Promise<any>;
36
+ req: Request) => any | Promise<any>;
34
37
  /**
35
38
  * Handler can be either a function or controller reference
36
39
  */
@@ -1,5 +1,6 @@
1
1
  import { ControllerHandler } from "./basic.mjs";
2
- import { ClearRequest } from "./ClearRequest.mjs";
2
+ import { Response } from "./core/Response.mjs";
3
+ import { Request } from "./core/Request.mjs";
3
4
  import { Context, HonoRequest, MiddlewareHandler } from "hono";
4
5
 
5
6
  //#region types/hono.d.ts
@@ -8,8 +9,10 @@ type RequestWithGetBody = HonoRequest & {
8
9
  };
9
10
  type HttpContext = Context & {
10
11
  req: RequestWithGetBody;
12
+ clearRequest: Request;
13
+ clearResponse: Response;
11
14
  };
12
- type RouteHandler = (ctx: HttpContext, req: ClearRequest) => any | Promise<any>;
15
+ type RouteHandler = (ctx: HttpContext, req: Request) => any | Promise<any>;
13
16
  type Handler = RouteHandler | ControllerHandler;
14
17
  type NextFunction = () => Promise<void>;
15
18
  type Middleware = MiddlewareHandler;
@@ -1,5 +1,6 @@
1
1
  import { ControllerHandler } from "./basic.mjs";
2
- import { ClearRequest } from "./ClearRequest.mjs";
2
+ import { Response } from "./core/Response.mjs";
3
+ import { Request } from "./core/Request.mjs";
3
4
  import Koa from "koa";
4
5
  import Router from "@koa/router";
5
6
 
@@ -10,10 +11,12 @@ interface RequestWithGetBody extends Koa.Request {
10
11
  }
11
12
  interface HttpContext extends Koa.Context {
12
13
  request: RequestWithGetBody;
14
+ clearRequest: Request;
15
+ clearResponse: Response;
13
16
  params: Record<string, any>;
14
17
  query: Record<string, any>;
15
18
  }
16
- type RouteHandler = (ctx: HttpContext, req: ClearRequest) => any | Promise<any>;
19
+ type RouteHandler = (ctx: HttpContext, req: Request) => any | Promise<any>;
17
20
  type Handler = RouteHandler | ControllerHandler;
18
21
  type NextFunction = Koa.Next;
19
22
  type Middleware = Koa.Middleware<any, any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clear-router",
3
- "version": "2.5.4",
3
+ "version": "2.5.6",
4
4
  "description": "Laravel-style routing for Node.js with support for Express, H3, Fastify, Hono, and Koa, including CommonJS, ESM, and TypeScript support.",
5
5
  "keywords": [
6
6
  "h3",
@@ -40,6 +40,14 @@
40
40
  "import": "./dist/core/index.mjs",
41
41
  "require": "./dist/core/index.cjs"
42
42
  },
43
+ "./decorators": {
44
+ "import": "./dist/decorators/index.mjs",
45
+ "require": "./dist/decorators/index.cjs"
46
+ },
47
+ "./decorators/setup": {
48
+ "import": "./dist/decorators/setup.mjs",
49
+ "require": "./dist/decorators/setup.cjs"
50
+ },
43
51
  "./express": {
44
52
  "import": "./dist/express/index.mjs",
45
53
  "require": "./dist/express/index.cjs"
@@ -79,7 +87,8 @@
79
87
  "fastify": "^5.0.0",
80
88
  "h3": "^2.0.1-rc.16",
81
89
  "hono": "^4.0.0",
82
- "koa": "^3.0.0"
90
+ "koa": "^3.0.0",
91
+ "reflect-metadata": "^0.2.2"
83
92
  },
84
93
  "peerDependenciesMeta": {
85
94
  "@koa/router": {
@@ -99,6 +108,9 @@
99
108
  },
100
109
  "koa": {
101
110
  "optional": true
111
+ },
112
+ "reflect-metadata": {
113
+ "optional": true
102
114
  }
103
115
  },
104
116
  "devDependencies": {
@@ -115,10 +127,12 @@
115
127
  "hono": "^4.12.8",
116
128
  "koa": "^3.2.0",
117
129
  "parasito": "^0.1.6",
130
+ "reflect-metadata": "^0.2.2",
118
131
  "tsdown": "^0.20.3",
119
132
  "tsx": "^4.21.0",
120
133
  "typescript": "^5.3.3",
121
134
  "typescript-eslint": "^8.56.1",
135
+ "unrun": "0.2.27",
122
136
  "vite-tsconfig-paths": "^6.1.1",
123
137
  "vitepress": "^1.6.4",
124
138
  "vitest": "^4.0.18"