abler-api 0.1.15 → 0.1.18

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/README.md CHANGED
@@ -5,7 +5,7 @@ API服务相关工具
5
5
  安装
6
6
 
7
7
  ```
8
- npm i abler-api-util@latest -s
8
+ npm i abler-api@latest -s
9
9
  ```
10
10
 
11
11
 
@@ -13,8 +13,13 @@ npm i abler-api-util@latest -s
13
13
  引用
14
14
 
15
15
  ```
16
- const {apiUtil} = require("abler-api");
16
+ const {apiUtil, preconditions} = require("abler-api");
17
17
  apiUtil.config(conf,errCfg,dbSql);
18
18
  ...
19
19
  ```
20
20
 
21
+
22
+
23
+ ### preconditions
24
+
25
+ API服务启动时前置条件检查,使用
@@ -3,20 +3,27 @@
3
3
  var require$$0 = require('crypto');
4
4
  var require$$1 = require('abler-util');
5
5
  var require$$2 = require('abler-db');
6
+ var require$$3 = require('abler-net');
7
+ var require$$0$1 = require('fs');
8
+ var require$$1$1 = require('path');
6
9
 
7
10
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
11
 
9
12
  var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
10
13
  var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1);
11
14
  var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2);
15
+ var require$$3__default = /*#__PURE__*/_interopDefaultLegacy(require$$3);
16
+ var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
17
+ var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
12
18
 
13
19
  const crypto = require$$0__default["default"];
14
- const ppUtil$1 = require$$1__default["default"].ppUtil;
20
+ const ppUtil$2 = require$$1__default["default"].ppUtil;
15
21
  const {
16
22
  dbUtil,
17
23
  kvStorage
18
24
  } = require$$2__default["default"];
19
- let conf, appSetting, err, dbSql;
25
+ const netUtil = require$$3__default["default"];
26
+ let conf$1, appSetting, err$1, dbSql;
20
27
  const pnToken = "access_token",
21
28
  hnToken = pnToken,
22
29
  pnApiKey = "apiKey",
@@ -24,20 +31,20 @@ const pnToken = "access_token",
24
31
  // 我们接收到的 headers 中的字段名总是全小写的
25
32
  pnApiSecret = "apiSecret",
26
33
  hnApiSecret = pnApiSecret.toLowerCase();
27
- const MD5 = ppUtil$1.MD5,
28
- moveProperty = ppUtil$1.moveProperty;
34
+ const MD5 = ppUtil$2.MD5,
35
+ moveProperty = ppUtil$2.moveProperty;
29
36
 
30
37
  class apiUtil$1 {
31
- static debugFlag = ppUtil$1.newGuid(); //应用必须设置,否则谁也不知道是啥
38
+ static debugFlag = ppUtil$2.newGuid(); //应用必须设置,否则谁也不知道是啥
32
39
 
33
- static testFlag = ppUtil$1.newGuid();
40
+ static testFlag = ppUtil$2.newGuid();
34
41
  static envId_dev = "?"; // static apiCallRecSaver;
35
42
 
36
43
  static config(appConfig, appErrCfg, appDbSql) {
37
- ppUtil$1.config(appConfig, appErrCfg);
38
- conf = appConfig;
39
- appSetting = conf?.appSetting;
40
- err = appErrCfg, dbSql = appDbSql;
44
+ ppUtil$2.config(appConfig, appErrCfg);
45
+ conf$1 = appConfig;
46
+ appSetting = conf$1?.appSetting;
47
+ err$1 = appErrCfg, dbSql = appDbSql;
41
48
  apiUtil$1.debugFlag = appSetting?.debugFlag || apiUtil$1.debugFlag;
42
49
  apiUtil$1.testFlag = appSetting?.testFlag || apiUtil$1.testFlag; // apiUtil.apiCallRecSaver = apiCallRecSaver;
43
50
  } //#region ===== 需要应用系统重写的方法
@@ -50,7 +57,7 @@ class apiUtil$1 {
50
57
 
51
58
 
52
59
  static _getApiSecret(companyId) {
53
- return ppUtil$1.newGuid();
60
+ return ppUtil$2.newGuid();
54
61
  }
55
62
  /**
56
63
  * 保存 API 调用记录,应用系统必须重写此方法
@@ -74,26 +81,6 @@ class apiUtil$1 {
74
81
  } //#endregion
75
82
  //#region ===== API服务相关工具
76
83
 
77
- /**
78
- * 获取客户端IP地址
79
- * @param req
80
- * @returns {*|string|string}
81
- */
82
-
83
-
84
- static getClientIp(req) {
85
- let ip = req.headers["x-real-ip"] || req.headers["x-true-ip"] || req.headers['x-forwarded-for'] || req.headers['x-forward-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.headers['host'] || ""; // console.log("Request IP:", ip, "req: ", req);
86
-
87
- if (ip.indexOf(",") >= 0) {
88
- ip = ip.split(',')[0];
89
- }
90
-
91
- if (ip.indexOf(":") >= 0) {
92
- ip = ip.substring(ip.lastIndexOf(':') + 1);
93
- }
94
-
95
- return ip;
96
- }
97
84
  /**
98
85
  * 从请求中解出数据,包括路径参数、查询参数和Body
99
86
  * @param req
@@ -173,18 +160,18 @@ class apiUtil$1 {
173
160
 
174
161
 
175
162
  static setParamsFunctions(params) {
176
- ppUtil$1.defUnenumProp(params, "asNumber", function (name, minValue, maxValue, defaultValue) {
163
+ ppUtil$2.defUnenumProp(params, "asNumber", function (name, minValue, maxValue, defaultValue) {
177
164
  // if (!this.hasOwnProperty(name)) // {} 定义的对象没有 hasOwnProperty 函数
178
165
  if (this[name] === undefined) return defaultValue;
179
166
  let result = +this[name];
180
167
 
181
168
  if (typeof result !== "number" || result < minValue || result > maxValue) {
182
- throw [err.INVALID_PARAM, `参数 ${name} 必须是 ${minValue} ~ ${maxValue} 之间的数字`];
169
+ throw [err$1.INVALID_PARAM, `参数 ${name} 必须是 ${minValue} ~ ${maxValue} 之间的数字`];
183
170
  }
184
171
 
185
172
  return result;
186
173
  });
187
- ppUtil$1.defUnenumProp(params, "asBool", function (name, defaultValue) {
174
+ ppUtil$2.defUnenumProp(params, "asBool", function (name, defaultValue) {
188
175
  if (this[name] === undefined) return defaultValue;
189
176
  let result = JSON.parse(this[name]);
190
177
  return !!result;
@@ -249,7 +236,7 @@ class apiUtil$1 {
249
236
 
250
237
  static apiFail(error, req) {
251
238
  configNeeded();
252
- let response = err.ERROR(error, err.errorLangParamFlag + ppUtil$1.getMsgLang(req));
239
+ let response = err$1.ERROR(error, err$1.errorLangParamFlag + ppUtil$2.getMsgLang(req));
253
240
  response.datetime = new Date();
254
241
 
255
242
  if (req && req.headers) {
@@ -470,12 +457,12 @@ class apiUtil$1 {
470
457
  delete params.token;
471
458
  } else {
472
459
  // 如果没有token,则返回错误
473
- console.log(err.TOKEN_NEEDED);
460
+ console.log(err$1.TOKEN_NEEDED);
474
461
 
475
462
  if (res) {
476
- res.send(err.ERROR(err.TOKEN_NEEDED));
463
+ res.send(err$1.ERROR(err$1.TOKEN_NEEDED));
477
464
  } else if (!noErr) {
478
- throw err.TOKEN_NEEDED;
465
+ throw err$1.TOKEN_NEEDED;
479
466
  }
480
467
  }
481
468
  }
@@ -497,7 +484,7 @@ class apiUtil$1 {
497
484
  const params = apiUtil$1.extractParams(req);
498
485
  req.accessToken = req.accessToken || apiUtil$1.extractToken(req);
499
486
 
500
- if (req.accessToken === MD5(ppUtil$1.idNumDisturbing)) {
487
+ if (req.accessToken === MD5(ppUtil$2.idNumDisturbing)) {
501
488
  //todo: 检查IP
502
489
  params.__internal__ = true;
503
490
  req.ignoreToken = true; // if (params.idNum || params.personId) {
@@ -518,7 +505,7 @@ class apiUtil$1 {
518
505
  return true;
519
506
  } else {
520
507
  // console.log('token error.', req.accessToken);
521
- throw err.TOKEN_INVALID;
508
+ throw err$1.TOKEN_INVALID;
522
509
  }
523
510
  }
524
511
  /**
@@ -532,7 +519,6 @@ class apiUtil$1 {
532
519
  req.accessToken = req.accessToken || apiUtil$1.extractToken(req);
533
520
  const tokenKey = apiUtil$1.userTokenStoreKey(req.accessToken);
534
521
  const expireTime = apiUtil$1.tokenExpireTime(req);
535
- await apiUtil$1.restoreTokenData(tokenKey, expireTime);
536
522
  return await apiUtil$1.restoreTokenData(tokenKey, expireTime).then(async function (data) {
537
523
  req.userInfo = apiUtil$1.setUserIdNo(data, data._idNo);
538
524
  if (req.tokenValidater) await req.tokenValidater(req.userInfo, req);
@@ -555,7 +541,7 @@ class apiUtil$1 {
555
541
 
556
542
  if (dbgToken) {
557
543
  let envId = process.env.ECS_DEPLOY_ID;
558
- req.__debug__ = dbgToken && dbgToken === MD5(req.headers.timestamp, ppUtil$1.commonHashDisturbing) && (envId === "florist_longdan" || envId === "shuzi");
544
+ req.__debug__ = dbgToken && dbgToken === MD5(req.headers.timestamp, ppUtil$2.commonHashDisturbing) && (envId === "florist_longdan" || envId === "shuzi");
559
545
  } else {
560
546
  req.__debug__ = false;
561
547
  } // console.log("__debug__:", req.__debug__, "dbgToken:", dbgToken);
@@ -735,7 +721,7 @@ class apiUtil$1 {
735
721
  };
736
722
 
737
723
  if (rec.secret !== "") {
738
- rec.secret = ppUtil$1.getEncAse192(rec.secret);
724
+ rec.secret = ppUtil$2.getEncAse192(rec.secret);
739
725
  }
740
726
 
741
727
  req.apiCallRec = rec;
@@ -802,7 +788,7 @@ class apiUtil$1 {
802
788
  return certInfo;
803
789
  }).catch(e => {
804
790
  console.log('获取企业证书失败:\n', e);
805
- throw [err.ACCESS_REFUSED, `获取企业证书失败:${err.ERROR(e).message}`];
791
+ throw [err$1.ACCESS_REFUSED, `获取企业证书失败:${err$1.ERROR(e).message}`];
806
792
  });
807
793
  }
808
794
  /**
@@ -816,7 +802,7 @@ class apiUtil$1 {
816
802
  static async verifyApiSignature(tokenData, req) {
817
803
  try {
818
804
  if (!req.headers.timestamp) {
819
- throw [err.ACCESS_REFUSED, `必须在请求头中设置时戳`];
805
+ throw [err$1.ACCESS_REFUSED, `必须在请求头中设置时戳`];
820
806
  }
821
807
 
822
808
  let timestamp = parseInt(req.headers.timestamp);
@@ -824,13 +810,13 @@ class apiUtil$1 {
824
810
  let maxTimeDiff = apiUtil$1.isDebugMode(req) ? 7 * 24 * 3600 : apiUtil$1.isTestMode(req) ? 4 * 3600 : 100; // 100
825
811
 
826
812
  if (timestamp.toString() == "NaN" || currentTime < timestamp - 5000 || currentTime - timestamp > maxTimeDiff * 1000) {
827
- throw [err.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
813
+ throw [err$1.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
828
814
  }
829
815
 
830
816
  let signature = req.headers.signature;
831
817
 
832
818
  if (!signature) {
833
- throw [err.ACCESS_REFUSED, `必须在请求头中提供签名`];
819
+ throw [err$1.ACCESS_REFUSED, `必须在请求头中提供签名`];
834
820
  }
835
821
 
836
822
  let signData = apiUtil$1.extractToken(req, null, true) || tokenData.apiKey;
@@ -885,7 +871,7 @@ class apiUtil$1 {
885
871
 
886
872
  if (!tokenData.certPublicKeySpare) {
887
873
  throw {
888
- eo: err.ACCESS_REFUSED,
874
+ eo: err$1.ACCESS_REFUSED,
889
875
  msgArgv: "签名验证异常",
890
876
  data: e
891
877
  };
@@ -934,7 +920,7 @@ class apiUtil$1 {
934
920
  } catch (e) {
935
921
  console.log("SPO服务签名验证异常(备用证书), ", e);
936
922
  throw {
937
- eo: err.ACCESS_REFUSED,
923
+ eo: err$1.ACCESS_REFUSED,
938
924
  msgArgv: "签名验证异常(spare)",
939
925
  data: e
940
926
  };
@@ -943,7 +929,7 @@ class apiUtil$1 {
943
929
 
944
930
  if (!verifyOK) {
945
931
  console.log("SPO服务签名验证失败, tokenData: ", tokenData);
946
- throw [err.ACCESS_REFUSED, "签名验证未通过"];
932
+ throw [err$1.ACCESS_REFUSED, "签名验证未通过"];
947
933
  }
948
934
 
949
935
  return verifyOK;
@@ -961,7 +947,7 @@ class apiUtil$1 {
961
947
  if (!tokenData.companyInfo) {
962
948
  tokenData.companyInfo = await apiUtil$1.queryCompanyInfo(tokenData.apiKey, true).catch(e => {
963
949
  console.log("执行企业信息查询发生异常", e);
964
- throw [err.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
950
+ throw [err$1.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
965
951
  });
966
952
  }
967
953
 
@@ -970,7 +956,7 @@ class apiUtil$1 {
970
956
  if (companyInfo != null) {
971
957
  let secret = apiUtil$1._getApiSecret(tokenData.apiKey);
972
958
 
973
- if (secret !== tokenData.apiSecret) throw err.API_SCREPT_INVALID; // 不再检查 IP 白名单,改为验证证书签名
959
+ if (secret !== tokenData.apiSecret) throw err$1.API_SCREPT_INVALID; // 不再检查 IP 白名单,改为验证证书签名
974
960
  // console.log("fromIp:", tokenData.clientIp, "ipWhiteList:", companyInfo.ipWhiteList);
975
961
  // let whiteList = companyInfo.ipWhiteList || "";
976
962
  // // 没有设置ip白名单的就不检查了
@@ -984,7 +970,7 @@ class apiUtil$1 {
984
970
  });
985
971
  }
986
972
 
987
- throw [err.API_KEY_INVALID, tokenData.apiKey];
973
+ throw [err$1.API_KEY_INVALID, tokenData.apiKey];
988
974
  }
989
975
  /**
990
976
  * 检查令牌数据是否存在
@@ -1035,10 +1021,152 @@ class apiUtil$1 {
1035
1021
  paramExists = typeof params[paramName] != 'undefined' || typeof params[paramName + paramSufix] != 'undefined';
1036
1022
  }
1037
1023
 
1038
- if (!paramExists) return ppUtil$1.errorPormise(err.ERROR(err.PARAMETER_NEEDED, paramName));
1024
+ if (!paramExists) return ppUtil$2.errorPormise(err$1.ERROR(err$1.PARAMETER_NEEDED, paramName));
1039
1025
  }
1040
1026
 
1041
1027
  return Promise.resolve(paramSufix);
1028
+ }
1029
+ /**
1030
+ * 获取客户端IP地址
1031
+ * @param req
1032
+ * @returns {*|string|string}
1033
+ */
1034
+
1035
+
1036
+ static getClientIp(req) {
1037
+ let ip = req.headers["x-real-ip"] || req.headers["x-true-ip"] || req.headers['x-forwarded-for'] || req.headers['x-forward-for'] || req.connection.remoteAddress || req.socket.remoteAddress || req.headers['host'] || ""; // console.log("Request IP:", ip, "req: ", req);
1038
+
1039
+ if (ip.indexOf(",") >= 0) {
1040
+ ip = ip.split(',')[0];
1041
+ }
1042
+
1043
+ if (ip.indexOf(":") >= 0) {
1044
+ ip = ip.substring(ip.lastIndexOf(':') + 1);
1045
+ }
1046
+
1047
+ return ip;
1048
+ }
1049
+ /**
1050
+ * 获取与本机一起提供服务的所有主机
1051
+ * @param params
1052
+ * @returns {{port: (number|number), hosts: [string]}}
1053
+ */
1054
+
1055
+
1056
+ static getEnvHosts(params) {
1057
+ configNeeded();
1058
+ let envType = ppUtil$2.getEnvType();
1059
+ let x = conf$1.envHosts[envType] || {
1060
+ hosts: ["localhost"]
1061
+ };
1062
+ let port = +params.port || 8443;
1063
+ return {
1064
+ hosts: x.hosts,
1065
+ port: x.port || port
1066
+ };
1067
+ }
1068
+ /**
1069
+ * 检查指定的host和发送请求的ip是不是自己的ip
1070
+ * @param host
1071
+ * @param req
1072
+ * @returns {Promise<*>}
1073
+ */
1074
+
1075
+
1076
+ static async hostIsMySelf(host, req) {
1077
+ let clientIp = apiUtil$1.getClientIp(req);
1078
+ return getMyIp({
1079
+ hosts: [host, clientIp]
1080
+ });
1081
+ }
1082
+ /**
1083
+ * 检查是否应该把请求转发到其它服务器,若是则转发
1084
+ * @param options
1085
+ * @returns {Promise<boolean>}
1086
+ */
1087
+
1088
+
1089
+ static async checkForwardsHost(options) {
1090
+ configNeeded();
1091
+ const params = options.replacements;
1092
+ const myEnvHosts = apiUtil$1.getEnvHosts(params);
1093
+ const myIp = ppUtil$2.getMyIp();
1094
+ const host = params.host || myIp;
1095
+ if (!myEnvHosts.hosts.contains(host)) throw [err$1.ACCESS_REFUSED, `环境${conf$1.envId}貌似无此主机:${params.host}`];
1096
+
1097
+ if (!apiUtil$1.hostIsMySelf(host, options._res.req)) {
1098
+ let result = await apiUtil$1.forwardsTo(host, myEnvHosts.port, params, options._res.req, myIp);
1099
+
1100
+ options._res.send(result);
1101
+
1102
+ return true;
1103
+ }
1104
+
1105
+ return false;
1106
+ }
1107
+ /**
1108
+ * 将收到的请求转发到另一台主机
1109
+ * @param anotherIp
1110
+ * @param port
1111
+ * @param params
1112
+ * @param req
1113
+ * @param lanClient
1114
+ * @returns {Promise<*>}
1115
+ */
1116
+
1117
+
1118
+ static async forwardsTo(anotherIp, port, params, req, lanClient) {
1119
+ let url = anotherIp.indexOf("://") > 0 ? anotherIp : `${req.headers.scheme}://${anotherIp}:${port}${req.originalUrl}`;
1120
+
1121
+ if (url.indexOf("?") > 0) {
1122
+ url = url.substring(0, url.indexOf("?"));
1123
+ }
1124
+
1125
+ let reqOptions = {
1126
+ method: req.method,
1127
+ url: url,
1128
+ data: params
1129
+ };
1130
+ let result = await netUtil.apiRequest(reqOptions);
1131
+
1132
+ if (result.status !== 200) {
1133
+ console.log(`访问 ${reqOptions.url} 出错`, result.status, result.res.statusMessage);
1134
+ throw [err$1.EXCEPTION, `[${result.status}] - ${result.res.statusMessage}`];
1135
+ }
1136
+
1137
+ return result.data;
1138
+ }
1139
+ /**
1140
+ * 解析配置项路径
1141
+ * @param keyPath
1142
+ * @returns {{parent: null, parentKey: string, value, key: string}}
1143
+ */
1144
+
1145
+
1146
+ static parseCfgPath(keyPath) {
1147
+ let keys = Array.isArray(keyPath) ? keyPath : keyPath.split(".");
1148
+ let parentKey = "";
1149
+ let key = "config";
1150
+ let value = conf$1;
1151
+ let parent = null;
1152
+
1153
+ for (let i = 0; i < keys.length; i++) {
1154
+ parent = value;
1155
+ parentKey += (parentKey ? "." : "") + key;
1156
+ key = keys[i];
1157
+ value = parent[key];
1158
+
1159
+ if (value === undefined) {
1160
+ throw [err$1.INVALID_PARAM, `无此配置项: ${key}`];
1161
+ }
1162
+ }
1163
+
1164
+ return {
1165
+ parent,
1166
+ parentKey,
1167
+ key,
1168
+ value
1169
+ };
1042
1170
  } //#endregion
1043
1171
  //region ====中间件
1044
1172
 
@@ -1052,7 +1180,7 @@ class apiUtil$1 {
1052
1180
  await apiUtil$1.checkRequestToken(req);
1053
1181
  await next();
1054
1182
  } catch (e) {
1055
- res.send(err.ERROR(e));
1183
+ res.send(err$1.ERROR(e));
1056
1184
  }
1057
1185
 
1058
1186
  return false;
@@ -1100,7 +1228,7 @@ class apiUtil$1 {
1100
1228
 
1101
1229
  return true;
1102
1230
  } catch (e) {
1103
- res.send(err.ERROR(e));
1231
+ res.send(err$1.ERROR(e));
1104
1232
  return false;
1105
1233
  }
1106
1234
  }
@@ -1150,11 +1278,11 @@ class apiUtil$1 {
1150
1278
  let errResponse = null;
1151
1279
 
1152
1280
  if (!tokenData.clientIp) {
1153
- errResponse = apiUtil$1.spoApiFail(err.GET_CLIENTIP_FAIL, req);
1281
+ errResponse = apiUtil$1.spoApiFail(err$1.GET_CLIENTIP_FAIL, req);
1154
1282
  } else if (!tokenData.apiKey) {
1155
- errResponse = apiUtil$1.spoApiFail([err.PARAMETER_NEEDED, "apiKey"], req);
1283
+ errResponse = apiUtil$1.spoApiFail([err$1.PARAMETER_NEEDED, "apiKey"], req);
1156
1284
  } else if (!tokenData.apiSecret) {
1157
- errResponse = apiUtil$1.spoApiFail([err.PARAMETER_NEEDED, "apiSecret"], req);
1285
+ errResponse = apiUtil$1.spoApiFail([err$1.PARAMETER_NEEDED, "apiSecret"], req);
1158
1286
  }
1159
1287
 
1160
1288
  if (errResponse != null) {
@@ -1190,7 +1318,7 @@ class apiUtil$1 {
1190
1318
  let accessToken = apiUtil$1.extractToken(req);
1191
1319
 
1192
1320
  if (!accessToken) {
1193
- res.send(apiUtil$1.spoApiFail(err.TOKEN_NEEDED, req)); // apiUtil.sendOrRedirect(req, res, spoApiFail(err.TOKEN_NEEDED, req));
1321
+ res.send(apiUtil$1.spoApiFail(err$1.TOKEN_NEEDED, req)); // apiUtil.sendOrRedirect(req, res, spoApiFail(err.TOKEN_NEEDED, req));
1194
1322
 
1195
1323
  return;
1196
1324
  }
@@ -1211,7 +1339,7 @@ class apiUtil$1 {
1211
1339
  req.tokenData = p;
1212
1340
  return apiUtil$1.$checkApiKeyOld(req, res, next);
1213
1341
  }).catch(e => {
1214
- apiUtil$1.sendOrRedirect(req, res, apiUtil$1.spoApiFail(err.TOKEN_INVALID, req));
1342
+ apiUtil$1.sendOrRedirect(req, res, apiUtil$1.spoApiFail(err$1.TOKEN_INVALID, req));
1215
1343
  });
1216
1344
  }
1217
1345
  /**
@@ -1246,24 +1374,247 @@ class apiUtil$1 {
1246
1374
  });
1247
1375
  }
1248
1376
  } //#endregion
1377
+ //region ====一些通用服务功能
1378
+
1379
+ /**
1380
+ * 获取配置数据
1381
+ * @param options
1382
+ * @returns {Promise<boolean|*>}
1383
+ */
1384
+ // api/config/appSetting.ossEnabled
1385
+
1386
+
1387
+ static async getConfigValue(options) {
1388
+ configNeeded();
1389
+ const params = options.replacements;
1390
+ let item = params.item;
1391
+ delete params.item;
1392
+ if (await apiUtil$1.checkForwardsHost(options)) return true;
1393
+ let c = apiUtil$1.parseCfgPath(item);
1394
+ delete c.parent;
1395
+ c.host = ppUtil$2.getMyIp();
1396
+ return c;
1397
+ }
1398
+ /**
1399
+ * 设置配置数据
1400
+ * @param options
1401
+ * @returns {Promise<*>}
1402
+ */
1403
+
1404
+
1405
+ static async setConfigValue(options) {
1406
+ configNeeded();
1407
+ const params = options.replacements;
1408
+ let item = params.item;
1409
+ delete params.item; // if (await checkForwardsHost(options))
1410
+ // return true;
1411
+
1412
+ await apiUtil$1.parametersOK(params, "value");
1413
+ let c = apiUtil$1.parseCfgPath(item);
1414
+
1415
+ if (typeof c.value === "object") {
1416
+ throw [err$1.ACCESS_REFUSED, `暂不支持修改复杂配置`];
1417
+ } // c.oldValue = c.value;
1418
+
1419
+
1420
+ c.newValue = params.value;
1421
+ c.parent[c.key] = c.newValue;
1422
+ delete c.parent;
1423
+ c.host = ppUtil$2.getMyIp();
1424
+ return c; // 应用层自行处理多机同步
1425
+ } //#endregion
1249
1426
 
1250
1427
 
1251
1428
  }
1252
1429
 
1253
1430
  function configNeeded() {
1254
- if (!conf || !err) {
1431
+ if (!conf$1 || !err$1) {
1432
+ ppUtil$2.configNeeded();
1433
+ conf$1 = ppUtil$2.appConfig;
1434
+ appSetting = conf$1.appSetting;
1435
+ err$1 = ppUtil$2.appErrCfg;
1436
+ }
1437
+ }
1438
+
1439
+ var ppUtilApi = apiUtil$1;
1440
+
1441
+ function commonjsRequire(path) {
1442
+ throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
1443
+ }
1444
+
1445
+ const fs = require$$0__default$1["default"];
1446
+ const path = require$$1__default$1["default"];
1447
+ const ppUtil$1 = require$$1__default["default"].ppUtil;
1448
+ const redisUtil = require$$2__default["default"].redisUtil;
1449
+ let conf, err; // const dbCheck = require('../dbupdate/dd-version');
1450
+
1451
+ /**
1452
+ * API服务启动时前置条件检查
1453
+ * ok = await preconditions
1454
+ * .setAppName(conf.thisApp)
1455
+ * .addCheckPromise(preconditions.checkExEnvSetting())
1456
+ * .addCheckPromise(preconditions.checkRedis())
1457
+ * .addCheckPromise(checkDatabase())
1458
+ * .addChecker(myChecker, args)
1459
+ * .checkAll()
1460
+ */
1461
+
1462
+ class preconditions$1 {
1463
+ static appName;
1464
+ static checkFunctions = [];
1465
+ static checkPromises = [];
1466
+
1467
+ static setAppName(aName) {
1255
1468
  ppUtil$1.configNeeded();
1256
1469
  conf = ppUtil$1.appConfig;
1257
- appSetting = conf.appSetting;
1258
1470
  err = ppUtil$1.appErrCfg;
1471
+ preconditions$1.appName = aName || conf.thisApp;
1472
+ return preconditions$1;
1473
+ }
1474
+
1475
+ static addCheckPromise(p) {
1476
+ preconditions$1.checkPromises.push(p);
1477
+ return preconditions$1;
1478
+ }
1479
+
1480
+ static addChecker(checkFunc, args) {
1481
+ preconditions$1.checkFunctions.push({
1482
+ check: checkFunc,
1483
+ args: args
1484
+ });
1485
+ return preconditions$1;
1486
+ }
1487
+
1488
+ static async checkAll() {
1489
+ for (let i = 0; i < preconditions$1.checkFunctions.length; i++) {
1490
+ const f = preconditions$1.checkFunctions[i];
1491
+ preconditions$1.addCheckPromise(f.check(f.args));
1492
+ }
1493
+
1494
+ for (let i = 0; i < preconditions$1.checkPromises.length; i++) {
1495
+ let msg = await preconditions$1.checkPromises[i];
1496
+
1497
+ if (msg) {
1498
+ if (!preconditions$1.messages) {
1499
+ preconditions$1.messages = [];
1500
+ }
1501
+
1502
+ preconditions$1.messages.push(`${preconditions$1.messages.length + 1}. ${msg}`);
1503
+ }
1504
+ }
1505
+
1506
+ let text = "";
1507
+
1508
+ if (preconditions$1.messages) {
1509
+ text = `*** 由于以下原因,${preconditions$1.appName} 尚不能正常提供服务:\n\n` + preconditions$1.messages.join("\n\n") + "\n\n*** 请检查以上各项条件,修复后重新启动服务";
1510
+ console.log("\n" + text); // for (let i = 0; i < preconditions.messages.length; i++) {
1511
+ // console.log(preconditions.messages[i]);
1512
+ // }
1513
+ }
1514
+
1515
+ if (!(await fs.async_exists("../log"))) {
1516
+ await fs.async_mkdir("../log");
1517
+ }
1518
+
1519
+ await fs.async_writeFile(`../log/preconditions`, text);
1520
+ return text === " ";
1521
+ } // 检查器
1522
+
1523
+ /**
1524
+ * 检查本机外部配置文件版本
1525
+ */
1526
+
1527
+
1528
+ static async checkExEnvSetting() {
1529
+ return await checkExEnvSetting();
1259
1530
  }
1531
+ /**
1532
+ * redis 可用性检查
1533
+ */
1534
+
1535
+
1536
+ static async checkRedis() {
1537
+ return await checkRedis();
1538
+ } // /**
1539
+ // * 数据库可用性及业务数据版本版本检查
1540
+ // */
1541
+ // static async checkDatabase() {
1542
+ // return await checkDatabase();
1543
+ // }
1544
+
1545
+
1260
1546
  }
1261
1547
 
1262
- var ppUtilApi = apiUtil$1;
1548
+ async function createEnvSettingFile(fileName) {
1549
+ try {
1550
+ const cfgText = await ppUtil$1.doCreateEnvSettingFile(fileName);
1551
+
1552
+ if (cfgText.indexOf(`cfgVersion: "${conf._envSetting.cfgVersion}"`) > 0) {
1553
+ console.log(`\n*** 已創建新的本機環境配置文件\n${fileName}\n请檢查各項內容是否正确(此项更新服务可正常运行)\n\n`);
1554
+ return "";
1555
+ }
1556
+
1557
+ return `已創建新的本機環境配置文件\n${fileName}\n请檢查並正確設置各項內容,然後將配置版本號修改為${conf._envSettings.default.cfgVersion}`;
1558
+ } catch (e) {
1559
+ return `創建本機環境配置文件失敗\n《${fileName}》\n${err.ERROR(e).message}`;
1560
+ }
1561
+ }
1562
+
1563
+ async function checkExEnvSetting() {
1564
+ if (!conf._envSetting.localSettingImported) {
1565
+ let fileName = conf.getEnvSettingFileName();
1566
+
1567
+ if (!fs.existsSync(fileName)) {
1568
+ return await createEnvSettingFile(fileName);
1569
+ }
1570
+
1571
+ let envSettingEx = commonjsRequire(fileName);
1572
+
1573
+ if (envSettingEx.cfgVersion !== conf._envSettings.default.cfgVersion) {
1574
+ if (envSettingEx.cfgVersion !== "0.0") {
1575
+ let fp = path.parse(fileName);
1576
+ let newFileName = path.join(fp.dir, fp.name + envSettingEx.cfgVersion + fp.ext);
1577
+
1578
+ if (!fs.existsSync(newFileName)) {
1579
+ fs.renameSync(fileName, newFileName);
1580
+ }
1581
+ }
1582
+
1583
+ return await createEnvSettingFile(fileName);
1584
+ }
1585
+ }
1586
+ } // async function checkDatabase() {
1587
+ // return dbCheck.check().then(info => info.updateMessage);
1588
+ // }
1589
+
1590
+
1591
+ async function checkRedis() {
1592
+ if (!conf.redis.enabled) return "";
1593
+ const redis = redisUtil.newClient("io"); // console.log(`checkRedis begin:`);
1594
+
1595
+ await ppUtil$1.wait(15 * 1000, param => {
1596
+ if (redis.ready && redis.connected || redis.error) {
1597
+ return true;
1598
+ }
1599
+ }).catch(e => {
1600
+ redis.error = e;
1601
+ });
1602
+
1603
+ if (redis.error) {
1604
+ console.log(`未能成功連接 redis: ${redis.error},請檢查相關設置`);
1605
+ return `未能成功連接 redis: ${redis.error},請檢查相關設置`;
1606
+ } // console.log(`checkRedis done:`);
1607
+ // console.log(redis);
1608
+
1609
+ }
1610
+
1611
+ var ppPrecond = preconditions$1;
1263
1612
 
1264
1613
  const apiUtil = ppUtilApi;
1614
+ const preconditions = ppPrecond;
1265
1615
  var ppUtil = {
1266
- apiUtil
1616
+ apiUtil,
1617
+ preconditions
1267
1618
  };
1268
1619
 
1269
1620
  module.exports = ppUtil;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abler-api",
3
- "version": "0.1.15",
3
+ "version": "0.1.18",
4
4
  "description": "API服务相关工具",
5
5
  "main": "./dist/cjs/pp-util.js",
6
6
  "-module": "./dist/es/pp-util.js",
@@ -16,7 +16,8 @@
16
16
  "dependencies": {
17
17
  "q": "^1.5.1",
18
18
  "abler-util": ">=0.1.1",
19
- "abler-db": ">=0.1.1"
19
+ "abler-db": ">=0.1.1",
20
+ "abler-net": ">=0.1.1"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@babel/core": "^7.18.5",