jsir 1.2.6 → 1.2.9

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/util.js CHANGED
@@ -1,28 +1,39 @@
1
1
  const setting = require('./setting')
2
2
  const os = require('os')
3
3
  const home = os.homedir()
4
- const exec = require('child_process').exec;
4
+ const {exec, spawnSync} = require('child_process');
5
5
  const readline = require('readline')
6
6
  const fs = require('fs')
7
7
  const http = require("http");
8
8
  const querystring = require('querystring');
9
9
  const axios = require('axios')
10
10
  const got = axios.create({
11
- timeout: 9000
11
+ timeout: 33000
12
12
  })
13
13
  const BigNumber = require('bignumber.js');
14
14
  const pad = require('pad');
15
- let crypto = require('crypto');
15
+ const crypto = require('crypto');
16
16
  const globalDirectories = require('global-dirs');
17
- let md5 = require('md5');
18
17
  const emptyFn = ()=>{}
19
18
  const dayJs = require('dayjs')
19
+ const table = require('console.table')
20
+
20
21
  let _globalLog = createLimitLogger2(`${setting.name}.log`, null, false)
21
22
  global.$log = str => {
22
- _globalLog(`[${timeStr()}] ${str}`)
23
+ str = trim(str)
24
+ if (str) {
25
+ _globalLog(`[${timeStr()}] ${str}`)
26
+ }
23
27
  }
24
28
  const $log = global.$log
25
- const $fnCache = {}
29
+ let _globalDraft= createLimitLogger2(`draft.log`, null, false)
30
+ global.$draft = str => {
31
+ if (trim(str)) {
32
+ _globalDraft(`---------${timeStr()}\n${str.split("\n").filter(i => trim(i)).join("\n")}`)
33
+ }
34
+ }
35
+ const $draft = global.$draft
36
+ global.$fnCache = {}
26
37
 
27
38
  global.$config = {
28
39
  _buildId: null,
@@ -38,7 +49,7 @@ global.$config = {
38
49
  localConfig: {},
39
50
  remoteConfig: {},
40
51
  getLocal: (key, defaultVal) => {
41
- if (key && !$config.localConfig.hasOwnProperty(key)) {
52
+ if (key && Object.keys($config.localConfig).indexOf(key) === -1) {
42
53
  getConfig(key)
43
54
  }
44
55
  return getVl($config.localConfig[key], defaultVal)
@@ -76,6 +87,14 @@ async function _buildConfig() {
76
87
  $config._buildId = setTimeout(_buildConfig, 3000);
77
88
  }
78
89
 
90
+ function tableStr(...args) {
91
+ return trim(table.getTable(...args))
92
+ }
93
+
94
+ function nableStr(rows) {
95
+ return tableStr(wrapRows(rows))
96
+ }
97
+
79
98
  function timeStr(fmt, date) {
80
99
  return dayJs(date || new Date()).format(fmt || 'YYYY/MM/DD HH:mm:ss')
81
100
  }
@@ -84,6 +103,9 @@ function vl(obj) {
84
103
  if (typeof obj === 'number') {
85
104
  return !Number.isNaN(obj)
86
105
  }
106
+ if (typeof obj === 'string') {
107
+ obj = trim(obj)
108
+ }
87
109
  return !(obj === null || obj === undefined || obj === '')
88
110
  }
89
111
 
@@ -95,17 +117,39 @@ function getVl(...obj) {
95
117
  }
96
118
  }
97
119
 
98
- async function cacheFn(key, fn, validMs) {
99
- if ($fnCache[key] && Date.now() <= $fnCache[key].expiredMs) {
120
+ let cacheFnResp;
121
+ async function cacheFn(key, fn, validMs, awaitRefresh) {
122
+ getOr($fnCache, key, {
123
+ validMsTime: 0
124
+ });
125
+ if (Date.now() <= $fnCache[key].validMsTime) {
100
126
  // do nothing
101
127
  } else {
102
- await (async () => {
103
- let val = await fn()
128
+ $fnCache[key].validMsTime = Date.now() * 3;
129
+ let sync = true
130
+ cacheFnResp = (async () => {
131
+ let val;
132
+ try {
133
+ val = await fn()
134
+ } finally {
135
+ if (!$fnCache[key].validMsTime > Date.now() * 2) {
136
+ sync = false
137
+ } else {
138
+ $fnCache[key].validMsTime = 0
139
+ }
140
+ }
141
+ if (!sync) {
142
+ return;
143
+ }
104
144
  $fnCache[key] = {
105
145
  val,
106
- expiredMs: Date.now() + (validMs || 1000 * 60 * 60 * 24 * 1000)
146
+ valInit: true,
147
+ validMsTime: Date.now() + (validMs || Date.now())
107
148
  }
108
- })()
149
+ })();
150
+ }
151
+ if (awaitRefresh || !$fnCache[key].valInit) {
152
+ await cacheFnResp;
109
153
  }
110
154
  return $fnCache[key].val
111
155
  }
@@ -162,7 +206,11 @@ function createLimitLogger(fileName, maxChars, logInfo = true) {
162
206
  }
163
207
 
164
208
  return (text) => {
165
- fs.appendFile(logPath, String(text) + '\n', emptyFn)
209
+ text = trim(text)
210
+ if (!text) {
211
+ return
212
+ }
213
+ fs.appendFile(logPath, text + '\n', emptyFn)
166
214
  }
167
215
  }
168
216
 
@@ -170,7 +218,6 @@ function createLimitLogger2(fileName, maxChars, logInfo = true) {
170
218
  let logDir = getLibDataDir() + "/log"
171
219
  mkdir(logDir)
172
220
  let logPath = logDir + "/" + fileName
173
- cleanFile(logPath, maxChars)
174
221
 
175
222
  if (logInfo) {
176
223
  info(`log: ${logPath}`)
@@ -178,12 +225,16 @@ function createLimitLogger2(fileName, maxChars, logInfo = true) {
178
225
 
179
226
  let minNum = (Date.now()/(1000 * 60 * 10)).toFixed(0)
180
227
  return (text) => {
228
+ text = trim(text)
229
+ if (!text) {
230
+ return
231
+ }
181
232
  let _minNum = (Date.now()/(1000 * 60 * 10)).toFixed(0)
182
233
  if (_minNum !== minNum) {
183
234
  minNum = _minNum
184
235
  cleanFile(logPath, maxChars)
185
236
  }
186
- fs.appendFile(logPath, String(text) + '\n', emptyFn)
237
+ fs.appendFile(logPath, text + '\n', emptyFn)
187
238
  }
188
239
  }
189
240
 
@@ -200,13 +251,17 @@ function textDataFile(fileName, fn) {
200
251
  return text
201
252
  }
202
253
  let val = fn(text)
203
- if (vl(val) && val.constructor.name === 'Promise') {
254
+ if (vl(val) && getType(val) === 'Promise') {
204
255
  return val.then(result => {
205
- fileLock(fileName, () => fs.writeFileSync(path, result))
256
+ if (vl(result) || String(result) === '') {
257
+ fileLock(fileName, () => fs.writeFileSync(path, result))
258
+ }
206
259
  return result
207
260
  })
208
261
  } else {
209
- fileLock(fileName, () => fs.writeFileSync(path, val))
262
+ if (vl(val) || String(val) === '') {
263
+ fileLock(fileName, () => fs.writeFileSync(path, val))
264
+ }
210
265
  return val
211
266
  }
212
267
  }
@@ -230,7 +285,7 @@ function dataFile(fileName, fn, fmt, defaultObj = {}) {
230
285
  return obj
231
286
  }
232
287
  let val = fn(obj)
233
- if (vl(val) && val.constructor.name === 'Promise') {
288
+ if (vl(val) && getType(val) === 'Promise') {
234
289
  return new Promise(async resolve => {
235
290
  let result = await val
236
291
  if (result && typeof result === 'object') {
@@ -262,23 +317,43 @@ function requireG(module){
262
317
  return require(path);
263
318
  }
264
319
 
320
+ function validStr(str, name) {
321
+ if (!vl(str) || typeof str !== 'string') {
322
+ throw "invalid cipher " + name;
323
+ }
324
+ }
325
+
265
326
  function aesCipher(str, key){
327
+ validStr(str, "str");
328
+ validStr(key, "key");
329
+
330
+ key = trim(key);
331
+ if (!key || key.length > 16) {
332
+ throw "aesCipher key length should between 1 and 16"
333
+ }
266
334
  try {
267
335
  const cipher = crypto.createCipheriv('aes-128-ecb', pad(key, 16, '0'), null);
268
336
  return cipher.update(str, 'utf8', 'hex') + cipher.final('hex');
269
337
  } catch(err) {
270
- console.log('加密失败');
271
- return err.message || err;
338
+ $log(errorStack(err))
339
+ throw 'aesCipher failed: ' + String(err)
272
340
  }
273
341
  }
274
342
 
275
343
  function aesDecipher(str, key){
344
+ validStr(str, "str");
345
+ validStr(key, "key");
346
+
347
+ key = trim(key);
348
+ if (!key || key.length > 16) {
349
+ throw "aesCipher key length should between 1 and 16"
350
+ }
276
351
  try {
277
352
  const decipher = crypto.createDecipheriv('aes-128-ecb', pad(key, 16, '0'), null);
278
353
  return decipher.update(str, 'hex', 'utf8') + decipher.final('utf8');
279
354
  } catch(err) {
280
- console.log('解密失败');
281
- return err.message || err;
355
+ $log(errorStack(err))
356
+ throw 'aesDecipher failed: ' + String(err)
282
357
  }
283
358
  }
284
359
 
@@ -439,7 +514,7 @@ function fileLock(key, fn) {
439
514
  } catch (e) {
440
515
  rmDir(file)
441
516
  }
442
- if (obj && obj.constructor.name === 'Promise') {
517
+ if (getType(obj)=== 'Promise') {
443
518
  return obj.then(result => {
444
519
  rmDir(file)
445
520
  return result
@@ -483,14 +558,13 @@ function fileCleaner(path, maxChars) {
483
558
  global.$cleanFiles[path] = 0
484
559
  }
485
560
 
486
- cleanFile(path, maxChars)
487
561
  if (!global.$fileCleanerOn) {
488
562
  timeLoop(() => {
489
563
  for (let aPath of Object.keys(global.$cleanFiles)) {
490
564
  try {
491
565
  cleanFile(path, maxChars)
492
566
  } catch (e) {
493
- console.log(e.toString().split("\n")[0])
567
+ console.log(String(e))
494
568
  }
495
569
  global.$cleanFiles[path] ++
496
570
  }
@@ -504,7 +578,7 @@ function cleanFile(path, maxChars) {
504
578
  return
505
579
  }
506
580
  let content = String(fs.readFileSync(path))
507
- let newContext = content.substr(- (maxChars || 1024 * 1000))
581
+ let newContext = content.substr(- (maxChars || 1024 * 1024))
508
582
  if (newContext.length < content.length) {
509
583
  fs.writeFileSync(path, newContext)
510
584
  }
@@ -594,18 +668,18 @@ function timeLoop(fn, timestamp, lastIds = []){
594
668
  try {
595
669
  val = fn()
596
670
  } catch (e) {
597
- console.error(e.toString().split("\n")[0])
598
- $log(e.stack)
671
+ error(String(e))
672
+ $log(new Error(errorStack(e)).stack)
599
673
  }
600
- if (vl(val) && val.constructor.name === 'Promise') {
674
+ if (vl(val) && getType(val) === 'Promise') {
601
675
  return val.then(result => {
602
676
  if (lastIds[0] !== false && result !== true) {
603
677
  lastIds[0] = setTimeout(() => timeLoop(fn, timestamp, lastIds), timestamp)
604
678
  }
605
679
  return lastIds
606
680
  }).catch(e => {
607
- console.error(e.toString().split("\n")[0])
608
- $log(e.stack)
681
+ error(String(e))
682
+ $log(new Error(errorStack(e)).stack)
609
683
 
610
684
  if (lastIds[0] !== false) {
611
685
  lastIds[0] = setTimeout(() => timeLoop(fn, timestamp, lastIds), timestamp)
@@ -654,6 +728,9 @@ function e(cmd, mbNum, doTrim = true){
654
728
  maxBuffer: 1024 * 1024 * (mbNum || 3) //quick fix
655
729
  },
656
730
  function (err, stdout, stderr) {
731
+ if (stderr) {
732
+ reject(trim(stderr))
733
+ }
657
734
  resolve(doTrim ? trim(stdout):String(stdout))
658
735
  });
659
736
  })
@@ -670,6 +747,10 @@ function ee(cmd, mbNum, doTrim = true){
670
747
  })
671
748
  }
672
749
 
750
+ function ei(cmd, args = []) {
751
+ spawnSync(cmd, args, {stdio:"inherit"});
752
+ }
753
+
673
754
  async function getCbText() {
674
755
  return await e(`pbpaste`, null, false)
675
756
  }
@@ -712,7 +793,7 @@ function splitArray(items, size) {
712
793
  }
713
794
 
714
795
  function isError(obj) {
715
- return obj && obj.constructor && obj.constructor.name === 'Error'
796
+ return getType(obj).endsWith('Error')
716
797
  }
717
798
 
718
799
  class Range {
@@ -786,24 +867,35 @@ function wrapRows(rows) {
786
867
  }
787
868
 
788
869
  function info(msg) {
789
- process.stdout.write('\x1B[32m')
790
- process.stdout.write('[info] ')
791
- process.stdout.write('\x1B[39m')
792
- console.log(msg)
870
+ console.log(infoStr('[info]'), msg)
871
+ }
872
+
873
+ function msg(msg) {
874
+ console.log(msgStr('[msg]'), msg)
793
875
  }
794
876
 
795
877
  function warn(msg) {
796
- process.stdout.write('\x1B[33m')
797
- process.stdout.write('[warn] ')
798
- process.stdout.write('\x1B[39m')
799
- console.log(msg)
878
+ console.warn(warnStr('[warn]'), msg)
800
879
  }
801
880
 
802
- function error(e, msg) {
803
- process.stdout.write('\x1B[35m')
804
- process.stdout.write(`[${msg || 'error'}] `)
805
- process.stdout.write('\x1B[39m')
806
- console.log(e)
881
+ function error(msg, tag) {
882
+ console.error(errorStr(`[${tag || 'error'}]`), msg)
883
+ }
884
+
885
+ function infoStr(str) {
886
+ return `\x1B[32m${str}\x1B[39m`
887
+ }
888
+
889
+ function msgStr(str) {
890
+ return `\x1B[36m${str}\x1B[39m`
891
+ }
892
+
893
+ function warnStr(str) {
894
+ return `\x1B[33m${str}\x1B[39m`
895
+ }
896
+
897
+ function errorStr(str) {
898
+ return `\x1B[31m${str}\x1B[39m`
807
899
  }
808
900
 
809
901
  function parseSteps(str) {
@@ -839,6 +931,134 @@ function parseSteps(str) {
839
931
  return result
840
932
  }
841
933
 
934
+ function errorStack(e) {
935
+ return String(e ? (e.stack || e):e)
936
+ }
937
+
938
+ function errorMsg(e) {
939
+ return trim(String(e).split("\n").map(trim).filter(i => i)[0])
940
+ }
941
+
942
+ function getType(obj) {
943
+ if (obj === '') {
944
+ return typeof obj;
945
+ }
946
+ if (!vl(obj)) {
947
+ return String(obj)
948
+ }
949
+ if (obj.constructor && obj.constructor.name) {
950
+ return obj.constructor.name;
951
+ }
952
+ return typeof obj
953
+ }
954
+
955
+ function getInfo(obj, key) {
956
+ let info = {}
957
+ if (key) {
958
+ info.key = key
959
+ }
960
+ if (!vl(obj)) {
961
+ info.type = getType(obj)
962
+ info.value = String(obj);
963
+ return info;
964
+ }
965
+
966
+ let value = ''
967
+ let str = trim(String(obj))
968
+ let fnName
969
+ if (typeof obj === 'function') {
970
+ fnName = obj.name
971
+ let fnStr = trim(str.split(/=\s*>|(?<=\))\s*{/)[0])
972
+ if (/[()]/.test(fnStr)) {
973
+ value = fnStr.split(/[()]/)[1]
974
+ } else {
975
+ value = fnStr
976
+ }
977
+ value = trim(value.split('\n').map(trim).join('\n '))
978
+ if (value) {
979
+ value = 'args: ' + value
980
+ }
981
+ } else if (typeof obj === 'string') {
982
+ value = 'length: ' + str.length;
983
+ } else {
984
+ let len = Object.keys(obj).length;
985
+ value = len > 0 ? ('keys: ' + len) : (str.length <= 64 ? str : `${str.substr(0, 64)}...[length: ${str.length}]`);
986
+ }
987
+ key = key || fnName
988
+ if (key) {
989
+ info.key = key;
990
+ }
991
+ info.type = getType(obj);
992
+ info.value = value;
993
+ return info;
994
+ }
995
+
996
+ function md5(message) {
997
+ return crypto.createHash('md5').update(message).digest('hex');
998
+ }
999
+
1000
+ async function batchAsync(fns = [], asyncNum = 1) {
1001
+ if (fns.length <= 0 || asyncNum < 1) {
1002
+ return []
1003
+ }
1004
+ let pros = []
1005
+ let doneMap = {}
1006
+ let proMap = {}
1007
+ for(let i = 0; i< fns.length; i++) {
1008
+ let pro = new Promise(async (resolve, reject) => {
1009
+ try {
1010
+ let resp = await fns[i]();
1011
+ doneMap[i] = pro;
1012
+ resolve(resp)
1013
+ } catch (e) {
1014
+ doneMap[i] = pro;
1015
+ resolve(isError(e) ? e:new Error(e));
1016
+ }
1017
+ })
1018
+ proMap[i] = pro;
1019
+ pros.push(pro)
1020
+
1021
+ if (asyncNum === 1) {
1022
+ await pro;
1023
+ } else {
1024
+ let undonePros = Object.keys(proMap).filter(i => !doneMap[i]).map(i => proMap[i])
1025
+ if (undonePros.length >= asyncNum) {
1026
+ await Promise.race(undonePros)
1027
+ }
1028
+ }
1029
+ }
1030
+ return await Promise.all(pros)
1031
+ }
1032
+
1033
+ function objProfileRows(result) {
1034
+ result = Object.keys(result).map(key => {
1035
+ return {
1036
+ key,
1037
+ type: getType(result[key])
1038
+ }})
1039
+ .sort((a,b) => {
1040
+ return a.type >= b.type ? 1:-1
1041
+ })
1042
+
1043
+ let temp = []
1044
+ for(let i = 0; i< Object.keys(result).length; i+=3) {
1045
+ let item = {}
1046
+ temp.push(item)
1047
+
1048
+ item['type'] = result[i].type
1049
+ item['name']= result[i].key
1050
+ if (result[i+1]) {
1051
+ item['type '] = result[i+1].type
1052
+ item['name ']= result[i+1].key
1053
+ }
1054
+ if (result[i+2]) {
1055
+ item['type '] = result[i+2].type
1056
+ item['name ']= result[i+2].key
1057
+ }
1058
+ }
1059
+ return temp
1060
+ }
1061
+
842
1062
  module.exports = {
843
1063
  run,
844
1064
  reget,
@@ -910,5 +1130,21 @@ module.exports = {
910
1130
  info,
911
1131
  warn,
912
1132
  error,
913
- parseSteps
1133
+ parseSteps,
1134
+ $draft,
1135
+ infoStr,
1136
+ warnStr,
1137
+ errorStr,
1138
+ errorStack,
1139
+ getType,
1140
+ getInfo,
1141
+ md5,
1142
+ batchAsync,
1143
+ ei,
1144
+ msg,
1145
+ msgStr,
1146
+ errorMsg,
1147
+ tableStr,
1148
+ nableStr,
1149
+ objProfileRows
914
1150
  }