@ruiapp/rapid-core 0.11.3 → 0.11.4
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 +113 -106
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/core/routesBuilder.ts +91 -79
- package/src/types.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -983,8 +983,119 @@ function isNullOrUndefinedOrEmpty(val) {
|
|
|
983
983
|
return isNull(val) || isUndefined(val) || val === "";
|
|
984
984
|
}
|
|
985
985
|
|
|
986
|
-
|
|
986
|
+
/**
|
|
987
|
+
* 在事务中执行`func`
|
|
988
|
+
* @param routeContext
|
|
989
|
+
* @param func
|
|
990
|
+
* @returns
|
|
991
|
+
*/
|
|
992
|
+
async function executeInDbTransaction(routeContext, func) {
|
|
993
|
+
if (!routeContext) {
|
|
994
|
+
throw new Error(`Patameter "routeContext" is required if you want run in transaction.`);
|
|
995
|
+
}
|
|
996
|
+
let transactionDbClient;
|
|
997
|
+
try {
|
|
998
|
+
transactionDbClient = await routeContext.initDbTransactionClient();
|
|
999
|
+
await routeContext.beginDbTransaction();
|
|
1000
|
+
const result = await func();
|
|
1001
|
+
await routeContext.commitDbTransaction();
|
|
1002
|
+
return result;
|
|
1003
|
+
}
|
|
1004
|
+
catch (ex) {
|
|
1005
|
+
await routeContext.rollbackDbTransaction();
|
|
1006
|
+
throw ex;
|
|
1007
|
+
}
|
|
1008
|
+
finally {
|
|
1009
|
+
if (transactionDbClient) {
|
|
1010
|
+
transactionDbClient.release();
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
async function executeInRouteContext(routeContext, inDbTransaction, func) {
|
|
1015
|
+
if (inDbTransaction) {
|
|
1016
|
+
return await executeInDbTransaction(routeContext, func);
|
|
1017
|
+
}
|
|
1018
|
+
else {
|
|
1019
|
+
return await func();
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
async function executeHandlerOfActions(server, routeConfig, handlerContext) {
|
|
1024
|
+
let handler = routeConfig.handler;
|
|
1025
|
+
if (handler) {
|
|
1026
|
+
if (lodash.isString(handler)) {
|
|
1027
|
+
handler = new Function(`return (${routeConfig.handler})`);
|
|
1028
|
+
}
|
|
1029
|
+
if (lodash.isFunction(handler)) {
|
|
1030
|
+
const result = handler(handlerContext);
|
|
1031
|
+
if (result instanceof Promise) {
|
|
1032
|
+
await result;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
else {
|
|
1036
|
+
throw new Error(`Invalid handler for route ${routeConfig.code}: ${routeConfig.handler}`);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
else if (routeConfig.actions) {
|
|
1040
|
+
for (const actionConfig of routeConfig.actions) {
|
|
1041
|
+
const actionCode = actionConfig.code;
|
|
1042
|
+
const handler = server.getActionHandlerByCode(actionCode);
|
|
1043
|
+
if (!handler) {
|
|
1044
|
+
throw new Error("Unknown handler: " + actionCode);
|
|
1045
|
+
}
|
|
1046
|
+
await server.beforeRunActionHandler(handlerContext, actionConfig);
|
|
1047
|
+
const result = handler(handlerContext, actionConfig.config);
|
|
1048
|
+
if (result instanceof Promise) {
|
|
1049
|
+
await result;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
async function handleRouteRequest(routeContext, next, server, routeConfig) {
|
|
1055
|
+
if (!routeConfig.handler && !routeConfig.actions) {
|
|
1056
|
+
throw new Error(`No handler or actions defined for route ${routeConfig.code}`);
|
|
1057
|
+
}
|
|
987
1058
|
const logger = server.getLogger();
|
|
1059
|
+
routeConfig = lodash.cloneDeep(routeConfig);
|
|
1060
|
+
routeContext.routeConfig = routeConfig;
|
|
1061
|
+
const { request, params } = routeContext;
|
|
1062
|
+
let search = request.url.search;
|
|
1063
|
+
if (search && search.startsWith("?")) {
|
|
1064
|
+
search = search.substring(1);
|
|
1065
|
+
}
|
|
1066
|
+
const query = qs__default["default"].parse(search);
|
|
1067
|
+
const input = Object.assign({}, params, query);
|
|
1068
|
+
const requestMethod = request.method;
|
|
1069
|
+
if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
|
|
1070
|
+
const body = request.body;
|
|
1071
|
+
if (body) {
|
|
1072
|
+
Object.assign(input, body.value);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
// Normalize input value
|
|
1076
|
+
logger.debug("Processing rapid request.", {
|
|
1077
|
+
method: requestMethod,
|
|
1078
|
+
url: request.url.toString(),
|
|
1079
|
+
input,
|
|
1080
|
+
});
|
|
1081
|
+
routeContext.response.status = 200;
|
|
1082
|
+
let handlerContext = {
|
|
1083
|
+
logger,
|
|
1084
|
+
routerContext: routeContext,
|
|
1085
|
+
next,
|
|
1086
|
+
server,
|
|
1087
|
+
input,
|
|
1088
|
+
results: [],
|
|
1089
|
+
};
|
|
1090
|
+
await server.beforeRunRouteActions(handlerContext);
|
|
1091
|
+
await executeInRouteContext(routeContext, routeConfig.executeInDbTransaction, async () => {
|
|
1092
|
+
await executeHandlerOfActions(server, routeConfig, handlerContext);
|
|
1093
|
+
});
|
|
1094
|
+
if (!isNullOrUndefined(handlerContext.output)) {
|
|
1095
|
+
routeContext.json(handlerContext.output, handlerContext.status);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
async function buildRoutes(server, applicationConfig) {
|
|
988
1099
|
const router = new Router__default["default"]();
|
|
989
1100
|
let baseUrl = server.config.baseUrl;
|
|
990
1101
|
if (baseUrl) {
|
|
@@ -1000,74 +1111,7 @@ async function buildRoutes(server, applicationConfig) {
|
|
|
1000
1111
|
return;
|
|
1001
1112
|
}
|
|
1002
1113
|
const routePath = baseUrl + routeConfig.endpoint;
|
|
1003
|
-
router[routeConfig.method.toLowerCase()](routePath,
|
|
1004
|
-
routerContext.routeConfig = lodash.cloneDeep(routeConfig);
|
|
1005
|
-
const { request, params } = routerContext;
|
|
1006
|
-
let search = request.url.search;
|
|
1007
|
-
if (search && search.startsWith("?")) {
|
|
1008
|
-
search = search.substring(1);
|
|
1009
|
-
}
|
|
1010
|
-
const query = qs__default["default"].parse(search);
|
|
1011
|
-
const input = Object.assign({}, params, query);
|
|
1012
|
-
const requestMethod = request.method;
|
|
1013
|
-
if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
|
|
1014
|
-
const body = request.body;
|
|
1015
|
-
if (body) {
|
|
1016
|
-
Object.assign(input, body.value);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
// Normalize input value
|
|
1020
|
-
logger.debug("Processing rapid request.", {
|
|
1021
|
-
method: requestMethod,
|
|
1022
|
-
url: request.url.toString(),
|
|
1023
|
-
input,
|
|
1024
|
-
});
|
|
1025
|
-
routerContext.response.status = 200;
|
|
1026
|
-
let handlerContext = {
|
|
1027
|
-
logger,
|
|
1028
|
-
routerContext,
|
|
1029
|
-
next,
|
|
1030
|
-
server,
|
|
1031
|
-
input,
|
|
1032
|
-
results: [],
|
|
1033
|
-
};
|
|
1034
|
-
await server.beforeRunRouteActions(handlerContext);
|
|
1035
|
-
let handler = routeConfig.handler;
|
|
1036
|
-
if (handler) {
|
|
1037
|
-
if (lodash.isString(handler)) {
|
|
1038
|
-
handler = new Function(`return (${routeConfig.handler})`);
|
|
1039
|
-
}
|
|
1040
|
-
if (lodash.isFunction(handler)) {
|
|
1041
|
-
const result = handler(handlerContext);
|
|
1042
|
-
if (result instanceof Promise) {
|
|
1043
|
-
await result;
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
else {
|
|
1047
|
-
throw new Error(`Invalid handler for route ${routeConfig.code}: ${routeConfig.handler}`);
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
else if (routeConfig.actions) {
|
|
1051
|
-
for (const actionConfig of routeConfig.actions) {
|
|
1052
|
-
const actionCode = actionConfig.code;
|
|
1053
|
-
const handler = server.getActionHandlerByCode(actionCode);
|
|
1054
|
-
if (!handler) {
|
|
1055
|
-
throw new Error("Unknown handler: " + actionCode);
|
|
1056
|
-
}
|
|
1057
|
-
await server.beforeRunActionHandler(handlerContext, actionConfig);
|
|
1058
|
-
const result = handler(handlerContext, actionConfig.config);
|
|
1059
|
-
if (result instanceof Promise) {
|
|
1060
|
-
await result;
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
else {
|
|
1065
|
-
throw new Error(`No handler or actions defined for route ${routeConfig.code}`);
|
|
1066
|
-
}
|
|
1067
|
-
if (!isNullOrUndefined(handlerContext.output)) {
|
|
1068
|
-
routerContext.json(handlerContext.output, handlerContext.status);
|
|
1069
|
-
}
|
|
1070
|
-
});
|
|
1114
|
+
router[routeConfig.method.toLowerCase()](routePath, (routeContext, next) => handleRouteRequest(routeContext, next, server, routeConfig));
|
|
1071
1115
|
});
|
|
1072
1116
|
return router.routes();
|
|
1073
1117
|
}
|
|
@@ -5511,43 +5555,6 @@ var licenseHelper = /*#__PURE__*/Object.freeze({
|
|
|
5511
5555
|
tryValidateLicense: tryValidateLicense
|
|
5512
5556
|
});
|
|
5513
5557
|
|
|
5514
|
-
/**
|
|
5515
|
-
* 在事务中执行`func`
|
|
5516
|
-
* @param routeContext
|
|
5517
|
-
* @param func
|
|
5518
|
-
* @returns
|
|
5519
|
-
*/
|
|
5520
|
-
async function executeInDbTransaction(routeContext, func) {
|
|
5521
|
-
if (!routeContext) {
|
|
5522
|
-
throw new Error(`Patameter "routeContext" is required if you want run in transaction.`);
|
|
5523
|
-
}
|
|
5524
|
-
let transactionDbClient;
|
|
5525
|
-
try {
|
|
5526
|
-
transactionDbClient = await routeContext.initDbTransactionClient();
|
|
5527
|
-
await routeContext.beginDbTransaction();
|
|
5528
|
-
const result = await func();
|
|
5529
|
-
await routeContext.commitDbTransaction();
|
|
5530
|
-
return result;
|
|
5531
|
-
}
|
|
5532
|
-
catch (ex) {
|
|
5533
|
-
await routeContext.rollbackDbTransaction();
|
|
5534
|
-
throw ex;
|
|
5535
|
-
}
|
|
5536
|
-
finally {
|
|
5537
|
-
if (transactionDbClient) {
|
|
5538
|
-
transactionDbClient.release();
|
|
5539
|
-
}
|
|
5540
|
-
}
|
|
5541
|
-
}
|
|
5542
|
-
async function executeInRouteContext(routeContext, inDbTransaction, func) {
|
|
5543
|
-
if (inDbTransaction) {
|
|
5544
|
-
return await executeInDbTransaction(routeContext, func);
|
|
5545
|
-
}
|
|
5546
|
-
else {
|
|
5547
|
-
return await func();
|
|
5548
|
-
}
|
|
5549
|
-
}
|
|
5550
|
-
|
|
5551
5558
|
const values = new Map();
|
|
5552
5559
|
async function set(key, value, options) {
|
|
5553
5560
|
let expireAt = -1;
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -2,13 +2,101 @@ import Router from "koa-tree-router";
|
|
|
2
2
|
import qs from "qs";
|
|
3
3
|
import { ActionHandlerContext } from "~/core/actionHandler";
|
|
4
4
|
import { IRpdServer } from "~/core/server";
|
|
5
|
-
import { RpdApplicationConfig } from "~/types";
|
|
5
|
+
import { RpdApplicationConfig, RpdRoute } from "~/types";
|
|
6
6
|
import { isNullOrUndefined } from "~/utilities/typeUtility";
|
|
7
7
|
import { Next, RouteContext } from "./routeContext";
|
|
8
8
|
import { cloneDeep, isFunction, isString } from "lodash";
|
|
9
|
+
import { executeInRouteContext } from "~/helpers/dbTransactionHelper";
|
|
10
|
+
|
|
11
|
+
async function executeHandlerOfActions(server: IRpdServer, routeConfig: RpdRoute, handlerContext: ActionHandlerContext) {
|
|
12
|
+
let handler = routeConfig.handler as any;
|
|
13
|
+
if (handler) {
|
|
14
|
+
if (isString(handler)) {
|
|
15
|
+
handler = new Function(`return (${routeConfig.handler})`) as any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (isFunction(handler)) {
|
|
19
|
+
const result = handler(handlerContext);
|
|
20
|
+
if (result instanceof Promise) {
|
|
21
|
+
await result;
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
throw new Error(`Invalid handler for route ${routeConfig.code}: ${routeConfig.handler}`);
|
|
25
|
+
}
|
|
26
|
+
} else if (routeConfig.actions) {
|
|
27
|
+
for (const actionConfig of routeConfig.actions) {
|
|
28
|
+
const actionCode = actionConfig.code;
|
|
29
|
+
const handler = server.getActionHandlerByCode(actionCode);
|
|
30
|
+
if (!handler) {
|
|
31
|
+
throw new Error("Unknown handler: " + actionCode);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
await server.beforeRunActionHandler(handlerContext, actionConfig);
|
|
35
|
+
|
|
36
|
+
const result = handler(handlerContext, actionConfig.config);
|
|
37
|
+
if (result instanceof Promise) {
|
|
38
|
+
await result;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function handleRouteRequest(routeContext: RouteContext, next: Next, server: IRpdServer, routeConfig: RpdRoute) {
|
|
45
|
+
if (!routeConfig.handler && !routeConfig.actions) {
|
|
46
|
+
throw new Error(`No handler or actions defined for route ${routeConfig.code}`);
|
|
47
|
+
}
|
|
9
48
|
|
|
10
|
-
export async function buildRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig) {
|
|
11
49
|
const logger = server.getLogger();
|
|
50
|
+
routeConfig = cloneDeep(routeConfig);
|
|
51
|
+
routeContext.routeConfig = routeConfig;
|
|
52
|
+
const { request, params } = routeContext;
|
|
53
|
+
|
|
54
|
+
let search = request.url.search;
|
|
55
|
+
if (search && search.startsWith("?")) {
|
|
56
|
+
search = search.substring(1);
|
|
57
|
+
}
|
|
58
|
+
const query = qs.parse(search);
|
|
59
|
+
const input = Object.assign({}, params, query);
|
|
60
|
+
|
|
61
|
+
const requestMethod = request.method;
|
|
62
|
+
if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
|
|
63
|
+
const body = request.body;
|
|
64
|
+
if (body) {
|
|
65
|
+
Object.assign(input, body.value);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Normalize input value
|
|
70
|
+
|
|
71
|
+
logger.debug("Processing rapid request.", {
|
|
72
|
+
method: requestMethod,
|
|
73
|
+
url: request.url.toString(),
|
|
74
|
+
input,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
routeContext.response.status = 200;
|
|
78
|
+
|
|
79
|
+
let handlerContext: ActionHandlerContext = {
|
|
80
|
+
logger,
|
|
81
|
+
routerContext: routeContext,
|
|
82
|
+
next,
|
|
83
|
+
server,
|
|
84
|
+
input,
|
|
85
|
+
results: [],
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
await server.beforeRunRouteActions(handlerContext);
|
|
89
|
+
|
|
90
|
+
await executeInRouteContext(routeContext, routeConfig.executeInDbTransaction, async () => {
|
|
91
|
+
await executeHandlerOfActions(server, routeConfig, handlerContext);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (!isNullOrUndefined(handlerContext.output)) {
|
|
95
|
+
routeContext.json(handlerContext.output, handlerContext.status);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export async function buildRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig) {
|
|
12
100
|
const router = new Router();
|
|
13
101
|
|
|
14
102
|
let baseUrl = server.config.baseUrl;
|
|
@@ -27,83 +115,7 @@ export async function buildRoutes(server: IRpdServer, applicationConfig: RpdAppl
|
|
|
27
115
|
|
|
28
116
|
const routePath = baseUrl + routeConfig.endpoint;
|
|
29
117
|
|
|
30
|
-
(router as any)[routeConfig.method.toLowerCase()](routePath,
|
|
31
|
-
routerContext.routeConfig = cloneDeep(routeConfig);
|
|
32
|
-
const { request, params } = routerContext;
|
|
33
|
-
|
|
34
|
-
let search = request.url.search;
|
|
35
|
-
if (search && search.startsWith("?")) {
|
|
36
|
-
search = search.substring(1);
|
|
37
|
-
}
|
|
38
|
-
const query = qs.parse(search);
|
|
39
|
-
const input = Object.assign({}, params, query);
|
|
40
|
-
|
|
41
|
-
const requestMethod = request.method;
|
|
42
|
-
if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
|
|
43
|
-
const body = request.body;
|
|
44
|
-
if (body) {
|
|
45
|
-
Object.assign(input, body.value);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Normalize input value
|
|
50
|
-
|
|
51
|
-
logger.debug("Processing rapid request.", {
|
|
52
|
-
method: requestMethod,
|
|
53
|
-
url: request.url.toString(),
|
|
54
|
-
input,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
routerContext.response.status = 200;
|
|
58
|
-
|
|
59
|
-
let handlerContext: ActionHandlerContext = {
|
|
60
|
-
logger,
|
|
61
|
-
routerContext,
|
|
62
|
-
next,
|
|
63
|
-
server,
|
|
64
|
-
input,
|
|
65
|
-
results: [],
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
await server.beforeRunRouteActions(handlerContext);
|
|
69
|
-
|
|
70
|
-
let handler = routeConfig.handler as any;
|
|
71
|
-
if (handler) {
|
|
72
|
-
if (isString(handler)) {
|
|
73
|
-
handler = new Function(`return (${routeConfig.handler})`) as any;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (isFunction(handler)) {
|
|
77
|
-
const result = handler(handlerContext);
|
|
78
|
-
if (result instanceof Promise) {
|
|
79
|
-
await result;
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
throw new Error(`Invalid handler for route ${routeConfig.code}: ${routeConfig.handler}`);
|
|
83
|
-
}
|
|
84
|
-
} else if (routeConfig.actions) {
|
|
85
|
-
for (const actionConfig of routeConfig.actions) {
|
|
86
|
-
const actionCode = actionConfig.code;
|
|
87
|
-
const handler = server.getActionHandlerByCode(actionCode);
|
|
88
|
-
if (!handler) {
|
|
89
|
-
throw new Error("Unknown handler: " + actionCode);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
await server.beforeRunActionHandler(handlerContext, actionConfig);
|
|
93
|
-
|
|
94
|
-
const result = handler(handlerContext, actionConfig.config);
|
|
95
|
-
if (result instanceof Promise) {
|
|
96
|
-
await result;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
} else {
|
|
100
|
-
throw new Error(`No handler or actions defined for route ${routeConfig.code}`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if (!isNullOrUndefined(handlerContext.output)) {
|
|
104
|
-
routerContext.json(handlerContext.output, handlerContext.status);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
118
|
+
(router as any)[routeConfig.method.toLowerCase()](routePath, (routeContext, next) => handleRouteRequest(routeContext, next, server, routeConfig));
|
|
107
119
|
});
|
|
108
120
|
|
|
109
121
|
return router.routes();
|
package/src/types.ts
CHANGED