typespeed 2.5.0 → 2.5.2

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.en.md +169 -0
  3. package/README.md +123 -37
  4. package/dist/default/rabbitmq.class.js +18 -1
  5. package/dist/default/redis.class.js +14 -1
  6. package/dist/default/socket-io.class.js +53 -4
  7. package/dist/typespeed.d.ts +7 -7
  8. package/package.json +7 -2
  9. package/.github/workflows/test.yml +0 -50
  10. package/app/nodemon.json +0 -5
  11. package/app/package.json +0 -17
  12. package/app/src/aop-test.class.ts +0 -29
  13. package/app/src/config-development.json +0 -26
  14. package/app/src/config-production.json +0 -15
  15. package/app/src/config.json +0 -50
  16. package/app/src/custom-log.class.ts +0 -33
  17. package/app/src/entities/mutil-users.class.ts +0 -5
  18. package/app/src/entities/user-dto.class.ts +0 -3
  19. package/app/src/first-page.class.ts +0 -46
  20. package/app/src/jwt-authentication.class.ts +0 -30
  21. package/app/src/main.ts +0 -24
  22. package/app/src/second-page.class.ts +0 -43
  23. package/app/src/test-bind.class.ts +0 -41
  24. package/app/src/test-database.class.ts +0 -81
  25. package/app/src/test-log.class.ts +0 -11
  26. package/app/src/test-mq.class.ts +0 -21
  27. package/app/src/test-orm.class.ts +0 -63
  28. package/app/src/test-redis.class.ts +0 -45
  29. package/app/src/test-request.class.ts +0 -37
  30. package/app/src/test-socket.class.ts +0 -56
  31. package/app/src/user-model.class.ts +0 -50
  32. package/app/src/views/index.html +0 -1
  33. package/app/src/views/socket.html +0 -23
  34. package/app/src/views/upload.html +0 -14
  35. package/app/static/favicon.ico +0 -0
  36. package/app/static/k.jpg +0 -0
  37. package/app/tsconfig.json +0 -20
  38. package/introduction/decorator/example-import.class.ts +0 -6
  39. package/introduction/decorator/main-app.ts +0 -6
  40. package/introduction/decorator/main-decorator.ts +0 -108
  41. package/introduction/decorator/main-import.ts +0 -1
  42. package/introduction/decorator/main-reflect.ts +0 -25
  43. package/introduction/decorator-next/dist/main.js +0 -116
  44. package/introduction/decorator-next/package.json +0 -14
  45. package/introduction/decorator-next/src/main.ts +0 -64
  46. package/introduction/decorator-next/tsconfig.json +0 -17
  47. package/introduction/decorator-next//346/225/231/347/250/213.md +0 -384
  48. package/introduction/tsconfig.json +0 -23
  49. package/introduction/web-services/db-init.ts +0 -39
  50. package/introduction/web-services/db-singleton.ts +0 -59
  51. package/introduction/web-services/http-if.ts +0 -10
  52. package/introduction/web-services/http-init.ts +0 -6
  53. package/introduction/web-services/http-router.ts +0 -28
  54. package/src/bind.decorator.ts +0 -50
  55. package/src/core.decorator.ts +0 -184
  56. package/src/database.decorator.ts +0 -446
  57. package/src/decorator-utils.ts +0 -53
  58. package/src/default/default-authentication.class.ts +0 -10
  59. package/src/default/express-server.class.ts +0 -150
  60. package/src/default/log-default.class.ts +0 -9
  61. package/src/default/node-cache.class.ts +0 -40
  62. package/src/default/pages/404.html +0 -226
  63. package/src/default/pages/500.html +0 -713
  64. package/src/default/rabbitmq.class.ts +0 -61
  65. package/src/default/read-write-db.class.ts +0 -53
  66. package/src/default/redis.class.ts +0 -79
  67. package/src/default/socket-io.class.ts +0 -81
  68. package/src/factory/authentication-factory.class.ts +0 -9
  69. package/src/factory/cache-factory.class.ts +0 -7
  70. package/src/factory/data-source-factory.class.ts +0 -4
  71. package/src/factory/log-factory.class.ts +0 -8
  72. package/src/factory/server-factory.class.ts +0 -6
  73. package/src/route.decorator.ts +0 -334
  74. package/src/scaffold/command.ts +0 -40
  75. package/src/scaffold/templates/front-page.class.ts.tpl +0 -12
  76. package/src/scaffold/templates/main.ts.tpl +0 -13
  77. package/src/scaffold/templates/nodemon.json.tpl +0 -7
  78. package/src/scaffold/templates/package.json.tpl +0 -16
  79. package/src/scaffold/templates/tsconfig.json.tpl +0 -17
  80. package/src/typespeed.d.ts +0 -403
  81. package/src/typespeed.ts +0 -139
  82. package/test/bind.test.ts +0 -28
  83. package/test/database.test.ts +0 -76
  84. package/test/decorator-utils.test.ts +0 -42
  85. package/test/first-page.test.ts +0 -42
  86. package/test/hooks.ts +0 -13
  87. package/test/mq.test.ts +0 -17
  88. package/test/orm.test.ts +0 -66
  89. package/test/redis.test.ts +0 -48
  90. package/test/request.test.ts +0 -51
  91. package/test/second-page.test.ts +0 -50
  92. package/test/socket.test.ts +0 -60
  93. package/test-env/docker-compose.test.yml +0 -31
  94. package/test-env/mysql-init/init.sql +0 -8
  95. package/test-env//346/234/254/345/234/260Docker/346/265/213/350/257/225/346/226/271/346/241/210.md +0 -69
  96. package/tsconfig.json +0 -25
@@ -1,61 +0,0 @@
1
- import { bean, getComponent } from "../core.decorator";
2
- import { config } from "../typespeed";
3
- import { connect } from "amqplib";
4
- let rabbitConnection = null;
5
-
6
- class RabbitMQ {
7
-
8
- @bean
9
- public getRabbitMQ(): RabbitMQ {
10
- if (!config("rabbitmq")) {
11
- return null;
12
- }
13
- return new RabbitMQ();
14
- }
15
-
16
- public async publishMessageToExchange(exchange: string, routingKey: string, message: string): Promise<void> {
17
- const channel = await getChannel();
18
- await channel.assertExchange(exchange);
19
- channel.publish(exchange, routingKey, Buffer.from(message));
20
- await channel.close();
21
- }
22
-
23
- public async sendMessageToQueue(queue: string, message: string): Promise<void> {
24
- const channel = await getChannel();
25
- await channel.accertQueue(queue);
26
- channel.sendToQueue(queue, Buffer.from(message));
27
- await channel.close();
28
- }
29
-
30
- public async publish(exchange: string, routingKey: string, message: string): Promise<void> {
31
- await this.publishMessageToExchange(exchange, routingKey, message);
32
- }
33
-
34
- public async send(queue: string, message: string): Promise<void> {
35
- await this.sendMessageToQueue(queue, message);
36
- }
37
- }
38
-
39
- async function getChannel() {
40
- if (rabbitConnection === null) {
41
- rabbitConnection = await connect(config("rabbitmq"));
42
- process.once('SIGINT', async () => {
43
- await rabbitConnection.close();
44
- });
45
- }
46
- const channel = await rabbitConnection.createChannel();
47
- return channel;
48
- }
49
-
50
- function rabbitListener(queue: string) {
51
- return (target: any, propertyKey: string) => {
52
- (async function () {
53
- const channel = await getChannel();
54
- await channel.assertQueue(queue);
55
- const targetBean = getComponent(target.constructor);
56
- await channel.consume(queue, targetBean[propertyKey], { noAck: true });
57
- }());
58
- }
59
- }
60
-
61
- export { RabbitMQ, rabbitListener };
@@ -1,53 +0,0 @@
1
- import { createConnection, createPool } from "mysql2";
2
- import DataSourceFactory from "../factory/data-source-factory.class";
3
- import { bean } from "../core.decorator";
4
- import { config } from "../typespeed";
5
- export default class ReadWriteDb extends DataSourceFactory {
6
- private readonly readSession;
7
- private readonly writeSession;
8
-
9
- @bean
10
- public getDataSource(): DataSourceFactory {
11
- if (!config("mysql")) {
12
- return null;
13
- }
14
- return new ReadWriteDb();
15
- }
16
-
17
- constructor() {
18
- super();
19
- const dbConfig = config("mysql");
20
- if (dbConfig["master"] && dbConfig["slave"]) {
21
- this.writeSession = this.getConnectionByConfig(dbConfig["master"]);
22
- if (Array.isArray(dbConfig["slave"])) {
23
- this.readSession = dbConfig["slave"].map(config => this.getConnectionByConfig(config));
24
- } else {
25
- this.readSession = [this.getConnectionByConfig(dbConfig["slave"])];
26
- }
27
- } else {
28
- this.writeSession = this.getConnectionByConfig(dbConfig);
29
- this.readSession = [this.writeSession];
30
- }
31
- }
32
-
33
- private getConnectionByConfig(config: object) {
34
- if (config["PoolOptions"] !== undefined) {
35
- // we need pool
36
- if (Object.keys(config["PoolOptions"]).length !== 0) {
37
- config = Object.assign(config, config["PoolOptions"]);
38
- }
39
- return createPool(config).promise();
40
- } else {
41
- // only connection
42
- return createConnection(config).promise();
43
- }
44
- }
45
-
46
- public readConnection() {
47
- return this.readSession[Math.floor(Math.random() * this.readSession.length)];
48
- }
49
-
50
- public writeConnection() {
51
- return this.writeSession;
52
- }
53
- }
@@ -1,79 +0,0 @@
1
- import { bean, getComponent } from "../core.decorator";
2
- import { default as IoRedis, RedisKey} from "ioredis";
3
- import { config } from "../typespeed";
4
- const redisSubscribers = {};
5
-
6
- class Redis extends IoRedis {
7
- private static pubObj: Redis = null;
8
- private static subObj: Redis = null;
9
-
10
- @bean
11
- public getRedis(): Redis {
12
- return Redis.getInstanceOfRedis("pub");
13
- }
14
-
15
- public async zrevranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>> {
16
- const list = await this.zrevrange(key, start, stop, "WITHSCORES");
17
- const map = new Map<string, number>();
18
- for (let i = 0; i < list.length; i = i + 2) {
19
- map.set(list[i], Number(list[i + 1]));
20
- }
21
- return map;
22
- }
23
-
24
- public async zranking(key: RedisKey, start: number | string, stop: number | string): Promise<Map<string, number>> {
25
- const list = await this.zrange(key, start, stop, "WITHSCORES");
26
- const map = new Map<string, number>();
27
- for (let i = 0; i < list.length; i = i + 2) {
28
- map.set(list[i], Number(list[i + 1]));
29
- }
30
- return map;
31
- }
32
-
33
- static getInstanceOfRedis(mode: "sub" | "pub") {
34
- if (!config("redis")) {
35
- return null;
36
- }
37
- if (mode === "pub") {
38
- this.pubObj = this.pubObj || new Redis(config("redis"));
39
- return this.pubObj;
40
- } else {
41
- this.subObj = this.subObj || new Redis(config("redis"));
42
- return this.subObj;
43
- }
44
- }
45
-
46
- static async close() {
47
- if(this.subObj != null) { await this.subObj.quit(); }
48
- if(this.pubObj != null) { await this.pubObj.quit(); }
49
- }
50
- }
51
-
52
- function redisSubscriber(channel: string) {
53
- if (!config("redis")) return function(){
54
- throw new Error("redis not configured");
55
- };
56
- Redis.getInstanceOfRedis("sub").subscribe(channel, function (err, count) {
57
- if (err) {
58
- console.error(err);
59
- }
60
- });
61
- return function (target: any, propertyKey: string) {
62
- redisSubscribers[channel] = {
63
- target: target,
64
- propertyKey: propertyKey
65
- };
66
- };
67
- }
68
-
69
- if (config("redis")) {
70
- Redis.getInstanceOfRedis("sub").on("message", async function (channel, message) {
71
- await getComponent(redisSubscribers[channel].target.constructor)[redisSubscribers[channel].propertyKey](message);
72
- });
73
- }
74
-
75
- process.once('SIGINT', () => {
76
- Redis.close();
77
- });
78
-
79
- export { Redis, redisSubscriber };
@@ -1,81 +0,0 @@
1
- import { Server as IoServer } from "socket.io";
2
- import { createServer } from "http";
3
- import { getComponent } from "../core.decorator";
4
-
5
- let io: IoServer = null;
6
- const listeners = { "event": [], "disconnect": null, "error": null, "connected": null };
7
-
8
- class SocketIo {
9
-
10
- public static setIoServer(app, ioSocketConfig) {
11
- const httpServer = createServer(app);
12
- io = new IoServer(httpServer, ioSocketConfig);
13
- io.use(async (socket, next) => {
14
- if (listeners["connected"] !== null) {
15
- await getComponent(listeners["connected"].target.constructor)[listeners["connected"].propertyKey](socket, async (err) => {
16
- if (listeners["error"] !== null && err) {
17
- await getComponent(listeners["error"].target.constructor)[listeners["error"].propertyKey](socket, err);
18
- }
19
- });
20
- }
21
- next();
22
- });
23
- io.on("connection", async (socket) => {
24
- if (listeners["disconnect"] !== null) {
25
- socket.on("disconnect", async (reason) => {
26
- await getComponent(listeners["disconnect"].target.constructor)[listeners["disconnect"].propertyKey](socket, reason);
27
- });
28
- }
29
- socket.use(async ([event, ...args], next) => {
30
- try {
31
- for (let listener of listeners["event"]) {
32
- if (listener[1] === event) {
33
- await getComponent(listener[0].target.constructor)[listener[0].propertyKey](socket, ...args);
34
- }
35
- }
36
- } catch (err) {
37
- next(err);
38
- }
39
- });
40
-
41
- if (listeners["error"] !== null) {
42
- socket.on("error", async (err) => {
43
- await getComponent(listeners["error"].target.constructor)[listeners["error"].propertyKey](socket, err);
44
- });
45
- }
46
- });
47
- return httpServer;
48
- }
49
-
50
- public static onEvent(event: string) {
51
- return (target: any, propertyKey: string) => {
52
- listeners["event"].push([{
53
- target: target,
54
- propertyKey: propertyKey
55
- }, event]);
56
- }
57
- }
58
-
59
- public static onError(target: any, propertyKey: string) {
60
- listeners["error"] = {
61
- target: target,
62
- propertyKey: propertyKey
63
- };
64
- }
65
-
66
- public static onDisconnect(target: any, propertyKey: string) {
67
- listeners["disconnect"] = {
68
- target: target,
69
- propertyKey: propertyKey
70
- };
71
- }
72
-
73
- public static onConnected(target: any, propertyKey: string) {
74
- listeners["connected"] = {
75
- target: target,
76
- propertyKey: propertyKey
77
- };
78
- }
79
- }
80
-
81
- export { SocketIo, io }
@@ -1,9 +0,0 @@
1
- import * as express from 'express';
2
- export default abstract class AuthenticationFactory {
3
- public preHandle(req: express.Request, res: express.Response, next: express.NextFunction): void{
4
- next();
5
- }
6
- public afterCompletion(req: express.Request, res: express.Response, next: express.NextFunction): void{
7
- next();
8
- }
9
- }
@@ -1,7 +0,0 @@
1
- export default abstract class CacheFactory {
2
- public abstract get(key: string): any;
3
- public abstract set(key: string, value: any, expire?: number): void;
4
- public abstract del(key: string): void;
5
- public abstract has(key: string): boolean;
6
- public abstract flush(): void;
7
- }
@@ -1,4 +0,0 @@
1
- export default abstract class DataSourceFactory {
2
- public abstract readConnection();
3
- public abstract writeConnection();
4
- }
@@ -1,8 +0,0 @@
1
- export default abstract class LogFactory {
2
- public log(message?: any, ...optionalParams: any[]) : void {
3
- console.log(message, ...optionalParams);
4
- }
5
- public error(message?: any, ...optionalParams: any[]) : void {
6
- console.error(message, ...optionalParams);
7
- }
8
- }
@@ -1,6 +0,0 @@
1
- export default abstract class ServerFactory {
2
- public app;
3
- protected middlewareList: Array<any> = [];
4
- public abstract setMiddleware(middleware: any);
5
- public abstract start(port: number): any;
6
- }
@@ -1,334 +0,0 @@
1
- import * as express from "express";
2
- import * as multiparty from "multiparty";
3
- import { expressjwt } from "express-jwt";
4
- import { getComponent } from "./core.decorator";
5
- import { isStd, getStdArgs } from "./decorator-utils";
6
- import { getBindMapping } from "./bind.decorator";
7
-
8
- const routerMapper = {
9
- "get": {},
10
- "post": {},
11
- "all": {}
12
- };
13
- const routerParams = {};
14
- const routerParamsTotal = {};
15
- const routerMiddleware = {};
16
- function setRouter(app: express.Application) {
17
- ["get", "post", "all"].forEach(method => {
18
- for (let key in routerMapper[method]) {
19
- const rounterFunction = routerMapper[method][key];
20
- if (routerMiddleware[rounterFunction["name"]]) {
21
- const args: Array<any> = [key, ...routerMiddleware[rounterFunction["name"]], rounterFunction["invoker"]];
22
- app[method].apply(app, args);
23
- } else {
24
- app[method](key, rounterFunction["invoker"]);
25
- }
26
- }
27
- });
28
- }
29
-
30
- function mapperFunction(method: string, value: string) {
31
- return (...args: any[]): any => {
32
- if (isStd(args)) {
33
- const [methodFn, ctx] = getStdArgs(args);
34
- ctx.addInitializer(function (this: any) {
35
- const className = this.constructor.name;
36
- const propertyKey = String(ctx.name);
37
- applyRouteBind(className, propertyKey, methodFn);
38
- routerMapper[method][value] = {
39
- "path": value,
40
- "name": [className, propertyKey].toString(),
41
- "target": this.constructor,
42
- "propertyKey": propertyKey,
43
- "invoker": async (req, res, next) => {
44
- const routerBean = getComponent(this.constructor);
45
- try {
46
- let paramTotal = routerBean[propertyKey].length;
47
- if (routerParamsTotal[[className, propertyKey].toString()]) {
48
- paramTotal = Math.max(paramTotal, routerParamsTotal[[className, propertyKey].toString()]);
49
- }
50
- const callArgs = [req, res, next];
51
- if (paramTotal > 0) {
52
- for (let i = 0; i < paramTotal; i++) {
53
- if (routerParams[[className, propertyKey, i].toString()]) {
54
- callArgs[i] = routerParams[[className, propertyKey, i].toString()](req, res, next);
55
- }
56
- }
57
- }
58
- const testResult = await routerBean[propertyKey].apply(routerBean, callArgs);
59
- if (typeof testResult === "object") {
60
- res.json(testResult);
61
- } else if (typeof testResult !== "undefined") {
62
- res.send(testResult);
63
- }
64
- return testResult;
65
- } catch (err) {
66
- next(err);
67
- }
68
- }
69
- };
70
- });
71
- return;
72
- }
73
- const target = args[0];
74
- const propertyKey = args[1] as string;
75
- applyRouteBind(target.constructor.name, propertyKey, target[propertyKey]);
76
- routerMapper[method][value] = {
77
- "path": value,
78
- "name": [target.constructor.name, propertyKey].toString(),
79
- "target": target.constructor,
80
- "propertyKey": propertyKey,
81
- "invoker": async (req, res, next) => {
82
- const routerBean = getComponent(target.constructor);
83
- try {
84
- let paramTotal = routerBean[propertyKey].length;
85
- if(routerParamsTotal[[target.constructor.name, propertyKey].toString()]){
86
- paramTotal = Math.max(paramTotal, routerParamsTotal[[target.constructor.name, propertyKey].toString()]);
87
- }
88
- const args = [req, res, next];
89
- if(paramTotal > 0) {
90
- for(let i = 0; i < paramTotal; i++) {
91
- if(routerParams[[target.constructor.name, propertyKey, i].toString()]){
92
- args[i] = routerParams[[target.constructor.name, propertyKey, i].toString()](req, res, next);
93
- }
94
- }
95
- }
96
- const testResult = await routerBean[propertyKey].apply(routerBean, args);
97
- if (typeof testResult === "object") {
98
- res.json(testResult);
99
- } else if (typeof testResult !== "undefined") {
100
- res.send(testResult);
101
- }
102
- return testResult;
103
- } catch (err) {
104
- next(err)
105
- }
106
- }
107
- }
108
- }
109
- }
110
-
111
- function upload(...args: any[]): any {
112
- if (isStd(args)) {
113
- const [, ctx] = getStdArgs(args);
114
- ctx.addInitializer(function (this: any) {
115
- const key = [this.constructor.name, String(ctx.name)].toString();
116
- if (routerMiddleware[key]) {
117
- routerMiddleware[key].push(uploadMiddleware);
118
- } else {
119
- routerMiddleware[key] = [uploadMiddleware];
120
- }
121
- });
122
- return;
123
- }
124
- const target = args[0];
125
- const propertyKey = args[1] as string;
126
- const key = [target.constructor.name, propertyKey].toString();
127
- if (routerMiddleware[key]) {
128
- routerMiddleware[key].push(uploadMiddleware);
129
- } else {
130
- routerMiddleware[key] = [uploadMiddleware];
131
- }
132
- }
133
-
134
- function uploadMiddleware(req, res, next) {
135
- const form = new multiparty.Form();
136
- form.parse(req, (err, fields, files) => {
137
- req.files = files || undefined;
138
- next();
139
- });
140
- }
141
-
142
- function jwt(jwtConfig) {
143
- return (...args: any[]): any => {
144
- if (isStd(args)) {
145
- const [, ctx] = getStdArgs(args);
146
- ctx.addInitializer(function (this: any) {
147
- const key = [this.constructor.name, String(ctx.name)].toString();
148
- if (routerMiddleware[key]) {
149
- routerMiddleware[key].push(expressjwt(jwtConfig));
150
- } else {
151
- routerMiddleware[key] = [expressjwt(jwtConfig)];
152
- }
153
- });
154
- return;
155
- }
156
- const target = args[0];
157
- const propertyKey = args[1] as string;
158
- const key = [target.constructor.name, propertyKey].toString();
159
- if (routerMiddleware[key]) {
160
- routerMiddleware[key].push(expressjwt(jwtConfig));
161
- } else {
162
- routerMiddleware[key] = [expressjwt(jwtConfig)];
163
- }
164
- }
165
- }
166
-
167
- function before(constructorFunction, methodName: string) {
168
- const targetBean = getComponent(constructorFunction);
169
- return function (...args: any[]) {
170
- if (isStd(args)) {
171
- const [, ctx] = getStdArgs(args);
172
- const hookKey = String(ctx.name);
173
- ctx.addInitializer(function (this: any) {
174
- const currentMethod = this[methodName];
175
- if (currentMethod && currentMethod.length > 0) {
176
- routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
177
- }
178
- Object.assign(this, {
179
- [methodName]: function (...innerArgs: any[]) {
180
- this[hookKey](...innerArgs);
181
- return currentMethod.apply(this, innerArgs);
182
- }
183
- })
184
- });
185
- return;
186
- }
187
- const target = args[0];
188
- const propertyKey = args[1] as string;
189
- const currentMethod = targetBean[methodName];
190
- if(currentMethod.length > 0){
191
- routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
192
- }
193
- Object.assign(targetBean, {
194
- [methodName]: function (...innerArgs) {
195
- target[propertyKey](...innerArgs);
196
- return currentMethod.apply(targetBean, innerArgs);
197
- }
198
- })
199
- };
200
- }
201
-
202
- function after(constructorFunction, methodName: string) {
203
- const targetBean = getComponent(constructorFunction);
204
- return function (...args: any[]) {
205
- if (isStd(args)) {
206
- const [, ctx] = getStdArgs(args);
207
- const hookKey = String(ctx.name);
208
- ctx.addInitializer(function (this: any) {
209
- const currentMethod = this[methodName];
210
- if (currentMethod && currentMethod.length > 0) {
211
- routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
212
- }
213
- Object.assign(this, {
214
- [methodName]: function (...innerArgs: any[]) {
215
- const result = currentMethod.apply(this, innerArgs);
216
- const afterResult = this[hookKey](result);
217
- return afterResult ?? result;
218
- }
219
- })
220
- });
221
- return;
222
- }
223
- const target = args[0];
224
- const propertyKey = args[1] as string;
225
- const currentMethod = targetBean[methodName];
226
- if(currentMethod.length > 0){
227
- routerParamsTotal[[constructorFunction.name, methodName].toString()] = currentMethod.length;
228
- }
229
- Object.assign(targetBean, {
230
- [methodName]: function (...innerArgs) {
231
- const result = currentMethod.apply(targetBean, innerArgs);
232
- const afterResult = target[propertyKey](result);
233
- return afterResult ?? result;
234
- }
235
- })
236
- };
237
- }
238
-
239
- function req(target: any, propertyKey: string, parameterIndex: number) {
240
- const key = [target.constructor.name, propertyKey, parameterIndex].toString();
241
- routerParams[key] = (req, res, next) => req;
242
- }
243
-
244
- function res(target: any, propertyKey: string, parameterIndex: number) {
245
- const key = [target.constructor.name, propertyKey, parameterIndex].toString();
246
- routerParams[key] = (req, res, next) => res;
247
- }
248
-
249
- function next(target: any, propertyKey: string, parameterIndex: number) {
250
- const key = [target.constructor.name, propertyKey, parameterIndex].toString();
251
- routerParams[key] = (req, res, next) => next;
252
- }
253
-
254
- function reqBody(target: any, propertyKey: string, parameterIndex: number) {
255
- const key = [target.constructor.name, propertyKey, parameterIndex].toString();
256
- routerParams[key] = (req, res, next) => req.body;
257
- }
258
-
259
- function reqParam(target: any, propertyKey: string, parameterIndex: number) {
260
- const key = [target.constructor.name, propertyKey, parameterIndex].toString();
261
- const paramName = getParamInFunction(target[propertyKey], parameterIndex);
262
- routerParams[key] = (req, res, next) => req.params[paramName];
263
- }
264
-
265
- function getParamInFunction(fn: Function, index: number) {
266
- const code = fn.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '').replace(/=>.*$/mg, '').replace(/=[^,]+/mg, '');
267
- const result = code.slice(code.indexOf('(') + 1, code.indexOf(')')).match(/([^\s,]+)/g);
268
- return result[index] || null;
269
- }
270
-
271
- /** 解析函数参数名列表(供 route @bind 做「参数名 → 索引」映射) */
272
- function getParamNames(fn: Function): string[] {
273
- const code = fn.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '').replace(/=>.*$/mg, '').replace(/=[^,)]+/g, '');
274
- const paramsStr = code.slice(code.indexOf('(') + 1, code.indexOf(')'));
275
- if (!paramsStr.trim()) return [];
276
- return paramsStr.split(',').map(p => {
277
- const matched = p.trim().match(/([A-Za-z_$][\w$]*)/);
278
- return matched ? matched[1] : p.trim();
279
- }).filter(Boolean);
280
- }
281
-
282
- /** 把 route @bind 的「来源字符串」转成参数解析器 */
283
- function getRouteSourceResolver(source: string, paramName: string) {
284
- switch (source) {
285
- case "req": return (req, res, next) => req;
286
- case "res": return (req, res, next) => res;
287
- case "next": return (req, res, next) => next;
288
- case "reqBody": return (req, res, next) => req.body;
289
- case "reqParam": return (req, res, next) => req.params[paramName];
290
- case "reqQuery": return (req, res, next) => req.query[paramName];
291
- case "reqForm": return (req, res, next) => req.body[paramName];
292
- default: return null;
293
- }
294
- }
295
-
296
- /** 读取 @bind 声明,把「参数名 → 来源」转成 routerParams 的「索引 → 解析器」 */
297
- function applyRouteBind(className: string, propertyKey: string, method: Function) {
298
- const bindMapping = getBindMapping(className, propertyKey);
299
- if (!bindMapping) return;
300
- const paramNames = getParamNames(method);
301
- const nameToIndex: Record<string, number> = {};
302
- paramNames.forEach((paramName, index) => {
303
- if (paramName && nameToIndex[paramName] === undefined) nameToIndex[paramName] = index;
304
- });
305
- for (const bindName in bindMapping) {
306
- const source = bindMapping[bindName];
307
- if (typeof source !== "string") continue; // 跳过 database 的数值映射
308
- const index = nameToIndex[bindName];
309
- if (index === undefined) continue;
310
- const resolver = getRouteSourceResolver(source, bindName);
311
- if (resolver) {
312
- routerParams[[className, propertyKey, index].toString()] = resolver;
313
- }
314
- }
315
- }
316
-
317
- function reqQuery(target: any, propertyKey: string, parameterIndex: number) {
318
- const key = [target.constructor.name, propertyKey, parameterIndex].toString();
319
- const paramName = getParamInFunction(target[propertyKey], parameterIndex);
320
- routerParams[key] = (req, res, next) => req.query[paramName];
321
- }
322
-
323
- function reqForm(paramName: string) {
324
- return (target: any, propertyKey: string, parameterIndex: number) => {
325
- const key = [target.constructor.name, propertyKey, parameterIndex].toString();
326
- routerParams[key] = (req, res, next) => req.body[paramName];
327
- }
328
- }
329
-
330
- const getMapping = (value: string) => mapperFunction("get", value);
331
- const postMapping = (value: string) => mapperFunction("post", value);
332
- const requestMapping = (value: string) => mapperFunction("all", value);
333
-
334
- export { next, reqBody, reqQuery, reqForm, reqParam, req, req as request, res, res as response, before, after, getMapping, postMapping, requestMapping, setRouter, upload, jwt };