@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
@@ -4,14 +4,15 @@ import {Errorf} from '@e22m4u/js-format';
4
4
  import {TrieRouter} from '@e22m4u/js-trie-router';
5
5
  import {RouteHandler} from '@e22m4u/js-trie-router';
6
6
  import {DataValidator} from '@e22m4u/ts-data-schema';
7
+ import {AfterReflector} from './decorators/index.js';
7
8
  import {DataTypeCaster} from '@e22m4u/ts-data-schema';
8
9
  import {ActionReflector} from './decorators/index.js';
10
+ import {BeforeReflector} from './decorators/index.js';
9
11
  import {NotAControllerError} from './errors/index.js';
10
12
  import {RequestContext} from '@e22m4u/js-trie-router';
11
13
  import {RoutePreHandler} from '@e22m4u/js-trie-router';
12
14
  import {RoutePostHandler} from '@e22m4u/js-trie-router';
13
15
  import {RequestDataSource} from './decorators/index.js';
14
- import {ControllerMetadata} from './decorators/index.js';
15
16
  import {DebuggableService} from './debuggable-service.js';
16
17
  import {ControllerReflector} from './decorators/index.js';
17
18
  import {RequestDataReflector} from './decorators/index.js';
@@ -45,6 +46,7 @@ export class ControllerRegistry extends DebuggableService {
45
46
  ctor: Constructor<T>,
46
47
  options?: ControllerRootOptions,
47
48
  ): this {
49
+ const debug = this.debug.bind(this.addController.name);
48
50
  // проверка повторной регистрации помогает
49
51
  // заметить ошибку в коде, который использует
50
52
  // интерфейс данного сервиса
@@ -55,66 +57,66 @@ export class ControllerRegistry extends DebuggableService {
55
57
  // метаданных применяемых декоратором
56
58
  const controllerMd = ControllerReflector.getMetadata(ctor);
57
59
  if (!controllerMd) throw new NotAControllerError(ctor);
58
- this.debug('Adding controller %s.', ctor.name);
60
+ debug('Adding controller %s.', ctor.name);
59
61
  // определение префикса применяемого
60
62
  // к маршрутам контроллера
61
- const pathPrefix = this.getPathPrefixByControllerMetadata(
62
- controllerMd,
63
- options,
64
- );
65
- this.debug('Path prefix is %v.', pathPrefix);
63
+ let pathPrefix = '';
64
+ pathPrefix += this.getPathPrefixFromControllerRootOptions(options);
65
+ pathPrefix += '/';
66
+ pathPrefix += this.getPathPrefixFromControllerMetadata(ctor);
67
+ pathPrefix = pathPrefix.replace(/\/{2,}/g, '/').replace(/\/$/, '');
68
+ debug('Controller path prefix is %v.', pathPrefix);
66
69
  // подготовка pre-обработчиков
67
- const preHandlers = this.getPreHandlersByControllerMetadata(
68
- controllerMd,
69
- options,
70
- );
71
- this.debug('%v total pre-handlers found.', preHandlers.length);
70
+ const preHandlers = [
71
+ ...this.getPreHandlersFromControllerRootOptions(options),
72
+ ...this.getPreHandlersFromBeforeMetadata(ctor),
73
+ ...this.getPreHandlersFromControllerMetadata(ctor),
74
+ ];
75
+ debug('Controller has %v pre-handlers.', preHandlers.length);
72
76
  // подготовка post-обработчиков
73
- const postHandlers = this.getPostHandlersByControllerMetadata(
74
- controllerMd,
75
- options,
76
- );
77
- this.debug('%v total post-handlers found.', postHandlers.length);
77
+ const postHandlers = [
78
+ ...this.getPostHandlersFromControllerRootOptions(options),
79
+ ...this.getPostHandlersFromAfterMetadata(ctor),
80
+ ...this.getPostHandlersFromControllerMetadata(ctor),
81
+ ];
82
+ debug('Controller has %v post-handlers.', postHandlers.length);
78
83
  // обход всех операций контроллера
79
84
  // для определения маршрутов
80
85
  const actionsMd = ActionReflector.getMetadata(ctor);
81
- this.debug('%v actions found.', actionsMd.size);
86
+ debug('%v actions found.', actionsMd.size);
82
87
  const router = this.getService(TrieRouter);
83
88
  actionsMd.forEach((actionMd, actionName) => {
84
- this.debug('Adding route for %s.%s.', ctor.name, actionName);
89
+ debug('Adding route for %s.%s.', ctor.name, actionName);
85
90
  // подготовка пути маршрута с префиксом
86
- this.debug('Route path is %v.', actionMd.path);
87
- const prefixedRoutePath = `${pathPrefix}/${actionMd.path}`.replace(
88
- /\/\//g,
89
- '/',
90
- );
91
- this.debug('Prefixed route path is %v.', prefixedRoutePath);
91
+ debug('Route path is %v.', actionMd.path);
92
+ const prefixedRoutePath = `${pathPrefix}/${actionMd.path}`
93
+ .replace(/\/{2,}/g, '/')
94
+ .replace(/\/$/, '');
95
+ debug('Prefixed route path is %v.', prefixedRoutePath);
92
96
  // подготовка pre-обработчиков операции
93
- const actionPreHandlers = Array.isArray(actionMd.before)
94
- ? actionMd.before
95
- : actionMd.before
96
- ? [actionMd.before]
97
- : [];
98
- this.debug('%v action pre-handlers found.', actionPreHandlers.length);
99
- const mergedPreHandlers = [...preHandlers, ...actionPreHandlers];
97
+ const actionPreHandlers = [
98
+ ...preHandlers,
99
+ ...this.getPreHandlersFromBeforeMetadata(ctor, actionName),
100
+ ...this.getPreHandlersFromActionMetadata(ctor, actionName),
101
+ ];
102
+ debug('%v action pre-handlers in total.', actionPreHandlers.length);
100
103
  // подготовка post-обработчиков операции
101
- const actionPostHandlers = Array.isArray(actionMd.after)
102
- ? actionMd.after
103
- : actionMd.after
104
- ? [actionMd.after]
105
- : [];
106
- this.debug('%v action post-handlers found.', actionPostHandlers.length);
107
- const mergedPostHandlers = [...postHandlers, ...actionPostHandlers];
104
+ const actionPostHandlers = [
105
+ ...postHandlers,
106
+ ...this.getPostHandlersFromAfterMetadata(ctor, actionName),
107
+ ...this.getPostHandlersFromActionMetadata(ctor, actionName),
108
+ ];
109
+ debug('%v action post-handlers in total.', actionPostHandlers.length);
108
110
  // подготовка обработчика маршрута
109
111
  const routeHandler = this.createRouteHandler(ctor, actionName);
110
112
  router.defineRoute({
111
113
  method: actionMd.method,
112
114
  path: prefixedRoutePath,
113
- preHandler: mergedPreHandlers,
115
+ preHandler: actionPreHandlers,
114
116
  handler: routeHandler,
115
- postHandler: mergedPostHandlers,
117
+ postHandler: actionPostHandlers,
116
118
  });
117
- this.debug(
119
+ debug(
118
120
  'Route %s %v is added.',
119
121
  actionMd.method.toUpperCase(),
120
122
  prefixedRoutePath,
@@ -134,90 +136,229 @@ export class ControllerRegistry extends DebuggableService {
134
136
  }
135
137
 
136
138
  /**
137
- * Get path prefix by controller metadata.
139
+ * Get path prefix from controller root options.
138
140
  *
139
- * @param controllerMd
140
141
  * @param options
141
142
  */
142
- getPathPrefixByControllerMetadata(
143
- controllerMd: ControllerMetadata,
143
+ protected getPathPrefixFromControllerRootOptions(
144
144
  options?: ControllerRootOptions,
145
145
  ) {
146
- const rootPathPrefix = options?.pathPrefix || '';
147
- this.debug('Root path prefix is %v.', rootPathPrefix);
148
- const controllerPathPrefix = controllerMd.path || '';
149
- this.debug('Controller path prefix is %v.', controllerPathPrefix);
150
- const mergedPathPrefix = `/${rootPathPrefix}/${controllerPathPrefix}`
151
- .replace(/\/\//g, '/')
152
- .replace(/\/$/, '');
153
- this.debug('Merged path prefix is %v.', mergedPathPrefix);
154
- return mergedPathPrefix;
146
+ const debug = this.debug.bind(
147
+ this.getPathPrefixFromControllerRootOptions.name,
148
+ );
149
+ debug('Getting path prefix from controller root options.');
150
+ const res = options?.pathPrefix || '';
151
+ debug('Controller path prefix is %v.', res);
152
+ return res;
153
+ }
154
+
155
+ /**
156
+ * Get path prefix from controller metadata.
157
+ *
158
+ * @param ctor
159
+ */
160
+ protected getPathPrefixFromControllerMetadata<T>(ctor: Constructor<T>) {
161
+ const debug = this.debug.bind(
162
+ this.getPathPrefixFromControllerMetadata.name,
163
+ );
164
+ debug('Getting path prefix from @controller metadata.');
165
+ debug('Metadata target is %s.', ctor.name);
166
+ const md = ControllerReflector.getMetadata(ctor);
167
+ if (!md) throw new Errorf('Controller %v has no metadata.', ctor);
168
+ const res = md.path || '';
169
+ debug('Controller path prefix is %v.', res);
170
+ return md.path || '';
155
171
  }
156
172
 
157
173
  /**
158
- * Get pre-handlers by controller metadata.
174
+ * Getting pre-handlers from controller root options.
159
175
  *
160
- * @param controllerMd
161
176
  * @param options
162
177
  */
163
- getPreHandlersByControllerMetadata(
164
- controllerMd: ControllerMetadata,
178
+ protected getPreHandlersFromControllerRootOptions(
165
179
  options?: ControllerRootOptions,
166
180
  ) {
167
- // подготовка дополнительных
168
- // pre-обработчиков запроса
169
- let rootPreHandlers: RoutePreHandler[] = [];
181
+ const debug = this.debug.bind(
182
+ this.getPreHandlersFromControllerRootOptions.name,
183
+ );
184
+ debug('Getting pre-handlers from controller root options.');
185
+ let res: RoutePreHandler[] = [];
170
186
  if (options?.before)
171
- rootPreHandlers = Array.isArray(options?.before)
172
- ? options.before
173
- : [options.before];
174
- this.debug('%v root pre-handlers found.', rootPreHandlers.length);
175
- // подготовка pre-обработчиков
176
- // запроса контроллера
177
- let ctlPreHandlers: RoutePreHandler[] = [];
178
- if (controllerMd.before)
179
- ctlPreHandlers = Array.isArray(controllerMd.before)
180
- ? controllerMd.before
181
- : [controllerMd.before];
182
- this.debug('%v controller pre-handlers found.', ctlPreHandlers.length);
183
- // подготовка объединенного набора
184
- // pre-обработчиков запроса
185
- const mergedPreHandlers = [...rootPreHandlers, ...ctlPreHandlers];
186
- this.debug('%v merged pre-handlers.', mergedPreHandlers.length);
187
- return mergedPreHandlers;
187
+ res = Array.isArray(options.before) ? options.before : [options.before];
188
+ debug('%v pre-handlers found.', res.length);
189
+ return res;
188
190
  }
189
191
 
190
192
  /**
191
- * Get post-handlers by controller metadata.
193
+ * Getting post-handlers from controller root options.
192
194
  *
193
- * @param controllerMd
194
195
  * @param options
195
196
  */
196
- getPostHandlersByControllerMetadata(
197
- controllerMd: ControllerMetadata,
197
+ protected getPostHandlersFromControllerRootOptions(
198
198
  options?: ControllerRootOptions,
199
199
  ) {
200
- // подготовка дополнительных
201
- // post-обработчиков запроса
202
- let rootPostHandlers: RoutePostHandler[] = [];
200
+ const debug = this.debug.bind(
201
+ this.getPostHandlersFromControllerRootOptions.name,
202
+ );
203
+ debug('Getting post-handlers from controller root options.');
204
+ let res: RoutePostHandler[] = [];
203
205
  if (options?.after)
204
- rootPostHandlers = Array.isArray(options.after)
205
- ? options.after
206
- : [options.after];
207
- this.debug('%v root post-handlers found.', rootPostHandlers.length);
208
- // подготовка post-обработчиков
209
- // запроса контроллера
210
- let ctlPostHandlers: RoutePostHandler[] = [];
211
- if (controllerMd.after)
212
- ctlPostHandlers = Array.isArray(controllerMd.after)
213
- ? controllerMd.after
214
- : [controllerMd.after];
215
- this.debug('%v controller post-handlers found.', ctlPostHandlers.length);
216
- // подготовка объединенного набора
217
- // post-обработчиков запроса
218
- const mergedPostHandlers = [...rootPostHandlers, ...ctlPostHandlers];
219
- this.debug('%v merged post-handlers.', mergedPostHandlers.length);
220
- return mergedPostHandlers;
206
+ res = Array.isArray(options.after) ? options.after : [options.after];
207
+ debug('%v post-handlers found.', res.length);
208
+ return res;
209
+ }
210
+
211
+ /**
212
+ * Get pre-handlers from before metadata.
213
+ *
214
+ * @param ctor
215
+ * @param actionName
216
+ */
217
+ protected getPreHandlersFromBeforeMetadata<T>(
218
+ ctor: Constructor<T>,
219
+ actionName?: string,
220
+ ) {
221
+ const debug = this.debug.bind(this.getPreHandlersFromBeforeMetadata.name);
222
+ debug('Getting pre-handlers from @before metadata.');
223
+ if (actionName) {
224
+ debug('Target is %s.%s.', ctor.name, actionName);
225
+ } else {
226
+ debug('Target is %s.', ctor.name);
227
+ }
228
+ let preHandlers: RoutePreHandler[] = [];
229
+ const mdArray = BeforeReflector.getMetadata(ctor, actionName);
230
+ mdArray.forEach(md => {
231
+ if (Array.isArray(md.middleware)) {
232
+ preHandlers = [...preHandlers, ...md.middleware];
233
+ } else {
234
+ preHandlers.push(md.middleware);
235
+ }
236
+ });
237
+ if (mdArray.length) {
238
+ debug('%v pre-handlers found.', mdArray.length);
239
+ } else {
240
+ debug('No pre-handlers found.');
241
+ }
242
+ return preHandlers;
243
+ }
244
+
245
+ /**
246
+ * Get post-handlers from after metadata.
247
+ *
248
+ * @param ctor
249
+ * @param actionName
250
+ */
251
+ protected getPostHandlersFromAfterMetadata<T>(
252
+ ctor: Constructor<T>,
253
+ actionName?: string,
254
+ ) {
255
+ const debug = this.debug.bind(this.getPostHandlersFromAfterMetadata.name);
256
+ debug('Getting post-handlers from @after metadata.');
257
+ if (actionName) {
258
+ debug('Target is %s.%s.', ctor.name, actionName);
259
+ } else {
260
+ debug('Target is %s.', ctor.name);
261
+ }
262
+ let res: RoutePostHandler[] = [];
263
+ const mdArray = AfterReflector.getMetadata(ctor, actionName);
264
+ mdArray.forEach(md => {
265
+ if (Array.isArray(md.middleware)) {
266
+ res = [...res, ...md.middleware];
267
+ } else {
268
+ res.push(md.middleware);
269
+ }
270
+ });
271
+ if (mdArray.length) {
272
+ debug('%v post-handlers found.', mdArray.length);
273
+ } else {
274
+ debug('No post-handlers found.');
275
+ }
276
+ return res;
277
+ }
278
+
279
+ /**
280
+ * Get pre-handlers from controller metadata.
281
+ *
282
+ * @param ctor
283
+ */
284
+ protected getPreHandlersFromControllerMetadata<T>(ctor: Constructor<T>) {
285
+ const debug = this.debug.bind(
286
+ this.getPreHandlersFromControllerMetadata.name,
287
+ );
288
+ debug('Getting pre-handlers from @controller metadata.');
289
+ debug('Target is %s.', ctor.name);
290
+ const md = ControllerReflector.getMetadata(ctor);
291
+ if (!md) throw new Errorf('Controller %v has no metadata.', ctor);
292
+ let res: RoutePreHandler[] = [];
293
+ if (md.before) res = Array.isArray(md.before) ? md.before : [md.before];
294
+ debug('%v pre-handlers found.', res.length);
295
+ return res;
296
+ }
297
+
298
+ /**
299
+ * Get post-handlers from controller metadata.
300
+ *
301
+ * @param ctor
302
+ */
303
+ protected getPostHandlersFromControllerMetadata<T>(ctor: Constructor<T>) {
304
+ const debug = this.debug.bind(
305
+ this.getPostHandlersFromControllerMetadata.name,
306
+ );
307
+ debug('Getting post-handlers from @controller metadata.');
308
+ const md = ControllerReflector.getMetadata(ctor);
309
+ if (!md) throw new Errorf('Controller %v has no metadata.', ctor);
310
+ let res: RoutePostHandler[] = [];
311
+ if (md.after) res = Array.isArray(md.after) ? md.after : [md.after];
312
+ debug('%v post-handlers found.', res.length);
313
+ return res;
314
+ }
315
+
316
+ /**
317
+ * Get pre-handlers from action metadata.
318
+ *
319
+ * @param ctor
320
+ * @param actionName
321
+ */
322
+ protected getPreHandlersFromActionMetadata<T>(
323
+ ctor: Constructor<T>,
324
+ actionName: string,
325
+ ) {
326
+ const debug = this.debug.bind(this.getPreHandlersFromActionMetadata.name);
327
+ debug('Getting pre-handlers from @action metadata.');
328
+ const actionsMd = ActionReflector.getMetadata(ctor);
329
+ const actionMd = actionsMd.get(actionName);
330
+ if (!actionMd)
331
+ throw new Errorf('Action %s.%s has no metadata.', ctor.name, actionName);
332
+ let res: RoutePreHandler[] = [];
333
+ if (actionMd.before)
334
+ res = Array.isArray(actionMd.before)
335
+ ? actionMd.before
336
+ : [actionMd.before];
337
+ debug('%v pre-handlers found.', res.length);
338
+ return res;
339
+ }
340
+
341
+ /**
342
+ * Get post-handlers from action metadata.
343
+ *
344
+ * @param ctor
345
+ * @param actionName
346
+ */
347
+ protected getPostHandlersFromActionMetadata<T>(
348
+ ctor: Constructor<T>,
349
+ actionName: string,
350
+ ) {
351
+ const debug = this.debug.bind(this.getPreHandlersFromActionMetadata.name);
352
+ debug('Getting post-handlers from @action metadata.');
353
+ const actionsMd = ActionReflector.getMetadata(ctor);
354
+ const actionMd = actionsMd.get(actionName);
355
+ if (!actionMd)
356
+ throw new Errorf('Action %s.%s has no metadata.', ctor.name, actionName);
357
+ let res: RoutePostHandler[] = [];
358
+ if (actionMd.after)
359
+ res = Array.isArray(actionMd.after) ? actionMd.after : [actionMd.after];
360
+ debug('%v pre-handlers found.', res.length);
361
+ return res;
221
362
  }
222
363
 
223
364
  /**
@@ -227,15 +368,12 @@ export class ControllerRegistry extends DebuggableService {
227
368
  * @param actionName
228
369
  * @protected
229
370
  */
230
- createRouteHandler<T extends object>(
371
+ protected createRouteHandler<T extends object>(
231
372
  controllerCtor: Constructor<T>,
232
373
  actionName: string,
233
374
  ): RouteHandler {
234
- this.debug(
235
- 'Creating route handler for %s.%s.',
236
- controllerCtor.name,
237
- actionName,
238
- );
375
+ const debug = this.debug.bind(this.createRouteHandler.name);
376
+ debug('Creating route handler for %s.%s.', controllerCtor.name, actionName);
239
377
  const requestContextMetadataMap = RequestContextReflector.getMetadata(
240
378
  controllerCtor,
241
379
  actionName,
@@ -248,7 +386,7 @@ export class ControllerRegistry extends DebuggableService {
248
386
  const dataTypeCaster = this.getService(DataTypeCaster);
249
387
  const dataValidator = this.getService(DataValidator);
250
388
  return (requestContext: RequestContext) => {
251
- this.debug(
389
+ debug(
252
390
  'Executing route handler for %s.%s.',
253
391
  controllerCtor.name,
254
392
  actionName,
@@ -260,13 +398,13 @@ export class ControllerRegistry extends DebuggableService {
260
398
  // значениями из контекста запроса
261
399
  const requestContextMd = requestContextMetadataMap.get(index);
262
400
  if (requestContextMd != null) {
263
- this.debug('Argument %v has request context metadata.', index);
401
+ debug('Argument %v has request context metadata.', index);
264
402
  // если свойство контекста не определено,
265
403
  // то используем весь объект контекста
266
404
  // в качестве значения текущего аргумента
267
405
  if (requestContextMd.property == null) {
268
- this.debug('Request context property is not specified.');
269
- this.debug('Argument %v is set to %v.', index, requestContext);
406
+ debug('Request context property is not specified.');
407
+ debug('Argument %v is set to %v.', index, requestContext);
270
408
  return requestContext;
271
409
  }
272
410
  // если свойство контекста определено,
@@ -274,11 +412,11 @@ export class ControllerRegistry extends DebuggableService {
274
412
  // в качестве текущего аргумента
275
413
  const propName = requestContextMd.property;
276
414
  const propValue = requestContext[propName];
277
- this.debug('Request context property is %v.', propName);
278
- this.debug('Argument %v is set to %v.', index, propValue);
415
+ debug('Request context property is %v.', propName);
416
+ debug('Argument %v is set to %v.', index, propValue);
279
417
  return propValue;
280
418
  } else {
281
- this.debug(
419
+ debug(
282
420
  'No RequestContextMetadata specified for %v argument.',
283
421
  index,
284
422
  );
@@ -287,7 +425,7 @@ export class ControllerRegistry extends DebuggableService {
287
425
  // значениями из данных запроса
288
426
  const requestDataMd = requestDataMetadataMap.get(index);
289
427
  if (requestDataMd != null) {
290
- this.debug('Argument %v has request data metadata.', index);
428
+ debug('Argument %v has request data metadata.', index);
291
429
  // получение данных
292
430
  // согласно источнику
293
431
  let data: unknown;
@@ -308,7 +446,7 @@ export class ControllerRegistry extends DebuggableService {
308
446
  data = requestContext.body;
309
447
  break;
310
448
  }
311
- this.debug('Request data source is %v.', requestDataMd.source);
449
+ debug('Request data source is %v.', requestDataMd.source);
312
450
  // при наличии схемы данных выполняется
313
451
  // их конвертация и валидация
314
452
  if (requestDataMd.schema) {
@@ -316,20 +454,20 @@ export class ControllerRegistry extends DebuggableService {
316
454
  noTypeCastError: true,
317
455
  sourcePath: requestDataMd.source,
318
456
  });
319
- this.debug('Data type casting is passed.');
457
+ debug('Data type casting is passed.');
320
458
  dataValidator.validate(
321
459
  data,
322
460
  requestDataMd.schema,
323
461
  requestDataMd.source,
324
462
  );
325
- this.debug('Data validation is passed.');
463
+ debug('Data validation is passed.');
326
464
  }
327
465
  // если свойство данных не определено,
328
466
  // то используем весь объекта данных
329
467
  // в качестве значения текущего аргумента
330
468
  if (requestDataMd.property == null) {
331
- this.debug('Request data property is not specified.');
332
- this.debug('Argument %v is set to %v.', index, data);
469
+ debug('Request data property is not specified.');
470
+ debug('Argument %v is set to %v.', index, data);
333
471
  return data;
334
472
  }
335
473
  // если свойство данных определено,
@@ -338,14 +476,11 @@ export class ControllerRegistry extends DebuggableService {
338
476
  const dataAsObject = data as Record<string, unknown>;
339
477
  const propName = requestDataMd.property;
340
478
  const propValue = dataAsObject[propName];
341
- this.debug('Request data property is %v.', propName);
342
- this.debug('Argument %v is set to %v.', index, propValue);
479
+ debug('Request data property is %v.', propName);
480
+ debug('Argument %v is set to %v.', index, propValue);
343
481
  return propValue;
344
482
  } else {
345
- this.debug(
346
- 'No RequestDataMetadata specified for %v argument.',
347
- index,
348
- );
483
+ debug('No RequestDataMetadata specified for %v argument.', index);
349
484
  }
350
485
  });
351
486
  // выполнение операции контроллера
@@ -22,6 +22,6 @@ export class DebuggableService extends Service {
22
22
  super(container);
23
23
  const serviceName = toCamelCase(this.constructor.name);
24
24
  this.debug = createDebugger(serviceName);
25
- this.debug('%v is created.', this.constructor);
25
+ this.debug.bind('constructor')('Service created.');
26
26
  }
27
27
  }
@@ -5,38 +5,38 @@ import {ActionReflector} from './action-reflector.js';
5
5
 
6
6
  describe('action', function () {
7
7
  it('sets given options to the target metadata', function () {
8
- const method = HttpMethod.GET;
9
- const path = 'myPath';
10
- const before = () => undefined;
11
- const after = () => undefined;
12
- const customOption = 'customOption';
8
+ const options = {
9
+ method: HttpMethod.GET,
10
+ path: 'myPath',
11
+ before: () => undefined,
12
+ after: () => undefined,
13
+ customOption: 'customOption',
14
+ };
13
15
  class Target {
14
- @action({method, path, before, after, customOption})
16
+ @action(options)
15
17
  method() {}
16
18
  }
17
19
  const res = ActionReflector.getMetadata(Target);
18
20
  expect(res.get('method')).to.be.eql({
21
+ ...options,
19
22
  propertyKey: 'method',
20
- method,
21
- path,
22
- before,
23
- after,
24
- customOption,
25
23
  });
26
24
  });
27
25
 
28
26
  it('overrides a given "propertyKey" option by the target method name', function () {
29
- const method = HttpMethod.GET;
30
- const path = 'myPath';
27
+ const options = {
28
+ propertyKey: 'myMethod',
29
+ method: HttpMethod.GET,
30
+ path: 'myPath',
31
+ };
31
32
  class Target {
32
- @action({propertyKey: 'myMethod', method, path})
33
+ @action(options)
33
34
  method() {}
34
35
  }
35
36
  const res = ActionReflector.getMetadata(Target);
36
37
  expect(res.get('method')).to.be.eql({
38
+ ...options,
37
39
  propertyKey: 'method',
38
- method,
39
- path,
40
40
  });
41
41
  });
42
42
  });