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 +14 -0
- package/dist/index.d.ts +58 -4
- package/dist/index.js +266 -171
- package/dist/index.mjs +263 -173
- package/dist/package.json +3 -3
- package/package.json +3 -3
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:
|
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:
|
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:
|
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 (
|
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(
|
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
|
577
|
-
throw Error(`
|
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.
|
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:
|
968
|
+
* @Description: base service
|
929
969
|
* @Usage:
|
930
970
|
* @Author: richen
|
931
971
|
* @Date: 2023-12-09 21:56:32
|
932
|
-
* @LastEditTime:
|
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
|
-
*
|
977
|
+
* Base service
|
992
978
|
*
|
993
979
|
* @export
|
994
|
-
* @
|
995
|
-
* @
|
980
|
+
* @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
|
981
|
+
* @class Base
|
996
982
|
*/
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
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
|
1004
|
+
* @Description: base controller
|
1010
1005
|
* @Usage:
|
1011
1006
|
* @Author: richen
|
1012
1007
|
* @Date: 2023-12-09 21:56:32
|
1013
|
-
* @LastEditTime:
|
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
|
1013
|
+
* Base controller
|
1019
1014
|
*
|
1020
1015
|
* @export
|
1021
|
-
* @
|
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
|
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:
|
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
|
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:
|
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 (
|
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(
|
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
|
562
|
-
throw Error(`
|
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.
|
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:
|
953
|
+
* @Description: base service
|
914
954
|
* @Usage:
|
915
955
|
* @Author: richen
|
916
956
|
* @Date: 2023-12-09 21:56:32
|
917
|
-
* @LastEditTime:
|
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
|
-
*
|
962
|
+
* Base service
|
977
963
|
*
|
978
964
|
* @export
|
979
|
-
* @
|
980
|
-
* @
|
965
|
+
* @deprecated When the framework version is > 3.10.5, do not need to inherit the Base class.
|
966
|
+
* @class Base
|
981
967
|
*/
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
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
|
989
|
+
* @Description: base controller
|
995
990
|
* @Usage:
|
996
991
|
* @Author: richen
|
997
992
|
* @Date: 2023-12-09 21:56:32
|
998
|
-
* @LastEditTime:
|
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
|
998
|
+
* Base controller
|
1004
999
|
*
|
1005
1000
|
* @export
|
1006
|
-
* @
|
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
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
96
|
+
"koatty_validation": "^1.3.0"
|
97
97
|
}
|
98
98
|
}
|