koatty 3.11.4-2 → 3.11.7

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,99 +1,32 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2024-04-15 05:09:24
3
+ * @Date: 2024-12-06 09:38:17
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
7
7
  */
8
- import { CONTROLLER_ROUTER, NewRouter } from 'koatty_router';
9
- export * from 'koatty_router';
10
- import { IOCContainer, TAGGED_CLS } from 'koatty_container';
8
+ import { LoadConfigs } from 'koatty_config';
9
+ export { Config } from 'koatty_config';
10
+ import { IOC, TAGGED_CLS } from 'koatty_container';
11
11
  export * from 'koatty_container';
12
- import { AppEventArr, Koatty } from 'koatty_core';
12
+ import { AppEventArr, implementsMiddlewareInterface, implementsControllerInterface, implementsServiceInterface, implementsPluginInterface, implementsAspectInterface, Koatty } from 'koatty_core';
13
13
  export * from 'koatty_core';
14
- import { NewServe, BindProcessEvent } from 'koatty_serve';
15
- export * from 'koatty_serve';
16
- import * as path from 'path';
17
- import { Load } from 'koatty_loader';
18
- import { prevent } from 'koatty_exception';
19
14
  export * from 'koatty_exception';
20
- import { LoadConfigs } from 'koatty_config';
21
- export { Config, Value } from 'koatty_config';
22
- import { Trace } from 'koatty_trace';
15
+ import { NewRouter } from 'koatty_router';
16
+ export * from 'koatty_router';
23
17
  import { Helper } from 'koatty_lib';
24
18
  export { Helper } from 'koatty_lib';
25
19
  import { DefaultLogger } from 'koatty_logger';
26
- import 'reflect-metadata';
27
-
28
- function TraceHandler(app) {
29
- const timeout = (app.config('http_timeout') || 10) * 1000;
30
- const encoding = app.config('encoding') || 'utf-8';
31
- const openTrace = app.config("open_trace") || false;
32
- const asyncHooks = app.config("async_hooks") || false;
33
- const options = {
34
- RequestIdHeaderName: app.config('trace_header') || 'X-Request-Id',
35
- RequestIdName: app.config('trace_id') || "requestId",
36
- IdFactory: undefined,
37
- Timeout: timeout,
38
- Encoding: encoding,
39
- OpenTrace: openTrace,
40
- AsyncHooks: asyncHooks,
41
- };
42
- app.use(Trace(options, app));
43
- }
44
-
45
- /*
46
- * @Description: framework helper
47
- * @Usage:
48
- * @Author: richen
49
- * @Date: 2023-12-09 21:56:32
50
- * @LastEditTime: 2024-01-16 01:20:17
51
- * @License: BSD (3-Clause)
52
- * @Copyright (c): <richenlin(at)gmail.com>
53
- */
54
- /**
55
- * Check class file
56
- * name should be always the same as class name
57
- * class must be unique
58
- *
59
- * @export
60
- * @param {string} fileName
61
- * @param {string} xpath
62
- * @param {*} target
63
- * @param {Set<unknown>} [exSet]
64
- * @returns {*}
65
- */
66
- function checkClass(fileName, xpath, target, exSet) {
67
- if (Helper.isClass(target) && target.name != fileName) { // export default class name{}
68
- throw Error(`The file(${xpath}) name should be always the same as class name.`);
69
- }
70
- if (target["__esModule"]) {
71
- if (target.name === undefined) { // export class name{}
72
- const keys = Object.keys(target);
73
- if (keys[0] != fileName && Helper.isClass(target[keys[0]])) {
74
- throw Error(`The file(${xpath}) name should be always the same as class name.`);
75
- }
76
- }
77
- else if (target.name != fileName) { // export default class {}
78
- throw Error(`The file(${xpath}) name should be always the same as class name.`);
79
- }
80
- }
81
- if (!exSet) {
82
- return;
83
- }
84
- if (exSet.has(fileName)) {
85
- throw new Error(`A same class already exists. at \`${xpath}\`.`);
86
- }
87
- exSet.add(fileName);
88
- return;
89
- }
20
+ import { Load } from 'koatty_loader';
21
+ import { NewServe } from 'koatty_serve';
22
+ import * as path from 'path';
90
23
 
91
24
  /*
92
25
  * @Description: framework logger
93
26
  * @Usage:
94
27
  * @Author: richen
95
28
  * @Date: 2023-12-09 21:56:32
96
- * @LastEditTime: 2023-12-09 23:02:27
29
+ * @LastEditTime: 2024-10-31 17:52:43
97
30
  * @License: BSD (3-Clause)
98
31
  * @Copyright (c): <richenlin(at)gmail.com>
99
32
  */
@@ -123,125 +56,98 @@ function SetLogger(app, config) {
123
56
  }
124
57
  }
125
58
 
59
+ var version = "3.11.7";
60
+ var engines = {
61
+ node: ">12.0.0"
62
+ };
63
+
126
64
  /*
127
- * @Description: component interface
65
+ * @Description: framework runtime checker
128
66
  * @Usage:
129
67
  * @Author: richen
130
68
  * @Date: 2023-12-09 21:56:32
131
- * @LastEditTime: 2024-01-19 08:36:27
69
+ * @LastEditTime: 2023-12-09 23:01:22
132
70
  * @License: BSD (3-Clause)
133
71
  * @Copyright (c): <richenlin(at)gmail.com>
134
72
  */
135
- // tslint:disable-next-line: no-import-side-effect
136
- /**
137
- * Indicates that an decorated class is a "component".
138
- *
139
- * @export
140
- * @param {string} [identifier] component name
141
- * @returns {ClassDecorator}
142
- */
143
- function Component(identifier) {
144
- return (target) => {
145
- identifier = identifier || IOCContainer.getIdentifier(target);
146
- IOCContainer.saveClass("COMPONENT", target, identifier);
147
- };
148
- }
73
+ const KOATTY_VERSION = version;
74
+ const ENGINES_VERSION = engines.node.slice(1) || '12.0.0';
149
75
  /**
150
- * Indicates that an decorated class is a "controller".
151
- *
152
- * @export
153
- * @param {string} [path] controller router path
154
- * @returns {ClassDecorator}
76
+ * check node version
77
+ * @return {void} []
155
78
  */
156
- function Controller(path = "") {
157
- return (target) => {
158
- const identifier = IOCContainer.getIdentifier(target);
159
- IOCContainer.saveClass("CONTROLLER", target, identifier);
160
- IOCContainer.savePropertyData(CONTROLLER_ROUTER, path, target, identifier);
161
- };
79
+ function checkRuntime() {
80
+ let nodeEngines = ENGINES_VERSION;
81
+ nodeEngines = nodeEngines.slice(0, nodeEngines.lastIndexOf('.'));
82
+ let nodeVersion = process.version;
83
+ if (nodeVersion[0] === 'v') {
84
+ nodeVersion = nodeVersion.slice(1);
85
+ }
86
+ nodeVersion = nodeVersion.slice(0, nodeVersion.lastIndexOf('.'));
87
+ if (Helper.toNumber(nodeEngines) > Helper.toNumber(nodeVersion)) {
88
+ Logger.Error(`Koatty need node version > ${nodeEngines}, current version is ${nodeVersion}, please upgrade it.`);
89
+ process.exit(-1);
90
+ }
162
91
  }
163
92
  /**
164
- * Indicates that an decorated class is a "middleware".
165
- *
166
- * @export
167
- * @param {string} [identifier] class name
168
- * @returns {ClassDecorator}
93
+ * unittest running environment detection
94
+ * only support jest
95
+ * @returns {boolean}
169
96
  */
170
- function Middleware(identifier) {
171
- return (target) => {
172
- identifier = identifier || IOCContainer.getIdentifier(target);
173
- IOCContainer.saveClass("MIDDLEWARE", target, identifier);
174
- };
175
- }
176
- /**
177
- * Indicates that an decorated class is a "service".
178
- *
179
- * @export
180
- * @param {string} [identifier] class name
181
- * @returns {ClassDecorator}
97
+ const checkUTRuntime = () => {
98
+ let isUTRuntime = false;
99
+ // UT运行环境判断,暂时先只判断jest
100
+ const argv = JSON.stringify(process.argv[1]);
101
+ if (argv.indexOf('jest') > -1) {
102
+ isUTRuntime = true;
103
+ }
104
+ return isUTRuntime;
105
+ };
106
+
107
+ /*
108
+ * @Description: framework helper
109
+ * @Usage:
110
+ * @Author: richen
111
+ * @Date: 2023-12-09 21:56:32
112
+ * @LastEditTime: 2024-01-16 01:20:17
113
+ * @License: BSD (3-Clause)
114
+ * @Copyright (c): <richenlin(at)gmail.com>
182
115
  */
183
- function Service(identifier) {
184
- return (target) => {
185
- identifier = identifier || IOCContainer.getIdentifier(target);
186
- IOCContainer.saveClass("SERVICE", target, identifier);
187
- };
188
- }
189
116
  /**
190
- * Indicates that an decorated class is a "plugin".
117
+ * Check class file
118
+ * name should be always the same as class name
119
+ * class must be unique
191
120
  *
192
121
  * @export
193
- * @param {string} [identifier] class name
194
- * @returns {ClassDecorator}
122
+ * @param {string} fileName
123
+ * @param {string} xpath
124
+ * @param {*} target
125
+ * @param {Set<unknown>} [exSet]
126
+ * @returns {*}
195
127
  */
196
- function Plugin(identifier) {
197
- return (target) => {
198
- identifier = identifier || IOCContainer.getIdentifier(target);
199
- //
200
- if (!identifier.endsWith("Plugin")) {
201
- throw Error("Plugin class name must be 'Plugin' suffix.");
128
+ function checkClass(fileName, xpath, target, exSet) {
129
+ if (Helper.isClass(target) && target.name != fileName) { // export default class name{}
130
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
131
+ }
132
+ if (target["__esModule"]) {
133
+ if (target.name === undefined) { // export class name{}
134
+ const keys = Object.keys(target);
135
+ if (keys[0] != fileName && Helper.isClass(target[keys[0]])) {
136
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
137
+ }
202
138
  }
203
- IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
204
- };
205
- }
206
- /**
207
- * check is implements Middleware Interface
208
- * @param cls
209
- * @returns
210
- */
211
- function implementsMiddlewareInterface(cls) {
212
- return 'run' in cls && Helper.isFunction(cls.run);
213
- }
214
- /**
215
- * check is implements Controller Interface
216
- * @param cls
217
- * @returns
218
- */
219
- function implementsControllerInterface(cls) {
220
- return 'app' in cls && 'ctx' in cls;
221
- }
222
- /**
223
- * check is implements Service Interface
224
- * @param cls
225
- * @returns
226
- */
227
- function implementsServiceInterface(cls) {
228
- return 'app' in cls;
229
- }
230
- /**
231
- * check is implements Plugin Interface
232
- * @param cls
233
- * @returns
234
- */
235
- function implementsPluginInterface(cls) {
236
- return 'run' in cls && Helper.isFunction(cls.run);
237
- }
238
- /**
239
- * check is implements Aspect Interface
240
- * @param cls
241
- * @returns
242
- */
243
- function implementsAspectInterface(cls) {
244
- return 'app' in cls && 'run' in cls && Helper.isFunction(cls.run);
139
+ else if (target.name != fileName) { // export default class {}
140
+ throw Error(`The file(${xpath}) name should be always the same as class name.`);
141
+ }
142
+ }
143
+ if (!exSet) {
144
+ return;
145
+ }
146
+ if (exSet.has(fileName)) {
147
+ throw new Error(`A same class already exists. at \`${xpath}\`.`);
148
+ }
149
+ exSet.add(fileName);
150
+ return;
245
151
  }
246
152
 
247
153
  /*
@@ -256,13 +162,13 @@ function implementsAspectInterface(cls) {
256
162
  const COMPONENT_SCAN = 'COMPONENT_SCAN';
257
163
  const CONFIGURATION_SCAN = 'CONFIGURATION_SCAN';
258
164
  // tslint:disable: no-irregular-whitespace
259
- const LOGO = `
260
-
261
- ┬┌─┌─┐┌─┐┌┬┐┌┬┐┬ ┬
262
- ├┴┐│ │├─┤ │ │ └┬┘
263
- ┴ ┴└─┘┴ ┴ ┴ ┴ ┴
264
- -------------------------------------------
265
- https://github.com/koatty
165
+ const LOGO = `
166
+
167
+ ┬┌─┌─┐┌─┐┌┬┐┌┬┐┬ ┬
168
+ ├┴┐│ │├─┤ │ │ └┬┘
169
+ ┴ ┴└─┘┴ ┴ ┴ ┴ ┴
170
+ -------------------------------------------
171
+ https://github.com/koatty
266
172
  `;
267
173
 
268
174
  /*
@@ -270,7 +176,7 @@ https://github.com/koatty
270
176
  * @Usage:
271
177
  * @Author: richen
272
178
  * @Date: 2023-12-09 22:55:49
273
- * @LastEditTime: 2024-01-24 11:54:29
179
+ * @LastEditTime: 2024-11-29 18:20:23
274
180
  * @License: BSD (3-Clause)
275
181
  * @Copyright (c): <richenlin(at)gmail.com>
276
182
  */
@@ -278,21 +184,30 @@ https://github.com/koatty
278
184
  *
279
185
  */
280
186
  class Loader {
187
+ /**
188
+ * Creates an instance of Loader.
189
+ * @param {KoattyApplication} app
190
+ * @memberof Loader
191
+ */
192
+ constructor(app) {
193
+ this.app = app;
194
+ }
281
195
  /**
282
196
  * initialize env
283
197
  *
284
198
  * @static
285
- * @param {Koatty} app
199
+ * @param {KoattyApplication} app
286
200
  * @memberof Loader
287
201
  */
288
202
  static initialize(app) {
289
- const env = (process.execArgv ?? []).join(",");
203
+ var _a, _b;
204
+ const env = ((_a = process.execArgv) !== null && _a !== void 0 ? _a : []).join(",");
290
205
  if (env.indexOf('ts-node') > -1 || env.indexOf('--debug') > -1) {
291
206
  app.appDebug = true;
292
207
  }
293
208
  // app.env
294
209
  app.env = process.env.KOATTY_ENV || process.env.NODE_ENV;
295
- if ((env.indexOf('--production') > -1) || ((app.env ?? '').indexOf('pro') > -1)) {
210
+ if ((env.indexOf('--production') > -1) || (((_b = app.env) !== null && _b !== void 0 ? _b : '').indexOf('pro') > -1)) {
296
211
  app.appDebug = false;
297
212
  }
298
213
  if (app.appDebug) {
@@ -308,7 +223,7 @@ class Loader {
308
223
  }
309
224
  // define path
310
225
  const rootPath = app.rootPath || process.cwd();
311
- const appPath = app.appPath || path.resolve(rootPath, env.indexOf('ts-node') > -1 ? 'src' : 'dist');
226
+ const appPath = app.appPath || path.resolve(rootPath, app.appDebug ? 'src' : 'dist');
312
227
  const koattyPath = path.resolve(__dirname, '..');
313
228
  Helper.define(app, 'rootPath', rootPath);
314
229
  Helper.define(app, 'appPath', appPath);
@@ -325,7 +240,6 @@ class Loader {
325
240
  process.env.APP_PATH = appPath;
326
241
  process.env.KOATTY_PATH = koattyPath;
327
242
  // Compatible with old version, will be deprecated
328
- Helper.define(app, 'prevent', prevent);
329
243
  Helper.define(app, 'thinkPath', koattyPath);
330
244
  process.env.THINK_PATH = koattyPath;
331
245
  }
@@ -333,14 +247,14 @@ class Loader {
333
247
  * Get component metadata
334
248
  *
335
249
  * @static
336
- * @param {Koatty} app
250
+ * @param {KoattyApplication} app
337
251
  * @param {*} target
338
252
  * @returns {*} {any[]}
339
253
  * @memberof Loader
340
254
  */
341
- static GetComponentMetas(app, target) {
255
+ static GetComponentMeta(app, target) {
342
256
  let componentMetas = [];
343
- const componentMeta = IOCContainer.getClassMetadata(TAGGED_CLS, COMPONENT_SCAN, target);
257
+ const componentMeta = IOC.getClassMetadata(TAGGED_CLS, COMPONENT_SCAN, target);
344
258
  if (componentMeta) {
345
259
  if (Helper.isArray(componentMeta)) {
346
260
  componentMetas = componentMeta;
@@ -354,36 +268,17 @@ class Loader {
354
268
  }
355
269
  return componentMetas;
356
270
  }
357
- /**
358
- * Load all bean, excepted config/*、App.ts
359
- *
360
- * @static
361
- * @param {Koatty} app
362
- * @param {*} target
363
- * @memberof Loader
364
- */
365
- static CheckAllComponents(app, target) {
366
- // component metadata
367
- const componentMetas = Loader.GetComponentMetas(app, target);
368
- // configuration metadata
369
- const configurationMetas = Loader.GetConfigurationMetas(app, target);
370
- const exSet = new Set();
371
- Load(componentMetas, '', (fileName, xpath, xTarget) => {
372
- checkClass(fileName, xpath, xTarget, exSet);
373
- }, ['**/**.js', '**/**.ts', '!**/**.d.ts'], [...configurationMetas, `${target.name || '.no'}.ts`]);
374
- exSet.clear();
375
- }
376
271
  /**
377
272
  * Get configuration metadata
378
273
  *
379
274
  * @static
380
- * @param {Koatty} app
275
+ * @param {KoattyApplication} app
381
276
  * @param {*} target
382
277
  * @returns {*} {any[]}
383
278
  * @memberof Loader
384
279
  */
385
- static GetConfigurationMetas(app, target) {
386
- const confMeta = IOCContainer.getClassMetadata(TAGGED_CLS, CONFIGURATION_SCAN, target);
280
+ static GetConfigurationMeta(app, target) {
281
+ const confMeta = IOC.getClassMetadata(TAGGED_CLS, CONFIGURATION_SCAN, target);
387
282
  let configurationMetas = [];
388
283
  if (confMeta) {
389
284
  if (Helper.isArray(confMeta)) {
@@ -395,11 +290,30 @@ class Loader {
395
290
  }
396
291
  return configurationMetas;
397
292
  }
293
+ /**
294
+ * Load all bean, excepted config/*、App.ts
295
+ *
296
+ * @static
297
+ * @param {KoattyApplication} app
298
+ * @param {*} target
299
+ * @memberof Loader
300
+ */
301
+ static CheckAllComponents(app, target) {
302
+ // component metadata
303
+ const componentMetas = Loader.GetComponentMeta(app, target);
304
+ // configuration metadata
305
+ const configurationMetas = Loader.GetConfigurationMeta(app, target);
306
+ const exSet = new Set();
307
+ Load(componentMetas, '', (fileName, xpath, xTarget) => {
308
+ checkClass(fileName, xpath, xTarget, exSet);
309
+ }, ['**/**.js', '**/**.ts', '!**/**.d.ts'], [...configurationMetas, `${target.name || '.no'}.ts`]);
310
+ exSet.clear();
311
+ }
398
312
  /**
399
313
  * Set Logger level
400
314
  *
401
315
  * @static
402
- * @param {Koatty} app
316
+ * @param {KoattyApplication} app
403
317
  * @memberof Loader
404
318
  */
405
319
  static SetLogger(app) {
@@ -428,7 +342,7 @@ class Loader {
428
342
  * Load app event hook funcs
429
343
  *
430
344
  * @static
431
- * @param {Koatty} app
345
+ * @param {KoattyApplication} app
432
346
  * @param {*} target
433
347
  * @memberof Loader
434
348
  */
@@ -438,25 +352,25 @@ class Loader {
438
352
  let funcs;
439
353
  switch (event) {
440
354
  case "appBoot" /* AppEvent.appBoot */:
441
- funcs = IOCContainer.getClassMetadata(TAGGED_CLS, "appBoot" /* AppEvent.appBoot */, target);
355
+ funcs = IOC.getClassMetadata(TAGGED_CLS, "appBoot" /* AppEvent.appBoot */, target);
442
356
  if (Helper.isArray(funcs)) {
443
357
  eventFuncs.set("appBoot" /* AppEvent.appBoot */, funcs);
444
358
  }
445
359
  break;
446
360
  case "appReady" /* AppEvent.appReady */:
447
- funcs = IOCContainer.getClassMetadata(TAGGED_CLS, "appReady" /* AppEvent.appReady */, target);
361
+ funcs = IOC.getClassMetadata(TAGGED_CLS, "appReady" /* AppEvent.appReady */, target);
448
362
  if (Helper.isArray(funcs)) {
449
363
  eventFuncs.set("appReady" /* AppEvent.appReady */, funcs);
450
364
  }
451
365
  break;
452
366
  case "appStart" /* AppEvent.appStart */:
453
- funcs = IOCContainer.getClassMetadata(TAGGED_CLS, "appStart" /* AppEvent.appStart */, target);
367
+ funcs = IOC.getClassMetadata(TAGGED_CLS, "appStart" /* AppEvent.appStart */, target);
454
368
  if (Helper.isArray(funcs)) {
455
369
  eventFuncs.set("appStart" /* AppEvent.appStart */, funcs);
456
370
  }
457
371
  break;
458
372
  case "appStop" /* AppEvent.appStop */:
459
- funcs = IOCContainer.getClassMetadata(TAGGED_CLS, "appStop" /* AppEvent.appStop */, target);
373
+ funcs = IOC.getClassMetadata(TAGGED_CLS, "appStop" /* AppEvent.appStop */, target);
460
374
  if (Helper.isArray(funcs)) {
461
375
  eventFuncs.set("appStop" /* AppEvent.appStop */, funcs);
462
376
  }
@@ -470,39 +384,70 @@ class Loader {
470
384
  }
471
385
  }
472
386
  }
387
+ /**
388
+ * LoadAllComponents
389
+ */
390
+ static async LoadAllComponents(app, target) {
391
+ var _a;
392
+ // Load configuration
393
+ Logger.Log('Koatty', '', 'Load Configurations ...');
394
+ // configuration metadata
395
+ const configurationMeta = Loader.GetConfigurationMeta(app, target);
396
+ const loader = new Loader(app);
397
+ loader.LoadConfigs(configurationMeta);
398
+ // Create Server
399
+ const serveOpts = {
400
+ hostname: app.config('app_host'),
401
+ port: app.config('app_port'),
402
+ protocol: app.config('protocol'),
403
+ };
404
+ Helper.define(app, "server", NewServe(app, serveOpts));
405
+ // Create router
406
+ const routerOpts = (_a = app.config(undefined, 'router')) !== null && _a !== void 0 ? _a : {};
407
+ Helper.define(app, "router", NewRouter(app, routerOpts));
408
+ // Load Components
409
+ Logger.Log('Koatty', '', 'Load Components ...');
410
+ await loader.LoadComponents();
411
+ // Load Middleware
412
+ Logger.Log('Koatty', '', 'Load Middlewares ...');
413
+ await loader.LoadMiddlewares();
414
+ // Load Services
415
+ Logger.Log('Koatty', '', 'Load Services ...');
416
+ await loader.LoadServices();
417
+ // Load Controllers
418
+ Logger.Log('Koatty', '', 'Load Controllers ...');
419
+ const controllers = await loader.LoadControllers();
420
+ // Load Routers
421
+ Logger.Log('Koatty', '', 'Load Routers ...');
422
+ loader.LoadRouter(controllers);
423
+ }
473
424
  /**
474
425
  * Load configuration
475
426
  *
476
- * @static
477
- * @param {Koatty} app
478
427
  * @param {string[]} [loadPath]
479
428
  * @memberof Loader
480
429
  */
481
- static LoadConfigs(app, loadPath) {
430
+ LoadConfigs(loadPath) {
482
431
  const frameConfig = {};
483
432
  // Logger.Debug(`Load configuration path: ${app.thinkPath}/config`);
484
- Load(["./config"], app.koattyPath, function (name, path, exp) {
433
+ Load(["./config"], this.app.koattyPath, function (name, path, exp) {
485
434
  frameConfig[name] = exp;
486
435
  });
487
436
  if (Helper.isArray(loadPath)) {
488
437
  loadPath = loadPath.length > 0 ? loadPath : ["./config"];
489
438
  }
490
- let appConfig = LoadConfigs(loadPath, app.appPath);
439
+ let appConfig = LoadConfigs(loadPath, this.app.appPath);
491
440
  appConfig = Helper.extend(frameConfig, appConfig, true);
492
- app.setMetaData("_configs", appConfig);
441
+ this.app.setMetaData("_configs", appConfig);
493
442
  }
494
443
  /**
495
444
  * Load middlewares
496
445
  * [async]
497
- * @static
498
- * @param {*} app
499
- * @param {(string | string[])} [loadPath]
500
446
  * @memberof Loader
501
447
  */
502
- static async LoadMiddlewares(app, loadPath) {
503
- // Error handling middleware
504
- await TraceHandler(app);
505
- let middlewareConf = app.config(undefined, "middleware");
448
+ async LoadMiddlewares() {
449
+ var _a;
450
+ let middlewareConf = this.app.config(undefined, "middleware");
506
451
  if (Helper.isEmpty(middlewareConf)) {
507
452
  middlewareConf = { config: {}, list: [] };
508
453
  }
@@ -510,12 +455,13 @@ class Loader {
510
455
  // Load(loadPath || ["./middleware"], app.koattyPath);
511
456
  //Mount application middleware
512
457
  // const middleware: any = {};
513
- const appMiddleware = IOCContainer.listClass("MIDDLEWARE") ?? [];
458
+ const appMiddleware = (_a = IOC.listClass("MIDDLEWARE")) !== null && _a !== void 0 ? _a : [];
514
459
  appMiddleware.forEach((item) => {
515
- item.id = (item.id ?? "").replace("MIDDLEWARE:", "");
460
+ var _a;
461
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("MIDDLEWARE:", "");
516
462
  if (item.id && Helper.isClass(item.target)) {
517
- IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
518
- const ctl = IOCContainer.getInsByClass(item.target);
463
+ IOC.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
464
+ const ctl = IOC.getInsByClass(item.target);
519
465
  if (!implementsMiddlewareInterface(ctl)) {
520
466
  throw Error(`The middleware ${item.id} must implements interface 'IMiddleware'.`);
521
467
  }
@@ -530,7 +476,7 @@ class Loader {
530
476
  //Automatically call middleware
531
477
  const middlewareConfig = middlewareConf.config || {};
532
478
  for (const key of appMList) {
533
- const handle = IOCContainer.get(key, "MIDDLEWARE");
479
+ const handle = IOC.get(key, "MIDDLEWARE");
534
480
  if (!handle) {
535
481
  throw Error(`Middleware ${key} load error.`);
536
482
  }
@@ -542,13 +488,13 @@ class Loader {
542
488
  continue;
543
489
  }
544
490
  Logger.Debug(`Load middleware: ${key}`);
545
- const result = await handle.run(middlewareConfig[key] || {}, app);
491
+ const result = await handle.run(middlewareConfig[key] || {}, this.app);
546
492
  if (Helper.isFunction(result)) {
547
493
  if (result.length < 3) {
548
- app.use(result);
494
+ this.app.use(result);
549
495
  }
550
496
  else {
551
- app.useExp(result);
497
+ this.app.useExp(result);
552
498
  }
553
499
  }
554
500
  }
@@ -556,20 +502,19 @@ class Loader {
556
502
  /**
557
503
  * Load controllers
558
504
  *
559
- * @static
560
- * @param {*} app
561
505
  * @memberof Loader
562
506
  */
563
- static LoadControllers(app) {
564
- const controllerList = IOCContainer.listClass("CONTROLLER");
507
+ async LoadControllers() {
508
+ const controllerList = IOC.listClass("CONTROLLER");
565
509
  const controllers = [];
566
510
  controllerList.forEach((item) => {
567
- item.id = (item.id ?? "").replace("CONTROLLER:", "");
511
+ var _a;
512
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("CONTROLLER:", "");
568
513
  if (item.id && Helper.isClass(item.target)) {
569
514
  Logger.Debug(`Load controller: ${item.id}`);
570
515
  // registering to IOC
571
- IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
572
- const ctl = IOCContainer.getInsByClass(item.target);
516
+ IOC.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
517
+ const ctl = IOC.getInsByClass(item.target);
573
518
  if (!implementsControllerInterface(ctl)) {
574
519
  throw Error(`The controller ${item.id} must implements interface 'IController'.`);
575
520
  }
@@ -581,19 +526,18 @@ class Loader {
581
526
  /**
582
527
  * Load services
583
528
  *
584
- * @static
585
- * @param {*} app
586
529
  * @memberof Loader
587
530
  */
588
- static LoadServices(app) {
589
- const serviceList = IOCContainer.listClass("SERVICE");
531
+ async LoadServices() {
532
+ const serviceList = IOC.listClass("SERVICE");
590
533
  serviceList.forEach((item) => {
591
- item.id = (item.id ?? "").replace("SERVICE:", "");
534
+ var _a;
535
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("SERVICE:", "");
592
536
  if (item.id && Helper.isClass(item.target)) {
593
537
  Logger.Debug(`Load service: ${item.id}`);
594
538
  // registering to IOC
595
- IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
596
- const ctl = IOCContainer.getInsByClass(item.target);
539
+ IOC.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
540
+ const ctl = IOC.getInsByClass(item.target);
597
541
  if (!implementsServiceInterface(ctl)) {
598
542
  throw Error(`The service ${item.id} must implements interface 'IService'.`);
599
543
  }
@@ -603,27 +547,27 @@ class Loader {
603
547
  /**
604
548
  * Load components
605
549
  *
606
- * @static
607
- * @param {*} app
608
550
  * @memberof Loader
609
551
  */
610
- static async LoadComponents(app) {
611
- const componentList = IOCContainer.listClass("COMPONENT");
552
+ async LoadComponents() {
553
+ var _a, _b;
554
+ const componentList = IOC.listClass("COMPONENT");
612
555
  const pluginList = [];
613
556
  componentList.forEach(async (item) => {
614
- item.id = (item.id ?? "").replace("COMPONENT:", "");
557
+ var _a;
558
+ item.id = ((_a = item.id) !== null && _a !== void 0 ? _a : "").replace("COMPONENT:", "");
615
559
  if (Helper.isClass(item.target)) {
616
560
  // registering to IOC
617
- IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
561
+ IOC.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
618
562
  if (item.id && (item.id).endsWith("Plugin")) {
619
- const ctl = IOCContainer.getInsByClass(item.target);
563
+ const ctl = IOC.getInsByClass(item.target);
620
564
  if (!implementsPluginInterface(ctl)) {
621
565
  throw Error(`The plugin ${item.id} must implements interface 'IPlugin'.`);
622
566
  }
623
567
  pluginList.push(item.id);
624
568
  }
625
569
  if (item.id && (item.id).endsWith("Aspect")) {
626
- const ctl = IOCContainer.getInsByClass(item.target);
570
+ const ctl = IOC.getInsByClass(item.target);
627
571
  if (!implementsAspectInterface(ctl)) {
628
572
  throw Error(`The aspect ${item.id} must implements interface 'IAspect'.`);
629
573
  }
@@ -631,14 +575,14 @@ class Loader {
631
575
  }
632
576
  });
633
577
  // load plugin config
634
- let pluginsConf = app.config(undefined, "plugin");
578
+ let pluginsConf = this.app.config(undefined, "plugin");
635
579
  if (Helper.isEmpty(pluginsConf)) {
636
580
  pluginsConf = { config: {}, list: [] };
637
581
  }
638
- const pluginConfList = pluginsConf.list ?? [];
582
+ const pluginConfList = (_a = pluginsConf.list) !== null && _a !== void 0 ? _a : [];
639
583
  // load plugin list
640
584
  for (const key of pluginConfList) {
641
- const handle = IOCContainer.get(key, "COMPONENT");
585
+ const handle = IOC.get(key, "COMPONENT");
642
586
  if (!handle) {
643
587
  throw Error(`Plugin ${key} load error.`);
644
588
  }
@@ -650,68 +594,110 @@ class Loader {
650
594
  continue;
651
595
  }
652
596
  // sync exec
653
- await handle.run(pluginsConf.config[key] ?? {}, app);
597
+ await handle.run((_b = pluginsConf.config[key]) !== null && _b !== void 0 ? _b : {}, this.app);
654
598
  }
655
599
  }
600
+ /**
601
+ * @description: load router
602
+ * @param {string} ctls
603
+ * @return {*}
604
+ */
605
+ async LoadRouter(ctls) {
606
+ // load router
607
+ await this.app.router.LoadRouter(this.app, ctls);
608
+ }
656
609
  }
657
610
 
658
- var version = "3.11.4-2";
659
- var engines = {
660
- node: ">12.0.0"
661
- };
662
-
663
611
  /*
664
- * @Description: framework runtime checker
612
+ * @Description: framework bootstrap
665
613
  * @Usage:
666
614
  * @Author: richen
667
- * @Date: 2023-12-09 21:56:32
668
- * @LastEditTime: 2023-12-09 23:01:22
615
+ * @Date: 2021-12-09 21:56:32
616
+ * @LastEditTime: 2024-11-29 18:13:06
669
617
  * @License: BSD (3-Clause)
670
618
  * @Copyright (c): <richenlin(at)gmail.com>
671
619
  */
672
- const KOATTY_VERSION = version;
673
- const ENGINES_VERSION = engines.node.slice(1) || '12.0.0';
674
620
  /**
675
- * check node version
676
- * @return {void} []
621
+ * Bootstrap application decorator
622
+ *
623
+ * @export
624
+ * @param {Function} [bootFunc]
625
+ * @returns {ClassDecorator}
677
626
  */
678
- function checkRuntime() {
679
- let nodeEngines = ENGINES_VERSION;
680
- nodeEngines = nodeEngines.slice(0, nodeEngines.lastIndexOf('.'));
681
- let nodeVersion = process.version;
682
- if (nodeVersion[0] === 'v') {
683
- nodeVersion = nodeVersion.slice(1);
684
- }
685
- nodeVersion = nodeVersion.slice(0, nodeVersion.lastIndexOf('.'));
686
- if (Helper.toNumber(nodeEngines) > Helper.toNumber(nodeVersion)) {
687
- Logger.Error(`Koatty need node version > ${nodeEngines}, current version is ${nodeVersion}, please upgrade it.`);
688
- process.exit(-1);
689
- }
627
+ function Bootstrap(bootFunc) {
628
+ return function (target) {
629
+ if (!(target.prototype instanceof Koatty)) {
630
+ throw new Error(`class does not inherit from Koatty`);
631
+ }
632
+ executeBootstrap(target, bootFunc);
633
+ };
690
634
  }
691
635
  /**
692
- * unittest running environment detection
693
- * only support jest
694
- * @returns {boolean}
636
+ * Actively perform dependency injection
637
+ * Parse the decorator, return the instantiated app.
638
+ * @export ExecBootStrap
639
+ * @param {Function} [bootFunc] callback function
640
+ * @returns
695
641
  */
696
- const checkUTRuntime = () => {
697
- let isUTRuntime = false;
698
- // UT运行环境判断,暂时先只判断jest
699
- const argv = JSON.stringify(process.argv[1]);
700
- if (argv.indexOf('jest') > -1) {
701
- isUTRuntime = true;
702
- }
703
- return isUTRuntime;
704
- };
705
-
706
- /*
707
- * @Description: framework bootstrap
708
- * @Usage:
709
- * @Author: richen
710
- * @Date: 2021-12-09 21:56:32
711
- * @LastEditTime: 2024-01-16 01:06:26
712
- * @License: BSD (3-Clause)
713
- * @Copyright (c): <richenlin(at)gmail.com>
642
+ function ExecBootStrap(bootFunc) {
643
+ return async (target) => {
644
+ if (!(target.prototype instanceof Koatty)) {
645
+ throw new Error(`class ${target.name} does not inherit from Koatty`);
646
+ }
647
+ return await executeBootstrap(target, bootFunc, true);
648
+ };
649
+ }
650
+ /**
651
+ * Define project scan path
652
+ *
653
+ * @export
654
+ * @param {(string | string[])} [scanPath]
655
+ * @returns {ClassDecorator}
656
+ */
657
+ function ComponentScan(scanPath) {
658
+ return (target) => {
659
+ if (!(target.prototype instanceof Koatty)) {
660
+ throw new Error(`class does not inherit from Koatty`);
661
+ }
662
+ scanPath = scanPath !== null && scanPath !== void 0 ? scanPath : '';
663
+ IOC.saveClassMetadata(TAGGED_CLS, COMPONENT_SCAN, scanPath, target);
664
+ };
665
+ }
666
+ /**
667
+ * Define project configuration scan path
668
+ *
669
+ * @export
670
+ * @param {(string | string[])} [scanPath]
671
+ * @returns {ClassDecorator}
672
+ */
673
+ function ConfigurationScan(scanPath) {
674
+ return (target) => {
675
+ if (!(target.prototype instanceof Koatty)) {
676
+ throw new Error(`class does not inherit from Koatty`);
677
+ }
678
+ scanPath = scanPath !== null && scanPath !== void 0 ? scanPath : '';
679
+ IOC.saveClassMetadata(TAGGED_CLS, CONFIGURATION_SCAN, scanPath, target);
680
+ };
681
+ }
682
+ /**
683
+ * @description: bind App event hook func
684
+ * example:
685
+ * export function TestDecorator(): ClassDecorator {
686
+ * return (target: Function) => {
687
+ * BindEventHook(AppEvent.appBoot, (app: KoattyApplication) => {
688
+ * // todo
689
+ * return Promise.resolve();
690
+ * }, target)
691
+ * }
692
+ * }
693
+ * @param {AppEvent} eventName
694
+ * @param {EventHookFunc} eventFunc
695
+ * @param {any} target
696
+ * @return {*}
714
697
  */
698
+ function BindEventHook(eventName, eventFunc, target) {
699
+ IOC.attachClassMetadata(TAGGED_CLS, eventName, eventFunc, target);
700
+ }
715
701
  /**
716
702
  * execute bootstrap
717
703
  *
@@ -736,7 +722,8 @@ const executeBootstrap = async function (target, bootFunc, isInitiative = false)
736
722
  Logger.enable(false);
737
723
  }
738
724
  try {
739
- !app.silent && Logger.Log("Koatty", LOGO);
725
+ if (!app.silent)
726
+ Logger.Log("Koatty", LOGO);
740
727
  if (!(app instanceof Koatty)) {
741
728
  throw new Error(`class ${target.name} does not inherit from Koatty`);
742
729
  }
@@ -747,44 +734,20 @@ const executeBootstrap = async function (target, bootFunc, isInitiative = false)
747
734
  Logger.Log('Koatty', '', 'Execute bootFunc ...');
748
735
  await bootFunc(app);
749
736
  }
750
- // Set IOCContainer.app
751
- IOCContainer.setApp(app);
752
- Logger.Log('Koatty', '', 'ComponentScan ...');
737
+ // Set IOC.app
738
+ IOC.setApp(app);
753
739
  // Check all bean
740
+ Logger.Log('Koatty', '', 'ComponentScan ...');
754
741
  Loader.CheckAllComponents(app, target);
755
- // Load configuration
756
- Logger.Log('Koatty', '', 'Load Configurations ...');
757
- // configuration metadata
758
- const configurationMetas = Loader.GetConfigurationMetas(app, target);
759
- Loader.LoadConfigs(app, configurationMetas);
760
742
  // Load App event hooks
761
743
  Loader.LoadAppEventHooks(app, target);
762
744
  Logger.Log('Koatty', '', 'Emit App Boot ...');
763
745
  await asyncEvent(app, "appBoot" /* AppEvent.appBoot */);
764
- // Create Server
765
- // app.server = newServe(app);
766
- Helper.define(app, "server", NewServe(app));
767
- // Create router
768
- // app.router = newRouter(app);
769
- Helper.define(app, "router", NewRouter(app));
770
- // Load Components
771
- Logger.Log('Koatty', '', 'Load Components ...');
772
- await Loader.LoadComponents(app);
773
- // Load Middleware
774
- Logger.Log('Koatty', '', 'Load Middlewares ...');
775
- await Loader.LoadMiddlewares(app);
776
- // Load Services
777
- Logger.Log('Koatty', '', 'Load Services ...');
778
- Loader.LoadServices(app);
779
- // Load Controllers
780
- Logger.Log('Koatty', '', 'Load Controllers ...');
781
- const controllers = Loader.LoadControllers(app);
746
+ // Load All components
747
+ await Loader.LoadAllComponents(app, target);
782
748
  // Emit app ready event
783
749
  Logger.Log('Koatty', '', 'Emit App Ready ...');
784
750
  await asyncEvent(app, "appReady" /* AppEvent.appReady */);
785
- // Load Routers
786
- Logger.Log('Koatty', '', 'Load Routers ...');
787
- app.router.LoadRouter(app, controllers);
788
751
  if (!isUTRuntime) {
789
752
  // Start Server
790
753
  app.listen(listenCallback);
@@ -803,19 +766,24 @@ const executeBootstrap = async function (target, bootFunc, isInitiative = false)
803
766
  * @returns {*}
804
767
  */
805
768
  const listenCallback = (app) => {
806
- const options = app.server.options;
769
+ let servers = [];
770
+ if (!Array.isArray(app.server)) {
771
+ servers = [app.server];
772
+ }
773
+ else {
774
+ servers = app.server;
775
+ }
807
776
  Logger.Log('Koatty', '', '====================================');
808
777
  Logger.Log("Koatty", "", `Nodejs Version: ${process.version}`);
809
778
  Logger.Log("Koatty", "", `Koatty Version: v${KOATTY_VERSION}`);
810
779
  Logger.Log("Koatty", "", `App Environment: ${app.env}`);
811
- Logger.Log('Koatty', '', `Server Protocol: ${(options.protocol).toUpperCase()}`);
812
- Logger.Log("Koatty", "", `Server running at ${options.protocol === "http2" ? "https" : options.protocol}://${options.hostname || '127.0.0.1'}:${options.port}/`);
780
+ servers.forEach(s => {
781
+ Logger.Log('Koatty', '', `Server: ${(s.options.protocol).toUpperCase()} running at ${s.options.protocol === "http2" ?
782
+ "https" : s.options.protocol}://${s.options.hostname || '127.0.0.1'}:${s.options.port}/`);
783
+ });
813
784
  Logger.Log("Koatty", "", "====================================");
814
- // binding event "appStop"
815
- Logger.Log('Koatty', '', 'Bind App Stop event ...');
816
- BindProcessEvent(app, 'appStop');
817
- // tslint:disable-next-line: no-unused-expression
818
- app.appDebug && Logger.Warn(`Running in debug mode.`);
785
+ if (app.appDebug)
786
+ Logger.Warn(`Running in debug mode.`);
819
787
  // Set Logger
820
788
  Loader.SetLogger(app);
821
789
  };
@@ -835,86 +803,5 @@ const asyncEvent = async function (event, eventName) {
835
803
  }
836
804
  return event.removeAllListeners(eventName);
837
805
  };
838
- /**
839
- * Bootstrap application
840
- *
841
- * @export
842
- * @param {Function} [bootFunc]
843
- * @returns {ClassDecorator}
844
- */
845
- function Bootstrap(bootFunc) {
846
- return function (target) {
847
- if (!(target.prototype instanceof Koatty)) {
848
- throw new Error(`class does not inherit from Koatty`);
849
- }
850
- executeBootstrap(target, bootFunc);
851
- };
852
- }
853
- /**
854
- * Actively perform dependency injection
855
- * Parse the decorator, return the instantiated app.
856
- * @export ExecBootStrap
857
- * @param {Function} [bootFunc] callback function
858
- * @returns
859
- */
860
- function ExecBootStrap(bootFunc) {
861
- return async (target) => {
862
- if (!(target.prototype instanceof Koatty)) {
863
- throw new Error(`class ${target.name} does not inherit from Koatty`);
864
- }
865
- return await executeBootstrap(target, bootFunc, true);
866
- };
867
- }
868
- /**
869
- * Define project scan path
870
- *
871
- * @export
872
- * @param {(string | string[])} [scanPath]
873
- * @returns {ClassDecorator}
874
- */
875
- function ComponentScan(scanPath) {
876
- return (target) => {
877
- if (!(target.prototype instanceof Koatty)) {
878
- throw new Error(`class does not inherit from Koatty`);
879
- }
880
- scanPath = scanPath ?? '';
881
- IOCContainer.saveClassMetadata(TAGGED_CLS, COMPONENT_SCAN, scanPath, target);
882
- };
883
- }
884
- /**
885
- * Define project configuration scan path
886
- *
887
- * @export
888
- * @param {(string | string[])} [scanPath]
889
- * @returns {ClassDecorator}
890
- */
891
- function ConfigurationScan(scanPath) {
892
- return (target) => {
893
- if (!(target.prototype instanceof Koatty)) {
894
- throw new Error(`class does not inherit from Koatty`);
895
- }
896
- scanPath = scanPath ?? '';
897
- IOCContainer.saveClassMetadata(TAGGED_CLS, CONFIGURATION_SCAN, scanPath, target);
898
- };
899
- }
900
- /**
901
- * @description: bind App event hook func
902
- * example:
903
- * export function TestDecorator(): ClassDecorator {
904
- * return (target: Function) => {
905
- * BindEventHook(AppEvent.appBoot, (app: Koatty) => {
906
- * // todo
907
- * return Promise.resolve();
908
- * }, target)
909
- * }
910
- * }
911
- * @param {AppEvent} eventName
912
- * @param {EventHookFunc} eventFunc
913
- * @param {any} target
914
- * @return {*}
915
- */
916
- function BindEventHook(eventName, eventFunc, target) {
917
- IOCContainer.attachClassMetadata(TAGGED_CLS, eventName, eventFunc, target);
918
- }
919
806
 
920
- export { BindEventHook, Bootstrap, Component, ComponentScan, ConfigurationScan, Controller, ExecBootStrap, Logger, Middleware, Plugin, Service, implementsAspectInterface, implementsControllerInterface, implementsMiddlewareInterface, implementsPluginInterface, implementsServiceInterface };
807
+ export { BindEventHook, Bootstrap, ComponentScan, ConfigurationScan, ExecBootStrap, Logger };