koatty 3.5.9 → 3.5.12-1

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 (129) hide show
  1. package/.commitlintrc.js +3 -0
  2. package/.eslintignore +2 -0
  3. package/.huskyrc +5 -0
  4. package/.versionrc.js +16 -0
  5. package/CHANGELOG.md +2 -37
  6. package/README.md +5 -9
  7. package/api-extractor.json +345 -0
  8. package/dist/LICENSE +29 -0
  9. package/dist/README.md +147 -0
  10. package/dist/index.d.ts +363 -19
  11. package/dist/index.js +1266 -26
  12. package/dist/index.mjs +1197 -0
  13. package/dist/package.json +98 -0
  14. package/docs/api/index.md +12 -0
  15. package/docs/api/koatty.apiinput.code.md +11 -0
  16. package/docs/api/koatty.apiinput.data.md +11 -0
  17. package/docs/api/koatty.apiinput.md +22 -0
  18. package/docs/api/koatty.apiinput.message.md +11 -0
  19. package/docs/api/koatty.apioutput.code.md +11 -0
  20. package/docs/api/koatty.apioutput.data.md +11 -0
  21. package/docs/api/koatty.apioutput.md +22 -0
  22. package/docs/api/koatty.apioutput.message.md +11 -0
  23. package/docs/api/koatty.appreadyhookfunc.md +11 -0
  24. package/docs/api/koatty.basecontroller._constructor_.md +20 -0
  25. package/docs/api/koatty.basecontroller._options.md +11 -0
  26. package/docs/api/koatty.basecontroller.app.md +11 -0
  27. package/docs/api/koatty.basecontroller.ctx.md +11 -0
  28. package/docs/api/koatty.basecontroller.fail.md +28 -0
  29. package/docs/api/koatty.basecontroller.init.md +19 -0
  30. package/docs/api/koatty.basecontroller.md +39 -0
  31. package/docs/api/koatty.basecontroller.ok.md +28 -0
  32. package/docs/api/koatty.baseservice._constructor_.md +20 -0
  33. package/docs/api/koatty.baseservice._options.md +11 -0
  34. package/docs/api/koatty.baseservice.app.md +11 -0
  35. package/docs/api/koatty.baseservice.init.md +25 -0
  36. package/docs/api/koatty.baseservice.md +36 -0
  37. package/docs/api/koatty.bindappreadyhook.md +26 -0
  38. package/docs/api/koatty.bootstrap.md +27 -0
  39. package/docs/api/koatty.component.md +27 -0
  40. package/docs/api/koatty.componentscan.md +27 -0
  41. package/docs/api/koatty.configurationscan.md +27 -0
  42. package/docs/api/koatty.controller.md +27 -0
  43. package/docs/api/koatty.httpcontroller.body.md +28 -0
  44. package/docs/api/koatty.httpcontroller.deny.md +26 -0
  45. package/docs/api/koatty.httpcontroller.expires.md +26 -0
  46. package/docs/api/koatty.httpcontroller.fail.md +28 -0
  47. package/docs/api/koatty.httpcontroller.header.md +27 -0
  48. package/docs/api/koatty.httpcontroller.isget.md +19 -0
  49. package/docs/api/koatty.httpcontroller.ismethod.md +26 -0
  50. package/docs/api/koatty.httpcontroller.ispost.md +19 -0
  51. package/docs/api/koatty.httpcontroller.json.md +26 -0
  52. package/docs/api/koatty.httpcontroller.md +35 -0
  53. package/docs/api/koatty.httpcontroller.ok.md +28 -0
  54. package/docs/api/koatty.httpcontroller.param.md +26 -0
  55. package/docs/api/koatty.httpcontroller.redirect.md +27 -0
  56. package/docs/api/koatty.httpcontroller.type.md +27 -0
  57. package/docs/api/koatty.icontroller.__after.md +11 -0
  58. package/docs/api/koatty.icontroller.__befor.md +11 -0
  59. package/docs/api/koatty.icontroller.app.md +11 -0
  60. package/docs/api/koatty.icontroller.ctx.md +11 -0
  61. package/docs/api/koatty.icontroller.fail.md +11 -0
  62. package/docs/api/koatty.icontroller.md +25 -0
  63. package/docs/api/koatty.icontroller.ok.md +11 -0
  64. package/docs/api/koatty.imiddleware.md +20 -0
  65. package/docs/api/koatty.imiddleware.run.md +11 -0
  66. package/docs/api/koatty.iplugin.md +20 -0
  67. package/docs/api/koatty.iplugin.run.md +11 -0
  68. package/docs/api/koatty.iservice.app.md +11 -0
  69. package/docs/api/koatty.iservice.md +20 -0
  70. package/docs/api/koatty.logger.md +11 -0
  71. package/docs/api/koatty.md +51 -0
  72. package/docs/api/koatty.middleware.md +27 -0
  73. package/docs/api/koatty.plugin.md +27 -0
  74. package/docs/api/koatty.service.md +27 -0
  75. package/jest.config.js +0 -2
  76. package/jest_html_reporters.html +1 -1
  77. package/package.json +39 -39
  78. package/rollup.config.js +63 -0
  79. package/scripts/copyright.js +28 -0
  80. package/scripts/postBuild.js +10 -0
  81. package/tsconfig.json +4 -2
  82. package/babel.config.js +0 -21
  83. package/commitlint.config.js +0 -14
  84. package/dist/config/config.d.ts +0 -18
  85. package/dist/config/config.js +0 -25
  86. package/dist/config/config.js.map +0 -1
  87. package/dist/config/middleware.d.ts +0 -23
  88. package/dist/config/middleware.js +0 -34
  89. package/dist/config/middleware.js.map +0 -1
  90. package/dist/config/plugin.d.ts +0 -11
  91. package/dist/config/plugin.js +0 -15
  92. package/dist/config/plugin.js.map +0 -1
  93. package/dist/config/router.d.ts +0 -8
  94. package/dist/config/router.js +0 -32
  95. package/dist/config/router.js.map +0 -1
  96. package/dist/controller/BaseController.d.ts +0 -60
  97. package/dist/controller/BaseController.js +0 -137
  98. package/dist/controller/BaseController.js.map +0 -1
  99. package/dist/controller/HttpController.d.ts +0 -131
  100. package/dist/controller/HttpController.js +0 -215
  101. package/dist/controller/HttpController.js.map +0 -1
  102. package/dist/core/Bootstrap.d.ts +0 -50
  103. package/dist/core/Bootstrap.js +0 -215
  104. package/dist/core/Bootstrap.js.map +0 -1
  105. package/dist/core/Component.d.ts +0 -94
  106. package/dist/core/Component.js +0 -89
  107. package/dist/core/Component.js.map +0 -1
  108. package/dist/core/Constants.d.ts +0 -11
  109. package/dist/core/Constants.js +0 -24
  110. package/dist/core/Constants.js.map +0 -1
  111. package/dist/core/Loader.d.ts +0 -110
  112. package/dist/core/Loader.js +0 -407
  113. package/dist/core/Loader.js.map +0 -1
  114. package/dist/index.js.map +0 -1
  115. package/dist/middleware/PayloadMiddleware.d.ts +0 -11
  116. package/dist/middleware/PayloadMiddleware.js +0 -22
  117. package/dist/middleware/PayloadMiddleware.js.map +0 -1
  118. package/dist/middleware/TraceMiddleware.d.ts +0 -11
  119. package/dist/middleware/TraceMiddleware.js +0 -22
  120. package/dist/middleware/TraceMiddleware.js.map +0 -1
  121. package/dist/service/BaseService.d.ts +0 -33
  122. package/dist/service/BaseService.js +0 -32
  123. package/dist/service/BaseService.js.map +0 -1
  124. package/dist/util/Helper.d.ts +0 -25
  125. package/dist/util/Helper.js +0 -117
  126. package/dist/util/Helper.js.map +0 -1
  127. package/dist/util/Logger.d.ts +0 -27
  128. package/dist/util/Logger.js +0 -41
  129. package/dist/util/Logger.js.map +0 -1
package/dist/index.mjs ADDED
@@ -0,0 +1,1197 @@
1
+ /*!
2
+ * @Author: richen
3
+ * @Date: 2021-12-21 12:32:53
4
+ * @License: BSD (3-Clause)
5
+ * @Copyright (c) - <richenlin(at)gmail.com>
6
+ * @HomePage: https://koatty.org/
7
+ */
8
+ import { Helper } from 'koatty_lib';
9
+ export { Helper } from 'koatty_lib';
10
+ import 'reflect-metadata';
11
+ import { NewRouter, CONTROLLER_ROUTER } from 'koatty_router';
12
+ export * from 'koatty_router';
13
+ import { Koatty } from 'koatty_core';
14
+ export * from 'koatty_core';
15
+ import { BindProcessEvent, Serve } from 'koatty_serve';
16
+ export * from 'koatty_serve';
17
+ import { IOCContainer, TAGGED_CLS } from 'koatty_container';
18
+ export * from 'koatty_container';
19
+ import * as path from 'path';
20
+ import { Load } from 'koatty_loader';
21
+ import { LoadConfigs } from 'koatty_config';
22
+ import { DefaultLogger } from 'koatty_logger';
23
+ import { prevent } from 'koatty_exception';
24
+ export * from 'koatty_exception';
25
+ import { Trace } from 'koatty_trace';
26
+ export * from 'koatty_trace';
27
+ import { Payload } from 'koatty_payload';
28
+
29
+ /**
30
+ * @ author: richen
31
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
32
+ * @ license: BSD (3-Clause)
33
+ * @ version: 2020-05-10 11:49:15
34
+ */
35
+ /**
36
+ * Check class file
37
+ * name should be always the same as class name
38
+ * class must be unique
39
+ *
40
+ * @export
41
+ * @param {string} fileName
42
+ * @param {string} xpath
43
+ * @param {*} target
44
+ * @param {Set<unknown>} [exSet]
45
+ * @returns {*}
46
+ */
47
+ function checkClass(fileName, xpath, target, exSet) {
48
+ if (Helper.isClass(target) && target.name != fileName) { // export default class name{}
49
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
50
+ }
51
+ if (target["__esModule"]) {
52
+ if (target.name === undefined) { // export class name{}
53
+ const keys = Object.keys(target);
54
+ if (keys[0] != fileName && Helper.isClass(target[keys[0]])) {
55
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
56
+ }
57
+ }
58
+ else if (target.name != fileName) { // export default class {}
59
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
60
+ }
61
+ }
62
+ if (!exSet) {
63
+ return;
64
+ }
65
+ if (exSet.has(fileName)) {
66
+ throw new Error(`A same class already exists. at \`${xpath}\`.`);
67
+ }
68
+ exSet.add(fileName);
69
+ return;
70
+ }
71
+ /**
72
+ * Format api interface data format
73
+ *
74
+ * @private
75
+ * @param {Error | string | ApiInput} msg 待处理的接口数据信息|接口msg
76
+ * @param {*} data 待返回的数据
77
+ * @param {number} defaultCode 默认错误码
78
+ * @returns {ApiOutput} 格式化之后的接口数据
79
+ * @memberof BaseController
80
+ */
81
+ function formatApiData(msg, data, defaultCode) {
82
+ let obj = {
83
+ code: defaultCode,
84
+ message: '',
85
+ data: null,
86
+ };
87
+ if (Helper.isError(msg)) {
88
+ const { code, message } = msg;
89
+ obj.code = code || defaultCode;
90
+ obj.message = message;
91
+ }
92
+ else if (Helper.isObject(msg)) {
93
+ obj = { ...obj, ...msg };
94
+ }
95
+ else {
96
+ obj.message = msg;
97
+ obj.data = data;
98
+ }
99
+ return obj;
100
+ }
101
+
102
+ /**
103
+ * @ author: richen
104
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
105
+ * @ license: BSD (3-Clause)
106
+ * @ version: 2020-05-20 15:45:24
107
+ */
108
+ /**
109
+ * Base controller
110
+ *
111
+ * @export
112
+ * @class BaseController
113
+ * @implements {IController}
114
+ */
115
+ class BaseController {
116
+ /**
117
+ * instance of BaseController.
118
+ * @param {Koatty} app
119
+ * @param {KoattyContext} ctx
120
+ * @memberof BaseController
121
+ */
122
+ constructor(ctx) {
123
+ this.ctx = ctx;
124
+ this.init();
125
+ }
126
+ /**
127
+ * init
128
+ *
129
+ * @protected
130
+ * @memberof BaseController
131
+ */
132
+ init() {
133
+ }
134
+ // /**
135
+ // * Class pre-execution method, executed before each class member methods (except constructor, init, __after) are executed.
136
+ // *
137
+ // * @returns {Promise<any>}
138
+ // * @memberof BaseController
139
+ // */
140
+ // public __before(): Promise<any> {
141
+ // return Promise.resolve();
142
+ // }
143
+ // /**
144
+ // * Class after-execution method,after each class member methods (except constructor, init, __before) are executed.
145
+ // *
146
+ // * @public
147
+ // * @returns {*}
148
+ // * @memberof BaseController
149
+ // */
150
+ // public __after(): Promise<any> {
151
+ // return Promise.resolve();
152
+ // }
153
+ /**
154
+ * Response to normalize json format content for success
155
+ *
156
+ * @param {(string | ApiInput)} msg 待处理的message消息
157
+ * @param {*} [data] 待处理的数据
158
+ * @param {number} [code=200] 错误码,默认0
159
+ * @returns {*}
160
+ * @memberof BaseController
161
+ */
162
+ ok(msg, data, code = 0) {
163
+ const obj = formatApiData(msg, data, code);
164
+ return Promise.resolve(obj);
165
+ }
166
+ /**
167
+ * Response to normalize json format content for fail
168
+ *
169
+ * @param {(string | ApiInput)} msg
170
+ * @param {*} [data]
171
+ * @param {number} [code=1]
172
+ * @returns {*}
173
+ * @memberof BaseController
174
+ */
175
+ fail(msg, data, code = 1) {
176
+ const obj = formatApiData(msg, data, code);
177
+ return Promise.resolve(obj);
178
+ }
179
+ }
180
+ // const properties = ["constructor", "init"];
181
+ // export const BaseController = new Proxy(Base, {
182
+ // set(target, key, value, receiver) {
183
+ // if (Reflect.get(target, key, receiver) === undefined) {
184
+ // return Reflect.set(target, key, value, receiver);
185
+ // } else if (key === "init") {
186
+ // return Reflect.set(target, key, value, receiver);
187
+ // } else {
188
+ // throw Error("Cannot redefine getter-only property");
189
+ // }
190
+ // },
191
+ // deleteProperty(target, key) {
192
+ // throw Error("Cannot delete getter-only property");
193
+ // },
194
+ // construct(target, args, newTarget) {
195
+ // Reflect.ownKeys(target.prototype).map((n) => {
196
+ // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
197
+ // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
198
+ // }
199
+ // });
200
+ // return Reflect.construct(target, args, newTarget);
201
+ // }
202
+ // });
203
+
204
+ /**
205
+ * @ author: richen
206
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
207
+ * @ license: BSD (3-Clause)
208
+ * @ version: 2020-05-20 15:45:24
209
+ */
210
+ /**
211
+ * HTTP controller
212
+ *
213
+ * @export
214
+ * @class HttpController
215
+ * @implements {IController}
216
+ */
217
+ class HttpController extends BaseController {
218
+ /**
219
+ * Whether it is a GET request
220
+ *
221
+ * @public
222
+ * @returns {boolean}
223
+ * @memberof HttpController
224
+ */
225
+ isGet() {
226
+ return this.ctx.method === "GET";
227
+ }
228
+ /**
229
+ * Whether it is a POST request
230
+ *
231
+ * @public
232
+ * @returns {boolean}
233
+ * @memberof HttpController
234
+ */
235
+ isPost() {
236
+ return this.ctx.method === "POST";
237
+ }
238
+ /**
239
+ * Determines whether the METHOD request is specified
240
+ *
241
+ * @public
242
+ * @param {string} method
243
+ * @returns {boolean}
244
+ * @memberof HttpController
245
+ */
246
+ isMethod(method) {
247
+ return this.ctx.method === method.toUpperCase();
248
+ }
249
+ /**
250
+ * Get/Set headers.
251
+ *
252
+ * @public
253
+ * @param {string} [name]
254
+ * @param {*} [value]
255
+ * @returns {*}
256
+ * @memberof HttpController
257
+ */
258
+ header(name, value) {
259
+ if (name === undefined) {
260
+ return this.ctx.headers;
261
+ }
262
+ if (value === undefined) {
263
+ return this.ctx.get(name);
264
+ }
265
+ return this.ctx.set(name, value);
266
+ }
267
+ /**
268
+ * Get POST/GET parameters, the POST value is priority.
269
+ *
270
+ * @param {string} [name]
271
+ * @returns
272
+ * @memberof HttpController
273
+ */
274
+ param(name) {
275
+ return this.ctx.bodyParser().then((body) => {
276
+ const getParams = this.ctx.queryParser() || {};
277
+ const postParams = (body.post ? body.post : body) || {};
278
+ if (name !== undefined) {
279
+ return postParams[name] === undefined ? getParams[name] : postParams[name];
280
+ }
281
+ return { ...getParams, ...postParams };
282
+ });
283
+ }
284
+ /**
285
+ * Set response content-type
286
+ *
287
+ * @public
288
+ * @param {string} contentType
289
+ * @param {(string | boolean)} [encoding]
290
+ * @returns {string}
291
+ * @memberof HttpController
292
+ */
293
+ type(contentType, encoding) {
294
+ if (encoding !== false && !contentType.includes("charset")) {
295
+ contentType = `${contentType}; charset=${encoding || this.app.config("encoding")}`;
296
+ }
297
+ this.ctx.type = contentType;
298
+ return contentType;
299
+ }
300
+ /**
301
+ * set cache-control and expires header
302
+ *
303
+ * @public
304
+ * @param {number} [timeout=30]
305
+ * @returns {void}
306
+ * @memberof HttpController
307
+ */
308
+ expires(timeout = 30) {
309
+ timeout = Helper.toNumber(timeout) * 1000;
310
+ const date = new Date(Date.now() + timeout);
311
+ this.ctx.set("Cache-Control", `max-age=${timeout}`);
312
+ return this.ctx.set("Expires", date.toUTCString());
313
+ }
314
+ /**
315
+ * Url redirect
316
+ *
317
+ * @param {string} urls
318
+ * @param {string} [alt]
319
+ * @returns {void}
320
+ * @memberof HttpController
321
+ */
322
+ redirect(urls, alt) {
323
+ return this.ctx.redirect(urls, alt);
324
+ }
325
+ /**
326
+ * Block access
327
+ *
328
+ * @param {number} [code=403]
329
+ * @returns {Promise<any>}
330
+ * @memberof HttpController
331
+ */
332
+ deny(code = 403) {
333
+ return this.ctx.throw(code);
334
+ }
335
+ /**
336
+ * Set response Body content
337
+ *
338
+ * @param {*} data
339
+ * @param {string} [contentType]
340
+ * @param {string} [encoding]
341
+ * @returns {Promise<any>}
342
+ * @memberof HttpController
343
+ */
344
+ body(data, contentType, encoding) {
345
+ contentType = contentType || "text/plain";
346
+ encoding = encoding || this.app.config("encoding") || "utf-8";
347
+ this.type(contentType, encoding);
348
+ this.ctx.body = data;
349
+ return null;
350
+ }
351
+ /**
352
+ * Respond to json formatted content
353
+ *
354
+ * @param {*} data
355
+ * @returns {Promise<any>}
356
+ * @memberof HttpController
357
+ */
358
+ json(data) {
359
+ return this.body(data, "application/json");
360
+ }
361
+ /**
362
+ * Response to normalize json format content for success
363
+ *
364
+ * @param {(string | ApiInput)} msg 待处理的message消息
365
+ * @param {*} [data] 待处理的数据
366
+ * @param {number} [code=200] 错误码,默认0
367
+ * @returns {*}
368
+ * @memberof HttpController
369
+ */
370
+ ok(msg, data, code = 0) {
371
+ const obj = formatApiData(msg, data, code);
372
+ return this.json(obj);
373
+ }
374
+ /**
375
+ * Response to normalize json format content for fail
376
+ *
377
+ * @param {(string | ApiInput)} msg
378
+ * @param {*} [data]
379
+ * @param {number} [code=1]
380
+ * @returns {*}
381
+ * @memberof HttpController
382
+ */
383
+ fail(msg, data, code = 1) {
384
+ const obj = formatApiData(msg, data, code);
385
+ return this.json(obj);
386
+ }
387
+ }
388
+ // const properties = ["constructor", "init"];
389
+ // export const HttpController = new Proxy(Base, {
390
+ // set(target, key, value, receiver) {
391
+ // if (Reflect.get(target, key, receiver) === undefined) {
392
+ // return Reflect.set(target, key, value, receiver);
393
+ // } else if (key === "init") {
394
+ // return Reflect.set(target, key, value, receiver);
395
+ // } else {
396
+ // throw Error("Cannot redefine getter-only property");
397
+ // }
398
+ // },
399
+ // deleteProperty(target, key) {
400
+ // throw Error("Cannot delete getter-only property");
401
+ // },
402
+ // construct(target, args, newTarget) {
403
+ // Reflect.ownKeys(target.prototype).map((n) => {
404
+ // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
405
+ // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
406
+ // }
407
+ // });
408
+ // return Reflect.construct(target, args, newTarget);
409
+ // }
410
+ // });
411
+
412
+ /**
413
+ * @ author: richen
414
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
415
+ * @ license: BSD (3-Clause)
416
+ * @ version: 2020-05-10 11:49:15
417
+ */
418
+ // Logger
419
+ const Logger = DefaultLogger;
420
+ /**
421
+ * SetLogger
422
+ *
423
+ * @export
424
+ * @param {{
425
+ * logLevel?: LogLevelType;
426
+ * logConsole?: boolean;
427
+ * logFile?: boolean;
428
+ * logFileLevel?: LogLevelType;
429
+ * logFilePath?: string;
430
+ * }} config
431
+ */
432
+ function SetLogger(config) {
433
+ if (config.logLevel !== undefined) {
434
+ DefaultLogger.setLevel(config.logLevel);
435
+ }
436
+ if (config.logConsole !== undefined) {
437
+ DefaultLogger.setLogConsole(config.logConsole);
438
+ }
439
+ if (config.logFile !== undefined) {
440
+ DefaultLogger.setLogFile(config.logFile);
441
+ DefaultLogger.setLogFilePath(config.logFilePath);
442
+ }
443
+ if (config.logFileLevel !== undefined) {
444
+ DefaultLogger.setLogFileLevel(config.logFileLevel);
445
+ }
446
+ }
447
+
448
+ /**
449
+ * Base class
450
+ *
451
+ * @export
452
+ * @class Base
453
+ */
454
+ class BaseService {
455
+ /**
456
+ * instance of Base.
457
+ * @param {...any[]} arg
458
+ * @memberof Base
459
+ */
460
+ constructor(...arg) {
461
+ this.init(arg);
462
+ }
463
+ /**
464
+ * init
465
+ *
466
+ * @protected
467
+ * @param {...any[]} arg
468
+ * @memberof Base
469
+ */
470
+ init(...arg) {
471
+ // todo
472
+ // Logger.Debug(arg)
473
+ }
474
+ }
475
+
476
+ /**
477
+ * @ author: richen
478
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
479
+ * @ license: BSD (3-Clause)
480
+ * @ version: 2020-05-10 11:49:15
481
+ */
482
+ const COMPONENT_SCAN = 'COMPONENT_SCAN';
483
+ const CONFIGURATION_SCAN = 'CONFIGURATION_SCAN';
484
+ const APP_READY_HOOK = "APP_READY_HOOK";
485
+ // tslint:disable: no-irregular-whitespace
486
+ const LOGO = `
487
+
488
+ ██  ██  ██████  █████  ████████ ████████ ██  ██ 
489
+ ██  ██  ██    ██ ██   ██    ██       ██     ██  ██  
490
+ █████   ██  ██ ███████  ██  ██   ████  
491
+ ██  ██  ██  ██ ██   ██  ██  ██   ██  
492
+ ██  ██  ██████  ██  ██  ██  ██  ██ 
493
+ https://github.com/koatty
494
+ `;
495
+
496
+ class TraceMiddleware {
497
+ run(options, app) {
498
+ return Trace(options, app);
499
+ }
500
+ }
501
+
502
+ class PayloadMiddleware {
503
+ run(options, app) {
504
+ return Payload(options, app);
505
+ }
506
+ }
507
+
508
+ /**
509
+ * @ author: richen
510
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
511
+ * @ license: BSD (3-Clause)
512
+ * @ version: 2020-07-06 11:18:01
513
+ */
514
+ /**
515
+ *
516
+ */
517
+ class Loader {
518
+ /**
519
+ * initialize env
520
+ *
521
+ * @static
522
+ * @param {Koatty} app
523
+ * @memberof Loader
524
+ */
525
+ static initialize(app) {
526
+ var _a, _b;
527
+ const env = ((_a = process.execArgv) !== null && _a !== void 0 ? _a : []).join(",");
528
+ if (env.indexOf('ts-node') > -1 || env.indexOf('--debug') > -1) {
529
+ app.appDebug = true;
530
+ }
531
+ // app.env
532
+ app.env = process.env.KOATTY_ENV || process.env.NODE_ENV;
533
+ if ((env.indexOf('--production') > -1) || (((_b = app.env) !== null && _b !== void 0 ? _b : '').indexOf('pro') > -1)) {
534
+ app.appDebug = false;
535
+ }
536
+ if (app.appDebug) {
537
+ app.env = 'development';
538
+ process.env.NODE_ENV = 'development';
539
+ process.env.APP_DEBUG = 'true';
540
+ Logger.setLevel("DEBUG");
541
+ }
542
+ else {
543
+ app.env = 'production';
544
+ process.env.NODE_ENV = 'production';
545
+ Logger.setLevel("INFO");
546
+ }
547
+ // define path
548
+ const rootPath = app.rootPath || process.cwd();
549
+ const appPath = app.appPath || path.resolve(rootPath, env.indexOf('ts-node') > -1 ? 'src' : 'dist');
550
+ const thinkPath = path.resolve(__dirname, '..');
551
+ Helper.define(app, 'rootPath', rootPath);
552
+ Helper.define(app, 'appPath', appPath);
553
+ Helper.define(app, 'thinkPath', thinkPath);
554
+ process.env.ROOT_PATH = rootPath;
555
+ process.env.APP_PATH = appPath;
556
+ process.env.THINK_PATH = thinkPath;
557
+ // Compatible with old version, will be deprecated
558
+ Helper.define(app, 'prevent', prevent);
559
+ Helper.define(app, 'root_path', rootPath);
560
+ Helper.define(app, 'app_path', appPath);
561
+ Helper.define(app, 'think_path', thinkPath);
562
+ }
563
+ /**
564
+ * Get component metadata
565
+ *
566
+ * @static
567
+ * @param {Koatty} app
568
+ * @param {*} target
569
+ * @returns {*} {any[]}
570
+ * @memberof Loader
571
+ */
572
+ static GetComponentMetas(app, target) {
573
+ let componentMetas = [];
574
+ const componentMeta = IOCContainer.getClassMetadata(TAGGED_CLS, COMPONENT_SCAN, target);
575
+ if (componentMeta) {
576
+ if (Helper.isArray(componentMeta)) {
577
+ componentMetas = componentMeta;
578
+ }
579
+ else {
580
+ componentMetas.push(componentMeta);
581
+ }
582
+ }
583
+ if (componentMetas.length < 1) {
584
+ componentMetas = [app.appPath];
585
+ }
586
+ return componentMetas;
587
+ }
588
+ /**
589
+ * Load all bean, excepted config/*、App.ts
590
+ *
591
+ * @static
592
+ * @param {Koatty} app
593
+ * @param {*} target
594
+ * @memberof Loader
595
+ */
596
+ static CheckAllComponents(app, target) {
597
+ // component metadata
598
+ const componentMetas = Loader.GetComponentMetas(app, target);
599
+ // configuration metadata
600
+ const configurationMetas = Loader.GetConfigurationMetas(app, target);
601
+ const exSet = new Set();
602
+ Load(componentMetas, '', (fileName, xpath, xTarget) => {
603
+ checkClass(fileName, xpath, xTarget, exSet);
604
+ }, ['**/**.js', '**/**.ts', '!**/**.d.ts'], [...configurationMetas, `${target.name || '.no'}.ts`]);
605
+ exSet.clear();
606
+ }
607
+ /**
608
+ * Get configuration metadata
609
+ *
610
+ * @static
611
+ * @param {Koatty} app
612
+ * @param {*} target
613
+ * @returns {*} {any[]}
614
+ * @memberof Loader
615
+ */
616
+ static GetConfigurationMetas(app, target) {
617
+ const confMeta = IOCContainer.getClassMetadata(TAGGED_CLS, CONFIGURATION_SCAN, target);
618
+ let configurationMetas = [];
619
+ if (confMeta) {
620
+ if (Helper.isArray(confMeta)) {
621
+ configurationMetas = confMeta;
622
+ }
623
+ else {
624
+ configurationMetas.push(confMeta);
625
+ }
626
+ }
627
+ return configurationMetas;
628
+ }
629
+ /**
630
+ * Set Logger level
631
+ *
632
+ * @static
633
+ * @param {Koatty} app
634
+ * @memberof Loader
635
+ */
636
+ static SetLogger(app) {
637
+ var _a;
638
+ const configs = (_a = app.getMetaData("_configs")) !== null && _a !== void 0 ? _a : {};
639
+ //Logger
640
+ if (configs.config) {
641
+ const opt = configs.config;
642
+ let logLevel = "DEBUG", logFileLevel = "INFO", logConsole = true, logFile = false, logFilePath = app.rootPath + "/logs";
643
+ if (app.env === "production") {
644
+ logLevel = "INFO";
645
+ logFileLevel = "WARN";
646
+ logConsole = false;
647
+ logFile = true;
648
+ }
649
+ if (opt.logs_level) {
650
+ logLevel = opt.logs_level;
651
+ }
652
+ if (opt.logs_write_level) {
653
+ logFileLevel = opt.logs_write_level;
654
+ }
655
+ if (opt.logs_write !== undefined) {
656
+ logFile = !!opt.logs_write;
657
+ }
658
+ if (opt.logs_console !== undefined) {
659
+ logConsole = !!opt.logs_console;
660
+ }
661
+ if (opt.logs_path) {
662
+ logFilePath = opt.logs_path;
663
+ }
664
+ SetLogger({ logLevel, logConsole, logFile, logFileLevel, logFilePath });
665
+ }
666
+ }
667
+ /**
668
+ * Load app ready hook funcs
669
+ *
670
+ * @static
671
+ * @param {Koatty} app
672
+ * @param {*} target
673
+ * @memberof Loader
674
+ */
675
+ static LoadAppReadyHooks(app, target) {
676
+ const funcs = IOCContainer.getClassMetadata(TAGGED_CLS, APP_READY_HOOK, target);
677
+ if (Helper.isArray(funcs)) {
678
+ funcs.forEach((element) => {
679
+ app.once('appReady', () => element(app));
680
+ return null;
681
+ });
682
+ }
683
+ }
684
+ /**
685
+ * Load configuration
686
+ *
687
+ * @static
688
+ * @param {Koatty} app
689
+ * @param {string[]} [loadPath]
690
+ * @memberof Loader
691
+ */
692
+ static LoadConfigs(app, loadPath) {
693
+ const frameConfig = {};
694
+ // Logger.Debug(`Load configuration path: ${app.thinkPath}/config`);
695
+ Load(["./config"], app.thinkPath, function (name, path, exp) {
696
+ frameConfig[name] = exp;
697
+ });
698
+ if (Helper.isArray(loadPath)) {
699
+ loadPath = loadPath.length > 0 ? loadPath : ["./config"];
700
+ }
701
+ let appConfig = LoadConfigs(loadPath, app.appPath);
702
+ appConfig = Helper.extend(frameConfig, appConfig, true);
703
+ app.setMetaData("_configs", appConfig);
704
+ }
705
+ /**
706
+ * Load middlewares
707
+ * [async]
708
+ * @static
709
+ * @param {*} app
710
+ * @param {(string | string[])} [loadPath]
711
+ * @memberof Loader
712
+ */
713
+ static async LoadMiddlewares(app, loadPath) {
714
+ var _a, _b;
715
+ let middlewareConf = app.config(undefined, "middleware");
716
+ if (Helper.isEmpty(middlewareConf)) {
717
+ middlewareConf = { config: {}, list: [] };
718
+ }
719
+ //Mount default middleware
720
+ Load(loadPath || ["./middleware"], app.thinkPath);
721
+ //Mount application middleware
722
+ // const middleware: any = {};
723
+ const appMiddleware = (_a = IOCContainer.listClass("MIDDLEWARE")) !== null && _a !== void 0 ? _a : [];
724
+ appMiddleware.push({ id: "TraceMiddleware", target: TraceMiddleware });
725
+ appMiddleware.push({ id: "PayloadMiddleware", target: PayloadMiddleware });
726
+ appMiddleware.forEach((item) => {
727
+ var _a;
728
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("MIDDLEWARE:", "");
729
+ if (item.id && Helper.isClass(item.target)) {
730
+ IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
731
+ // middleware[item.id] = item.target;
732
+ }
733
+ });
734
+ const middlewareConfList = middlewareConf.list;
735
+ const defaultList = ["TraceMiddleware", "PayloadMiddleware"];
736
+ middlewareConfList.forEach((item) => {
737
+ if (!defaultList.includes(item)) {
738
+ defaultList.push(item);
739
+ }
740
+ });
741
+ // if (defaultList.length > middlewareConfList.length) {
742
+ // Logger.Warn("Some middleware is loaded but not allowed to execute.");
743
+ // }
744
+ //de-duplication
745
+ const appMList = [...new Set(defaultList)];
746
+ //Automatically call middleware
747
+ for (const key of appMList) {
748
+ const handle = IOCContainer.get(key, "MIDDLEWARE");
749
+ if (!handle) {
750
+ Logger.Error(`Middleware ${key} load error.`);
751
+ continue;
752
+ }
753
+ if (!Helper.isFunction(handle.run)) {
754
+ Logger.Error(`Middleware ${key} must be implements method 'run'.`);
755
+ continue;
756
+ }
757
+ if (middlewareConf.config[key] === false) {
758
+ Logger.Warn(`Middleware ${key} is loaded but not allowed to execute.`);
759
+ continue;
760
+ }
761
+ Logger.Debug(`Load middleware: ${key}`);
762
+ const result = await handle.run((_b = middlewareConf.config[key]) !== null && _b !== void 0 ? _b : {}, app);
763
+ if (Helper.isFunction(result)) {
764
+ if (result.length < 3) {
765
+ app.use(result);
766
+ }
767
+ else {
768
+ app.useExp(result);
769
+ }
770
+ }
771
+ }
772
+ // app.setMetaData("_middlewares", middleware);
773
+ }
774
+ /**
775
+ * Load controllers
776
+ *
777
+ * @static
778
+ * @param {*} app
779
+ * @memberof Loader
780
+ */
781
+ static LoadControllers(app) {
782
+ const controllerList = IOCContainer.listClass("CONTROLLER");
783
+ const controllers = {};
784
+ controllerList.forEach((item) => {
785
+ var _a;
786
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("CONTROLLER:", "");
787
+ if (item.id && Helper.isClass(item.target)) {
788
+ Logger.Debug(`Load controller: ${item.id}`);
789
+ // registering to IOC
790
+ IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
791
+ const ctl = IOCContainer.getInsByClass(item.target);
792
+ if (!(ctl instanceof BaseController)) {
793
+ throw new Error(`class ${item.id} does not inherit from BaseController`);
794
+ }
795
+ controllers[item.id] = 1;
796
+ }
797
+ });
798
+ app.setMetaData("_controllers", controllers);
799
+ }
800
+ /**
801
+ * Load services
802
+ *
803
+ * @static
804
+ * @param {*} app
805
+ * @memberof Loader
806
+ */
807
+ static LoadServices(app) {
808
+ const serviceList = IOCContainer.listClass("SERVICE");
809
+ serviceList.forEach((item) => {
810
+ var _a;
811
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("SERVICE:", "");
812
+ if (item.id && Helper.isClass(item.target)) {
813
+ Logger.Debug(`Load service: ${item.id}`);
814
+ // registering to IOC
815
+ IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
816
+ const ctl = IOCContainer.getInsByClass(item.target);
817
+ if (!(ctl instanceof BaseService)) {
818
+ throw new Error(`class ${item.id} does not inherit from BaseService`);
819
+ }
820
+ }
821
+ });
822
+ }
823
+ /**
824
+ * Load components
825
+ *
826
+ * @static
827
+ * @param {*} app
828
+ * @memberof Loader
829
+ */
830
+ static LoadComponents(app) {
831
+ const componentList = IOCContainer.listClass("COMPONENT");
832
+ componentList.forEach((item) => {
833
+ var _a;
834
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("COMPONENT:", "");
835
+ if (item.id && !(item.id).endsWith("Plugin") && Helper.isClass(item.target)) {
836
+ Logger.Debug(`Load component: ${item.id}`);
837
+ // inject schedule
838
+ // injectSchedule(item.target, item.target.prototype, IOCContainer);
839
+ // registering to IOC
840
+ IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
841
+ }
842
+ });
843
+ }
844
+ /**
845
+ * Load plugins
846
+ *
847
+ * @static
848
+ * @param {*} app
849
+ * @memberof Loader
850
+ */
851
+ static async LoadPlugins(app) {
852
+ var _a;
853
+ const componentList = IOCContainer.listClass("COMPONENT");
854
+ let pluginsConf = app.config(undefined, "plugin");
855
+ if (Helper.isEmpty(pluginsConf)) {
856
+ pluginsConf = { config: {}, list: [] };
857
+ }
858
+ const pluginList = [];
859
+ componentList.forEach(async (item) => {
860
+ var _a;
861
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("COMPONENT:", "");
862
+ if (item.id && (item.id).endsWith("Plugin") && Helper.isClass(item.target)) {
863
+ // Logger.Debug(`Load plugin: ${item.id}`);
864
+ // registering to IOC
865
+ IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
866
+ pluginList.push(item.id);
867
+ }
868
+ });
869
+ const pluginConfList = pluginsConf.list;
870
+ if (pluginList.length > pluginConfList.length) {
871
+ Logger.Warn("Some plugins is loaded but not allowed to execute.");
872
+ }
873
+ for (const key of pluginConfList) {
874
+ const handle = IOCContainer.get(key, "COMPONENT");
875
+ if (!Helper.isFunction(handle.run)) {
876
+ Logger.Error(`plugin ${key} must be implements method 'run'.`);
877
+ continue;
878
+ }
879
+ if (pluginsConf.config[key] === false) {
880
+ continue;
881
+ }
882
+ // Logger.Debug(`Execute plugin: ${key}`);
883
+ // sync exec
884
+ await handle.run((_a = pluginsConf.config[key]) !== null && _a !== void 0 ? _a : {}, app);
885
+ }
886
+ }
887
+ }
888
+
889
+ var version = "3.5.12-1";
890
+ var engines = {
891
+ node: ">12.0.0"
892
+ };
893
+
894
+ /*
895
+ * @Description:
896
+ * @Usage:
897
+ * @Author: richen
898
+ * @Date: 2021-12-17 11:54:06
899
+ * @LastEditTime: 2021-12-17 13:13:00
900
+ */
901
+ const KOATTY_VERSION = version;
902
+ const ENGINES_VERSION = engines.node.slice(1) || '12.0.0';
903
+ /**
904
+ * check node version
905
+ * @return {void} []
906
+ */
907
+ function checkRuntime() {
908
+ let nodeEngines = ENGINES_VERSION;
909
+ nodeEngines = nodeEngines.slice(0, nodeEngines.lastIndexOf('.'));
910
+ let nodeVersion = process.version;
911
+ if (nodeVersion[0] === 'v') {
912
+ nodeVersion = nodeVersion.slice(1);
913
+ }
914
+ nodeVersion = nodeVersion.slice(0, nodeVersion.lastIndexOf('.'));
915
+ if (Helper.toNumber(nodeEngines) > Helper.toNumber(nodeVersion)) {
916
+ Logger.Error(`Koatty need node version > ${nodeEngines}, current version is ${nodeVersion}, please upgrade it.`);
917
+ process.exit(-1);
918
+ }
919
+ }
920
+
921
+ /**
922
+ * @ author: richen
923
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
924
+ * @ license: BSD (3-Clause)
925
+ * @ version: 2020-07-06 11:22:58
926
+ */
927
+ /**
928
+ * execute bootstrap
929
+ *
930
+ * @param {*} target
931
+ * @param {Function} bootFunc
932
+ * @returns {Promise<void>}
933
+ */
934
+ const ExecBootstrap = async function (target, bootFunc) {
935
+ // checked runtime
936
+ checkRuntime();
937
+ const app = Reflect.construct(target, []);
938
+ try {
939
+ console.log(LOGO);
940
+ if (!(app instanceof Koatty)) {
941
+ throw new Error(`class ${target.name} does not inherit from Koatty`);
942
+ }
943
+ // version
944
+ Helper.define(app, "version", KOATTY_VERSION);
945
+ // Initialize env
946
+ Loader.initialize(app);
947
+ // exec bootFunc
948
+ if (Helper.isFunction(bootFunc)) {
949
+ Logger.Log('think', '', 'Execute bootFunc ...');
950
+ await bootFunc(app);
951
+ }
952
+ // Set IOCContainer.app
953
+ IOCContainer.setApp(app);
954
+ Logger.Log('think', '', 'ComponentScan ...');
955
+ // Check all bean
956
+ Loader.CheckAllComponents(app, target);
957
+ // Load configuration
958
+ Logger.Log('think', '', 'Load Configurations ...');
959
+ // configuration metadata
960
+ const configurationMetas = Loader.GetConfigurationMetas(app, target);
961
+ Loader.LoadConfigs(app, configurationMetas);
962
+ // Load Plugin
963
+ Logger.Log('think', '', 'Load Plugins ...');
964
+ await Loader.LoadPlugins(app);
965
+ // Set Logger
966
+ Loader.SetLogger(app);
967
+ // app.emit("appBoot");
968
+ await asyncEvent(app, 'appBoot');
969
+ // Load App ready hooks
970
+ Loader.LoadAppReadyHooks(app, target);
971
+ // New router
972
+ const KoattyRouter = newRouter(app);
973
+ // Load Middleware
974
+ Logger.Log('think', '', 'Load Middlewares ...');
975
+ await Loader.LoadMiddlewares(app);
976
+ // Load Components
977
+ Logger.Log('think', '', 'Load Components ...');
978
+ Loader.LoadComponents(app);
979
+ // Load Services
980
+ Logger.Log('think', '', 'Load Services ...');
981
+ Loader.LoadServices(app);
982
+ // Load Controllers
983
+ Logger.Log('think', '', 'Load Controllers ...');
984
+ Loader.LoadControllers(app);
985
+ // Emit app ready event
986
+ Logger.Log('think', '', 'Emit App Ready ...');
987
+ // app.emit("appReady");
988
+ await asyncEvent(app, 'appReady');
989
+ // Load Routers
990
+ Logger.Log('think', '', 'Load Routers ...');
991
+ KoattyRouter.LoadRouter(app.getMetaData("_controllers"));
992
+ // Emit app started event
993
+ Logger.Log('think', '', 'Emit App Start ...');
994
+ // app.emit("appStart");
995
+ const server = newServe(app);
996
+ await asyncEvent(app, 'appStart');
997
+ Logger.Log('think', '', '====================================');
998
+ // Start server
999
+ app.listen(server);
1000
+ // binding event "appStop"
1001
+ BindProcessEvent(app, 'appStop');
1002
+ }
1003
+ catch (err) {
1004
+ Logger.Error(err);
1005
+ process.exit();
1006
+ }
1007
+ };
1008
+ /**
1009
+ * create router
1010
+ *
1011
+ * @export
1012
+ * @param {Koatty} app
1013
+ * @returns {*}
1014
+ */
1015
+ const newRouter = function (app) {
1016
+ var _a;
1017
+ const protocol = app.config("protocol") || "http";
1018
+ const options = (_a = app.config(undefined, 'router')) !== null && _a !== void 0 ? _a : {};
1019
+ const router = NewRouter(app, options, protocol);
1020
+ Helper.define(app, "router", router);
1021
+ return router;
1022
+ };
1023
+ /**
1024
+ * create serve
1025
+ *
1026
+ * @param {Koatty} app
1027
+ * @returns {*}
1028
+ */
1029
+ const newServe = function (app) {
1030
+ const protocol = app.config("protocol") || "http";
1031
+ const server = Serve(app, protocol);
1032
+ Helper.define(app, "server", server);
1033
+ return server;
1034
+ };
1035
+ /**
1036
+ * Execute event as async
1037
+ *
1038
+ * @param {Koatty} event
1039
+ * @param {string} eventName
1040
+ */
1041
+ const asyncEvent = async function (event, eventName) {
1042
+ const ls = event.listeners(eventName);
1043
+ // eslint-disable-next-line no-restricted-syntax
1044
+ for await (const func of ls) {
1045
+ if (Helper.isFunction(func)) {
1046
+ func();
1047
+ }
1048
+ }
1049
+ return event.removeAllListeners(eventName);
1050
+ };
1051
+ /**
1052
+ * Bootstrap application
1053
+ *
1054
+ * @export
1055
+ * @param {Function} [bootFunc]
1056
+ * @returns {ClassDecorator}
1057
+ */
1058
+ function Bootstrap(bootFunc) {
1059
+ return function (target) {
1060
+ if (!(target.prototype instanceof Koatty)) {
1061
+ throw new Error(`class does not inherit from Koatty`);
1062
+ }
1063
+ ExecBootstrap(target, bootFunc);
1064
+ };
1065
+ }
1066
+ /**
1067
+ * Define project scan path
1068
+ *
1069
+ * @export
1070
+ * @param {(string | string[])} [scanPath]
1071
+ * @returns {ClassDecorator}
1072
+ */
1073
+ function ComponentScan(scanPath) {
1074
+ Logger.Log('think', '', 'ComponentScan');
1075
+ return (target) => {
1076
+ if (!(target.prototype instanceof Koatty)) {
1077
+ throw new Error(`class does not inherit from Koatty`);
1078
+ }
1079
+ scanPath = scanPath !== null && scanPath !== void 0 ? scanPath : '';
1080
+ IOCContainer.saveClassMetadata(TAGGED_CLS, COMPONENT_SCAN, scanPath, target);
1081
+ };
1082
+ }
1083
+ /**
1084
+ * Define project configuration scan path
1085
+ *
1086
+ * @export
1087
+ * @param {(string | string[])} [scanPath]
1088
+ * @returns {ClassDecorator}
1089
+ */
1090
+ function ConfigurationScan(scanPath) {
1091
+ Logger.Log('think', '', 'ConfigurationScan');
1092
+ return (target) => {
1093
+ if (!(target.prototype instanceof Koatty)) {
1094
+ throw new Error(`class does not inherit from Koatty`);
1095
+ }
1096
+ scanPath = scanPath !== null && scanPath !== void 0 ? scanPath : '';
1097
+ IOCContainer.saveClassMetadata(TAGGED_CLS, CONFIGURATION_SCAN, scanPath, target);
1098
+ };
1099
+ }
1100
+ /**
1101
+ * bind AppReadyHookFunc
1102
+ * example:
1103
+ * export function TestDecorator(): ClassDecorator {
1104
+ * return (target: any) => {
1105
+ * BindAppReadyHook((app: Koatty) => {
1106
+ * // todo
1107
+ * return Promise.resolve();
1108
+ * }, target)
1109
+ * }
1110
+ * }
1111
+ *
1112
+ * @export
1113
+ * @param {AppReadyHookFunc} func
1114
+ * @param {*} target
1115
+ */
1116
+ function BindAppReadyHook(func, target) {
1117
+ IOCContainer.attachClassMetadata(TAGGED_CLS, APP_READY_HOOK, func, target);
1118
+ }
1119
+
1120
+ /**
1121
+ * @ author: richen
1122
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
1123
+ * @ license: BSD (3-Clause)
1124
+ * @ version: 2020-05-10 11:32:45
1125
+ */
1126
+ /**
1127
+ * Indicates that an decorated class is a "component".
1128
+ *
1129
+ * @export
1130
+ * @param {string} [identifier] component name
1131
+ * @returns {ClassDecorator}
1132
+ */
1133
+ function Component(identifier) {
1134
+ return (target) => {
1135
+ identifier = identifier || IOCContainer.getIdentifier(target);
1136
+ IOCContainer.saveClass("COMPONENT", target, identifier);
1137
+ };
1138
+ }
1139
+ /**
1140
+ * Indicates that an decorated class is a "controller".
1141
+ *
1142
+ * @export
1143
+ * @param {string} [path] controller router path
1144
+ * @returns {ClassDecorator}
1145
+ */
1146
+ function Controller(path = "") {
1147
+ return (target) => {
1148
+ const identifier = IOCContainer.getIdentifier(target);
1149
+ IOCContainer.saveClass("CONTROLLER", target, identifier);
1150
+ IOCContainer.savePropertyData(CONTROLLER_ROUTER, path, target, identifier);
1151
+ };
1152
+ }
1153
+ /**
1154
+ * Indicates that an decorated class is a "middleware".
1155
+ *
1156
+ * @export
1157
+ * @param {string} [identifier] middleware name
1158
+ * @returns {ClassDecorator}
1159
+ */
1160
+ function Middleware(identifier) {
1161
+ return (target) => {
1162
+ identifier = identifier || IOCContainer.getIdentifier(target);
1163
+ IOCContainer.saveClass("MIDDLEWARE", target, identifier);
1164
+ };
1165
+ }
1166
+ /**
1167
+ * Indicates that an decorated class is a "service".
1168
+ *
1169
+ * @export
1170
+ * @param {string} [identifier] middleware name
1171
+ * @returns {ClassDecorator}
1172
+ */
1173
+ function Service(identifier) {
1174
+ return (target) => {
1175
+ identifier = identifier || IOCContainer.getIdentifier(target);
1176
+ IOCContainer.saveClass("SERVICE", target, identifier);
1177
+ };
1178
+ }
1179
+ /**
1180
+ * Indicates that an decorated class is a "plugin".
1181
+ *
1182
+ * @export
1183
+ * @param {string} [identifier]
1184
+ * @returns {ClassDecorator}
1185
+ */
1186
+ function Plugin(identifier) {
1187
+ return (target) => {
1188
+ identifier = identifier || IOCContainer.getIdentifier(target);
1189
+ //
1190
+ if (!identifier.endsWith("Plugin")) {
1191
+ throw Error("Plugin class name must be 'Plugin' suffix.");
1192
+ }
1193
+ IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
1194
+ };
1195
+ }
1196
+
1197
+ export { BaseController, BaseService, BindAppReadyHook, Bootstrap, Component, ComponentScan, ConfigurationScan, Controller, HttpController, Logger, Middleware, Plugin, Service };