abler-api 0.1.16 → 0.1.19

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
  /**
@@ -554,7 +541,7 @@ class apiUtil$1 {
554
541
 
555
542
  if (dbgToken) {
556
543
  let envId = process.env.ECS_DEPLOY_ID;
557
- 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");
558
545
  } else {
559
546
  req.__debug__ = false;
560
547
  } // console.log("__debug__:", req.__debug__, "dbgToken:", dbgToken);
@@ -734,7 +721,7 @@ class apiUtil$1 {
734
721
  };
735
722
 
736
723
  if (rec.secret !== "") {
737
- rec.secret = ppUtil$1.getEncAse192(rec.secret);
724
+ rec.secret = ppUtil$2.getEncAse192(rec.secret);
738
725
  }
739
726
 
740
727
  req.apiCallRec = rec;
@@ -801,7 +788,7 @@ class apiUtil$1 {
801
788
  return certInfo;
802
789
  }).catch(e => {
803
790
  console.log('获取企业证书失败:\n', e);
804
- throw [err.ACCESS_REFUSED, `获取企业证书失败:${err.ERROR(e).message}`];
791
+ throw [err$1.ACCESS_REFUSED, `获取企业证书失败:${err$1.ERROR(e).message}`];
805
792
  });
806
793
  }
807
794
  /**
@@ -815,7 +802,7 @@ class apiUtil$1 {
815
802
  static async verifyApiSignature(tokenData, req) {
816
803
  try {
817
804
  if (!req.headers.timestamp) {
818
- throw [err.ACCESS_REFUSED, `必须在请求头中设置时戳`];
805
+ throw [err$1.ACCESS_REFUSED, `必须在请求头中设置时戳`];
819
806
  }
820
807
 
821
808
  let timestamp = parseInt(req.headers.timestamp);
@@ -823,13 +810,13 @@ class apiUtil$1 {
823
810
  let maxTimeDiff = apiUtil$1.isDebugMode(req) ? 7 * 24 * 3600 : apiUtil$1.isTestMode(req) ? 4 * 3600 : 100; // 100
824
811
 
825
812
  if (timestamp.toString() == "NaN" || currentTime < timestamp - 5000 || currentTime - timestamp > maxTimeDiff * 1000) {
826
- throw [err.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
813
+ throw [err$1.ACCESS_REFUSED, `时戳(${timestamp})无效,当前时戳:${currentTime},时差 ${(currentTime - timestamp) / 1000}秒`];
827
814
  }
828
815
 
829
816
  let signature = req.headers.signature;
830
817
 
831
818
  if (!signature) {
832
- throw [err.ACCESS_REFUSED, `必须在请求头中提供签名`];
819
+ throw [err$1.ACCESS_REFUSED, `必须在请求头中提供签名`];
833
820
  }
834
821
 
835
822
  let signData = apiUtil$1.extractToken(req, null, true) || tokenData.apiKey;
@@ -884,7 +871,7 @@ class apiUtil$1 {
884
871
 
885
872
  if (!tokenData.certPublicKeySpare) {
886
873
  throw {
887
- eo: err.ACCESS_REFUSED,
874
+ eo: err$1.ACCESS_REFUSED,
888
875
  msgArgv: "签名验证异常",
889
876
  data: e
890
877
  };
@@ -933,7 +920,7 @@ class apiUtil$1 {
933
920
  } catch (e) {
934
921
  console.log("SPO服务签名验证异常(备用证书), ", e);
935
922
  throw {
936
- eo: err.ACCESS_REFUSED,
923
+ eo: err$1.ACCESS_REFUSED,
937
924
  msgArgv: "签名验证异常(spare)",
938
925
  data: e
939
926
  };
@@ -942,7 +929,7 @@ class apiUtil$1 {
942
929
 
943
930
  if (!verifyOK) {
944
931
  console.log("SPO服务签名验证失败, tokenData: ", tokenData);
945
- throw [err.ACCESS_REFUSED, "签名验证未通过"];
932
+ throw [err$1.ACCESS_REFUSED, "签名验证未通过"];
946
933
  }
947
934
 
948
935
  return verifyOK;
@@ -960,7 +947,7 @@ class apiUtil$1 {
960
947
  if (!tokenData.companyInfo) {
961
948
  tokenData.companyInfo = await apiUtil$1.queryCompanyInfo(tokenData.apiKey, true).catch(e => {
962
949
  console.log("执行企业信息查询发生异常", e);
963
- throw [err.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
950
+ throw [err$1.API_KEY_INVALID, "执行企业信息查询发生异常:" + e.message || ""];
964
951
  });
965
952
  }
966
953
 
@@ -969,7 +956,7 @@ class apiUtil$1 {
969
956
  if (companyInfo != null) {
970
957
  let secret = apiUtil$1._getApiSecret(tokenData.apiKey);
971
958
 
972
- if (secret !== tokenData.apiSecret) throw err.API_SCREPT_INVALID; // 不再检查 IP 白名单,改为验证证书签名
959
+ if (secret !== tokenData.apiSecret) throw err$1.API_SCREPT_INVALID; // 不再检查 IP 白名单,改为验证证书签名
973
960
  // console.log("fromIp:", tokenData.clientIp, "ipWhiteList:", companyInfo.ipWhiteList);
974
961
  // let whiteList = companyInfo.ipWhiteList || "";
975
962
  // // 没有设置ip白名单的就不检查了
@@ -983,7 +970,7 @@ class apiUtil$1 {
983
970
  });
984
971
  }
985
972
 
986
- throw [err.API_KEY_INVALID, tokenData.apiKey];
973
+ throw [err$1.API_KEY_INVALID, tokenData.apiKey];
987
974
  }
988
975
  /**
989
976
  * 检查令牌数据是否存在
@@ -1034,10 +1021,152 @@ class apiUtil$1 {
1034
1021
  paramExists = typeof params[paramName] != 'undefined' || typeof params[paramName + paramSufix] != 'undefined';
1035
1022
  }
1036
1023
 
1037
- 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));
1038
1025
  }
1039
1026
 
1040
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
+ };
1041
1170
  } //#endregion
1042
1171
  //region ====中间件
1043
1172
 
@@ -1051,7 +1180,7 @@ class apiUtil$1 {
1051
1180
  await apiUtil$1.checkRequestToken(req);
1052
1181
  await next();
1053
1182
  } catch (e) {
1054
- res.send(err.ERROR(e));
1183
+ res.send(err$1.ERROR(e));
1055
1184
  }
1056
1185
 
1057
1186
  return false;
@@ -1099,7 +1228,7 @@ class apiUtil$1 {
1099
1228
 
1100
1229
  return true;
1101
1230
  } catch (e) {
1102
- res.send(err.ERROR(e));
1231
+ res.send(err$1.ERROR(e));
1103
1232
  return false;
1104
1233
  }
1105
1234
  }
@@ -1149,11 +1278,11 @@ class apiUtil$1 {
1149
1278
  let errResponse = null;
1150
1279
 
1151
1280
  if (!tokenData.clientIp) {
1152
- errResponse = apiUtil$1.spoApiFail(err.GET_CLIENTIP_FAIL, req);
1281
+ errResponse = apiUtil$1.spoApiFail(err$1.GET_CLIENTIP_FAIL, req);
1153
1282
  } else if (!tokenData.apiKey) {
1154
- errResponse = apiUtil$1.spoApiFail([err.PARAMETER_NEEDED, "apiKey"], req);
1283
+ errResponse = apiUtil$1.spoApiFail([err$1.PARAMETER_NEEDED, "apiKey"], req);
1155
1284
  } else if (!tokenData.apiSecret) {
1156
- errResponse = apiUtil$1.spoApiFail([err.PARAMETER_NEEDED, "apiSecret"], req);
1285
+ errResponse = apiUtil$1.spoApiFail([err$1.PARAMETER_NEEDED, "apiSecret"], req);
1157
1286
  }
1158
1287
 
1159
1288
  if (errResponse != null) {
@@ -1189,7 +1318,7 @@ class apiUtil$1 {
1189
1318
  let accessToken = apiUtil$1.extractToken(req);
1190
1319
 
1191
1320
  if (!accessToken) {
1192
- 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));
1193
1322
 
1194
1323
  return;
1195
1324
  }
@@ -1210,7 +1339,7 @@ class apiUtil$1 {
1210
1339
  req.tokenData = p;
1211
1340
  return apiUtil$1.$checkApiKeyOld(req, res, next);
1212
1341
  }).catch(e => {
1213
- 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));
1214
1343
  });
1215
1344
  }
1216
1345
  /**
@@ -1245,24 +1374,247 @@ class apiUtil$1 {
1245
1374
  });
1246
1375
  }
1247
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
1248
1426
 
1249
1427
 
1250
1428
  }
1251
1429
 
1252
1430
  function configNeeded() {
1253
- 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) {
1254
1468
  ppUtil$1.configNeeded();
1255
1469
  conf = ppUtil$1.appConfig;
1256
- appSetting = conf.appSetting;
1257
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();
1258
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
+
1259
1546
  }
1260
1547
 
1261
- 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;
1262
1612
 
1263
1613
  const apiUtil = ppUtilApi;
1614
+ const preconditions = ppPrecond;
1264
1615
  var ppUtil = {
1265
- apiUtil
1616
+ apiUtil,
1617
+ preconditions
1266
1618
  };
1267
1619
 
1268
1620
  module.exports = ppUtil;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abler-api",
3
- "version": "0.1.16",
3
+ "version": "0.1.19",
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",