koatty 3.11.4-2 → 3.11.6

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