@maiyunnet/kebab 2.0.14 → 2.0.16
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/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/buffer.js +3 -9
- package/lib/captcha.js +2 -2
- package/lib/consistent.js +1 -1
- package/lib/core.d.ts +42 -18
- package/lib/core.js +147 -152
- package/lib/crypto.js +2 -2
- package/lib/db.d.ts +3 -3
- package/lib/db.js +32 -73
- package/lib/dns.d.ts +1 -1
- package/lib/dns.js +5 -5
- package/lib/fs.js +17 -9
- package/lib/jwt.d.ts +3 -3
- package/lib/jwt.js +5 -5
- package/lib/kv.d.ts +2 -2
- package/lib/kv.js +2 -2
- package/lib/lan.js +1 -1
- package/lib/net/formdata.js +2 -2
- package/lib/net/request.d.ts +1 -1
- package/lib/net/request.js +1 -1
- package/lib/net/response.d.ts +1 -1
- package/lib/net.d.ts +2 -2
- package/lib/net.js +4 -4
- package/lib/s3.d.ts +1 -1
- package/lib/s3.js +5 -5
- package/lib/scan.d.ts +3 -3
- package/lib/scan.js +6 -6
- package/lib/session.d.ts +3 -3
- package/lib/session.js +7 -7
- package/lib/sql.d.ts +3 -3
- package/lib/sql.js +7 -37
- package/lib/ssh/sftp.js +2 -2
- package/lib/ssh/shell.js +1 -1
- package/lib/text.d.ts +6 -1
- package/lib/text.js +9 -1
- package/lib/time.d.ts +1 -1
- package/lib/time.js +1 -1
- package/lib/turnstile.d.ts +1 -1
- package/lib/turnstile.js +2 -2
- package/lib/ws.d.ts +10 -2
- package/lib/ws.js +62 -3
- package/lib/zip.d.ts +1 -1
- package/lib/zip.js +5 -11
- package/lib/zlib.js +7 -21
- package/package.json +5 -4
- package/sys/child.js +43 -84
- package/sys/cmd.js +7 -6
- package/sys/ctr.d.ts +2 -2
- package/sys/ctr.js +2 -2
- package/sys/master.js +131 -9
- package/sys/mod.d.ts +4 -4
- package/sys/mod.js +24 -176
- package/sys/route.d.ts +1 -1
- package/sys/route.js +22 -20
- package/www/example/ctr/main.d.ts +1 -1
- package/www/example/ctr/main.js +1 -1
- package/www/example/ctr/middle.d.ts +2 -2
- package/www/example/ctr/middle.js +1 -1
- package/www/example/ctr/test.d.ts +3 -2
- package/www/example/ctr/test.js +83 -30
- package/www/example/mod/test.d.ts +2 -2
- package/www/example/mod/test.js +2 -2
- package/www/example/mod/testdata.d.ts +1 -1
- package/www/example/mod/testdata.js +1 -1
- package/www/example/ws/mproxy.d.ts +1 -1
- package/www/example/ws/mproxy.js +2 -2
- package/www/example/ws/rproxy.d.ts +1 -1
- package/www/example/ws/rproxy.js +2 -2
- package/www/example/ws/rsocket.d.ts +4 -0
- package/www/example/ws/rsocket.js +47 -0
- package/www/example/ws/test.d.ts +6 -1
- package/www/example/ws/test.js +10 -3
package/sys/child.js
CHANGED
|
@@ -43,13 +43,13 @@ const tls = __importStar(require("tls"));
|
|
|
43
43
|
const http = __importStar(require("http"));
|
|
44
44
|
const crypto = __importStar(require("crypto"));
|
|
45
45
|
// --- 库和定义 ---
|
|
46
|
-
const fs = __importStar(require("
|
|
47
|
-
const lCore = __importStar(require("
|
|
48
|
-
const lText = __importStar(require("
|
|
49
|
-
const sCtr = __importStar(require("
|
|
50
|
-
const kebab = __importStar(require("
|
|
46
|
+
const fs = __importStar(require("~/lib/fs"));
|
|
47
|
+
const lCore = __importStar(require("~/lib/core"));
|
|
48
|
+
const lText = __importStar(require("~/lib/text"));
|
|
49
|
+
const sCtr = __importStar(require("~/sys/ctr"));
|
|
50
|
+
const kebab = __importStar(require("~/index"));
|
|
51
51
|
// --- 初始化 ---
|
|
52
|
-
const sRoute = __importStar(require("
|
|
52
|
+
const sRoute = __importStar(require("~/sys/route"));
|
|
53
53
|
/** --- 10 秒往主线程发送一次心跳的 Timer --- */
|
|
54
54
|
const hbTimer = setInterval(function () {
|
|
55
55
|
if (!process.connected || !process.send) {
|
|
@@ -61,9 +61,11 @@ const hbTimer = setInterval(function () {
|
|
|
61
61
|
});
|
|
62
62
|
}, 10_000);
|
|
63
63
|
/** --- 加载的证书列表(path: { sc, cert }) --- */
|
|
64
|
-
|
|
64
|
+
let certList = [];
|
|
65
65
|
/** --- server: index --- */
|
|
66
66
|
let certHostIndex = {};
|
|
67
|
+
/** --- 最后一次加载证书到内存的时间 --- */
|
|
68
|
+
let certLastLoad = 0;
|
|
67
69
|
/** --- 当前的虚拟主机配置列表 - 读取于 conf/vhost/*.json --- */
|
|
68
70
|
let vhosts = [];
|
|
69
71
|
/** --- http 服务器 --- */
|
|
@@ -82,6 +84,12 @@ async function run() {
|
|
|
82
84
|
http2Server = http2.createSecureServer({
|
|
83
85
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
84
86
|
'SNICallback': (servername, cb) => {
|
|
87
|
+
if (Date.now() - certLastLoad > 60_000 * 60 * 24) {
|
|
88
|
+
// --- 不能用异步,不要干扰 SNI 进程 ---
|
|
89
|
+
reloadCert().catch(e => {
|
|
90
|
+
lCore.display('[CHILD][run] reloadCert error', e);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
85
93
|
const i = certHostIndex[servername];
|
|
86
94
|
if (i !== undefined) {
|
|
87
95
|
cb(null, certList[i].sc);
|
|
@@ -119,16 +127,8 @@ async function run() {
|
|
|
119
127
|
if (!linkCount[key]) {
|
|
120
128
|
delete linkCount[key];
|
|
121
129
|
}
|
|
122
|
-
})().catch(
|
|
123
|
-
|
|
124
|
-
'path': '',
|
|
125
|
-
'urlFull': '',
|
|
126
|
-
'hostname': '',
|
|
127
|
-
'req': req,
|
|
128
|
-
'get': {},
|
|
129
|
-
'cookie': {},
|
|
130
|
-
'headers': {}
|
|
131
|
-
}, '[child][http2][request]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
130
|
+
})().catch(function (e) {
|
|
131
|
+
lCore.log({}, '[CHILD][http2][request] ' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
132
132
|
--linkCount[key];
|
|
133
133
|
if (!linkCount[key]) {
|
|
134
134
|
delete linkCount[key];
|
|
@@ -153,16 +153,8 @@ async function run() {
|
|
|
153
153
|
if (!linkCount[key]) {
|
|
154
154
|
delete linkCount[key];
|
|
155
155
|
}
|
|
156
|
-
})().catch(
|
|
157
|
-
|
|
158
|
-
'path': '',
|
|
159
|
-
'urlFull': '',
|
|
160
|
-
'hostname': '',
|
|
161
|
-
'req': req,
|
|
162
|
-
'get': {},
|
|
163
|
-
'cookie': {},
|
|
164
|
-
'headers': {}
|
|
165
|
-
}, '[child][http2][upgrade]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
156
|
+
})().catch(function (e) {
|
|
157
|
+
lCore.log({}, '[CHILD][http2][upgrade] ' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
166
158
|
--linkCount[key];
|
|
167
159
|
if (!linkCount[key]) {
|
|
168
160
|
delete linkCount[key];
|
|
@@ -186,16 +178,8 @@ async function run() {
|
|
|
186
178
|
if (!linkCount[key]) {
|
|
187
179
|
delete linkCount[key];
|
|
188
180
|
}
|
|
189
|
-
})().catch(
|
|
190
|
-
|
|
191
|
-
'path': '',
|
|
192
|
-
'urlFull': '',
|
|
193
|
-
'hostname': '',
|
|
194
|
-
'req': req,
|
|
195
|
-
'get': {},
|
|
196
|
-
'cookie': {},
|
|
197
|
-
'headers': {}
|
|
198
|
-
}, '[child][http][request]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
181
|
+
})().catch(function (e) {
|
|
182
|
+
lCore.log({}, '[CHILD][http][request] ' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
199
183
|
--linkCount[key];
|
|
200
184
|
if (!linkCount[key]) {
|
|
201
185
|
delete linkCount[key];
|
|
@@ -218,16 +202,8 @@ async function run() {
|
|
|
218
202
|
if (!linkCount[key]) {
|
|
219
203
|
delete linkCount[key];
|
|
220
204
|
}
|
|
221
|
-
})().catch(
|
|
222
|
-
|
|
223
|
-
'path': '',
|
|
224
|
-
'urlFull': '',
|
|
225
|
-
'hostname': '',
|
|
226
|
-
'req': req,
|
|
227
|
-
'get': {},
|
|
228
|
-
'cookie': {},
|
|
229
|
-
'headers': {}
|
|
230
|
-
}, '[child][http][upgrade]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
205
|
+
})().catch(function (e) {
|
|
206
|
+
lCore.log({}, '[CHILD][http][upgrade] ' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
231
207
|
--linkCount[key];
|
|
232
208
|
if (!linkCount[key]) {
|
|
233
209
|
delete linkCount[key];
|
|
@@ -335,7 +311,7 @@ async function requestHandler(req, res, https) {
|
|
|
335
311
|
}
|
|
336
312
|
}
|
|
337
313
|
catch (e) {
|
|
338
|
-
|
|
314
|
+
lCore.log({
|
|
339
315
|
'path': path.slice(('/' + pathList.slice(0, i).join('/')).length + 1),
|
|
340
316
|
'urlFull': (uri.protocol ?? '') + '//' + (uri.host ?? '') + '/' + now,
|
|
341
317
|
'hostname': uri.hostname ?? '',
|
|
@@ -343,7 +319,7 @@ async function requestHandler(req, res, https) {
|
|
|
343
319
|
'get': uri.query ? lText.queryParse(uri.query) : {},
|
|
344
320
|
'cookie': {},
|
|
345
321
|
'headers': {}
|
|
346
|
-
}, '
|
|
322
|
+
}, '[CHILD][requestHandler][E0]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
347
323
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
348
324
|
res.setHeader('content-length', 25);
|
|
349
325
|
res.writeHead(500);
|
|
@@ -381,15 +357,7 @@ async function requestHandler(req, res, https) {
|
|
|
381
357
|
}
|
|
382
358
|
}
|
|
383
359
|
catch (e) {
|
|
384
|
-
|
|
385
|
-
'path': path.slice(1),
|
|
386
|
-
'urlFull': (uri.protocol ?? '') + '//' + (uri.host ?? '') + '/' + now,
|
|
387
|
-
'hostname': uri.hostname ?? '',
|
|
388
|
-
'req': req,
|
|
389
|
-
'get': uri.query ? lText.queryParse(uri.query) : {},
|
|
390
|
-
'cookie': {},
|
|
391
|
-
'headers': {}
|
|
392
|
-
}, '(E02)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
360
|
+
lCore.log({}, '[CHILD][requestHandler][E1]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
393
361
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
394
362
|
res.setHeader('content-length', 25);
|
|
395
363
|
res.writeHead(500);
|
|
@@ -540,7 +508,17 @@ async function reload() {
|
|
|
540
508
|
}
|
|
541
509
|
}
|
|
542
510
|
// --- 重新加载证书对 ---
|
|
543
|
-
|
|
511
|
+
await reloadCert();
|
|
512
|
+
// --- 其他操作 ---
|
|
513
|
+
sRoute.clearKebabConfigs();
|
|
514
|
+
sCtr.clearLocaleData();
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* --- 重新加载证书对 ---
|
|
518
|
+
*/
|
|
519
|
+
async function reloadCert() {
|
|
520
|
+
certLastLoad = Date.now();
|
|
521
|
+
const cl = [];
|
|
544
522
|
try {
|
|
545
523
|
const certConfig = await fs.getContent(kebab.CONF_CWD + 'cert.json', 'utf8');
|
|
546
524
|
if (certConfig) {
|
|
@@ -556,7 +534,7 @@ async function reload() {
|
|
|
556
534
|
'key': key,
|
|
557
535
|
'cert': cert
|
|
558
536
|
});
|
|
559
|
-
|
|
537
|
+
cl.push({
|
|
560
538
|
'cert': certo,
|
|
561
539
|
'sc': sc
|
|
562
540
|
});
|
|
@@ -566,10 +544,8 @@ async function reload() {
|
|
|
566
544
|
catch {
|
|
567
545
|
// --- NOTHING ---
|
|
568
546
|
}
|
|
547
|
+
certList = cl;
|
|
569
548
|
certHostIndex = {};
|
|
570
|
-
// --- 其他操作 ---
|
|
571
|
-
sRoute.clearKebabConfigs();
|
|
572
|
-
sCtr.clearLocaleData();
|
|
573
549
|
}
|
|
574
550
|
// --- 接收主进程回传信号,主要用来 reload,restart ---
|
|
575
551
|
process.on('message', function (msg) {
|
|
@@ -598,17 +574,8 @@ process.on('message', function (msg) {
|
|
|
598
574
|
for (const key in linkCount) {
|
|
599
575
|
str.push(key + ':' + linkCount[key].toString());
|
|
600
576
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
await lCore.log({
|
|
604
|
-
'path': '',
|
|
605
|
-
'urlFull': '',
|
|
606
|
-
'hostname': '',
|
|
607
|
-
'req': null,
|
|
608
|
-
'get': {},
|
|
609
|
-
'cookie': {},
|
|
610
|
-
'headers': {}
|
|
611
|
-
}, `[child] Worker ${process.pid} busy: ${str.join(',')}.`, '-error');
|
|
577
|
+
lCore.display(`[CHILD] Worker ${process.pid} busy: ${str.join(',')}.`);
|
|
578
|
+
lCore.log({}, `[CHILD] Worker ${process.pid} busy: ${str.join(',')}.`, '-error');
|
|
612
579
|
await lCore.sleep(30_000);
|
|
613
580
|
waiting += 30_000;
|
|
614
581
|
if (waiting > 3600_000) {
|
|
@@ -635,16 +602,8 @@ process.on('message', function (msg) {
|
|
|
635
602
|
break;
|
|
636
603
|
}
|
|
637
604
|
}
|
|
638
|
-
})().catch(
|
|
639
|
-
|
|
640
|
-
'path': '',
|
|
641
|
-
'urlFull': '',
|
|
642
|
-
'hostname': '',
|
|
643
|
-
'req': null,
|
|
644
|
-
'get': {},
|
|
645
|
-
'cookie': {},
|
|
646
|
-
'headers': {}
|
|
647
|
-
}, '[child][process][message]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
605
|
+
})().catch(function (e) {
|
|
606
|
+
lCore.log({}, '[CHILD][process][message] ' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
648
607
|
});
|
|
649
608
|
});
|
|
650
609
|
/**
|
package/sys/cmd.js
CHANGED
|
@@ -39,12 +39,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
* Last: 2020-3-7 23:51:18, 2022-07-22 14:14:09, 2022-9-27 14:52:19, 2023-5-23 21:42:46, 2024-7-2 15:12:28
|
|
40
40
|
*/
|
|
41
41
|
const http = __importStar(require("http"));
|
|
42
|
-
const lFs = __importStar(require("
|
|
43
|
-
const lText = __importStar(require("
|
|
44
|
-
const lTime = __importStar(require("
|
|
45
|
-
const lCore = __importStar(require("
|
|
46
|
-
const lCrypto = __importStar(require("
|
|
47
|
-
const kebab = __importStar(require("
|
|
42
|
+
const lFs = __importStar(require("~/lib/fs"));
|
|
43
|
+
const lText = __importStar(require("~/lib/text"));
|
|
44
|
+
const lTime = __importStar(require("~/lib/time"));
|
|
45
|
+
const lCore = __importStar(require("~/lib/core"));
|
|
46
|
+
const lCrypto = __importStar(require("~/lib/crypto"));
|
|
47
|
+
const kebab = __importStar(require("~/index"));
|
|
48
48
|
/** --- 解析命令 --- */
|
|
49
49
|
const cmds = process.argv.slice(2);
|
|
50
50
|
/** --- 批量创建目录 --- */
|
|
@@ -110,6 +110,7 @@ async function run() {
|
|
|
110
110
|
config.rpcSecret ??= 'MUSTCHANGE';
|
|
111
111
|
config.debug ??= true;
|
|
112
112
|
config.max ??= 64;
|
|
113
|
+
config.hosts ??= [];
|
|
113
114
|
// --- config - set ---
|
|
114
115
|
config.set ??= {};
|
|
115
116
|
config.set.timezone ??= 8;
|
package/sys/ctr.d.ts
CHANGED
|
@@ -34,9 +34,9 @@ export declare class Ctr {
|
|
|
34
34
|
/** --- Cookie 数组 --- */
|
|
35
35
|
protected _cookie: Record<string, string>;
|
|
36
36
|
/** --- Jwt 数组 --- */
|
|
37
|
-
protected _jwt: Record<string,
|
|
37
|
+
protected _jwt: Record<string, any>;
|
|
38
38
|
/** --- Session 数组 --- */
|
|
39
|
-
protected _session: Record<string,
|
|
39
|
+
protected _session: Record<string, any>;
|
|
40
40
|
/** --- Session --- 对象 */
|
|
41
41
|
protected _sess: session.Session | null;
|
|
42
42
|
/** --- 页面浏览器客户端缓存 --- */
|
package/sys/ctr.js
CHANGED
|
@@ -147,9 +147,9 @@ class Ctr {
|
|
|
147
147
|
if (!this._waitInfo.asyncTask.count) {
|
|
148
148
|
this._waitInfo.asyncTask.resolve();
|
|
149
149
|
}
|
|
150
|
-
})().catch(
|
|
150
|
+
})().catch(e => {
|
|
151
151
|
lCore.display('[ERROR][CTR][ASYNCTASK]', e);
|
|
152
|
-
|
|
152
|
+
lCore.log(this, '[CTR][_asyncTask] ' + text.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
153
153
|
--this._waitInfo.asyncTask.count;
|
|
154
154
|
if (!this._waitInfo.asyncTask.count) {
|
|
155
155
|
this._waitInfo.asyncTask.resolve();
|
package/sys/master.js
CHANGED
|
@@ -42,14 +42,14 @@ const os = __importStar(require("os"));
|
|
|
42
42
|
const cluster = __importStar(require("cluster"));
|
|
43
43
|
const http = __importStar(require("http"));
|
|
44
44
|
// --- 库和定义 ---
|
|
45
|
-
const kebab = __importStar(require("
|
|
46
|
-
const sRoute = __importStar(require("
|
|
47
|
-
const lCore = __importStar(require("
|
|
48
|
-
const lFs = __importStar(require("
|
|
49
|
-
const lText = __importStar(require("
|
|
50
|
-
const lCrypto = __importStar(require("
|
|
51
|
-
const lTime = __importStar(require("
|
|
52
|
-
const lZip = __importStar(require("
|
|
45
|
+
const kebab = __importStar(require("~/index"));
|
|
46
|
+
const sRoute = __importStar(require("~/sys/route"));
|
|
47
|
+
const lCore = __importStar(require("~/lib/core"));
|
|
48
|
+
const lFs = __importStar(require("~/lib/fs"));
|
|
49
|
+
const lText = __importStar(require("~/lib/text"));
|
|
50
|
+
const lCrypto = __importStar(require("~/lib/crypto"));
|
|
51
|
+
const lTime = __importStar(require("~/lib/time"));
|
|
52
|
+
const lZip = __importStar(require("~/lib/zip"));
|
|
53
53
|
/** --- 当前运行中的子进程列表 --- */
|
|
54
54
|
const workerList = {};
|
|
55
55
|
/**
|
|
@@ -130,7 +130,7 @@ function createRpcListener() {
|
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
132
|
if (lCore.globalConfig.rpcSecret === 'MUSTCHANGE') {
|
|
133
|
-
res.end(
|
|
133
|
+
res.end(`The rpcSecret is not set. It's recommended to set it to: ${lCore.random(32, lCore.RANDOM_LUN)}`);
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
136
|
switch (msg.action) {
|
|
@@ -235,9 +235,19 @@ function createRpcListener() {
|
|
|
235
235
|
}
|
|
236
236
|
// --- 看文件夹是否存在 ---
|
|
237
237
|
if (pat && !await lFs.isDir(to + pat)) {
|
|
238
|
+
if (rtn.post['strict'] === '1') {
|
|
239
|
+
res.end('Path not found: ' + to + pat);
|
|
240
|
+
await sRoute.unlinkUploadFiles(rtn.files);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
238
243
|
await lFs.mkdir(to + pat);
|
|
239
244
|
}
|
|
240
245
|
// --- 覆盖或创建文件 ---
|
|
246
|
+
if ((rtn.post['strict'] === '1') && !await lFs.isFile(to + pat + fname)) {
|
|
247
|
+
res.end('Path not found: ' + to + pat + fname);
|
|
248
|
+
await sRoute.unlinkUploadFiles(rtn.files);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
241
251
|
await lFs.putContent(to + pat + fname, ls[path]);
|
|
242
252
|
}
|
|
243
253
|
await sRoute.unlinkUploadFiles(rtn.files);
|
|
@@ -252,6 +262,118 @@ function createRpcListener() {
|
|
|
252
262
|
}
|
|
253
263
|
break;
|
|
254
264
|
}
|
|
265
|
+
case 'log': {
|
|
266
|
+
// --- 获取日志信息 ---
|
|
267
|
+
const path = kebab.LOG_CWD + msg.hostname + (msg.fend ?? '') + '/' + msg.path + '.csv';
|
|
268
|
+
if (!await lFs.isFile(path)) {
|
|
269
|
+
res.end(lText.stringifyJson({
|
|
270
|
+
'result': 1,
|
|
271
|
+
'data': false,
|
|
272
|
+
}));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
/** --- 剩余 limit --- */
|
|
276
|
+
let limit = msg.limit ?? 100;
|
|
277
|
+
/** --- 剩余 offset --- */
|
|
278
|
+
let offset = msg.offset ?? 0;
|
|
279
|
+
const rtn = await new Promise((resolve) => {
|
|
280
|
+
const list = [];
|
|
281
|
+
/** --- 当前行号 --- */
|
|
282
|
+
let line = 0;
|
|
283
|
+
/** --- 当前行数据 --- */
|
|
284
|
+
let packet = '';
|
|
285
|
+
lFs.createReadStream(path, {
|
|
286
|
+
'encoding': 'utf8',
|
|
287
|
+
'start': msg.start,
|
|
288
|
+
}).on('data', (buf) => {
|
|
289
|
+
if (typeof buf !== 'string') {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
while (true) {
|
|
293
|
+
// --- 分包 ---
|
|
294
|
+
const index = buf.indexOf('\n');
|
|
295
|
+
if (index === -1) {
|
|
296
|
+
// --- 本次包还没有结束 ---
|
|
297
|
+
packet += buf;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
// --- 本次行结束了 ---
|
|
301
|
+
if (limit === 0) {
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
packet += buf.slice(0, index);
|
|
305
|
+
buf = buf.slice(index + 1);
|
|
306
|
+
++line;
|
|
307
|
+
// --- 先执行下本次完成的 ---
|
|
308
|
+
if (line > 1) {
|
|
309
|
+
if (offset === 0) {
|
|
310
|
+
if (!msg.search || packet.includes(msg.search)) {
|
|
311
|
+
const result = [];
|
|
312
|
+
let currentField = '';
|
|
313
|
+
let inQuotes = false;
|
|
314
|
+
for (let i = 0; i < packet.length; ++i) {
|
|
315
|
+
const char = packet[i];
|
|
316
|
+
if (char === '"') {
|
|
317
|
+
if (inQuotes && packet[i + 1] === '"') {
|
|
318
|
+
currentField += '"';
|
|
319
|
+
++i;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
inQuotes = !inQuotes;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
else if (char === ',' && !inQuotes) {
|
|
326
|
+
result.push(currentField);
|
|
327
|
+
currentField = '';
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
currentField += char;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
result.push(currentField);
|
|
334
|
+
list.push(result);
|
|
335
|
+
--limit;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
--offset;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// --- 处理结束 ---
|
|
343
|
+
packet = '';
|
|
344
|
+
// --- 看看还有没有后面的粘连包 ---
|
|
345
|
+
if (!buf.length) {
|
|
346
|
+
// --- 没粘连包 ---
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
// --- 有粘连包 ---
|
|
350
|
+
}
|
|
351
|
+
}).on('end', () => {
|
|
352
|
+
resolve(list);
|
|
353
|
+
}).on('error', () => {
|
|
354
|
+
resolve(false);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
res.end(lText.stringifyJson({
|
|
358
|
+
'result': 1,
|
|
359
|
+
'data': rtn,
|
|
360
|
+
}));
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
case 'ls': {
|
|
364
|
+
// --- 获取目录内文件/文件夹列表 ---
|
|
365
|
+
const path = lText.urlResolve(kebab.ROOT_CWD, msg.path);
|
|
366
|
+
res.end(lText.stringifyJson({
|
|
367
|
+
'result': 1,
|
|
368
|
+
'data': (await lFs.readDir(path, msg.encoding)).map(item => ({
|
|
369
|
+
'isFile': item.isFile(),
|
|
370
|
+
'isDirectory': item.isDirectory(),
|
|
371
|
+
'isSymbolicLink': item.isSymbolicLink(),
|
|
372
|
+
'name': item.name,
|
|
373
|
+
})),
|
|
374
|
+
}));
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
255
377
|
default: {
|
|
256
378
|
res.end('Not command: ' + msg.action);
|
|
257
379
|
return;
|
package/sys/mod.d.ts
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Date: 2019-6-4 21:35
|
|
4
4
|
* Last: 2020-4-14 13:33:51, 2022-07-23 16:01:34, 2022-09-06 22:59:26, 2023-5-24 19:11:37, 2023-6-13 21:47:58, 2023-7-10 18:54:03, 2023-8-23 17:03:16, 2023-12-11 15:21:22, 2023-12-20 23:12:03, 2024-3-8 16:05:29, 2024-3-20 19:58:15, 2024-8-11 21:14:54, 2024-10-5 14:00:22, 2024-12-14 19:58:34
|
|
5
5
|
*/
|
|
6
|
-
import * as lSql from '
|
|
7
|
-
import * as lDb from '
|
|
8
|
-
import * as sCtr from '
|
|
9
|
-
import * as types from '
|
|
6
|
+
import * as lSql from '~/lib/sql';
|
|
7
|
+
import * as lDb from '~/lib/db';
|
|
8
|
+
import * as sCtr from '~/sys/ctr';
|
|
9
|
+
import * as types from '~/types';
|
|
10
10
|
/** --- 条数列表 --- */
|
|
11
11
|
declare class Rows<T extends Mod> implements types.Rows<T> {
|
|
12
12
|
private readonly _items;
|