jsir 2.6.12 → 2.6.14
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/cmd/oaa.js +90 -64
- package/deps/evalCode.js +2 -8
- package/deps/room.js +11 -6
- package/deps/setting.js +4 -2
- package/deps/util.js +97 -44
- package/package.json +2 -3
package/cmd/oaa.js
CHANGED
|
@@ -4,7 +4,7 @@ const {
|
|
|
4
4
|
getLibDataDir, trim, regEach, getConfig, mkdir, reget,
|
|
5
5
|
getCbText, e, sleep, objDataFile, vl, md5, BigNumber,
|
|
6
6
|
arrayDataFile, infoStr, warnStr,
|
|
7
|
-
getInfo,
|
|
7
|
+
getInfo, msgStr, getType,
|
|
8
8
|
isMatch, draftQuery, setConfig,
|
|
9
9
|
getTextComments, importG, requireG,
|
|
10
10
|
clearConsole, trimText, getFnArgsStr,
|
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
getFullPath, parseUniqueName, toUniqueName, isJsirFileName, toJsirFileName,
|
|
14
14
|
getAlias, wrapperJsirText, eia, getKeyTips, getValTips, getJsirTypeKey,
|
|
15
15
|
createDetachedProcess, interceptStdStreams,
|
|
16
|
-
draftModify, isRunningInBackground, fileJson, fileLock, processLock, cleanFileLocks, getMd5Key
|
|
16
|
+
draftModify, isRunningInBackground, fileJson, fileLock, processLock, cleanFileLocks, getMd5Key, terminalTitle
|
|
17
17
|
} = $lib;
|
|
18
18
|
const _args = process.argv.slice(2).map(trim);
|
|
19
19
|
const evalCode = require('../deps/evalCode')
|
|
@@ -131,10 +131,24 @@ const $data = {
|
|
|
131
131
|
`
|
|
132
132
|
get or set by async function
|
|
133
133
|
`
|
|
134
|
-
if (
|
|
135
|
-
return
|
|
134
|
+
if (vl(_data[key])) {
|
|
135
|
+
return _dealOnLazyGet(key, onLazyTempCode);
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
let result = null;
|
|
138
|
+
await processLock('gafs:' + key, async () => {
|
|
139
|
+
if (!vl(_data[key])) {
|
|
140
|
+
result = _dataSet(key, await fn(), onLazyTempCode)
|
|
141
|
+
} else {
|
|
142
|
+
result = _dealOnLazyGet(key, onLazyTempCode)
|
|
143
|
+
}
|
|
144
|
+
}, async () => {
|
|
145
|
+
if (!vl(_data[key])) {
|
|
146
|
+
return true;
|
|
147
|
+
} else {
|
|
148
|
+
result = _dealOnLazyGet(key, onLazyTempCode)
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
return result;
|
|
138
152
|
},
|
|
139
153
|
set: _dataSet,
|
|
140
154
|
del: (key) => {
|
|
@@ -184,6 +198,7 @@ function checkWorkspaces() {
|
|
|
184
198
|
}
|
|
185
199
|
|
|
186
200
|
async function start() {
|
|
201
|
+
terminalTitle()
|
|
187
202
|
cleanFileLocks();
|
|
188
203
|
|
|
189
204
|
setting.wrapperInput = wrapperInput;
|
|
@@ -337,8 +352,8 @@ function initRl(callback, promptStr, hidden) {
|
|
|
337
352
|
})
|
|
338
353
|
_rl.on("SIGINT", async () => {
|
|
339
354
|
if (_noAppendNextLine) {
|
|
340
|
-
|
|
341
|
-
|
|
355
|
+
setting.promptId = Date.now();
|
|
356
|
+
await delTips();
|
|
342
357
|
} else {
|
|
343
358
|
_rl._writeToOutput = origin_writeToOutput;
|
|
344
359
|
_haveWrapperInput = true;
|
|
@@ -350,12 +365,12 @@ function initRl(callback, promptStr, hidden) {
|
|
|
350
365
|
}
|
|
351
366
|
origin_writeToOutput = _rl._writeToOutput
|
|
352
367
|
if (promptStr !== '') {
|
|
353
|
-
promptStr = promptStr || (
|
|
368
|
+
promptStr = promptStr || (callback !== wrapperInput ? "-> ":"")
|
|
354
369
|
if (promptStr) {
|
|
355
370
|
promptStr = infoStr(promptStr);
|
|
356
371
|
} else {
|
|
357
|
-
if (
|
|
358
|
-
|
|
372
|
+
if (setting.newError) {
|
|
373
|
+
setting.newError = false;
|
|
359
374
|
promptStr = errorStr(defaultPromptStr())
|
|
360
375
|
} else {
|
|
361
376
|
promptStr = infoStr(defaultPromptStr())
|
|
@@ -394,6 +409,7 @@ function closeRl() {
|
|
|
394
409
|
}
|
|
395
410
|
|
|
396
411
|
function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
|
|
412
|
+
callback = callback || wrapperInput;
|
|
397
413
|
if (!setting.enableNextLine) {
|
|
398
414
|
console.$log(warnStr("[warn]"), "NextLine Disabled");
|
|
399
415
|
resolve(null);
|
|
@@ -405,15 +421,11 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
|
|
|
405
421
|
return;
|
|
406
422
|
}
|
|
407
423
|
initRl(callback, promptStr, hidden);
|
|
408
|
-
|
|
409
|
-
if (!isJsirNext) {
|
|
424
|
+
if (callback !== wrapperInput) {
|
|
410
425
|
_haveWrapperInput = false
|
|
411
426
|
}
|
|
412
|
-
if (isJsirNext) {
|
|
413
|
-
global.$newInput = true;
|
|
414
|
-
}
|
|
415
427
|
end = trim(end)
|
|
416
|
-
let
|
|
428
|
+
let inputs = []
|
|
417
429
|
let lineHandler = async line => {
|
|
418
430
|
let textLine = line
|
|
419
431
|
line = trim(line)
|
|
@@ -422,33 +434,32 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
|
|
|
422
434
|
end = line
|
|
423
435
|
line = ''
|
|
424
436
|
} else if (line !== end) {
|
|
425
|
-
|
|
437
|
+
inputs.push(textLine)
|
|
426
438
|
}
|
|
427
439
|
} else {
|
|
428
|
-
|
|
440
|
+
inputs.push(line)
|
|
429
441
|
}
|
|
430
|
-
if (trim(textLine) && (hidden ||
|
|
442
|
+
if (trim(textLine) && (hidden || callback !== wrapperInput)) {
|
|
431
443
|
_rl.history = _rl.history.slice(1)
|
|
432
444
|
}
|
|
433
445
|
if (!isText || line === end) {
|
|
446
|
+
let promptId = setting.promptId;
|
|
434
447
|
_haveWrapperInput = true;
|
|
435
448
|
closeRl()
|
|
436
|
-
inputStr =
|
|
437
|
-
if (!isText && /^\d+$/.test(inputStr) && /^\s+/.test(textLine)
|
|
449
|
+
let inputStr = inputs.join("\n");
|
|
450
|
+
if (callback === wrapperInput && !isText && /^\d+$/.test(inputStr) && /^\s+/.test(textLine)) {
|
|
438
451
|
inputStr = '.e ' + inputStr;
|
|
439
452
|
}
|
|
440
|
-
let pro = (callback || wrapperInput)(inputStr);
|
|
441
|
-
resolve(inputStr);
|
|
442
453
|
try {
|
|
443
|
-
await
|
|
454
|
+
resolve(await callback(inputStr));
|
|
444
455
|
} finally {
|
|
445
|
-
if (
|
|
456
|
+
if (callback === wrapperInput) {
|
|
446
457
|
if (!_noAppendNextLine) {
|
|
447
458
|
if (/^\s+$/.test(textLine)) {
|
|
448
459
|
clearConsole(textLine.length - 1)
|
|
449
460
|
filterCmdAndList();
|
|
450
461
|
nextLine(null, defaultPromptStr(true))
|
|
451
|
-
} else {
|
|
462
|
+
} else if (promptId === setting.promptId) {
|
|
452
463
|
nextLine()
|
|
453
464
|
}
|
|
454
465
|
}
|
|
@@ -460,6 +471,9 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
|
|
|
460
471
|
_rl.removeAllListeners('line')
|
|
461
472
|
_rl.on('line', lineHandler)
|
|
462
473
|
_rl.prompt()
|
|
474
|
+
if (callback === wrapperInput) {
|
|
475
|
+
setting.promptId = Date.now();
|
|
476
|
+
}
|
|
463
477
|
setting.lastOutput = null;
|
|
464
478
|
}
|
|
465
479
|
|
|
@@ -470,7 +484,11 @@ async function nextText(callback, end, hidden) {
|
|
|
470
484
|
}
|
|
471
485
|
|
|
472
486
|
async function save(args) {
|
|
473
|
-
let
|
|
487
|
+
let pair = parseUniqueName(args.join(' '));
|
|
488
|
+
if (pair[0] && !setting.workspaceMap[pair[0]]) {
|
|
489
|
+
throw 'invalid name'
|
|
490
|
+
}
|
|
491
|
+
let uniqueName = toUniqueName(toJsirFileName(pair[1]), pair[0])
|
|
474
492
|
let path = getFullPath(uniqueName)
|
|
475
493
|
if (fs.existsSync(path)) {
|
|
476
494
|
console.warn(`${path} already exist`)
|
|
@@ -612,10 +630,15 @@ async function wrapperInput(str, packOutput = false) {
|
|
|
612
630
|
if (packOutput) {
|
|
613
631
|
setting.enterOutputs = []
|
|
614
632
|
}
|
|
633
|
+
const promptId = setting.promptId;
|
|
615
634
|
try {
|
|
616
635
|
await _wrapperInput(str);
|
|
617
636
|
} catch (e) {
|
|
618
|
-
|
|
637
|
+
if (promptId === setting.promptId) {
|
|
638
|
+
console.error(e)
|
|
639
|
+
} else {
|
|
640
|
+
console.$error(e)
|
|
641
|
+
}
|
|
619
642
|
}
|
|
620
643
|
if (packOutput) {
|
|
621
644
|
let outputs = setting.enterOutputs || [];
|
|
@@ -639,16 +662,16 @@ async function _wrapperInput(str) {
|
|
|
639
662
|
if (!str) {
|
|
640
663
|
return;
|
|
641
664
|
}
|
|
642
|
-
|
|
665
|
+
setting.newError = false;
|
|
643
666
|
str = wrapperAlias(str);
|
|
644
667
|
|
|
645
668
|
if (/^[`'"]/.test(str)) {
|
|
646
|
-
let fstr = str.
|
|
669
|
+
let fstr = str.substring(0, 1);
|
|
647
670
|
if (fstr === '`') {
|
|
648
|
-
let text = str.
|
|
671
|
+
let text = str.substring(1) + "\n" + await nextText(line => line, fstr)
|
|
649
672
|
await wrapperInput(text)
|
|
650
673
|
} else {
|
|
651
|
-
let fLine = trim(str.
|
|
674
|
+
let fLine = trim(str.substring(1))
|
|
652
675
|
if (fLine) {
|
|
653
676
|
if (/\s+[+-]$/.test(fLine)) {
|
|
654
677
|
console.log((await draftModify(fLine)).join("\n"))
|
|
@@ -701,6 +724,7 @@ async function runInit(uniqueName, args) {
|
|
|
701
724
|
if (arg === '-') {
|
|
702
725
|
await offServer(uniqueName)
|
|
703
726
|
} else {
|
|
727
|
+
console.$log(`Execute ${uniqueName}`);
|
|
704
728
|
let exportLib = await _requireSource(setting.defaultSpace, uniqueName, true);
|
|
705
729
|
if (typeof exportLib === "function") {
|
|
706
730
|
await execLibFn(exportLib, args)
|
|
@@ -930,7 +954,7 @@ function dealStarCmd(rows, cmd, filterStr) {
|
|
|
930
954
|
}
|
|
931
955
|
|
|
932
956
|
// Capture single-line comments
|
|
933
|
-
if (line.trim().startsWith('//')) {
|
|
957
|
+
if (line.trim().startsWith('//') || line.trim().startsWith("@")) {
|
|
934
958
|
potentialComments.push(line);
|
|
935
959
|
}
|
|
936
960
|
|
|
@@ -968,7 +992,8 @@ function dealStarCmd(rows, cmd, filterStr) {
|
|
|
968
992
|
}
|
|
969
993
|
|
|
970
994
|
// If not capturing function, reset potential comments
|
|
971
|
-
if (!capturingFunction && !inMultiLineComment && line.trim() !== ''
|
|
995
|
+
if (!capturingFunction && !inMultiLineComment && line.trim() !== ''
|
|
996
|
+
&& !line.trim().startsWith('//') && !line.trim().startsWith('@')) {
|
|
972
997
|
potentialComments = [];
|
|
973
998
|
}
|
|
974
999
|
}
|
|
@@ -1039,7 +1064,7 @@ function delTipsByIndex(idxs) {
|
|
|
1039
1064
|
console.warn("no items")
|
|
1040
1065
|
return;
|
|
1041
1066
|
}
|
|
1042
|
-
delTips(...params)
|
|
1067
|
+
return delTips(...params)
|
|
1043
1068
|
}
|
|
1044
1069
|
|
|
1045
1070
|
function getPackageVersion(space, name) {
|
|
@@ -1185,8 +1210,8 @@ const keywordDef = {
|
|
|
1185
1210
|
},
|
|
1186
1211
|
clear: {
|
|
1187
1212
|
comment: 'Clear task',
|
|
1188
|
-
exeFn: (args) => {
|
|
1189
|
-
delTipsByIndex(args.filter(i => i))
|
|
1213
|
+
exeFn: async (args) => {
|
|
1214
|
+
await delTipsByIndex(args.filter(i => i))
|
|
1190
1215
|
},
|
|
1191
1216
|
args: {
|
|
1192
1217
|
tipIndex: 'left prompt index, can be separated by spaces for multiple'
|
|
@@ -1550,11 +1575,11 @@ const keywordDef = {
|
|
|
1550
1575
|
},
|
|
1551
1576
|
quit: {
|
|
1552
1577
|
comment: 'Exit',
|
|
1553
|
-
exeFn: (args) => {
|
|
1578
|
+
exeFn: async (args) => {
|
|
1554
1579
|
Room.offRoom();
|
|
1555
|
-
delTips();
|
|
1556
|
-
console.log(infoStr("Bye!"));
|
|
1580
|
+
await delTips();
|
|
1557
1581
|
_noAppendNextLine = true;
|
|
1582
|
+
console.log(infoStr("Bye!"));
|
|
1558
1583
|
},
|
|
1559
1584
|
short: 'q'
|
|
1560
1585
|
},
|
|
@@ -1625,7 +1650,7 @@ const keywordDef = {
|
|
|
1625
1650
|
},
|
|
1626
1651
|
debug: {
|
|
1627
1652
|
comment: 'debug mode',
|
|
1628
|
-
exeFn: (args) => {
|
|
1653
|
+
exeFn: async (args) => {
|
|
1629
1654
|
if ('+' === args[0]) {
|
|
1630
1655
|
if (!global.$DEBUG) {
|
|
1631
1656
|
global.$DEBUG = true;
|
|
@@ -1633,11 +1658,11 @@ const keywordDef = {
|
|
|
1633
1658
|
}
|
|
1634
1659
|
} else if ('-' === args[0]) {
|
|
1635
1660
|
if (global.$DEBUG) {
|
|
1636
|
-
delTips("DEBUG")
|
|
1661
|
+
await delTips("DEBUG")
|
|
1637
1662
|
}
|
|
1638
1663
|
} else {
|
|
1639
1664
|
if (global.$DEBUG) {
|
|
1640
|
-
delTips("DEBUG")
|
|
1665
|
+
await delTips("DEBUG")
|
|
1641
1666
|
} else {
|
|
1642
1667
|
global.$DEBUG = true;
|
|
1643
1668
|
setTips("DEBUG", "DEBUG", () => delete global.$DEBUG);
|
|
@@ -1648,7 +1673,7 @@ const keywordDef = {
|
|
|
1648
1673
|
},
|
|
1649
1674
|
test: {
|
|
1650
1675
|
comment: 'test mode',
|
|
1651
|
-
exeFn: (args) => {
|
|
1676
|
+
exeFn: async (args) => {
|
|
1652
1677
|
if ('+' === args[0]) {
|
|
1653
1678
|
if (!global.$TEST) {
|
|
1654
1679
|
global.$TEST = true;
|
|
@@ -1656,11 +1681,11 @@ const keywordDef = {
|
|
|
1656
1681
|
}
|
|
1657
1682
|
} else if ('-' === args[0]) {
|
|
1658
1683
|
if (global.$TEST) {
|
|
1659
|
-
delTips("TEST")
|
|
1684
|
+
await delTips("TEST")
|
|
1660
1685
|
}
|
|
1661
1686
|
} else {
|
|
1662
1687
|
if (global.$TEST) {
|
|
1663
|
-
delTips("TEST")
|
|
1688
|
+
await delTips("TEST")
|
|
1664
1689
|
} else {
|
|
1665
1690
|
global.$TEST = true;
|
|
1666
1691
|
setTips("TEST", "TEST", () => delete global.$TEST);
|
|
@@ -1999,12 +2024,6 @@ function getArgComments(argDef, showShort = false) {
|
|
|
1999
2024
|
let item = warnStr(k) + (shortMap[k] ? ` ${warnStr(shortMap[k])}`:'') + (argDef[k] ? ` ${argDef[k]}`:'')
|
|
2000
2025
|
comments.push(item)
|
|
2001
2026
|
}
|
|
2002
|
-
comments[0] = comments[0]
|
|
2003
|
-
if (comments.length > 1) {
|
|
2004
|
-
for(let i = 1; i< comments.length; i++) {
|
|
2005
|
-
comments[i] = comments[i]
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
2027
|
}
|
|
2009
2028
|
return comments
|
|
2010
2029
|
}
|
|
@@ -2079,6 +2098,9 @@ async function runCmd(str = '', uniqueName = '', text = '') {
|
|
|
2079
2098
|
}
|
|
2080
2099
|
|
|
2081
2100
|
let scriptArgs = await getScriptArgs(argDef, enrichArgs(str.replace(/^\d+\s*/, '')));
|
|
2101
|
+
if (uniqueName) {
|
|
2102
|
+
console.$log(`Execute ${uniqueName}`);
|
|
2103
|
+
}
|
|
2082
2104
|
return await evalText(text, uniqueName, scriptArgs)
|
|
2083
2105
|
}
|
|
2084
2106
|
|
|
@@ -2224,20 +2246,22 @@ function parseArgDef(inputString) {
|
|
|
2224
2246
|
result[s1] = '';
|
|
2225
2247
|
}
|
|
2226
2248
|
}
|
|
2249
|
+
let tempResult = {}
|
|
2227
2250
|
for (let key of Object.keys(result)) {
|
|
2228
2251
|
let comment = result[key];
|
|
2229
2252
|
let defaultValStr = ''
|
|
2230
2253
|
if (key.indexOf("=") !== -1) {
|
|
2231
|
-
delete result[key];
|
|
2232
2254
|
let ss = key.split('=').map(trim);
|
|
2233
2255
|
key = ss[0]
|
|
2234
2256
|
defaultValStr = ss[1]
|
|
2235
2257
|
}
|
|
2236
2258
|
if (defaultValStr) {
|
|
2237
|
-
|
|
2259
|
+
tempResult[key] = ['<' + warnStr(defaultValStr) + '>', comment].join(' ')
|
|
2260
|
+
} else {
|
|
2261
|
+
tempResult[key] = comment
|
|
2238
2262
|
}
|
|
2239
2263
|
}
|
|
2240
|
-
return
|
|
2264
|
+
return tempResult;
|
|
2241
2265
|
}
|
|
2242
2266
|
|
|
2243
2267
|
function getArgDef(text, uniqueName) {
|
|
@@ -2279,7 +2303,7 @@ function getArgDef(text, uniqueName) {
|
|
|
2279
2303
|
|
|
2280
2304
|
function filterRequire(currSpace, cmdMatchStr) {
|
|
2281
2305
|
if (typeof cmdMatchStr === 'number') {
|
|
2282
|
-
cmdMatchStr = '0x' +
|
|
2306
|
+
cmdMatchStr = '0x' + BigNumber(cmdMatchStr).toString(16).padStart(8, '0');
|
|
2283
2307
|
}
|
|
2284
2308
|
cmdMatchStr = trim(cmdMatchStr);
|
|
2285
2309
|
|
|
@@ -2435,9 +2459,6 @@ function _addErrorTag(lines) {
|
|
|
2435
2459
|
}
|
|
2436
2460
|
|
|
2437
2461
|
async function evalText($text = '', $cmdName = '', $args = {}) {
|
|
2438
|
-
if ($cmdName) {
|
|
2439
|
-
console.$log(`Execute ${$cmdName}`);
|
|
2440
|
-
}
|
|
2441
2462
|
let currSpace;
|
|
2442
2463
|
if ($cmdName) {
|
|
2443
2464
|
let pair = parseUniqueName($cmdName)
|
|
@@ -2464,10 +2485,15 @@ async function evalText($text = '', $cmdName = '', $args = {}) {
|
|
|
2464
2485
|
$homeDir, $lib, _cmdMap);
|
|
2465
2486
|
}
|
|
2466
2487
|
|
|
2467
|
-
|
|
2488
|
+
let sigExitCount = 0
|
|
2489
|
+
async function sigExit() {
|
|
2468
2490
|
if (_noAppendNextLine) {
|
|
2469
|
-
|
|
2470
|
-
|
|
2491
|
+
setting.promptId = Date.now();
|
|
2492
|
+
sigExitCount ++;
|
|
2493
|
+
if (sigExitCount > 1) {
|
|
2494
|
+
process.exit(0);
|
|
2495
|
+
}
|
|
2496
|
+
await delTips();
|
|
2471
2497
|
} else {
|
|
2472
2498
|
nextLine();
|
|
2473
2499
|
}
|
|
@@ -2484,9 +2510,9 @@ process.on('rejectionHandled',function(err){
|
|
|
2484
2510
|
})
|
|
2485
2511
|
process.on('SIGINT', sigExit);
|
|
2486
2512
|
process.on('SIGTERM', sigExit);
|
|
2487
|
-
process.on('beforeExit', function () {
|
|
2513
|
+
process.on('beforeExit', async function () {
|
|
2488
2514
|
if (_noAppendNextLine) {
|
|
2489
|
-
|
|
2515
|
+
terminalTitle(null)
|
|
2490
2516
|
} else {
|
|
2491
2517
|
nextLine();
|
|
2492
2518
|
Room.onRoom()
|
package/deps/evalCode.js
CHANGED
|
@@ -19,23 +19,17 @@ module.exports = async ($text = '', $cmdName = '', $args = [],
|
|
|
19
19
|
|
|
20
20
|
const $setTips = $lib.setTips;
|
|
21
21
|
const $delTips = $lib.delTips;
|
|
22
|
-
const $tips =
|
|
23
|
-
set: $lib.setTips,
|
|
24
|
-
del: $lib.delTips,
|
|
25
|
-
has: $lib.hasTips,
|
|
26
|
-
key: $lib.tipKeys
|
|
27
|
-
}
|
|
22
|
+
const $tips = $lib.tipFns;
|
|
28
23
|
const $errorTag = $lib.errorTag;
|
|
29
24
|
const $aop = $lib.aop;
|
|
30
25
|
const $aopAsync = $lib.aopAsync;
|
|
31
26
|
|
|
32
27
|
const $context = {
|
|
33
28
|
$defArgs,
|
|
34
|
-
$data, $config,
|
|
29
|
+
$data, $config, $tips,
|
|
35
30
|
$require, $requires, $import,
|
|
36
31
|
$text, $cmdName, $args,
|
|
37
32
|
$nextLine, $nextText,
|
|
38
|
-
$setTips, $delTips, $tips,
|
|
39
33
|
$enter, $filterCmd,
|
|
40
34
|
$currentSpace, $defaultSpace, $workspaceMap,
|
|
41
35
|
$homeDir, $lib, $cmdMap
|
package/deps/room.js
CHANGED
|
@@ -57,7 +57,7 @@ function onRoom() {
|
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
59
|
res.output = await setting.wrapperInput(req.input, true)
|
|
60
|
-
|
|
60
|
+
setting.promptId = Date.now()
|
|
61
61
|
}
|
|
62
62
|
})
|
|
63
63
|
} catch (e) {
|
|
@@ -113,7 +113,12 @@ async function initNodes() {
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
} else {
|
|
116
|
-
let resp =
|
|
116
|
+
let resp = '';
|
|
117
|
+
try {
|
|
118
|
+
resp = await e(`${tailscalePath} status`);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
debug("initNodes", e)
|
|
121
|
+
}
|
|
117
122
|
for (let line of resp.split("\n").map(trim)) {
|
|
118
123
|
let offline = line.indexOf('offline') !== -1
|
|
119
124
|
let ss = line.split(/\s+/);
|
|
@@ -248,8 +253,8 @@ async function _syncSetting(room) {
|
|
|
248
253
|
setting.services = {}
|
|
249
254
|
setting.serviceFns = {}
|
|
250
255
|
for (const room of setting.rooms) {
|
|
251
|
-
if (
|
|
252
|
-
continue
|
|
256
|
+
if (!room.active) {
|
|
257
|
+
continue;
|
|
253
258
|
}
|
|
254
259
|
for (const pid of Object.keys(room.jsirs || {})) {
|
|
255
260
|
let jsir = room.jsirs[pid];
|
|
@@ -297,7 +302,7 @@ async function processTasks() {
|
|
|
297
302
|
if (unHandleKey) {
|
|
298
303
|
console.$log(process.pid, `run task ${unHandleKey}[${defTasks[unHandleKey]}]`)
|
|
299
304
|
await setting.wrapperInput(defTasks[unHandleKey]);
|
|
300
|
-
if (!
|
|
305
|
+
if (!setting.newError) {
|
|
301
306
|
tasks[unHandleKey] = process.pid;
|
|
302
307
|
console.$log(process.pid, `handle task ${unHandleKey}[${defTasks[unHandleKey]}]`)
|
|
303
308
|
}
|
|
@@ -431,7 +436,7 @@ async function initRoomJsir(room) {
|
|
|
431
436
|
lastUpdateTime: setting.roomTime,
|
|
432
437
|
port: setting.server ? setting.server.address()?.port:null,
|
|
433
438
|
services: services,
|
|
434
|
-
newError:
|
|
439
|
+
newError: setting.newError,
|
|
435
440
|
version: packageJson.version,
|
|
436
441
|
upTime: formatUptime()
|
|
437
442
|
}
|
package/deps/setting.js
CHANGED
|
@@ -46,6 +46,8 @@ module.exports = {
|
|
|
46
46
|
serviceReg: /[^a-zA-Z]service[^a-zA-Z]|[^a-zA-Z]service$/i,
|
|
47
47
|
wrapperInput: null,
|
|
48
48
|
lastOutput: null,
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
lastChangeFlag: null,
|
|
50
|
+
terminalTitle: null,
|
|
51
|
+
promptId: Date.now(),
|
|
52
|
+
newError: false
|
|
51
53
|
}
|
package/deps/util.js
CHANGED
|
@@ -6,7 +6,6 @@ const readline = require('readline')
|
|
|
6
6
|
const fs = require('fs')
|
|
7
7
|
const fp = require('fs').promises
|
|
8
8
|
const BigNumber = require('bignumber.js');
|
|
9
|
-
const pad = require('pad');
|
|
10
9
|
const crypto = require('crypto');
|
|
11
10
|
const dayJs = require('dayjs')
|
|
12
11
|
const table = require('console.table')
|
|
@@ -16,9 +15,6 @@ const _types = setting.fileType
|
|
|
16
15
|
const _typeKeys = Object.keys(_types)
|
|
17
16
|
const util = require('util')
|
|
18
17
|
|
|
19
|
-
global.$newInput = false
|
|
20
|
-
global.$newError = false
|
|
21
|
-
|
|
22
18
|
let libDataDir;
|
|
23
19
|
let lockDir;
|
|
24
20
|
let logDir;
|
|
@@ -255,6 +251,7 @@ function createConsole(uniqueName) {
|
|
|
255
251
|
result.$log = $log;
|
|
256
252
|
result.$error = $error;
|
|
257
253
|
result.$draft = draftLog;
|
|
254
|
+
result.$abort = () => false;
|
|
258
255
|
if (uniqueName) {
|
|
259
256
|
let pair = parseUniqueName(uniqueName)
|
|
260
257
|
let fileName = pair[0] + '/' + pair[1].split(".")[0]
|
|
@@ -267,21 +264,24 @@ function createConsole(uniqueName) {
|
|
|
267
264
|
error: true,
|
|
268
265
|
syncLogs: [result.$log, roomError]
|
|
269
266
|
});
|
|
267
|
+
const promptId = setting.promptId;
|
|
268
|
+
result.$abort = () => promptId !== setting.promptId;
|
|
270
269
|
}
|
|
271
270
|
let quite = false
|
|
271
|
+
let promptId = 0
|
|
272
272
|
if (uniqueName) {
|
|
273
|
-
|
|
273
|
+
promptId = setting.promptId;
|
|
274
274
|
}
|
|
275
275
|
for (let key of Object.keys(_consoleFns)) {
|
|
276
276
|
result[key] = (...args) => {
|
|
277
|
-
if (
|
|
277
|
+
if (promptId !== setting.promptId) {
|
|
278
278
|
quite = true;
|
|
279
279
|
}
|
|
280
280
|
if ('debug' === key && !global.$DEBUG) {
|
|
281
281
|
return;
|
|
282
282
|
}
|
|
283
283
|
if ('error' === key) {
|
|
284
|
-
|
|
284
|
+
setting.newError = true;
|
|
285
285
|
}
|
|
286
286
|
let hasFlag = false;
|
|
287
287
|
let sameFlag = false;
|
|
@@ -309,6 +309,7 @@ function createConsole(uniqueName) {
|
|
|
309
309
|
let _args = _consoleFns[key].args(args);
|
|
310
310
|
let lastOutput = null;
|
|
311
311
|
if (hasFlag) {
|
|
312
|
+
terminalTitle(setting.lastChangeFlag.replace(/^\*/, '').replace(/\*$/, '').trim())
|
|
312
313
|
lastOutput = _args.join(" ")
|
|
313
314
|
if (!isRunningInBackground() && setting.lastOutput && sameFlag) {
|
|
314
315
|
let lines = setting.lastOutput.split('\n').length;
|
|
@@ -336,6 +337,20 @@ console = createConsole();
|
|
|
336
337
|
// fix console done
|
|
337
338
|
|
|
338
339
|
|
|
340
|
+
function terminalTitle(title = 'jsir') {
|
|
341
|
+
if (isRunningInBackground()) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (setting.terminalTitle !== title) {
|
|
345
|
+
setting.terminalTitle = title;
|
|
346
|
+
if (title) {
|
|
347
|
+
process.stdout.write(`\x1b]0;${setting.terminalTitle}\x07`);
|
|
348
|
+
} else {
|
|
349
|
+
process.stdout.write('\x1b]0;\x07');
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
339
354
|
function getFullPath(name) {
|
|
340
355
|
name = trim(name)
|
|
341
356
|
if (!name) {
|
|
@@ -787,10 +802,10 @@ function createLimitLogger(fileName, {
|
|
|
787
802
|
|
|
788
803
|
let text = consoleStrs(...args)
|
|
789
804
|
if (error) {
|
|
790
|
-
|
|
805
|
+
setting.newError = true;
|
|
791
806
|
}
|
|
792
807
|
if (time) {
|
|
793
|
-
text = `${timeStr('YYYY-MM-DD HH:mm:ss.SSS')} ${
|
|
808
|
+
text = `${timeStr('YYYY-MM-DD HH:mm:ss.SSS')} ${String(process.pid%1000).padStart(3, '0')}> ${text}`
|
|
794
809
|
}
|
|
795
810
|
syncQueue(() => fp.appendFile(logPath, text + '\n'), logPath)
|
|
796
811
|
let _minNum = (Date.now()/(1000 * 60 * 10)).toFixed(0)
|
|
@@ -983,16 +998,17 @@ function aesCipher(str, key, useIv = false){
|
|
|
983
998
|
if (!key || key.length > 16) {
|
|
984
999
|
throw "aesCipher key length should be between 1 and 16"
|
|
985
1000
|
}
|
|
1001
|
+
key = key.padEnd(16, '0');
|
|
986
1002
|
if (useIv) {
|
|
987
1003
|
// Generate random IV
|
|
988
1004
|
const iv = crypto.randomBytes(16);
|
|
989
|
-
const cipher = crypto.createCipheriv('aes-128-cbc',
|
|
1005
|
+
const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
|
|
990
1006
|
|
|
991
1007
|
// Return IV and ciphertext, as IV is needed for decryption
|
|
992
1008
|
const ciphertext = cipher.update(str, 'utf8', 'hex') + cipher.final('hex');
|
|
993
1009
|
return iv.toString('hex') + ':' + ciphertext; // Combine IV and ciphertext
|
|
994
1010
|
}
|
|
995
|
-
const cipher = crypto.createCipheriv('aes-128-ecb',
|
|
1011
|
+
const cipher = crypto.createCipheriv('aes-128-ecb', key, null);
|
|
996
1012
|
return cipher.update(str, 'utf8', 'hex') + cipher.final('hex');
|
|
997
1013
|
}
|
|
998
1014
|
|
|
@@ -1004,7 +1020,7 @@ function aesDecipher(str, key){
|
|
|
1004
1020
|
if (!key || key.length > 16) {
|
|
1005
1021
|
throw "aesCipher key length should be between 1 and 16";
|
|
1006
1022
|
}
|
|
1007
|
-
|
|
1023
|
+
key = key.padEnd(16, '0');
|
|
1008
1024
|
// Extract IV and ciphertext
|
|
1009
1025
|
if(str.indexOf(":") !== -1) {
|
|
1010
1026
|
const [ivHex, ciphertext] = str.split(':');
|
|
@@ -1012,10 +1028,10 @@ function aesDecipher(str, key){
|
|
|
1012
1028
|
throw "Invalid encrypted string format";
|
|
1013
1029
|
}
|
|
1014
1030
|
const iv = Buffer.from(ivHex, 'hex');
|
|
1015
|
-
const decipher = crypto.createDecipheriv('aes-128-cbc',
|
|
1031
|
+
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
|
|
1016
1032
|
return decipher.update(ciphertext, 'hex', 'utf8') + decipher.final('utf8');
|
|
1017
1033
|
}
|
|
1018
|
-
const decipher = crypto.createDecipheriv('aes-128-ecb',
|
|
1034
|
+
const decipher = crypto.createDecipheriv('aes-128-ecb', key, null);
|
|
1019
1035
|
return decipher.update(str, 'hex', 'utf8') + decipher.final('utf8');
|
|
1020
1036
|
}
|
|
1021
1037
|
|
|
@@ -1286,19 +1302,21 @@ async function _fileLock(key, fn) {
|
|
|
1286
1302
|
|
|
1287
1303
|
async function fileLock(key, fn, wait = true) {
|
|
1288
1304
|
`
|
|
1289
|
-
文件锁,
|
|
1305
|
+
文件锁, 默认一直等待直到加锁成功执行fn
|
|
1290
1306
|
wait = false, 加锁失败则不执行fn
|
|
1291
1307
|
return void
|
|
1292
1308
|
`
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
break;
|
|
1297
|
-
}
|
|
1298
|
-
await sleep(9);
|
|
1309
|
+
while (true) {
|
|
1310
|
+
if (await _fileLock(key, fn)) {
|
|
1311
|
+
break;
|
|
1299
1312
|
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1313
|
+
if (typeof wait === 'function') {
|
|
1314
|
+
wait = await wait();
|
|
1315
|
+
}
|
|
1316
|
+
if (!wait) {
|
|
1317
|
+
break;
|
|
1318
|
+
}
|
|
1319
|
+
await sleep(9);
|
|
1302
1320
|
}
|
|
1303
1321
|
}
|
|
1304
1322
|
|
|
@@ -1308,32 +1326,35 @@ async function processLock(key, fn, wait = true) {
|
|
|
1308
1326
|
wait = false, 加锁失败则不执行fn
|
|
1309
1327
|
return void
|
|
1310
1328
|
`
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
break;
|
|
1315
|
-
}
|
|
1316
|
-
await sleep(9);
|
|
1329
|
+
while (true) {
|
|
1330
|
+
if (await _processLock(key, fn)) {
|
|
1331
|
+
break;
|
|
1317
1332
|
}
|
|
1318
|
-
|
|
1319
|
-
|
|
1333
|
+
if (typeof wait === 'function') {
|
|
1334
|
+
wait = await wait();
|
|
1335
|
+
}
|
|
1336
|
+
if (!wait) {
|
|
1337
|
+
break;
|
|
1338
|
+
}
|
|
1339
|
+
await sleep(9);
|
|
1320
1340
|
}
|
|
1321
1341
|
}
|
|
1322
1342
|
|
|
1343
|
+
const $locks = {}
|
|
1323
1344
|
async function _processLock(key, fn) {
|
|
1324
1345
|
if (!key || typeof fn !== 'function') {
|
|
1325
1346
|
throw new Error('invalid arguments');
|
|
1326
1347
|
}
|
|
1327
1348
|
key = key.trim();
|
|
1328
|
-
if (
|
|
1349
|
+
if ($locks.hasOwnProperty(key)) {
|
|
1329
1350
|
return false;
|
|
1330
1351
|
}
|
|
1331
|
-
|
|
1352
|
+
$locks[key] = true;
|
|
1332
1353
|
try {
|
|
1333
1354
|
await fn();
|
|
1334
1355
|
return true;
|
|
1335
1356
|
} finally {
|
|
1336
|
-
delete
|
|
1357
|
+
delete $locks[key];
|
|
1337
1358
|
}
|
|
1338
1359
|
}
|
|
1339
1360
|
|
|
@@ -1356,23 +1377,25 @@ function setTips(key, value, onRm) {
|
|
|
1356
1377
|
if (!vl(key) || key.indexOf(",") !== -1) {
|
|
1357
1378
|
throw "invalid tip key";
|
|
1358
1379
|
}
|
|
1359
|
-
|
|
1380
|
+
key = trim(key)
|
|
1381
|
+
getOr(setting.tips, key, []).push(vl(value) ? value:'');
|
|
1360
1382
|
if (onRm) {
|
|
1361
1383
|
getOr(_tipsOnRm, key, []).push(onRm)
|
|
1362
1384
|
}
|
|
1363
1385
|
}
|
|
1364
1386
|
|
|
1365
1387
|
function delTips(...keys) {
|
|
1388
|
+
let pros = []
|
|
1366
1389
|
for (let key of Object.keys(setting.tips)) {
|
|
1367
1390
|
if (keys.length === 0) {
|
|
1368
1391
|
if (key === 'DEBUG') {
|
|
1369
1392
|
continue
|
|
1370
1393
|
}
|
|
1371
1394
|
delete setting.tips[key]
|
|
1372
|
-
tipsOnRmCallback(key)
|
|
1395
|
+
pros.push(tipsOnRmCallback(key))
|
|
1373
1396
|
} else if (keys.indexOf(key) !== -1) {
|
|
1374
1397
|
delete setting.tips[key]
|
|
1375
|
-
tipsOnRmCallback(key)
|
|
1398
|
+
pros.push(tipsOnRmCallback(key))
|
|
1376
1399
|
}
|
|
1377
1400
|
}
|
|
1378
1401
|
if (keys.length === 0) {
|
|
@@ -1380,13 +1403,22 @@ function delTips(...keys) {
|
|
|
1380
1403
|
if (key === 'DEBUG') {
|
|
1381
1404
|
continue
|
|
1382
1405
|
}
|
|
1383
|
-
tipsOnRmCallback(key)
|
|
1406
|
+
pros.push(tipsOnRmCallback(key))
|
|
1384
1407
|
}
|
|
1385
1408
|
}
|
|
1409
|
+
pros = pros.filter(i => i);
|
|
1410
|
+
if (pros.length > 0) {
|
|
1411
|
+
return Promise.all(pros)
|
|
1412
|
+
}
|
|
1386
1413
|
}
|
|
1387
1414
|
|
|
1388
|
-
function hasTips(key) {
|
|
1389
|
-
|
|
1415
|
+
function hasTips(key, value) {
|
|
1416
|
+
key = trim(key)
|
|
1417
|
+
if (vl(value)) {
|
|
1418
|
+
return setting.tips.hasOwnProperty(key) && setting.tips[key].includes(value);
|
|
1419
|
+
} else {
|
|
1420
|
+
return setting.tips.hasOwnProperty(key);
|
|
1421
|
+
}
|
|
1390
1422
|
}
|
|
1391
1423
|
|
|
1392
1424
|
function tipKeys() {
|
|
@@ -1396,15 +1428,22 @@ function tipKeys() {
|
|
|
1396
1428
|
function tipsOnRmCallback(key) {
|
|
1397
1429
|
let callbacks = _tipsOnRm[key]
|
|
1398
1430
|
delete _tipsOnRm[key]
|
|
1431
|
+
const pros = [];
|
|
1399
1432
|
if (callbacks && callbacks.length > 0) {
|
|
1400
1433
|
for (let callback of callbacks) {
|
|
1401
1434
|
try {
|
|
1402
|
-
callback()
|
|
1435
|
+
let result = callback()
|
|
1436
|
+
if (getType(result) === 'Promise') {
|
|
1437
|
+
pros.push(result.catch(e => $error(`[${key}] OnRmCallback`, e)))
|
|
1438
|
+
}
|
|
1403
1439
|
} catch (e) {
|
|
1404
1440
|
$error(`[${key}] OnRmCallback`, e)
|
|
1405
1441
|
}
|
|
1406
1442
|
}
|
|
1407
1443
|
}
|
|
1444
|
+
if (pros.length > 0) {
|
|
1445
|
+
return Promise.all(pros);
|
|
1446
|
+
}
|
|
1408
1447
|
}
|
|
1409
1448
|
|
|
1410
1449
|
async function timer(key, ms, fn, label, printInfo = true){
|
|
@@ -2147,6 +2186,9 @@ end tell
|
|
|
2147
2186
|
function getKeyTips() {
|
|
2148
2187
|
let items = [];
|
|
2149
2188
|
for (let key of Object.keys(setting.tips)) {
|
|
2189
|
+
if (key.startsWith("_")) {
|
|
2190
|
+
continue;
|
|
2191
|
+
}
|
|
2150
2192
|
items.push(trim(key))
|
|
2151
2193
|
}
|
|
2152
2194
|
return items
|
|
@@ -2155,6 +2197,9 @@ function getKeyTips() {
|
|
|
2155
2197
|
function getValTips() {
|
|
2156
2198
|
let items = [];
|
|
2157
2199
|
for (let key of Object.keys(setting.tips)) {
|
|
2200
|
+
if (key.startsWith("_")) {
|
|
2201
|
+
continue;
|
|
2202
|
+
}
|
|
2158
2203
|
let val = setting.tips[key].map(i => {
|
|
2159
2204
|
if (typeof i === 'function') {
|
|
2160
2205
|
try {
|
|
@@ -2260,13 +2305,20 @@ async function aopAsync(items, fn, args) {
|
|
|
2260
2305
|
}
|
|
2261
2306
|
|
|
2262
2307
|
function getMd5Key(str) {
|
|
2263
|
-
return '0x' + md5(str).
|
|
2308
|
+
return '0x' + md5(str).substring(0, 8);
|
|
2264
2309
|
}
|
|
2265
2310
|
|
|
2266
2311
|
function isMd5Key(str) {
|
|
2267
2312
|
return /^0x[a-z\d]{8}$/.test(str);
|
|
2268
2313
|
}
|
|
2269
2314
|
|
|
2315
|
+
const tipFns = {
|
|
2316
|
+
set: setTips,
|
|
2317
|
+
del: delTips,
|
|
2318
|
+
has: hasTips,
|
|
2319
|
+
key: tipKeys
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2270
2322
|
module.exports = {
|
|
2271
2323
|
formatUptime,
|
|
2272
2324
|
wrapperJsirText,
|
|
@@ -2291,7 +2343,6 @@ module.exports = {
|
|
|
2291
2343
|
bMul,
|
|
2292
2344
|
getConfig,
|
|
2293
2345
|
getCbText,
|
|
2294
|
-
pad,
|
|
2295
2346
|
aesCipher,
|
|
2296
2347
|
aesDecipher,
|
|
2297
2348
|
requireG,
|
|
@@ -2387,5 +2438,7 @@ module.exports = {
|
|
|
2387
2438
|
isPidAlive,
|
|
2388
2439
|
cleanFileLocks,
|
|
2389
2440
|
getMd5Key,
|
|
2390
|
-
isMd5Key
|
|
2441
|
+
isMd5Key,
|
|
2442
|
+
terminalTitle,
|
|
2443
|
+
tipFns
|
|
2391
2444
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsir",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.14",
|
|
4
4
|
"description": "JavaScript Script Management Tool",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"bignumber.js": "^9.0.0",
|
|
22
22
|
"chokidar": "^3.5.2",
|
|
23
23
|
"console.table": "^0.10.0",
|
|
24
|
-
"dayjs": "^1.10.4"
|
|
25
|
-
"pad": "^3.2.0"
|
|
24
|
+
"dayjs": "^1.10.4"
|
|
26
25
|
}
|
|
27
26
|
}
|