@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.
Files changed (73) hide show
  1. package/index.d.ts +1 -1
  2. package/index.js +1 -1
  3. package/lib/buffer.js +3 -9
  4. package/lib/captcha.js +2 -2
  5. package/lib/consistent.js +1 -1
  6. package/lib/core.d.ts +42 -18
  7. package/lib/core.js +147 -152
  8. package/lib/crypto.js +2 -2
  9. package/lib/db.d.ts +3 -3
  10. package/lib/db.js +32 -73
  11. package/lib/dns.d.ts +1 -1
  12. package/lib/dns.js +5 -5
  13. package/lib/fs.js +17 -9
  14. package/lib/jwt.d.ts +3 -3
  15. package/lib/jwt.js +5 -5
  16. package/lib/kv.d.ts +2 -2
  17. package/lib/kv.js +2 -2
  18. package/lib/lan.js +1 -1
  19. package/lib/net/formdata.js +2 -2
  20. package/lib/net/request.d.ts +1 -1
  21. package/lib/net/request.js +1 -1
  22. package/lib/net/response.d.ts +1 -1
  23. package/lib/net.d.ts +2 -2
  24. package/lib/net.js +4 -4
  25. package/lib/s3.d.ts +1 -1
  26. package/lib/s3.js +5 -5
  27. package/lib/scan.d.ts +3 -3
  28. package/lib/scan.js +6 -6
  29. package/lib/session.d.ts +3 -3
  30. package/lib/session.js +7 -7
  31. package/lib/sql.d.ts +3 -3
  32. package/lib/sql.js +7 -37
  33. package/lib/ssh/sftp.js +2 -2
  34. package/lib/ssh/shell.js +1 -1
  35. package/lib/text.d.ts +6 -1
  36. package/lib/text.js +9 -1
  37. package/lib/time.d.ts +1 -1
  38. package/lib/time.js +1 -1
  39. package/lib/turnstile.d.ts +1 -1
  40. package/lib/turnstile.js +2 -2
  41. package/lib/ws.d.ts +10 -2
  42. package/lib/ws.js +62 -3
  43. package/lib/zip.d.ts +1 -1
  44. package/lib/zip.js +5 -11
  45. package/lib/zlib.js +7 -21
  46. package/package.json +5 -4
  47. package/sys/child.js +43 -84
  48. package/sys/cmd.js +7 -6
  49. package/sys/ctr.d.ts +2 -2
  50. package/sys/ctr.js +2 -2
  51. package/sys/master.js +131 -9
  52. package/sys/mod.d.ts +4 -4
  53. package/sys/mod.js +24 -176
  54. package/sys/route.d.ts +1 -1
  55. package/sys/route.js +22 -20
  56. package/www/example/ctr/main.d.ts +1 -1
  57. package/www/example/ctr/main.js +1 -1
  58. package/www/example/ctr/middle.d.ts +2 -2
  59. package/www/example/ctr/middle.js +1 -1
  60. package/www/example/ctr/test.d.ts +3 -2
  61. package/www/example/ctr/test.js +83 -30
  62. package/www/example/mod/test.d.ts +2 -2
  63. package/www/example/mod/test.js +2 -2
  64. package/www/example/mod/testdata.d.ts +1 -1
  65. package/www/example/mod/testdata.js +1 -1
  66. package/www/example/ws/mproxy.d.ts +1 -1
  67. package/www/example/ws/mproxy.js +2 -2
  68. package/www/example/ws/rproxy.d.ts +1 -1
  69. package/www/example/ws/rproxy.js +2 -2
  70. package/www/example/ws/rsocket.d.ts +4 -0
  71. package/www/example/ws/rsocket.js +47 -0
  72. package/www/example/ws/test.d.ts +6 -1
  73. 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("../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"));
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("../sys/route"));
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
- const certList = [];
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(async function (e) {
123
- await lCore.log({
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(async function (e) {
157
- await lCore.log({
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(async function (e) {
190
- await lCore.log({
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(async function (e) {
222
- await lCore.log({
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
- await lCore.log({
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
- }, '(E01)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
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
- await lCore.log({
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
- certList.length = 0;
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
- certList.push({
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
- // eslint-disable-next-line no-console
602
- console.log(`[child] Worker ${process.pid} busy: ${str.join(',')}.`);
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(async function (e) {
639
- await lCore.log({
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("../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"));
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, types.Json>;
37
+ protected _jwt: Record<string, any>;
38
38
  /** --- Session 数组 --- */
39
- protected _session: Record<string, types.Json>;
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(async (e) => {
150
+ })().catch(e => {
151
151
  lCore.display('[ERROR][CTR][ASYNCTASK]', e);
152
- await lCore.log(this, '(ctr.asyncTask)' + text.stringifyJson(e.stack).slice(1, -1), '-error');
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("../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"));
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('rpcSecret need be "' + lCore.random(32, lCore.RANDOM_LUN) + '"');
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 '../lib/sql';
7
- import * as lDb from '../lib/db';
8
- import * as sCtr from '../sys/ctr';
9
- import * as types from '../types';
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;