@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.
Files changed (80) hide show
  1. package/README-ru.md +227 -0
  2. package/README.md +227 -0
  3. package/dist/cjs/index.cjs +448 -153
  4. package/dist/esm/controller-registry.d.ts +53 -11
  5. package/dist/esm/controller-registry.js +242 -104
  6. package/dist/esm/debuggable-service.js +1 -1
  7. package/dist/esm/decorators/action/action-decorator.d.ts +7 -8
  8. package/dist/esm/decorators/action/action-decorator.js +1 -5
  9. package/dist/esm/decorators/action/action-decorator.spec.js +16 -16
  10. package/dist/esm/decorators/action/action-metadata.d.ts +0 -1
  11. package/dist/esm/decorators/after/after-decorator.d.ts +9 -0
  12. package/dist/esm/decorators/after/after-decorator.js +22 -0
  13. package/dist/esm/decorators/after/after-decorator.spec.d.ts +1 -0
  14. package/dist/esm/decorators/after/after-decorator.spec.js +115 -0
  15. package/dist/esm/decorators/after/after-metadata.d.ts +13 -0
  16. package/dist/esm/decorators/after/after-metadata.js +5 -0
  17. package/dist/esm/decorators/after/after-reflector.d.ts +22 -0
  18. package/dist/esm/decorators/after/after-reflector.js +29 -0
  19. package/dist/esm/decorators/after/after-reflector.spec.d.ts +1 -0
  20. package/dist/esm/decorators/after/after-reflector.spec.js +102 -0
  21. package/dist/esm/decorators/after/index.d.ts +3 -0
  22. package/dist/esm/decorators/after/index.js +3 -0
  23. package/dist/esm/decorators/before/before-decorator.d.ts +9 -0
  24. package/dist/esm/decorators/before/before-decorator.js +22 -0
  25. package/dist/esm/decorators/before/before-decorator.spec.d.ts +1 -0
  26. package/dist/esm/decorators/before/before-decorator.spec.js +115 -0
  27. package/dist/esm/decorators/before/before-metadata.d.ts +13 -0
  28. package/dist/esm/decorators/before/before-metadata.js +5 -0
  29. package/dist/esm/decorators/before/before-reflector.d.ts +22 -0
  30. package/dist/esm/decorators/before/before-reflector.js +29 -0
  31. package/dist/esm/decorators/before/before-reflector.spec.d.ts +1 -0
  32. package/dist/esm/decorators/before/before-reflector.spec.js +102 -0
  33. package/dist/esm/decorators/before/index.d.ts +3 -0
  34. package/dist/esm/decorators/before/index.js +3 -0
  35. package/dist/esm/decorators/controller/controller-decorator.d.ts +2 -1
  36. package/dist/esm/decorators/controller/controller-decorator.js +27 -6
  37. package/dist/esm/decorators/controller/controller-decorator.spec.js +37 -15
  38. package/dist/esm/decorators/controller/controller-metadata.d.ts +0 -1
  39. package/dist/esm/decorators/index.d.ts +2 -0
  40. package/dist/esm/decorators/index.js +2 -0
  41. package/dist/esm/decorators/request-context/request-context-decorator.d.ts +2 -3
  42. package/dist/esm/decorators/request-context/request-context-decorator.js +3 -6
  43. package/dist/esm/decorators/request-context/request-context-decorator.spec.js +2 -17
  44. package/dist/esm/decorators/request-context/request-context-metadata.d.ts +0 -1
  45. package/dist/esm/decorators/request-data/request-data-decorator.d.ts +7 -3
  46. package/dist/esm/decorators/request-data/request-data-decorator.js +16 -16
  47. package/dist/esm/decorators/request-data/request-data-decorator.spec.js +12 -10
  48. package/dist/esm/decorators/request-data/request-data-metadata.d.ts +0 -1
  49. package/dist/esm/utils/create-debugger.d.ts +35 -2
  50. package/dist/esm/utils/create-debugger.js +71 -5
  51. package/package.json +17 -17
  52. package/src/controller-registry.spec.ts +601 -275
  53. package/src/controller-registry.ts +263 -128
  54. package/src/debuggable-service.ts +1 -1
  55. package/src/decorators/action/action-decorator.spec.ts +16 -16
  56. package/src/decorators/action/action-decorator.ts +10 -12
  57. package/src/decorators/action/action-metadata.ts +0 -1
  58. package/src/decorators/after/after-decorator.spec.ts +92 -0
  59. package/src/decorators/after/after-decorator.ts +40 -0
  60. package/src/decorators/after/after-metadata.ts +17 -0
  61. package/src/decorators/after/after-reflector.spec.ts +107 -0
  62. package/src/decorators/after/after-reflector.ts +45 -0
  63. package/src/decorators/after/index.ts +3 -0
  64. package/src/decorators/before/before-decorator.spec.ts +92 -0
  65. package/src/decorators/before/before-decorator.ts +40 -0
  66. package/src/decorators/before/before-metadata.ts +17 -0
  67. package/src/decorators/before/before-reflector.spec.ts +111 -0
  68. package/src/decorators/before/before-reflector.ts +50 -0
  69. package/src/decorators/before/index.ts +3 -0
  70. package/src/decorators/controller/controller-decorator.spec.ts +33 -16
  71. package/src/decorators/controller/controller-decorator.ts +33 -6
  72. package/src/decorators/controller/controller-metadata.ts +0 -1
  73. package/src/decorators/index.ts +2 -0
  74. package/src/decorators/request-context/request-context-decorator.spec.ts +2 -15
  75. package/src/decorators/request-context/request-context-decorator.ts +3 -8
  76. package/src/decorators/request-context/request-context-metadata.ts +0 -1
  77. package/src/decorators/request-data/request-data-decorator.spec.ts +12 -11
  78. package/src/decorators/request-data/request-data-decorator.ts +41 -16
  79. package/src/decorators/request-data/request-data-metadata.ts +0 -1
  80. 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 by controller metadata.
36
+ * Get path prefix from controller root options.
38
37
  *
39
- * @param controllerMd
40
38
  * @param options
41
39
  */
42
- getPathPrefixByControllerMetadata(controllerMd: ControllerMetadata, options?: ControllerRootOptions): string;
40
+ protected getPathPrefixFromControllerRootOptions(options?: ControllerRootOptions): string;
43
41
  /**
44
- * Get pre-handlers by controller metadata.
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
- getPreHandlersByControllerMetadata(controllerMd: ControllerMetadata, options?: ControllerRootOptions): RouteHandler[];
52
+ protected getPreHandlersFromControllerRootOptions(options?: ControllerRootOptions): RouteHandler[];
50
53
  /**
51
- * Get post-handlers by controller metadata.
54
+ * Getting post-handlers from controller root options.
52
55
  *
53
- * @param controllerMd
54
56
  * @param options
55
57
  */
56
- getPostHandlersByControllerMetadata(controllerMd: ControllerMetadata, options?: ControllerRootOptions): RoutePostHandler[];
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
- this.debug('Adding controller %s.', ctor.name);
41
+ debug('Adding controller %s.', ctor.name);
39
42
  // определение префикса применяемого
40
43
  // к маршрутам контроллера
41
- const pathPrefix = this.getPathPrefixByControllerMetadata(controllerMd, options);
42
- this.debug('Path prefix is %v.', pathPrefix);
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 = this.getPreHandlersByControllerMetadata(controllerMd, options);
45
- this.debug('%v total pre-handlers found.', preHandlers.length);
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 = this.getPostHandlersByControllerMetadata(controllerMd, options);
48
- this.debug('%v total post-handlers found.', postHandlers.length);
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
- this.debug('%v actions found.', actionsMd.size);
67
+ debug('%v actions found.', actionsMd.size);
53
68
  const router = this.getService(TrieRouter);
54
69
  actionsMd.forEach((actionMd, actionName) => {
55
- this.debug('Adding route for %s.%s.', ctor.name, actionName);
70
+ debug('Adding route for %s.%s.', ctor.name, actionName);
56
71
  // подготовка пути маршрута с префиксом
57
- this.debug('Route path is %v.', actionMd.path);
58
- const prefixedRoutePath = `${pathPrefix}/${actionMd.path}`.replace(/\/\//g, '/');
59
- this.debug('Prefixed route path is %v.', prefixedRoutePath);
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 = Array.isArray(actionMd.before)
62
- ? actionMd.before
63
- : actionMd.before
64
- ? [actionMd.before]
65
- : [];
66
- this.debug('%v action pre-handlers found.', actionPreHandlers.length);
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 = Array.isArray(actionMd.after)
70
- ? actionMd.after
71
- : actionMd.after
72
- ? [actionMd.after]
73
- : [];
74
- this.debug('%v action post-handlers found.', actionPostHandlers.length);
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: mergedPreHandlers,
96
+ preHandler: actionPreHandlers,
82
97
  handler: routeHandler,
83
- postHandler: mergedPostHandlers,
98
+ postHandler: actionPostHandlers,
84
99
  });
85
- this.debug('Route %s %v is added.', actionMd.method.toUpperCase(), prefixedRoutePath);
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 by controller metadata.
114
+ * Get path prefix from controller root options.
100
115
  *
101
- * @param controllerMd
102
116
  * @param options
103
117
  */
104
- getPathPrefixByControllerMetadata(controllerMd, options) {
105
- const rootPathPrefix = options?.pathPrefix || '';
106
- this.debug('Root path prefix is %v.', rootPathPrefix);
107
- const controllerPathPrefix = controllerMd.path || '';
108
- this.debug('Controller path prefix is %v.', controllerPathPrefix);
109
- const mergedPathPrefix = `/${rootPathPrefix}/${controllerPathPrefix}`
110
- .replace(/\/\//g, '/')
111
- .replace(/\/$/, '');
112
- this.debug('Merged path prefix is %v.', mergedPathPrefix);
113
- return mergedPathPrefix;
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
- * Get pre-handlers by controller metadata.
142
+ * Getting pre-handlers from controller root options.
117
143
  *
118
- * @param controllerMd
119
144
  * @param options
120
145
  */
121
- getPreHandlersByControllerMetadata(controllerMd, options) {
122
- // подготовка дополнительных
123
- // pre-обработчиков запроса
124
- let rootPreHandlers = [];
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
- rootPreHandlers = Array.isArray(options?.before)
127
- ? options.before
128
- : [options.before];
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
- * Get post-handlers by controller metadata.
156
+ * Getting post-handlers from controller root options.
146
157
  *
147
- * @param controllerMd
148
158
  * @param options
149
159
  */
150
- getPostHandlersByControllerMetadata(controllerMd, options) {
151
- // подготовка дополнительных
152
- // post-обработчиков запроса
153
- let rootPostHandlers = [];
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
- rootPostHandlers = Array.isArray(options.after)
156
- ? options.after
157
- : [options.after];
158
- this.debug('%v root post-handlers found.', rootPostHandlers.length);
159
- // подготовка post-обработчиков
160
- // запроса контроллера
161
- let ctlPostHandlers = [];
162
- if (controllerMd.after)
163
- ctlPostHandlers = Array.isArray(controllerMd.after)
164
- ? controllerMd.after
165
- : [controllerMd.after];
166
- this.debug('%v controller post-handlers found.', ctlPostHandlers.length);
167
- // подготовка объединенного набора
168
- // post-обработчиков запроса
169
- const mergedPostHandlers = [...rootPostHandlers, ...ctlPostHandlers];
170
- this.debug('%v merged post-handlers.', mergedPostHandlers.length);
171
- return mergedPostHandlers;
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('Creating route handler for %s.%s.', controllerCtor.name, actionName);
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
- this.debug('Executing route handler for %s.%s.', controllerCtor.name, actionName);
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
- this.debug('Argument %v has request context metadata.', index);
334
+ debug('Argument %v has request context metadata.', index);
197
335
  // если свойство контекста не определено,
198
336
  // то используем весь объект контекста
199
337
  // в качестве значения текущего аргумента
200
338
  if (requestContextMd.property == null) {
201
- this.debug('Request context property is not specified.');
202
- this.debug('Argument %v is set to %v.', index, requestContext);
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
- this.debug('Request context property is %v.', propName);
211
- this.debug('Argument %v is set to %v.', index, propValue);
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
- this.debug('No RequestContextMetadata specified for %v argument.', index);
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
- this.debug('Argument %v has request data metadata.', index);
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
- this.debug('Request data source is %v.', requestDataMd.source);
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
- this.debug('Data type casting is passed.');
388
+ debug('Data type casting is passed.');
251
389
  dataValidator.validate(data, requestDataMd.schema, requestDataMd.source);
252
- this.debug('Data validation is passed.');
390
+ debug('Data validation is passed.');
253
391
  }
254
392
  // если свойство данных не определено,
255
393
  // то используем весь объекта данных
256
394
  // в качестве значения текущего аргумента
257
395
  if (requestDataMd.property == null) {
258
- this.debug('Request data property is not specified.');
259
- this.debug('Argument %v is set to %v.', index, data);
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
- this.debug('Request data property is %v.', propName);
269
- this.debug('Argument %v is set to %v.', index, propValue);
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
- this.debug('No RequestDataMetadata specified for %v argument.', index);
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('%v is created.', this.constructor);
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 alias options.
15
+ * Action method options.
16
16
  */
17
- type ActionAliasOptions = Flatten<Omit<ActionOptions, 'method' | 'path'>>;
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?: ActionAliasOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
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?: ActionAliasOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
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?: ActionAliasOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
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?: ActionAliasOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
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?: ActionAliasOptions) => (target: Prototype<object>, propertyKey: string, descriptor: PropertyDescriptor) => void;
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
- const metadata = {
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
  /**