@velajs/vela 0.10.0 → 1.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 +113 -0
- package/README.md +36 -2
- package/dist/cache/cache.decorators.d.ts +2 -2
- package/dist/cache/cache.module.d.ts +1 -1
- package/dist/cache/cache.module.js +1 -1
- package/dist/constants.d.ts +29 -26
- package/dist/constants.js +26 -29
- package/dist/container/container.js +2 -2
- package/dist/container/decorators.js +8 -11
- package/dist/container/types.d.ts +1 -0
- package/dist/errors/http-exception.d.ts +21 -20
- package/dist/errors/http-exception.js +6 -6
- package/dist/event-emitter/event-emitter.decorators.js +2 -3
- package/dist/event-emitter/event-emitter.subscriber.js +2 -1
- package/dist/factory.d.ts +0 -1
- package/dist/factory.js +2 -32
- package/dist/fetch/fetch.module.d.ts +2 -2
- package/dist/fetch/fetch.module.js +2 -2
- package/dist/health/health.service.js +6 -2
- package/dist/http/decorators.d.ts +6 -5
- package/dist/http/decorators.js +28 -76
- package/dist/http/execution-context.d.ts +4 -0
- package/dist/http/execution-context.js +15 -0
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.js +1 -1
- package/dist/http/route.manager.d.ts +1 -2
- package/dist/http/route.manager.js +20 -31
- package/dist/http/types.d.ts +0 -1
- package/dist/index.d.ts +4 -10
- package/dist/index.js +7 -12
- package/dist/internal.d.ts +11 -0
- package/dist/internal.js +13 -0
- package/dist/metadata.js +6 -15
- package/dist/module/decorators.d.ts +1 -3
- package/dist/module/decorators.js +8 -20
- package/dist/module/graph.d.ts +10 -0
- package/dist/module/graph.js +35 -0
- package/dist/module/index.d.ts +2 -0
- package/dist/module/index.js +1 -0
- package/dist/{http/middleware-consumer.d.ts → module/middleware.d.ts} +4 -13
- package/dist/{http/middleware-consumer.js → module/middleware.js} +0 -13
- package/dist/module/module-loader.d.ts +1 -1
- package/dist/module/module-loader.js +17 -13
- package/dist/module/types.d.ts +1 -29
- package/dist/openapi/decorators.js +15 -10
- package/dist/openapi/document.js +7 -42
- package/dist/pipeline/app-providers.d.ts +10 -0
- package/dist/pipeline/app-providers.js +43 -0
- package/dist/pipeline/component.manager.d.ts +1 -0
- package/dist/pipeline/component.manager.js +10 -34
- package/dist/pipeline/decorators.d.ts +5 -5
- package/dist/pipeline/decorators.js +1 -9
- package/dist/pipeline/reflector.d.ts +8 -24
- package/dist/pipeline/reflector.js +10 -55
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/metadata.registry.d.ts +20 -15
- package/dist/registry/metadata.registry.js +135 -154
- package/dist/registry/paths.d.ts +3 -0
- package/dist/registry/paths.js +15 -0
- package/dist/registry/types.d.ts +24 -14
- package/dist/registry/types.js +0 -1
- package/dist/registry/util.d.ts +3 -0
- package/dist/registry/util.js +8 -0
- package/dist/schedule/cron-matcher.d.ts +2 -0
- package/dist/schedule/cron-matcher.js +62 -0
- package/dist/schedule/index.d.ts +4 -3
- package/dist/schedule/index.js +2 -2
- package/dist/schedule/schedule.decorators.js +3 -6
- package/dist/schedule/schedule.module.d.ts +2 -6
- package/dist/schedule/schedule.module.js +4 -42
- package/dist/schedule/schedule.registry.js +3 -2
- package/dist/schedule/schedule.tokens.d.ts +0 -3
- package/dist/schedule/schedule.tokens.js +0 -2
- package/dist/schedule/schedule.types.d.ts +0 -3
- package/dist/schedule-node/index.d.ts +2 -0
- package/dist/schedule-node/index.js +2 -0
- package/dist/schedule-node/schedule-node.module.d.ts +4 -0
- package/dist/schedule-node/schedule-node.module.js +18 -0
- package/dist/{schedule → schedule-node}/schedule.executor.d.ts +2 -5
- package/dist/schedule-node/schedule.executor.js +91 -0
- package/dist/services/logger.d.ts +9 -8
- package/dist/services/logger.js +14 -15
- package/dist/throttler/throttler.decorators.d.ts +2 -2
- package/package.json +9 -9
- package/dist/schedule/schedule.executor.js +0 -169
- package/dist/testing/index.d.ts +0 -2
- package/dist/testing/index.js +0 -2
- package/dist/testing/testing.builder.d.ts +0 -29
- package/dist/testing/testing.builder.js +0 -148
- package/dist/testing/testing.module.d.ts +0 -9
- package/dist/testing/testing.module.js +0 -15
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { getMetadata as internalGetMetadata } from "../metadata.js";
|
|
2
1
|
import { MetadataRegistry } from "../registry/metadata.registry.js";
|
|
3
|
-
const SET_METADATA_KEY = 'vela:metadata';
|
|
4
|
-
let _decoratorKeyCounter = 0;
|
|
5
2
|
/**
|
|
6
3
|
* Decorator that attaches custom metadata to a class or method.
|
|
7
4
|
* Read via Reflector in guards/interceptors.
|
|
@@ -15,13 +12,10 @@ let _decoratorKeyCounter = 0;
|
|
|
15
12
|
* class AdminController { ... }
|
|
16
13
|
* ```
|
|
17
14
|
*/ export function SetMetadata(key, value) {
|
|
18
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
19
15
|
return (target, propertyKey)=>{
|
|
20
16
|
if (propertyKey !== undefined) {
|
|
21
|
-
// Method decorator
|
|
22
17
|
MetadataRegistry.setCustomHandlerMeta(target.constructor, propertyKey, key, value);
|
|
23
18
|
} else {
|
|
24
|
-
// Class decorator
|
|
25
19
|
MetadataRegistry.setCustomClassMeta(target, key, value);
|
|
26
20
|
}
|
|
27
21
|
};
|
|
@@ -54,7 +48,7 @@ let _decoratorKeyCounter = 0;
|
|
|
54
48
|
* // reflector.get(Roles, context) — typed as string[] | undefined
|
|
55
49
|
* ```
|
|
56
50
|
*/ static createDecorator(options) {
|
|
57
|
-
const key = options?.key ?? `vela:custom:${
|
|
51
|
+
const key = options?.key ?? `vela:custom:${crypto.randomUUID()}`;
|
|
58
52
|
const decorator = (value)=>SetMetadata(key, value);
|
|
59
53
|
decorator.KEY = key;
|
|
60
54
|
return decorator;
|
|
@@ -67,52 +61,22 @@ let _decoratorKeyCounter = 0;
|
|
|
67
61
|
* Handler-level metadata takes priority over class-level.
|
|
68
62
|
*/ get(key, context) {
|
|
69
63
|
const resolvedKey = this.resolveKey(key);
|
|
70
|
-
|
|
71
|
-
const handlerValue = MetadataRegistry.getCustomHandlerMeta(
|
|
72
|
-
if (handlerValue !== undefined)
|
|
73
|
-
|
|
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;
|
|
64
|
+
const ctor = context.getClass();
|
|
65
|
+
const handlerValue = MetadataRegistry.getCustomHandlerMeta(ctor, context.getHandler(), resolvedKey);
|
|
66
|
+
if (handlerValue !== undefined) return handlerValue;
|
|
67
|
+
return MetadataRegistry.getCustomClassMeta(ctor, resolvedKey);
|
|
90
68
|
}
|
|
91
69
|
/**
|
|
92
70
|
* Get metadata only from the handler (method) level.
|
|
93
71
|
*/ getHandler(key, context) {
|
|
94
72
|
const resolvedKey = this.resolveKey(key);
|
|
95
|
-
|
|
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);
|
|
73
|
+
return MetadataRegistry.getCustomHandlerMeta(context.getClass(), context.getHandler(), resolvedKey);
|
|
103
74
|
}
|
|
104
75
|
/**
|
|
105
76
|
* Get metadata only from the class level.
|
|
106
77
|
*/ getClass(key, context) {
|
|
107
78
|
const resolvedKey = this.resolveKey(key);
|
|
108
|
-
|
|
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);
|
|
79
|
+
return MetadataRegistry.getCustomClassMeta(context.getClass(), resolvedKey);
|
|
116
80
|
}
|
|
117
81
|
/**
|
|
118
82
|
* Get all metadata values for a key from both handler and class.
|
|
@@ -127,11 +91,7 @@ let _decoratorKeyCounter = 0;
|
|
|
127
91
|
* Returns handler value if defined, else class value, else undefined.
|
|
128
92
|
* First defined value wins.
|
|
129
93
|
*/ getAllAndOverride(key, context) {
|
|
130
|
-
|
|
131
|
-
if (handlerValue !== undefined) {
|
|
132
|
-
return handlerValue;
|
|
133
|
-
}
|
|
134
|
-
return this.getClass(key, context);
|
|
94
|
+
return this.getHandler(key, context) ?? this.getClass(key, context);
|
|
135
95
|
}
|
|
136
96
|
/**
|
|
137
97
|
* Collects handler + class values, filters undefineds.
|
|
@@ -145,13 +105,8 @@ let _decoratorKeyCounter = 0;
|
|
|
145
105
|
const values = [];
|
|
146
106
|
if (handlerValue !== undefined) values.push(handlerValue);
|
|
147
107
|
if (classValue !== undefined) values.push(classValue);
|
|
148
|
-
if (values.length === 0)
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
if (values.length === 1) {
|
|
152
|
-
return values[0];
|
|
153
|
-
}
|
|
154
|
-
// Both defined — merge strategy depends on type
|
|
108
|
+
if (values.length === 0) return [];
|
|
109
|
+
if (values.length === 1) return values[0];
|
|
155
110
|
if (Array.isArray(values[0]) && Array.isArray(values[1])) {
|
|
156
111
|
return [
|
|
157
112
|
...values[0],
|
package/dist/registry/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { MetadataRegistry } from './metadata.registry';
|
|
2
|
-
export type { Type, Constructor, ComponentType, ComponentTypeMap, ComponentInstance, MiddlewareType, GuardType, PipeType, InterceptorType, FilterType, RouteDefinition, ParameterMetadata, ModuleOptions, ProviderOptions,
|
|
2
|
+
export type { Type, Constructor, ComponentType, ComponentTypeMap, ComponentInstance, MiddlewareType, GuardType, PipeType, InterceptorType, FilterType, RouteDefinition, ParameterMetadata, ModuleOptions, ProviderOptions, InjectionToken, } from './types';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Scope } from '../constants';
|
|
2
2
|
import type { InjectMetadata } from '../container/types';
|
|
3
|
-
import type { Type } from '
|
|
4
|
-
import type { ComponentType, ComponentTypeMap, Constructor, HttpHandlerMeta, ModuleOptions, ParameterMetadata, RouteDefinition } from './types';
|
|
3
|
+
import type { ComponentType, ComponentTypeMap, Constructor, HttpHandlerMeta, ModuleOptions, ParameterMetadata, RouteDefinition, Type } from './types';
|
|
5
4
|
export interface ControllerOptions {
|
|
6
5
|
version?: number | number[];
|
|
7
6
|
}
|
|
@@ -11,17 +10,17 @@ export declare class MetadataRegistry {
|
|
|
11
10
|
private static readonly controllerOptions;
|
|
12
11
|
private static readonly modules;
|
|
13
12
|
private static readonly parameters;
|
|
14
|
-
private static readonly global;
|
|
15
|
-
private static readonly controller;
|
|
16
|
-
private static readonly handler;
|
|
17
13
|
private static readonly injectables;
|
|
18
14
|
private static readonly scopes;
|
|
19
15
|
private static readonly injectTokens;
|
|
20
16
|
private static readonly handlerHttpMeta;
|
|
21
17
|
private static readonly catchTypes;
|
|
22
18
|
private static readonly routeVersions;
|
|
23
|
-
private static readonly
|
|
24
|
-
private static readonly
|
|
19
|
+
private static readonly classMeta;
|
|
20
|
+
private static readonly handlerMeta;
|
|
21
|
+
private static readonly controllerComponents;
|
|
22
|
+
private static readonly handlerComponents;
|
|
23
|
+
private static globalComponents;
|
|
25
24
|
static getRoutes(controller: Constructor): RouteDefinition[];
|
|
26
25
|
static addRoute(controller: Constructor, route: RouteDefinition): void;
|
|
27
26
|
static getControllerPath(controller: Constructor): string;
|
|
@@ -36,8 +35,8 @@ export declare class MetadataRegistry {
|
|
|
36
35
|
static getGlobal<T extends ComponentType>(type: T): Set<ComponentTypeMap[T]>;
|
|
37
36
|
static registerController<T extends ComponentType>(type: T, controller: Constructor, component: ComponentTypeMap[T]): void;
|
|
38
37
|
static getController<T extends ComponentType>(type: T, controller: Constructor): ComponentTypeMap[T][];
|
|
39
|
-
static registerHandler<T extends ComponentType>(type: T,
|
|
40
|
-
static getHandler<T extends ComponentType>(type: T,
|
|
38
|
+
static registerHandler<T extends ComponentType>(type: T, controller: Constructor, methodName: string | symbol, component: ComponentTypeMap[T]): void;
|
|
39
|
+
static getHandler<T extends ComponentType>(type: T, controller: Constructor, methodName: string | symbol): ComponentTypeMap[T][];
|
|
41
40
|
static markInjectable(target: object): void;
|
|
42
41
|
static hasInjectable(target: object): boolean;
|
|
43
42
|
static setScope(target: object, scope: Scope): void;
|
|
@@ -51,12 +50,18 @@ export declare class MetadataRegistry {
|
|
|
51
50
|
static hasCatchTypes(filter: Constructor): boolean;
|
|
52
51
|
static setRouteVersion(controller: Constructor, method: string | symbol, version: number | number[]): void;
|
|
53
52
|
static getRouteVersion(controller: Constructor, method: string | symbol): number | number[] | undefined;
|
|
54
|
-
static setCustomClassMeta(target:
|
|
55
|
-
static getCustomClassMeta(target:
|
|
56
|
-
static getCustomClassMetaAll(target:
|
|
57
|
-
static setCustomHandlerMeta(target:
|
|
58
|
-
static getCustomHandlerMeta(target:
|
|
59
|
-
static getCustomHandlerMetaAll(target:
|
|
53
|
+
static setCustomClassMeta(target: object, key: string, value: unknown): void;
|
|
54
|
+
static getCustomClassMeta(target: object, key: string): unknown;
|
|
55
|
+
static getCustomClassMetaAll(target: object): Map<string, unknown> | undefined;
|
|
56
|
+
static setCustomHandlerMeta(target: object, handler: string | symbol, key: string, value: unknown): void;
|
|
57
|
+
static getCustomHandlerMeta(target: object, handler: string | symbol, key: string): unknown;
|
|
58
|
+
static getCustomHandlerMetaAll(target: object, handler: string | symbol): Map<string, unknown> | undefined;
|
|
59
|
+
static appendCustomClassMeta<T>(target: object, key: string, item: T): void;
|
|
60
|
+
static appendCustomHandlerMeta<T>(target: object, handler: string | symbol, key: string, item: T): void;
|
|
61
|
+
static setReflectMetadata(target: object, key: string, value: unknown, propertyKey?: string | symbol): void;
|
|
62
|
+
static getReflectMetadata<T = unknown>(target: object, key: string, propertyKey?: string | symbol): T | undefined;
|
|
63
|
+
static getParamTypes(target: object, propertyKey?: string | symbol): unknown[] | undefined;
|
|
60
64
|
static propagateControllerComponents(from: Constructor, to: Constructor): void;
|
|
61
65
|
static clear(): void;
|
|
66
|
+
static reset(): void;
|
|
62
67
|
}
|
|
@@ -1,108 +1,69 @@
|
|
|
1
|
+
import { getOrCreate, getOrCreateArray, getOrCreateMap } from "./util.js";
|
|
2
|
+
function emptyComponentStore() {
|
|
3
|
+
return {
|
|
4
|
+
middleware: new Set(),
|
|
5
|
+
guard: new Set(),
|
|
6
|
+
pipe: new Set(),
|
|
7
|
+
interceptor: new Set(),
|
|
8
|
+
filter: new Set()
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function emptyComponentByOwner() {
|
|
12
|
+
return {
|
|
13
|
+
middleware: new Map(),
|
|
14
|
+
guard: new Map(),
|
|
15
|
+
pipe: new Map(),
|
|
16
|
+
interceptor: new Map(),
|
|
17
|
+
filter: new Map()
|
|
18
|
+
};
|
|
19
|
+
}
|
|
1
20
|
export class MetadataRegistry {
|
|
21
|
+
// Decoration metadata (set at import time, persists across clear()).
|
|
2
22
|
static routes = new Map();
|
|
3
23
|
static controllers = new Map();
|
|
4
24
|
static controllerOptions = new Map();
|
|
5
25
|
static modules = new Map();
|
|
6
26
|
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
27
|
static injectables = new Set();
|
|
76
28
|
static scopes = new Map();
|
|
77
29
|
static injectTokens = new Map();
|
|
78
|
-
// HTTP handler metadata
|
|
79
30
|
static handlerHttpMeta = new Map();
|
|
80
|
-
// Exception filter types
|
|
81
31
|
static catchTypes = new Map();
|
|
82
|
-
// Route versions
|
|
83
32
|
static routeVersions = new Map();
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
33
|
+
// Free-form key→value class & handler meta. Backs:
|
|
34
|
+
// - @SetMetadata (custom user keys)
|
|
35
|
+
// - feature decorators (@Cron, @OnEvent, @ApiDoc, …)
|
|
36
|
+
// - the SWC shim (Reflect.metadata's design:* keys)
|
|
37
|
+
// - external Reflect.defineMetadata / Reflect.getMetadata calls.
|
|
38
|
+
static classMeta = new Map();
|
|
39
|
+
static handlerMeta = new Map();
|
|
40
|
+
// Component decoration (set by @UseGuards/@UsePipes/etc. at decoration time).
|
|
41
|
+
static controllerComponents = emptyComponentByOwner();
|
|
42
|
+
static handlerComponents = {
|
|
43
|
+
middleware: new Map(),
|
|
44
|
+
guard: new Map(),
|
|
45
|
+
pipe: new Map(),
|
|
46
|
+
interceptor: new Map(),
|
|
47
|
+
filter: new Map()
|
|
48
|
+
};
|
|
49
|
+
// Global components — app-time state (cleared by clear()).
|
|
50
|
+
static globalComponents = emptyComponentStore();
|
|
87
51
|
// Routes
|
|
88
52
|
static getRoutes(controller) {
|
|
89
|
-
return this.routes.get(controller)
|
|
53
|
+
return this.routes.get(controller) ?? [];
|
|
90
54
|
}
|
|
91
55
|
static addRoute(controller, route) {
|
|
92
|
-
|
|
93
|
-
this.routes.set(controller, []);
|
|
94
|
-
}
|
|
95
|
-
this.routes.get(controller).push(route);
|
|
56
|
+
getOrCreateArray(this.routes, controller).push(route);
|
|
96
57
|
}
|
|
97
58
|
// Controllers
|
|
98
59
|
static getControllerPath(controller) {
|
|
99
|
-
return this.controllers.get(controller)
|
|
60
|
+
return this.controllers.get(controller) ?? '';
|
|
100
61
|
}
|
|
101
62
|
static setControllerPath(controller, path) {
|
|
102
63
|
this.controllers.set(controller, path);
|
|
103
64
|
}
|
|
104
65
|
static getControllerOptions(controller) {
|
|
105
|
-
return this.controllerOptions.get(controller)
|
|
66
|
+
return this.controllerOptions.get(controller) ?? {};
|
|
106
67
|
}
|
|
107
68
|
static setControllerOptions(controller, options) {
|
|
108
69
|
this.controllerOptions.set(controller, options);
|
|
@@ -116,46 +77,37 @@ export class MetadataRegistry {
|
|
|
116
77
|
}
|
|
117
78
|
// Parameters
|
|
118
79
|
static getParameters(controller) {
|
|
119
|
-
return this.parameters.get(controller)
|
|
80
|
+
return this.parameters.get(controller) ?? new Map();
|
|
120
81
|
}
|
|
121
82
|
static addParameter(controller, methodName, param) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
const methodParams = this.parameters.get(controller);
|
|
126
|
-
if (!methodParams.has(methodName)) {
|
|
127
|
-
methodParams.set(methodName, []);
|
|
128
|
-
}
|
|
129
|
-
methodParams.get(methodName).push(param);
|
|
83
|
+
const methodMap = getOrCreateMap(this.parameters, controller);
|
|
84
|
+
getOrCreateArray(methodMap, methodName).push(param);
|
|
130
85
|
}
|
|
131
|
-
// Component registration —
|
|
86
|
+
// Component registration — global
|
|
132
87
|
static registerGlobal(type, component) {
|
|
133
|
-
this.
|
|
88
|
+
this.globalComponents[type].add(component);
|
|
134
89
|
}
|
|
135
90
|
static getGlobal(type) {
|
|
136
|
-
return this.
|
|
91
|
+
return this.globalComponents[type];
|
|
137
92
|
}
|
|
93
|
+
// Component registration — controller-level
|
|
138
94
|
static registerController(type, controller, component) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
typeMap.set(controller, []);
|
|
142
|
-
}
|
|
143
|
-
typeMap.get(controller).push(component);
|
|
95
|
+
const map = this.controllerComponents[type];
|
|
96
|
+
getOrCreateArray(map, controller).push(component);
|
|
144
97
|
}
|
|
145
98
|
static getController(type, controller) {
|
|
146
|
-
const
|
|
147
|
-
return
|
|
99
|
+
const map = this.controllerComponents[type];
|
|
100
|
+
return map.get(controller) ?? [];
|
|
148
101
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
typeMap.get(handlerKey).push(component);
|
|
102
|
+
// Component registration — handler-level
|
|
103
|
+
static registerHandler(type, controller, methodName, component) {
|
|
104
|
+
const map = this.handlerComponents[type];
|
|
105
|
+
const methodMap = getOrCreateMap(map, controller);
|
|
106
|
+
getOrCreateArray(methodMap, methodName).push(component);
|
|
155
107
|
}
|
|
156
|
-
static getHandler(type,
|
|
157
|
-
const
|
|
158
|
-
return
|
|
108
|
+
static getHandler(type, controller, methodName) {
|
|
109
|
+
const map = this.handlerComponents[type];
|
|
110
|
+
return map.get(controller)?.get(methodName) ?? [];
|
|
159
111
|
}
|
|
160
112
|
// DI metadata
|
|
161
113
|
static markInjectable(target) {
|
|
@@ -178,12 +130,8 @@ export class MetadataRegistry {
|
|
|
178
130
|
}
|
|
179
131
|
// HTTP handler metadata
|
|
180
132
|
static setHandlerHttpMeta(controller, method, meta) {
|
|
181
|
-
|
|
182
|
-
this.handlerHttpMeta.set(controller, new Map());
|
|
183
|
-
}
|
|
184
|
-
const methodMap = this.handlerHttpMeta.get(controller);
|
|
133
|
+
const methodMap = getOrCreateMap(this.handlerHttpMeta, controller);
|
|
185
134
|
const existing = methodMap.get(method) ?? {};
|
|
186
|
-
// Append-merge responseHeaders
|
|
187
135
|
const merged = {
|
|
188
136
|
...existing,
|
|
189
137
|
...meta
|
|
@@ -211,79 +159,112 @@ export class MetadataRegistry {
|
|
|
211
159
|
}
|
|
212
160
|
// Route versions
|
|
213
161
|
static setRouteVersion(controller, method, version) {
|
|
214
|
-
|
|
215
|
-
this.routeVersions.set(controller, new Map());
|
|
216
|
-
}
|
|
217
|
-
this.routeVersions.get(controller).set(method, version);
|
|
162
|
+
getOrCreateMap(this.routeVersions, controller).set(method, version);
|
|
218
163
|
}
|
|
219
164
|
static getRouteVersion(controller, method) {
|
|
220
165
|
return this.routeVersions.get(controller)?.get(method);
|
|
221
166
|
}
|
|
222
|
-
// Custom metadata (
|
|
167
|
+
// Custom class/handler metadata. One slot per (target, key) for class-level,
|
|
168
|
+
// (target, handler, key) for handler-level. The same slots back @SetMetadata,
|
|
169
|
+
// every feature decorator (@Cron, @OnEvent, @ApiDoc, …), the SWC shim, and
|
|
170
|
+
// external Reflect.defineMetadata calls — one model, one source of truth.
|
|
223
171
|
static setCustomClassMeta(target, key, value) {
|
|
224
|
-
|
|
225
|
-
this.customClassMeta.set(target, new Map());
|
|
226
|
-
}
|
|
227
|
-
this.customClassMeta.get(target).set(key, value);
|
|
172
|
+
getOrCreate(this.classMeta, target, ()=>new Map()).set(key, value);
|
|
228
173
|
}
|
|
229
174
|
static getCustomClassMeta(target, key) {
|
|
230
|
-
return this.
|
|
175
|
+
return this.classMeta.get(target)?.get(key);
|
|
231
176
|
}
|
|
232
177
|
static getCustomClassMetaAll(target) {
|
|
233
|
-
return this.
|
|
178
|
+
return this.classMeta.get(target);
|
|
234
179
|
}
|
|
235
180
|
static setCustomHandlerMeta(target, handler, key, value) {
|
|
236
|
-
|
|
237
|
-
|
|
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);
|
|
181
|
+
const byHandler = getOrCreate(this.handlerMeta, target, ()=>new Map());
|
|
182
|
+
getOrCreate(byHandler, handler, ()=>new Map()).set(key, value);
|
|
244
183
|
}
|
|
245
184
|
static getCustomHandlerMeta(target, handler, key) {
|
|
246
|
-
return this.
|
|
185
|
+
return this.handlerMeta.get(target)?.get(handler)?.get(key);
|
|
247
186
|
}
|
|
248
187
|
static getCustomHandlerMetaAll(target, handler) {
|
|
249
|
-
return this.
|
|
188
|
+
return this.handlerMeta.get(target)?.get(handler);
|
|
189
|
+
}
|
|
190
|
+
// Append helpers — for stackable metadata like @Cron / @Interval / @OnEvent / @ApiResponse.
|
|
191
|
+
static appendCustomClassMeta(target, key, item) {
|
|
192
|
+
const list = this.getCustomClassMeta(target, key) ?? [];
|
|
193
|
+
list.push(item);
|
|
194
|
+
this.setCustomClassMeta(target, key, list);
|
|
195
|
+
}
|
|
196
|
+
static appendCustomHandlerMeta(target, handler, key, item) {
|
|
197
|
+
const list = this.getCustomHandlerMeta(target, handler, key) ?? [];
|
|
198
|
+
list.push(item);
|
|
199
|
+
this.setCustomHandlerMeta(target, handler, key, list);
|
|
200
|
+
}
|
|
201
|
+
// Reflect-style API — same storage as the typed setters above. Lets external
|
|
202
|
+
// code (and the SWC shim's Reflect.metadata polyfill) write/read uniformly.
|
|
203
|
+
static setReflectMetadata(target, key, value, propertyKey) {
|
|
204
|
+
if (propertyKey !== undefined) {
|
|
205
|
+
this.setCustomHandlerMeta(target, propertyKey, key, value);
|
|
206
|
+
} else {
|
|
207
|
+
this.setCustomClassMeta(target, key, value);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
static getReflectMetadata(target, key, propertyKey) {
|
|
211
|
+
if (propertyKey !== undefined) {
|
|
212
|
+
return this.getCustomHandlerMeta(target, propertyKey, key);
|
|
213
|
+
}
|
|
214
|
+
return this.getCustomClassMeta(target, key);
|
|
215
|
+
}
|
|
216
|
+
// SWC-emitted design:paramtypes — class-level for constructors, handler-level for methods.
|
|
217
|
+
static getParamTypes(target, propertyKey) {
|
|
218
|
+
return this.getReflectMetadata(target, 'design:paramtypes', propertyKey);
|
|
250
219
|
}
|
|
251
220
|
// Propagate all controller-level components from one class to another.
|
|
252
|
-
// Used by ModuleLoader to apply module-level decorators to every controller.
|
|
253
221
|
static propagateControllerComponents(from, to) {
|
|
254
|
-
for (const
|
|
255
|
-
|
|
222
|
+
for (const type of [
|
|
223
|
+
'middleware',
|
|
224
|
+
'guard',
|
|
225
|
+
'pipe',
|
|
226
|
+
'interceptor',
|
|
227
|
+
'filter'
|
|
228
|
+
]){
|
|
229
|
+
const map = this.controllerComponents[type];
|
|
230
|
+
const components = map.get(from);
|
|
256
231
|
if (components && components.length > 0) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
typeMap.get(to).push(...components);
|
|
232
|
+
const target = getOrCreateArray(map, to);
|
|
233
|
+
target.push(...components);
|
|
261
234
|
}
|
|
262
235
|
}
|
|
263
236
|
}
|
|
264
|
-
// Clear
|
|
237
|
+
// Clear app-time state. Decoration metadata persists — once a class is
|
|
238
|
+
// decorated, that fact is permanent for the lifetime of the process.
|
|
265
239
|
static clear() {
|
|
240
|
+
this.globalComponents = emptyComponentStore();
|
|
241
|
+
}
|
|
242
|
+
// Full reset, including decoration metadata. Used in framework-internal scenarios.
|
|
243
|
+
static reset() {
|
|
266
244
|
this.routes.clear();
|
|
267
245
|
this.controllers.clear();
|
|
268
246
|
this.controllerOptions.clear();
|
|
269
247
|
this.modules.clear();
|
|
270
248
|
this.parameters.clear();
|
|
271
|
-
for (const set of this.global.values()){
|
|
272
|
-
set.clear();
|
|
273
|
-
}
|
|
274
|
-
for (const map of this.controller.values()){
|
|
275
|
-
map.clear();
|
|
276
|
-
}
|
|
277
|
-
for (const map of this.handler.values()){
|
|
278
|
-
map.clear();
|
|
279
|
-
}
|
|
280
249
|
this.injectables.clear();
|
|
281
250
|
this.scopes.clear();
|
|
282
251
|
this.injectTokens.clear();
|
|
283
252
|
this.handlerHttpMeta.clear();
|
|
284
253
|
this.catchTypes.clear();
|
|
285
254
|
this.routeVersions.clear();
|
|
286
|
-
this.
|
|
287
|
-
this.
|
|
255
|
+
this.classMeta.clear();
|
|
256
|
+
this.handlerMeta.clear();
|
|
257
|
+
for (const type of [
|
|
258
|
+
'middleware',
|
|
259
|
+
'guard',
|
|
260
|
+
'pipe',
|
|
261
|
+
'interceptor',
|
|
262
|
+
'filter'
|
|
263
|
+
]){
|
|
264
|
+
this.controllerComponents[type].clear();
|
|
265
|
+
this.handlerComponents[type].clear();
|
|
266
|
+
}
|
|
267
|
+
this.globalComponents = emptyComponentStore();
|
|
268
|
+
// reflectMeta is a WeakMap — entries die with their targets.
|
|
288
269
|
}
|
|
289
270
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Single home for path manipulation. Used by route building, openapi docs,
|
|
2
|
+
// and decorator metadata.
|
|
3
|
+
export function normalizePath(path) {
|
|
4
|
+
if (!path) return path;
|
|
5
|
+
return path.startsWith('/') ? path : `/${path}`;
|
|
6
|
+
}
|
|
7
|
+
export function joinPaths(prefix, path) {
|
|
8
|
+
const cleanPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
|
|
9
|
+
const cleanPath = path && !path.startsWith('/') ? `/${path}` : path;
|
|
10
|
+
return `${cleanPrefix}${cleanPath}` || '/';
|
|
11
|
+
}
|
|
12
|
+
// Convert ':id' Hono syntax to '{id}' OpenAPI syntax.
|
|
13
|
+
export function toOpenApiPath(path) {
|
|
14
|
+
return path.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, '{$1}');
|
|
15
|
+
}
|
package/dist/registry/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Context } from 'hono';
|
|
2
2
|
import type { CanActivate, ExceptionFilter, NestInterceptor, NestMiddleware, PipeTransform } from '../pipeline/types';
|
|
3
|
-
|
|
4
|
-
export type Constructor
|
|
3
|
+
import type { Constructor, ForwardRef, InjectionToken, ProviderOptions, Token, Type } from '../container/types';
|
|
4
|
+
export type { Constructor, ForwardRef, InjectionToken, ProviderOptions, Token, Type };
|
|
5
5
|
export type ComponentType = 'middleware' | 'guard' | 'pipe' | 'interceptor' | 'filter';
|
|
6
6
|
export type MiddlewareType = Type<NestMiddleware> | NestMiddleware;
|
|
7
7
|
export type GuardType = Type<CanActivate> | CanActivate;
|
|
@@ -37,21 +37,31 @@ export interface HttpHandlerMeta {
|
|
|
37
37
|
statusCode: number;
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
+
export type ModuleImport = Type | DynamicModule | ForwardRef;
|
|
41
|
+
export interface AsyncModuleOptions<T = unknown> {
|
|
42
|
+
imports?: ModuleImport[];
|
|
43
|
+
useFactory: (...args: any[]) => T | Promise<T>;
|
|
44
|
+
inject?: Token[];
|
|
45
|
+
}
|
|
46
|
+
export interface DynamicModule {
|
|
47
|
+
module: Type;
|
|
48
|
+
imports?: ModuleImport[];
|
|
49
|
+
providers?: Array<Type | ProviderOptions>;
|
|
50
|
+
controllers?: Type[];
|
|
51
|
+
exports?: Array<Type | InjectionToken>;
|
|
52
|
+
global?: boolean;
|
|
53
|
+
}
|
|
40
54
|
export interface ModuleOptions {
|
|
41
|
-
imports?: unknown[];
|
|
42
55
|
providers?: Array<Type | ProviderOptions>;
|
|
43
56
|
controllers?: Type[];
|
|
44
|
-
|
|
57
|
+
imports?: ModuleImport[];
|
|
58
|
+
exports?: Array<Type | InjectionToken>;
|
|
45
59
|
isGlobal?: boolean;
|
|
46
60
|
}
|
|
47
|
-
export interface
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
useValue?: T;
|
|
54
|
-
useFactory?: (...args: unknown[]) => T | Promise<T>;
|
|
55
|
-
inject?: unknown[];
|
|
56
|
-
useExisting?: unknown;
|
|
61
|
+
export interface ModuleMetadata {
|
|
62
|
+
providers: Array<Type | ProviderOptions>;
|
|
63
|
+
controllers: Type[];
|
|
64
|
+
imports: ModuleImport[];
|
|
65
|
+
exports: Array<Type | InjectionToken>;
|
|
66
|
+
isGlobal: boolean;
|
|
57
67
|
}
|
package/dist/registry/types.js
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Single map.get + optional set. Replaces `map.has(key) || map.set(key, …); map.get(key)!` patterns.
|
|
2
|
+
export function getOrCreate(map, key, factory) {
|
|
3
|
+
let v = map.get(key);
|
|
4
|
+
if (v === undefined) map.set(key, v = factory());
|
|
5
|
+
return v;
|
|
6
|
+
}
|
|
7
|
+
export const getOrCreateMap = (map, key)=>getOrCreate(map, key, ()=>new Map());
|
|
8
|
+
export const getOrCreateArray = (map, key)=>getOrCreate(map, key, ()=>[]);
|