jsir 2.3.3 → 2.3.5
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 +42 -5
- package/deps/room.js +171 -64
- package/deps/server.js +110 -0
- package/deps/setting.js +4 -1
- package/deps/util.js +26 -4
- package/package.json +2 -3
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, getRoomsDir
|
|
15
15
|
} = $lib;
|
|
16
16
|
const _args = process.argv.slice(2).map(trim);
|
|
17
17
|
const evalCode = require('../deps/evalCode')
|
|
@@ -562,13 +562,13 @@ async function wrapperInput(str) {
|
|
|
562
562
|
}
|
|
563
563
|
|
|
564
564
|
function wrapperAlias(str) {
|
|
565
|
-
let aliasMap =
|
|
565
|
+
let aliasMap = null;
|
|
566
566
|
try {
|
|
567
567
|
aliasMap = getConfig("alias");
|
|
568
568
|
} catch (e) {
|
|
569
569
|
console.$error("getAlias failed ", e);
|
|
570
570
|
}
|
|
571
|
-
if (Object.keys(aliasMap).length <= 0) {
|
|
571
|
+
if (!aliasMap || Object.keys(aliasMap).length <= 0) {
|
|
572
572
|
return str;
|
|
573
573
|
}
|
|
574
574
|
let fstr = str.split(/\s+/)[0];
|
|
@@ -1342,8 +1342,6 @@ const keywordDef = {
|
|
|
1342
1342
|
_noAppendNextLine = false
|
|
1343
1343
|
resetCmdMap()
|
|
1344
1344
|
console.log(warnStr(`(${setting.name} ${packageJson.version}) You can start with .help, use * to expand context.`))
|
|
1345
|
-
room.onRoom()
|
|
1346
|
-
nextLine()
|
|
1347
1345
|
},
|
|
1348
1346
|
short: 'p'
|
|
1349
1347
|
},
|
|
@@ -1404,6 +1402,44 @@ const keywordDef = {
|
|
|
1404
1402
|
}
|
|
1405
1403
|
},
|
|
1406
1404
|
short: 'D'
|
|
1405
|
+
},
|
|
1406
|
+
room: {
|
|
1407
|
+
comment: 'manage room',
|
|
1408
|
+
exeFn: async (args) => {
|
|
1409
|
+
let results = [];
|
|
1410
|
+
await room.syncSetting();
|
|
1411
|
+
for (let i = 0; i < setting.rooms.length; i++) {
|
|
1412
|
+
let room = setting.rooms[i]
|
|
1413
|
+
results.push({
|
|
1414
|
+
mid: i,
|
|
1415
|
+
name: (room.local ? "*":" ") + room.name,
|
|
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
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
if (results.length > 0) {
|
|
1437
|
+
console.nable(results)
|
|
1438
|
+
} else {
|
|
1439
|
+
console.warn("no items")
|
|
1440
|
+
}
|
|
1441
|
+
},
|
|
1442
|
+
short: 'm'
|
|
1407
1443
|
}
|
|
1408
1444
|
}
|
|
1409
1445
|
|
|
@@ -2097,6 +2133,7 @@ process.on('beforeExit', function () {
|
|
|
2097
2133
|
delTips();
|
|
2098
2134
|
} else {
|
|
2099
2135
|
nextLine();
|
|
2136
|
+
room.onRoom()
|
|
2100
2137
|
}
|
|
2101
2138
|
});
|
|
2102
2139
|
|
package/deps/room.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
const os = require('os');
|
|
2
|
-
const {fileJson, fileLock, vl, createConsole, getKeyTips, getValTips
|
|
2
|
+
const {fileJson, fileLock, vl, createConsole, getKeyTips, getValTips,
|
|
3
|
+
getRoomsDir, e, regEach} = require('./util');
|
|
4
|
+
const server = require('../deps/server')
|
|
3
5
|
const roomDataFile = "jsirRoom.json"
|
|
6
|
+
const roomsDirLockKey = "RW_" + getRoomsDir();
|
|
7
|
+
const syncRoomsLockKey = "SyncRooms_" + getRoomsDir();
|
|
8
|
+
const enrichRoomInfoLockKey = "ENRICH_" + roomDataFile
|
|
4
9
|
const console = createConsole();
|
|
5
|
-
const ping = require("ping");
|
|
6
10
|
const net = require("net");
|
|
7
11
|
const setting = require('../deps/setting')
|
|
12
|
+
const fp = require('fs').promises
|
|
13
|
+
const http = require('http');
|
|
14
|
+
let tailscalePath = os.platform() === 'darwin' ?
|
|
15
|
+
'/Applications/Tailscale.app/Contents/MacOS/Tailscale':'tailscale';
|
|
8
16
|
|
|
9
17
|
function isPidAlive(pid) {
|
|
10
18
|
try {
|
|
@@ -20,8 +28,13 @@ function isPidAlive(pid) {
|
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
function onRoom() {
|
|
23
|
-
return
|
|
24
31
|
if (!setting.roomTid[0]) {
|
|
32
|
+
try {
|
|
33
|
+
server.setRoute("post", "/", (req, res) => setting.selfRoom)
|
|
34
|
+
server.setRoute("get", "/", (req, res) => setting.selfRoom)
|
|
35
|
+
} catch (e) {
|
|
36
|
+
console.$error("initRoute failed", e)
|
|
37
|
+
}
|
|
25
38
|
_onRoom();
|
|
26
39
|
}
|
|
27
40
|
}
|
|
@@ -29,56 +42,135 @@ function onRoom() {
|
|
|
29
42
|
function _onRoom() {
|
|
30
43
|
setting.roomTid[0] = setTimeout(async () => {
|
|
31
44
|
try {
|
|
32
|
-
await
|
|
45
|
+
await initRoom();
|
|
33
46
|
} catch (e) {
|
|
34
47
|
console.$error('initRoom', e)
|
|
35
48
|
}
|
|
36
49
|
if (setting.roomTid[0]) {
|
|
37
50
|
_onRoom();
|
|
38
51
|
}
|
|
39
|
-
},
|
|
52
|
+
}, 3000)
|
|
40
53
|
}
|
|
41
54
|
|
|
42
55
|
function offRoom() {
|
|
43
|
-
return;
|
|
44
56
|
if (setting.roomTid[0]) {
|
|
45
57
|
clearTimeout(setting.roomTid[0])
|
|
46
58
|
setting.roomTid[0] = null
|
|
59
|
+
if (setting.server) {
|
|
60
|
+
setting.server.close(() => {
|
|
61
|
+
console.$log('Existing server shut down.');
|
|
62
|
+
});
|
|
63
|
+
}
|
|
47
64
|
}
|
|
48
65
|
}
|
|
49
66
|
|
|
50
|
-
|
|
51
|
-
console.$log("getNodes")
|
|
67
|
+
function getSelfIP(nodes) {
|
|
52
68
|
let ips = getLocalIPs().ipv4;
|
|
53
|
-
ips = ips.filter(i =>
|
|
69
|
+
ips = ips.filter(i => nodes.indexOf(i) !== -1);
|
|
70
|
+
return ips[0]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function getTailscaleNodes() {
|
|
74
|
+
console.$log("getNodes")
|
|
75
|
+
let resp = await e(`${tailscalePath} status`);
|
|
54
76
|
let nodes = []
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
77
|
+
regEach(resp, /^(\d+\.\d+\.\d+\.\d+)\s+/mg, arr => {
|
|
78
|
+
nodes.push(arr[1])
|
|
79
|
+
});
|
|
80
|
+
return [...new Set(nodes)];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function enrichRoomInfo() {
|
|
84
|
+
let nodes = await getTailscaleNodes();
|
|
85
|
+
let ip = getSelfIP(nodes)
|
|
86
|
+
await fileJson(roomDataFile, async room => {
|
|
87
|
+
// 设置roomName
|
|
88
|
+
let name = os.hostname();
|
|
89
|
+
if (!vl(room.name) || room.name !== name) {
|
|
90
|
+
room.name = name;
|
|
91
|
+
console.$log("set roomName", name)
|
|
92
|
+
}
|
|
93
|
+
room.selfNode = ip;
|
|
94
|
+
room.nodes = nodes;
|
|
95
|
+
room.lastUpdateTime = Date.now()
|
|
96
|
+
console.$log("init room", room.name)
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function syncRooms() {
|
|
101
|
+
console.$log('syncRooms')
|
|
102
|
+
let roomsDir = getRoomsDir();
|
|
103
|
+
let room = await fileJson(roomDataFile)
|
|
104
|
+
|
|
105
|
+
let syncRooms = []
|
|
106
|
+
for (let node of room.nodes) {
|
|
107
|
+
if (node === room.selfNode) {
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
let respBody = await reqNode(node, "get", "/");
|
|
112
|
+
syncRooms.push(JSON.parse(respBody))
|
|
113
|
+
} catch (e) {
|
|
114
|
+
console.$log(`sync ${node} failed`, e);
|
|
115
|
+
}
|
|
59
116
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
await fileLock(roomDataFile + "getNodes", async () => {
|
|
65
|
-
let nodes = await getTailScaleNodes();
|
|
66
|
-
await fileJson(roomDataFile, async room => {
|
|
67
|
-
// 设置roomName
|
|
68
|
-
let name = os.hostname();
|
|
69
|
-
if (!vl(room.name) || room.name !== name) {
|
|
70
|
-
room.name = name;
|
|
71
|
-
console.$log("set roomName", name)
|
|
117
|
+
await fileLock(roomsDirLockKey, async () => {
|
|
118
|
+
for (let syncRoom of syncRooms) {
|
|
119
|
+
if (syncRoom.selfNode) {
|
|
120
|
+
await fp.writeFile(syncRoom.selfNode, JSON.stringify(syncRoom, null, 2))
|
|
72
121
|
}
|
|
122
|
+
}
|
|
123
|
+
})
|
|
73
124
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
125
|
+
// 清理 roomsDir
|
|
126
|
+
let files = await fp.readdir(roomsDir)
|
|
127
|
+
let nodes = room.nodes;
|
|
128
|
+
for (let file of files) {
|
|
129
|
+
if (nodes.indexOf(file) === -1) {
|
|
130
|
+
try {
|
|
131
|
+
await fp.unlink(roomsDir + '/' + file)
|
|
132
|
+
} catch (e) {
|
|
133
|
+
console.$error(e);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function syncSetting() {
|
|
140
|
+
let room = await fileJson(roomDataFile)
|
|
141
|
+
await fileLock(roomsDirLockKey, async () => await _syncSetting(room));
|
|
79
142
|
}
|
|
80
143
|
|
|
81
|
-
async function
|
|
144
|
+
async function _syncSetting(room) {
|
|
145
|
+
setting.selfRoom = room;
|
|
146
|
+
setting.selfRoom.local = true;
|
|
147
|
+
let roomDir = getRoomsDir();
|
|
148
|
+
let rooms = []
|
|
149
|
+
let files = await fp.readdir(roomDir);
|
|
150
|
+
for (let node of setting.selfRoom.nodes) {
|
|
151
|
+
if (files.indexOf(node) !== -1) {
|
|
152
|
+
let resp = String(await fp.readFile(roomDir + '/' + node));
|
|
153
|
+
let room = JSON.parse(resp);
|
|
154
|
+
if (room.selfNode !== setting.selfRoom.selfNode) {
|
|
155
|
+
rooms.push(room)
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
rooms.push({
|
|
159
|
+
selfNode: node,
|
|
160
|
+
jsirs: []
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
setting.rooms = [setting.selfRoom, ...rooms]
|
|
165
|
+
.map(room => {
|
|
166
|
+
room.active = Date.now() - (room.lastUpdateTime || 0) <= 18000;
|
|
167
|
+
Object.entries(room.jsirs).forEach(([key, jsir]) =>
|
|
168
|
+
jsir.active = Date.now() - (jsir.lastUpdateTime || 0) <= 6000)
|
|
169
|
+
return room;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function initRoom() {
|
|
82
174
|
let roomUpdateTouchTime = false;
|
|
83
175
|
await fileJson(roomDataFile, async room => {
|
|
84
176
|
await initRoomJsir(room)
|
|
@@ -88,8 +180,11 @@ async function _initRoom() {
|
|
|
88
180
|
})
|
|
89
181
|
|
|
90
182
|
if (roomUpdateTouchTime) {
|
|
91
|
-
|
|
183
|
+
await fileLock(enrichRoomInfoLockKey, enrichRoomInfo, false)
|
|
184
|
+
await fileLock(syncRoomsLockKey, syncRooms, false);
|
|
92
185
|
}
|
|
186
|
+
|
|
187
|
+
await syncSetting();
|
|
93
188
|
}
|
|
94
189
|
|
|
95
190
|
async function getEventLoopDelay() {
|
|
@@ -103,14 +198,10 @@ async function getEventLoopDelay() {
|
|
|
103
198
|
}
|
|
104
199
|
|
|
105
200
|
async function initRoomJsir(room) {
|
|
106
|
-
room.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
delete room.jsir[pid]
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
room.jsir[process.pid] = {
|
|
201
|
+
room.jsirs = Object.fromEntries(
|
|
202
|
+
Object.entries(room.jsirs || {}).filter(([pid]) => isPidAlive(pid))
|
|
203
|
+
);
|
|
204
|
+
room.jsirs[process.pid] = {
|
|
114
205
|
pid: process.pid,
|
|
115
206
|
space: setting.defaultSpace,
|
|
116
207
|
tips: getKeyTips().reduce((obj, key, index) => {
|
|
@@ -119,7 +210,8 @@ async function initRoomJsir(room) {
|
|
|
119
210
|
}, {}),
|
|
120
211
|
busy: await getEventLoopDelay(),
|
|
121
212
|
back: isRunningInBackground(),
|
|
122
|
-
lastUpdateTime: Date.now()
|
|
213
|
+
lastUpdateTime: Date.now(),
|
|
214
|
+
port: setting.server.address().port
|
|
123
215
|
}
|
|
124
216
|
console.$log("init jsir", process.pid)
|
|
125
217
|
}
|
|
@@ -200,33 +292,48 @@ function checkPortOpen(ip, port) {
|
|
|
200
292
|
});
|
|
201
293
|
}
|
|
202
294
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
// 扫描 1 到 254 的 IP
|
|
213
|
-
const promises = [];
|
|
214
|
-
for (let i = 1; i <= 254; i++) {
|
|
215
|
-
const ip = `${subnet}${i}`;
|
|
216
|
-
promises.push(
|
|
217
|
-
ping.promise.probe(ip, { timeout: 1 }).then((res) => {
|
|
218
|
-
if (res.alive) {
|
|
219
|
-
reachableIPs.push(ip);
|
|
220
|
-
}
|
|
221
|
-
})
|
|
222
|
-
);
|
|
295
|
+
async function reqNode(node, method, url) {
|
|
296
|
+
let port = 52108;
|
|
297
|
+
let room = setting.rooms.filter(i => i.selfNode === node)[0]
|
|
298
|
+
if (room) {
|
|
299
|
+
let activeJsir = Object.values(room.jsirs)
|
|
300
|
+
.filter(i => i.active).sort((a,b) => a.busy - b.busy);
|
|
301
|
+
if (activeJsir.length > 0) {
|
|
302
|
+
port = activeJsir[0].port;
|
|
303
|
+
}
|
|
223
304
|
}
|
|
305
|
+
let opt = {
|
|
306
|
+
hostname: node,
|
|
307
|
+
port: port, // HTTP 默认端口
|
|
308
|
+
path: url,
|
|
309
|
+
method: method.toUpperCase(),
|
|
310
|
+
};
|
|
311
|
+
console.$log('reqRoom', JSON.stringify(opt))
|
|
312
|
+
return await new Promise((resolve, reject) => {
|
|
313
|
+
const req = http.request(opt, (res) => {
|
|
314
|
+
let data = '';
|
|
315
|
+
// 数据块接收
|
|
316
|
+
res.on('data', (chunk) => {
|
|
317
|
+
data += chunk;
|
|
318
|
+
});
|
|
319
|
+
// 响应结束
|
|
320
|
+
res.on('end', () => {
|
|
321
|
+
resolve(data)
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
// 错误处理
|
|
326
|
+
req.on('error', (e) => {
|
|
327
|
+
reject(e)
|
|
328
|
+
});
|
|
224
329
|
|
|
225
|
-
|
|
226
|
-
|
|
330
|
+
// 结束请求
|
|
331
|
+
req.end();
|
|
332
|
+
})
|
|
227
333
|
}
|
|
228
334
|
|
|
229
335
|
module.exports = {
|
|
230
336
|
onRoom,
|
|
231
|
-
offRoom
|
|
337
|
+
offRoom,
|
|
338
|
+
syncSetting
|
|
232
339
|
}
|
package/deps/server.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const {createConsole, vl} = require('./util');
|
|
3
|
+
const console = createConsole();
|
|
4
|
+
const setting = require('../deps/setting')
|
|
5
|
+
|
|
6
|
+
// 尝试监听的端口
|
|
7
|
+
const preferredPort = 52108;
|
|
8
|
+
|
|
9
|
+
// 路由存储
|
|
10
|
+
const routes = {};
|
|
11
|
+
|
|
12
|
+
// 创建一个 HTTP 服务
|
|
13
|
+
function createServer(port) {
|
|
14
|
+
const server = http.createServer(async (req, res) => {
|
|
15
|
+
const method = req.method.toLowerCase();
|
|
16
|
+
const url = req.url;
|
|
17
|
+
|
|
18
|
+
// 查找对应的路由处理函数
|
|
19
|
+
const routeKey = `${method} ${url}`;
|
|
20
|
+
if (routes[routeKey]) {
|
|
21
|
+
await routes[routeKey](req, res);
|
|
22
|
+
} else {
|
|
23
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
24
|
+
res.end('Not Found\n');
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
server.listen(port, () => {
|
|
29
|
+
const address = server.address();
|
|
30
|
+
console.$log(`Server listening on port ${address.port}`);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
server.on('error', (err) => {
|
|
34
|
+
console.$error(`Error occurred: ${err.message}`);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return server;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 尝试启动服务的逻辑
|
|
41
|
+
function startServer() {
|
|
42
|
+
if (!setting.server) {
|
|
43
|
+
try {
|
|
44
|
+
setting.server = createServer(preferredPort);
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.$error("startServer failed", e)
|
|
47
|
+
setting.server = createServer(0);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 设置路由的方法
|
|
53
|
+
function setRoute(method, url, fn, handler = jsonHandle) {
|
|
54
|
+
startServer();
|
|
55
|
+
|
|
56
|
+
const routeKey = `${method.toLowerCase()} ${url}`;
|
|
57
|
+
if (handler) {
|
|
58
|
+
routes[routeKey] = async (req, res) => {
|
|
59
|
+
await handler(req, res, fn)
|
|
60
|
+
};
|
|
61
|
+
} else {
|
|
62
|
+
routes[routeKey] = fn;
|
|
63
|
+
}
|
|
64
|
+
console.$log(`AddRoute: ${method.toUpperCase()} ${url} ${handler ? handler.constructor.name:''}`);
|
|
65
|
+
return setting.server;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function delRoute(method, url) {
|
|
69
|
+
const routeKey = `${method.toLowerCase()} ${url}`;
|
|
70
|
+
delete routes[routeKey];
|
|
71
|
+
console.$log(`DelRoute: ${method.toUpperCase()} ${url}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function jsonHandle(req, res, fn) {
|
|
75
|
+
let body = '';
|
|
76
|
+
|
|
77
|
+
// 监听请求数据
|
|
78
|
+
req.on('data', chunk => {
|
|
79
|
+
body += chunk;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
req.on('end', async () => {
|
|
83
|
+
try {
|
|
84
|
+
// 解析 JSON 请求体
|
|
85
|
+
const requestData = body ? JSON.parse(body):{};
|
|
86
|
+
|
|
87
|
+
// 创建响应 JSON 数据
|
|
88
|
+
let responseData = {};
|
|
89
|
+
let result = await fn(requestData, responseData);
|
|
90
|
+
if (vl(result)) {
|
|
91
|
+
responseData = result;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 设置响应头
|
|
95
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
96
|
+
// 返回 JSON 响应
|
|
97
|
+
res.end(JSON.stringify(responseData));
|
|
98
|
+
} catch (error) {
|
|
99
|
+
// 错误处理:如果 JSON 解析失败
|
|
100
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
101
|
+
res.end(JSON.stringify({ error: 'Invalid JSON format' }));
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = {
|
|
107
|
+
setRoute,
|
|
108
|
+
delRoute,
|
|
109
|
+
jsonHandle
|
|
110
|
+
};
|
package/deps/setting.js
CHANGED
package/deps/util.js
CHANGED
|
@@ -23,6 +23,8 @@ let lockDir;
|
|
|
23
23
|
let logDir;
|
|
24
24
|
let tempDir;
|
|
25
25
|
let configDir;
|
|
26
|
+
let roomsDir;
|
|
27
|
+
let dataDir;
|
|
26
28
|
|
|
27
29
|
class SyncQueue {
|
|
28
30
|
constructor() {
|
|
@@ -708,7 +710,7 @@ function getInitName(fileName) {
|
|
|
708
710
|
}
|
|
709
711
|
|
|
710
712
|
function dataFile(fileName, fn, fmt, defaultObj = {}, returnStr = false) {
|
|
711
|
-
let dataDir =
|
|
713
|
+
let dataDir = getDataDir()
|
|
712
714
|
fileName = trim(fileName)
|
|
713
715
|
let path
|
|
714
716
|
if (fileName.startsWith("/")) {
|
|
@@ -758,11 +760,11 @@ async function fileExist(path) {
|
|
|
758
760
|
}
|
|
759
761
|
}
|
|
760
762
|
|
|
761
|
-
async function fileJson(key, fn, fmt = true, safeMs = 49000) {
|
|
763
|
+
async function fileJson(key, fn = null, fmt = true, safeMs = 49000) {
|
|
762
764
|
`
|
|
763
765
|
多进程安全文件读写
|
|
764
766
|
`
|
|
765
|
-
let dataDir =
|
|
767
|
+
let dataDir = getDataDir()
|
|
766
768
|
let fileName = trim(key)
|
|
767
769
|
let path = dataDir + "/" + fileName;
|
|
768
770
|
let homeDir = setting.workspaceMap[setting.defaultSpace]
|
|
@@ -901,6 +903,24 @@ function getConfigDir() {
|
|
|
901
903
|
return configDir;
|
|
902
904
|
}
|
|
903
905
|
|
|
906
|
+
function getRoomsDir() {
|
|
907
|
+
if (roomsDir) {
|
|
908
|
+
return roomsDir
|
|
909
|
+
}
|
|
910
|
+
roomsDir = getLibDataDir() + '/rooms';
|
|
911
|
+
mkdir(roomsDir);
|
|
912
|
+
return roomsDir;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
function getDataDir() {
|
|
916
|
+
if (dataDir) {
|
|
917
|
+
return dataDir
|
|
918
|
+
}
|
|
919
|
+
dataDir = getLibDataDir() + '/data';
|
|
920
|
+
mkdir(dataDir);
|
|
921
|
+
return dataDir;
|
|
922
|
+
}
|
|
923
|
+
|
|
904
924
|
function getAlias(aliasMap, key) {
|
|
905
925
|
key = trim(key)
|
|
906
926
|
if (!key) {
|
|
@@ -2062,5 +2082,7 @@ module.exports = {
|
|
|
2062
2082
|
terminalRun,
|
|
2063
2083
|
eia,
|
|
2064
2084
|
getKeyTips,
|
|
2065
|
-
getValTips
|
|
2085
|
+
getValTips,
|
|
2086
|
+
getRoomsDir,
|
|
2087
|
+
getDataDir
|
|
2066
2088
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsir",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.5",
|
|
4
4
|
"description": "JavaScript Script Management Tool",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"chokidar": "^3.5.2",
|
|
23
23
|
"console.table": "^0.10.0",
|
|
24
24
|
"dayjs": "^1.10.4",
|
|
25
|
-
"pad": "^3.2.0"
|
|
26
|
-
"ping": "^0.4.4"
|
|
25
|
+
"pad": "^3.2.0"
|
|
27
26
|
}
|
|
28
27
|
}
|