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