@velajs/vela 0.2.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +84 -0
  4. package/dist/application.d.ts +44 -0
  5. package/dist/application.js +112 -0
  6. package/dist/constants.d.ts +35 -0
  7. package/dist/constants.js +43 -0
  8. package/dist/container/container.d.ts +25 -0
  9. package/dist/container/container.js +195 -0
  10. package/dist/container/decorators.d.ts +8 -0
  11. package/dist/container/decorators.js +36 -0
  12. package/dist/container/index.d.ts +4 -0
  13. package/dist/container/index.js +3 -0
  14. package/dist/container/types.d.ts +37 -0
  15. package/dist/container/types.js +11 -0
  16. package/dist/errors/http-exception.d.ts +61 -0
  17. package/dist/errors/http-exception.js +128 -0
  18. package/dist/errors/index.d.ts +1 -0
  19. package/dist/errors/index.js +1 -0
  20. package/dist/factory.d.ts +5 -0
  21. package/dist/factory.js +39 -0
  22. package/dist/http/decorators.d.ts +122 -0
  23. package/dist/http/decorators.js +276 -0
  24. package/dist/http/index.d.ts +3 -0
  25. package/dist/http/index.js +2 -0
  26. package/dist/http/route.manager.d.ts +34 -0
  27. package/dist/http/route.manager.js +373 -0
  28. package/dist/http/types.d.ts +29 -0
  29. package/dist/http/types.js +1 -0
  30. package/dist/index.d.ts +20 -0
  31. package/dist/index.js +26 -0
  32. package/dist/lifecycle/index.d.ts +20 -0
  33. package/dist/lifecycle/index.js +15 -0
  34. package/dist/metadata.d.ts +10 -0
  35. package/dist/metadata.js +29 -0
  36. package/dist/module/decorators.d.ts +5 -0
  37. package/dist/module/decorators.js +32 -0
  38. package/dist/module/index.d.ts +3 -0
  39. package/dist/module/index.js +2 -0
  40. package/dist/module/module-loader.d.ts +20 -0
  41. package/dist/module/module-loader.js +159 -0
  42. package/dist/module/types.d.ts +19 -0
  43. package/dist/module/types.js +1 -0
  44. package/dist/pipeline/component.manager.d.ts +18 -0
  45. package/dist/pipeline/component.manager.js +105 -0
  46. package/dist/pipeline/decorators.d.ts +10 -0
  47. package/dist/pipeline/decorators.js +50 -0
  48. package/dist/pipeline/index.d.ts +7 -0
  49. package/dist/pipeline/index.js +5 -0
  50. package/dist/pipeline/pipes.d.ts +25 -0
  51. package/dist/pipeline/pipes.js +52 -0
  52. package/dist/pipeline/reflector.d.ts +102 -0
  53. package/dist/pipeline/reflector.js +166 -0
  54. package/dist/pipeline/tokens.d.ts +33 -0
  55. package/dist/pipeline/tokens.js +27 -0
  56. package/dist/pipeline/types.d.ts +31 -0
  57. package/dist/pipeline/types.js +1 -0
  58. package/dist/registry/index.d.ts +2 -0
  59. package/dist/registry/index.js +1 -0
  60. package/dist/registry/metadata.registry.d.ts +61 -0
  61. package/dist/registry/metadata.registry.js +276 -0
  62. package/dist/registry/types.d.ts +55 -0
  63. package/dist/registry/types.js +2 -0
  64. package/package.json +72 -0
@@ -0,0 +1,166 @@
1
+ import { getMetadata as internalGetMetadata } from "../metadata.js";
2
+ import { MetadataRegistry } from "../registry/metadata.registry.js";
3
+ const SET_METADATA_KEY = 'vela:metadata';
4
+ let _decoratorKeyCounter = 0;
5
+ /**
6
+ * Decorator that attaches custom metadata to a class or method.
7
+ * Read via Reflector in guards/interceptors.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const Roles = (...roles: string[]) => SetMetadata('roles', roles);
12
+ *
13
+ * @Controller('/admin')
14
+ * @Roles('admin')
15
+ * class AdminController { ... }
16
+ * ```
17
+ */ export function SetMetadata(key, value) {
18
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
19
+ return (target, propertyKey)=>{
20
+ if (propertyKey !== undefined) {
21
+ // Method decorator
22
+ MetadataRegistry.setCustomHandlerMeta(target.constructor, propertyKey, key, value);
23
+ } else {
24
+ // Class decorator
25
+ MetadataRegistry.setCustomClassMeta(target, key, value);
26
+ }
27
+ };
28
+ }
29
+ /**
30
+ * Reads custom metadata set by @SetMetadata().
31
+ * Use in guards/interceptors via ExecutionContext.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * class RolesGuard implements CanActivate {
36
+ * private reflector = new Reflector();
37
+ *
38
+ * canActivate(context: ExecutionContext): boolean {
39
+ * const roles = this.reflector.get<string[]>('roles', context);
40
+ * if (!roles) return true;
41
+ * const user = ...; // extract from request
42
+ * return roles.some(r => user.roles.includes(r));
43
+ * }
44
+ * }
45
+ * ```
46
+ */ export class Reflector {
47
+ /**
48
+ * Create a type-safe decorator that sets metadata with a typed key.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const Roles = Reflector.createDecorator<string[]>();
53
+ * // Roles(['admin']) — class or method decorator
54
+ * // reflector.get(Roles, context) — typed as string[] | undefined
55
+ * ```
56
+ */ static createDecorator(options) {
57
+ const key = options?.key ?? `vela:custom:${_decoratorKeyCounter++}`;
58
+ const decorator = (value)=>SetMetadata(key, value);
59
+ decorator.KEY = key;
60
+ return decorator;
61
+ }
62
+ resolveKey(keyOrDecorator) {
63
+ return typeof keyOrDecorator === 'string' ? keyOrDecorator : keyOrDecorator.KEY;
64
+ }
65
+ /**
66
+ * Get metadata value from handler first, then class.
67
+ * Handler-level metadata takes priority over class-level.
68
+ */ get(key, context) {
69
+ const resolvedKey = this.resolveKey(key);
70
+ // Check handler-level first (MetadataRegistry)
71
+ const handlerValue = MetadataRegistry.getCustomHandlerMeta(context.getClass(), context.getHandler(), resolvedKey);
72
+ if (handlerValue !== undefined) {
73
+ return handlerValue;
74
+ }
75
+ // Check class-level (MetadataRegistry)
76
+ const classValue = MetadataRegistry.getCustomClassMeta(context.getClass(), resolvedKey);
77
+ if (classValue !== undefined) {
78
+ return classValue;
79
+ }
80
+ // Fallback to WeakMap for external package compat
81
+ const handlerMeta = internalGetMetadata(SET_METADATA_KEY, context.getClass(), context.getHandler());
82
+ if (handlerMeta?.has(resolvedKey)) {
83
+ return handlerMeta.get(resolvedKey);
84
+ }
85
+ const classMeta = internalGetMetadata(SET_METADATA_KEY, context.getClass());
86
+ if (classMeta?.has(resolvedKey)) {
87
+ return classMeta.get(resolvedKey);
88
+ }
89
+ return undefined;
90
+ }
91
+ /**
92
+ * Get metadata only from the handler (method) level.
93
+ */ getHandler(key, context) {
94
+ const resolvedKey = this.resolveKey(key);
95
+ // MetadataRegistry first
96
+ const value = MetadataRegistry.getCustomHandlerMeta(context.getClass(), context.getHandler(), resolvedKey);
97
+ if (value !== undefined) {
98
+ return value;
99
+ }
100
+ // Fallback to WeakMap
101
+ const meta = internalGetMetadata(SET_METADATA_KEY, context.getClass(), context.getHandler());
102
+ return meta?.get(resolvedKey);
103
+ }
104
+ /**
105
+ * Get metadata only from the class level.
106
+ */ getClass(key, context) {
107
+ const resolvedKey = this.resolveKey(key);
108
+ // MetadataRegistry first
109
+ const value = MetadataRegistry.getCustomClassMeta(context.getClass(), resolvedKey);
110
+ if (value !== undefined) {
111
+ return value;
112
+ }
113
+ // Fallback to WeakMap
114
+ const meta = internalGetMetadata(SET_METADATA_KEY, context.getClass());
115
+ return meta?.get(resolvedKey);
116
+ }
117
+ /**
118
+ * Get all metadata values for a key from both handler and class.
119
+ * Returns [handlerValue, classValue] (either may be undefined).
120
+ */ getAll(key, context) {
121
+ return [
122
+ this.getHandler(key, context),
123
+ this.getClass(key, context)
124
+ ];
125
+ }
126
+ /**
127
+ * Returns handler value if defined, else class value, else undefined.
128
+ * First defined value wins.
129
+ */ getAllAndOverride(key, context) {
130
+ const handlerValue = this.getHandler(key, context);
131
+ if (handlerValue !== undefined) {
132
+ return handlerValue;
133
+ }
134
+ return this.getClass(key, context);
135
+ }
136
+ /**
137
+ * Collects handler + class values, filters undefineds.
138
+ * - 0 values → []
139
+ * - 1 value → return it
140
+ * - Arrays → concatenate
141
+ * - Objects → Object.assign({}, ...values)
142
+ * - Otherwise → wrap in array
143
+ */ getAllAndMerge(key, context) {
144
+ const [handlerValue, classValue] = this.getAll(key, context);
145
+ const values = [];
146
+ if (handlerValue !== undefined) values.push(handlerValue);
147
+ if (classValue !== undefined) values.push(classValue);
148
+ if (values.length === 0) {
149
+ return [];
150
+ }
151
+ if (values.length === 1) {
152
+ return values[0];
153
+ }
154
+ // Both defined — merge strategy depends on type
155
+ if (Array.isArray(values[0]) && Array.isArray(values[1])) {
156
+ return [
157
+ ...values[0],
158
+ ...values[1]
159
+ ];
160
+ }
161
+ if (typeof values[0] === 'object' && values[0] !== null && !Array.isArray(values[0]) && typeof values[1] === 'object' && values[1] !== null && !Array.isArray(values[1])) {
162
+ return Object.assign({}, values[0], values[1]);
163
+ }
164
+ return values;
165
+ }
166
+ }
@@ -0,0 +1,33 @@
1
+ import { InjectionToken } from '../container/types';
2
+ import type { CanActivate, ExceptionFilter, NestInterceptor, NestMiddleware, PipeTransform } from './types';
3
+ /**
4
+ * Register global guards via module providers instead of app.useGlobalGuards().
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * @Module({
9
+ * providers: [
10
+ * AuthGuard,
11
+ * { token: APP_GUARD, useClass: AuthGuard },
12
+ * ],
13
+ * })
14
+ * class AppModule {}
15
+ * ```
16
+ */
17
+ export declare const APP_GUARD: InjectionToken<CanActivate>;
18
+ /**
19
+ * Register global pipes via module providers.
20
+ */
21
+ export declare const APP_PIPE: InjectionToken<PipeTransform<unknown, unknown>>;
22
+ /**
23
+ * Register global interceptors via module providers.
24
+ */
25
+ export declare const APP_INTERCEPTOR: InjectionToken<NestInterceptor>;
26
+ /**
27
+ * Register global filters via module providers.
28
+ */
29
+ export declare const APP_FILTER: InjectionToken<ExceptionFilter<unknown>>;
30
+ /**
31
+ * Register global middleware via module providers.
32
+ */
33
+ export declare const APP_MIDDLEWARE: InjectionToken<NestMiddleware>;
@@ -0,0 +1,27 @@
1
+ import { InjectionToken } from "../container/types.js";
2
+ /**
3
+ * Register global guards via module providers instead of app.useGlobalGuards().
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * @Module({
8
+ * providers: [
9
+ * AuthGuard,
10
+ * { token: APP_GUARD, useClass: AuthGuard },
11
+ * ],
12
+ * })
13
+ * class AppModule {}
14
+ * ```
15
+ */ export const APP_GUARD = new InjectionToken('APP_GUARD');
16
+ /**
17
+ * Register global pipes via module providers.
18
+ */ export const APP_PIPE = new InjectionToken('APP_PIPE');
19
+ /**
20
+ * Register global interceptors via module providers.
21
+ */ export const APP_INTERCEPTOR = new InjectionToken('APP_INTERCEPTOR');
22
+ /**
23
+ * Register global filters via module providers.
24
+ */ export const APP_FILTER = new InjectionToken('APP_FILTER');
25
+ /**
26
+ * Register global middleware via module providers.
27
+ */ export const APP_MIDDLEWARE = new InjectionToken('APP_MIDDLEWARE');
@@ -0,0 +1,31 @@
1
+ import type { Context } from 'hono';
2
+ import type { Type } from '../container/types';
3
+ export interface ExecutionContext {
4
+ getClass(): Type;
5
+ getHandler(): string | symbol;
6
+ getContext<T = Context>(): T;
7
+ getRequest(): Request;
8
+ }
9
+ export interface CanActivate {
10
+ canActivate(context: ExecutionContext): boolean | Promise<boolean>;
11
+ }
12
+ export interface CallHandler {
13
+ handle(): Promise<unknown>;
14
+ }
15
+ export interface NestInterceptor {
16
+ intercept(context: ExecutionContext, next: CallHandler): Promise<unknown>;
17
+ }
18
+ export interface ArgumentMetadata {
19
+ type: string;
20
+ metatype?: Type;
21
+ data?: string;
22
+ }
23
+ export interface PipeTransform<T = unknown, R = unknown> {
24
+ transform(value: T, metadata: ArgumentMetadata): R | Promise<R>;
25
+ }
26
+ export interface ExceptionFilter<T = unknown> {
27
+ catch(exception: T, context: ExecutionContext): unknown | Promise<unknown>;
28
+ }
29
+ export interface NestMiddleware {
30
+ use(c: import('hono').Context, next: import('hono').Next): Promise<Response | void>;
31
+ }
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,2 @@
1
+ export { MetadataRegistry } from './metadata.registry';
2
+ export type { Type, Constructor, ComponentType, ComponentTypeMap, ComponentInstance, MiddlewareType, GuardType, PipeType, InterceptorType, FilterType, RouteDefinition, ParameterMetadata, ModuleOptions, ProviderOptions, InjectionTokenLike, } from './types';
@@ -0,0 +1 @@
1
+ export { MetadataRegistry } from "./metadata.registry.js";
@@ -0,0 +1,61 @@
1
+ import type { Scope } from '../constants';
2
+ import type { InjectMetadata } from '../container/types';
3
+ import type { Type } from '../container/types';
4
+ import type { ComponentType, ComponentTypeMap, Constructor, HttpHandlerMeta, ModuleOptions, ParameterMetadata, RouteDefinition } from './types';
5
+ export interface ControllerOptions {
6
+ version?: number | number[];
7
+ }
8
+ export declare class MetadataRegistry {
9
+ private static readonly routes;
10
+ private static readonly controllers;
11
+ private static readonly controllerOptions;
12
+ private static readonly modules;
13
+ private static readonly parameters;
14
+ private static readonly global;
15
+ private static readonly controller;
16
+ private static readonly handler;
17
+ private static readonly injectables;
18
+ private static readonly scopes;
19
+ private static readonly injectTokens;
20
+ private static readonly handlerHttpMeta;
21
+ private static readonly catchTypes;
22
+ private static readonly routeVersions;
23
+ private static readonly customClassMeta;
24
+ private static readonly customHandlerMeta;
25
+ static getRoutes(controller: Constructor): RouteDefinition[];
26
+ static addRoute(controller: Constructor, route: RouteDefinition): void;
27
+ static getControllerPath(controller: Constructor): string;
28
+ static setControllerPath(controller: Constructor, path: string): void;
29
+ static getControllerOptions(controller: Constructor): ControllerOptions;
30
+ static setControllerOptions(controller: Constructor, options: ControllerOptions): void;
31
+ static getModuleOptions(module: Constructor): ModuleOptions | undefined;
32
+ static setModuleOptions(module: Constructor, options: ModuleOptions): void;
33
+ static getParameters(controller: Constructor): Map<string | symbol, ParameterMetadata[]>;
34
+ static addParameter(controller: Constructor, methodName: string | symbol, param: ParameterMetadata): void;
35
+ static registerGlobal<T extends ComponentType>(type: T, component: ComponentTypeMap[T]): void;
36
+ static getGlobal<T extends ComponentType>(type: T): Set<ComponentTypeMap[T]>;
37
+ static registerController<T extends ComponentType>(type: T, controller: Constructor, component: ComponentTypeMap[T]): void;
38
+ static getController<T extends ComponentType>(type: T, controller: Constructor): ComponentTypeMap[T][];
39
+ static registerHandler<T extends ComponentType>(type: T, handlerKey: string, component: ComponentTypeMap[T]): void;
40
+ static getHandler<T extends ComponentType>(type: T, handlerKey: string): ComponentTypeMap[T][];
41
+ static markInjectable(target: Constructor): void;
42
+ static hasInjectable(target: Constructor): boolean;
43
+ static setScope(target: Constructor, scope: Scope): void;
44
+ static getScope(target: Constructor): Scope | undefined;
45
+ static setInjectTokens(target: Constructor, tokens: InjectMetadata[]): void;
46
+ static getInjectTokens(target: Constructor): InjectMetadata[] | undefined;
47
+ static setHandlerHttpMeta(controller: Constructor, method: string | symbol, meta: HttpHandlerMeta): void;
48
+ static getHandlerHttpMeta(controller: Constructor, method: string | symbol): HttpHandlerMeta | undefined;
49
+ static setCatchTypes(filter: Constructor, types: Type<Error>[]): void;
50
+ static getCatchTypes(filter: Constructor): Type<Error>[] | undefined;
51
+ static hasCatchTypes(filter: Constructor): boolean;
52
+ static setRouteVersion(controller: Constructor, method: string | symbol, version: number | number[]): void;
53
+ static getRouteVersion(controller: Constructor, method: string | symbol): number | number[] | undefined;
54
+ static setCustomClassMeta(target: Constructor, key: string, value: unknown): void;
55
+ static getCustomClassMeta(target: Constructor, key: string): unknown;
56
+ static getCustomClassMetaAll(target: Constructor): Map<string, unknown> | undefined;
57
+ static setCustomHandlerMeta(target: Constructor, handler: string | symbol, key: string, value: unknown): void;
58
+ static getCustomHandlerMeta(target: Constructor, handler: string | symbol, key: string): unknown;
59
+ static getCustomHandlerMetaAll(target: Constructor, handler: string | symbol): Map<string, unknown> | undefined;
60
+ static clear(): void;
61
+ }
@@ -0,0 +1,276 @@
1
+ export class MetadataRegistry {
2
+ static routes = new Map();
3
+ static controllers = new Map();
4
+ static controllerOptions = new Map();
5
+ static modules = new Map();
6
+ static parameters = new Map();
7
+ // 3-level component hierarchy
8
+ static global = new Map([
9
+ [
10
+ 'middleware',
11
+ new Set()
12
+ ],
13
+ [
14
+ 'guard',
15
+ new Set()
16
+ ],
17
+ [
18
+ 'pipe',
19
+ new Set()
20
+ ],
21
+ [
22
+ 'interceptor',
23
+ new Set()
24
+ ],
25
+ [
26
+ 'filter',
27
+ new Set()
28
+ ]
29
+ ]);
30
+ static controller = new Map([
31
+ [
32
+ 'middleware',
33
+ new Map()
34
+ ],
35
+ [
36
+ 'guard',
37
+ new Map()
38
+ ],
39
+ [
40
+ 'pipe',
41
+ new Map()
42
+ ],
43
+ [
44
+ 'interceptor',
45
+ new Map()
46
+ ],
47
+ [
48
+ 'filter',
49
+ new Map()
50
+ ]
51
+ ]);
52
+ static handler = new Map([
53
+ [
54
+ 'middleware',
55
+ new Map()
56
+ ],
57
+ [
58
+ 'guard',
59
+ new Map()
60
+ ],
61
+ [
62
+ 'pipe',
63
+ new Map()
64
+ ],
65
+ [
66
+ 'interceptor',
67
+ new Map()
68
+ ],
69
+ [
70
+ 'filter',
71
+ new Map()
72
+ ]
73
+ ]);
74
+ // DI metadata
75
+ static injectables = new Set();
76
+ static scopes = new Map();
77
+ static injectTokens = new Map();
78
+ // HTTP handler metadata
79
+ static handlerHttpMeta = new Map();
80
+ // Exception filter types
81
+ static catchTypes = new Map();
82
+ // Route versions
83
+ static routeVersions = new Map();
84
+ // Custom metadata (SetMetadata)
85
+ static customClassMeta = new Map();
86
+ static customHandlerMeta = new Map();
87
+ // Routes
88
+ static getRoutes(controller) {
89
+ return this.routes.get(controller) || [];
90
+ }
91
+ static addRoute(controller, route) {
92
+ if (!this.routes.has(controller)) {
93
+ this.routes.set(controller, []);
94
+ }
95
+ this.routes.get(controller).push(route);
96
+ }
97
+ // Controllers
98
+ static getControllerPath(controller) {
99
+ return this.controllers.get(controller) || '';
100
+ }
101
+ static setControllerPath(controller, path) {
102
+ this.controllers.set(controller, path);
103
+ }
104
+ static getControllerOptions(controller) {
105
+ return this.controllerOptions.get(controller) || {};
106
+ }
107
+ static setControllerOptions(controller, options) {
108
+ this.controllerOptions.set(controller, options);
109
+ }
110
+ // Modules
111
+ static getModuleOptions(module) {
112
+ return this.modules.get(module);
113
+ }
114
+ static setModuleOptions(module, options) {
115
+ this.modules.set(module, options);
116
+ }
117
+ // Parameters
118
+ static getParameters(controller) {
119
+ return this.parameters.get(controller) || new Map();
120
+ }
121
+ static addParameter(controller, methodName, param) {
122
+ if (!this.parameters.has(controller)) {
123
+ this.parameters.set(controller, new Map());
124
+ }
125
+ const methodParams = this.parameters.get(controller);
126
+ if (!methodParams.has(methodName)) {
127
+ methodParams.set(methodName, []);
128
+ }
129
+ methodParams.get(methodName).push(param);
130
+ }
131
+ // Component registration — 3 levels
132
+ static registerGlobal(type, component) {
133
+ this.global.get(type).add(component);
134
+ }
135
+ static getGlobal(type) {
136
+ return this.global.get(type);
137
+ }
138
+ static registerController(type, controller, component) {
139
+ const typeMap = this.controller.get(type);
140
+ if (!typeMap.has(controller)) {
141
+ typeMap.set(controller, []);
142
+ }
143
+ typeMap.get(controller).push(component);
144
+ }
145
+ static getController(type, controller) {
146
+ const typeMap = this.controller.get(type);
147
+ return typeMap.get(controller) || [];
148
+ }
149
+ static registerHandler(type, handlerKey, component) {
150
+ const typeMap = this.handler.get(type);
151
+ if (!typeMap.has(handlerKey)) {
152
+ typeMap.set(handlerKey, []);
153
+ }
154
+ typeMap.get(handlerKey).push(component);
155
+ }
156
+ static getHandler(type, handlerKey) {
157
+ const typeMap = this.handler.get(type);
158
+ return typeMap.get(handlerKey) || [];
159
+ }
160
+ // DI metadata
161
+ static markInjectable(target) {
162
+ this.injectables.add(target);
163
+ }
164
+ static hasInjectable(target) {
165
+ return this.injectables.has(target);
166
+ }
167
+ static setScope(target, scope) {
168
+ this.scopes.set(target, scope);
169
+ }
170
+ static getScope(target) {
171
+ return this.scopes.get(target);
172
+ }
173
+ static setInjectTokens(target, tokens) {
174
+ this.injectTokens.set(target, tokens);
175
+ }
176
+ static getInjectTokens(target) {
177
+ return this.injectTokens.get(target);
178
+ }
179
+ // HTTP handler metadata
180
+ static setHandlerHttpMeta(controller, method, meta) {
181
+ if (!this.handlerHttpMeta.has(controller)) {
182
+ this.handlerHttpMeta.set(controller, new Map());
183
+ }
184
+ const methodMap = this.handlerHttpMeta.get(controller);
185
+ const existing = methodMap.get(method) ?? {};
186
+ // Append-merge responseHeaders
187
+ const merged = {
188
+ ...existing,
189
+ ...meta
190
+ };
191
+ if (meta.responseHeaders) {
192
+ merged.responseHeaders = [
193
+ ...existing.responseHeaders ?? [],
194
+ ...meta.responseHeaders
195
+ ];
196
+ }
197
+ methodMap.set(method, merged);
198
+ }
199
+ static getHandlerHttpMeta(controller, method) {
200
+ return this.handlerHttpMeta.get(controller)?.get(method);
201
+ }
202
+ // Exception filter types
203
+ static setCatchTypes(filter, types) {
204
+ this.catchTypes.set(filter, types);
205
+ }
206
+ static getCatchTypes(filter) {
207
+ return this.catchTypes.get(filter);
208
+ }
209
+ static hasCatchTypes(filter) {
210
+ return this.catchTypes.has(filter);
211
+ }
212
+ // Route versions
213
+ static setRouteVersion(controller, method, version) {
214
+ if (!this.routeVersions.has(controller)) {
215
+ this.routeVersions.set(controller, new Map());
216
+ }
217
+ this.routeVersions.get(controller).set(method, version);
218
+ }
219
+ static getRouteVersion(controller, method) {
220
+ return this.routeVersions.get(controller)?.get(method);
221
+ }
222
+ // Custom metadata (SetMetadata)
223
+ static setCustomClassMeta(target, key, value) {
224
+ if (!this.customClassMeta.has(target)) {
225
+ this.customClassMeta.set(target, new Map());
226
+ }
227
+ this.customClassMeta.get(target).set(key, value);
228
+ }
229
+ static getCustomClassMeta(target, key) {
230
+ return this.customClassMeta.get(target)?.get(key);
231
+ }
232
+ static getCustomClassMetaAll(target) {
233
+ return this.customClassMeta.get(target);
234
+ }
235
+ static setCustomHandlerMeta(target, handler, key, value) {
236
+ if (!this.customHandlerMeta.has(target)) {
237
+ this.customHandlerMeta.set(target, new Map());
238
+ }
239
+ const handlerMap = this.customHandlerMeta.get(target);
240
+ if (!handlerMap.has(handler)) {
241
+ handlerMap.set(handler, new Map());
242
+ }
243
+ handlerMap.get(handler).set(key, value);
244
+ }
245
+ static getCustomHandlerMeta(target, handler, key) {
246
+ return this.customHandlerMeta.get(target)?.get(handler)?.get(key);
247
+ }
248
+ static getCustomHandlerMetaAll(target, handler) {
249
+ return this.customHandlerMeta.get(target)?.get(handler);
250
+ }
251
+ // Clear all (for testing)
252
+ static clear() {
253
+ this.routes.clear();
254
+ this.controllers.clear();
255
+ this.controllerOptions.clear();
256
+ this.modules.clear();
257
+ this.parameters.clear();
258
+ for (const set of this.global.values()){
259
+ set.clear();
260
+ }
261
+ for (const map of this.controller.values()){
262
+ map.clear();
263
+ }
264
+ for (const map of this.handler.values()){
265
+ map.clear();
266
+ }
267
+ this.injectables.clear();
268
+ this.scopes.clear();
269
+ this.injectTokens.clear();
270
+ this.handlerHttpMeta.clear();
271
+ this.catchTypes.clear();
272
+ this.routeVersions.clear();
273
+ this.customClassMeta.clear();
274
+ this.customHandlerMeta.clear();
275
+ }
276
+ }
@@ -0,0 +1,55 @@
1
+ import type { CanActivate, ExceptionFilter, NestInterceptor, NestMiddleware, PipeTransform } from '../pipeline/types';
2
+ export type Type<T = any> = new (...args: any[]) => T;
3
+ export type Constructor = Function;
4
+ export type ComponentType = 'middleware' | 'guard' | 'pipe' | 'interceptor' | 'filter';
5
+ export type MiddlewareType = Type<NestMiddleware> | NestMiddleware;
6
+ export type GuardType = Type<CanActivate> | CanActivate;
7
+ export type PipeType = Type<PipeTransform> | PipeTransform;
8
+ export type InterceptorType = Type<NestInterceptor> | NestInterceptor;
9
+ export type FilterType = Type<ExceptionFilter> | ExceptionFilter;
10
+ export interface ComponentTypeMap {
11
+ middleware: MiddlewareType;
12
+ guard: GuardType;
13
+ pipe: PipeType;
14
+ interceptor: InterceptorType;
15
+ filter: FilterType;
16
+ }
17
+ export type ComponentInstance = MiddlewareType | GuardType | PipeType | InterceptorType | FilterType;
18
+ export interface RouteDefinition {
19
+ method: string;
20
+ path: string;
21
+ handlerName: string | symbol;
22
+ version?: number | number[];
23
+ }
24
+ export interface ParameterMetadata {
25
+ index: number;
26
+ type: string;
27
+ name?: string;
28
+ pipes?: PipeType[];
29
+ factory?: (data: unknown, ctx: unknown) => unknown;
30
+ }
31
+ export interface HttpHandlerMeta {
32
+ httpCode?: number;
33
+ responseHeaders?: Array<[string, string]>;
34
+ redirect?: {
35
+ url: string;
36
+ statusCode: number;
37
+ };
38
+ }
39
+ export interface ModuleOptions {
40
+ imports?: unknown[];
41
+ providers?: Array<Type | ProviderOptions>;
42
+ controllers?: Type[];
43
+ exports?: Array<Type | InjectionTokenLike>;
44
+ }
45
+ export interface InjectionTokenLike {
46
+ toString(): string;
47
+ }
48
+ export interface ProviderOptions<T = unknown> {
49
+ token?: unknown;
50
+ scope?: string;
51
+ useValue?: T;
52
+ useFactory?: (...args: unknown[]) => T | Promise<T>;
53
+ inject?: unknown[];
54
+ useExisting?: unknown;
55
+ }
@@ -0,0 +1,2 @@
1
+ // Forward-compatible with ProviderOptions
2
+ export { };