koatty 3.10.4 → 3.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-24 10:16:17
3
+ * @Date: 2024-01-04 07:59:12
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,127 @@ 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-04 07:43:03
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
+ /**
282
+ * check is implements Aspect Interface
283
+ * @param cls
284
+ * @returns
285
+ */
286
+ function implementsAspectInterface(cls) {
287
+ return 'app' in cls && 'run' in cls && koatty_lib.Helper.isFunction(cls.run);
288
+ }
289
+
255
290
  /*
256
291
  * @Description: framework constants
257
292
  * @Usage:
@@ -278,7 +313,7 @@ https://github.com/koatty
278
313
  * @Usage:
279
314
  * @Author: richen
280
315
  * @Date: 2023-12-09 22:55:49
281
- * @LastEditTime: 2023-12-24 10:10:52
316
+ * @LastEditTime: 2024-01-04 05:52:31
282
317
  * @License: BSD (3-Clause)
283
318
  * @Copyright (c): <richenlin(at)gmail.com>
284
319
  */
@@ -523,6 +558,10 @@ class Loader {
523
558
  item.id = (item.id ?? "").replace("MIDDLEWARE:", "");
524
559
  if (item.id && koatty_lib.Helper.isClass(item.target)) {
525
560
  koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "MIDDLEWARE", args: [] });
561
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
562
+ if (!implementsMiddlewareInterface(ctl)) {
563
+ throw Error(`The middleware ${item.id} must implements interface 'IMiddleware'.`);
564
+ }
526
565
  }
527
566
  });
528
567
  const middlewareConfList = middlewareConf.list || [];
@@ -574,8 +613,8 @@ class Loader {
574
613
  // registering to IOC
575
614
  koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Prototype", type: "CONTROLLER", args: [] });
576
615
  const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
577
- if (!(ctl instanceof BaseController)) {
578
- throw Error(`Controller class ${item.id} does not inherit from BaseController`);
616
+ if (!implementsControllerInterface(ctl)) {
617
+ throw Error(`The controller ${item.id} must implements interface 'IController'.`);
579
618
  }
580
619
  controllers.push(item.id);
581
620
  }
@@ -597,6 +636,10 @@ class Loader {
597
636
  Logger.Debug(`Load service: ${item.id}`);
598
637
  // registering to IOC
599
638
  koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "SERVICE", args: [] });
639
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
640
+ if (!implementsServiceInterface(ctl)) {
641
+ throw Error(`The service ${item.id} must implements interface 'IService'.`);
642
+ }
600
643
  }
601
644
  });
602
645
  }
@@ -631,11 +674,21 @@ class Loader {
631
674
  componentList.forEach(async (item) => {
632
675
  item.id = (item.id ?? "").replace("COMPONENT:", "");
633
676
  if (koatty_lib.Helper.isClass(item.target)) {
677
+ // registering to IOC
678
+ koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
634
679
  if (item.id && (item.id).endsWith("Plugin")) {
680
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
681
+ if (!implementsPluginInterface(ctl)) {
682
+ throw Error(`The plugin ${item.id} must implements interface 'IPlugin'.`);
683
+ }
635
684
  pluginList.push(item.id);
636
685
  }
637
- // registering to IOC
638
- koatty_container.IOCContainer.reg(item.id, item.target, { scope: "Singleton", type: "COMPONENT", args: [] });
686
+ if (item.id && (item.id).endsWith("Aspect")) {
687
+ const ctl = koatty_container.IOCContainer.getInsByClass(item.target);
688
+ if (!implementsAspectInterface(ctl)) {
689
+ throw Error(`The aspect ${item.id} must implements interface 'IAspect'.`);
690
+ }
691
+ }
639
692
  }
640
693
  });
641
694
  // load plugin config
@@ -663,7 +716,7 @@ class Loader {
663
716
  }
664
717
  }
665
718
 
666
- var version = "3.10.4";
719
+ var version = "3.11.1";
667
720
  var engines = {
668
721
  node: ">12.0.0"
669
722
  };
@@ -926,119 +979,169 @@ function BindEventHook(eventName, eventFunc, target) {
926
979
  }
927
980
 
928
981
  /*
929
- * @Description: component interface
982
+ * @Description: base service
930
983
  * @Usage:
931
984
  * @Author: richen
932
985
  * @Date: 2023-12-09 21:56:32
933
- * @LastEditTime: 2023-12-23 11:40:44
986
+ * @LastEditTime: 2024-01-03 21:57:26
934
987
  * @License: BSD (3-Clause)
935
988
  * @Copyright (c): <richenlin(at)gmail.com>
936
989
  */
937
- // tslint:disable-next-line: no-import-side-effect
938
- /**
939
- * Indicates that an decorated class is a "component".
940
- *
941
- * @export
942
- * @param {string} [identifier] component name
943
- * @returns {ClassDecorator}
944
- */
945
- function Component(identifier) {
946
- return (target) => {
947
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
948
- koatty_container.IOCContainer.saveClass("COMPONENT", target, identifier);
949
- };
950
- }
951
- /**
952
- * Indicates that an decorated class is a "controller".
953
- *
954
- * @export
955
- * @param {string} [path] controller router path
956
- * @returns {ClassDecorator}
957
- */
958
- function Controller(path = "") {
959
- return (target) => {
960
- const identifier = koatty_container.IOCContainer.getIdentifier(target);
961
- koatty_container.IOCContainer.saveClass("CONTROLLER", target, identifier);
962
- koatty_container.IOCContainer.savePropertyData(koatty_serve.CONTROLLER_ROUTER, path, target, identifier);
963
- };
964
- }
965
990
  /**
966
- * Indicates that an decorated class is a "middleware".
967
- *
968
- * @export
969
- * @param {string} [identifier] class name
970
- * @returns {ClassDecorator}
971
- */
972
- function Middleware(identifier) {
973
- return (target) => {
974
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
975
- koatty_container.IOCContainer.saveClass("MIDDLEWARE", target, identifier);
976
- };
977
- }
978
- /**
979
- * Indicates that an decorated class is a "service".
980
- *
981
- * @export
982
- * @param {string} [identifier] class name
983
- * @returns {ClassDecorator}
984
- */
985
- function Service(identifier) {
986
- return (target) => {
987
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
988
- koatty_container.IOCContainer.saveClass("SERVICE", target, identifier);
989
- };
990
- }
991
- /**
992
- * Indicates that an decorated class is a "plugin".
991
+ * Base service
993
992
  *
994
993
  * @export
995
- * @param {string} [identifier] class name
996
- * @returns {ClassDecorator}
994
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
995
+ * @class Base
997
996
  */
998
- function Plugin(identifier) {
999
- return (target) => {
1000
- identifier = identifier || koatty_container.IOCContainer.getIdentifier(target);
1001
- //
1002
- if (!identifier.endsWith("Plugin")) {
1003
- throw Error("Plugin class name must be 'Plugin' suffix.");
1004
- }
1005
- koatty_container.IOCContainer.saveClass("COMPONENT", target, `${identifier}`);
1006
- };
997
+ class BaseService {
998
+ /**
999
+ * instance of BaseController.
1000
+ * @param {Koatty} app
1001
+ * @param {KoattyContext} ctx
1002
+ * @memberof BaseController
1003
+ */
1004
+ constructor(...arg) {
1005
+ this.init(arg);
1006
+ }
1007
+ /**
1008
+ * init
1009
+ *
1010
+ * @protected
1011
+ * @memberof BaseController
1012
+ */
1013
+ init(...arg) {
1014
+ }
1007
1015
  }
1008
1016
 
1009
1017
  /*
1010
- * @Description: base service
1018
+ * @Description: base controller
1011
1019
  * @Usage:
1012
1020
  * @Author: richen
1013
1021
  * @Date: 2023-12-09 21:56:32
1014
- * @LastEditTime: 2023-12-09 23:03:23
1022
+ * @LastEditTime: 2024-01-03 21:57:20
1015
1023
  * @License: BSD (3-Clause)
1016
1024
  * @Copyright (c): <richenlin(at)gmail.com>
1017
1025
  */
1018
1026
  /**
1019
- * Base service
1027
+ * Base controller
1020
1028
  *
1021
1029
  * @export
1022
- * @class Base
1030
+ * @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
1031
+ * @class BaseController
1032
+ * @implements {IController}
1023
1033
  */
1024
- class BaseService {
1034
+ class BaseController {
1025
1035
  /**
1026
1036
  * instance of BaseController.
1027
1037
  * @param {Koatty} app
1028
1038
  * @param {KoattyContext} ctx
1029
1039
  * @memberof BaseController
1030
1040
  */
1031
- constructor(...arg) {
1041
+ constructor(ctx, ...arg) {
1042
+ this.ctx = ctx;
1032
1043
  this.init(arg);
1033
1044
  }
1034
1045
  /**
1035
1046
  * init
1036
1047
  *
1037
- * @protected
1038
1048
  * @memberof BaseController
1039
1049
  */
1040
1050
  init(...arg) {
1041
1051
  }
1052
+ /**
1053
+ * Response to normalize json format content for success
1054
+ *
1055
+ * @deprecated 使用 Output.ok 代替
1056
+ * @param {(string | ApiInput)} msg 待处理的message消息
1057
+ * @param {*} [data] 待处理的数据
1058
+ * @param {number} [code=200] 错误码,默认0
1059
+ * @returns {*}
1060
+ * @memberof BaseController
1061
+ */
1062
+ ok(msg, data, code = 0) {
1063
+ const obj = formatApiData(msg, data, code);
1064
+ return Promise.resolve(obj);
1065
+ }
1066
+ /**
1067
+ * Response to normalize json format content for fail
1068
+ *
1069
+ * @deprecated 使用 Output.fail 代替
1070
+ * @param {(string | ApiInput)} msg
1071
+ * @param {*} [data]
1072
+ * @param {number} [code=1]
1073
+ * @returns {*}
1074
+ * @memberof BaseController
1075
+ */
1076
+ fail(msg, data, code = 1) {
1077
+ const obj = formatApiData(msg, data, code);
1078
+ this.ctx.body = obj.data;
1079
+ this.ctx.throw(obj.message, obj.code, 200);
1080
+ }
1081
+ }
1082
+ // const properties = ["constructor", "init"];
1083
+ // export const BaseController = new Proxy(Base, {
1084
+ // set(target, key, value, receiver) {
1085
+ // if (Reflect.get(target, key, receiver) === undefined) {
1086
+ // return Reflect.set(target, key, value, receiver);
1087
+ // } else if (key === "init") {
1088
+ // return Reflect.set(target, key, value, receiver);
1089
+ // } else {
1090
+ // throw Error("Cannot redefine getter-only property");
1091
+ // }
1092
+ // },
1093
+ // deleteProperty(target, key) {
1094
+ // throw Error("Cannot delete getter-only property");
1095
+ // },
1096
+ // construct(target, args, newTarget) {
1097
+ // Reflect.ownKeys(target.prototype).map((n) => {
1098
+ // if (newTarget.prototype.hasOwnProperty(n) && !properties.includes(Helper.toString(n))) {
1099
+ // throw Error(`Cannot override the final method "${Helper.toString(n)}"`);
1100
+ // }
1101
+ // });
1102
+ // return Reflect.construct(target, args, newTarget);
1103
+ // }
1104
+ // });
1105
+
1106
+ /*
1107
+ * @Description: output data
1108
+ * @Usage:
1109
+ * @Author: richen
1110
+ * @Date: 2024-01-03 22:03:34
1111
+ * @LastEditTime: 2024-01-03 22:07:20
1112
+ * @License: BSD (3-Clause)
1113
+ * @Copyright (c): <richenlin(at)gmail.com>
1114
+ */
1115
+ class Output {
1116
+ /**
1117
+ * Response to normalize json format content for success
1118
+ *
1119
+ * @param {KoattyContext} ctx
1120
+ * @param {(string | ApiInput)} msg 待处理的message消息
1121
+ * @param {*} [data] 待处理的数据
1122
+ * @param {number} [code=200] 错误码,默认0
1123
+ * @returns {*}
1124
+ * @memberof BaseController
1125
+ */
1126
+ static ok(ctx, msg, data, code = 0) {
1127
+ const obj = formatApiData(msg, data, code);
1128
+ return Promise.resolve(obj);
1129
+ }
1130
+ /**
1131
+ * Response to normalize json format content for fail
1132
+ *
1133
+ * @param {KoattyContext} ctx
1134
+ * @param {(string | ApiInput)} msg
1135
+ * @param {*} [data]
1136
+ * @param {number} [code=1]
1137
+ * @returns {*}
1138
+ * @memberof BaseController
1139
+ */
1140
+ static fail(ctx, msg, data, code = 1) {
1141
+ const obj = formatApiData(msg, data, code);
1142
+ ctx.body = obj.data;
1143
+ ctx.throw(obj.message, obj.code, 200);
1144
+ }
1042
1145
  }
1043
1146
 
1044
1147
  Object.defineProperty(exports, 'Config', {
@@ -1064,8 +1167,14 @@ exports.Controller = Controller;
1064
1167
  exports.ExecBootStrap = ExecBootStrap;
1065
1168
  exports.Logger = Logger;
1066
1169
  exports.Middleware = Middleware;
1170
+ exports.Output = Output;
1067
1171
  exports.Plugin = Plugin;
1068
1172
  exports.Service = Service;
1173
+ exports.implementsAspectInterface = implementsAspectInterface;
1174
+ exports.implementsControllerInterface = implementsControllerInterface;
1175
+ exports.implementsMiddlewareInterface = implementsMiddlewareInterface;
1176
+ exports.implementsPluginInterface = implementsPluginInterface;
1177
+ exports.implementsServiceInterface = implementsServiceInterface;
1069
1178
  Object.keys(koatty_container).forEach(function (k) {
1070
1179
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1071
1180
  enumerable: true,