@e22m4u/ts-rest-router 0.0.6 → 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/README-ru.md +227 -0
- package/README.md +227 -0
- package/dist/cjs/index.cjs +448 -153
- package/dist/esm/controller-registry.d.ts +53 -11
- package/dist/esm/controller-registry.js +242 -104
- package/dist/esm/debuggable-service.js +1 -1
- package/dist/esm/decorators/action/action-decorator.d.ts +7 -8
- package/dist/esm/decorators/action/action-decorator.js +1 -5
- package/dist/esm/decorators/action/action-decorator.spec.js +16 -16
- package/dist/esm/decorators/action/action-metadata.d.ts +0 -1
- package/dist/esm/decorators/after/after-decorator.d.ts +9 -0
- package/dist/esm/decorators/after/after-decorator.js +22 -0
- package/dist/esm/decorators/after/after-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/after/after-decorator.spec.js +115 -0
- package/dist/esm/decorators/after/after-metadata.d.ts +13 -0
- package/dist/esm/decorators/after/after-metadata.js +5 -0
- package/dist/esm/decorators/after/after-reflector.d.ts +22 -0
- package/dist/esm/decorators/after/after-reflector.js +29 -0
- package/dist/esm/decorators/after/after-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/after/after-reflector.spec.js +102 -0
- package/dist/esm/decorators/after/index.d.ts +3 -0
- package/dist/esm/decorators/after/index.js +3 -0
- package/dist/esm/decorators/before/before-decorator.d.ts +9 -0
- package/dist/esm/decorators/before/before-decorator.js +22 -0
- package/dist/esm/decorators/before/before-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/before/before-decorator.spec.js +115 -0
- package/dist/esm/decorators/before/before-metadata.d.ts +13 -0
- package/dist/esm/decorators/before/before-metadata.js +5 -0
- package/dist/esm/decorators/before/before-reflector.d.ts +22 -0
- package/dist/esm/decorators/before/before-reflector.js +29 -0
- package/dist/esm/decorators/before/before-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/before/before-reflector.spec.js +102 -0
- package/dist/esm/decorators/before/index.d.ts +3 -0
- package/dist/esm/decorators/before/index.js +3 -0
- package/dist/esm/decorators/controller/controller-decorator.d.ts +2 -1
- package/dist/esm/decorators/controller/controller-decorator.js +27 -6
- package/dist/esm/decorators/controller/controller-decorator.spec.js +37 -15
- package/dist/esm/decorators/controller/controller-metadata.d.ts +0 -1
- package/dist/esm/decorators/index.d.ts +2 -0
- package/dist/esm/decorators/index.js +2 -0
- package/dist/esm/decorators/request-context/request-context-decorator.d.ts +2 -3
- package/dist/esm/decorators/request-context/request-context-decorator.js +3 -6
- package/dist/esm/decorators/request-context/request-context-decorator.spec.js +2 -17
- package/dist/esm/decorators/request-context/request-context-metadata.d.ts +0 -1
- package/dist/esm/decorators/request-data/request-data-decorator.d.ts +7 -3
- package/dist/esm/decorators/request-data/request-data-decorator.js +16 -16
- package/dist/esm/decorators/request-data/request-data-decorator.spec.js +12 -10
- package/dist/esm/decorators/request-data/request-data-metadata.d.ts +0 -1
- package/dist/esm/utils/create-debugger.d.ts +35 -2
- package/dist/esm/utils/create-debugger.js +71 -5
- package/package.json +17 -17
- package/src/controller-registry.spec.ts +601 -275
- package/src/controller-registry.ts +263 -128
- package/src/debuggable-service.ts +1 -1
- package/src/decorators/action/action-decorator.spec.ts +16 -16
- package/src/decorators/action/action-decorator.ts +10 -12
- package/src/decorators/action/action-metadata.ts +0 -1
- package/src/decorators/after/after-decorator.spec.ts +92 -0
- package/src/decorators/after/after-decorator.ts +40 -0
- package/src/decorators/after/after-metadata.ts +17 -0
- package/src/decorators/after/after-reflector.spec.ts +107 -0
- package/src/decorators/after/after-reflector.ts +45 -0
- package/src/decorators/after/index.ts +3 -0
- package/src/decorators/before/before-decorator.spec.ts +92 -0
- package/src/decorators/before/before-decorator.ts +40 -0
- package/src/decorators/before/before-metadata.ts +17 -0
- package/src/decorators/before/before-reflector.spec.ts +111 -0
- package/src/decorators/before/before-reflector.ts +50 -0
- package/src/decorators/before/index.ts +3 -0
- package/src/decorators/controller/controller-decorator.spec.ts +33 -16
- package/src/decorators/controller/controller-decorator.ts +33 -6
- package/src/decorators/controller/controller-metadata.ts +0 -1
- package/src/decorators/index.ts +2 -0
- package/src/decorators/request-context/request-context-decorator.spec.ts +2 -15
- package/src/decorators/request-context/request-context-decorator.ts +3 -8
- package/src/decorators/request-context/request-context-metadata.ts +0 -1
- package/src/decorators/request-data/request-data-decorator.spec.ts +12 -11
- package/src/decorators/request-data/request-data-decorator.ts +41 -16
- package/src/decorators/request-data/request-data-metadata.ts +0 -1
- package/src/utils/create-debugger.ts +84 -7
@@ -2,7 +2,6 @@ import { Constructor } from './types.js';
|
|
2
2
|
import { RouteHandler } from '@e22m4u/js-trie-router';
|
3
3
|
import { RoutePreHandler } from '@e22m4u/js-trie-router';
|
4
4
|
import { RoutePostHandler } from '@e22m4u/js-trie-router';
|
5
|
-
import { ControllerMetadata } from './decorators/index.js';
|
6
5
|
import { DebuggableService } from './debuggable-service.js';
|
7
6
|
/**
|
8
7
|
* Controller root options.
|
@@ -34,26 +33,69 @@ export declare class ControllerRegistry extends DebuggableService {
|
|
34
33
|
*/
|
35
34
|
hasController<T extends object>(ctor: Constructor<T>): boolean;
|
36
35
|
/**
|
37
|
-
* Get path prefix
|
36
|
+
* Get path prefix from controller root options.
|
38
37
|
*
|
39
|
-
* @param controllerMd
|
40
38
|
* @param options
|
41
39
|
*/
|
42
|
-
|
40
|
+
protected getPathPrefixFromControllerRootOptions(options?: ControllerRootOptions): string;
|
43
41
|
/**
|
44
|
-
* Get
|
42
|
+
* Get path prefix from controller metadata.
|
43
|
+
*
|
44
|
+
* @param ctor
|
45
|
+
*/
|
46
|
+
protected getPathPrefixFromControllerMetadata<T>(ctor: Constructor<T>): string;
|
47
|
+
/**
|
48
|
+
* Getting pre-handlers from controller root options.
|
45
49
|
*
|
46
|
-
* @param controllerMd
|
47
50
|
* @param options
|
48
51
|
*/
|
49
|
-
|
52
|
+
protected getPreHandlersFromControllerRootOptions(options?: ControllerRootOptions): RouteHandler[];
|
50
53
|
/**
|
51
|
-
*
|
54
|
+
* Getting post-handlers from controller root options.
|
52
55
|
*
|
53
|
-
* @param controllerMd
|
54
56
|
* @param options
|
55
57
|
*/
|
56
|
-
|
58
|
+
protected getPostHandlersFromControllerRootOptions(options?: ControllerRootOptions): RoutePostHandler[];
|
59
|
+
/**
|
60
|
+
* Get pre-handlers from before metadata.
|
61
|
+
*
|
62
|
+
* @param ctor
|
63
|
+
* @param actionName
|
64
|
+
*/
|
65
|
+
protected getPreHandlersFromBeforeMetadata<T>(ctor: Constructor<T>, actionName?: string): RouteHandler[];
|
66
|
+
/**
|
67
|
+
* Get post-handlers from after metadata.
|
68
|
+
*
|
69
|
+
* @param ctor
|
70
|
+
* @param actionName
|
71
|
+
*/
|
72
|
+
protected getPostHandlersFromAfterMetadata<T>(ctor: Constructor<T>, actionName?: string): RoutePostHandler[];
|
73
|
+
/**
|
74
|
+
* Get pre-handlers from controller metadata.
|
75
|
+
*
|
76
|
+
* @param ctor
|
77
|
+
*/
|
78
|
+
protected getPreHandlersFromControllerMetadata<T>(ctor: Constructor<T>): RouteHandler[];
|
79
|
+
/**
|
80
|
+
* Get post-handlers from controller metadata.
|
81
|
+
*
|
82
|
+
* @param ctor
|
83
|
+
*/
|
84
|
+
protected getPostHandlersFromControllerMetadata<T>(ctor: Constructor<T>): RoutePostHandler[];
|
85
|
+
/**
|
86
|
+
* Get pre-handlers from action metadata.
|
87
|
+
*
|
88
|
+
* @param ctor
|
89
|
+
* @param actionName
|
90
|
+
*/
|
91
|
+
protected getPreHandlersFromActionMetadata<T>(ctor: Constructor<T>, actionName: string): RouteHandler[];
|
92
|
+
/**
|
93
|
+
* Get post-handlers from action metadata.
|
94
|
+
*
|
95
|
+
* @param ctor
|
96
|
+
* @param actionName
|
97
|
+
*/
|
98
|
+
protected getPostHandlersFromActionMetadata<T>(ctor: Constructor<T>, actionName: string): RoutePostHandler[];
|
57
99
|
/**
|
58
100
|
* Create route handler.
|
59
101
|
*
|
@@ -61,5 +103,5 @@ export declare class ControllerRegistry extends DebuggableService {
|
|
61
103
|
* @param actionName
|
62
104
|
* @protected
|
63
105
|
*/
|
64
|
-
createRouteHandler<T extends object>(controllerCtor: Constructor<T>, actionName: string): RouteHandler;
|
106
|
+
protected createRouteHandler<T extends object>(controllerCtor: Constructor<T>, actionName: string): RouteHandler;
|
65
107
|
}
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import { Errorf } from '@e22m4u/js-format';
|
2
2
|
import { TrieRouter } from '@e22m4u/js-trie-router';
|
3
3
|
import { DataValidator } from '@e22m4u/ts-data-schema';
|
4
|
+
import { AfterReflector } from './decorators/index.js';
|
4
5
|
import { DataTypeCaster } from '@e22m4u/ts-data-schema';
|
5
6
|
import { ActionReflector } from './decorators/index.js';
|
7
|
+
import { BeforeReflector } from './decorators/index.js';
|
6
8
|
import { NotAControllerError } from './errors/index.js';
|
7
9
|
import { RequestDataSource } from './decorators/index.js';
|
8
10
|
import { DebuggableService } from './debuggable-service.js';
|
@@ -24,6 +26,7 @@ export class ControllerRegistry extends DebuggableService {
|
|
24
26
|
* @param options
|
25
27
|
*/
|
26
28
|
addController(ctor, options) {
|
29
|
+
const debug = this.debug.bind(this.addController.name);
|
27
30
|
// проверка повторной регистрации помогает
|
28
31
|
// заметить ошибку в коде, который использует
|
29
32
|
// интерфейс данного сервиса
|
@@ -35,54 +38,66 @@ export class ControllerRegistry extends DebuggableService {
|
|
35
38
|
const controllerMd = ControllerReflector.getMetadata(ctor);
|
36
39
|
if (!controllerMd)
|
37
40
|
throw new NotAControllerError(ctor);
|
38
|
-
|
41
|
+
debug('Adding controller %s.', ctor.name);
|
39
42
|
// определение префикса применяемого
|
40
43
|
// к маршрутам контроллера
|
41
|
-
|
42
|
-
this.
|
44
|
+
let pathPrefix = '';
|
45
|
+
pathPrefix += this.getPathPrefixFromControllerRootOptions(options);
|
46
|
+
pathPrefix += '/';
|
47
|
+
pathPrefix += this.getPathPrefixFromControllerMetadata(ctor);
|
48
|
+
pathPrefix = pathPrefix.replace(/\/{2,}/g, '/').replace(/\/$/, '');
|
49
|
+
debug('Controller path prefix is %v.', pathPrefix);
|
43
50
|
// подготовка pre-обработчиков
|
44
|
-
const preHandlers =
|
45
|
-
|
51
|
+
const preHandlers = [
|
52
|
+
...this.getPreHandlersFromControllerRootOptions(options),
|
53
|
+
...this.getPreHandlersFromBeforeMetadata(ctor),
|
54
|
+
...this.getPreHandlersFromControllerMetadata(ctor),
|
55
|
+
];
|
56
|
+
debug('Controller has %v pre-handlers.', preHandlers.length);
|
46
57
|
// подготовка post-обработчиков
|
47
|
-
const postHandlers =
|
48
|
-
|
58
|
+
const postHandlers = [
|
59
|
+
...this.getPostHandlersFromControllerRootOptions(options),
|
60
|
+
...this.getPostHandlersFromAfterMetadata(ctor),
|
61
|
+
...this.getPostHandlersFromControllerMetadata(ctor),
|
62
|
+
];
|
63
|
+
debug('Controller has %v post-handlers.', postHandlers.length);
|
49
64
|
// обход всех операций контроллера
|
50
65
|
// для определения маршрутов
|
51
66
|
const actionsMd = ActionReflector.getMetadata(ctor);
|
52
|
-
|
67
|
+
debug('%v actions found.', actionsMd.size);
|
53
68
|
const router = this.getService(TrieRouter);
|
54
69
|
actionsMd.forEach((actionMd, actionName) => {
|
55
|
-
|
70
|
+
debug('Adding route for %s.%s.', ctor.name, actionName);
|
56
71
|
// подготовка пути маршрута с префиксом
|
57
|
-
|
58
|
-
const prefixedRoutePath = `${pathPrefix}/${actionMd.path}
|
59
|
-
|
72
|
+
debug('Route path is %v.', actionMd.path);
|
73
|
+
const prefixedRoutePath = `${pathPrefix}/${actionMd.path}`
|
74
|
+
.replace(/\/{2,}/g, '/')
|
75
|
+
.replace(/\/$/, '');
|
76
|
+
debug('Prefixed route path is %v.', prefixedRoutePath);
|
60
77
|
// подготовка pre-обработчиков операции
|
61
|
-
const actionPreHandlers =
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
const mergedPreHandlers = [...preHandlers, ...actionPreHandlers];
|
78
|
+
const actionPreHandlers = [
|
79
|
+
...preHandlers,
|
80
|
+
...this.getPreHandlersFromBeforeMetadata(ctor, actionName),
|
81
|
+
...this.getPreHandlersFromActionMetadata(ctor, actionName),
|
82
|
+
];
|
83
|
+
debug('%v action pre-handlers in total.', actionPreHandlers.length);
|
68
84
|
// подготовка post-обработчиков операции
|
69
|
-
const actionPostHandlers =
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
const mergedPostHandlers = [...postHandlers, ...actionPostHandlers];
|
85
|
+
const actionPostHandlers = [
|
86
|
+
...postHandlers,
|
87
|
+
...this.getPostHandlersFromAfterMetadata(ctor, actionName),
|
88
|
+
...this.getPostHandlersFromActionMetadata(ctor, actionName),
|
89
|
+
];
|
90
|
+
debug('%v action post-handlers in total.', actionPostHandlers.length);
|
76
91
|
// подготовка обработчика маршрута
|
77
92
|
const routeHandler = this.createRouteHandler(ctor, actionName);
|
78
93
|
router.defineRoute({
|
79
94
|
method: actionMd.method,
|
80
95
|
path: prefixedRoutePath,
|
81
|
-
preHandler:
|
96
|
+
preHandler: actionPreHandlers,
|
82
97
|
handler: routeHandler,
|
83
|
-
postHandler:
|
98
|
+
postHandler: actionPostHandlers,
|
84
99
|
});
|
85
|
-
|
100
|
+
debug('Route %s %v is added.', actionMd.method.toUpperCase(), prefixedRoutePath);
|
86
101
|
});
|
87
102
|
this.controllers.add(ctor);
|
88
103
|
return this;
|
@@ -96,79 +111,201 @@ export class ControllerRegistry extends DebuggableService {
|
|
96
111
|
return this.controllers.has(ctor);
|
97
112
|
}
|
98
113
|
/**
|
99
|
-
* Get path prefix
|
114
|
+
* Get path prefix from controller root options.
|
100
115
|
*
|
101
|
-
* @param controllerMd
|
102
116
|
* @param options
|
103
117
|
*/
|
104
|
-
|
105
|
-
const
|
106
|
-
|
107
|
-
const
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
118
|
+
getPathPrefixFromControllerRootOptions(options) {
|
119
|
+
const debug = this.debug.bind(this.getPathPrefixFromControllerRootOptions.name);
|
120
|
+
debug('Getting path prefix from controller root options.');
|
121
|
+
const res = options?.pathPrefix || '';
|
122
|
+
debug('Controller path prefix is %v.', res);
|
123
|
+
return res;
|
124
|
+
}
|
125
|
+
/**
|
126
|
+
* Get path prefix from controller metadata.
|
127
|
+
*
|
128
|
+
* @param ctor
|
129
|
+
*/
|
130
|
+
getPathPrefixFromControllerMetadata(ctor) {
|
131
|
+
const debug = this.debug.bind(this.getPathPrefixFromControllerMetadata.name);
|
132
|
+
debug('Getting path prefix from @controller metadata.');
|
133
|
+
debug('Metadata target is %s.', ctor.name);
|
134
|
+
const md = ControllerReflector.getMetadata(ctor);
|
135
|
+
if (!md)
|
136
|
+
throw new Errorf('Controller %v has no metadata.', ctor);
|
137
|
+
const res = md.path || '';
|
138
|
+
debug('Controller path prefix is %v.', res);
|
139
|
+
return md.path || '';
|
114
140
|
}
|
115
141
|
/**
|
116
|
-
*
|
142
|
+
* Getting pre-handlers from controller root options.
|
117
143
|
*
|
118
|
-
* @param controllerMd
|
119
144
|
* @param options
|
120
145
|
*/
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
let
|
146
|
+
getPreHandlersFromControllerRootOptions(options) {
|
147
|
+
const debug = this.debug.bind(this.getPreHandlersFromControllerRootOptions.name);
|
148
|
+
debug('Getting pre-handlers from controller root options.');
|
149
|
+
let res = [];
|
125
150
|
if (options?.before)
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
this.debug('%v root pre-handlers found.', rootPreHandlers.length);
|
130
|
-
// подготовка pre-обработчиков
|
131
|
-
// запроса контроллера
|
132
|
-
let ctlPreHandlers = [];
|
133
|
-
if (controllerMd.before)
|
134
|
-
ctlPreHandlers = Array.isArray(controllerMd.before)
|
135
|
-
? controllerMd.before
|
136
|
-
: [controllerMd.before];
|
137
|
-
this.debug('%v controller pre-handlers found.', ctlPreHandlers.length);
|
138
|
-
// подготовка объединенного набора
|
139
|
-
// pre-обработчиков запроса
|
140
|
-
const mergedPreHandlers = [...rootPreHandlers, ...ctlPreHandlers];
|
141
|
-
this.debug('%v merged pre-handlers.', mergedPreHandlers.length);
|
142
|
-
return mergedPreHandlers;
|
151
|
+
res = Array.isArray(options.before) ? options.before : [options.before];
|
152
|
+
debug('%v pre-handlers found.', res.length);
|
153
|
+
return res;
|
143
154
|
}
|
144
155
|
/**
|
145
|
-
*
|
156
|
+
* Getting post-handlers from controller root options.
|
146
157
|
*
|
147
|
-
* @param controllerMd
|
148
158
|
* @param options
|
149
159
|
*/
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
let
|
160
|
+
getPostHandlersFromControllerRootOptions(options) {
|
161
|
+
const debug = this.debug.bind(this.getPostHandlersFromControllerRootOptions.name);
|
162
|
+
debug('Getting post-handlers from controller root options.');
|
163
|
+
let res = [];
|
154
164
|
if (options?.after)
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
this.debug(
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
165
|
+
res = Array.isArray(options.after) ? options.after : [options.after];
|
166
|
+
debug('%v post-handlers found.', res.length);
|
167
|
+
return res;
|
168
|
+
}
|
169
|
+
/**
|
170
|
+
* Get pre-handlers from before metadata.
|
171
|
+
*
|
172
|
+
* @param ctor
|
173
|
+
* @param actionName
|
174
|
+
*/
|
175
|
+
getPreHandlersFromBeforeMetadata(ctor, actionName) {
|
176
|
+
const debug = this.debug.bind(this.getPreHandlersFromBeforeMetadata.name);
|
177
|
+
debug('Getting pre-handlers from @before metadata.');
|
178
|
+
if (actionName) {
|
179
|
+
debug('Target is %s.%s.', ctor.name, actionName);
|
180
|
+
}
|
181
|
+
else {
|
182
|
+
debug('Target is %s.', ctor.name);
|
183
|
+
}
|
184
|
+
let preHandlers = [];
|
185
|
+
const mdArray = BeforeReflector.getMetadata(ctor, actionName);
|
186
|
+
mdArray.forEach(md => {
|
187
|
+
if (Array.isArray(md.middleware)) {
|
188
|
+
preHandlers = [...preHandlers, ...md.middleware];
|
189
|
+
}
|
190
|
+
else {
|
191
|
+
preHandlers.push(md.middleware);
|
192
|
+
}
|
193
|
+
});
|
194
|
+
if (mdArray.length) {
|
195
|
+
debug('%v pre-handlers found.', mdArray.length);
|
196
|
+
}
|
197
|
+
else {
|
198
|
+
debug('No pre-handlers found.');
|
199
|
+
}
|
200
|
+
return preHandlers;
|
201
|
+
}
|
202
|
+
/**
|
203
|
+
* Get post-handlers from after metadata.
|
204
|
+
*
|
205
|
+
* @param ctor
|
206
|
+
* @param actionName
|
207
|
+
*/
|
208
|
+
getPostHandlersFromAfterMetadata(ctor, actionName) {
|
209
|
+
const debug = this.debug.bind(this.getPostHandlersFromAfterMetadata.name);
|
210
|
+
debug('Getting post-handlers from @after metadata.');
|
211
|
+
if (actionName) {
|
212
|
+
debug('Target is %s.%s.', ctor.name, actionName);
|
213
|
+
}
|
214
|
+
else {
|
215
|
+
debug('Target is %s.', ctor.name);
|
216
|
+
}
|
217
|
+
let res = [];
|
218
|
+
const mdArray = AfterReflector.getMetadata(ctor, actionName);
|
219
|
+
mdArray.forEach(md => {
|
220
|
+
if (Array.isArray(md.middleware)) {
|
221
|
+
res = [...res, ...md.middleware];
|
222
|
+
}
|
223
|
+
else {
|
224
|
+
res.push(md.middleware);
|
225
|
+
}
|
226
|
+
});
|
227
|
+
if (mdArray.length) {
|
228
|
+
debug('%v post-handlers found.', mdArray.length);
|
229
|
+
}
|
230
|
+
else {
|
231
|
+
debug('No post-handlers found.');
|
232
|
+
}
|
233
|
+
return res;
|
234
|
+
}
|
235
|
+
/**
|
236
|
+
* Get pre-handlers from controller metadata.
|
237
|
+
*
|
238
|
+
* @param ctor
|
239
|
+
*/
|
240
|
+
getPreHandlersFromControllerMetadata(ctor) {
|
241
|
+
const debug = this.debug.bind(this.getPreHandlersFromControllerMetadata.name);
|
242
|
+
debug('Getting pre-handlers from @controller metadata.');
|
243
|
+
debug('Target is %s.', ctor.name);
|
244
|
+
const md = ControllerReflector.getMetadata(ctor);
|
245
|
+
if (!md)
|
246
|
+
throw new Errorf('Controller %v has no metadata.', ctor);
|
247
|
+
let res = [];
|
248
|
+
if (md.before)
|
249
|
+
res = Array.isArray(md.before) ? md.before : [md.before];
|
250
|
+
debug('%v pre-handlers found.', res.length);
|
251
|
+
return res;
|
252
|
+
}
|
253
|
+
/**
|
254
|
+
* Get post-handlers from controller metadata.
|
255
|
+
*
|
256
|
+
* @param ctor
|
257
|
+
*/
|
258
|
+
getPostHandlersFromControllerMetadata(ctor) {
|
259
|
+
const debug = this.debug.bind(this.getPostHandlersFromControllerMetadata.name);
|
260
|
+
debug('Getting post-handlers from @controller metadata.');
|
261
|
+
const md = ControllerReflector.getMetadata(ctor);
|
262
|
+
if (!md)
|
263
|
+
throw new Errorf('Controller %v has no metadata.', ctor);
|
264
|
+
let res = [];
|
265
|
+
if (md.after)
|
266
|
+
res = Array.isArray(md.after) ? md.after : [md.after];
|
267
|
+
debug('%v post-handlers found.', res.length);
|
268
|
+
return res;
|
269
|
+
}
|
270
|
+
/**
|
271
|
+
* Get pre-handlers from action metadata.
|
272
|
+
*
|
273
|
+
* @param ctor
|
274
|
+
* @param actionName
|
275
|
+
*/
|
276
|
+
getPreHandlersFromActionMetadata(ctor, actionName) {
|
277
|
+
const debug = this.debug.bind(this.getPreHandlersFromActionMetadata.name);
|
278
|
+
debug('Getting pre-handlers from @action metadata.');
|
279
|
+
const actionsMd = ActionReflector.getMetadata(ctor);
|
280
|
+
const actionMd = actionsMd.get(actionName);
|
281
|
+
if (!actionMd)
|
282
|
+
throw new Errorf('Action %s.%s has no metadata.', ctor.name, actionName);
|
283
|
+
let res = [];
|
284
|
+
if (actionMd.before)
|
285
|
+
res = Array.isArray(actionMd.before)
|
286
|
+
? actionMd.before
|
287
|
+
: [actionMd.before];
|
288
|
+
debug('%v pre-handlers found.', res.length);
|
289
|
+
return res;
|
290
|
+
}
|
291
|
+
/**
|
292
|
+
* Get post-handlers from action metadata.
|
293
|
+
*
|
294
|
+
* @param ctor
|
295
|
+
* @param actionName
|
296
|
+
*/
|
297
|
+
getPostHandlersFromActionMetadata(ctor, actionName) {
|
298
|
+
const debug = this.debug.bind(this.getPreHandlersFromActionMetadata.name);
|
299
|
+
debug('Getting post-handlers from @action metadata.');
|
300
|
+
const actionsMd = ActionReflector.getMetadata(ctor);
|
301
|
+
const actionMd = actionsMd.get(actionName);
|
302
|
+
if (!actionMd)
|
303
|
+
throw new Errorf('Action %s.%s has no metadata.', ctor.name, actionName);
|
304
|
+
let res = [];
|
305
|
+
if (actionMd.after)
|
306
|
+
res = Array.isArray(actionMd.after) ? actionMd.after : [actionMd.after];
|
307
|
+
debug('%v pre-handlers found.', res.length);
|
308
|
+
return res;
|
172
309
|
}
|
173
310
|
/**
|
174
311
|
* Create route handler.
|
@@ -178,14 +315,15 @@ export class ControllerRegistry extends DebuggableService {
|
|
178
315
|
* @protected
|
179
316
|
*/
|
180
317
|
createRouteHandler(controllerCtor, actionName) {
|
181
|
-
this.debug(
|
318
|
+
const debug = this.debug.bind(this.createRouteHandler.name);
|
319
|
+
debug('Creating route handler for %s.%s.', controllerCtor.name, actionName);
|
182
320
|
const requestContextMetadataMap = RequestContextReflector.getMetadata(controllerCtor, actionName);
|
183
321
|
const requestDataMetadataMap = RequestDataReflector.getMetadata(controllerCtor, actionName);
|
184
322
|
const argsNumber = controllerCtor.prototype[actionName].length;
|
185
323
|
const dataTypeCaster = this.getService(DataTypeCaster);
|
186
324
|
const dataValidator = this.getService(DataValidator);
|
187
325
|
return (requestContext) => {
|
188
|
-
|
326
|
+
debug('Executing route handler for %s.%s.', controllerCtor.name, actionName);
|
189
327
|
const args = Array(argsNumber)
|
190
328
|
.fill(undefined)
|
191
329
|
.map((_, index) => {
|
@@ -193,13 +331,13 @@ export class ControllerRegistry extends DebuggableService {
|
|
193
331
|
// значениями из контекста запроса
|
194
332
|
const requestContextMd = requestContextMetadataMap.get(index);
|
195
333
|
if (requestContextMd != null) {
|
196
|
-
|
334
|
+
debug('Argument %v has request context metadata.', index);
|
197
335
|
// если свойство контекста не определено,
|
198
336
|
// то используем весь объект контекста
|
199
337
|
// в качестве значения текущего аргумента
|
200
338
|
if (requestContextMd.property == null) {
|
201
|
-
|
202
|
-
|
339
|
+
debug('Request context property is not specified.');
|
340
|
+
debug('Argument %v is set to %v.', index, requestContext);
|
203
341
|
return requestContext;
|
204
342
|
}
|
205
343
|
// если свойство контекста определено,
|
@@ -207,18 +345,18 @@ export class ControllerRegistry extends DebuggableService {
|
|
207
345
|
// в качестве текущего аргумента
|
208
346
|
const propName = requestContextMd.property;
|
209
347
|
const propValue = requestContext[propName];
|
210
|
-
|
211
|
-
|
348
|
+
debug('Request context property is %v.', propName);
|
349
|
+
debug('Argument %v is set to %v.', index, propValue);
|
212
350
|
return propValue;
|
213
351
|
}
|
214
352
|
else {
|
215
|
-
|
353
|
+
debug('No RequestContextMetadata specified for %v argument.', index);
|
216
354
|
}
|
217
355
|
// заполнение аргументов операции
|
218
356
|
// значениями из данных запроса
|
219
357
|
const requestDataMd = requestDataMetadataMap.get(index);
|
220
358
|
if (requestDataMd != null) {
|
221
|
-
|
359
|
+
debug('Argument %v has request data metadata.', index);
|
222
360
|
// получение данных
|
223
361
|
// согласно источнику
|
224
362
|
let data;
|
@@ -239,7 +377,7 @@ export class ControllerRegistry extends DebuggableService {
|
|
239
377
|
data = requestContext.body;
|
240
378
|
break;
|
241
379
|
}
|
242
|
-
|
380
|
+
debug('Request data source is %v.', requestDataMd.source);
|
243
381
|
// при наличии схемы данных выполняется
|
244
382
|
// их конвертация и валидация
|
245
383
|
if (requestDataMd.schema) {
|
@@ -247,16 +385,16 @@ export class ControllerRegistry extends DebuggableService {
|
|
247
385
|
noTypeCastError: true,
|
248
386
|
sourcePath: requestDataMd.source,
|
249
387
|
});
|
250
|
-
|
388
|
+
debug('Data type casting is passed.');
|
251
389
|
dataValidator.validate(data, requestDataMd.schema, requestDataMd.source);
|
252
|
-
|
390
|
+
debug('Data validation is passed.');
|
253
391
|
}
|
254
392
|
// если свойство данных не определено,
|
255
393
|
// то используем весь объекта данных
|
256
394
|
// в качестве значения текущего аргумента
|
257
395
|
if (requestDataMd.property == null) {
|
258
|
-
|
259
|
-
|
396
|
+
debug('Request data property is not specified.');
|
397
|
+
debug('Argument %v is set to %v.', index, data);
|
260
398
|
return data;
|
261
399
|
}
|
262
400
|
// если свойство данных определено,
|
@@ -265,12 +403,12 @@ export class ControllerRegistry extends DebuggableService {
|
|
265
403
|
const dataAsObject = data;
|
266
404
|
const propName = requestDataMd.property;
|
267
405
|
const propValue = dataAsObject[propName];
|
268
|
-
|
269
|
-
|
406
|
+
debug('Request data property is %v.', propName);
|
407
|
+
debug('Argument %v is set to %v.', index, propValue);
|
270
408
|
return propValue;
|
271
409
|
}
|
272
410
|
else {
|
273
|
-
|
411
|
+
debug('No RequestDataMetadata specified for %v argument.', index);
|
274
412
|
}
|
275
413
|
});
|
276
414
|
// выполнение операции контроллера
|
@@ -18,6 +18,6 @@ export class DebuggableService extends Service {
|
|
18
18
|
super(container);
|
19
19
|
const serviceName = toCamelCase(this.constructor.name);
|
20
20
|
this.debug = createDebugger(serviceName);
|
21
|
-
this.debug('
|
21
|
+
this.debug.bind('constructor')('Service created.');
|
22
22
|
}
|
23
23
|
}
|
@@ -12,42 +12,41 @@ export type ActionOptions = Flatten<Omit<ActionMetadata, 'propertyKey'>>;
|
|
12
12
|
*/
|
13
13
|
export declare function action<T extends object>(options: ActionOptions): (target: Prototype<T>, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
14
14
|
/**
|
15
|
-
* Action
|
15
|
+
* Action method options.
|
16
16
|
*/
|
17
|
-
type
|
17
|
+
export type ActionMethodOptions = Flatten<Omit<ActionOptions, 'method' | 'path'>>;
|
18
18
|
/**
|
19
19
|
* Get decorator.
|
20
20
|
*
|
21
21
|
* @param path
|
22
22
|
* @param options
|
23
23
|
*/
|
24
|
-
export declare const get: (path: string, options?:
|
24
|
+
export declare const get: (path: string, options?: ActionMethodOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
25
25
|
/**
|
26
26
|
* Post decorator.
|
27
27
|
*
|
28
28
|
* @param path
|
29
29
|
* @param options
|
30
30
|
*/
|
31
|
-
export declare const post: (path: string, options?:
|
31
|
+
export declare const post: (path: string, options?: ActionMethodOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
32
32
|
/**
|
33
33
|
* Put decorator.
|
34
34
|
*
|
35
35
|
* @param path
|
36
36
|
* @param options
|
37
37
|
*/
|
38
|
-
export declare const put: (path: string, options?:
|
38
|
+
export declare const put: (path: string, options?: ActionMethodOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
39
39
|
/**
|
40
40
|
* Patch decorator.
|
41
41
|
*
|
42
42
|
* @param path
|
43
43
|
* @param options
|
44
44
|
*/
|
45
|
-
export declare const patch: (path: string, options?:
|
45
|
+
export declare const patch: (path: string, options?: ActionMethodOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
46
46
|
/**
|
47
47
|
* Del decorator.
|
48
48
|
*
|
49
49
|
* @param path
|
50
50
|
* @param options
|
51
51
|
*/
|
52
|
-
export declare const del: (path: string, options?:
|
53
|
-
export {};
|
52
|
+
export declare const del: (path: string, options?: ActionMethodOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
@@ -12,11 +12,7 @@ export function action(options) {
|
|
12
12
|
const decoratorType = getDecoratorTargetType(target, propertyKey, descriptor);
|
13
13
|
if (decoratorType !== DecoratorTargetType.INSTANCE_METHOD)
|
14
14
|
throw new Error('@action decorator is only supported on an instance method.');
|
15
|
-
|
16
|
-
...options,
|
17
|
-
propertyKey,
|
18
|
-
};
|
19
|
-
ActionReflector.setMetadata(metadata, target.constructor, propertyKey);
|
15
|
+
ActionReflector.setMetadata({ ...options, propertyKey }, target.constructor, propertyKey);
|
20
16
|
};
|
21
17
|
}
|
22
18
|
/**
|