koatty 3.10.4-1 → 3.10.4-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.
package/dist/index.js CHANGED
@@ -1,13 +1,12 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-11 04:45:04
3
+ * @Date: 2023-12-15 00:18:46
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
7
7
  */
8
8
  'use strict';
9
9
 
10
- require('reflect-metadata');
11
10
  var koatty_core = require('koatty_core');
12
11
  var path = require('path');
13
12
  var koatty_loader = require('koatty_loader');
@@ -18,6 +17,7 @@ var koatty_exception = require('koatty_exception');
18
17
  var koatty_container = require('koatty_container');
19
18
  var koatty_trace = require('koatty_trace');
20
19
  var koatty_serve = require('koatty_serve');
20
+ require('reflect-metadata');
21
21
 
22
22
  function _interopNamespaceDefault(e) {
23
23
  var n = Object.create(null);
@@ -38,129 +38,129 @@ function _interopNamespaceDefault(e) {
38
38
 
39
39
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
40
40
 
41
- /*
42
- * @Description: framework logger
43
- * @Usage:
44
- * @Author: richen
45
- * @Date: 2023-12-09 21:56:32
46
- * @LastEditTime: 2023-12-09 23:02:27
47
- * @License: BSD (3-Clause)
48
- * @Copyright (c): <richenlin(at)gmail.com>
49
- */
50
- // Logger
51
- const Logger = koatty_logger.DefaultLogger;
52
- /**
53
- * SetLogger
54
- *
55
- * @export
56
- * @param {{
57
- * logLevel?: LogLevelType;
58
- * logFilePath?: string;
59
- * sensFields?: string[];
60
- * }} config
61
- */
62
- function SetLogger(app, config) {
63
- if (config.logLevel) {
64
- koatty_logger.DefaultLogger.setLevel(config.logLevel);
65
- }
66
- if (config.logFilePath && !app.silent) {
67
- koatty_lib.Helper.define(app, "logsPath", config.logFilePath);
68
- process.env.LOGS_PATH = config.logFilePath;
69
- koatty_logger.DefaultLogger.setLogFilePath(config.logFilePath);
70
- }
71
- if (config.sensFields) {
72
- koatty_logger.DefaultLogger.setSensFields(config.sensFields);
73
- }
41
+ /*
42
+ * @Description: framework logger
43
+ * @Usage:
44
+ * @Author: richen
45
+ * @Date: 2023-12-09 21:56:32
46
+ * @LastEditTime: 2023-12-09 23:02:27
47
+ * @License: BSD (3-Clause)
48
+ * @Copyright (c): <richenlin(at)gmail.com>
49
+ */
50
+ // Logger
51
+ const Logger = koatty_logger.DefaultLogger;
52
+ /**
53
+ * SetLogger
54
+ *
55
+ * @export
56
+ * @param {{
57
+ * logLevel?: LogLevelType;
58
+ * logFilePath?: string;
59
+ * sensFields?: string[];
60
+ * }} config
61
+ */
62
+ function SetLogger(app, config) {
63
+ if (config.logLevel) {
64
+ koatty_logger.DefaultLogger.setLevel(config.logLevel);
65
+ }
66
+ if (config.logFilePath && !app.silent) {
67
+ koatty_lib.Helper.define(app, "logsPath", config.logFilePath);
68
+ process.env.LOGS_PATH = config.logFilePath;
69
+ koatty_logger.DefaultLogger.setLogFilePath(config.logFilePath);
70
+ }
71
+ if (config.sensFields) {
72
+ koatty_logger.DefaultLogger.setSensFields(config.sensFields);
73
+ }
74
74
  }
75
75
 
76
- /*
77
- * @Description: framework helper
78
- * @Usage:
79
- * @Author: richen
80
- * @Date: 2023-12-09 21:56:32
81
- * @LastEditTime: 2023-12-09 23:01:56
82
- * @License: BSD (3-Clause)
83
- * @Copyright (c): <richenlin(at)gmail.com>
84
- */
85
- /**
86
- * Check class file
87
- * name should be always the same as class name
88
- * class must be unique
89
- *
90
- * @export
91
- * @param {string} fileName
92
- * @param {string} xpath
93
- * @param {*} target
94
- * @param {Set<unknown>} [exSet]
95
- * @returns {*}
96
- */
97
- function checkClass(fileName, xpath, target, exSet) {
98
- if (koatty_lib.Helper.isClass(target) && target.name != fileName) { // export default class name{}
99
- throw Error(`The file(${xpath}) name should be always the same as class name.`);
100
- }
101
- if (target["__esModule"]) {
102
- if (target.name === undefined) { // export class name{}
103
- const keys = Object.keys(target);
104
- if (keys[0] != fileName && koatty_lib.Helper.isClass(target[keys[0]])) {
105
- throw Error(`The file(${xpath}) name should be always the same as class name.`);
106
- }
107
- }
108
- else if (target.name != fileName) { // export default class {}
109
- throw Error(`The file(${xpath}) name should be always the same as class name.`);
110
- }
111
- }
112
- if (!exSet) {
113
- return;
114
- }
115
- if (exSet.has(fileName)) {
116
- throw new Error(`A same class already exists. at \`${xpath}\`.`);
117
- }
118
- exSet.add(fileName);
119
- return;
120
- }
121
- /**
122
- * Format api interface data format
123
- *
124
- * @private
125
- * @param {Error | string | ApiInput} msg 待处理的接口数据信息|接口msg
126
- * @param {*} data 待返回的数据
127
- * @param {number} defaultCode 默认错误码
128
- * @returns {ApiOutput} 格式化之后的接口数据
129
- * @memberof BaseController
130
- */
131
- function formatApiData(msg, data, defaultCode) {
132
- let obj = {
133
- code: defaultCode,
134
- message: '',
135
- data: null,
136
- };
137
- if (koatty_lib.Helper.isError(msg)) {
138
- const { code, message } = msg;
139
- obj.code = code || defaultCode;
140
- obj.message = message;
141
- }
142
- else if (koatty_lib.Helper.isObject(msg)) {
143
- obj = { ...obj, ...msg };
144
- }
145
- else {
146
- obj.message = msg;
147
- obj.data = data;
148
- }
149
- return obj;
76
+ /*
77
+ * @Description: framework helper
78
+ * @Usage:
79
+ * @Author: richen
80
+ * @Date: 2023-12-09 21:56:32
81
+ * @LastEditTime: 2023-12-09 23:01:56
82
+ * @License: BSD (3-Clause)
83
+ * @Copyright (c): <richenlin(at)gmail.com>
84
+ */
85
+ /**
86
+ * Check class file
87
+ * name should be always the same as class name
88
+ * class must be unique
89
+ *
90
+ * @export
91
+ * @param {string} fileName
92
+ * @param {string} xpath
93
+ * @param {*} target
94
+ * @param {Set<unknown>} [exSet]
95
+ * @returns {*}
96
+ */
97
+ function checkClass(fileName, xpath, target, exSet) {
98
+ if (koatty_lib.Helper.isClass(target) && target.name != fileName) { // export default class name{}
99
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
100
+ }
101
+ if (target["__esModule"]) {
102
+ if (target.name === undefined) { // export class name{}
103
+ const keys = Object.keys(target);
104
+ if (keys[0] != fileName && koatty_lib.Helper.isClass(target[keys[0]])) {
105
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
106
+ }
107
+ }
108
+ else if (target.name != fileName) { // export default class {}
109
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
110
+ }
111
+ }
112
+ if (!exSet) {
113
+ return;
114
+ }
115
+ if (exSet.has(fileName)) {
116
+ throw new Error(`A same class already exists. at \`${xpath}\`.`);
117
+ }
118
+ exSet.add(fileName);
119
+ return;
120
+ }
121
+ /**
122
+ * Format api interface data format
123
+ *
124
+ * @private
125
+ * @param {Error | string | ApiInput} msg 待处理的接口数据信息|接口msg
126
+ * @param {*} data 待返回的数据
127
+ * @param {number} defaultCode 默认错误码
128
+ * @returns {ApiOutput} 格式化之后的接口数据
129
+ * @memberof BaseController
130
+ */
131
+ function formatApiData(msg, data, defaultCode) {
132
+ let obj = {
133
+ code: defaultCode,
134
+ message: '',
135
+ data: null,
136
+ };
137
+ if (koatty_lib.Helper.isError(msg)) {
138
+ const { code, message } = msg;
139
+ obj.code = code || defaultCode;
140
+ obj.message = message;
141
+ }
142
+ else if (koatty_lib.Helper.isObject(msg)) {
143
+ obj = { ...obj, ...msg };
144
+ }
145
+ else {
146
+ obj.message = msg;
147
+ obj.data = data;
148
+ }
149
+ return obj;
150
150
  }
151
151
 
152
- /*
153
- * @Description: framework constants
154
- * @Usage:
155
- * @Author: richen
156
- * @Date: 2023-12-09 21:56:32
157
- * @LastEditTime: 2023-12-09 23:00:13
158
- * @License: BSD (3-Clause)
159
- * @Copyright (c): <richenlin(at)gmail.com>
160
- */
161
- const COMPONENT_SCAN = 'COMPONENT_SCAN';
162
- const CONFIGURATION_SCAN = 'CONFIGURATION_SCAN';
163
- // tslint:disable: no-irregular-whitespace
152
+ /*
153
+ * @Description: framework constants
154
+ * @Usage:
155
+ * @Author: richen
156
+ * @Date: 2023-12-09 21:56:32
157
+ * @LastEditTime: 2023-12-09 23:00:13
158
+ * @License: BSD (3-Clause)
159
+ * @Copyright (c): <richenlin(at)gmail.com>
160
+ */
161
+ const COMPONENT_SCAN = 'COMPONENT_SCAN';
162
+ const CONFIGURATION_SCAN = 'CONFIGURATION_SCAN';
163
+ // tslint:disable: no-irregular-whitespace
164
164
  const LOGO = `
165
165
 
166
166
  ┬┌─┌─┐┌─┐┌┬┐┌┬┐┬ ┬
@@ -170,881 +170,878 @@ const LOGO = `
170
170
  https://github.com/koatty
171
171
  `;
172
172
 
173
- /*
174
- * @Description: base controller
175
- * @Usage:
176
- * @Author: richen
177
- * @Date: 2023-12-09 21:56:32
178
- * @LastEditTime: 2023-12-09 23:03:09
179
- * @License: BSD (3-Clause)
180
- * @Copyright (c): <richenlin(at)gmail.com>
181
- */
182
- /**
183
- * Base controller
184
- *
185
- * @export
186
- * @class BaseController
187
- * @implements {IController}
188
- */
189
- class BaseController {
190
- /**
191
- * instance of BaseController.
192
- * @param {Koatty} app
193
- * @param {KoattyContext} ctx
194
- * @memberof BaseController
195
- */
196
- constructor(ctx, ...arg) {
197
- this.ctx = ctx;
198
- this.init(arg);
199
- }
200
- /**
201
- * init
202
- *
203
- * @memberof BaseController
204
- */
205
- init(...arg) {
206
- }
207
- /**
208
- * Response to normalize json format content for success
209
- *
210
- * @param {(string | ApiInput)} msg 待处理的message消息
211
- * @param {*} [data] 待处理的数据
212
- * @param {number} [code=200] 错误码,默认0
213
- * @returns {*}
214
- * @memberof BaseController
215
- */
216
- ok(msg, data, code = 0) {
217
- const obj = formatApiData(msg, data, code);
218
- return Promise.resolve(obj);
219
- }
220
- /**
221
- * Response to normalize json format content for fail
222
- *
223
- * @param {(string | ApiInput)} msg
224
- * @param {*} [data]
225
- * @param {number} [code=1]
226
- * @returns {*}
227
- * @memberof BaseController
228
- */
229
- fail(msg, data, code = 1) {
230
- const obj = formatApiData(msg, data, code);
231
- this.ctx.body = obj.data;
232
- this.ctx.throw(obj.message, obj.code, 200);
233
- }
234
- }
235
- // const properties = ["constructor", "init"];
236
- // export const BaseController = new Proxy(Base, {
237
- // set(target, key, value, receiver) {
238
- // if (Reflect.get(target, key, receiver) === undefined) {
239
- // return Reflect.set(target, key, value, receiver);
240
- // } else if (key === "init") {
241
- // return Reflect.set(target, key, value, receiver);
242
- // } else {
243
- // throw Error("Cannot redefine getter-only property");
244
- // }
245
- // },
246
- // deleteProperty(target, key) {
247
- // throw Error("Cannot delete getter-only property");
248
- // },
249
- // construct(target, args, newTarget) {
250
- // Reflect.ownKeys(target.prototype).map((n) => {
251
- // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
252
- // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
253
- // }
254
- // });
255
- // return Reflect.construct(target, args, newTarget);
256
- // }
173
+ /*
174
+ * @Description: base controller
175
+ * @Usage:
176
+ * @Author: richen
177
+ * @Date: 2023-12-09 21:56:32
178
+ * @LastEditTime: 2023-12-09 23:03:09
179
+ * @License: BSD (3-Clause)
180
+ * @Copyright (c): <richenlin(at)gmail.com>
181
+ */
182
+ /**
183
+ * Base controller
184
+ *
185
+ * @export
186
+ * @class BaseController
187
+ * @implements {IController}
188
+ */
189
+ class BaseController {
190
+ /**
191
+ * instance of BaseController.
192
+ * @param {Koatty} app
193
+ * @param {KoattyContext} ctx
194
+ * @memberof BaseController
195
+ */
196
+ constructor(ctx, ...arg) {
197
+ this.ctx = ctx;
198
+ this.init(arg);
199
+ }
200
+ /**
201
+ * init
202
+ *
203
+ * @memberof BaseController
204
+ */
205
+ init(...arg) {
206
+ }
207
+ /**
208
+ * Response to normalize json format content for success
209
+ *
210
+ * @param {(string | ApiInput)} msg 待处理的message消息
211
+ * @param {*} [data] 待处理的数据
212
+ * @param {number} [code=200] 错误码,默认0
213
+ * @returns {*}
214
+ * @memberof BaseController
215
+ */
216
+ ok(msg, data, code = 0) {
217
+ const obj = formatApiData(msg, data, code);
218
+ return Promise.resolve(obj);
219
+ }
220
+ /**
221
+ * Response to normalize json format content for fail
222
+ *
223
+ * @param {(string | ApiInput)} msg
224
+ * @param {*} [data]
225
+ * @param {number} [code=1]
226
+ * @returns {*}
227
+ * @memberof BaseController
228
+ */
229
+ fail(msg, data, code = 1) {
230
+ const obj = formatApiData(msg, data, code);
231
+ this.ctx.body = obj.data;
232
+ this.ctx.throw(obj.message, obj.code, 200);
233
+ }
234
+ }
235
+ // const properties = ["constructor", "init"];
236
+ // export const BaseController = new Proxy(Base, {
237
+ // set(target, key, value, receiver) {
238
+ // if (Reflect.get(target, key, receiver) === undefined) {
239
+ // return Reflect.set(target, key, value, receiver);
240
+ // } else if (key === "init") {
241
+ // return Reflect.set(target, key, value, receiver);
242
+ // } else {
243
+ // throw Error("Cannot redefine getter-only property");
244
+ // }
245
+ // },
246
+ // deleteProperty(target, key) {
247
+ // throw Error("Cannot delete getter-only property");
248
+ // },
249
+ // construct(target, args, newTarget) {
250
+ // Reflect.ownKeys(target.prototype).map((n) => {
251
+ // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
252
+ // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
253
+ // }
254
+ // });
255
+ // return Reflect.construct(target, args, newTarget);
256
+ // }
257
257
  // });
258
258
 
259
- /*
260
- * @Description: trace & catcher middleware
261
- * @Usage:
262
- * @Author: richen
263
- * @Date: 2023-12-09 22:55:54
264
- * @LastEditTime: 2023-12-09 23:00:44
265
- * @License: BSD (3-Clause)
266
- * @Copyright (c): <richenlin(at)gmail.com>
267
- */
268
- class TraceMiddleware {
269
- run(options, app) {
270
- return koatty_trace.Trace(options, app);
271
- }
259
+ function TraceHandler(app) {
260
+ const timeout = (app.config('http_timeout') || 10) * 1000;
261
+ const encoding = app.config('encoding') || 'utf-8';
262
+ const openTrace = app.config("open_trace") || false;
263
+ const asyncHooks = app.config("async_hooks") || false;
264
+ const options = {
265
+ RequestIdHeaderName: app.config('trace_header') || 'X-Request-Id',
266
+ RequestIdName: app.config('trace_id') || "requestId",
267
+ IdFactory: undefined,
268
+ Timeout: timeout,
269
+ Encoding: encoding,
270
+ OpenTrace: openTrace,
271
+ AsyncHooks: asyncHooks,
272
+ };
273
+ app.use(koatty_trace.Trace(options, app));
272
274
  }
273
275
 
274
- /*
275
- * @Description: framework loader
276
- * @Usage:
277
- * @Author: richen
278
- * @Date: 2023-12-09 22:55:49
279
- * @LastEditTime: 2023-12-09 23:00:37
280
- * @License: BSD (3-Clause)
281
- * @Copyright (c): <richenlin(at)gmail.com>
282
- */
283
- /**
284
- *
285
- */
286
- class Loader {
287
- /**
288
- * initialize env
289
- *
290
- * @static
291
- * @param {Koatty} app
292
- * @memberof Loader
293
- */
294
- static initialize(app) {
295
- const env = (process.execArgv ?? []).join(",");
296
- if (env.indexOf('ts-node') > -1 || env.indexOf('--debug') > -1) {
297
- app.appDebug = true;
298
- }
299
- // app.env
300
- app.env = process.env.KOATTY_ENV || process.env.NODE_ENV;
301
- if ((env.indexOf('--production') > -1) || ((app.env ?? '').indexOf('pro') > -1)) {
302
- app.appDebug = false;
303
- }
304
- if (app.appDebug) {
305
- app.env = 'development';
306
- process.env.NODE_ENV = 'development';
307
- process.env.APP_DEBUG = 'true';
308
- Logger.setLevel("debug");
309
- }
310
- else {
311
- app.env = 'production';
312
- process.env.NODE_ENV = 'production';
313
- Logger.setLevel("info");
314
- }
315
- // define path
316
- const rootPath = app.rootPath || process.cwd();
317
- const appPath = app.appPath || path__namespace.resolve(rootPath, env.indexOf('ts-node') > -1 ? 'src' : 'dist');
318
- const koattyPath = path__namespace.resolve(__dirname, '..');
319
- koatty_lib.Helper.define(app, 'rootPath', rootPath);
320
- koatty_lib.Helper.define(app, 'appPath', appPath);
321
- koatty_lib.Helper.define(app, 'koattyPath', koattyPath);
322
- //
323
- if (koatty_lib.Helper.isEmpty(app.name)) {
324
- const pkg = koatty_lib.Helper.safeRequire(`${path__namespace.dirname(appPath)}/package.json`);
325
- if (pkg.name) {
326
- app.name = pkg.name;
327
- app.version = app.version || pkg.version;
328
- }
329
- }
330
- process.env.ROOT_PATH = rootPath;
331
- process.env.APP_PATH = appPath;
332
- process.env.KOATTY_PATH = koattyPath;
333
- // Compatible with old version, will be deprecated
334
- koatty_lib.Helper.define(app, 'prevent', koatty_exception.prevent);
335
- koatty_lib.Helper.define(app, 'thinkPath', koattyPath);
336
- process.env.THINK_PATH = koattyPath;
337
- }
338
- /**
339
- * Get component metadata
340
- *
341
- * @static
342
- * @param {Koatty} app
343
- * @param {*} target
344
- * @returns {*} {any[]}
345
- * @memberof Loader
346
- */
347
- static GetComponentMetas(app, target) {
348
- let componentMetas = [];
349
- const componentMeta = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, COMPONENT_SCAN, target);
350
- if (componentMeta) {
351
- if (koatty_lib.Helper.isArray(componentMeta)) {
352
- componentMetas = componentMeta;
353
- }
354
- else {
355
- componentMetas.push(componentMeta);
356
- }
357
- }
358
- if (componentMetas.length < 1) {
359
- componentMetas = [app.appPath];
360
- }
361
- return componentMetas;
362
- }
363
- /**
364
- * Load all bean, excepted config/*、App.ts
365
- *
366
- * @static
367
- * @param {Koatty} app
368
- * @param {*} target
369
- * @memberof Loader
370
- */
371
- static CheckAllComponents(app, target) {
372
- // component metadata
373
- const componentMetas = Loader.GetComponentMetas(app, target);
374
- // configuration metadata
375
- const configurationMetas = Loader.GetConfigurationMetas(app, target);
376
- const exSet = new Set();
377
- koatty_loader.Load(componentMetas, '', (fileName, xpath, xTarget) => {
378
- checkClass(fileName, xpath, xTarget, exSet);
379
- }, ['**/**.js', '**/**.ts', '!**/**.d.ts'], [...configurationMetas, `${target.name || '.no'}.ts`]);
380
- exSet.clear();
381
- }
382
- /**
383
- * Get configuration metadata
384
- *
385
- * @static
386
- * @param {Koatty} app
387
- * @param {*} target
388
- * @returns {*} {any[]}
389
- * @memberof Loader
390
- */
391
- static GetConfigurationMetas(app, target) {
392
- const confMeta = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, CONFIGURATION_SCAN, target);
393
- let configurationMetas = [];
394
- if (confMeta) {
395
- if (koatty_lib.Helper.isArray(confMeta)) {
396
- configurationMetas = confMeta;
397
- }
398
- else {
399
- configurationMetas.push(confMeta);
400
- }
401
- }
402
- return configurationMetas;
403
- }
404
- /**
405
- * Set Logger level
406
- *
407
- * @static
408
- * @param {Koatty} app
409
- * @memberof Loader
410
- */
411
- static SetLogger(app) {
412
- const data = app.getMetaData('_configs') || [];
413
- const configs = data[0] || {};
414
- //Logger
415
- if (configs.config) {
416
- const opt = configs.config;
417
- let logLevel = "debug", logFilePath = "", sensFields = [];
418
- if (app.env === "production") {
419
- logLevel = "info";
420
- }
421
- if (opt.logs_level) {
422
- logLevel = (opt.logs_level).toLowerCase();
423
- }
424
- if (opt.logs_path) {
425
- logFilePath = opt.logs_path;
426
- }
427
- if (opt.sens_fields) {
428
- sensFields = opt.sens_fields;
429
- }
430
- SetLogger(app, { logLevel, logFilePath, sensFields });
431
- }
432
- }
433
- /**
434
- * Load app event hook funcs
435
- *
436
- * @static
437
- * @param {Koatty} app
438
- * @param {*} target
439
- * @memberof Loader
440
- */
441
- static LoadAppEventHooks(app, target) {
442
- const eventFuncs = new Map();
443
- for (const event of koatty_core.AppEventArr) {
444
- let funcs;
445
- switch (event) {
446
- case "appBoot" /* AppEvent.appBoot */:
447
- funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appBoot" /* AppEvent.appBoot */, target);
448
- if (koatty_lib.Helper.isArray(funcs)) {
449
- eventFuncs.set("appBoot" /* AppEvent.appBoot */, funcs);
450
- }
451
- break;
452
- case "appReady" /* AppEvent.appReady */:
453
- funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appReady" /* AppEvent.appReady */, target);
454
- if (koatty_lib.Helper.isArray(funcs)) {
455
- eventFuncs.set("appReady" /* AppEvent.appReady */, funcs);
456
- }
457
- break;
458
- case "appStart" /* AppEvent.appStart */:
459
- funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appStart" /* AppEvent.appStart */, target);
460
- if (koatty_lib.Helper.isArray(funcs)) {
461
- eventFuncs.set("appStart" /* AppEvent.appStart */, funcs);
462
- }
463
- break;
464
- case "appStop" /* AppEvent.appStop */:
465
- funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appStop" /* AppEvent.appStop */, target);
466
- if (koatty_lib.Helper.isArray(funcs)) {
467
- eventFuncs.set("appStop" /* AppEvent.appStop */, funcs);
468
- }
469
- break;
470
- }
471
- }
472
- // loop event emit
473
- for (const [event, funcs] of eventFuncs) {
474
- for (const func of funcs) {
475
- app.once(event, () => func(app));
476
- }
477
- }
478
- }
479
- /**
480
- * Load configuration
481
- *
482
- * @static
483
- * @param {Koatty} app
484
- * @param {string[]} [loadPath]
485
- * @memberof Loader
486
- */
487
- static LoadConfigs(app, loadPath) {
488
- const frameConfig = {};
489
- // Logger.Debug(`Load configuration path: ${app.thinkPath}/config`);
490
- koatty_loader.Load(["./config"], app.koattyPath, function (name, path, exp) {
491
- frameConfig[name] = exp;
492
- });
493
- if (koatty_lib.Helper.isArray(loadPath)) {
494
- loadPath = loadPath.length > 0 ? loadPath : ["./config"];
495
- }
496
- let appConfig = koatty_config.LoadConfigs(loadPath, app.appPath);
497
- appConfig = koatty_lib.Helper.extend(frameConfig, appConfig, true);
498
- app.setMetaData("_configs", appConfig);
499
- }
500
- /**
501
- * Load middlewares
502
- * [async]
503
- * @static
504
- * @param {*} app
505
- * @param {(string | string[])} [loadPath]
506
- * @memberof Loader
507
- */
508
- static async LoadMiddlewares(app, loadPath) {
509
- let middlewareConf = app.config(undefined, "middleware");
510
- if (koatty_lib.Helper.isEmpty(middlewareConf)) {
511
- middlewareConf = { config: {}, list: [] };
512
- }
513
- //Mount default middleware
514
- koatty_loader.Load(loadPath || ["./middleware"], app.koattyPath);
515
- //Mount application middleware
516
- // const middleware: any = {};
517
- const appMiddleware = koatty_container.IOCContainer.listClass("MIDDLEWARE") ?? [];
518
- appMiddleware.push({ id: "TraceMiddleware", target: TraceMiddleware });
519
- appMiddleware.forEach((item) => {
520
- item.id = (item.id ?? "").replace("MIDDLEWARE:", "");
521
- if (item.id && koatty_lib.Helper.isClass(item.target)) {
522
- koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
523
- }
524
- });
525
- const middlewareConfList = middlewareConf.list;
526
- const defaultList = ["TraceMiddleware"];
527
- //de-duplication
528
- const appMList = new Set(defaultList);
529
- middlewareConfList.forEach((item) => {
530
- appMList.add(item);
531
- });
532
- //Automatically call middleware
533
- for (const key of appMList) {
534
- const handle = koatty_container.IOCContainer.get(key, "MIDDLEWARE");
535
- if (!handle) {
536
- Logger.Error(`Middleware ${key} load error.`);
537
- continue;
538
- }
539
- if (!koatty_lib.Helper.isFunction(handle.run)) {
540
- Logger.Error(`Middleware ${key} must be implements method 'run'.`);
541
- continue;
542
- }
543
- if (middlewareConf.config[key] === false) {
544
- // Default middleware cannot be disabled
545
- if (defaultList.includes(key)) {
546
- Logger.Warn(`Middleware ${key} cannot be disabled.`);
547
- }
548
- else {
549
- Logger.Warn(`Middleware ${key} already loaded but not effective.`);
550
- continue;
551
- }
552
- }
553
- Logger.Debug(`Load middleware: ${key}`);
554
- const result = await handle.run(middlewareConf.config[key] || {}, app);
555
- if (koatty_lib.Helper.isFunction(result)) {
556
- if (result.length < 3) {
557
- app.use(result);
558
- }
559
- else {
560
- app.useExp(result);
561
- }
562
- }
563
- }
564
- }
565
- /**
566
- * Load controllers
567
- *
568
- * @static
569
- * @param {*} app
570
- * @memberof Loader
571
- */
572
- static LoadControllers(app) {
573
- const controllerList = koatty_container.IOCContainer.listClass("CONTROLLER");
574
- const controllers = [];
575
- controllerList.forEach((item) => {
576
- item.id = (item.id ?? "").replace("CONTROLLER:", "");
577
- if (item.id && koatty_lib.Helper.isClass(item.target)) {
578
- Logger.Debug(`Load controller: ${item.id}`);
579
- // registering to IOC
580
- koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
581
- const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
582
- if (!(ctl instanceof BaseController)) {
583
- throw new Error(`class ${item.id} does not inherit from BaseController`);
584
- }
585
- controllers.push(item.id);
586
- }
587
- });
588
- return controllers;
589
- }
590
- /**
591
- * Load services
592
- *
593
- * @static
594
- * @param {*} app
595
- * @memberof Loader
596
- */
597
- static LoadServices(app) {
598
- const serviceList = koatty_container.IOCContainer.listClass("SERVICE");
599
- serviceList.forEach((item) => {
600
- item.id = (item.id ?? "").replace("SERVICE:", "");
601
- if (item.id && koatty_lib.Helper.isClass(item.target)) {
602
- Logger.Debug(`Load service: ${item.id}`);
603
- // registering to IOC
604
- koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
605
- }
606
- });
607
- }
608
- /**
609
- * Load components
610
- *
611
- * @static
612
- * @param {*} app
613
- * @memberof Loader
614
- */
615
- // public static LoadComponents(app: Koatty) {
616
- // const componentList = IOCContainer.listClass("COMPONENT");
617
- // componentList.forEach((item: ComponentItem) => {
618
- // item.id = (item.id ?? "").replace("COMPONENT:", "");
619
- // if (item.id && !(item.id).endsWith("Plugin") && Helper.isClass(item.target)) {
620
- // Logger.Debug(`Load component: ${item.id}`);
621
- // // registering to IOC
622
- // IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
623
- // }
624
- // });
625
- // }
626
- /**
627
- * Load components
628
- *
629
- * @static
630
- * @param {*} app
631
- * @memberof Loader
632
- */
633
- static async LoadComponents(app) {
634
- const componentList = koatty_container.IOCContainer.listClass("COMPONENT");
635
- const pluginList = [];
636
- componentList.forEach(async (item) => {
637
- item.id = (item.id ?? "").replace("COMPONENT:", "");
638
- if (koatty_lib.Helper.isClass(item.target)) {
639
- if (item.id && (item.id).endsWith("Plugin")) {
640
- pluginList.push(item.id);
641
- }
642
- // registering to IOC
643
- koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
644
- }
645
- });
646
- // load plugin config
647
- let pluginsConf = app.config(undefined, "plugin");
648
- if (koatty_lib.Helper.isEmpty(pluginsConf)) {
649
- pluginsConf = { config: {}, list: [] };
650
- }
651
- const pluginConfList = pluginsConf.list ?? [];
652
- // load plugin list
653
- for (const key of pluginConfList) {
654
- const handle = koatty_container.IOCContainer.get(key, "COMPONENT");
655
- if (!handle) {
656
- Logger.Error(`Plugin ${key} load error.`);
657
- continue;
658
- }
659
- if (!koatty_lib.Helper.isFunction(handle.run)) {
660
- Logger.Error(`Plugin ${key} must be implements method 'run'.`);
661
- continue;
662
- }
663
- if (pluginsConf.config[key] === false) {
664
- Logger.Warn(`Plugin ${key} already loaded but not effective.`);
665
- continue;
666
- }
667
- // sync exec
668
- await handle.run(pluginsConf.config[key] ?? {}, app);
669
- }
670
- }
276
+ /*
277
+ * @Description: framework loader
278
+ * @Usage:
279
+ * @Author: richen
280
+ * @Date: 2023-12-09 22:55:49
281
+ * @LastEditTime: 2023-12-14 23:10:33
282
+ * @License: BSD (3-Clause)
283
+ * @Copyright (c): <richenlin(at)gmail.com>
284
+ */
285
+ /**
286
+ *
287
+ */
288
+ class Loader {
289
+ /**
290
+ * initialize env
291
+ *
292
+ * @static
293
+ * @param {Koatty} app
294
+ * @memberof Loader
295
+ */
296
+ static initialize(app) {
297
+ const env = (process.execArgv ?? []).join(",");
298
+ if (env.indexOf('ts-node') > -1 || env.indexOf('--debug') > -1) {
299
+ app.appDebug = true;
300
+ }
301
+ // app.env
302
+ app.env = process.env.KOATTY_ENV || process.env.NODE_ENV;
303
+ if ((env.indexOf('--production') > -1) || ((app.env ?? '').indexOf('pro') > -1)) {
304
+ app.appDebug = false;
305
+ }
306
+ if (app.appDebug) {
307
+ app.env = 'development';
308
+ process.env.NODE_ENV = 'development';
309
+ process.env.APP_DEBUG = 'true';
310
+ Logger.setLevel("debug");
311
+ }
312
+ else {
313
+ app.env = 'production';
314
+ process.env.NODE_ENV = 'production';
315
+ Logger.setLevel("info");
316
+ }
317
+ // define path
318
+ const rootPath = app.rootPath || process.cwd();
319
+ const appPath = app.appPath || path__namespace.resolve(rootPath, env.indexOf('ts-node') > -1 ? 'src' : 'dist');
320
+ const koattyPath = path__namespace.resolve(__dirname, '..');
321
+ koatty_lib.Helper.define(app, 'rootPath', rootPath);
322
+ koatty_lib.Helper.define(app, 'appPath', appPath);
323
+ koatty_lib.Helper.define(app, 'koattyPath', koattyPath);
324
+ //
325
+ if (koatty_lib.Helper.isEmpty(app.name)) {
326
+ const pkg = koatty_lib.Helper.safeRequire(`${path__namespace.dirname(appPath)}/package.json`);
327
+ if (pkg.name) {
328
+ app.name = pkg.name;
329
+ app.version = app.version || pkg.version;
330
+ }
331
+ }
332
+ process.env.ROOT_PATH = rootPath;
333
+ process.env.APP_PATH = appPath;
334
+ process.env.KOATTY_PATH = koattyPath;
335
+ // Compatible with old version, will be deprecated
336
+ koatty_lib.Helper.define(app, 'prevent', koatty_exception.prevent);
337
+ koatty_lib.Helper.define(app, 'thinkPath', koattyPath);
338
+ process.env.THINK_PATH = koattyPath;
339
+ }
340
+ /**
341
+ * Get component metadata
342
+ *
343
+ * @static
344
+ * @param {Koatty} app
345
+ * @param {*} target
346
+ * @returns {*} {any[]}
347
+ * @memberof Loader
348
+ */
349
+ static GetComponentMetas(app, target) {
350
+ let componentMetas = [];
351
+ const componentMeta = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, COMPONENT_SCAN, target);
352
+ if (componentMeta) {
353
+ if (koatty_lib.Helper.isArray(componentMeta)) {
354
+ componentMetas = componentMeta;
355
+ }
356
+ else {
357
+ componentMetas.push(componentMeta);
358
+ }
359
+ }
360
+ if (componentMetas.length < 1) {
361
+ componentMetas = [app.appPath];
362
+ }
363
+ return componentMetas;
364
+ }
365
+ /**
366
+ * Load all bean, excepted config/*、App.ts
367
+ *
368
+ * @static
369
+ * @param {Koatty} app
370
+ * @param {*} target
371
+ * @memberof Loader
372
+ */
373
+ static CheckAllComponents(app, target) {
374
+ // component metadata
375
+ const componentMetas = Loader.GetComponentMetas(app, target);
376
+ // configuration metadata
377
+ const configurationMetas = Loader.GetConfigurationMetas(app, target);
378
+ const exSet = new Set();
379
+ koatty_loader.Load(componentMetas, '', (fileName, xpath, xTarget) => {
380
+ checkClass(fileName, xpath, xTarget, exSet);
381
+ }, ['**/**.js', '**/**.ts', '!**/**.d.ts'], [...configurationMetas, `${target.name || '.no'}.ts`]);
382
+ exSet.clear();
383
+ }
384
+ /**
385
+ * Get configuration metadata
386
+ *
387
+ * @static
388
+ * @param {Koatty} app
389
+ * @param {*} target
390
+ * @returns {*} {any[]}
391
+ * @memberof Loader
392
+ */
393
+ static GetConfigurationMetas(app, target) {
394
+ const confMeta = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, CONFIGURATION_SCAN, target);
395
+ let configurationMetas = [];
396
+ if (confMeta) {
397
+ if (koatty_lib.Helper.isArray(confMeta)) {
398
+ configurationMetas = confMeta;
399
+ }
400
+ else {
401
+ configurationMetas.push(confMeta);
402
+ }
403
+ }
404
+ return configurationMetas;
405
+ }
406
+ /**
407
+ * Set Logger level
408
+ *
409
+ * @static
410
+ * @param {Koatty} app
411
+ * @memberof Loader
412
+ */
413
+ static SetLogger(app) {
414
+ const data = app.getMetaData('_configs') || [];
415
+ const configs = data[0] || {};
416
+ //Logger
417
+ if (configs.config) {
418
+ const opt = configs.config;
419
+ let logLevel = "debug", logFilePath = "", sensFields = [];
420
+ if (app.env === "production") {
421
+ logLevel = "info";
422
+ }
423
+ if (opt.logs_level) {
424
+ logLevel = (opt.logs_level).toLowerCase();
425
+ }
426
+ if (opt.logs_path) {
427
+ logFilePath = opt.logs_path;
428
+ }
429
+ if (opt.sens_fields) {
430
+ sensFields = opt.sens_fields;
431
+ }
432
+ SetLogger(app, { logLevel, logFilePath, sensFields });
433
+ }
434
+ }
435
+ /**
436
+ * Load app event hook funcs
437
+ *
438
+ * @static
439
+ * @param {Koatty} app
440
+ * @param {*} target
441
+ * @memberof Loader
442
+ */
443
+ static LoadAppEventHooks(app, target) {
444
+ const eventFuncs = new Map();
445
+ for (const event of koatty_core.AppEventArr) {
446
+ let funcs;
447
+ switch (event) {
448
+ case "appBoot" /* AppEvent.appBoot */:
449
+ funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appBoot" /* AppEvent.appBoot */, target);
450
+ if (koatty_lib.Helper.isArray(funcs)) {
451
+ eventFuncs.set("appBoot" /* AppEvent.appBoot */, funcs);
452
+ }
453
+ break;
454
+ case "appReady" /* AppEvent.appReady */:
455
+ funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appReady" /* AppEvent.appReady */, target);
456
+ if (koatty_lib.Helper.isArray(funcs)) {
457
+ eventFuncs.set("appReady" /* AppEvent.appReady */, funcs);
458
+ }
459
+ break;
460
+ case "appStart" /* AppEvent.appStart */:
461
+ funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appStart" /* AppEvent.appStart */, target);
462
+ if (koatty_lib.Helper.isArray(funcs)) {
463
+ eventFuncs.set("appStart" /* AppEvent.appStart */, funcs);
464
+ }
465
+ break;
466
+ case "appStop" /* AppEvent.appStop */:
467
+ funcs = koatty_container.IOCContainer.getClassMetadata(koatty_container.TAGGED_CLS, "appStop" /* AppEvent.appStop */, target);
468
+ if (koatty_lib.Helper.isArray(funcs)) {
469
+ eventFuncs.set("appStop" /* AppEvent.appStop */, funcs);
470
+ }
471
+ break;
472
+ }
473
+ }
474
+ // loop event emit
475
+ for (const [event, funcs] of eventFuncs) {
476
+ for (const func of funcs) {
477
+ app.once(event, () => func(app));
478
+ }
479
+ }
480
+ }
481
+ /**
482
+ * Load configuration
483
+ *
484
+ * @static
485
+ * @param {Koatty} app
486
+ * @param {string[]} [loadPath]
487
+ * @memberof Loader
488
+ */
489
+ static LoadConfigs(app, loadPath) {
490
+ const frameConfig = {};
491
+ // Logger.Debug(`Load configuration path: ${app.thinkPath}/config`);
492
+ koatty_loader.Load(["./config"], app.koattyPath, function (name, path, exp) {
493
+ frameConfig[name] = exp;
494
+ });
495
+ if (koatty_lib.Helper.isArray(loadPath)) {
496
+ loadPath = loadPath.length > 0 ? loadPath : ["./config"];
497
+ }
498
+ let appConfig = koatty_config.LoadConfigs(loadPath, app.appPath);
499
+ appConfig = koatty_lib.Helper.extend(frameConfig, appConfig, true);
500
+ app.setMetaData("_configs", appConfig);
501
+ }
502
+ /**
503
+ * Load middlewares
504
+ * [async]
505
+ * @static
506
+ * @param {*} app
507
+ * @param {(string | string[])} [loadPath]
508
+ * @memberof Loader
509
+ */
510
+ static async LoadMiddlewares(app, loadPath) {
511
+ // Error handling middleware
512
+ TraceHandler(app);
513
+ let middlewareConf = app.config(undefined, "middleware");
514
+ if (koatty_lib.Helper.isEmpty(middlewareConf)) {
515
+ middlewareConf = { config: {}, list: [] };
516
+ }
517
+ //Mount default middleware
518
+ // Load(loadPath || ["./middleware"], app.koattyPath);
519
+ //Mount application middleware
520
+ // const middleware: any = {};
521
+ const appMiddleware = koatty_container.IOCContainer.listClass("MIDDLEWARE") ?? [];
522
+ appMiddleware.forEach((item) => {
523
+ item.id = (item.id ?? "").replace("MIDDLEWARE:", "");
524
+ if (item.id && koatty_lib.Helper.isClass(item.target)) {
525
+ koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
526
+ }
527
+ });
528
+ const middlewareConfList = middlewareConf.list;
529
+ //de-duplication
530
+ const appMList = new Set([]);
531
+ middlewareConfList.forEach((item) => {
532
+ appMList.add(item);
533
+ });
534
+ //Automatically call middleware
535
+ for (const key of appMList) {
536
+ const handle = koatty_container.IOCContainer.get(key, "MIDDLEWARE");
537
+ if (!handle) {
538
+ Logger.Error(`Middleware ${key} load error.`);
539
+ continue;
540
+ }
541
+ if (!koatty_lib.Helper.isFunction(handle.run)) {
542
+ Logger.Error(`The middleware ${key} must implements interface 'IMiddleware'.`);
543
+ continue;
544
+ }
545
+ if (middlewareConf.config[key] === false) {
546
+ Logger.Warn(`The middleware ${key} has been loaded but not executed.`);
547
+ continue;
548
+ }
549
+ Logger.Debug(`Load middleware: ${key}`);
550
+ const result = await handle.run(middlewareConf.config[key] || {}, app);
551
+ if (koatty_lib.Helper.isFunction(result)) {
552
+ if (result.length < 3) {
553
+ app.use(result);
554
+ }
555
+ else {
556
+ app.useExp(result);
557
+ }
558
+ }
559
+ }
560
+ }
561
+ /**
562
+ * Load controllers
563
+ *
564
+ * @static
565
+ * @param {*} app
566
+ * @memberof Loader
567
+ */
568
+ static LoadControllers(app) {
569
+ const controllerList = koatty_container.IOCContainer.listClass("CONTROLLER");
570
+ const controllers = [];
571
+ controllerList.forEach((item) => {
572
+ item.id = (item.id ?? "").replace("CONTROLLER:", "");
573
+ if (item.id && koatty_lib.Helper.isClass(item.target)) {
574
+ Logger.Debug(`Load controller: ${item.id}`);
575
+ // registering to IOC
576
+ koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
577
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
578
+ if (!(ctl instanceof BaseController)) {
579
+ throw new Error(`class ${item.id} does not inherit from BaseController`);
580
+ }
581
+ controllers.push(item.id);
582
+ }
583
+ });
584
+ return controllers;
585
+ }
586
+ /**
587
+ * Load services
588
+ *
589
+ * @static
590
+ * @param {*} app
591
+ * @memberof Loader
592
+ */
593
+ static LoadServices(app) {
594
+ const serviceList = koatty_container.IOCContainer.listClass("SERVICE");
595
+ serviceList.forEach((item) => {
596
+ item.id = (item.id ?? "").replace("SERVICE:", "");
597
+ if (item.id && koatty_lib.Helper.isClass(item.target)) {
598
+ Logger.Debug(`Load service: ${item.id}`);
599
+ // registering to IOC
600
+ koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
601
+ }
602
+ });
603
+ }
604
+ /**
605
+ * Load components
606
+ *
607
+ * @static
608
+ * @param {*} app
609
+ * @memberof Loader
610
+ */
611
+ // public static LoadComponents(app: Koatty) {
612
+ // const componentList = IOCContainer.listClass("COMPONENT");
613
+ // componentList.forEach((item: ComponentItem) => {
614
+ // item.id = (item.id ?? "").replace("COMPONENT:", "");
615
+ // if (item.id && !(item.id).endsWith("Plugin") && Helper.isClass(item.target)) {
616
+ // Logger.Debug(`Load component: ${item.id}`);
617
+ // // registering to IOC
618
+ // IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
619
+ // }
620
+ // });
621
+ // }
622
+ /**
623
+ * Load components
624
+ *
625
+ * @static
626
+ * @param {*} app
627
+ * @memberof Loader
628
+ */
629
+ static async LoadComponents(app) {
630
+ const componentList = koatty_container.IOCContainer.listClass("COMPONENT");
631
+ const pluginList = [];
632
+ componentList.forEach(async (item) => {
633
+ item.id = (item.id ?? "").replace("COMPONENT:", "");
634
+ if (koatty_lib.Helper.isClass(item.target)) {
635
+ if (item.id && (item.id).endsWith("Plugin")) {
636
+ pluginList.push(item.id);
637
+ }
638
+ // registering to IOC
639
+ koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
640
+ }
641
+ });
642
+ // load plugin config
643
+ let pluginsConf = app.config(undefined, "plugin");
644
+ if (koatty_lib.Helper.isEmpty(pluginsConf)) {
645
+ pluginsConf = { config: {}, list: [] };
646
+ }
647
+ const pluginConfList = pluginsConf.list ?? [];
648
+ // load plugin list
649
+ for (const key of pluginConfList) {
650
+ const handle = koatty_container.IOCContainer.get(key, "COMPONENT");
651
+ if (!handle) {
652
+ Logger.Error(`Plugin ${key} load error.`);
653
+ continue;
654
+ }
655
+ if (!koatty_lib.Helper.isFunction(handle.run)) {
656
+ Logger.Error(`Plugin ${key} must be implements method 'run'.`);
657
+ continue;
658
+ }
659
+ if (pluginsConf.config[key] === false) {
660
+ Logger.Warn(`Plugin ${key} already loaded but not effective.`);
661
+ continue;
662
+ }
663
+ // sync exec
664
+ await handle.run(pluginsConf.config[key] ?? {}, app);
665
+ }
666
+ }
671
667
  }
672
668
 
673
- var version = "3.10.4-1";
669
+ var version = "3.10.4-2";
674
670
  var engines = {
675
671
  node: ">12.0.0"
676
672
  };
677
673
 
678
- /*
679
- * @Description: framework runtime checker
680
- * @Usage:
681
- * @Author: richen
682
- * @Date: 2023-12-09 21:56:32
683
- * @LastEditTime: 2023-12-09 23:01:22
684
- * @License: BSD (3-Clause)
685
- * @Copyright (c): <richenlin(at)gmail.com>
686
- */
687
- const KOATTY_VERSION = version;
688
- const ENGINES_VERSION = engines.node.slice(1) || '12.0.0';
689
- /**
690
- * check node version
691
- * @return {void} []
692
- */
693
- function checkRuntime() {
694
- let nodeEngines = ENGINES_VERSION;
695
- nodeEngines = nodeEngines.slice(0, nodeEngines.lastIndexOf('.'));
696
- let nodeVersion = process.version;
697
- if (nodeVersion[0] === 'v') {
698
- nodeVersion = nodeVersion.slice(1);
699
- }
700
- nodeVersion = nodeVersion.slice(0, nodeVersion.lastIndexOf('.'));
701
- if (koatty_lib.Helper.toNumber(nodeEngines) > koatty_lib.Helper.toNumber(nodeVersion)) {
702
- Logger.Error(`Koatty need node version > ${nodeEngines}, current version is ${nodeVersion}, please upgrade it.`);
703
- process.exit(-1);
704
- }
705
- }
706
- /**
707
- * unittest running environment detection
708
- * only support jest
709
- * @returns {boolean}
710
- */
711
- const checkUTRuntime = () => {
712
- let isUTRuntime = false;
713
- // UT运行环境判断,暂时先只判断jest
714
- const argv = JSON.stringify(process.argv[1]);
715
- if (argv.indexOf('jest') > -1) {
716
- isUTRuntime = true;
717
- }
718
- return isUTRuntime;
674
+ /*
675
+ * @Description: framework runtime checker
676
+ * @Usage:
677
+ * @Author: richen
678
+ * @Date: 2023-12-09 21:56:32
679
+ * @LastEditTime: 2023-12-09 23:01:22
680
+ * @License: BSD (3-Clause)
681
+ * @Copyright (c): <richenlin(at)gmail.com>
682
+ */
683
+ const KOATTY_VERSION = version;
684
+ const ENGINES_VERSION = engines.node.slice(1) || '12.0.0';
685
+ /**
686
+ * check node version
687
+ * @return {void} []
688
+ */
689
+ function checkRuntime() {
690
+ let nodeEngines = ENGINES_VERSION;
691
+ nodeEngines = nodeEngines.slice(0, nodeEngines.lastIndexOf('.'));
692
+ let nodeVersion = process.version;
693
+ if (nodeVersion[0] === 'v') {
694
+ nodeVersion = nodeVersion.slice(1);
695
+ }
696
+ nodeVersion = nodeVersion.slice(0, nodeVersion.lastIndexOf('.'));
697
+ if (koatty_lib.Helper.toNumber(nodeEngines) > koatty_lib.Helper.toNumber(nodeVersion)) {
698
+ Logger.Error(`Koatty need node version > ${nodeEngines}, current version is ${nodeVersion}, please upgrade it.`);
699
+ process.exit(-1);
700
+ }
701
+ }
702
+ /**
703
+ * unittest running environment detection
704
+ * only support jest
705
+ * @returns {boolean}
706
+ */
707
+ const checkUTRuntime = () => {
708
+ let isUTRuntime = false;
709
+ // UT运行环境判断,暂时先只判断jest
710
+ const argv = JSON.stringify(process.argv[1]);
711
+ if (argv.indexOf('jest') > -1) {
712
+ isUTRuntime = true;
713
+ }
714
+ return isUTRuntime;
719
715
  };
720
716
 
721
- /*
722
- * @Description: framework bootstrap
723
- * @Usage:
724
- * @Author: richen
725
- * @Date: 2023-12-09 21:56:32
726
- * @LastEditTime: 2023-12-09 22:59:19
727
- * @License: BSD (3-Clause)
728
- * @Copyright (c): <richenlin(at)gmail.com>
729
- */
730
- /**
731
- * execute bootstrap
732
- *
733
- * @param {*} target
734
- * @param {Function} bootFunc
735
- * @param {boolean} [isInitiative=false] Whether to actively execute app instantiation,
736
- * mainly for unittest scenarios, you need to actively obtain app instances
737
- * @returns {Promise<void>}
738
- */
739
- const executeBootstrap = async function (target, bootFunc, isInitiative = false) {
740
- // checked runtime
741
- checkRuntime();
742
- // unittest running environment
743
- const isUTRuntime = checkUTRuntime();
744
- if (!isInitiative && isUTRuntime) {
745
- return;
746
- }
747
- const app = Reflect.construct(target, []);
748
- // unittest does not print startup logs
749
- if (isUTRuntime) {
750
- app.silent = true;
751
- Logger.enable(false);
752
- }
753
- try {
754
- !app.silent && Logger.Log("Koatty", LOGO);
755
- if (!(app instanceof koatty_core.Koatty)) {
756
- throw new Error(`class ${target.name} does not inherit from Koatty`);
757
- }
758
- // Initialize env
759
- Loader.initialize(app);
760
- // exec bootFunc
761
- if (koatty_lib.Helper.isFunction(bootFunc)) {
762
- Logger.Log('Koatty', '', 'Execute bootFunc ...');
763
- await bootFunc(app);
764
- }
765
- // Set IOCContainer.app
766
- koatty_container.IOCContainer.setApp(app);
767
- Logger.Log('Koatty', '', 'ComponentScan ...');
768
- // Check all bean
769
- Loader.CheckAllComponents(app, target);
770
- // Load configuration
771
- Logger.Log('Koatty', '', 'Load Configurations ...');
772
- // configuration metadata
773
- const configurationMetas = Loader.GetConfigurationMetas(app, target);
774
- Loader.LoadConfigs(app, configurationMetas);
775
- // Load App event hooks
776
- Loader.LoadAppEventHooks(app, target);
777
- Logger.Log('Koatty', '', 'Emit App Boot ...');
778
- await asyncEvent(app, "appBoot" /* AppEvent.appBoot */);
779
- // Load Components
780
- Logger.Log('Koatty', '', 'Load Components ...');
781
- await Loader.LoadComponents(app);
782
- // Load Middleware
783
- Logger.Log('Koatty', '', 'Load Middlewares ...');
784
- await Loader.LoadMiddlewares(app);
785
- // Load Services
786
- Logger.Log('Koatty', '', 'Load Services ...');
787
- Loader.LoadServices(app);
788
- // Load Controllers
789
- Logger.Log('Koatty', '', 'Load Controllers ...');
790
- const controllers = Loader.LoadControllers(app);
791
- // Create Server
792
- // app.server = newServe(app);
793
- koatty_lib.Helper.define(app, "server", koatty_serve.NewServe(app));
794
- // Create router
795
- // app.router = newRouter(app);
796
- koatty_lib.Helper.define(app, "router", koatty_serve.NewRouter(app));
797
- // Emit app ready event
798
- Logger.Log('Koatty', '', 'Emit App Ready ...');
799
- await asyncEvent(app, "appReady" /* AppEvent.appReady */);
800
- // Load Routers
801
- Logger.Log('Koatty', '', 'Load Routers ...');
802
- app.router.LoadRouter(controllers);
803
- if (!isUTRuntime) {
804
- // Start Server
805
- app.listen(listenCallback);
806
- }
807
- return app;
808
- }
809
- catch (err) {
810
- Logger.Error(err);
811
- process.exit();
812
- }
813
- };
814
- /**
815
- * Listening callback function
816
- *
817
- * @param {Koatty} app
818
- * @returns {*}
819
- */
820
- const listenCallback = (app) => {
821
- const options = app.server.options;
822
- Logger.Log('Koatty', '', '====================================');
823
- Logger.Log("Koatty", "", `Nodejs Version: ${process.version}`);
824
- Logger.Log("Koatty", "", `Koatty Version: v${KOATTY_VERSION}`);
825
- Logger.Log("Koatty", "", `App Environment: ${app.env}`);
826
- Logger.Log('Koatty', '', `Server Protocol: ${(options.protocol).toUpperCase()}`);
827
- Logger.Log("Koatty", "", `Server running at ${options.protocol === "http2" ? "https" : options.protocol}://${options.hostname || '127.0.0.1'}:${options.port}/`);
828
- Logger.Log("Koatty", "", "====================================");
829
- // binding event "appStop"
830
- Logger.Log('Koatty', '', 'Bind App Stop event ...');
831
- koatty_serve.BindProcessEvent(app, 'appStop');
832
- // tslint:disable-next-line: no-unused-expression
833
- app.appDebug && Logger.Warn(`Running in debug mode.`);
834
- // Set Logger
835
- Loader.SetLogger(app);
836
- };
837
- /**
838
- * Execute event as async
839
- *
840
- * @param {Koatty} event
841
- * @param {string} eventName
842
- */
843
- const asyncEvent = async function (event, eventName) {
844
- const ls = event.listeners(eventName);
845
- // eslint-disable-next-line no-restricted-syntax
846
- for await (const func of ls) {
847
- if (koatty_lib.Helper.isFunction(func)) {
848
- func();
849
- }
850
- }
851
- return event.removeAllListeners(eventName);
852
- };
853
- /**
854
- * Bootstrap application
855
- *
856
- * @export
857
- * @param {Function} [bootFunc]
858
- * @returns {ClassDecorator}
859
- */
860
- function Bootstrap(bootFunc) {
861
- return function (target) {
862
- if (!(target.prototype instanceof koatty_core.Koatty)) {
863
- throw new Error(`class does not inherit from Koatty`);
864
- }
865
- executeBootstrap(target, bootFunc);
866
- };
867
- }
868
- /**
869
- * Actively perform dependency injection
870
- * Parse the decorator, return the instantiated app.
871
- * @export ExecBootStrap
872
- * @param {Function} [bootFunc] callback function
873
- * @returns
874
- */
875
- function ExecBootStrap(bootFunc) {
876
- return async (target) => {
877
- if (!(target.prototype instanceof koatty_core.Koatty)) {
878
- throw new Error(`class ${target.name} does not inherit from Koatty`);
879
- }
880
- return await executeBootstrap(target, bootFunc, true);
881
- };
882
- }
883
- /**
884
- * Define project scan path
885
- *
886
- * @export
887
- * @param {(string | string[])} [scanPath]
888
- * @returns {ClassDecorator}
889
- */
890
- function ComponentScan(scanPath) {
891
- return (target) => {
892
- if (!(target.prototype instanceof koatty_core.Koatty)) {
893
- throw new Error(`class does not inherit from Koatty`);
894
- }
895
- scanPath = scanPath ?? '';
896
- koatty_container.IOCContainer.saveClassMetadata(koatty_container.TAGGED_CLS, COMPONENT_SCAN, scanPath, target);
897
- };
898
- }
899
- /**
900
- * Define project configuration scan path
901
- *
902
- * @export
903
- * @param {(string | string[])} [scanPath]
904
- * @returns {ClassDecorator}
905
- */
906
- function ConfigurationScan(scanPath) {
907
- return (target) => {
908
- if (!(target.prototype instanceof koatty_core.Koatty)) {
909
- throw new Error(`class does not inherit from Koatty`);
910
- }
911
- scanPath = scanPath ?? '';
912
- koatty_container.IOCContainer.saveClassMetadata(koatty_container.TAGGED_CLS, CONFIGURATION_SCAN, scanPath, target);
913
- };
914
- }
915
- /**
916
- * @description: bind App event hook func
917
- * example:
918
- * export function TestDecorator(): ClassDecorator {
919
- * return (target: Function) => {
920
- * BindEventHook(AppEvent.appBoot, (app: Koatty) => {
921
- * // todo
922
- * return Promise.resolve();
923
- * }, target)
924
- * }
925
- * }
926
- * @param {AppEvent} eventName
927
- * @param {EventHookFunc} eventFunc
928
- * @param {any} target
929
- * @return {*}
930
- */
931
- function BindEventHook(eventName, eventFunc, target) {
932
- koatty_container.IOCContainer.attachClassMetadata(koatty_container.TAGGED_CLS, eventName, eventFunc, target);
717
+ /*
718
+ * @Description: framework bootstrap
719
+ * @Usage:
720
+ * @Author: richen
721
+ * @Date: 2023-12-09 21:56:32
722
+ * @LastEditTime: 2023-12-14 23:06:45
723
+ * @License: BSD (3-Clause)
724
+ * @Copyright (c): <richenlin(at)gmail.com>
725
+ */
726
+ /**
727
+ * execute bootstrap
728
+ *
729
+ * @param {*} target
730
+ * @param {Function} bootFunc
731
+ * @param {boolean} [isInitiative=false] Whether to actively execute app instantiation,
732
+ * mainly for unittest scenarios, you need to actively obtain app instances
733
+ * @returns {Promise<void>}
734
+ */
735
+ const executeBootstrap = async function (target, bootFunc, isInitiative = false) {
736
+ // checked runtime
737
+ checkRuntime();
738
+ // unittest running environment
739
+ const isUTRuntime = checkUTRuntime();
740
+ if (!isInitiative && isUTRuntime) {
741
+ return;
742
+ }
743
+ const app = Reflect.construct(target, []);
744
+ // unittest does not print startup logs
745
+ if (isUTRuntime) {
746
+ app.silent = true;
747
+ Logger.enable(false);
748
+ }
749
+ try {
750
+ !app.silent && Logger.Log("Koatty", LOGO);
751
+ if (!(app instanceof koatty_core.Koatty)) {
752
+ throw new Error(`class ${target.name} does not inherit from Koatty`);
753
+ }
754
+ // Initialize env
755
+ Loader.initialize(app);
756
+ // exec bootFunc
757
+ if (koatty_lib.Helper.isFunction(bootFunc)) {
758
+ Logger.Log('Koatty', '', 'Execute bootFunc ...');
759
+ await bootFunc(app);
760
+ }
761
+ // Set IOCContainer.app
762
+ koatty_container.IOCContainer.setApp(app);
763
+ Logger.Log('Koatty', '', 'ComponentScan ...');
764
+ // Check all bean
765
+ Loader.CheckAllComponents(app, target);
766
+ // Load configuration
767
+ Logger.Log('Koatty', '', 'Load Configurations ...');
768
+ // configuration metadata
769
+ const configurationMetas = Loader.GetConfigurationMetas(app, target);
770
+ Loader.LoadConfigs(app, configurationMetas);
771
+ // Load App event hooks
772
+ Loader.LoadAppEventHooks(app, target);
773
+ Logger.Log('Koatty', '', 'Emit App Boot ...');
774
+ await asyncEvent(app, "appBoot" /* AppEvent.appBoot */);
775
+ // Load Components
776
+ Logger.Log('Koatty', '', 'Load Components ...');
777
+ await Loader.LoadComponents(app);
778
+ // Load Middleware
779
+ Logger.Log('Koatty', '', 'Load Middlewares ...');
780
+ await Loader.LoadMiddlewares(app);
781
+ // Load Services
782
+ Logger.Log('Koatty', '', 'Load Services ...');
783
+ Loader.LoadServices(app);
784
+ // Load Controllers
785
+ Logger.Log('Koatty', '', 'Load Controllers ...');
786
+ const controllers = Loader.LoadControllers(app);
787
+ // Create Server
788
+ // app.server = newServe(app);
789
+ koatty_lib.Helper.define(app, "server", koatty_serve.NewServe(app));
790
+ // Create router
791
+ // app.router = newRouter(app);
792
+ koatty_lib.Helper.define(app, "router", koatty_serve.NewRouter(app));
793
+ // Emit app ready event
794
+ Logger.Log('Koatty', '', 'Emit App Ready ...');
795
+ await asyncEvent(app, "appReady" /* AppEvent.appReady */);
796
+ // Load Routers
797
+ Logger.Log('Koatty', '', 'Load Routers ...');
798
+ app.router.LoadRouter(controllers);
799
+ if (!isUTRuntime) {
800
+ // Start Server
801
+ app.listen(listenCallback);
802
+ }
803
+ return app;
804
+ }
805
+ catch (err) {
806
+ Logger.Error(err);
807
+ process.exit();
808
+ }
809
+ };
810
+ /**
811
+ * Listening callback function
812
+ *
813
+ * @param {Koatty} app
814
+ * @returns {*}
815
+ */
816
+ const listenCallback = (app) => {
817
+ const options = app.server.options;
818
+ Logger.Log('Koatty', '', '====================================');
819
+ Logger.Log("Koatty", "", `Nodejs Version: ${process.version}`);
820
+ Logger.Log("Koatty", "", `Koatty Version: v${KOATTY_VERSION}`);
821
+ Logger.Log("Koatty", "", `App Environment: ${app.env}`);
822
+ Logger.Log('Koatty', '', `Server Protocol: ${(options.protocol).toUpperCase()}`);
823
+ Logger.Log("Koatty", "", `Server running at ${options.protocol === "http2" ? "https" : options.protocol}://${options.hostname || '127.0.0.1'}:${options.port}/`);
824
+ Logger.Log("Koatty", "", "====================================");
825
+ // binding event "appStop"
826
+ Logger.Log('Koatty', '', 'Bind App Stop event ...');
827
+ koatty_serve.BindProcessEvent(app, 'appStop');
828
+ // tslint:disable-next-line: no-unused-expression
829
+ app.appDebug && Logger.Warn(`Running in debug mode.`);
830
+ // Set Logger
831
+ Loader.SetLogger(app);
832
+ };
833
+ /**
834
+ * Execute event as async
835
+ *
836
+ * @param {Koatty} event
837
+ * @param {string} eventName
838
+ */
839
+ const asyncEvent = async function (event, eventName) {
840
+ const ls = event.listeners(eventName);
841
+ // eslint-disable-next-line no-restricted-syntax
842
+ for await (const func of ls) {
843
+ if (koatty_lib.Helper.isFunction(func)) {
844
+ func();
845
+ }
846
+ }
847
+ return event.removeAllListeners(eventName);
848
+ };
849
+ /**
850
+ * Bootstrap application
851
+ *
852
+ * @export
853
+ * @param {Function} [bootFunc]
854
+ * @returns {ClassDecorator}
855
+ */
856
+ function Bootstrap(bootFunc) {
857
+ return function (target) {
858
+ if (!(target.prototype instanceof koatty_core.Koatty)) {
859
+ throw new Error(`class does not inherit from Koatty`);
860
+ }
861
+ executeBootstrap(target, bootFunc);
862
+ };
863
+ }
864
+ /**
865
+ * Actively perform dependency injection
866
+ * Parse the decorator, return the instantiated app.
867
+ * @export ExecBootStrap
868
+ * @param {Function} [bootFunc] callback function
869
+ * @returns
870
+ */
871
+ function ExecBootStrap(bootFunc) {
872
+ return async (target) => {
873
+ if (!(target.prototype instanceof koatty_core.Koatty)) {
874
+ throw new Error(`class ${target.name} does not inherit from Koatty`);
875
+ }
876
+ return await executeBootstrap(target, bootFunc, true);
877
+ };
878
+ }
879
+ /**
880
+ * Define project scan path
881
+ *
882
+ * @export
883
+ * @param {(string | string[])} [scanPath]
884
+ * @returns {ClassDecorator}
885
+ */
886
+ function ComponentScan(scanPath) {
887
+ return (target) => {
888
+ if (!(target.prototype instanceof koatty_core.Koatty)) {
889
+ throw new Error(`class does not inherit from Koatty`);
890
+ }
891
+ scanPath = scanPath ?? '';
892
+ koatty_container.IOCContainer.saveClassMetadata(koatty_container.TAGGED_CLS, COMPONENT_SCAN, scanPath, target);
893
+ };
894
+ }
895
+ /**
896
+ * Define project configuration scan path
897
+ *
898
+ * @export
899
+ * @param {(string | string[])} [scanPath]
900
+ * @returns {ClassDecorator}
901
+ */
902
+ function ConfigurationScan(scanPath) {
903
+ return (target) => {
904
+ if (!(target.prototype instanceof koatty_core.Koatty)) {
905
+ throw new Error(`class does not inherit from Koatty`);
906
+ }
907
+ scanPath = scanPath ?? '';
908
+ koatty_container.IOCContainer.saveClassMetadata(koatty_container.TAGGED_CLS, CONFIGURATION_SCAN, scanPath, target);
909
+ };
910
+ }
911
+ /**
912
+ * @description: bind App event hook func
913
+ * example:
914
+ * export function TestDecorator(): ClassDecorator {
915
+ * return (target: Function) => {
916
+ * BindEventHook(AppEvent.appBoot, (app: Koatty) => {
917
+ * // todo
918
+ * return Promise.resolve();
919
+ * }, target)
920
+ * }
921
+ * }
922
+ * @param {AppEvent} eventName
923
+ * @param {EventHookFunc} eventFunc
924
+ * @param {any} target
925
+ * @return {*}
926
+ */
927
+ function BindEventHook(eventName, eventFunc, target) {
928
+ koatty_container.IOCContainer.attachClassMetadata(koatty_container.TAGGED_CLS, eventName, eventFunc, target);
933
929
  }
934
930
 
935
- /*
936
- * @Description: component interface
937
- * @Usage:
938
- * @Author: richen
939
- * @Date: 2023-12-09 21:56:32
940
- * @LastEditTime: 2023-12-09 23:03:33
941
- * @License: BSD (3-Clause)
942
- * @Copyright (c): <richenlin(at)gmail.com>
943
- */
944
- /**
945
- * Indicates that an decorated class is a "component".
946
- *
947
- * @export
948
- * @param {string} [identifier] component name
949
- * @returns {ClassDecorator}
950
- */
951
- function Component(identifier) {
952
- return (target) => {
953
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
954
- koatty_container.IOCContainer.saveClass("COMPONENT", target, identifier);
955
- };
956
- }
957
- /**
958
- * Indicates that an decorated class is a "controller".
959
- *
960
- * @export
961
- * @param {string} [path] controller router path
962
- * @returns {ClassDecorator}
963
- */
964
- function Controller(path = "") {
965
- return (target) => {
966
- const identifier = koatty_container.IOCContainer.getIdentifier(target);
967
- koatty_container.IOCContainer.saveClass("CONTROLLER", target, identifier);
968
- koatty_container.IOCContainer.savePropertyData(koatty_serve.CONTROLLER_ROUTER, path, target, identifier);
969
- };
970
- }
971
- /**
972
- * Indicates that an decorated class is a "middleware".
973
- *
974
- * @export
975
- * @param {string} [identifier] class name
976
- * @returns {ClassDecorator}
977
- */
978
- function Middleware(identifier) {
979
- return (target) => {
980
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
981
- koatty_container.IOCContainer.saveClass("MIDDLEWARE", target, identifier);
982
- };
983
- }
984
- /**
985
- * Indicates that an decorated class is a "service".
986
- *
987
- * @export
988
- * @param {string} [identifier] class name
989
- * @returns {ClassDecorator}
990
- */
991
- function Service(identifier) {
992
- return (target) => {
993
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
994
- koatty_container.IOCContainer.saveClass("SERVICE", target, identifier);
995
- };
996
- }
997
- /**
998
- * Indicates that an decorated class is a "plugin".
999
- *
1000
- * @export
1001
- * @param {string} [identifier] class name
1002
- * @returns {ClassDecorator}
1003
- */
1004
- function Plugin(identifier) {
1005
- return (target) => {
1006
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
1007
- //
1008
- if (!identifier.endsWith("Plugin")) {
1009
- throw Error("Plugin class name must be 'Plugin' suffix.");
1010
- }
1011
- koatty_container.IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
1012
- };
931
+ /*
932
+ * @Description: component interface
933
+ * @Usage:
934
+ * @Author: richen
935
+ * @Date: 2023-12-09 21:56:32
936
+ * @LastEditTime: 2023-12-09 23:03:33
937
+ * @License: BSD (3-Clause)
938
+ * @Copyright (c): <richenlin(at)gmail.com>
939
+ */
940
+ // tslint:disable-next-line: no-import-side-effect
941
+ /**
942
+ * Indicates that an decorated class is a "component".
943
+ *
944
+ * @export
945
+ * @param {string} [identifier] component name
946
+ * @returns {ClassDecorator}
947
+ */
948
+ function Component(identifier) {
949
+ return (target) => {
950
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
951
+ koatty_container.IOCContainer.saveClass("COMPONENT", target, identifier);
952
+ };
953
+ }
954
+ /**
955
+ * Indicates that an decorated class is a "controller".
956
+ *
957
+ * @export
958
+ * @param {string} [path] controller router path
959
+ * @returns {ClassDecorator}
960
+ */
961
+ function Controller(path = "") {
962
+ return (target) => {
963
+ const identifier = koatty_container.IOCContainer.getIdentifier(target);
964
+ koatty_container.IOCContainer.saveClass("CONTROLLER", target, identifier);
965
+ koatty_container.IOCContainer.savePropertyData(koatty_serve.CONTROLLER_ROUTER, path, target, identifier);
966
+ };
967
+ }
968
+ /**
969
+ * Indicates that an decorated class is a "middleware".
970
+ *
971
+ * @export
972
+ * @param {string} [identifier] class name
973
+ * @returns {ClassDecorator}
974
+ */
975
+ function Middleware(identifier) {
976
+ return (target) => {
977
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
978
+ koatty_container.IOCContainer.saveClass("MIDDLEWARE", target, identifier);
979
+ };
980
+ }
981
+ /**
982
+ * Indicates that an decorated class is a "service".
983
+ *
984
+ * @export
985
+ * @param {string} [identifier] class name
986
+ * @returns {ClassDecorator}
987
+ */
988
+ function Service(identifier) {
989
+ return (target) => {
990
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
991
+ koatty_container.IOCContainer.saveClass("SERVICE", target, identifier);
992
+ };
993
+ }
994
+ /**
995
+ * Indicates that an decorated class is a "plugin".
996
+ *
997
+ * @export
998
+ * @param {string} [identifier] class name
999
+ * @returns {ClassDecorator}
1000
+ */
1001
+ function Plugin(identifier) {
1002
+ return (target) => {
1003
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
1004
+ //
1005
+ if (!identifier.endsWith("Plugin")) {
1006
+ throw Error("Plugin class name must be 'Plugin' suffix.");
1007
+ }
1008
+ koatty_container.IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
1009
+ };
1013
1010
  }
1014
1011
 
1015
- /*
1016
- * @Description: base service
1017
- * @Usage:
1018
- * @Author: richen
1019
- * @Date: 2023-12-09 21:56:32
1020
- * @LastEditTime: 2023-12-09 23:03:23
1021
- * @License: BSD (3-Clause)
1022
- * @Copyright (c): <richenlin(at)gmail.com>
1023
- */
1024
- /**
1025
- * Base service
1026
- *
1027
- * @export
1028
- * @class Base
1029
- */
1030
- class BaseService {
1031
- /**
1032
- * instance of BaseController.
1033
- * @param {Koatty} app
1034
- * @param {KoattyContext} ctx
1035
- * @memberof BaseController
1036
- */
1037
- constructor(...arg) {
1038
- this.init(arg);
1039
- }
1040
- /**
1041
- * init
1042
- *
1043
- * @protected
1044
- * @memberof BaseController
1045
- */
1046
- init(...arg) {
1047
- }
1012
+ /*
1013
+ * @Description: base service
1014
+ * @Usage:
1015
+ * @Author: richen
1016
+ * @Date: 2023-12-09 21:56:32
1017
+ * @LastEditTime: 2023-12-09 23:03:23
1018
+ * @License: BSD (3-Clause)
1019
+ * @Copyright (c): <richenlin(at)gmail.com>
1020
+ */
1021
+ /**
1022
+ * Base service
1023
+ *
1024
+ * @export
1025
+ * @class Base
1026
+ */
1027
+ class BaseService {
1028
+ /**
1029
+ * instance of BaseController.
1030
+ * @param {Koatty} app
1031
+ * @param {KoattyContext} ctx
1032
+ * @memberof BaseController
1033
+ */
1034
+ constructor(...arg) {
1035
+ this.init(arg);
1036
+ }
1037
+ /**
1038
+ * init
1039
+ *
1040
+ * @protected
1041
+ * @memberof BaseController
1042
+ */
1043
+ init(...arg) {
1044
+ }
1048
1045
  }
1049
1046
 
1050
1047
  Object.defineProperty(exports, 'Config', {
@@ -1073,31 +1070,31 @@ exports.Middleware = Middleware;
1073
1070
  exports.Plugin = Plugin;
1074
1071
  exports.Service = Service;
1075
1072
  Object.keys(koatty_core).forEach(function (k) {
1076
- if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
1073
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1077
1074
  enumerable: true,
1078
1075
  get: function () { return koatty_core[k]; }
1079
1076
  });
1080
1077
  });
1081
1078
  Object.keys(koatty_exception).forEach(function (k) {
1082
- if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
1079
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1083
1080
  enumerable: true,
1084
1081
  get: function () { return koatty_exception[k]; }
1085
1082
  });
1086
1083
  });
1087
1084
  Object.keys(koatty_container).forEach(function (k) {
1088
- if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
1085
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1089
1086
  enumerable: true,
1090
1087
  get: function () { return koatty_container[k]; }
1091
1088
  });
1092
1089
  });
1093
1090
  Object.keys(koatty_trace).forEach(function (k) {
1094
- if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
1091
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1095
1092
  enumerable: true,
1096
1093
  get: function () { return koatty_trace[k]; }
1097
1094
  });
1098
1095
  });
1099
1096
  Object.keys(koatty_serve).forEach(function (k) {
1100
- if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
1097
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1101
1098
  enumerable: true,
1102
1099
  get: function () { return koatty_serve[k]; }
1103
1100
  });