@e22m4u/ts-rest-router 0.0.2

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 (145) hide show
  1. package/.c8rc +9 -0
  2. package/.commitlintrc +5 -0
  3. package/.editorconfig +13 -0
  4. package/.husky/commit-msg +1 -0
  5. package/.husky/pre-commit +6 -0
  6. package/.mocharc.json +5 -0
  7. package/.prettierrc +7 -0
  8. package/LICENSE +21 -0
  9. package/README-ru.md +41 -0
  10. package/README.md +41 -0
  11. package/build-cjs.js +16 -0
  12. package/dist/cjs/index.cjs +692 -0
  13. package/dist/esm/controller-registry.d.ts +65 -0
  14. package/dist/esm/controller-registry.js +281 -0
  15. package/dist/esm/controller-registry.spec.d.ts +1 -0
  16. package/dist/esm/controller-registry.spec.js +719 -0
  17. package/dist/esm/debuggable-service.d.ts +18 -0
  18. package/dist/esm/debuggable-service.js +23 -0
  19. package/dist/esm/debuggable-service.spec.d.ts +1 -0
  20. package/dist/esm/debuggable-service.spec.js +16 -0
  21. package/dist/esm/decorators/action/action-decorator.d.ts +53 -0
  22. package/dist/esm/decorators/action/action-decorator.js +66 -0
  23. package/dist/esm/decorators/action/action-decorator.spec.d.ts +1 -0
  24. package/dist/esm/decorators/action/action-decorator.spec.js +59 -0
  25. package/dist/esm/decorators/action/action-metadata.d.ts +23 -0
  26. package/dist/esm/decorators/action/action-metadata.js +5 -0
  27. package/dist/esm/decorators/action/action-reflector.d.ts +22 -0
  28. package/dist/esm/decorators/action/action-reflector.js +29 -0
  29. package/dist/esm/decorators/action/action-reflector.spec.d.ts +1 -0
  30. package/dist/esm/decorators/action/action-reflector.spec.js +84 -0
  31. package/dist/esm/decorators/action/index.d.ts +3 -0
  32. package/dist/esm/decorators/action/index.js +3 -0
  33. package/dist/esm/decorators/controller/controller-decorator.d.ts +13 -0
  34. package/dist/esm/decorators/controller/controller-decorator.js +20 -0
  35. package/dist/esm/decorators/controller/controller-decorator.spec.d.ts +1 -0
  36. package/dist/esm/decorators/controller/controller-decorator.spec.js +53 -0
  37. package/dist/esm/decorators/controller/controller-metadata.d.ts +17 -0
  38. package/dist/esm/decorators/controller/controller-metadata.js +5 -0
  39. package/dist/esm/decorators/controller/controller-reflector.d.ts +20 -0
  40. package/dist/esm/decorators/controller/controller-reflector.js +24 -0
  41. package/dist/esm/decorators/controller/controller-reflector.spec.d.ts +1 -0
  42. package/dist/esm/decorators/controller/controller-reflector.spec.js +45 -0
  43. package/dist/esm/decorators/controller/index.d.ts +3 -0
  44. package/dist/esm/decorators/controller/index.js +3 -0
  45. package/dist/esm/decorators/index.d.ts +4 -0
  46. package/dist/esm/decorators/index.js +4 -0
  47. package/dist/esm/decorators/request-context/index.d.ts +3 -0
  48. package/dist/esm/decorators/request-context/index.js +3 -0
  49. package/dist/esm/decorators/request-context/request-context-decorator.d.ts +17 -0
  50. package/dist/esm/decorators/request-context/request-context-decorator.js +32 -0
  51. package/dist/esm/decorators/request-context/request-context-decorator.spec.d.ts +1 -0
  52. package/dist/esm/decorators/request-context/request-context-decorator.spec.js +59 -0
  53. package/dist/esm/decorators/request-context/request-context-metadata.d.ts +17 -0
  54. package/dist/esm/decorators/request-context/request-context-metadata.js +5 -0
  55. package/dist/esm/decorators/request-context/request-context-reflector.d.ts +24 -0
  56. package/dist/esm/decorators/request-context/request-context-reflector.js +31 -0
  57. package/dist/esm/decorators/request-context/request-context-reflector.spec.d.ts +1 -0
  58. package/dist/esm/decorators/request-context/request-context-reflector.spec.js +59 -0
  59. package/dist/esm/decorators/request-data/index.d.ts +3 -0
  60. package/dist/esm/decorators/request-data/index.js +3 -0
  61. package/dist/esm/decorators/request-data/request-data-decorator.d.ts +28 -0
  62. package/dist/esm/decorators/request-data/request-data-decorator.js +84 -0
  63. package/dist/esm/decorators/request-data/request-data-decorator.spec.d.ts +1 -0
  64. package/dist/esm/decorators/request-data/request-data-decorator.spec.js +534 -0
  65. package/dist/esm/decorators/request-data/request-data-metadata.d.ts +29 -0
  66. package/dist/esm/decorators/request-data/request-data-metadata.js +16 -0
  67. package/dist/esm/decorators/request-data/request-data-reflector.d.ts +24 -0
  68. package/dist/esm/decorators/request-data/request-data-reflector.js +31 -0
  69. package/dist/esm/decorators/request-data/request-data-reflector.spec.d.ts +1 -0
  70. package/dist/esm/decorators/request-data/request-data-reflector.spec.js +60 -0
  71. package/dist/esm/errors/index.d.ts +1 -0
  72. package/dist/esm/errors/index.js +1 -0
  73. package/dist/esm/errors/not-a-controller-error.d.ts +12 -0
  74. package/dist/esm/errors/not-a-controller-error.js +14 -0
  75. package/dist/esm/index.d.ts +5 -0
  76. package/dist/esm/index.js +5 -0
  77. package/dist/esm/rest-router.d.ts +19 -0
  78. package/dist/esm/rest-router.js +24 -0
  79. package/dist/esm/types.d.ts +57 -0
  80. package/dist/esm/types.js +2 -0
  81. package/dist/esm/utils/capitalize.d.ts +6 -0
  82. package/dist/esm/utils/capitalize.js +8 -0
  83. package/dist/esm/utils/capitalize.spec.d.ts +1 -0
  84. package/dist/esm/utils/capitalize.spec.js +8 -0
  85. package/dist/esm/utils/create-debugger.d.ts +11 -0
  86. package/dist/esm/utils/create-debugger.js +15 -0
  87. package/dist/esm/utils/create-debugger.spec.d.ts +1 -0
  88. package/dist/esm/utils/create-debugger.spec.js +8 -0
  89. package/dist/esm/utils/create-error.d.ts +10 -0
  90. package/dist/esm/utils/create-error.js +13 -0
  91. package/dist/esm/utils/create-error.spec.d.ts +1 -0
  92. package/dist/esm/utils/create-error.spec.js +8 -0
  93. package/dist/esm/utils/index.d.ts +4 -0
  94. package/dist/esm/utils/index.js +4 -0
  95. package/dist/esm/utils/to-camel-case.d.ts +6 -0
  96. package/dist/esm/utils/to-camel-case.js +11 -0
  97. package/dist/esm/utils/to-camel-case.spec.d.ts +1 -0
  98. package/dist/esm/utils/to-camel-case.spec.js +10 -0
  99. package/dist/tsconfig.tsbuildinfo +1 -0
  100. package/eslint.config.js +43 -0
  101. package/package.json +74 -0
  102. package/src/controller-registry.spec.ts +592 -0
  103. package/src/controller-registry.ts +355 -0
  104. package/src/debuggable-service.spec.ts +18 -0
  105. package/src/debuggable-service.ts +27 -0
  106. package/src/decorators/action/action-decorator.spec.ts +42 -0
  107. package/src/decorators/action/action-decorator.ts +100 -0
  108. package/src/decorators/action/action-metadata.ts +28 -0
  109. package/src/decorators/action/action-reflector.spec.ts +84 -0
  110. package/src/decorators/action/action-reflector.ts +38 -0
  111. package/src/decorators/action/index.ts +3 -0
  112. package/src/decorators/controller/controller-decorator.spec.ts +41 -0
  113. package/src/decorators/controller/controller-decorator.ts +29 -0
  114. package/src/decorators/controller/controller-metadata.ts +21 -0
  115. package/src/decorators/controller/controller-reflector.spec.ts +45 -0
  116. package/src/decorators/controller/controller-reflector.ts +28 -0
  117. package/src/decorators/controller/index.ts +3 -0
  118. package/src/decorators/index.ts +4 -0
  119. package/src/decorators/request-context/index.ts +3 -0
  120. package/src/decorators/request-context/request-context-decorator.spec.ts +41 -0
  121. package/src/decorators/request-context/request-context-decorator.ts +57 -0
  122. package/src/decorators/request-context/request-context-metadata.ts +21 -0
  123. package/src/decorators/request-context/request-context-reflector.spec.ts +77 -0
  124. package/src/decorators/request-context/request-context-reflector.ts +57 -0
  125. package/src/decorators/request-data/index.ts +3 -0
  126. package/src/decorators/request-data/request-data-decorator.spec.ts +477 -0
  127. package/src/decorators/request-data/request-data-decorator.ts +106 -0
  128. package/src/decorators/request-data/request-data-metadata.ts +34 -0
  129. package/src/decorators/request-data/request-data-reflector.spec.ts +78 -0
  130. package/src/decorators/request-data/request-data-reflector.ts +57 -0
  131. package/src/errors/index.ts +1 -0
  132. package/src/errors/not-a-controller-error.ts +15 -0
  133. package/src/index.ts +5 -0
  134. package/src/rest-router.ts +31 -0
  135. package/src/types.ts +59 -0
  136. package/src/utils/capitalize.spec.ts +9 -0
  137. package/src/utils/capitalize.ts +8 -0
  138. package/src/utils/create-debugger.spec.ts +9 -0
  139. package/src/utils/create-debugger.ts +21 -0
  140. package/src/utils/create-error.spec.ts +9 -0
  141. package/src/utils/create-error.ts +19 -0
  142. package/src/utils/index.ts +4 -0
  143. package/src/utils/to-camel-case.spec.ts +11 -0
  144. package/src/utils/to-camel-case.ts +11 -0
  145. package/tsconfig.json +17 -0
@@ -0,0 +1,65 @@
1
+ import { Constructor } from './types.js';
2
+ import { RouteHandler } from '@e22m4u/js-trie-router';
3
+ import { RoutePreHandler } from '@e22m4u/js-trie-router';
4
+ import { RoutePostHandler } from '@e22m4u/js-trie-router';
5
+ import { ControllerMetadata } from './decorators/index.js';
6
+ import { DebuggableService } from './debuggable-service.js';
7
+ /**
8
+ * Controller root options.
9
+ */
10
+ export type ControllerRootOptions = {
11
+ pathPrefix?: string;
12
+ before?: RoutePreHandler | RoutePreHandler[];
13
+ after?: RoutePostHandler | RoutePostHandler[];
14
+ };
15
+ /**
16
+ * Controller registry.
17
+ */
18
+ export declare class ControllerRegistry extends DebuggableService {
19
+ /**
20
+ * Controllers.
21
+ */
22
+ controllers: Set<unknown>;
23
+ /**
24
+ * Add controller.
25
+ *
26
+ * @param ctor
27
+ * @param options
28
+ */
29
+ addController<T extends object>(ctor: Constructor<T>, options?: ControllerRootOptions): this;
30
+ /**
31
+ * Has controller.
32
+ *
33
+ * @param ctor
34
+ */
35
+ hasController<T extends object>(ctor: Constructor<T>): boolean;
36
+ /**
37
+ * Get path prefix by controller metadata.
38
+ *
39
+ * @param controllerMd
40
+ * @param options
41
+ */
42
+ getPathPrefixByControllerMetadata(controllerMd: ControllerMetadata, options?: ControllerRootOptions): string;
43
+ /**
44
+ * Get pre-handlers by controller metadata.
45
+ *
46
+ * @param controllerMd
47
+ * @param options
48
+ */
49
+ getPreHandlersByControllerMetadata(controllerMd: ControllerMetadata, options?: ControllerRootOptions): RouteHandler[];
50
+ /**
51
+ * Get post-handlers by controller metadata.
52
+ *
53
+ * @param controllerMd
54
+ * @param options
55
+ */
56
+ getPostHandlersByControllerMetadata(controllerMd: ControllerMetadata, options?: ControllerRootOptions): RoutePostHandler[];
57
+ /**
58
+ * Create route handler.
59
+ *
60
+ * @param controllerCtor
61
+ * @param actionName
62
+ * @protected
63
+ */
64
+ createRouteHandler<T extends object>(controllerCtor: Constructor<T>, actionName: string): RouteHandler;
65
+ }
@@ -0,0 +1,281 @@
1
+ import { Errorf } from '@e22m4u/js-format';
2
+ import { TrieRouter } from '@e22m4u/js-trie-router';
3
+ import { DataValidator } from '@e22m4u/ts-data-schema';
4
+ import { DataTypeCaster } from '@e22m4u/ts-data-schema';
5
+ import { ActionReflector } from './decorators/index.js';
6
+ import { NotAControllerError } from './errors/index.js';
7
+ import { RequestDataSource } from './decorators/index.js';
8
+ import { DebuggableService } from './debuggable-service.js';
9
+ import { ControllerReflector } from './decorators/index.js';
10
+ import { RequestDataReflector } from './decorators/index.js';
11
+ import { RequestContextReflector } from './decorators/index.js';
12
+ /**
13
+ * Controller registry.
14
+ */
15
+ export class ControllerRegistry extends DebuggableService {
16
+ /**
17
+ * Controllers.
18
+ */
19
+ controllers = new Set();
20
+ /**
21
+ * Add controller.
22
+ *
23
+ * @param ctor
24
+ * @param options
25
+ */
26
+ addController(ctor, options) {
27
+ // проверка повторной регистрации помогает
28
+ // заметить ошибку в коде, который использует
29
+ // интерфейс данного сервиса
30
+ if (this.hasController(ctor))
31
+ throw new Errorf('The controller %v is already registered.');
32
+ // так как контроллером может быть любой
33
+ // класс, выполняется проверка на наличие
34
+ // метаданных применяемых декоратором
35
+ const controllerMd = ControllerReflector.getMetadata(ctor);
36
+ if (!controllerMd)
37
+ throw new NotAControllerError(ctor);
38
+ this.debug('Adding controller %s.', ctor.name);
39
+ // определение префикса применяемого
40
+ // к маршрутам контроллера
41
+ const pathPrefix = this.getPathPrefixByControllerMetadata(controllerMd, options);
42
+ this.debug('Path prefix is %v.', pathPrefix);
43
+ // подготовка pre-обработчиков
44
+ const preHandlers = this.getPreHandlersByControllerMetadata(controllerMd, options);
45
+ this.debug('%v total pre-handlers found.', preHandlers.length);
46
+ // подготовка post-обработчиков
47
+ const postHandlers = this.getPostHandlersByControllerMetadata(controllerMd, options);
48
+ this.debug('%v total post-handlers found.', postHandlers.length);
49
+ // обход всех операций контроллера
50
+ // для определения маршрутов
51
+ const actionsMd = ActionReflector.getMetadata(ctor);
52
+ this.debug('%v actions found.', actionsMd.size);
53
+ const router = this.getService(TrieRouter);
54
+ actionsMd.forEach((actionMd, actionName) => {
55
+ this.debug('Adding route for %s.%s.', ctor.name, actionName);
56
+ // подготовка пути маршрута с префиксом
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);
60
+ // подготовка 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];
68
+ // подготовка 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];
76
+ // подготовка обработчика маршрута
77
+ const routeHandler = this.createRouteHandler(ctor, actionName);
78
+ router.defineRoute({
79
+ method: actionMd.method,
80
+ path: prefixedRoutePath,
81
+ preHandler: mergedPreHandlers,
82
+ handler: routeHandler,
83
+ postHandler: mergedPostHandlers,
84
+ });
85
+ this.debug('Route %s %v is added.', actionMd.method.toUpperCase(), prefixedRoutePath);
86
+ });
87
+ this.controllers.add(ctor);
88
+ return this;
89
+ }
90
+ /**
91
+ * Has controller.
92
+ *
93
+ * @param ctor
94
+ */
95
+ hasController(ctor) {
96
+ return this.controllers.has(ctor);
97
+ }
98
+ /**
99
+ * Get path prefix by controller metadata.
100
+ *
101
+ * @param controllerMd
102
+ * @param options
103
+ */
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;
114
+ }
115
+ /**
116
+ * Get pre-handlers by controller metadata.
117
+ *
118
+ * @param controllerMd
119
+ * @param options
120
+ */
121
+ getPreHandlersByControllerMetadata(controllerMd, options) {
122
+ // подготовка дополнительных
123
+ // pre-обработчиков запроса
124
+ let rootPreHandlers = [];
125
+ 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;
143
+ }
144
+ /**
145
+ * Get post-handlers by controller metadata.
146
+ *
147
+ * @param controllerMd
148
+ * @param options
149
+ */
150
+ getPostHandlersByControllerMetadata(controllerMd, options) {
151
+ // подготовка дополнительных
152
+ // post-обработчиков запроса
153
+ let rootPostHandlers = [];
154
+ 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;
172
+ }
173
+ /**
174
+ * Create route handler.
175
+ *
176
+ * @param controllerCtor
177
+ * @param actionName
178
+ * @protected
179
+ */
180
+ createRouteHandler(controllerCtor, actionName) {
181
+ this.debug('Creating route handler for %s.%s.', controllerCtor.name, actionName);
182
+ const requestContextMetadataMap = RequestContextReflector.getMetadata(controllerCtor, actionName);
183
+ const requestDataMetadataMap = RequestDataReflector.getMetadata(controllerCtor, actionName);
184
+ const argsNumber = controllerCtor.prototype[actionName].length;
185
+ const dataTypeCaster = this.getService(DataTypeCaster);
186
+ const dataValidator = this.getService(DataValidator);
187
+ return (requestContext) => {
188
+ this.debug('Executing route handler for %s.%s.', controllerCtor.name, actionName);
189
+ const args = Array(argsNumber).map((value, index) => {
190
+ if (value != null)
191
+ return value;
192
+ // заполнение аргументов операции
193
+ // значениями из контекста запроса
194
+ const requestContextMd = requestContextMetadataMap.get(index);
195
+ if (requestContextMd != null) {
196
+ this.debug('Argument %v has request context metadata.', index);
197
+ // если свойство контекста не определено,
198
+ // то используем весь объект контекста
199
+ // в качестве значения текущего аргумента
200
+ if (requestContextMd.property == null) {
201
+ this.debug('Request context property is not specified.');
202
+ this.debug('Argument %v is set to %v.', index, requestContext);
203
+ return requestContext;
204
+ }
205
+ // если свойство контекста определено,
206
+ // то используем значение этого свойства
207
+ // в качестве текущего аргумента
208
+ const propName = requestContextMd.property;
209
+ const propValue = requestContext[propName];
210
+ this.debug('Request context property is %v.', propName);
211
+ this.debug('Argument %v is set to %v.', index, propValue);
212
+ return propValue;
213
+ }
214
+ else {
215
+ this.debug('No RequestContextMetadata specified for %v argument.', index);
216
+ }
217
+ // заполнение аргументов операции
218
+ // значениями из данных запроса
219
+ const requestDataMd = requestDataMetadataMap.get(index);
220
+ if (requestDataMd != null) {
221
+ this.debug('Argument %v has request data metadata.', index);
222
+ // получение данных
223
+ // согласно источнику
224
+ let data;
225
+ switch (requestDataMd.source) {
226
+ case RequestDataSource.PARAMS:
227
+ data = requestContext.params;
228
+ break;
229
+ case RequestDataSource.QUERY:
230
+ data = requestContext.query;
231
+ break;
232
+ case RequestDataSource.HEADERS:
233
+ data = requestContext.headers;
234
+ break;
235
+ case RequestDataSource.COOKIE:
236
+ data = requestContext.cookie;
237
+ break;
238
+ case RequestDataSource.BODY:
239
+ data = requestContext.body;
240
+ break;
241
+ }
242
+ this.debug('Request data source is %v.', requestDataMd.source);
243
+ // при наличии схемы данных выполняется
244
+ // их конвертация и валидация
245
+ if (requestDataMd.schema) {
246
+ data = dataTypeCaster.cast(data, requestDataMd.schema, {
247
+ noTypeCastError: true,
248
+ sourcePath: requestDataMd.source,
249
+ });
250
+ this.debug('Data type casting is passed.');
251
+ dataValidator.validate(data, requestDataMd.schema, requestDataMd.source);
252
+ this.debug('Data validation is passed.');
253
+ }
254
+ // если свойство данных не определено,
255
+ // то используем весь объекта данных
256
+ // в качестве значения текущего аргумента
257
+ if (requestDataMd.property == null) {
258
+ this.debug('Request data property is not specified.');
259
+ this.debug('Argument %v is set to %v.', index, data);
260
+ return data;
261
+ }
262
+ // если свойство данных определено,
263
+ // то используем значение этого свойства
264
+ // в качестве текущего аргумента
265
+ const dataAsObject = data;
266
+ const propName = requestDataMd.property;
267
+ const propValue = dataAsObject[propName];
268
+ this.debug('Request data property is %v.', propName);
269
+ this.debug('Argument %v is set to %v.', index, propValue);
270
+ return propValue;
271
+ }
272
+ else {
273
+ this.debug('No RequestDataMetadata specified for %v argument.', index);
274
+ }
275
+ });
276
+ // выполнение операции контроллера
277
+ const controller = this.getService(controllerCtor);
278
+ return controller[actionName](...args);
279
+ };
280
+ }
281
+ }
@@ -0,0 +1 @@
1
+ export {};