-
-
Notifications
You must be signed in to change notification settings - Fork 286
/
EndpointRegistry.ts
137 lines (118 loc) · 3.68 KB
/
EndpointRegistry.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import {descriptorOf, getInheritedClass, Metadata, Store, Type} from "@tsed/core";
import {EndpointMetadata} from "../models/EndpointMetadata";
/**
* Registry for all Endpoint collected on a provide.
*/
export class EndpointRegistry {
/**
* Return all endpoints from the given class. This method doesn't return the endpoints from the parent of the given class.
* @param {Type<any>} target
* @returns {any}
*/
static getOwnEndpoints(target: Type<any>) {
if (!this.hasEndpoints(target)) {
Metadata.set("endpoints", [], target);
}
return Metadata.getOwn("endpoints", target);
}
/**
* Get all endpoints from a given class and his parents.
* @param {Type<any>} target
* @returns {EndpointMetadata[]}
*/
static getEndpoints(target: Type<any>): EndpointMetadata[] {
return this.getOwnEndpoints(target).concat(this.inherit(target));
}
/**
* Gets a value indicating whether the target object or its prototype chain has endpoints.
* @param {Type<any>} target
* @returns {boolean}
*/
static hasEndpoints(target: Type<any>) {
return Metadata.hasOwn("endpoints", target);
}
/**
* Get an endpoint.
* @param target
* @param propertyKey
*/
static get(target: Type<any>, propertyKey: string | symbol): EndpointMetadata {
if (!this.has(target, propertyKey)) {
const endpoint = new EndpointMetadata({target, propertyKey});
this.getOwnEndpoints(target).push(endpoint);
Metadata.set("endpoints", endpoint, target, propertyKey);
}
return Metadata.getOwn("endpoints", target, propertyKey);
}
/**
* Gets a value indicating whether the target object or its prototype chain has already method registered.
* @param target
* @param method
*/
static has(target: Type<any>, method: string | symbol): boolean {
return Metadata.hasOwn("endpoints", target, method);
}
/**
* Append mvc in the pool (before).
* @param target
* @param targetKey
* @param args
*/
static useBefore(target: Type<any>, targetKey: string | symbol, args: any[]) {
this.get(target, targetKey).before(args);
return this;
}
/**
* Add middleware and configuration for the endpoint.
* @param target
* @param targetKey
* @param args
* @returns {Endpoint}
*/
static use(target: Type<any>, targetKey: string | symbol, args: any[]) {
this.get(target, targetKey).merge(args);
return this;
}
/**
* Append mvc in the pool (after).
* @param target
* @param targetKey
* @param args
*/
static useAfter(target: Type<any>, targetKey: string | symbol, args: any[]) {
this.get(target, targetKey).after(args);
return this;
}
/**
* Store a data on store manager.
* @param target
* @param propertyKey
* @returns {any}
*/
static store(target: any, propertyKey: string): Store {
return Store.from(target, propertyKey, descriptorOf(target, propertyKey));
}
/**
* Retrieve all endpoints from inherited class and store it in the registry.
* @param {Type<any>} ctrlClass
*/
private static inherit(ctrlClass: Type<any>) {
const endpoints: EndpointMetadata[] = [];
let inheritedClass = getInheritedClass(ctrlClass);
while (inheritedClass && EndpointRegistry.hasEndpoints(inheritedClass)) {
this.getOwnEndpoints(inheritedClass).forEach((endpoint: EndpointMetadata) => {
endpoints.push(inheritEndpoint(ctrlClass, endpoint));
});
inheritedClass = getInheritedClass(inheritedClass);
}
return endpoints;
}
}
function inheritEndpoint(target: Type<any>, endpoint: EndpointMetadata): EndpointMetadata {
return new EndpointMetadata({
...endpoint,
target,
type: endpoint.type,
parent: endpoint
});
}