@velajs/vela 0.4.3 → 0.5.1
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/dist/cache/cache.module.d.ts +4 -1
- package/dist/cache/cache.module.js +51 -9
- package/dist/config/config.module.d.ts +4 -1
- package/dist/config/config.module.js +40 -3
- package/dist/config/config.types.d.ts +1 -0
- package/dist/constants.d.ts +8 -2
- package/dist/constants.js +6 -0
- package/dist/container/container.d.ts +2 -0
- package/dist/container/container.js +51 -16
- package/dist/container/decorators.d.ts +3 -1
- package/dist/container/decorators.js +27 -6
- package/dist/container/index.d.ts +4 -2
- package/dist/container/index.js +4 -2
- package/dist/container/mixin.d.ts +24 -0
- package/dist/container/mixin.js +26 -0
- package/dist/container/module-ref.d.ts +21 -0
- package/dist/container/module-ref.js +48 -0
- package/dist/container/types.d.ts +9 -3
- package/dist/container/types.js +9 -0
- package/dist/cors/cors.module.js +2 -2
- package/dist/errors/http-exception.d.ts +20 -20
- package/dist/errors/http-exception.js +47 -41
- package/dist/factory.js +11 -2
- package/dist/fetch/fetch.module.d.ts +6 -0
- package/dist/fetch/fetch.module.js +77 -0
- package/dist/fetch/fetch.service.d.ts +24 -0
- package/dist/fetch/fetch.service.js +145 -0
- package/dist/fetch/fetch.types.d.ts +24 -0
- package/dist/fetch/fetch.types.js +1 -0
- package/dist/fetch/index.d.ts +3 -0
- package/dist/fetch/index.js +2 -0
- package/dist/health/health.service.js +2 -2
- package/dist/http/decorators.d.ts +65 -0
- package/dist/http/decorators.js +91 -2
- package/dist/http/index.d.ts +3 -1
- package/dist/http/index.js +2 -1
- package/dist/http/middleware-consumer.d.ts +36 -0
- package/dist/http/middleware-consumer.js +71 -0
- package/dist/http/route.manager.d.ts +4 -0
- package/dist/http/route.manager.js +91 -6
- package/dist/http/types.d.ts +1 -0
- package/dist/index.d.ts +11 -6
- package/dist/index.js +7 -4
- package/dist/metadata.d.ts +1 -1
- package/dist/module/decorators.d.ts +1 -0
- package/dist/module/decorators.js +24 -8
- package/dist/module/index.d.ts +2 -2
- package/dist/module/index.js +1 -1
- package/dist/module/module-loader.d.ts +5 -1
- package/dist/module/module-loader.js +54 -10
- package/dist/module/types.d.ts +13 -3
- package/dist/pipeline/index.d.ts +3 -2
- package/dist/pipeline/index.js +1 -1
- package/dist/pipeline/pipes.d.ts +22 -0
- package/dist/pipeline/pipes.js +50 -0
- package/dist/pipeline/tokens.d.ts +1 -1
- package/dist/pipeline/tokens.js +1 -1
- package/dist/pipeline/types.d.ts +16 -0
- package/dist/registry/metadata.registry.d.ts +7 -6
- package/dist/registry/metadata.registry.js +13 -0
- package/dist/registry/types.d.ts +1 -0
- package/dist/schedule/schedule.module.d.ts +4 -1
- package/dist/schedule/schedule.module.js +39 -7
- package/dist/testing/testing.builder.js +5 -5
- package/dist/throttler/throttler.module.d.ts +2 -1
- package/dist/throttler/throttler.module.js +47 -9
- package/dist/validation/validation.pipe.js +1 -1
- package/package.json +1 -1
|
@@ -38,12 +38,60 @@ export declare const Patch: (path?: string) => MethodDecorator;
|
|
|
38
38
|
export declare const Delete: (path?: string) => MethodDecorator;
|
|
39
39
|
export declare const Options: (path?: string) => MethodDecorator;
|
|
40
40
|
export declare const Head: (path?: string) => MethodDecorator;
|
|
41
|
+
export declare const All: (path?: string) => MethodDecorator;
|
|
41
42
|
export declare const Sse: (path?: string) => MethodDecorator;
|
|
42
43
|
export declare const Param: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
43
44
|
export declare const Query: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
44
45
|
export declare const Body: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
45
46
|
export declare const Headers: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
46
47
|
export declare const Req: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
48
|
+
/**
|
|
49
|
+
* Injects the Hono `Context` as the response handle.
|
|
50
|
+
* In Hono, request and response state are unified in the `Context` object,
|
|
51
|
+
* so `@Res()` and `@Req()` both return it.
|
|
52
|
+
*
|
|
53
|
+
* Use `c.header()`, `c.setCookie()`, `c.redirect()`, etc. for response control.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* @Get('/set-cookie')
|
|
58
|
+
* handle(@Res() c: Context) {
|
|
59
|
+
* c.setCookie('session', 'abc123', { httpOnly: true });
|
|
60
|
+
* return { ok: true };
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const Res: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
65
|
+
export declare const Ip: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
66
|
+
export declare const Cookie: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
67
|
+
/**
|
|
68
|
+
* Injects all cookies as a `Record<string, string>`, or a single cookie value by name.
|
|
69
|
+
*
|
|
70
|
+
* - `@Cookie()` — all cookies as an object
|
|
71
|
+
* - `@Cookie('token')` — the value of the `token` cookie
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* @Get('/me')
|
|
76
|
+
* handle(@Cookie('session') session: string) { ... }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare const Cookies: (nameOrPipe?: string | PipeType, ...pipes: PipeType[]) => ParameterDecorator;
|
|
80
|
+
/**
|
|
81
|
+
* Injects the raw request body as a `Uint8Array`.
|
|
82
|
+
* Useful for webhook HMAC verification (Stripe, GitHub, etc.) where you
|
|
83
|
+
* need the raw bytes before any JSON parsing.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* @Post('/webhook')
|
|
88
|
+
* async handle(@RawBody() body: Uint8Array) {
|
|
89
|
+
* const sig = new TextDecoder().decode(body);
|
|
90
|
+
* // verify HMAC...
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function RawBody(): ParameterDecorator;
|
|
47
95
|
/**
|
|
48
96
|
* Factory for creating custom parameter decorators.
|
|
49
97
|
*
|
|
@@ -120,4 +168,21 @@ export declare function getRedirect(target: Constructor, method: string | symbol
|
|
|
120
168
|
url: string;
|
|
121
169
|
statusCode: number;
|
|
122
170
|
} | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Composes multiple decorators into one. Applies them in order (top to bottom),
|
|
173
|
+
* matching how stacked decorators behave when written separately.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* const Auth = (...roles: string[]) => applyDecorators(
|
|
178
|
+
* UseGuards(JwtGuard, RolesGuard),
|
|
179
|
+
* SetMetadata('roles', roles),
|
|
180
|
+
* );
|
|
181
|
+
*
|
|
182
|
+
* @Auth('admin')
|
|
183
|
+
* @Get('/admin')
|
|
184
|
+
* handle() { ... }
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
export declare function applyDecorators(...decorators: Array<ClassDecorator | MethodDecorator | PropertyDecorator | ParameterDecorator>): ClassDecorator & MethodDecorator & PropertyDecorator;
|
|
123
188
|
export declare function isController(target: Constructor): boolean;
|
package/dist/http/decorators.js
CHANGED
|
@@ -22,7 +22,7 @@ function normalizePath(path) {
|
|
|
22
22
|
if (typeof prefixOrOptions === 'string') {
|
|
23
23
|
prefix = prefixOrOptions;
|
|
24
24
|
} else if (prefixOrOptions) {
|
|
25
|
-
prefix = prefixOrOptions.prefix ?? '';
|
|
25
|
+
prefix = prefixOrOptions.path ?? prefixOrOptions.prefix ?? '';
|
|
26
26
|
version = prefixOrOptions.version;
|
|
27
27
|
} else {
|
|
28
28
|
prefix = '';
|
|
@@ -96,6 +96,7 @@ export const Patch = createMethodDecorator(HttpMethod.PATCH);
|
|
|
96
96
|
export const Delete = createMethodDecorator(HttpMethod.DELETE);
|
|
97
97
|
export const Options = createMethodDecorator(HttpMethod.OPTIONS);
|
|
98
98
|
export const Head = createMethodDecorator(HttpMethod.HEAD);
|
|
99
|
+
export const All = createMethodDecorator(HttpMethod.ALL);
|
|
99
100
|
export const Sse = createMethodDecorator(HttpMethod.GET);
|
|
100
101
|
// Parameter decorators
|
|
101
102
|
const CUSTOM_PARAM_TYPE = 'custom';
|
|
@@ -136,6 +137,60 @@ export const Query = createBuiltinParamDecorator(ParamType.QUERY);
|
|
|
136
137
|
export const Body = createBuiltinParamDecorator(ParamType.BODY);
|
|
137
138
|
export const Headers = createBuiltinParamDecorator(ParamType.HEADERS);
|
|
138
139
|
export const Req = createBuiltinParamDecorator(ParamType.REQUEST);
|
|
140
|
+
/**
|
|
141
|
+
* Injects the Hono `Context` as the response handle.
|
|
142
|
+
* In Hono, request and response state are unified in the `Context` object,
|
|
143
|
+
* so `@Res()` and `@Req()` both return it.
|
|
144
|
+
*
|
|
145
|
+
* Use `c.header()`, `c.setCookie()`, `c.redirect()`, etc. for response control.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* @Get('/set-cookie')
|
|
150
|
+
* handle(@Res() c: Context) {
|
|
151
|
+
* c.setCookie('session', 'abc123', { httpOnly: true });
|
|
152
|
+
* return { ok: true };
|
|
153
|
+
* }
|
|
154
|
+
* ```
|
|
155
|
+
*/ export const Res = createBuiltinParamDecorator(ParamType.RESPONSE);
|
|
156
|
+
export const Ip = createBuiltinParamDecorator(ParamType.IP);
|
|
157
|
+
export const Cookie = createBuiltinParamDecorator(ParamType.COOKIE);
|
|
158
|
+
/**
|
|
159
|
+
* Injects all cookies as a `Record<string, string>`, or a single cookie value by name.
|
|
160
|
+
*
|
|
161
|
+
* - `@Cookie()` — all cookies as an object
|
|
162
|
+
* - `@Cookie('token')` — the value of the `token` cookie
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* @Get('/me')
|
|
167
|
+
* handle(@Cookie('session') session: string) { ... }
|
|
168
|
+
* ```
|
|
169
|
+
*/ export const Cookies = Cookie;
|
|
170
|
+
/**
|
|
171
|
+
* Injects the raw request body as a `Uint8Array`.
|
|
172
|
+
* Useful for webhook HMAC verification (Stripe, GitHub, etc.) where you
|
|
173
|
+
* need the raw bytes before any JSON parsing.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* @Post('/webhook')
|
|
178
|
+
* async handle(@RawBody() body: Uint8Array) {
|
|
179
|
+
* const sig = new TextDecoder().decode(body);
|
|
180
|
+
* // verify HMAC...
|
|
181
|
+
* }
|
|
182
|
+
* ```
|
|
183
|
+
*/ export function RawBody() {
|
|
184
|
+
return (target, propertyKey, parameterIndex)=>{
|
|
185
|
+
if (propertyKey === undefined) {
|
|
186
|
+
throw new Error('Parameter decorators can only be used on method parameters');
|
|
187
|
+
}
|
|
188
|
+
MetadataRegistry.addParameter(target.constructor, propertyKey, {
|
|
189
|
+
index: parameterIndex,
|
|
190
|
+
type: ParamType.RAW_BODY
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
}
|
|
139
194
|
/**
|
|
140
195
|
* Factory for creating custom parameter decorators.
|
|
141
196
|
*
|
|
@@ -175,10 +230,15 @@ export const Req = createBuiltinParamDecorator(ParamType.REQUEST);
|
|
|
175
230
|
factory: (_unused, ctx)=>{
|
|
176
231
|
const honoCtx = ctx;
|
|
177
232
|
const execCtx = {
|
|
233
|
+
getType: ()=>'http',
|
|
178
234
|
getClass: ()=>target.constructor,
|
|
179
235
|
getHandler: ()=>propertyKey,
|
|
180
236
|
getContext: ()=>honoCtx,
|
|
181
|
-
getRequest: ()=>honoCtx.req.raw
|
|
237
|
+
getRequest: ()=>honoCtx.req.raw,
|
|
238
|
+
switchToHttp: ()=>({
|
|
239
|
+
getRequest: ()=>honoCtx.req.raw,
|
|
240
|
+
getResponse: ()=>honoCtx
|
|
241
|
+
})
|
|
182
242
|
};
|
|
183
243
|
return factory(data, execCtx);
|
|
184
244
|
},
|
|
@@ -271,6 +331,35 @@ export function getRedirect(target, method) {
|
|
|
271
331
|
if (meta?.redirect) return meta.redirect;
|
|
272
332
|
return getMetadata(METADATA_KEYS.REDIRECT, target, method);
|
|
273
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Composes multiple decorators into one. Applies them in order (top to bottom),
|
|
336
|
+
* matching how stacked decorators behave when written separately.
|
|
337
|
+
*
|
|
338
|
+
* @example
|
|
339
|
+
* ```ts
|
|
340
|
+
* const Auth = (...roles: string[]) => applyDecorators(
|
|
341
|
+
* UseGuards(JwtGuard, RolesGuard),
|
|
342
|
+
* SetMetadata('roles', roles),
|
|
343
|
+
* );
|
|
344
|
+
*
|
|
345
|
+
* @Auth('admin')
|
|
346
|
+
* @Get('/admin')
|
|
347
|
+
* handle() { ... }
|
|
348
|
+
* ```
|
|
349
|
+
*/ export function applyDecorators(...decorators) {
|
|
350
|
+
const composed = (target, propertyKey, descriptor)=>{
|
|
351
|
+
for (const decorator of decorators){
|
|
352
|
+
if (propertyKey === undefined && typeof descriptor !== 'number') {
|
|
353
|
+
decorator(target);
|
|
354
|
+
} else if (typeof descriptor === 'number') {
|
|
355
|
+
decorator(target, propertyKey, descriptor);
|
|
356
|
+
} else {
|
|
357
|
+
decorator(target, propertyKey, descriptor);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
return composed;
|
|
362
|
+
}
|
|
274
363
|
// Helpers
|
|
275
364
|
export function isController(target) {
|
|
276
365
|
return MetadataRegistry.getControllerPath(target) !== '' || MetadataRegistry.getRoutes(target).length > 0;
|
package/dist/http/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { RouteManager } from './route.manager';
|
|
2
|
-
export {
|
|
2
|
+
export { MiddlewareBuilder, RequestMethod } from './middleware-consumer';
|
|
3
|
+
export type { MiddlewareConsumer, MiddlewareConfigProxy, RouteInfo, NestModule, MiddlewareRouteDefinition } from './middleware-consumer';
|
|
4
|
+
export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, All, Sse, Param, Query, Body, Headers, Req, Res, Ip, Cookie, Cookies, RawBody, HttpCode, Header, Redirect, createParamDecorator, applyDecorators, isController, } from './decorators';
|
|
3
5
|
export type { RouteMetadata, ControllerMetadata, ControllerOptions, ParamMetadata, ControllerRegistration, } from './types';
|
package/dist/http/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { RouteManager } from "./route.manager.js";
|
|
2
|
-
export {
|
|
2
|
+
export { MiddlewareBuilder, RequestMethod } from "./middleware-consumer.js";
|
|
3
|
+
export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, All, Sse, Param, Query, Body, Headers, Req, Res, Ip, Cookie, Cookies, RawBody, HttpCode, Header, Redirect, createParamDecorator, applyDecorators, isController } from "./decorators.js";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { NestMiddleware } from '../pipeline/types';
|
|
2
|
+
import type { Type } from '../registry/types';
|
|
3
|
+
export declare enum RequestMethod {
|
|
4
|
+
GET = "GET",
|
|
5
|
+
POST = "POST",
|
|
6
|
+
PUT = "PUT",
|
|
7
|
+
DELETE = "DELETE",
|
|
8
|
+
PATCH = "PATCH",
|
|
9
|
+
OPTIONS = "OPTIONS",
|
|
10
|
+
HEAD = "HEAD",
|
|
11
|
+
ALL = "ALL"
|
|
12
|
+
}
|
|
13
|
+
export interface RouteInfo {
|
|
14
|
+
path: string;
|
|
15
|
+
method?: RequestMethod;
|
|
16
|
+
}
|
|
17
|
+
export interface MiddlewareRouteDefinition {
|
|
18
|
+
middleware: Array<Type<NestMiddleware> | NestMiddleware>;
|
|
19
|
+
routes: RouteInfo[];
|
|
20
|
+
excludes: RouteInfo[];
|
|
21
|
+
}
|
|
22
|
+
export interface MiddlewareConfigProxy {
|
|
23
|
+
exclude(...routes: Array<string | RouteInfo>): MiddlewareConfigProxy;
|
|
24
|
+
forRoutes(...routes: Array<string | Function | RouteInfo>): MiddlewareConsumer;
|
|
25
|
+
}
|
|
26
|
+
export interface MiddlewareConsumer {
|
|
27
|
+
apply(...middleware: Array<Type<NestMiddleware> | NestMiddleware>): MiddlewareConfigProxy;
|
|
28
|
+
}
|
|
29
|
+
export interface NestModule {
|
|
30
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
31
|
+
}
|
|
32
|
+
export declare class MiddlewareBuilder implements MiddlewareConsumer {
|
|
33
|
+
private definitions;
|
|
34
|
+
apply(...middleware: Array<Type<NestMiddleware> | NestMiddleware>): MiddlewareConfigProxy;
|
|
35
|
+
getDefinitions(): MiddlewareRouteDefinition[];
|
|
36
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MetadataRegistry } from "../registry/metadata.registry.js";
|
|
2
|
+
export var RequestMethod = /*#__PURE__*/ function(RequestMethod) {
|
|
3
|
+
RequestMethod["GET"] = "GET";
|
|
4
|
+
RequestMethod["POST"] = "POST";
|
|
5
|
+
RequestMethod["PUT"] = "PUT";
|
|
6
|
+
RequestMethod["DELETE"] = "DELETE";
|
|
7
|
+
RequestMethod["PATCH"] = "PATCH";
|
|
8
|
+
RequestMethod["OPTIONS"] = "OPTIONS";
|
|
9
|
+
RequestMethod["HEAD"] = "HEAD";
|
|
10
|
+
RequestMethod["ALL"] = "ALL";
|
|
11
|
+
return RequestMethod;
|
|
12
|
+
}({});
|
|
13
|
+
export class MiddlewareBuilder {
|
|
14
|
+
definitions = [];
|
|
15
|
+
apply(...middleware) {
|
|
16
|
+
const currentMiddleware = [
|
|
17
|
+
...middleware
|
|
18
|
+
];
|
|
19
|
+
let currentExcludes = [];
|
|
20
|
+
const proxy = {
|
|
21
|
+
exclude: (...routes)=>{
|
|
22
|
+
currentExcludes = routes.map(normalizeRouteArg);
|
|
23
|
+
return proxy;
|
|
24
|
+
},
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
26
|
+
forRoutes: (...routes)=>{
|
|
27
|
+
this.definitions.push({
|
|
28
|
+
middleware: currentMiddleware,
|
|
29
|
+
routes: routes.flatMap(resolveRouteArg),
|
|
30
|
+
excludes: [
|
|
31
|
+
...currentExcludes
|
|
32
|
+
]
|
|
33
|
+
});
|
|
34
|
+
currentExcludes = [];
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
return proxy;
|
|
39
|
+
}
|
|
40
|
+
getDefinitions() {
|
|
41
|
+
return [
|
|
42
|
+
...this.definitions
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function normalizeRouteArg(route) {
|
|
47
|
+
return typeof route === 'string' ? {
|
|
48
|
+
path: route
|
|
49
|
+
} : route;
|
|
50
|
+
}
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
52
|
+
function resolveRouteArg(route) {
|
|
53
|
+
if (typeof route === 'string') {
|
|
54
|
+
return [
|
|
55
|
+
{
|
|
56
|
+
path: route
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
if (typeof route === 'function') {
|
|
61
|
+
const prefix = MetadataRegistry.getControllerPath(route);
|
|
62
|
+
return [
|
|
63
|
+
{
|
|
64
|
+
path: prefix || '/'
|
|
65
|
+
}
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
return [
|
|
69
|
+
route
|
|
70
|
+
];
|
|
71
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import type { Container } from '../container/container';
|
|
3
3
|
import type { Token, Type } from '../container/types';
|
|
4
|
+
import type { MiddlewareRouteDefinition } from './middleware-consumer';
|
|
4
5
|
import type { CanActivate, ExceptionFilter, NestInterceptor, NestMiddleware, PipeTransform } from '../pipeline/types';
|
|
5
6
|
import type { FilterType, GuardType, InterceptorType, MiddlewareType, PipeType } from '../registry/types';
|
|
6
7
|
import type { ControllerRegistration } from './types';
|
|
@@ -13,7 +14,9 @@ export declare class RouteManager {
|
|
|
13
14
|
private globalInterceptors;
|
|
14
15
|
private globalFilters;
|
|
15
16
|
private globalPrefix;
|
|
17
|
+
private consumerMiddlewareDefinitions;
|
|
16
18
|
constructor(container: Container);
|
|
19
|
+
registerConsumerMiddleware(definitions: MiddlewareRouteDefinition[]): this;
|
|
17
20
|
setGlobalPrefix(prefix: string): this;
|
|
18
21
|
useGlobalMiddleware(...middleware: MiddlewareType[]): this;
|
|
19
22
|
useGlobalMiddlewareTokens(...middlewareTokens: Array<Token<NestMiddleware>>): this;
|
|
@@ -38,5 +41,6 @@ export declare class RouteManager {
|
|
|
38
41
|
private registerRoute;
|
|
39
42
|
private buildVersionedPaths;
|
|
40
43
|
private joinPaths;
|
|
44
|
+
private matchesConsumerPath;
|
|
41
45
|
getControllers(): ControllerRegistration[];
|
|
42
46
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
2
|
import { HttpMethod, ParamType } from "../constants.js";
|
|
3
3
|
import { getMetadata } from "../metadata.js";
|
|
4
|
+
import { RequestMethod } from "./middleware-consumer.js";
|
|
4
5
|
import { ForbiddenException, HttpException } from "../errors/http-exception.js";
|
|
5
6
|
import { ComponentManager } from "../pipeline/component.manager.js";
|
|
6
7
|
import { shouldFilterCatch } from "../pipeline/decorators.js";
|
|
@@ -27,9 +28,14 @@ export class RouteManager {
|
|
|
27
28
|
globalInterceptors = [];
|
|
28
29
|
globalFilters = [];
|
|
29
30
|
globalPrefix = '';
|
|
31
|
+
consumerMiddlewareDefinitions = [];
|
|
30
32
|
constructor(container){
|
|
31
33
|
this.container = container;
|
|
32
34
|
}
|
|
35
|
+
registerConsumerMiddleware(definitions) {
|
|
36
|
+
this.consumerMiddlewareDefinitions.push(...definitions);
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
33
39
|
setGlobalPrefix(prefix) {
|
|
34
40
|
this.globalPrefix = prefix && !prefix.startsWith('/') ? `/${prefix}` : prefix;
|
|
35
41
|
return this;
|
|
@@ -125,6 +131,37 @@ export class RouteManager {
|
|
|
125
131
|
return resolved.use(c, next);
|
|
126
132
|
});
|
|
127
133
|
}
|
|
134
|
+
// Register MiddlewareConsumer-configured middleware
|
|
135
|
+
for (const def of this.consumerMiddlewareDefinitions){
|
|
136
|
+
app.use('*', (c, next)=>{
|
|
137
|
+
const reqPath = c.req.path;
|
|
138
|
+
const reqMethod = c.req.method;
|
|
139
|
+
const matches = def.routes.some((route)=>{
|
|
140
|
+
if (!this.matchesConsumerPath(reqPath, route.path)) return false;
|
|
141
|
+
if (route.method && route.method !== RequestMethod.ALL) {
|
|
142
|
+
if (reqMethod !== route.method) return false;
|
|
143
|
+
}
|
|
144
|
+
return true;
|
|
145
|
+
});
|
|
146
|
+
if (!matches) return next();
|
|
147
|
+
const excluded = def.excludes.some((exclude)=>{
|
|
148
|
+
if (!this.matchesConsumerPath(reqPath, exclude.path)) return false;
|
|
149
|
+
if (exclude.method && exclude.method !== RequestMethod.ALL) {
|
|
150
|
+
if (reqMethod !== exclude.method) return false;
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
});
|
|
154
|
+
if (excluded) return next();
|
|
155
|
+
const requestContainer = this.getRequestContainer(c);
|
|
156
|
+
const runChain = (index)=>{
|
|
157
|
+
if (index >= def.middleware.length) return next();
|
|
158
|
+
const instance = this.instantiate(def.middleware[index], requestContainer);
|
|
159
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
160
|
+
return instance.use(c, ()=>runChain(index + 1)).then(()=>{});
|
|
161
|
+
};
|
|
162
|
+
return runChain(0);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
128
165
|
// First pass: register all custom routes (must come before CRUD /:id routes)
|
|
129
166
|
for (const { controller, metadata, routes } of this.controllers){
|
|
130
167
|
if (routes.length > 0) {
|
|
@@ -171,10 +208,15 @@ export class RouteManager {
|
|
|
171
208
|
}
|
|
172
209
|
createExecutionContext(c, controller, route) {
|
|
173
210
|
return {
|
|
211
|
+
getType: ()=>'http',
|
|
174
212
|
getClass: ()=>controller,
|
|
175
213
|
getHandler: ()=>route.handlerName,
|
|
176
214
|
getContext: ()=>c,
|
|
177
|
-
getRequest: ()=>c.req.raw
|
|
215
|
+
getRequest: ()=>c.req.raw,
|
|
216
|
+
switchToHttp: ()=>({
|
|
217
|
+
getRequest: ()=>c.req.raw,
|
|
218
|
+
getResponse: ()=>c
|
|
219
|
+
})
|
|
178
220
|
};
|
|
179
221
|
}
|
|
180
222
|
createHandler(route, controller, allParamMetadata) {
|
|
@@ -310,10 +352,17 @@ export class RouteManager {
|
|
|
310
352
|
case ParamType.QUERY:
|
|
311
353
|
return param.name ? c.req.query(param.name) : c.req.query();
|
|
312
354
|
case ParamType.BODY:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
355
|
+
{
|
|
356
|
+
let body;
|
|
357
|
+
try {
|
|
358
|
+
body = await c.req.json();
|
|
359
|
+
} catch {
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
if (param.name && body !== null && typeof body === 'object') {
|
|
363
|
+
return body[param.name];
|
|
364
|
+
}
|
|
365
|
+
return body;
|
|
317
366
|
}
|
|
318
367
|
case ParamType.HEADERS:
|
|
319
368
|
if (param.name) {
|
|
@@ -326,6 +375,28 @@ export class RouteManager {
|
|
|
326
375
|
return headers;
|
|
327
376
|
case ParamType.REQUEST:
|
|
328
377
|
return c;
|
|
378
|
+
case ParamType.RESPONSE:
|
|
379
|
+
return c;
|
|
380
|
+
case ParamType.IP:
|
|
381
|
+
return c.req.raw.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? c.req.raw.headers.get('x-real-ip') ?? null;
|
|
382
|
+
case ParamType.COOKIE:
|
|
383
|
+
{
|
|
384
|
+
const cookieHeader = c.req.raw.headers.get('cookie') ?? '';
|
|
385
|
+
const cookies = {};
|
|
386
|
+
for (const pair of cookieHeader.split(';')){
|
|
387
|
+
const eqIdx = pair.indexOf('=');
|
|
388
|
+
if (eqIdx === -1) continue;
|
|
389
|
+
const name = pair.slice(0, eqIdx).trim();
|
|
390
|
+
const value = pair.slice(eqIdx + 1).trim();
|
|
391
|
+
if (name) cookies[name] = decodeURIComponent(value);
|
|
392
|
+
}
|
|
393
|
+
return param.name ? cookies[param.name] ?? undefined : cookies;
|
|
394
|
+
}
|
|
395
|
+
case ParamType.RAW_BODY:
|
|
396
|
+
{
|
|
397
|
+
const buffer = await c.req.arrayBuffer();
|
|
398
|
+
return new Uint8Array(buffer);
|
|
399
|
+
}
|
|
329
400
|
default:
|
|
330
401
|
// Custom param decorator — use factory if available
|
|
331
402
|
if (param.factory) {
|
|
@@ -368,7 +439,11 @@ export class RouteManager {
|
|
|
368
439
|
app.options(normalizedPath, handler);
|
|
369
440
|
break;
|
|
370
441
|
case HttpMethod.HEAD:
|
|
371
|
-
|
|
442
|
+
// Hono converts HEAD to GET internally, so register as GET
|
|
443
|
+
app.get(normalizedPath, handler);
|
|
444
|
+
break;
|
|
445
|
+
case HttpMethod.ALL:
|
|
446
|
+
app.all(normalizedPath, handler);
|
|
372
447
|
break;
|
|
373
448
|
default:
|
|
374
449
|
app.on(method.toUpperCase(), normalizedPath, handler);
|
|
@@ -393,6 +468,16 @@ export class RouteManager {
|
|
|
393
468
|
const cleanPath = path && !path.startsWith('/') ? `/${path}` : path;
|
|
394
469
|
return `${cleanPrefix}${cleanPath}` || '/';
|
|
395
470
|
}
|
|
471
|
+
matchesConsumerPath(reqPath, routePath) {
|
|
472
|
+
if (routePath === '*') return true;
|
|
473
|
+
const normalized = routePath.startsWith('/') ? routePath : `/${routePath}`;
|
|
474
|
+
if (reqPath === normalized) return true;
|
|
475
|
+
if (reqPath.startsWith(`${normalized}/`)) return true;
|
|
476
|
+
if (normalized.endsWith('*')) {
|
|
477
|
+
return reqPath.startsWith(normalized.slice(0, -1));
|
|
478
|
+
}
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
396
481
|
getControllers() {
|
|
397
482
|
return [
|
|
398
483
|
...this.controllers
|
package/dist/http/types.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -2,14 +2,16 @@ import './metadata';
|
|
|
2
2
|
export { defineMetadata, getMetadata } from './metadata';
|
|
3
3
|
export { VelaFactory } from './factory';
|
|
4
4
|
export { VelaApplication } from './application';
|
|
5
|
-
export { Container, Injectable, Inject, InjectionToken } from './container/index';
|
|
5
|
+
export { Container, Injectable, Inject, Optional, InjectionToken, ForwardRef, forwardRef, ModuleRef, mixin } from './container/index';
|
|
6
6
|
export type { Type, Token, InjectableOptions, ProviderOptions, } from './container/index';
|
|
7
7
|
export { METADATA_KEYS, HttpMethod, ParamType, Scope } from './constants';
|
|
8
|
-
export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, Sse, Param, Query, Body, Headers, Req, HttpCode, Header, Redirect, createParamDecorator, } from './http/index';
|
|
8
|
+
export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, All, Sse, Param, Query, Body, Headers, Req, Res, Ip, Cookie, Cookies, RawBody, HttpCode, Header, Redirect, createParamDecorator, applyDecorators, } from './http/index';
|
|
9
9
|
export { Logger, LogLevel } from './services/index';
|
|
10
10
|
export type { LoggerService } from './services/index';
|
|
11
11
|
export { ConfigModule, ConfigService, CONFIG_OPTIONS } from './config/index';
|
|
12
12
|
export type { ConfigModuleOptions } from './config/index';
|
|
13
|
+
export { HttpModule, HttpService, HTTP_MODULE_OPTIONS, HttpRequestException } from './fetch/index';
|
|
14
|
+
export type { HttpModuleOptions, HttpResponse, HttpRequestConfig } from './fetch/index';
|
|
13
15
|
export { CorsModule, CORS_OPTIONS } from './cors/index';
|
|
14
16
|
export type { CorsOptions } from './cors/index';
|
|
15
17
|
export { CacheModule, CacheService, CacheInterceptor, MemoryCacheStore, CacheKey, CacheTTL, CACHE_MANAGER, CACHE_MODULE_OPTIONS, CACHE_KEY_METADATA, CACHE_TTL_METADATA, } from './cache/index';
|
|
@@ -22,12 +24,15 @@ export { HealthModule, HealthCheckService, HealthIndicatorService, HttpHealthInd
|
|
|
22
24
|
export type { HealthCheckResult, HealthCheckStatus, HealthIndicatorResult, HealthIndicatorFunction, ResponseCheckCallback, HttpPingOptions, } from './health/index';
|
|
23
25
|
export { ThrottlerModule, ThrottlerGuard, ThrottlerStorage, Throttle, SkipThrottle, THROTTLER_OPTIONS, THROTTLER_STORAGE, THROTTLE_METADATA, SKIP_THROTTLE_METADATA, } from './throttler/index';
|
|
24
26
|
export type { ThrottlerModuleOptions, ThrottleConfig, ThrottlerStore, ThrottlerStorageRecord, RateLimitInfo, } from './throttler/index';
|
|
25
|
-
export { Module } from './module/index';
|
|
26
|
-
export type { ModuleOptions, DynamicModule } from './module/index';
|
|
27
|
+
export { Global, Module } from './module/index';
|
|
28
|
+
export type { ModuleOptions, DynamicModule, AsyncModuleOptions, ModuleImport } from './module/index';
|
|
29
|
+
export { RequestMethod } from './http/index';
|
|
30
|
+
export type { MiddlewareConsumer, NestModule, RouteInfo } from './http/index';
|
|
27
31
|
export { UseMiddleware, UseGuards, UsePipes, UseInterceptors, UseFilters, Catch, SetMetadata, Reflector, APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER, APP_MIDDLEWARE, } from './pipeline/index';
|
|
28
|
-
export type { ExecutionContext, CanActivate, CallHandler, NestInterceptor, NestMiddleware, PipeTransform, ExceptionFilter, ArgumentMetadata, ReflectableDecorator, CreateDecoratorOptions, } from './pipeline/index';
|
|
32
|
+
export type { HttpArgumentsHost, ExecutionContext, CanActivate, CallHandler, NestInterceptor, NestMiddleware, PipeTransform, ExceptionFilter, ArgumentMetadata, ReflectableDecorator, CreateDecoratorOptions, } from './pipeline/index';
|
|
29
33
|
export type { Constructor, MiddlewareType, GuardType, PipeType, InterceptorType, FilterType, } from './registry/index';
|
|
30
|
-
export { ParseIntPipe, ParseFloatPipe, ParseBoolPipe, DefaultValuePipe, RequiredPipe, ZodValidationPipe, } from './pipeline/index';
|
|
34
|
+
export { ParseIntPipe, ParseFloatPipe, ParseBoolPipe, ParseUUIDPipe, ParseEnumPipe, ParseArrayPipe, DefaultValuePipe, RequiredPipe, ZodValidationPipe, } from './pipeline/index';
|
|
35
|
+
export type { ParseUUIDPipeOptions, ParseArrayPipeOptions } from './pipeline/index';
|
|
31
36
|
export { HttpException, BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, MethodNotAllowedException, NotAcceptableException, RequestTimeoutException, ConflictException, GoneException, PayloadTooLargeException, UnsupportedMediaTypeException, UnprocessableEntityException, TooManyRequestsException, InternalServerErrorException, NotImplementedException, BadGatewayException, ServiceUnavailableException, GatewayTimeoutException, } from './errors/index';
|
|
32
37
|
export type { OnModuleInit, OnApplicationBootstrap, OnModuleDestroy, OnApplicationShutdown, BeforeApplicationShutdown, } from './lifecycle/index';
|
|
33
38
|
export { MetadataRegistry } from './registry/index';
|
package/dist/index.js
CHANGED
|
@@ -4,15 +4,17 @@ export { defineMetadata, getMetadata } from "./metadata.js";
|
|
|
4
4
|
export { VelaFactory } from "./factory.js";
|
|
5
5
|
export { VelaApplication } from "./application.js";
|
|
6
6
|
// DI Container
|
|
7
|
-
export { Container, Injectable, Inject, InjectionToken } from "./container/index.js";
|
|
7
|
+
export { Container, Injectable, Inject, Optional, InjectionToken, ForwardRef, forwardRef, ModuleRef, mixin } from "./container/index.js";
|
|
8
8
|
// Constants
|
|
9
9
|
export { METADATA_KEYS, HttpMethod, ParamType, Scope } from "./constants.js";
|
|
10
10
|
// HTTP Decorators
|
|
11
|
-
export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, Sse, Param, Query, Body, Headers, Req, HttpCode, Header, Redirect, createParamDecorator } from "./http/index.js";
|
|
11
|
+
export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, All, Sse, Param, Query, Body, Headers, Req, Res, Ip, Cookie, Cookies, RawBody, HttpCode, Header, Redirect, createParamDecorator, applyDecorators } from "./http/index.js";
|
|
12
12
|
// Services
|
|
13
13
|
export { Logger, LogLevel } from "./services/index.js";
|
|
14
14
|
// Config
|
|
15
15
|
export { ConfigModule, ConfigService, CONFIG_OPTIONS } from "./config/index.js";
|
|
16
|
+
// HTTP Client
|
|
17
|
+
export { HttpModule, HttpService, HTTP_MODULE_OPTIONS, HttpRequestException } from "./fetch/index.js";
|
|
16
18
|
// CORS
|
|
17
19
|
export { CorsModule, CORS_OPTIONS } from "./cors/index.js";
|
|
18
20
|
// Cache
|
|
@@ -26,11 +28,12 @@ export { HealthModule, HealthCheckService, HealthIndicatorService, HttpHealthInd
|
|
|
26
28
|
// Throttler
|
|
27
29
|
export { ThrottlerModule, ThrottlerGuard, ThrottlerStorage, Throttle, SkipThrottle, THROTTLER_OPTIONS, THROTTLER_STORAGE, THROTTLE_METADATA, SKIP_THROTTLE_METADATA } from "./throttler/index.js";
|
|
28
30
|
// Module
|
|
29
|
-
export { Module } from "./module/index.js";
|
|
31
|
+
export { Global, Module } from "./module/index.js";
|
|
32
|
+
export { RequestMethod } from "./http/index.js";
|
|
30
33
|
// Pipeline Decorators
|
|
31
34
|
export { UseMiddleware, UseGuards, UsePipes, UseInterceptors, UseFilters, Catch, SetMetadata, Reflector, APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER, APP_MIDDLEWARE } from "./pipeline/index.js";
|
|
32
35
|
// Built-in Pipes
|
|
33
|
-
export { ParseIntPipe, ParseFloatPipe, ParseBoolPipe, DefaultValuePipe, RequiredPipe, ZodValidationPipe } from "./pipeline/index.js";
|
|
36
|
+
export { ParseIntPipe, ParseFloatPipe, ParseBoolPipe, ParseUUIDPipe, ParseEnumPipe, ParseArrayPipe, DefaultValuePipe, RequiredPipe, ZodValidationPipe } from "./pipeline/index.js";
|
|
34
37
|
// Errors
|
|
35
38
|
export { HttpException, BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, MethodNotAllowedException, NotAcceptableException, RequestTimeoutException, ConflictException, GoneException, PayloadTooLargeException, UnsupportedMediaTypeException, UnprocessableEntityException, TooManyRequestsException, InternalServerErrorException, NotImplementedException, BadGatewayException, ServiceUnavailableException, GatewayTimeoutException } from "./errors/index.js";
|
|
36
39
|
// Registry (for advanced usage)
|
package/dist/metadata.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ declare global {
|
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
export declare function defineMetadata(key: string, value: unknown, target: object, propertyKey?: string | symbol): void;
|
|
10
|
-
export declare function getMetadata(key: string, target: object, propertyKey?: string | symbol):
|
|
10
|
+
export declare function getMetadata<T = unknown>(key: string, target: object, propertyKey?: string | symbol): T | undefined;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Constructor } from '../registry/types';
|
|
2
2
|
import type { ModuleMetadata, ModuleOptions } from './types';
|
|
3
|
+
export declare function Global(): ClassDecorator;
|
|
3
4
|
export declare function Module(options?: ModuleOptions): ClassDecorator;
|
|
4
5
|
export declare function isModule(target: Constructor): boolean;
|
|
5
6
|
export declare function getModuleMetadata(target: Constructor): ModuleMetadata | undefined;
|