jsir 2.3.7 → 2.3.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/cmd/oaa.js +56 -41
- package/deps/room.js +38 -22
- package/deps/server.js +42 -3
- package/deps/setting.js +2 -1
- package/deps/util.js +66 -29
- package/package.json +1 -1
package/cmd/oaa.js
CHANGED
|
@@ -11,7 +11,7 @@ const {
|
|
|
11
11
|
createConsole, setTips, delTips,
|
|
12
12
|
getEditor, errorStr, getConfigDir,
|
|
13
13
|
getFullPath, parseUniqueName, toUniqueName, isJsirFileName, toJsirFileName,
|
|
14
|
-
getAlias, wrapperJsirText, eia, getKeyTips, getValTips,
|
|
14
|
+
getAlias, wrapperJsirText, eia, getKeyTips, getValTips, getJsirTypeKey
|
|
15
15
|
} = $lib;
|
|
16
16
|
const _args = process.argv.slice(2).map(trim);
|
|
17
17
|
const evalCode = require('../deps/evalCode')
|
|
@@ -437,9 +437,10 @@ async function save(args) {
|
|
|
437
437
|
return
|
|
438
438
|
}
|
|
439
439
|
let resp;
|
|
440
|
-
|
|
440
|
+
let typeKey = getJsirTypeKey(args[0]);
|
|
441
|
+
if (typeKey === setting.exeKey) {
|
|
441
442
|
resp = example.exeFile;
|
|
442
|
-
} else if (
|
|
443
|
+
} else if (typeKey === setting.initKey) {
|
|
443
444
|
resp = example.initFile;
|
|
444
445
|
} else {
|
|
445
446
|
resp = await getCbText();
|
|
@@ -498,8 +499,8 @@ function listCmd(tmpMap) {
|
|
|
498
499
|
a = parseUniqueName(a)[1];
|
|
499
500
|
b = parseUniqueName(b)[1];
|
|
500
501
|
let typeKeys = Object.keys(_types);
|
|
501
|
-
let orderA = typeKeys.indexOf(a
|
|
502
|
-
let orderB = typeKeys.indexOf(b
|
|
502
|
+
let orderA = typeKeys.indexOf(getJsirTypeKey(a));
|
|
503
|
+
let orderB = typeKeys.indexOf(getJsirTypeKey(b));
|
|
503
504
|
orderA = orderA === -1 ? 999999:orderA;
|
|
504
505
|
orderB = orderB === -1 ? 999999:orderB;
|
|
505
506
|
return orderA - orderB
|
|
@@ -521,7 +522,7 @@ function listCmd(tmpMap) {
|
|
|
521
522
|
let item = {
|
|
522
523
|
key: ' ' + i,
|
|
523
524
|
name: pair[0] + '/' + name,
|
|
524
|
-
type: [_types[name
|
|
525
|
+
type: [_types[getJsirTypeKey(name)] || setting.defaultType, suffix].map(trim).join(".")
|
|
525
526
|
}
|
|
526
527
|
items.push(item)
|
|
527
528
|
|
|
@@ -620,7 +621,7 @@ async function _wrapperInput(str) {
|
|
|
620
621
|
let path = getFullPath(_cmdMap[strs[0]])
|
|
621
622
|
let uniqueName = trim(_cmdMap[strs[0]]);
|
|
622
623
|
let fileName = parseUniqueName(uniqueName)[1]
|
|
623
|
-
let firstName = fileName
|
|
624
|
+
let firstName = getJsirTypeKey(fileName)
|
|
624
625
|
if (firstName === setting.fileKey) {
|
|
625
626
|
await workFile(uniqueName)
|
|
626
627
|
} else if (firstName !== setting.exeKey) {
|
|
@@ -964,6 +965,41 @@ let compareMode = {
|
|
|
964
965
|
}
|
|
965
966
|
}
|
|
966
967
|
|
|
968
|
+
async function showRooms() {
|
|
969
|
+
let results = [];
|
|
970
|
+
for (let i = 0; i < setting.rooms.length; i++) {
|
|
971
|
+
let room = setting.rooms[i]
|
|
972
|
+
let isLocal = setting.selfRoom.selfNode === room.selfNode;
|
|
973
|
+
results.push({
|
|
974
|
+
mid: i,
|
|
975
|
+
name: (isLocal ? "*" : " ") + room.name,
|
|
976
|
+
node: room.selfNode,
|
|
977
|
+
active: room.active,
|
|
978
|
+
})
|
|
979
|
+
for (let key of Object.keys(room.jsirs)) {
|
|
980
|
+
let jsir = room.jsirs[key]
|
|
981
|
+
results.push({
|
|
982
|
+
mid: i,
|
|
983
|
+
name: (isLocal ? "*" : " ") + room.name,
|
|
984
|
+
node: room.selfNode,
|
|
985
|
+
active: room.active,
|
|
986
|
+
pid: (process.pid === jsir.pid ? "*" : " ") + jsir.pid,
|
|
987
|
+
space: jsir.space,
|
|
988
|
+
running: jsir.active,
|
|
989
|
+
port: jsir.port,
|
|
990
|
+
back: jsir.back,
|
|
991
|
+
busy: jsir.busy,
|
|
992
|
+
tips: Object.keys(jsir.tips).map(i => i + ': ' + jsir.tips[i]).join('\n')
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
if (results.length > 0) {
|
|
997
|
+
console.nable(results)
|
|
998
|
+
} else {
|
|
999
|
+
console.warn("no items")
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
967
1003
|
const keywordDef = {
|
|
968
1004
|
help: {
|
|
969
1005
|
comment: 'Help documentation',
|
|
@@ -1404,39 +1440,17 @@ const keywordDef = {
|
|
|
1404
1440
|
short: 'D'
|
|
1405
1441
|
},
|
|
1406
1442
|
room: {
|
|
1407
|
-
comment: 'manage room',
|
|
1443
|
+
comment: 'manage room ([node])',
|
|
1408
1444
|
exeFn: async (args) => {
|
|
1409
|
-
let results = [];
|
|
1410
1445
|
await room.syncSetting();
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
node: room.selfNode,
|
|
1417
|
-
active: room.active,
|
|
1418
|
-
})
|
|
1419
|
-
for (let key of Object.keys(room.jsirs)) {
|
|
1420
|
-
let jsir = room.jsirs[key]
|
|
1421
|
-
results.push({
|
|
1422
|
-
mid: i,
|
|
1423
|
-
name: (room.local ? "*":"") + room.name,
|
|
1424
|
-
node: room.selfNode,
|
|
1425
|
-
active: room.active,
|
|
1426
|
-
pid: (process.pid === jsir.pid ? "*":" ") + jsir.pid,
|
|
1427
|
-
space: jsir.space,
|
|
1428
|
-
running: jsir.active,
|
|
1429
|
-
port: jsir.port,
|
|
1430
|
-
back: jsir.back,
|
|
1431
|
-
busy: jsir.busy,
|
|
1432
|
-
tips: Object.keys(jsir.tips).map(i => i + ': ' + jsir.tips[i]).join('\n')
|
|
1433
|
-
});
|
|
1446
|
+
if (args[0]) {
|
|
1447
|
+
if (setting.selfRoom.nodes.indexOf(args[0]) !== -1) {
|
|
1448
|
+
await eia("ssh", [args[0]])
|
|
1449
|
+
} else {
|
|
1450
|
+
console.warn("invalid node")
|
|
1434
1451
|
}
|
|
1435
|
-
}
|
|
1436
|
-
if (results.length > 0) {
|
|
1437
|
-
console.nable(results)
|
|
1438
1452
|
} else {
|
|
1439
|
-
|
|
1453
|
+
await showRooms();
|
|
1440
1454
|
}
|
|
1441
1455
|
},
|
|
1442
1456
|
short: 'm'
|
|
@@ -1450,7 +1464,7 @@ function getQuickRunCmds(input, matchStr) {
|
|
|
1450
1464
|
} else if (input.startsWith("/")) {
|
|
1451
1465
|
matchStr = '/' + matchStr;
|
|
1452
1466
|
}
|
|
1453
|
-
return filterCmd(matchStr).filter(i => parseUniqueName(i)[1]
|
|
1467
|
+
return filterCmd(matchStr).filter(i => getJsirTypeKey(parseUniqueName(i)[1]) === setting.exeKey)
|
|
1454
1468
|
}
|
|
1455
1469
|
|
|
1456
1470
|
async function preLoad(text, fnNameMatch, fn, packages = [], space) {
|
|
@@ -1963,7 +1977,7 @@ function parseArgDef(inputString) {
|
|
|
1963
1977
|
}
|
|
1964
1978
|
|
|
1965
1979
|
function getArgDef(text, uniqueName) {
|
|
1966
|
-
if (uniqueName &&
|
|
1980
|
+
if (uniqueName && getJsirTypeKey(parseUniqueName(uniqueName)[1]) !== setting.exeKey) {
|
|
1967
1981
|
return {}
|
|
1968
1982
|
}
|
|
1969
1983
|
if (text.indexOf("$defArgs") === -1) {
|
|
@@ -2025,7 +2039,7 @@ function filterRequire(currSpace, cmdMatchStr) {
|
|
|
2025
2039
|
cmds = cmds.filter(cmd => parseUniqueName(cmd)[0] === (appointSpace || currSpace))
|
|
2026
2040
|
}
|
|
2027
2041
|
if (cmds.length > 0) {
|
|
2028
|
-
cmds = cmds.filter(cmd => parseUniqueName(cmd)[1]
|
|
2042
|
+
cmds = cmds.filter(cmd => getJsirTypeKey(parseUniqueName(cmd)[1]) === setting.initKey)
|
|
2029
2043
|
}
|
|
2030
2044
|
}
|
|
2031
2045
|
if (cmds.length > 1) {
|
|
@@ -2042,9 +2056,10 @@ async function _requireSource(currSpace, cmdMatchStr) {
|
|
|
2042
2056
|
let path = getFullPath(uniqueName)
|
|
2043
2057
|
let text = String(await fp.readFile(path))
|
|
2044
2058
|
let pair = parseUniqueName(uniqueName)
|
|
2045
|
-
|
|
2059
|
+
let typeKey = getJsirTypeKey(pair[1]);
|
|
2060
|
+
if (typeKey === setting.initKey) {
|
|
2046
2061
|
result = await evalText(text, uniqueName)
|
|
2047
|
-
} else if (
|
|
2062
|
+
} else if (typeKey === setting.exeKey) {
|
|
2048
2063
|
result = async (argsStr) => {
|
|
2049
2064
|
return await runCmd(trim(argsStr), uniqueName, text)
|
|
2050
2065
|
}
|
package/deps/room.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
const os = require('os');
|
|
2
2
|
const {fileJson, fileLock, vl, createConsole, getKeyTips, getValTips,
|
|
3
|
-
getRoomsDir, e, regEach
|
|
4
|
-
|
|
3
|
+
getRoomsDir, e, regEach, isRunningInBackground,
|
|
4
|
+
batchAsync
|
|
5
|
+
} = require('./util');
|
|
6
|
+
const {setRoute, createSign} = require('../deps/server')
|
|
5
7
|
const roomDataFile = "jsirRoom.json"
|
|
6
8
|
const roomsDirLockKey = "RW_" + getRoomsDir();
|
|
7
9
|
const syncRoomsLockKey = "SyncRooms_" + getRoomsDir();
|
|
@@ -71,7 +73,6 @@ function getSelfIP(nodes) {
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
async function getTailscaleNodes() {
|
|
74
|
-
console.$log("getNodes")
|
|
75
76
|
let resp = await e(`${tailscalePath} status`);
|
|
76
77
|
let nodes = []
|
|
77
78
|
regEach(resp, /^(\d+\.\d+\.\d+\.\d+)\s+/mg, arr => {
|
|
@@ -94,28 +95,36 @@ async function enrichRoomInfo() {
|
|
|
94
95
|
room.nodes = nodes;
|
|
95
96
|
room.lastUpdateTime = Date.now()
|
|
96
97
|
console.$log("init room", room.name)
|
|
98
|
+
|
|
99
|
+
// 提前设置一下
|
|
100
|
+
setting.selfRoom = Object.assign(setting.selfRoom || {}, room);
|
|
97
101
|
})
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
async function syncRooms() {
|
|
101
|
-
console.$log('syncRooms')
|
|
102
105
|
let roomsDir = getRoomsDir();
|
|
103
106
|
let room = await fileJson(roomDataFile)
|
|
104
107
|
|
|
105
108
|
let syncRooms = []
|
|
109
|
+
let fns = []
|
|
106
110
|
for (let node of room.nodes) {
|
|
107
111
|
if (node === room.selfNode) {
|
|
108
112
|
continue
|
|
109
113
|
}
|
|
110
|
-
|
|
111
|
-
let respBody =
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
fns.push(async () => {
|
|
115
|
+
let respBody = ''
|
|
116
|
+
try {
|
|
117
|
+
respBody = await reqNode(node, "get", "/");
|
|
118
|
+
syncRooms.push(JSON.parse(respBody))
|
|
119
|
+
console.$log(`sync ${node} success`);
|
|
120
|
+
} catch (e) {
|
|
121
|
+
console.$log(`sync ${node} failed:`, respBody, e);
|
|
122
|
+
}
|
|
123
|
+
})
|
|
116
124
|
}
|
|
125
|
+
await batchAsync(fns, 9, 3000);
|
|
117
126
|
await fileLock(roomsDirLockKey, async () => {
|
|
118
|
-
for (let syncRoom of syncRooms) {
|
|
127
|
+
for (let syncRoom of [...syncRooms]) {
|
|
119
128
|
if (syncRoom.selfNode) {
|
|
120
129
|
await fp.writeFile(roomsDir + "/" + syncRoom.selfNode, JSON.stringify(syncRoom, null, 2))
|
|
121
130
|
}
|
|
@@ -134,6 +143,7 @@ async function syncRooms() {
|
|
|
134
143
|
}
|
|
135
144
|
}
|
|
136
145
|
}
|
|
146
|
+
console.$log('syncRooms done')
|
|
137
147
|
}
|
|
138
148
|
|
|
139
149
|
async function syncSetting() {
|
|
@@ -143,7 +153,6 @@ async function syncSetting() {
|
|
|
143
153
|
|
|
144
154
|
async function _syncSetting(room) {
|
|
145
155
|
setting.selfRoom = room;
|
|
146
|
-
setting.selfRoom.local = true;
|
|
147
156
|
let roomDir = getRoomsDir();
|
|
148
157
|
let rooms = []
|
|
149
158
|
let files = await fp.readdir(roomDir);
|
|
@@ -166,9 +175,9 @@ async function _syncSetting(room) {
|
|
|
166
175
|
}
|
|
167
176
|
setting.rooms = [setting.selfRoom, ...rooms]
|
|
168
177
|
.map(room => {
|
|
169
|
-
room.active = Date.now() - (room.lastUpdateTime || 0) <=
|
|
178
|
+
room.active = Date.now() - (room.lastUpdateTime || 0) <= 9000;
|
|
170
179
|
Object.entries(room.jsirs).forEach(([key, jsir]) =>
|
|
171
|
-
jsir.active = Date.now() - (jsir.lastUpdateTime || 0) <=
|
|
180
|
+
jsir.active = Date.now() - (jsir.lastUpdateTime || 0) <= 9000)
|
|
172
181
|
return room;
|
|
173
182
|
});
|
|
174
183
|
}
|
|
@@ -177,14 +186,14 @@ async function initRoom() {
|
|
|
177
186
|
let roomUpdateTouchTime = false;
|
|
178
187
|
await fileJson(roomDataFile, async room => {
|
|
179
188
|
await initRoomJsir(room)
|
|
180
|
-
if (!vl(room.lastUpdateTime) || (Date.now() - room.lastUpdateTime) >
|
|
189
|
+
if (!vl(room.lastUpdateTime) || (Date.now() - room.lastUpdateTime) > 3000) {
|
|
181
190
|
roomUpdateTouchTime = true;
|
|
182
191
|
}
|
|
183
192
|
})
|
|
184
193
|
|
|
185
194
|
if (roomUpdateTouchTime) {
|
|
186
195
|
await fileLock(enrichRoomInfoLockKey, enrichRoomInfo, false)
|
|
187
|
-
|
|
196
|
+
fileLock(syncRoomsLockKey, syncRooms, false);
|
|
188
197
|
}
|
|
189
198
|
|
|
190
199
|
await syncSetting();
|
|
@@ -216,11 +225,6 @@ async function initRoomJsir(room) {
|
|
|
216
225
|
lastUpdateTime: Date.now(),
|
|
217
226
|
port: setting.server ? setting.server.address().port:null
|
|
218
227
|
}
|
|
219
|
-
console.$log("init jsir", process.pid)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function isRunningInBackground() {
|
|
223
|
-
return !(process.stdout.isTTY && process.stdin.isTTY);
|
|
224
228
|
}
|
|
225
229
|
|
|
226
230
|
/**
|
|
@@ -295,12 +299,18 @@ function checkPortOpen(ip, port) {
|
|
|
295
299
|
});
|
|
296
300
|
}
|
|
297
301
|
|
|
302
|
+
function isDisableConnect(node, port) {
|
|
303
|
+
let disableTime = setting.disableConnect[node + ":" + port] || 0;
|
|
304
|
+
return disableTime > Date.now()
|
|
305
|
+
}
|
|
306
|
+
|
|
298
307
|
async function reqNode(node, method, url) {
|
|
299
308
|
let port = 52108;
|
|
300
309
|
let room = setting.rooms.filter(i => i.selfNode === node)[0]
|
|
301
310
|
if (room) {
|
|
302
311
|
let activeJsir = Object.values(room.jsirs)
|
|
303
|
-
.filter(i =>
|
|
312
|
+
.filter(i => !isDisableConnect(node, i.port))
|
|
313
|
+
.sort((a,b) => a.busy - b.busy);
|
|
304
314
|
if (activeJsir.length > 0) {
|
|
305
315
|
port = activeJsir[0].port;
|
|
306
316
|
}
|
|
@@ -310,6 +320,9 @@ async function reqNode(node, method, url) {
|
|
|
310
320
|
port: port, // HTTP 默认端口
|
|
311
321
|
path: url,
|
|
312
322
|
method: method.toUpperCase(),
|
|
323
|
+
headers: {
|
|
324
|
+
'sign': createSign()
|
|
325
|
+
}
|
|
313
326
|
};
|
|
314
327
|
console.$log('reqRoom', JSON.stringify(opt))
|
|
315
328
|
return await new Promise((resolve, reject) => {
|
|
@@ -327,6 +340,9 @@ async function reqNode(node, method, url) {
|
|
|
327
340
|
|
|
328
341
|
// 错误处理
|
|
329
342
|
req.on('error', (e) => {
|
|
343
|
+
if (room) {
|
|
344
|
+
setting.disableConnect[node + ":" + port] = Date.now() + 9000
|
|
345
|
+
}
|
|
330
346
|
reject(e)
|
|
331
347
|
});
|
|
332
348
|
|
package/deps/server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const http = require('http');
|
|
2
|
-
const {createConsole, vl} = require('./util');
|
|
2
|
+
const {createConsole, vl, aesDecipher, md5, aesCipher} = require('./util');
|
|
3
3
|
const console = createConsole();
|
|
4
4
|
const setting = require('../deps/setting')
|
|
5
5
|
// 尝试监听的端口
|
|
@@ -8,6 +8,24 @@ const preferredPort = 52108;
|
|
|
8
8
|
const routes = {};
|
|
9
9
|
let invokeStart = false;
|
|
10
10
|
|
|
11
|
+
function verifySign(sign) {
|
|
12
|
+
try {
|
|
13
|
+
let key = md5([...setting.selfRoom.nodes].sort().join(":")).substring(0, 16);
|
|
14
|
+
return parseInt(aesDecipher(sign, key), 10); // 假设sign是base64编码的毫秒数
|
|
15
|
+
} catch (e) {
|
|
16
|
+
return null; // 解码失败返回null
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function createSign() {
|
|
21
|
+
try {
|
|
22
|
+
let key = md5([...setting.selfRoom.nodes].sort().join(":")).substring(0, 16);
|
|
23
|
+
return aesCipher(String(Date.now()), key)
|
|
24
|
+
} catch (e) {
|
|
25
|
+
return null; // 解码失败返回null
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
11
29
|
// 创建一个 HTTP 服务
|
|
12
30
|
async function createServer(port) {
|
|
13
31
|
const server = http.createServer(async (req, res) => {
|
|
@@ -17,6 +35,26 @@ async function createServer(port) {
|
|
|
17
35
|
// 查找对应的路由处理函数
|
|
18
36
|
const routeKey = `${method} ${url}`;
|
|
19
37
|
if (routes[routeKey]) {
|
|
38
|
+
// 取header里的sign字段
|
|
39
|
+
const sign = req.headers['sign'];
|
|
40
|
+
if (sign) {
|
|
41
|
+
const decodedTime = verifySign(sign);
|
|
42
|
+
const currentTime = Date.now();
|
|
43
|
+
|
|
44
|
+
if (decodedTime === null || Math.abs(currentTime - decodedTime) > 3000) {
|
|
45
|
+
// 解码失败或者时间差大于9秒,返回403
|
|
46
|
+
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
47
|
+
res.end('Forbidden: Invalid Sign\n');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
// 如果没有sign字段,返回403
|
|
52
|
+
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
53
|
+
res.end('Forbidden: Missing Sign\n');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 如果签名通过,继续处理请求
|
|
20
58
|
await routes[routeKey](req, res);
|
|
21
59
|
} else {
|
|
22
60
|
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
@@ -44,7 +82,7 @@ async function startServer() {
|
|
|
44
82
|
try {
|
|
45
83
|
setting.server = await createServer(preferredPort);
|
|
46
84
|
} catch (e) {
|
|
47
|
-
console.$log("startServer failed
|
|
85
|
+
console.$log("startServer failed, try other port")
|
|
48
86
|
setting.server = await createServer(0);
|
|
49
87
|
}
|
|
50
88
|
}
|
|
@@ -107,5 +145,6 @@ function jsonHandle(req, res, fn) {
|
|
|
107
145
|
module.exports = {
|
|
108
146
|
setRoute,
|
|
109
147
|
delRoute,
|
|
110
|
-
jsonHandle
|
|
148
|
+
jsonHandle,
|
|
149
|
+
createSign
|
|
111
150
|
};
|
package/deps/setting.js
CHANGED
package/deps/util.js
CHANGED
|
@@ -14,6 +14,7 @@ const initModulePaths = Object.assign([], module.paths)
|
|
|
14
14
|
const path = require('path')
|
|
15
15
|
const _types = setting.fileType
|
|
16
16
|
const _typeKeys = Object.keys(_types)
|
|
17
|
+
const util = require('util')
|
|
17
18
|
|
|
18
19
|
global.$newInput = false
|
|
19
20
|
global.$newError = false
|
|
@@ -26,6 +27,37 @@ let configDir;
|
|
|
26
27
|
let roomsDir;
|
|
27
28
|
let dataDir;
|
|
28
29
|
|
|
30
|
+
|
|
31
|
+
function isRunningInBackground() {
|
|
32
|
+
return !(process.stdout.isTTY && process.stdin.isTTY);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 模拟 console.log 的输出字符串,返回打印的完整字符串
|
|
37
|
+
* @param {...any} args - 传入的参数
|
|
38
|
+
* @returns {string} - 返回最终打印的完整字符串
|
|
39
|
+
*/
|
|
40
|
+
function consoleStrs(...args) {
|
|
41
|
+
// 如果没有参数,返回空字符串
|
|
42
|
+
if (args.length === 0) {
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 格式化第一个参数
|
|
47
|
+
if (typeof args[0] === 'string') {
|
|
48
|
+
return util.format(...args); // 处理格式化字符串 (%s, %d 等)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 如果第一个参数不是字符串,直接用空格拼接其他参数的字符串化结果
|
|
52
|
+
return args
|
|
53
|
+
.map((arg) =>
|
|
54
|
+
typeof arg !== 'string'
|
|
55
|
+
? util.inspect(arg, { depth: 2, colors: true }) // 对象序列化
|
|
56
|
+
: String(arg) // 其他类型转为字符串
|
|
57
|
+
)
|
|
58
|
+
.join(' ');
|
|
59
|
+
}
|
|
60
|
+
|
|
29
61
|
class SyncQueue {
|
|
30
62
|
constructor() {
|
|
31
63
|
this.queue = [];
|
|
@@ -135,15 +167,15 @@ function dealLevelArgs(levelStrFn, args) {
|
|
|
135
167
|
if (args.length <= 0) {
|
|
136
168
|
return args;
|
|
137
169
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
170
|
+
let text = consoleStrs(...args)
|
|
171
|
+
if (typeof args[0] === "string" && args[0].trim() && text.startsWith(args[0])) {
|
|
172
|
+
if(text.length === args[0].length) {
|
|
173
|
+
text = levelStrFn(args[0])
|
|
174
|
+
} else {
|
|
175
|
+
text = levelStrFn(args[0]) + ' ' + consoleStrs(...args.slice(1))
|
|
176
|
+
}
|
|
144
177
|
}
|
|
145
|
-
|
|
146
|
-
return args
|
|
178
|
+
return text;
|
|
147
179
|
}
|
|
148
180
|
|
|
149
181
|
const _console =Object.assign({}, global.console);
|
|
@@ -162,23 +194,23 @@ const _consoleFns= {
|
|
|
162
194
|
},
|
|
163
195
|
info: {
|
|
164
196
|
fn: _console.info,
|
|
165
|
-
args: args => [infoStr('[info]'),
|
|
197
|
+
args: args => [infoStr('[info]'), dealLevelArgs(infoStr, args)]
|
|
166
198
|
},
|
|
167
199
|
msg: {
|
|
168
200
|
fn: _console.log,
|
|
169
|
-
args: args => [msgStr('[msg]'),
|
|
201
|
+
args: args => [msgStr('[msg]'), dealLevelArgs(msgStr, args)]
|
|
170
202
|
},
|
|
171
203
|
warn: {
|
|
172
204
|
fn: _console.warn,
|
|
173
|
-
args: args => [warnStr('[warn]'),
|
|
205
|
+
args: args => [warnStr('[warn]'), dealLevelArgs(warnStr, args)],
|
|
174
206
|
},
|
|
175
207
|
error: {
|
|
176
208
|
fn: _console.error,
|
|
177
|
-
args: args => [errorStr('[error]'),
|
|
209
|
+
args: args => [errorStr('[error]'), dealLevelArgs(errorStr, args)]
|
|
178
210
|
},
|
|
179
211
|
debug: {
|
|
180
212
|
fn: _console.debug,
|
|
181
|
-
args: args => [debugStr('[debug]'),
|
|
213
|
+
args: args => [debugStr('[debug]'), dealLevelArgs(debugStr, args)]
|
|
182
214
|
}
|
|
183
215
|
}
|
|
184
216
|
|
|
@@ -224,7 +256,7 @@ function createConsole(uniqueName) {
|
|
|
224
256
|
if ('debug' === key && !global.$DEBUG) {
|
|
225
257
|
return;
|
|
226
258
|
}
|
|
227
|
-
if (uniqueName && quite) {
|
|
259
|
+
if (isRunningInBackground() || (uniqueName && quite)) {
|
|
228
260
|
if ((key === 'table' || key === 'nable') && typeof args[0] === "object") {
|
|
229
261
|
args = ['', ...args]
|
|
230
262
|
}
|
|
@@ -660,16 +692,15 @@ function createLimitLogger(fileName, {
|
|
|
660
692
|
if (args.length <= 0) {
|
|
661
693
|
return
|
|
662
694
|
}
|
|
663
|
-
// 处理参数
|
|
664
|
-
args = args.map(i => isError(i) ? errorStack(i):i);
|
|
665
695
|
|
|
666
696
|
// 处理同步函数
|
|
667
697
|
syncLogs.forEach(i => i(...args));
|
|
668
698
|
|
|
669
|
-
let text = args
|
|
699
|
+
let text = consoleStrs(...args)
|
|
670
700
|
if (error) {
|
|
671
701
|
global.$newError = true;
|
|
672
702
|
}
|
|
703
|
+
text = `${pad(3, String(process.pid%1000), ' ')}> ${text}`
|
|
673
704
|
if (time) {
|
|
674
705
|
text = `${timeStr('YYYY-MM-DD HH:mm:ss.SSS')} ${text}`
|
|
675
706
|
}
|
|
@@ -700,10 +731,10 @@ function getInitName(fileName) {
|
|
|
700
731
|
fileName = trim(fileName)
|
|
701
732
|
let homeDir = setting.workspaceMap[setting.defaultSpace]
|
|
702
733
|
if (!fileName.startsWith("/")) {
|
|
703
|
-
fileName
|
|
704
|
-
|
|
705
|
-
fileName = fileName + '.js'
|
|
734
|
+
if (getJsirTypeKey(fileName) !== setting.initKey) {
|
|
735
|
+
fileName = setting.initKey + ' ' + fileName
|
|
706
736
|
}
|
|
737
|
+
fileName = toJsirFileName(fileName)
|
|
707
738
|
fileName = homeDir + '/' + fileName
|
|
708
739
|
}
|
|
709
740
|
return fileName;
|
|
@@ -768,7 +799,7 @@ async function fileJson(key, fn = null, fmt = true, safeMs = 49000) {
|
|
|
768
799
|
let fileName = trim(key)
|
|
769
800
|
let path = dataDir + "/" + fileName;
|
|
770
801
|
let homeDir = setting.workspaceMap[setting.defaultSpace]
|
|
771
|
-
let isInit = fileName
|
|
802
|
+
let isInit = getJsirTypeKey(fileName) === setting.initKey;
|
|
772
803
|
if (isInit) {
|
|
773
804
|
path = homeDir + '/' + toJsirFileName(fileName);
|
|
774
805
|
}
|
|
@@ -868,7 +899,7 @@ function aesCipher(str, key){
|
|
|
868
899
|
const cipher = crypto.createCipheriv('aes-128-ecb', pad(key, 16, '0'), null);
|
|
869
900
|
return cipher.update(str, 'utf8', 'hex') + cipher.final('hex');
|
|
870
901
|
} catch(err) {
|
|
871
|
-
$
|
|
902
|
+
$log(err)
|
|
872
903
|
throw 'aesCipher failed: ' + String(err)
|
|
873
904
|
}
|
|
874
905
|
}
|
|
@@ -885,7 +916,7 @@ function aesDecipher(str, key){
|
|
|
885
916
|
const decipher = crypto.createDecipheriv('aes-128-ecb', pad(key, 16, '0'), null);
|
|
886
917
|
return decipher.update(str, 'hex', 'utf8') + decipher.final('utf8');
|
|
887
918
|
} catch(err) {
|
|
888
|
-
$
|
|
919
|
+
$log(err)
|
|
889
920
|
throw 'aesDecipher failed: ' + String(err)
|
|
890
921
|
}
|
|
891
922
|
}
|
|
@@ -1813,7 +1844,7 @@ function md5(message) {
|
|
|
1813
1844
|
return crypto.createHash('md5').update(message).digest('hex');
|
|
1814
1845
|
}
|
|
1815
1846
|
|
|
1816
|
-
async function batchAsync(fns = [], asyncNum = 1) {
|
|
1847
|
+
async function batchAsync(fns = [], asyncNum = 1, limitMs = 9000) {
|
|
1817
1848
|
if (fns.length <= 0 || asyncNum < 1) {
|
|
1818
1849
|
return []
|
|
1819
1850
|
}
|
|
@@ -1823,9 +1854,9 @@ async function batchAsync(fns = [], asyncNum = 1) {
|
|
|
1823
1854
|
for(let i = 0; i< fns.length; i++) {
|
|
1824
1855
|
let pro = new Promise(async (resolve, reject) => {
|
|
1825
1856
|
try {
|
|
1826
|
-
let resp = await fns[i]();
|
|
1857
|
+
let resp = await timeLimit([fns[i]()], limitMs);
|
|
1827
1858
|
doneMap[i] = pro;
|
|
1828
|
-
resolve(resp)
|
|
1859
|
+
resolve(resp[0])
|
|
1829
1860
|
} catch (e) {
|
|
1830
1861
|
doneMap[i] = pro;
|
|
1831
1862
|
resolve(isError(e) ? e:new Error(e));
|
|
@@ -1931,8 +1962,8 @@ function getTextComments(text) {
|
|
|
1931
1962
|
|
|
1932
1963
|
function wrapperJsirText(text) {
|
|
1933
1964
|
return text
|
|
1934
|
-
.replace(/^require\s*\(\s*(["'`][ei]
|
|
1935
|
-
.replace(/([\s=;])require\s*\(\s*(["'`][ei]
|
|
1965
|
+
.replace(/^require\s*\(\s*(["'`][ei][^a-zA-Z]+)/mg, 'await $require($2')
|
|
1966
|
+
.replace(/([\s=;])require\s*\(\s*(["'`][ei][^a-zA-Z]+)/g, '$1await $require($2')
|
|
1936
1967
|
.replace(/([\s=;])import\s*\(/g, '$1$import(')
|
|
1937
1968
|
.replace(/^import\s*\(/mg, '$import(')
|
|
1938
1969
|
.replace(/^module\.exports\s*=\s*/m, 'return ')
|
|
@@ -1980,6 +2011,10 @@ function getValTips() {
|
|
|
1980
2011
|
return items
|
|
1981
2012
|
}
|
|
1982
2013
|
|
|
2014
|
+
function getJsirTypeKey(fileName) {
|
|
2015
|
+
return fileName.split(/[^a-zA-Z]+/)[0] || ''
|
|
2016
|
+
}
|
|
2017
|
+
|
|
1983
2018
|
module.exports = {
|
|
1984
2019
|
wrapperJsirText,
|
|
1985
2020
|
run,
|
|
@@ -2084,5 +2119,7 @@ module.exports = {
|
|
|
2084
2119
|
getKeyTips,
|
|
2085
2120
|
getValTips,
|
|
2086
2121
|
getRoomsDir,
|
|
2087
|
-
getDataDir
|
|
2122
|
+
getDataDir,
|
|
2123
|
+
getJsirTypeKey,
|
|
2124
|
+
isRunningInBackground
|
|
2088
2125
|
}
|