jsir 2.4.5 → 2.4.6
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 +21 -29
- package/deps/room.js +124 -47
- package/deps/server.js +1 -1
- package/deps/setting.js +1 -1
- package/deps/util.js +18 -18
- package/package.json +1 -1
package/cmd/oaa.js
CHANGED
|
@@ -30,9 +30,8 @@ const _libDataDir = getLibDataDir()
|
|
|
30
30
|
const _fileWatcherMap = {}
|
|
31
31
|
const _types = setting.fileType
|
|
32
32
|
const console = createConsole();
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const {reqNode} = require("../deps/room");
|
|
33
|
+
const Room = require('../deps/room');
|
|
34
|
+
const Server = require('../deps/server')
|
|
36
35
|
|
|
37
36
|
let lastFilterArg = '';
|
|
38
37
|
let _cmdMapFile = setting.name + 'CmdMap.json'
|
|
@@ -675,9 +674,9 @@ async function joinServer(uniqueName) {
|
|
|
675
674
|
let pair = parseUniqueName(uniqueName)
|
|
676
675
|
for (let key of Object.keys(exportLib)) {
|
|
677
676
|
let val = exportLib[key];
|
|
678
|
-
|
|
677
|
+
Server.setRoute('post', `/${pair[0]}/${trimJsirFileName(pair[1])}/${key}`,async (req, res) => {
|
|
679
678
|
res.result = await val(...req);
|
|
680
|
-
}
|
|
679
|
+
})
|
|
681
680
|
}
|
|
682
681
|
console.msg(uniqueName, 'has become a service.');
|
|
683
682
|
}
|
|
@@ -1187,11 +1186,13 @@ const keywordDef = {
|
|
|
1187
1186
|
setting: {
|
|
1188
1187
|
comment: 'Global settings',
|
|
1189
1188
|
exeFn: async (args) => {
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1189
|
+
if (args[0]) {
|
|
1190
|
+
if (_cmdMap[args[0]]){
|
|
1191
|
+
let uniqueName = _cmdMap[args[0]];
|
|
1192
|
+
await eia(getEditor(), [`${getConfigDir()}/${md5(uniqueName)}.json`])
|
|
1193
|
+
} else {
|
|
1194
|
+
console.warn('invalid args')
|
|
1195
|
+
}
|
|
1195
1196
|
} else {
|
|
1196
1197
|
await eia(getEditor(), [`${getLibDataDir()}/config.json`])
|
|
1197
1198
|
}
|
|
@@ -1428,7 +1429,7 @@ const keywordDef = {
|
|
|
1428
1429
|
quit: {
|
|
1429
1430
|
comment: 'Exit',
|
|
1430
1431
|
exeFn: (args) => {
|
|
1431
|
-
|
|
1432
|
+
Room.offRoom();
|
|
1432
1433
|
delTips();
|
|
1433
1434
|
console.log(infoStr("Bye!"));
|
|
1434
1435
|
_noAppendNextLine = true;
|
|
@@ -1490,7 +1491,11 @@ const keywordDef = {
|
|
|
1490
1491
|
console.warn('log file not found')
|
|
1491
1492
|
return;
|
|
1492
1493
|
}
|
|
1493
|
-
|
|
1494
|
+
if (isRunningInBackground()) {
|
|
1495
|
+
console.log(await e(`tail -n 500 "${path}"`))
|
|
1496
|
+
} else {
|
|
1497
|
+
await eia(cmdStr, [`"${path}"`], true)
|
|
1498
|
+
}
|
|
1494
1499
|
},
|
|
1495
1500
|
short: 'l'
|
|
1496
1501
|
},
|
|
@@ -1509,7 +1514,7 @@ const keywordDef = {
|
|
|
1509
1514
|
room: {
|
|
1510
1515
|
comment: 'manage room ([node])',
|
|
1511
1516
|
exeFn: async (args) => {
|
|
1512
|
-
await
|
|
1517
|
+
await Room.syncSetting();
|
|
1513
1518
|
if (args.length > 0) {
|
|
1514
1519
|
let have = false;
|
|
1515
1520
|
let tasks = []
|
|
@@ -1525,7 +1530,7 @@ const keywordDef = {
|
|
|
1525
1530
|
tasks.push(async (input) => {
|
|
1526
1531
|
let jsir = room.jsirs[pid];
|
|
1527
1532
|
console.log(infoStr(`[${pid}]`))
|
|
1528
|
-
let resp = await reqNode(room.selfNode, "post", "/enter", jsir.port, JSON.stringify({input}))
|
|
1533
|
+
let resp = await Room.reqNode(room.selfNode, "post", "/enter", jsir.port, JSON.stringify({input}))
|
|
1529
1534
|
console.log(JSON.parse(resp).output)
|
|
1530
1535
|
})
|
|
1531
1536
|
}
|
|
@@ -2162,20 +2167,7 @@ async function _requireSource(currSpace, cmdMatchStr, force = false) {
|
|
|
2162
2167
|
let serviceObj = {};
|
|
2163
2168
|
for (let fn of setting.services[serviceKey]) {
|
|
2164
2169
|
serviceObj[fn] = async (...args) => {
|
|
2165
|
-
|
|
2166
|
-
let targets = setting.serviceFns[key] || []
|
|
2167
|
-
targets = targets
|
|
2168
|
-
.filter(i => i.active)
|
|
2169
|
-
.filter(i => !room.isDisableConnect(i.node, i.port));
|
|
2170
|
-
let target = null;
|
|
2171
|
-
if (targets.length > 0) {
|
|
2172
|
-
target = room.busyPick(targets);
|
|
2173
|
-
} else {
|
|
2174
|
-
throw `service function ${key} not found`;
|
|
2175
|
-
}
|
|
2176
|
-
let resp = await room.reqNode(target.node, 'post',
|
|
2177
|
-
`/${pair[0]}/${encodeURIComponent(trimJsirFileName(pair[1]))}/${fn}`, target.port, JSON.stringify(args))
|
|
2178
|
-
return JSON.parse(resp).result;
|
|
2170
|
+
return await Room.reqFn(`${serviceKey}/${fn}`, args);
|
|
2179
2171
|
}
|
|
2180
2172
|
}
|
|
2181
2173
|
return serviceObj
|
|
@@ -2271,7 +2263,7 @@ process.on('beforeExit', function () {
|
|
|
2271
2263
|
delTips();
|
|
2272
2264
|
} else {
|
|
2273
2265
|
nextLine();
|
|
2274
|
-
|
|
2266
|
+
Room.onRoom(wrapperInput)
|
|
2275
2267
|
}
|
|
2276
2268
|
});
|
|
2277
2269
|
|
package/deps/room.js
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
const os = require('os');
|
|
2
2
|
const {fileJson, fileLock, vl, createConsole, getKeyTips, getValTips,
|
|
3
3
|
getRoomsDir, e, regEach, isRunningInBackground,
|
|
4
|
-
batchAsync, debugStr, trim, getOr, errorTag, warnStr, getConfig
|
|
4
|
+
batchAsync, debugStr, trim, getOr, errorTag, warnStr, getConfig, getConfigDir,
|
|
5
|
+
fileExist
|
|
5
6
|
} = require('./util');
|
|
6
7
|
const {setRoute, createSign} = require('../deps/server')
|
|
7
8
|
const roomDataFile = "jsirRoom.json"
|
|
8
9
|
const roomsDirLockKey = "RW_" + getRoomsDir();
|
|
9
10
|
const syncRoomsLockKey = "SyncRooms_" + getRoomsDir();
|
|
11
|
+
const syncConfigsLockKey = "SyncConfigs_" + getConfigDir();
|
|
10
12
|
const updateRoomInfoLockKey = "UPDATE_" + roomDataFile
|
|
11
13
|
const console = createConsole();
|
|
12
|
-
const net = require("net");
|
|
13
14
|
const setting = require('../deps/setting')
|
|
14
15
|
const fp = require('fs').promises
|
|
15
16
|
const http = require('http');
|
|
16
|
-
|
|
17
|
+
const tailscalePath = os.platform() === 'darwin' ?
|
|
17
18
|
'/Applications/Tailscale.app/Contents/MacOS/Tailscale':'tailscale';
|
|
19
|
+
const configMain = getConfig("configMain");
|
|
18
20
|
|
|
19
21
|
function debug(...args) {
|
|
20
22
|
if (global.$DEBUG) {
|
|
@@ -35,6 +37,19 @@ function isPidAlive(pid) {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
async function localConfigs() {
|
|
41
|
+
let configDir = getConfigDir();
|
|
42
|
+
let configFiles = await fp.readdir(configDir)
|
|
43
|
+
let fns = configFiles
|
|
44
|
+
.map(i => () => fp.readFile(`${configDir}/${i}`));
|
|
45
|
+
let buffers = await batchAsync(fns, 33);
|
|
46
|
+
let configs = {}
|
|
47
|
+
for (let i = 0; i < configFiles.length; i++) {
|
|
48
|
+
configs[configFiles[i]] = String(buffers[i]);
|
|
49
|
+
}
|
|
50
|
+
return configs;
|
|
51
|
+
}
|
|
52
|
+
|
|
38
53
|
function onRoom(wrapperInput) {
|
|
39
54
|
if (!setting.roomTid[0]) {
|
|
40
55
|
try {
|
|
@@ -42,12 +57,12 @@ function onRoom(wrapperInput) {
|
|
|
42
57
|
setRoute("get", "/", (req, res) => setting.selfRoom)
|
|
43
58
|
setRoute("post", "/enter", async (req, res) => {
|
|
44
59
|
if (!getConfig("enableRemote", true)) {
|
|
45
|
-
res.output = warnStr("Disable Remote
|
|
60
|
+
res.output = warnStr("Disable Remote")
|
|
46
61
|
return;
|
|
47
62
|
}
|
|
48
63
|
if (vl(req.input)) {
|
|
49
64
|
if (!isRunningInBackground() && ['.nsir', '.N'].indexOf(req.input.trim()) === -1) {
|
|
50
|
-
res.output = warnStr("Disable Remote
|
|
65
|
+
res.output = warnStr("Disable Remote")
|
|
51
66
|
return;
|
|
52
67
|
}
|
|
53
68
|
setting.enterOutputs = []
|
|
@@ -57,6 +72,11 @@ function onRoom(wrapperInput) {
|
|
|
57
72
|
res.output = outputs.join('');
|
|
58
73
|
}
|
|
59
74
|
})
|
|
75
|
+
if (configMain) {
|
|
76
|
+
setRoute("post", "/" + setting.configMainFnKey, async (req, res) => {
|
|
77
|
+
res.result = await localConfigs();
|
|
78
|
+
})
|
|
79
|
+
}
|
|
60
80
|
} catch (e) {
|
|
61
81
|
debug("initRoute failed", e)
|
|
62
82
|
}
|
|
@@ -252,11 +272,44 @@ async function initRoom() {
|
|
|
252
272
|
if (roomUpdateTouchTime) {
|
|
253
273
|
await fileLock(updateRoomInfoLockKey, updateRoomInfo, false)
|
|
254
274
|
fileLock(syncRoomsLockKey, syncRooms, false);
|
|
275
|
+
if (!configMain && setting.serviceFns.hasOwnProperty(setting.configMainFnKey)) {
|
|
276
|
+
fileLock(syncConfigsLockKey, syncConfigs, false);
|
|
277
|
+
}
|
|
255
278
|
}
|
|
256
279
|
|
|
257
280
|
await syncSetting();
|
|
258
281
|
}
|
|
259
282
|
|
|
283
|
+
async function syncConfigs() {
|
|
284
|
+
let configs;
|
|
285
|
+
try {
|
|
286
|
+
configs = await reqFn(setting.configMainFnKey);
|
|
287
|
+
} catch (e) {
|
|
288
|
+
debug("syncConfigs failed", e)
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
let configDir = getConfigDir();
|
|
292
|
+
let fns = [];
|
|
293
|
+
for (let key of Object.keys(configs)) {
|
|
294
|
+
let path = configDir + "/" + key;
|
|
295
|
+
let text = configs[key];
|
|
296
|
+
fns.push(async () => {
|
|
297
|
+
if (await fileExist(path)) {
|
|
298
|
+
let currText = String(await fp.readFile(path));
|
|
299
|
+
if (currText !== text) {
|
|
300
|
+
await fp.writeFile(path, text)
|
|
301
|
+
debug(`sync ${key} success`);
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
await fp.writeFile(path, text)
|
|
305
|
+
debug(`sync ${key} success`);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
await batchAsync(fns, 33)
|
|
310
|
+
debug('syncConfigs done')
|
|
311
|
+
}
|
|
312
|
+
|
|
260
313
|
async function cleanRoom(room) {
|
|
261
314
|
// 清理进程
|
|
262
315
|
for (let pid of Object.keys(room.jsirs || {})) {
|
|
@@ -297,7 +350,11 @@ async function initRoomJsir(room) {
|
|
|
297
350
|
for (let key of Object.keys(setting.routes)) {
|
|
298
351
|
let ss = key.split("/").map(trim).filter(i => i);
|
|
299
352
|
if (ss.length > 3) {
|
|
353
|
+
// 脚本空间service
|
|
300
354
|
getOr(services, ss[1] + '/' + ss[2], []).push(ss[3])
|
|
355
|
+
} else if (ss.length > 2) {
|
|
356
|
+
// jsir service
|
|
357
|
+
getOr(services, ss[1], []).push(ss[2])
|
|
301
358
|
}
|
|
302
359
|
}
|
|
303
360
|
// 初始化jsir
|
|
@@ -374,53 +431,57 @@ async function reqNode(node, method, url, port, body) {
|
|
|
374
431
|
'sign': createSign()
|
|
375
432
|
}
|
|
376
433
|
};
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
data
|
|
434
|
+
let time = Date.now();
|
|
435
|
+
try {
|
|
436
|
+
return await new Promise((resolve, reject) => {
|
|
437
|
+
try {
|
|
438
|
+
let timeoutMs = setting.reqNodeTimeouts[url] || setting.reqNodeDefaultTimeout;
|
|
439
|
+
let timeout = null
|
|
440
|
+
|
|
441
|
+
const req = http.request(opt, (res) => {
|
|
442
|
+
let data = '';
|
|
443
|
+
// 数据块接收
|
|
444
|
+
res.on('data', (chunk) => {
|
|
445
|
+
data += chunk;
|
|
446
|
+
});
|
|
447
|
+
// 响应结束
|
|
448
|
+
res.on('end', () => {
|
|
449
|
+
clearTimeout(timeout)
|
|
450
|
+
// 检查响应状态码
|
|
451
|
+
if (res.statusCode !== 200) {
|
|
452
|
+
reject(errorTag(new Error(data), decodeURIComponent(url)));
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
resolve(data)
|
|
456
|
+
});
|
|
388
457
|
});
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
//
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
458
|
+
|
|
459
|
+
// 设置超时逻辑
|
|
460
|
+
timeout = setTimeout(() => {
|
|
461
|
+
req.destroy(); // 中断请求
|
|
462
|
+
}, timeoutMs); // 10秒超时
|
|
463
|
+
|
|
464
|
+
// 错误处理
|
|
465
|
+
req.on('error', (e) => {
|
|
466
|
+
clearTimeout(timeout); // 清除超时定时器
|
|
467
|
+
if (room) {
|
|
468
|
+
setting.disableConnect[node + ":" + port] = Date.now() + setting.disableConnectLimit
|
|
396
469
|
}
|
|
397
|
-
|
|
470
|
+
reject(e)
|
|
398
471
|
});
|
|
399
|
-
});
|
|
400
472
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
req.destroy(); // 中断请求
|
|
404
|
-
}, timeoutMs); // 10秒超时
|
|
405
|
-
|
|
406
|
-
// 错误处理
|
|
407
|
-
req.on('error', (e) => {
|
|
408
|
-
clearTimeout(timeout); // 清除超时定时器
|
|
409
|
-
if (room) {
|
|
410
|
-
setting.disableConnect[node + ":" + port] = Date.now() + setting.disableConnectLimit
|
|
473
|
+
if (body) {
|
|
474
|
+
req.write(body)
|
|
411
475
|
}
|
|
476
|
+
// 结束请求
|
|
477
|
+
req.end();
|
|
478
|
+
} catch (e) {
|
|
412
479
|
reject(e)
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
if (body) {
|
|
416
|
-
req.write(body)
|
|
417
480
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
})
|
|
481
|
+
});
|
|
482
|
+
} finally {
|
|
483
|
+
debug(`reqRoom cost ${Date.now() - time}ms`, JSON.stringify(opt), )
|
|
484
|
+
}
|
|
424
485
|
}
|
|
425
486
|
|
|
426
487
|
function busyPick(busyItems) {
|
|
@@ -441,11 +502,27 @@ function busyPick(busyItems) {
|
|
|
441
502
|
}
|
|
442
503
|
}
|
|
443
504
|
|
|
505
|
+
async function reqFn(fnKey, args = []) {
|
|
506
|
+
let targets = setting.serviceFns[fnKey] || []
|
|
507
|
+
targets = targets
|
|
508
|
+
.filter(i => i.active)
|
|
509
|
+
.filter(i => !isDisableConnect(i.node, i.port));
|
|
510
|
+
let target = null;
|
|
511
|
+
if (targets.length > 0) {
|
|
512
|
+
target = busyPick(targets);
|
|
513
|
+
} else {
|
|
514
|
+
throw `service function ${fnKey} not found`;
|
|
515
|
+
}
|
|
516
|
+
let resp = await reqNode(target.node, 'post',
|
|
517
|
+
`/${encodeURI(fnKey)}`, target.port, JSON.stringify(args || []))
|
|
518
|
+
return JSON.parse(resp).result;
|
|
519
|
+
}
|
|
520
|
+
|
|
444
521
|
module.exports = {
|
|
445
522
|
onRoom,
|
|
446
523
|
offRoom,
|
|
447
524
|
syncSetting,
|
|
448
525
|
reqNode,
|
|
449
|
-
|
|
450
|
-
|
|
526
|
+
reqFn,
|
|
527
|
+
localConfigs
|
|
451
528
|
}
|
package/deps/server.js
CHANGED
|
@@ -36,7 +36,7 @@ function createSign() {
|
|
|
36
36
|
async function createServer(port) {
|
|
37
37
|
const server = http.createServer(async (req, res) => {
|
|
38
38
|
const method = req.method.toLowerCase();
|
|
39
|
-
const url =
|
|
39
|
+
const url = decodeURI(req.url);
|
|
40
40
|
|
|
41
41
|
// 获取客户端的 IP 地址
|
|
42
42
|
const clientIp = req.socket.remoteAddress || req.connection.remoteAddress;
|
package/deps/setting.js
CHANGED
package/deps/util.js
CHANGED
|
@@ -256,7 +256,7 @@ function createConsole(uniqueName) {
|
|
|
256
256
|
if ('debug' === key && !global.$DEBUG) {
|
|
257
257
|
return;
|
|
258
258
|
}
|
|
259
|
-
if (uniqueName &&
|
|
259
|
+
if (uniqueName && quite) {
|
|
260
260
|
if ((key === 'table' || key === 'nable') && typeof args[0] === "object") {
|
|
261
261
|
args = ['', ...args]
|
|
262
262
|
}
|
|
@@ -272,9 +272,6 @@ function createConsole(uniqueName) {
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
|
-
if (uniqueName) {
|
|
276
|
-
setting.consoleMap[uniqueName] = result;
|
|
277
|
-
}
|
|
278
275
|
return result;
|
|
279
276
|
}
|
|
280
277
|
|
|
@@ -1017,9 +1014,6 @@ function _getConfig(key, defaultVal, uniqueName) {
|
|
|
1017
1014
|
if (key === undefined) {
|
|
1018
1015
|
return config
|
|
1019
1016
|
}
|
|
1020
|
-
if (uniqueName && setting.consoleMap[uniqueName]) {
|
|
1021
|
-
setting.consoleMap[uniqueName].msg(`require ${uniqueName} config "${key}"`)
|
|
1022
|
-
}
|
|
1023
1017
|
let writeFlag = false
|
|
1024
1018
|
if (!(key in config)) {
|
|
1025
1019
|
writeFlag = true
|
|
@@ -1175,14 +1169,7 @@ async function _fileLock(key, fn, expireMs = 49000) {
|
|
|
1175
1169
|
const expireAt = expireMs > 0 ? now + expireMs : 0;
|
|
1176
1170
|
|
|
1177
1171
|
// 1. 尝试判断锁目录是否已存在
|
|
1178
|
-
let lockExists =
|
|
1179
|
-
try {
|
|
1180
|
-
await fp.access(lockKeyDir); // 若存在则不抛错
|
|
1181
|
-
lockExists = true;
|
|
1182
|
-
} catch (_) {
|
|
1183
|
-
// 不存在时会抛ENOENT错误,说明还没有锁
|
|
1184
|
-
lockExists = false;
|
|
1185
|
-
}
|
|
1172
|
+
let lockExists = await fileExist(lockKeyDir);
|
|
1186
1173
|
|
|
1187
1174
|
if (lockExists) {
|
|
1188
1175
|
// 目录存在时,读取文件名中的过期时间戳
|
|
@@ -1569,6 +1556,9 @@ async function eia(cmd, args = [], shell = false) {
|
|
|
1569
1556
|
`
|
|
1570
1557
|
当前进程不会卡住,输入输出由cmd进程持有
|
|
1571
1558
|
`
|
|
1559
|
+
if (isRunningInBackground()) {
|
|
1560
|
+
throw 'Unsupported Operation';
|
|
1561
|
+
}
|
|
1572
1562
|
setting.enableNextLine = false;
|
|
1573
1563
|
let child = spawn(cmd, args, {stdio:"inherit", shell});
|
|
1574
1564
|
return new Promise((resolve, reject) => {
|
|
@@ -1895,7 +1885,7 @@ function md5(message) {
|
|
|
1895
1885
|
return crypto.createHash('md5').update(message).digest('hex');
|
|
1896
1886
|
}
|
|
1897
1887
|
|
|
1898
|
-
async function batchAsync(fns = [], asyncNum =
|
|
1888
|
+
async function batchAsync(fns = [], asyncNum = 9, limitMs = 0) {
|
|
1899
1889
|
if (fns.length <= 0 || asyncNum < 1) {
|
|
1900
1890
|
return []
|
|
1901
1891
|
}
|
|
@@ -1905,7 +1895,12 @@ async function batchAsync(fns = [], asyncNum = 1, limitMs = 49000) {
|
|
|
1905
1895
|
for(let i = 0; i< fns.length; i++) {
|
|
1906
1896
|
let pro = new Promise(async (resolve, reject) => {
|
|
1907
1897
|
try {
|
|
1908
|
-
let resp
|
|
1898
|
+
let resp;
|
|
1899
|
+
if (limitMs) {
|
|
1900
|
+
resp = await timeLimit([fns[i]()], limitMs);
|
|
1901
|
+
} else {
|
|
1902
|
+
resp = [await fns[i]()];
|
|
1903
|
+
}
|
|
1909
1904
|
doneMap[i] = pro;
|
|
1910
1905
|
resolve(resp[0])
|
|
1911
1906
|
} catch (e) {
|
|
@@ -2082,6 +2077,8 @@ function interceptStdStreams() {
|
|
|
2082
2077
|
process.stdout.write = (chunk, ...args) => {
|
|
2083
2078
|
if(setting.enterOutputs) {
|
|
2084
2079
|
setting.enterOutputs.push(chunk.toString());
|
|
2080
|
+
} else if (isRunningInBackground()) {
|
|
2081
|
+
console.$log(process.pid, "STDOUT", "\n" + chunk.toString().trimEnd());
|
|
2085
2082
|
} else {
|
|
2086
2083
|
originalStdoutWrite(chunk, ...args); // 保留原始行为
|
|
2087
2084
|
}
|
|
@@ -2091,6 +2088,8 @@ function interceptStdStreams() {
|
|
|
2091
2088
|
process.stderr.write = (chunk, ...args) => {
|
|
2092
2089
|
if(setting.enterOutputs) {
|
|
2093
2090
|
setting.enterOutputs.push(chunk.toString());
|
|
2091
|
+
} else if (isRunningInBackground()) {
|
|
2092
|
+
console.$error(process.pid, errorStr("STDERR"), "\n" + chunk.toString().trimEnd());
|
|
2094
2093
|
} else {
|
|
2095
2094
|
originalStderrWrite(chunk, ...args); // 保留原始行为
|
|
2096
2095
|
}
|
|
@@ -2206,5 +2205,6 @@ module.exports = {
|
|
|
2206
2205
|
isRunningInBackground,
|
|
2207
2206
|
createDetachedProcess,
|
|
2208
2207
|
interceptStdStreams,
|
|
2209
|
-
draftModify
|
|
2208
|
+
draftModify,
|
|
2209
|
+
fileExist
|
|
2210
2210
|
}
|