koatty 3.10.4-5 → 3.11.0

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/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [3.11.0](https://github.com/thinkkoa/koatty/compare/v3.10.4...v3.11.0) (2024-01-03)
6
+
7
+
8
+ ### Features
9
+
10
+ * 增加Output类 ([09e43c4](https://github.com/thinkkoa/koatty/commit/09e43c49e2e6bc6c9cb85cd03081bd5f25134c5b))
11
+
12
+ ### [3.10.4](https://github.com/thinkkoa/koatty/compare/v3.10.4-5...v3.10.4) (2023-12-24)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * 类型断言 ([16caed6](https://github.com/thinkkoa/koatty/commit/16caed67c1b66b444a3313441d0b65b9ded4186c))
18
+
5
19
  ### [3.10.4-5](https://github.com/thinkkoa/koatty/compare/v3.10.4-4...v3.10.4-5) (2023-12-23)
6
20
 
7
21
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-23 11:42:32
3
+ * @Date: 2024-01-03 23:02:24
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -37,6 +37,7 @@ export declare interface ApiOutput {
37
37
  * Base controller
38
38
  *
39
39
  * @export
40
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
40
41
  * @class BaseController
41
42
  * @implements {IController}
42
43
  */
@@ -58,6 +59,7 @@ export declare class BaseController implements IController {
58
59
  /**
59
60
  * Response to normalize json format content for success
60
61
  *
62
+ * @deprecated 使用 Output.ok 代替
61
63
  * @param {(string | ApiInput)} msg 待处理的message消息
62
64
  * @param {*} [data] 待处理的数据
63
65
  * @param {number} [code=200] 错误码,默认0
@@ -68,6 +70,7 @@ export declare class BaseController implements IController {
68
70
  /**
69
71
  * Response to normalize json format content for fail
70
72
  *
73
+ * @deprecated 使用 Output.fail 代替
71
74
  * @param {(string | ApiInput)} msg
72
75
  * @param {*} [data]
73
76
  * @param {number} [code=1]
@@ -81,6 +84,7 @@ export declare class BaseController implements IController {
81
84
  * Base service
82
85
  *
83
86
  * @export
87
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
84
88
  * @class Base
85
89
  */
86
90
  export declare class BaseService implements IService {
@@ -182,9 +186,6 @@ export { Helper }
182
186
  export declare interface IController {
183
187
  readonly app: Koatty;
184
188
  readonly ctx: KoattyContext;
185
- init(...arg: any[]): void;
186
- ok(msg: string | ApiInput, data?: any, code?: number): Promise<ApiOutput>;
187
- fail(msg: Error | string | ApiInput, data?: any, code?: number): void;
188
189
  }
189
190
 
190
191
  /**
@@ -194,6 +195,34 @@ export declare interface IMiddleware {
194
195
  run: (options: any, app: Koatty) => KoattyMiddleware;
195
196
  }
196
197
 
198
+ /**
199
+ * check is implements Controller Interface
200
+ * @param cls
201
+ * @returns
202
+ */
203
+ export declare function implementsControllerInterface(cls: any): cls is IController;
204
+
205
+ /**
206
+ * check is implements Middleware Interface
207
+ * @param cls
208
+ * @returns
209
+ */
210
+ export declare function implementsMiddlewareInterface(cls: any): cls is IMiddleware;
211
+
212
+ /**
213
+ * check is implements Plugin Interface
214
+ * @param cls
215
+ * @returns
216
+ */
217
+ export declare function implementsPluginInterface(cls: any): cls is IPlugin;
218
+
219
+ /**
220
+ * check is implements Service Interface
221
+ * @param cls
222
+ * @returns
223
+ */
224
+ export declare function implementsServiceInterface(cls: any): cls is IService;
225
+
197
226
  /**
198
227
  * Interface for Plugin
199
228
  */
@@ -226,6 +255,31 @@ export declare const Logger: Logger_2;
226
255
  */
227
256
  export declare function Middleware(identifier?: string): ClassDecorator;
228
257
 
258
+ export declare class Output {
259
+ /**
260
+ * Response to normalize json format content for success
261
+ *
262
+ * @param {KoattyContext} ctx
263
+ * @param {(string | ApiInput)} msg 待处理的message消息
264
+ * @param {*} [data] 待处理的数据
265
+ * @param {number} [code=200] 错误码,默认0
266
+ * @returns {*}
267
+ * @memberof BaseController
268
+ */
269
+ static ok(ctx: KoattyContext, msg: string | ApiInput, data?: any, code?: number): Promise<ApiOutput>;
270
+ /**
271
+ * Response to normalize json format content for fail
272
+ *
273
+ * @param {KoattyContext} ctx
274
+ * @param {(string | ApiInput)} msg
275
+ * @param {*} [data]
276
+ * @param {number} [code=1]
277
+ * @returns {*}
278
+ * @memberof BaseController
279
+ */
280
+ static fail(ctx: KoattyContext, msg: Error | string | ApiInput, data?: any, code?: number): void;
281
+ }
282
+
229
283
  /**
230
284
  * Indicates that an decorated class is a "plugin".
231
285
  *
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-23 11:42:17
3
+ * @Date: 2024-01-03 23:02:11
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -131,92 +131,6 @@ function formatApiData(msg, data, defaultCode) {
131
131
  return obj;
132
132
  }
133
133
 
134
- /*
135
- * @Description: base controller
136
- * @Usage:
137
- * @Author: richen
138
- * @Date: 2023-12-09 21:56:32
139
- * @LastEditTime: 2023-12-09 23:03:09
140
- * @License: BSD (3-Clause)
141
- * @Copyright (c): <richenlin(at)gmail.com>
142
- */
143
- /**
144
- * Base controller
145
- *
146
- * @export
147
- * @class BaseController
148
- * @implements {IController}
149
- */
150
- class BaseController {
151
- /**
152
- * instance of BaseController.
153
- * @param {Koatty} app
154
- * @param {KoattyContext} ctx
155
- * @memberof BaseController
156
- */
157
- constructor(ctx, ...arg) {
158
- this.ctx = ctx;
159
- this.init(arg);
160
- }
161
- /**
162
- * init
163
- *
164
- * @memberof BaseController
165
- */
166
- init(...arg) {
167
- }
168
- /**
169
- * Response to normalize json format content for success
170
- *
171
- * @param {(string | ApiInput)} msg 待处理的message消息
172
- * @param {*} [data] 待处理的数据
173
- * @param {number} [code=200] 错误码,默认0
174
- * @returns {*}
175
- * @memberof BaseController
176
- */
177
- ok(msg, data, code = 0) {
178
- const obj = formatApiData(msg, data, code);
179
- return Promise.resolve(obj);
180
- }
181
- /**
182
- * Response to normalize json format content for fail
183
- *
184
- * @param {(string | ApiInput)} msg
185
- * @param {*} [data]
186
- * @param {number} [code=1]
187
- * @returns {*}
188
- * @memberof BaseController
189
- */
190
- fail(msg, data, code = 1) {
191
- const obj = formatApiData(msg, data, code);
192
- this.ctx.body = obj.data;
193
- this.ctx.throw(obj.message, obj.code, 200);
194
- }
195
- }
196
- // const properties = ["constructor", "init"];
197
- // export const BaseController = new Proxy(Base, {
198
- // set(target, key, value, receiver) {
199
- // if (Reflect.get(target, key, receiver) === undefined) {
200
- // return Reflect.set(target, key, value, receiver);
201
- // } else if (key === "init") {
202
- // return Reflect.set(target, key, value, receiver);
203
- // } else {
204
- // throw Error("Cannot redefine getter-only property");
205
- // }
206
- // },
207
- // deleteProperty(target, key) {
208
- // throw Error("Cannot delete getter-only property");
209
- // },
210
- // construct(target, args, newTarget) {
211
- // Reflect.ownKeys(target.prototype).map((n) => {
212
- // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
213
- // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
214
- // }
215
- // });
216
- // return Reflect.construct(target, args, newTarget);
217
- // }
218
- // });
219
-
220
134
  /*
221
135
  * @Description: framework logger
222
136
  * @Usage:
@@ -252,6 +166,119 @@ function SetLogger(app, config) {
252
166
  }
253
167
  }
254
168
 
169
+ /*
170
+ * @Description: component interface
171
+ * @Usage:
172
+ * @Author: richen
173
+ * @Date: 2023-12-09 21:56:32
174
+ * @LastEditTime: 2024-01-03 21:27:20
175
+ * @License: BSD (3-Clause)
176
+ * @Copyright (c): <richenlin(at)gmail.com>
177
+ */
178
+ // tslint:disable-next-line: no-import-side-effect
179
+ /**
180
+ * Indicates that an decorated class is a "component".
181
+ *
182
+ * @export
183
+ * @param {string} [identifier] component name
184
+ * @returns {ClassDecorator}
185
+ */
186
+ function Component(identifier) {
187
+ return (target) => {
188
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
189
+ koatty_container.IOCContainer.saveClass("COMPONENT", target, identifier);
190
+ };
191
+ }
192
+ /**
193
+ * Indicates that an decorated class is a "controller".
194
+ *
195
+ * @export
196
+ * @param {string} [path] controller router path
197
+ * @returns {ClassDecorator}
198
+ */
199
+ function Controller(path = "") {
200
+ return (target) => {
201
+ const identifier = koatty_container.IOCContainer.getIdentifier(target);
202
+ koatty_container.IOCContainer.saveClass("CONTROLLER", target, identifier);
203
+ koatty_container.IOCContainer.savePropertyData(koatty_serve.CONTROLLER_ROUTER, path, target, identifier);
204
+ };
205
+ }
206
+ /**
207
+ * Indicates that an decorated class is a "middleware".
208
+ *
209
+ * @export
210
+ * @param {string} [identifier] class name
211
+ * @returns {ClassDecorator}
212
+ */
213
+ function Middleware(identifier) {
214
+ return (target) => {
215
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
216
+ koatty_container.IOCContainer.saveClass("MIDDLEWARE", target, identifier);
217
+ };
218
+ }
219
+ /**
220
+ * Indicates that an decorated class is a "service".
221
+ *
222
+ * @export
223
+ * @param {string} [identifier] class name
224
+ * @returns {ClassDecorator}
225
+ */
226
+ function Service(identifier) {
227
+ return (target) => {
228
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
229
+ koatty_container.IOCContainer.saveClass("SERVICE", target, identifier);
230
+ };
231
+ }
232
+ /**
233
+ * Indicates that an decorated class is a "plugin".
234
+ *
235
+ * @export
236
+ * @param {string} [identifier] class name
237
+ * @returns {ClassDecorator}
238
+ */
239
+ function Plugin(identifier) {
240
+ return (target) => {
241
+ identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
242
+ //
243
+ if (!identifier.endsWith("Plugin")) {
244
+ throw Error("Plugin class name must be 'Plugin' suffix.");
245
+ }
246
+ koatty_container.IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
247
+ };
248
+ }
249
+ /**
250
+ * check is implements Middleware Interface
251
+ * @param cls
252
+ * @returns
253
+ */
254
+ function implementsMiddlewareInterface(cls) {
255
+ return 'run' in cls && koatty_lib.Helper.isFunction(cls.run);
256
+ }
257
+ /**
258
+ * check is implements Controller Interface
259
+ * @param cls
260
+ * @returns
261
+ */
262
+ function implementsControllerInterface(cls) {
263
+ return 'app' in cls && 'ctx' in cls;
264
+ }
265
+ /**
266
+ * check is implements Service Interface
267
+ * @param cls
268
+ * @returns
269
+ */
270
+ function implementsServiceInterface(cls) {
271
+ return 'app' in cls;
272
+ }
273
+ /**
274
+ * check is implements Plugin Interface
275
+ * @param cls
276
+ * @returns
277
+ */
278
+ function implementsPluginInterface(cls) {
279
+ return 'run' in cls && koatty_lib.Helper.isFunction(cls.run);
280
+ }
281
+
255
282
  /*
256
283
  * @Description: framework constants
257
284
  * @Usage:
@@ -278,7 +305,7 @@ https://github.com/koatty
278
305
  * @Usage:
279
306
  * @Author: richen
280
307
  * @Date: 2023-12-09 22:55:49
281
- * @LastEditTime: 2023-12-22 07:31:21
308
+ * @LastEditTime: 2024-01-03 21:56:07
282
309
  * @License: BSD (3-Clause)
283
310
  * @Copyright (c): <richenlin(at)gmail.com>
284
311
  */
@@ -523,15 +550,20 @@ class Loader {
523
550
  item.id = (item.id ?? "").replace("MIDDLEWARE:", "");
524
551
  if (item.id && koatty_lib.Helper.isClass(item.target)) {
525
552
  koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
553
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
554
+ if (!implementsMiddlewareInterface(ctl)) {
555
+ throw Error(`The middleware ${item.id} must implements interface 'IMiddleware'.`);
556
+ }
526
557
  }
527
558
  });
528
- const middlewareConfList = middlewareConf.list;
559
+ const middlewareConfList = middlewareConf.list || [];
529
560
  //de-duplication
530
561
  const appMList = new Set([]);
531
562
  middlewareConfList.forEach((item) => {
532
563
  appMList.add(item);
533
564
  });
534
565
  //Automatically call middleware
566
+ const middlewareConfig = middlewareConf.config || {};
535
567
  for (const key of appMList) {
536
568
  const handle = koatty_container.IOCContainer.get(key, "MIDDLEWARE");
537
569
  if (!handle) {
@@ -540,12 +572,12 @@ class Loader {
540
572
  if (!koatty_lib.Helper.isFunction(handle.run)) {
541
573
  throw Error(`The middleware ${key} must implements interface 'IMiddleware'.`);
542
574
  }
543
- if (middlewareConf.config[key] === false) {
575
+ if (middlewareConfig[key] === false) {
544
576
  Logger.Warn(`The middleware ${key} has been loaded but not executed.`);
545
577
  continue;
546
578
  }
547
579
  Logger.Debug(`Load middleware: ${key}`);
548
- const result = await handle.run(middlewareConf.config[key] || {}, app);
580
+ const result = await handle.run(middlewareConfig[key] || {}, app);
549
581
  if (koatty_lib.Helper.isFunction(result)) {
550
582
  if (result.length < 3) {
551
583
  app.use(result);
@@ -573,8 +605,8 @@ class Loader {
573
605
  // registering to IOC
574
606
  koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
575
607
  const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
576
- if (!(ctl instanceof BaseController)) {
577
- throw Error(`Controller class ${item.id} does not inherit from BaseController`);
608
+ if (!implementsControllerInterface(ctl)) {
609
+ throw Error(`The controller ${item.id} must implements interface 'IController'.`);
578
610
  }
579
611
  controllers.push(item.id);
580
612
  }
@@ -596,6 +628,10 @@ class Loader {
596
628
  Logger.Debug(`Load service: ${item.id}`);
597
629
  // registering to IOC
598
630
  koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
631
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
632
+ if (!implementsServiceInterface(ctl)) {
633
+ throw Error(`The service ${item.id} must implements interface 'IService'.`);
634
+ }
599
635
  }
600
636
  });
601
637
  }
@@ -630,11 +666,15 @@ class Loader {
630
666
  componentList.forEach(async (item) => {
631
667
  item.id = (item.id ?? "").replace("COMPONENT:", "");
632
668
  if (koatty_lib.Helper.isClass(item.target)) {
669
+ // registering to IOC
670
+ koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
633
671
  if (item.id && (item.id).endsWith("Plugin")) {
672
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
673
+ if (!implementsPluginInterface(ctl)) {
674
+ throw Error(`The plugin ${item.id} must implements interface 'IPlugin'.`);
675
+ }
634
676
  pluginList.push(item.id);
635
677
  }
636
- // registering to IOC
637
- koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
638
678
  }
639
679
  });
640
680
  // load plugin config
@@ -662,7 +702,7 @@ class Loader {
662
702
  }
663
703
  }
664
704
 
665
- var version = "3.10.4-5";
705
+ var version = "3.11.0";
666
706
  var engines = {
667
707
  node: ">12.0.0"
668
708
  };
@@ -925,119 +965,169 @@ function BindEventHook(eventName, eventFunc, target) {
925
965
  }
926
966
 
927
967
  /*
928
- * @Description: component interface
968
+ * @Description: base service
929
969
  * @Usage:
930
970
  * @Author: richen
931
971
  * @Date: 2023-12-09 21:56:32
932
- * @LastEditTime: 2023-12-23 11:40:44
972
+ * @LastEditTime: 2024-01-03 21:57:26
933
973
  * @License: BSD (3-Clause)
934
974
  * @Copyright (c): <richenlin(at)gmail.com>
935
975
  */
936
- // tslint:disable-next-line: no-import-side-effect
937
- /**
938
- * Indicates that an decorated class is a "component".
939
- *
940
- * @export
941
- * @param {string} [identifier] component name
942
- * @returns {ClassDecorator}
943
- */
944
- function Component(identifier) {
945
- return (target) => {
946
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
947
- koatty_container.IOCContainer.saveClass("COMPONENT", target, identifier);
948
- };
949
- }
950
- /**
951
- * Indicates that an decorated class is a "controller".
952
- *
953
- * @export
954
- * @param {string} [path] controller router path
955
- * @returns {ClassDecorator}
956
- */
957
- function Controller(path = "") {
958
- return (target) => {
959
- const identifier = koatty_container.IOCContainer.getIdentifier(target);
960
- koatty_container.IOCContainer.saveClass("CONTROLLER", target, identifier);
961
- koatty_container.IOCContainer.savePropertyData(koatty_serve.CONTROLLER_ROUTER, path, target, identifier);
962
- };
963
- }
964
- /**
965
- * Indicates that an decorated class is a "middleware".
966
- *
967
- * @export
968
- * @param {string} [identifier] class name
969
- * @returns {ClassDecorator}
970
- */
971
- function Middleware(identifier) {
972
- return (target) => {
973
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
974
- koatty_container.IOCContainer.saveClass("MIDDLEWARE", target, identifier);
975
- };
976
- }
977
- /**
978
- * Indicates that an decorated class is a "service".
979
- *
980
- * @export
981
- * @param {string} [identifier] class name
982
- * @returns {ClassDecorator}
983
- */
984
- function Service(identifier) {
985
- return (target) => {
986
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
987
- koatty_container.IOCContainer.saveClass("SERVICE", target, identifier);
988
- };
989
- }
990
976
  /**
991
- * Indicates that an decorated class is a "plugin".
977
+ * Base service
992
978
  *
993
979
  * @export
994
- * @param {string} [identifier] class name
995
- * @returns {ClassDecorator}
980
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
981
+ * @class Base
996
982
  */
997
- function Plugin(identifier) {
998
- return (target) => {
999
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
1000
- //
1001
- if (!identifier.endsWith("Plugin")) {
1002
- throw Error("Plugin class name must be 'Plugin' suffix.");
1003
- }
1004
- koatty_container.IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
1005
- };
983
+ class BaseService {
984
+ /**
985
+ * instance of BaseController.
986
+ * @param {Koatty} app
987
+ * @param {KoattyContext} ctx
988
+ * @memberof BaseController
989
+ */
990
+ constructor(...arg) {
991
+ this.init(arg);
992
+ }
993
+ /**
994
+ * init
995
+ *
996
+ * @protected
997
+ * @memberof BaseController
998
+ */
999
+ init(...arg) {
1000
+ }
1006
1001
  }
1007
1002
 
1008
1003
  /*
1009
- * @Description: base service
1004
+ * @Description: base controller
1010
1005
  * @Usage:
1011
1006
  * @Author: richen
1012
1007
  * @Date: 2023-12-09 21:56:32
1013
- * @LastEditTime: 2023-12-09 23:03:23
1008
+ * @LastEditTime: 2024-01-03 21:57:20
1014
1009
  * @License: BSD (3-Clause)
1015
1010
  * @Copyright (c): <richenlin(at)gmail.com>
1016
1011
  */
1017
1012
  /**
1018
- * Base service
1013
+ * Base controller
1019
1014
  *
1020
1015
  * @export
1021
- * @class Base
1016
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
1017
+ * @class BaseController
1018
+ * @implements {IController}
1022
1019
  */
1023
- class BaseService {
1020
+ class BaseController {
1024
1021
  /**
1025
1022
  * instance of BaseController.
1026
1023
  * @param {Koatty} app
1027
1024
  * @param {KoattyContext} ctx
1028
1025
  * @memberof BaseController
1029
1026
  */
1030
- constructor(...arg) {
1027
+ constructor(ctx, ...arg) {
1028
+ this.ctx = ctx;
1031
1029
  this.init(arg);
1032
1030
  }
1033
1031
  /**
1034
1032
  * init
1035
1033
  *
1036
- * @protected
1037
1034
  * @memberof BaseController
1038
1035
  */
1039
1036
  init(...arg) {
1040
1037
  }
1038
+ /**
1039
+ * Response to normalize json format content for success
1040
+ *
1041
+ * @deprecated 使用 Output.ok 代替
1042
+ * @param {(string | ApiInput)} msg 待处理的message消息
1043
+ * @param {*} [data] 待处理的数据
1044
+ * @param {number} [code=200] 错误码,默认0
1045
+ * @returns {*}
1046
+ * @memberof BaseController
1047
+ */
1048
+ ok(msg, data, code = 0) {
1049
+ const obj = formatApiData(msg, data, code);
1050
+ return Promise.resolve(obj);
1051
+ }
1052
+ /**
1053
+ * Response to normalize json format content for fail
1054
+ *
1055
+ * @deprecated 使用 Output.fail 代替
1056
+ * @param {(string | ApiInput)} msg
1057
+ * @param {*} [data]
1058
+ * @param {number} [code=1]
1059
+ * @returns {*}
1060
+ * @memberof BaseController
1061
+ */
1062
+ fail(msg, data, code = 1) {
1063
+ const obj = formatApiData(msg, data, code);
1064
+ this.ctx.body = obj.data;
1065
+ this.ctx.throw(obj.message, obj.code, 200);
1066
+ }
1067
+ }
1068
+ // const properties = ["constructor", "init"];
1069
+ // export const BaseController = new Proxy(Base, {
1070
+ // set(target, key, value, receiver) {
1071
+ // if (Reflect.get(target, key, receiver) === undefined) {
1072
+ // return Reflect.set(target, key, value, receiver);
1073
+ // } else if (key === "init") {
1074
+ // return Reflect.set(target, key, value, receiver);
1075
+ // } else {
1076
+ // throw Error("Cannot redefine getter-only property");
1077
+ // }
1078
+ // },
1079
+ // deleteProperty(target, key) {
1080
+ // throw Error("Cannot delete getter-only property");
1081
+ // },
1082
+ // construct(target, args, newTarget) {
1083
+ // Reflect.ownKeys(target.prototype).map((n) => {
1084
+ // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
1085
+ // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
1086
+ // }
1087
+ // });
1088
+ // return Reflect.construct(target, args, newTarget);
1089
+ // }
1090
+ // });
1091
+
1092
+ /*
1093
+ * @Description: output data
1094
+ * @Usage:
1095
+ * @Author: richen
1096
+ * @Date: 2024-01-03 22:03:34
1097
+ * @LastEditTime: 2024-01-03 22:07:20
1098
+ * @License: BSD (3-Clause)
1099
+ * @Copyright (c): <richenlin(at)gmail.com>
1100
+ */
1101
+ class Output {
1102
+ /**
1103
+ * Response to normalize json format content for success
1104
+ *
1105
+ * @param {KoattyContext} ctx
1106
+ * @param {(string | ApiInput)} msg 待处理的message消息
1107
+ * @param {*} [data] 待处理的数据
1108
+ * @param {number} [code=200] 错误码,默认0
1109
+ * @returns {*}
1110
+ * @memberof BaseController
1111
+ */
1112
+ static ok(ctx, msg, data, code = 0) {
1113
+ const obj = formatApiData(msg, data, code);
1114
+ return Promise.resolve(obj);
1115
+ }
1116
+ /**
1117
+ * Response to normalize json format content for fail
1118
+ *
1119
+ * @param {KoattyContext} ctx
1120
+ * @param {(string | ApiInput)} msg
1121
+ * @param {*} [data]
1122
+ * @param {number} [code=1]
1123
+ * @returns {*}
1124
+ * @memberof BaseController
1125
+ */
1126
+ static fail(ctx, msg, data, code = 1) {
1127
+ const obj = formatApiData(msg, data, code);
1128
+ ctx.body = obj.data;
1129
+ ctx.throw(obj.message, obj.code, 200);
1130
+ }
1041
1131
  }
1042
1132
 
1043
1133
  Object.defineProperty(exports, 'Config', {
@@ -1063,8 +1153,13 @@ exports.Controller = Controller;
1063
1153
  exports.ExecBootStrap = ExecBootStrap;
1064
1154
  exports.Logger = Logger;
1065
1155
  exports.Middleware = Middleware;
1156
+ exports.Output = Output;
1066
1157
  exports.Plugin = Plugin;
1067
1158
  exports.Service = Service;
1159
+ exports.implementsControllerInterface = implementsControllerInterface;
1160
+ exports.implementsMiddlewareInterface = implementsMiddlewareInterface;
1161
+ exports.implementsPluginInterface = implementsPluginInterface;
1162
+ exports.implementsServiceInterface = implementsServiceInterface;
1068
1163
  Object.keys(koatty_container).forEach(function (k) {
1069
1164
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1070
1165
  enumerable: true,
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-23 11:42:17
3
+ * @Date: 2024-01-03 23:02:11
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -9,7 +9,7 @@ import { IOCContainer, TAGGED_CLS } from 'koatty_container';
9
9
  export * from 'koatty_container';
10
10
  import { AppEventArr, Koatty } from 'koatty_core';
11
11
  export * from 'koatty_core';
12
- import { NewServe, NewRouter, BindProcessEvent, CONTROLLER_ROUTER } from 'koatty_serve';
12
+ import { CONTROLLER_ROUTER, NewServe, NewRouter, BindProcessEvent } from 'koatty_serve';
13
13
  export * from 'koatty_serve';
14
14
  import * as path from 'path';
15
15
  import { Load } from 'koatty_loader';
@@ -116,92 +116,6 @@ function formatApiData(msg, data, defaultCode) {
116
116
  return obj;
117
117
  }
118
118
 
119
- /*
120
- * @Description: base controller
121
- * @Usage:
122
- * @Author: richen
123
- * @Date: 2023-12-09 21:56:32
124
- * @LastEditTime: 2023-12-09 23:03:09
125
- * @License: BSD (3-Clause)
126
- * @Copyright (c): <richenlin(at)gmail.com>
127
- */
128
- /**
129
- * Base controller
130
- *
131
- * @export
132
- * @class BaseController
133
- * @implements {IController}
134
- */
135
- class BaseController {
136
- /**
137
- * instance of BaseController.
138
- * @param {Koatty} app
139
- * @param {KoattyContext} ctx
140
- * @memberof BaseController
141
- */
142
- constructor(ctx, ...arg) {
143
- this.ctx = ctx;
144
- this.init(arg);
145
- }
146
- /**
147
- * init
148
- *
149
- * @memberof BaseController
150
- */
151
- init(...arg) {
152
- }
153
- /**
154
- * Response to normalize json format content for success
155
- *
156
- * @param {(string | ApiInput)} msg 待处理的message消息
157
- * @param {*} [data] 待处理的数据
158
- * @param {number} [code=200] 错误码,默认0
159
- * @returns {*}
160
- * @memberof BaseController
161
- */
162
- ok(msg, data, code = 0) {
163
- const obj = formatApiData(msg, data, code);
164
- return Promise.resolve(obj);
165
- }
166
- /**
167
- * Response to normalize json format content for fail
168
- *
169
- * @param {(string | ApiInput)} msg
170
- * @param {*} [data]
171
- * @param {number} [code=1]
172
- * @returns {*}
173
- * @memberof BaseController
174
- */
175
- fail(msg, data, code = 1) {
176
- const obj = formatApiData(msg, data, code);
177
- this.ctx.body = obj.data;
178
- this.ctx.throw(obj.message, obj.code, 200);
179
- }
180
- }
181
- // const properties = ["constructor", "init"];
182
- // export const BaseController = new Proxy(Base, {
183
- // set(target, key, value, receiver) {
184
- // if (Reflect.get(target, key, receiver) === undefined) {
185
- // return Reflect.set(target, key, value, receiver);
186
- // } else if (key === "init") {
187
- // return Reflect.set(target, key, value, receiver);
188
- // } else {
189
- // throw Error("Cannot redefine getter-only property");
190
- // }
191
- // },
192
- // deleteProperty(target, key) {
193
- // throw Error("Cannot delete getter-only property");
194
- // },
195
- // construct(target, args, newTarget) {
196
- // Reflect.ownKeys(target.prototype).map((n) => {
197
- // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
198
- // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
199
- // }
200
- // });
201
- // return Reflect.construct(target, args, newTarget);
202
- // }
203
- // });
204
-
205
119
  /*
206
120
  * @Description: framework logger
207
121
  * @Usage:
@@ -237,6 +151,119 @@ function SetLogger(app, config) {
237
151
  }
238
152
  }
239
153
 
154
+ /*
155
+ * @Description: component interface
156
+ * @Usage:
157
+ * @Author: richen
158
+ * @Date: 2023-12-09 21:56:32
159
+ * @LastEditTime: 2024-01-03 21:27:20
160
+ * @License: BSD (3-Clause)
161
+ * @Copyright (c): <richenlin(at)gmail.com>
162
+ */
163
+ // tslint:disable-next-line: no-import-side-effect
164
+ /**
165
+ * Indicates that an decorated class is a "component".
166
+ *
167
+ * @export
168
+ * @param {string} [identifier] component name
169
+ * @returns {ClassDecorator}
170
+ */
171
+ function Component(identifier) {
172
+ return (target) => {
173
+ identifier = identifier || IOCContainer.getIdentifier(target);
174
+ IOCContainer.saveClass("COMPONENT", target, identifier);
175
+ };
176
+ }
177
+ /**
178
+ * Indicates that an decorated class is a "controller".
179
+ *
180
+ * @export
181
+ * @param {string} [path] controller router path
182
+ * @returns {ClassDecorator}
183
+ */
184
+ function Controller(path = "") {
185
+ return (target) => {
186
+ const identifier = IOCContainer.getIdentifier(target);
187
+ IOCContainer.saveClass("CONTROLLER", target, identifier);
188
+ IOCContainer.savePropertyData(CONTROLLER_ROUTER, path, target, identifier);
189
+ };
190
+ }
191
+ /**
192
+ * Indicates that an decorated class is a "middleware".
193
+ *
194
+ * @export
195
+ * @param {string} [identifier] class name
196
+ * @returns {ClassDecorator}
197
+ */
198
+ function Middleware(identifier) {
199
+ return (target) => {
200
+ identifier = identifier || IOCContainer.getIdentifier(target);
201
+ IOCContainer.saveClass("MIDDLEWARE", target, identifier);
202
+ };
203
+ }
204
+ /**
205
+ * Indicates that an decorated class is a "service".
206
+ *
207
+ * @export
208
+ * @param {string} [identifier] class name
209
+ * @returns {ClassDecorator}
210
+ */
211
+ function Service(identifier) {
212
+ return (target) => {
213
+ identifier = identifier || IOCContainer.getIdentifier(target);
214
+ IOCContainer.saveClass("SERVICE", target, identifier);
215
+ };
216
+ }
217
+ /**
218
+ * Indicates that an decorated class is a "plugin".
219
+ *
220
+ * @export
221
+ * @param {string} [identifier] class name
222
+ * @returns {ClassDecorator}
223
+ */
224
+ function Plugin(identifier) {
225
+ return (target) => {
226
+ identifier = identifier || IOCContainer.getIdentifier(target);
227
+ //
228
+ if (!identifier.endsWith("Plugin")) {
229
+ throw Error("Plugin class name must be 'Plugin' suffix.");
230
+ }
231
+ IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
232
+ };
233
+ }
234
+ /**
235
+ * check is implements Middleware Interface
236
+ * @param cls
237
+ * @returns
238
+ */
239
+ function implementsMiddlewareInterface(cls) {
240
+ return 'run' in cls && Helper.isFunction(cls.run);
241
+ }
242
+ /**
243
+ * check is implements Controller Interface
244
+ * @param cls
245
+ * @returns
246
+ */
247
+ function implementsControllerInterface(cls) {
248
+ return 'app' in cls && 'ctx' in cls;
249
+ }
250
+ /**
251
+ * check is implements Service Interface
252
+ * @param cls
253
+ * @returns
254
+ */
255
+ function implementsServiceInterface(cls) {
256
+ return 'app' in cls;
257
+ }
258
+ /**
259
+ * check is implements Plugin Interface
260
+ * @param cls
261
+ * @returns
262
+ */
263
+ function implementsPluginInterface(cls) {
264
+ return 'run' in cls && Helper.isFunction(cls.run);
265
+ }
266
+
240
267
  /*
241
268
  * @Description: framework constants
242
269
  * @Usage:
@@ -263,7 +290,7 @@ https://github.com/koatty
263
290
  * @Usage:
264
291
  * @Author: richen
265
292
  * @Date: 2023-12-09 22:55:49
266
- * @LastEditTime: 2023-12-22 07:31:21
293
+ * @LastEditTime: 2024-01-03 21:56:07
267
294
  * @License: BSD (3-Clause)
268
295
  * @Copyright (c): <richenlin(at)gmail.com>
269
296
  */
@@ -508,15 +535,20 @@ class Loader {
508
535
  item.id = (item.id ?? "").replace("MIDDLEWARE:", "");
509
536
  if (item.id && Helper.isClass(item.target)) {
510
537
  IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
538
+ const ctl = IOCContainer.getInsByClass(item.target);
539
+ if (!implementsMiddlewareInterface(ctl)) {
540
+ throw Error(`The middleware ${item.id} must implements interface 'IMiddleware'.`);
541
+ }
511
542
  }
512
543
  });
513
- const middlewareConfList = middlewareConf.list;
544
+ const middlewareConfList = middlewareConf.list || [];
514
545
  //de-duplication
515
546
  const appMList = new Set([]);
516
547
  middlewareConfList.forEach((item) => {
517
548
  appMList.add(item);
518
549
  });
519
550
  //Automatically call middleware
551
+ const middlewareConfig = middlewareConf.config || {};
520
552
  for (const key of appMList) {
521
553
  const handle = IOCContainer.get(key, "MIDDLEWARE");
522
554
  if (!handle) {
@@ -525,12 +557,12 @@ class Loader {
525
557
  if (!Helper.isFunction(handle.run)) {
526
558
  throw Error(`The middleware ${key} must implements interface 'IMiddleware'.`);
527
559
  }
528
- if (middlewareConf.config[key] === false) {
560
+ if (middlewareConfig[key] === false) {
529
561
  Logger.Warn(`The middleware ${key} has been loaded but not executed.`);
530
562
  continue;
531
563
  }
532
564
  Logger.Debug(`Load middleware: ${key}`);
533
- const result = await handle.run(middlewareConf.config[key] || {}, app);
565
+ const result = await handle.run(middlewareConfig[key] || {}, app);
534
566
  if (Helper.isFunction(result)) {
535
567
  if (result.length < 3) {
536
568
  app.use(result);
@@ -558,8 +590,8 @@ class Loader {
558
590
  // registering to IOC
559
591
  IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
560
592
  const ctl = IOCContainer.getInsByClass(item.target);
561
- if (!(ctl instanceof BaseController)) {
562
- throw Error(`Controller class ${item.id} does not inherit from BaseController`);
593
+ if (!implementsControllerInterface(ctl)) {
594
+ throw Error(`The controller ${item.id} must implements interface 'IController'.`);
563
595
  }
564
596
  controllers.push(item.id);
565
597
  }
@@ -581,6 +613,10 @@ class Loader {
581
613
  Logger.Debug(`Load service: ${item.id}`);
582
614
  // registering to IOC
583
615
  IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
616
+ const ctl = IOCContainer.getInsByClass(item.target);
617
+ if (!implementsServiceInterface(ctl)) {
618
+ throw Error(`The service ${item.id} must implements interface 'IService'.`);
619
+ }
584
620
  }
585
621
  });
586
622
  }
@@ -615,11 +651,15 @@ class Loader {
615
651
  componentList.forEach(async (item) => {
616
652
  item.id = (item.id ?? "").replace("COMPONENT:", "");
617
653
  if (Helper.isClass(item.target)) {
654
+ // registering to IOC
655
+ IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
618
656
  if (item.id && (item.id).endsWith("Plugin")) {
657
+ const ctl = IOCContainer.getInsByClass(item.target);
658
+ if (!implementsPluginInterface(ctl)) {
659
+ throw Error(`The plugin ${item.id} must implements interface 'IPlugin'.`);
660
+ }
619
661
  pluginList.push(item.id);
620
662
  }
621
- // registering to IOC
622
- IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
623
663
  }
624
664
  });
625
665
  // load plugin config
@@ -647,7 +687,7 @@ class Loader {
647
687
  }
648
688
  }
649
689
 
650
- var version = "3.10.4-5";
690
+ var version = "3.11.0";
651
691
  var engines = {
652
692
  node: ">12.0.0"
653
693
  };
@@ -910,119 +950,169 @@ function BindEventHook(eventName, eventFunc, target) {
910
950
  }
911
951
 
912
952
  /*
913
- * @Description: component interface
953
+ * @Description: base service
914
954
  * @Usage:
915
955
  * @Author: richen
916
956
  * @Date: 2023-12-09 21:56:32
917
- * @LastEditTime: 2023-12-23 11:40:44
957
+ * @LastEditTime: 2024-01-03 21:57:26
918
958
  * @License: BSD (3-Clause)
919
959
  * @Copyright (c): <richenlin(at)gmail.com>
920
960
  */
921
- // tslint:disable-next-line: no-import-side-effect
922
- /**
923
- * Indicates that an decorated class is a "component".
924
- *
925
- * @export
926
- * @param {string} [identifier] component name
927
- * @returns {ClassDecorator}
928
- */
929
- function Component(identifier) {
930
- return (target) => {
931
- identifier = identifier || IOCContainer.getIdentifier(target);
932
- IOCContainer.saveClass("COMPONENT", target, identifier);
933
- };
934
- }
935
- /**
936
- * Indicates that an decorated class is a "controller".
937
- *
938
- * @export
939
- * @param {string} [path] controller router path
940
- * @returns {ClassDecorator}
941
- */
942
- function Controller(path = "") {
943
- return (target) => {
944
- const identifier = IOCContainer.getIdentifier(target);
945
- IOCContainer.saveClass("CONTROLLER", target, identifier);
946
- IOCContainer.savePropertyData(CONTROLLER_ROUTER, path, target, identifier);
947
- };
948
- }
949
- /**
950
- * Indicates that an decorated class is a "middleware".
951
- *
952
- * @export
953
- * @param {string} [identifier] class name
954
- * @returns {ClassDecorator}
955
- */
956
- function Middleware(identifier) {
957
- return (target) => {
958
- identifier = identifier || IOCContainer.getIdentifier(target);
959
- IOCContainer.saveClass("MIDDLEWARE", target, identifier);
960
- };
961
- }
962
- /**
963
- * Indicates that an decorated class is a "service".
964
- *
965
- * @export
966
- * @param {string} [identifier] class name
967
- * @returns {ClassDecorator}
968
- */
969
- function Service(identifier) {
970
- return (target) => {
971
- identifier = identifier || IOCContainer.getIdentifier(target);
972
- IOCContainer.saveClass("SERVICE", target, identifier);
973
- };
974
- }
975
961
  /**
976
- * Indicates that an decorated class is a "plugin".
962
+ * Base service
977
963
  *
978
964
  * @export
979
- * @param {string} [identifier] class name
980
- * @returns {ClassDecorator}
965
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
966
+ * @class Base
981
967
  */
982
- function Plugin(identifier) {
983
- return (target) => {
984
- identifier = identifier || IOCContainer.getIdentifier(target);
985
- //
986
- if (!identifier.endsWith("Plugin")) {
987
- throw Error("Plugin class name must be 'Plugin' suffix.");
988
- }
989
- IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
990
- };
968
+ class BaseService {
969
+ /**
970
+ * instance of BaseController.
971
+ * @param {Koatty} app
972
+ * @param {KoattyContext} ctx
973
+ * @memberof BaseController
974
+ */
975
+ constructor(...arg) {
976
+ this.init(arg);
977
+ }
978
+ /**
979
+ * init
980
+ *
981
+ * @protected
982
+ * @memberof BaseController
983
+ */
984
+ init(...arg) {
985
+ }
991
986
  }
992
987
 
993
988
  /*
994
- * @Description: base service
989
+ * @Description: base controller
995
990
  * @Usage:
996
991
  * @Author: richen
997
992
  * @Date: 2023-12-09 21:56:32
998
- * @LastEditTime: 2023-12-09 23:03:23
993
+ * @LastEditTime: 2024-01-03 21:57:20
999
994
  * @License: BSD (3-Clause)
1000
995
  * @Copyright (c): <richenlin(at)gmail.com>
1001
996
  */
1002
997
  /**
1003
- * Base service
998
+ * Base controller
1004
999
  *
1005
1000
  * @export
1006
- * @class Base
1001
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
1002
+ * @class BaseController
1003
+ * @implements {IController}
1007
1004
  */
1008
- class BaseService {
1005
+ class BaseController {
1009
1006
  /**
1010
1007
  * instance of BaseController.
1011
1008
  * @param {Koatty} app
1012
1009
  * @param {KoattyContext} ctx
1013
1010
  * @memberof BaseController
1014
1011
  */
1015
- constructor(...arg) {
1012
+ constructor(ctx, ...arg) {
1013
+ this.ctx = ctx;
1016
1014
  this.init(arg);
1017
1015
  }
1018
1016
  /**
1019
1017
  * init
1020
1018
  *
1021
- * @protected
1022
1019
  * @memberof BaseController
1023
1020
  */
1024
1021
  init(...arg) {
1025
1022
  }
1023
+ /**
1024
+ * Response to normalize json format content for success
1025
+ *
1026
+ * @deprecated 使用 Output.ok 代替
1027
+ * @param {(string | ApiInput)} msg 待处理的message消息
1028
+ * @param {*} [data] 待处理的数据
1029
+ * @param {number} [code=200] 错误码,默认0
1030
+ * @returns {*}
1031
+ * @memberof BaseController
1032
+ */
1033
+ ok(msg, data, code = 0) {
1034
+ const obj = formatApiData(msg, data, code);
1035
+ return Promise.resolve(obj);
1036
+ }
1037
+ /**
1038
+ * Response to normalize json format content for fail
1039
+ *
1040
+ * @deprecated 使用 Output.fail 代替
1041
+ * @param {(string | ApiInput)} msg
1042
+ * @param {*} [data]
1043
+ * @param {number} [code=1]
1044
+ * @returns {*}
1045
+ * @memberof BaseController
1046
+ */
1047
+ fail(msg, data, code = 1) {
1048
+ const obj = formatApiData(msg, data, code);
1049
+ this.ctx.body = obj.data;
1050
+ this.ctx.throw(obj.message, obj.code, 200);
1051
+ }
1052
+ }
1053
+ // const properties = ["constructor", "init"];
1054
+ // export const BaseController = new Proxy(Base, {
1055
+ // set(target, key, value, receiver) {
1056
+ // if (Reflect.get(target, key, receiver) === undefined) {
1057
+ // return Reflect.set(target, key, value, receiver);
1058
+ // } else if (key === "init") {
1059
+ // return Reflect.set(target, key, value, receiver);
1060
+ // } else {
1061
+ // throw Error("Cannot redefine getter-only property");
1062
+ // }
1063
+ // },
1064
+ // deleteProperty(target, key) {
1065
+ // throw Error("Cannot delete getter-only property");
1066
+ // },
1067
+ // construct(target, args, newTarget) {
1068
+ // Reflect.ownKeys(target.prototype).map((n) => {
1069
+ // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
1070
+ // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
1071
+ // }
1072
+ // });
1073
+ // return Reflect.construct(target, args, newTarget);
1074
+ // }
1075
+ // });
1076
+
1077
+ /*
1078
+ * @Description: output data
1079
+ * @Usage:
1080
+ * @Author: richen
1081
+ * @Date: 2024-01-03 22:03:34
1082
+ * @LastEditTime: 2024-01-03 22:07:20
1083
+ * @License: BSD (3-Clause)
1084
+ * @Copyright (c): <richenlin(at)gmail.com>
1085
+ */
1086
+ class Output {
1087
+ /**
1088
+ * Response to normalize json format content for success
1089
+ *
1090
+ * @param {KoattyContext} ctx
1091
+ * @param {(string | ApiInput)} msg 待处理的message消息
1092
+ * @param {*} [data] 待处理的数据
1093
+ * @param {number} [code=200] 错误码,默认0
1094
+ * @returns {*}
1095
+ * @memberof BaseController
1096
+ */
1097
+ static ok(ctx, msg, data, code = 0) {
1098
+ const obj = formatApiData(msg, data, code);
1099
+ return Promise.resolve(obj);
1100
+ }
1101
+ /**
1102
+ * Response to normalize json format content for fail
1103
+ *
1104
+ * @param {KoattyContext} ctx
1105
+ * @param {(string | ApiInput)} msg
1106
+ * @param {*} [data]
1107
+ * @param {number} [code=1]
1108
+ * @returns {*}
1109
+ * @memberof BaseController
1110
+ */
1111
+ static fail(ctx, msg, data, code = 1) {
1112
+ const obj = formatApiData(msg, data, code);
1113
+ ctx.body = obj.data;
1114
+ ctx.throw(obj.message, obj.code, 200);
1115
+ }
1026
1116
  }
1027
1117
 
1028
- export { BaseController, BaseService, BindEventHook, Bootstrap, Component, ComponentScan, ConfigurationScan, Controller, ExecBootStrap, Logger, Middleware, Plugin, Service };
1118
+ export { BaseController, BaseService, BindEventHook, Bootstrap, Component, ComponentScan, ConfigurationScan, Controller, ExecBootStrap, Logger, Middleware, Output, Plugin, Service, implementsControllerInterface, implementsMiddlewareInterface, implementsPluginInterface, implementsServiceInterface };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koatty",
3
- "version": "3.10.4-5",
3
+ "version": "3.11.0",
4
4
  "description": "Koa2 + Typescript = koatty. Use Typescript's decorator implement auto injection.",
5
5
  "scripts": {
6
6
  "build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
@@ -82,7 +82,7 @@
82
82
  "typescript": "^5.x.x"
83
83
  },
84
84
  "dependencies": {
85
- "koa": "^2.14.2",
85
+ "koa": "^2.15.0",
86
86
  "koatty_config": "^1.1.6",
87
87
  "koatty_container": "^1.8.10",
88
88
  "koatty_core": "^1.8.4",
@@ -93,6 +93,6 @@
93
93
  "koatty_proto": "^1.1.12",
94
94
  "koatty_serve": "2.1.0",
95
95
  "koatty_trace": "^1.10.4",
96
- "koatty_validation": "^1.2.10"
96
+ "koatty_validation": "^1.3.0"
97
97
  }
98
98
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koatty",
3
- "version": "3.10.4-5",
3
+ "version": "3.11.0",
4
4
  "description": "Koa2 + Typescript = koatty. Use Typescript's decorator implement auto injection.",
5
5
  "scripts": {
6
6
  "build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
@@ -82,7 +82,7 @@
82
82
  "typescript": "^5.x.x"
83
83
  },
84
84
  "dependencies": {
85
- "koa": "^2.14.2",
85
+ "koa": "^2.15.0",
86
86
  "koatty_config": "^1.1.6",
87
87
  "koatty_container": "^1.8.10",
88
88
  "koatty_core": "^1.8.4",
@@ -93,6 +93,6 @@
93
93
  "koatty_proto": "^1.1.12",
94
94
  "koatty_serve": "2.1.0",
95
95
  "koatty_trace": "^1.10.4",
96
- "koatty_validation": "^1.2.10"
96
+ "koatty_validation": "^1.3.0"
97
97
  }
98
98
  }