@velajs/vela 0.1.0
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/CHANGELOG.md +19 -0
- package/LICENSE +21 -0
- package/README.md +84 -0
- package/dist/application.d.ts +44 -0
- package/dist/application.js +112 -0
- package/dist/constants.d.ts +35 -0
- package/dist/constants.js +43 -0
- package/dist/container/container.d.ts +25 -0
- package/dist/container/container.js +195 -0
- package/dist/container/decorators.d.ts +8 -0
- package/dist/container/decorators.js +36 -0
- package/dist/container/index.d.ts +4 -0
- package/dist/container/index.js +3 -0
- package/dist/container/types.d.ts +37 -0
- package/dist/container/types.js +11 -0
- package/dist/errors/http-exception.d.ts +61 -0
- package/dist/errors/http-exception.js +128 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/factory.d.ts +5 -0
- package/dist/factory.js +39 -0
- package/dist/http/decorators.d.ts +122 -0
- package/dist/http/decorators.js +276 -0
- package/dist/http/index.d.ts +3 -0
- package/dist/http/index.js +2 -0
- package/dist/http/route.manager.d.ts +34 -0
- package/dist/http/route.manager.js +373 -0
- package/dist/http/types.d.ts +29 -0
- package/dist/http/types.js +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +26 -0
- package/dist/lifecycle/index.d.ts +20 -0
- package/dist/lifecycle/index.js +15 -0
- package/dist/metadata.d.ts +10 -0
- package/dist/metadata.js +29 -0
- package/dist/module/decorators.d.ts +5 -0
- package/dist/module/decorators.js +32 -0
- package/dist/module/index.d.ts +3 -0
- package/dist/module/index.js +2 -0
- package/dist/module/module-loader.d.ts +20 -0
- package/dist/module/module-loader.js +159 -0
- package/dist/module/types.d.ts +19 -0
- package/dist/module/types.js +1 -0
- package/dist/pipeline/component.manager.d.ts +18 -0
- package/dist/pipeline/component.manager.js +105 -0
- package/dist/pipeline/decorators.d.ts +10 -0
- package/dist/pipeline/decorators.js +50 -0
- package/dist/pipeline/index.d.ts +7 -0
- package/dist/pipeline/index.js +5 -0
- package/dist/pipeline/pipes.d.ts +25 -0
- package/dist/pipeline/pipes.js +52 -0
- package/dist/pipeline/reflector.d.ts +102 -0
- package/dist/pipeline/reflector.js +166 -0
- package/dist/pipeline/tokens.d.ts +33 -0
- package/dist/pipeline/tokens.js +27 -0
- package/dist/pipeline/types.d.ts +31 -0
- package/dist/pipeline/types.js +1 -0
- package/dist/registry/index.d.ts +2 -0
- package/dist/registry/index.js +1 -0
- package/dist/registry/metadata.registry.d.ts +61 -0
- package/dist/registry/metadata.registry.js +276 -0
- package/dist/registry/types.d.ts +55 -0
- package/dist/registry/types.js +2 -0
- 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
|
+
}
|