@maiyunnet/kebab 3.0.3 → 3.1.1

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 (72) hide show
  1. package/README.md +1 -1
  2. package/index.d.ts +1 -1
  3. package/index.js +1 -1
  4. package/lib/captcha.js +2 -2
  5. package/lib/consistent.js +1 -1
  6. package/lib/core.d.ts +3 -3
  7. package/lib/core.js +29 -13
  8. package/lib/cron.d.ts +40 -0
  9. package/lib/cron.js +126 -0
  10. package/lib/crypto.js +2 -2
  11. package/lib/db.d.ts +4 -3
  12. package/lib/db.js +27 -15
  13. package/lib/dns.d.ts +1 -1
  14. package/lib/dns.js +7 -7
  15. package/lib/jwt.d.ts +3 -3
  16. package/lib/jwt.js +4 -4
  17. package/lib/kv.d.ts +4 -3
  18. package/lib/kv.js +21 -9
  19. package/lib/lan.js +1 -1
  20. package/lib/net/formdata.js +2 -2
  21. package/lib/net/request.d.ts +1 -1
  22. package/lib/net/request.js +2 -2
  23. package/lib/net/response.d.ts +1 -1
  24. package/lib/net.d.ts +2 -2
  25. package/lib/net.js +4 -4
  26. package/lib/s3.d.ts +1 -1
  27. package/lib/s3.js +2 -2
  28. package/lib/scan.d.ts +3 -3
  29. package/lib/scan.js +6 -6
  30. package/lib/session.d.ts +3 -3
  31. package/lib/session.js +6 -6
  32. package/lib/sql.d.ts +2 -2
  33. package/lib/sql.js +3 -3
  34. package/lib/ssh/sftp.js +2 -2
  35. package/lib/ssh/shell.js +1 -1
  36. package/lib/text.d.ts +2 -2
  37. package/lib/text.js +1 -1
  38. package/lib/time.d.ts +1 -1
  39. package/lib/time.js +1 -1
  40. package/lib/turnstile.d.ts +1 -1
  41. package/lib/turnstile.js +2 -2
  42. package/lib/ws.d.ts +2 -2
  43. package/lib/ws.js +2 -2
  44. package/lib/zip.d.ts +1 -1
  45. package/lib/zip.js +1 -1
  46. package/package.json +9 -6
  47. package/sys/child.js +6 -6
  48. package/sys/cmd.js +6 -6
  49. package/sys/master.js +8 -8
  50. package/sys/mod.d.ts +5 -5
  51. package/sys/mod.js +39 -16
  52. package/sys/route.d.ts +1 -1
  53. package/sys/route.js +11 -11
  54. package/www/example/ctr/main.d.ts +1 -1
  55. package/www/example/ctr/main.js +1 -1
  56. package/www/example/ctr/middle.d.ts +2 -2
  57. package/www/example/ctr/middle.js +1 -1
  58. package/www/example/ctr/test.d.ts +4 -2
  59. package/www/example/ctr/test.js +125 -42
  60. package/www/example/mod/test.d.ts +2 -2
  61. package/www/example/mod/test.js +2 -2
  62. package/www/example/mod/testdata.d.ts +1 -1
  63. package/www/example/mod/testdata.js +1 -1
  64. package/www/example/view/test.ejs +2 -1
  65. package/www/example/ws/mproxy.d.ts +1 -1
  66. package/www/example/ws/mproxy.js +3 -3
  67. package/www/example/ws/rproxy.d.ts +1 -1
  68. package/www/example/ws/rproxy.js +3 -3
  69. package/www/example/ws/rsocket.d.ts +1 -1
  70. package/www/example/ws/rsocket.js +3 -3
  71. package/www/example/ws/test.d.ts +1 -1
  72. package/www/example/ws/test.js +3 -3
package/README.md CHANGED
@@ -28,7 +28,7 @@ Run `npm i @maiyunnet/kebab` to install the latest version. After installation,
28
28
 
29
29
  ## Library
30
30
 
31
- Buffer, Captcha, Consistent, Core, Crypto, Db (MySQL), Dns (DNSPod, Alibaba Cloud), Fs, Jwt, Kv (Redis), Lan, Net, S3, Scan, Session, Sql, Ssh (Shell, Sftp), Text, Time, Ws, Zip, Zlib.
31
+ Buffer, Captcha, Consistent, Core, Cron, Crypto, Db (MySQL), Dns (DNSPod, Alibaba Cloud), Fs, Jwt, Kv (Redis), Lan, Net, S3, Scan, Session, Sql, Ssh (Shell, Sftp), Text, Time, Ws, Zip, Zlib.
32
32
 
33
33
  ## Partial Features
34
34
 
package/index.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * ------------------------
9
9
  */
10
10
  /** --- 当前系统版本号 --- */
11
- export declare const VER = "3.0.3";
11
+ export declare const VER = "3.1.1";
12
12
  /** --- 框架根目录,以 / 结尾 --- */
13
13
  export declare const ROOT_PATH: string;
14
14
  export declare const LIB_PATH: string;
package/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * ------------------------
9
9
  */
10
10
  /** --- 当前系统版本号 --- */
11
- export const VER = '3.0.3';
11
+ export const VER = '3.1.1';
12
12
  // --- 服务端用的路径 ---
13
13
  const imu = import.meta.url.replace('file://', '').replace(/^\/(\w:)/, '$1').replace(/\\/g, '/');
14
14
  /** --- /xxx/xxx --- */
package/lib/captcha.js CHANGED
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import * as svgCaptcha from 'svg-captcha';
7
7
  import * as mime from '@litert/mime';
8
- import * as core from '../lib/core.js';
9
- import * as kebab from '../index.js';
8
+ import * as core from '#lib/core.js';
9
+ import * as kebab from '#index.js';
10
10
  svgCaptcha.loadFont(kebab.LIB_PATH + 'captcha/zcool-addict-italic.ttf');
11
11
  export class Captcha {
12
12
  constructor(opt) {
package/lib/consistent.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Date: 2022-09-12 10:51:16
4
4
  * Last: 2022-09-12 10:51:20, 2023-3-17 10:52:04, 2023-11-15 11:45:28
5
5
  */
6
- import * as crypto from '../lib/crypto.js';
6
+ import * as crypto from '#lib/crypto.js';
7
7
  export class Consistent {
8
8
  constructor(vcount) {
9
9
  /** --- 虚拟节点数量 --- */
package/lib/core.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as http from 'http';
2
2
  import * as http2 from 'http2';
3
3
  import * as stream from 'stream';
4
- import * as lResponse from '../lib/net/response.js';
5
- import * as sCtr from '../sys/ctr.js';
6
- import * as types from '../types/index.js';
4
+ import * as lResponse from '#lib/net/response.js';
5
+ import * as sCtr from '#sys/ctr.js';
6
+ import * as types from '#types/index.js';
7
7
  /** --- 全局参数 --- */
8
8
  export declare const globalConfig: types.IConfig & {
9
9
  'httpPort': number;
package/lib/core.js CHANGED
@@ -5,14 +5,14 @@
5
5
  */
6
6
  import * as cp from 'child_process';
7
7
  import * as stream from 'stream';
8
- import * as lTime from '../lib/time.js';
9
- import * as lFs from '../lib/fs.js';
10
- import * as lText from '../lib/text.js';
11
- import * as lNet from '../lib/net.js';
12
- import * as lCrypto from '../lib/crypto.js';
13
- import * as lResponse from '../lib/net/response.js';
14
- import * as sCtr from '../sys/ctr.js';
15
- import * as kebab from '../index.js';
8
+ import * as lTime from '#lib/time.js';
9
+ import * as lFs from '#lib/fs.js';
10
+ import * as lText from '#lib/text.js';
11
+ import * as lNet from '#lib/net.js';
12
+ import * as lCrypto from '#lib/crypto.js';
13
+ import * as lResponse from '#lib/net/response.js';
14
+ import * as sCtr from '#sys/ctr.js';
15
+ import * as kebab from '#index.js';
16
16
  /** --- 全局参数 --- */
17
17
  export const globalConfig = {};
18
18
  /**
@@ -154,7 +154,7 @@ export function purify(text) {
154
154
  * @param tree 当前树,无需传入
155
155
  */
156
156
  export function checkType(val, type, tree = 'root') {
157
- /** --- 要校验的对象 --- */
157
+ /** --- 要校验的对象类型 --- */
158
158
  const vtype = typeof val;
159
159
  if (Array.isArray(type)) {
160
160
  // --- 数组的话 ---
@@ -179,13 +179,19 @@ export function checkType(val, type, tree = 'root') {
179
179
  return type.test(val) ? '' : 'regexp:' + tree + ':' + vtype;
180
180
  }
181
181
  if (ttype === 'string') {
182
+ // --- 示例组在是字符串的前提下,判断是否是必填项 ---
182
183
  if (vtype !== 'string' && val !== undefined && val !== null) {
184
+ // --- 用户值不是字符串,也不是未填,那直接失败 ---
183
185
  return 'string:' + tree + ':' + vtype;
184
186
  }
185
- // --- 是字符串、undefinednull ---
187
+ // --- 是字符串 或 undefinednull ---
186
188
  if (type) {
187
- return val ? '' : 'require:' + tree + ':' + vtype;
189
+ // --- 示例组有值,必然必填 ---
190
+ return val ?
191
+ '' : // --- 有值,直接成功 ---
192
+ 'string:' + tree + ':' + vtype;
188
193
  }
194
+ // --- 示例组无值,用户值有没有值都成功 ---
189
195
  return '';
190
196
  }
191
197
  if (val === undefined || val === null) {
@@ -203,14 +209,24 @@ export function checkType(val, type, tree = 'root') {
203
209
  }
204
210
  // --- 先判断每个值是否相等 ---
205
211
  for (const key in type) {
206
- const res = checkType(val[key], type[key], tree + '.' + key);
212
+ // --- 先判断是否是可选值 ---
213
+ /** --- 示例组的 key 可能是 x? --- */
214
+ let k = key;
215
+ if (key.endsWith('?')) {
216
+ k = key.slice(0, -1);
217
+ if (val[k] === undefined || val[k] === null) {
218
+ // --- 示例允许为空且用户值为空,则跳过 ---
219
+ continue;
220
+ }
221
+ }
222
+ const res = checkType(val[k], type[key], tree + '.' + k);
207
223
  if (res) {
208
224
  return res;
209
225
  }
210
226
  }
211
227
  // --- 再判断是否传了类型限定中没有的值 ---
212
228
  for (const key in val) {
213
- if (type[key] !== undefined) {
229
+ if (type[key] !== undefined || type[key + '?'] !== undefined) {
214
230
  continue;
215
231
  }
216
232
  return `undefined:${tree}.${key}:${typeof val[key]}`;
package/lib/cron.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /** --- 获取定时任务列表 --- */
2
+ export declare function getRegulars(): IRegularData[];
3
+ /**
4
+ * --- 创建定时执行的计划任务 ---
5
+ * @param task 计划任务对象
6
+ * @param immediate 如果传入的时间小于当前时间且没有执行过则立即执行一次(格式:YmdHi)
7
+ */
8
+ export declare function regular(task: IRegular, immediate?: string): Promise<boolean>;
9
+ /**
10
+ * --- 执行定时任务 ---
11
+ */
12
+ export declare function run(): void;
13
+ /** --- 定时任务 --- */
14
+ export interface IRegular {
15
+ /** --- 任务名称 --- */
16
+ 'name': string;
17
+ /** --- 任务对象 --- */
18
+ 'date': {
19
+ /** --- -1, 1 - 12 --- */
20
+ 'month': number;
21
+ /** --- -1, 1 - 31 --- */
22
+ 'day': number;
23
+ /** --- -1, 0 - 23 --- */
24
+ 'hour': number;
25
+ /** --- -1, 0 - 59 --- */
26
+ 'minute': number;
27
+ /** --- -1, 0 - 6 --- */
28
+ 'week': number;
29
+ };
30
+ /** --- 任务函数 --- */
31
+ callback: (date: string) => void | Promise<void>;
32
+ }
33
+ export interface IRegularData extends IRegular {
34
+ /** --- 上次执行时间字符串 --- */
35
+ 'last': string;
36
+ /** --- 总执行次数 --- */
37
+ 'count': number;
38
+ /** --- 定时任务重启后的执行次数 --- */
39
+ 'rcount': number;
40
+ }
package/lib/cron.js ADDED
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Project: Kebab, User: JianSuoQiYue
3
+ * Date: 2025-9-20 19:46:30
4
+ * Last: 2025-9-20 19:46:32
5
+ */
6
+ import * as kebab from '#index.js';
7
+ import * as lFs from '#lib/fs.js';
8
+ import * as lCore from '#lib/core.js';
9
+ import * as lText from '#lib/text.js';
10
+ import * as lTime from '#lib/time.js';
11
+ /** --- 定时任务列表 --- */
12
+ const regulars = [];
13
+ /** --- 获取定时任务列表 --- */
14
+ export function getRegulars() {
15
+ return regulars;
16
+ }
17
+ /**
18
+ * --- 创建定时执行的计划任务 ---
19
+ * @param task 计划任务对象
20
+ * @param immediate 如果传入的时间小于当前时间且没有执行过则立即执行一次(格式:YmdHi)
21
+ */
22
+ export async function regular(task, immediate = '') {
23
+ if (!/^[a-z0-9-_]{1,32}$/.test(task.name)) {
24
+ return false;
25
+ }
26
+ if (regulars.find(item => item.name === task.name)) {
27
+ // --- 当前进程已经注册过了,不能再注册了 ---
28
+ return false;
29
+ }
30
+ // --- 检查是否存在相同名称的计划任务 ---
31
+ if (!await lFs.isDir(kebab.LOG_CWD + `cron/`)) {
32
+ await lFs.mkdir(kebab.LOG_CWD + `cron/`);
33
+ await lFs.putContent(kebab.LOG_CWD + `cron/lock.txt`, 'Kebab');
34
+ }
35
+ // --- 保存计划任务 ---
36
+ const content = await lFs.getContent(kebab.LOG_CWD + `cron/${task.name}.json`, 'utf8');
37
+ /** --- 任务对象 --- */
38
+ const obj = {
39
+ ...task,
40
+ 'last': '',
41
+ 'count': 0,
42
+ 'rcount': 0,
43
+ };
44
+ if (content) {
45
+ const json = JSON.parse(content);
46
+ obj.last = json.last;
47
+ obj.count = json.count;
48
+ }
49
+ await lFs.putContent(kebab.LOG_CWD + `cron/${obj.name}.json`, JSON.stringify(obj));
50
+ // --- 检查是否需要立即执行 ---
51
+ /** --- 当前日期字符串 --- */
52
+ const date = lTime.format(null, 'YmdHi');
53
+ if (immediate && (immediate < date)) {
54
+ try {
55
+ obj.callback(date);
56
+ }
57
+ catch (e) {
58
+ const msg = `[CRON][${obj.name}] ${lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""')}`;
59
+ lCore.debug(msg);
60
+ lCore.log({}, msg, '-error');
61
+ }
62
+ // --- 设置执行后的数据 ---
63
+ obj.last = date;
64
+ ++obj.count;
65
+ ++obj.rcount;
66
+ await lFs.putContent(kebab.LOG_CWD + `cron/${obj.name}.json`, JSON.stringify(obj));
67
+ }
68
+ regulars.push(obj);
69
+ return true;
70
+ }
71
+ /**
72
+ * --- 执行定时任务 ---
73
+ */
74
+ export function run() {
75
+ /** --- 当前日期字符串 --- */
76
+ const date = lTime.format(null, 'YmdHi');
77
+ /** --- 当前时间 --- */
78
+ const now = new Date();
79
+ /** --- 当前月份 --- */
80
+ const month = now.getMonth() + 1;
81
+ /** --- 当前日期 --- */
82
+ const day = now.getDate();
83
+ /** --- 当前小时 --- */
84
+ const hour = now.getHours();
85
+ /** --- 当前分钟 --- */
86
+ const minute = now.getMinutes();
87
+ /** --- 当前星期几 --- */
88
+ const week = now.getDay();
89
+ // --- 检查定时任务是否需要执行 ---
90
+ for (const task of regulars) {
91
+ if ((task.date.minute !== -1) && (task.date.minute !== minute)) {
92
+ continue;
93
+ }
94
+ if ((task.date.hour !== -1) && (task.date.hour !== hour)) {
95
+ continue;
96
+ }
97
+ if ((task.date.week !== -1) && (task.date.week !== week)) {
98
+ continue;
99
+ }
100
+ if ((task.date.day !== -1) && (task.date.day !== day)) {
101
+ continue;
102
+ }
103
+ if ((task.date.month !== -1) && (task.date.month !== month)) {
104
+ continue;
105
+ }
106
+ if (task.last === date) {
107
+ continue;
108
+ }
109
+ // --- 执行回调 ---
110
+ try {
111
+ task.callback(date);
112
+ }
113
+ catch (e) {
114
+ const msg = `[CRON][${task.name}] ${lText.stringifyJson(e.message ?? '').slice(1, -1).replace(/"/g, '""')}`;
115
+ lCore.debug(msg);
116
+ lCore.log({}, msg, '-error');
117
+ }
118
+ // --- 设置执行后的数据 ---
119
+ task.last = date;
120
+ ++task.count;
121
+ ++task.rcount;
122
+ lFs.putContent(kebab.LOG_CWD + `cron/${task.name}.json`, JSON.stringify(task)).catch(() => { });
123
+ }
124
+ }
125
+ // --- 每15秒检查一次 ---
126
+ setInterval(run, 15_000);
package/lib/crypto.js CHANGED
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import * as crypto from 'crypto';
7
7
  // --- 库和定义 ---
8
- import * as lFs from '../lib/fs.js';
9
- import * as lCore from '../lib/core.js';
8
+ import * as lFs from '#lib/fs.js';
9
+ import * as lCore from '#lib/core.js';
10
10
  // --- 非对称加密 ---
11
11
  /**
12
12
  * --- 创建非对称秘钥 ---
package/lib/db.d.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  * Last: 2020-4-13 15:34:45, 2022-09-12 13:10:34, 2023-5-24 18:29:38, 2024-7-11 14:37:54, 2024-8-25 00:32:53, 2024-9-22 17:30:47, 2025-8-3 20:24:03
5
5
  */
6
6
  import * as mysql2 from 'mysql2/promise';
7
- import * as sCtr from '../sys/ctr.js';
8
- import * as types from '../types/index.js';
7
+ import * as sCtr from '#sys/ctr.js';
8
+ import * as types from '#types/index.js';
9
9
  /** --- query 返回的数据 --- */
10
10
  export interface IData {
11
11
  'rows': any[] | null;
@@ -159,8 +159,9 @@ export declare class Connection {
159
159
  refreshLast(): void;
160
160
  /**
161
161
  * --- 通过执行一条语句判断当前连接是否可用 ---
162
+ * @param last 是否刷新最后使用时间(默认刷新)
162
163
  */
163
- isAvailable(): Promise<boolean>;
164
+ isAvailable(last?: boolean): Promise<boolean>;
164
165
  /**
165
166
  * --- 执行一条 SQL 并获得返回数据 ---
166
167
  * @param sql 执行的 SQL 字符串
package/lib/db.js CHANGED
@@ -7,11 +7,11 @@
7
7
  // --- 第三方 ---
8
8
  import * as mysql2 from 'mysql2/promise';
9
9
  // --- 库和定义 ---
10
- import * as lTime from '../lib/time.js';
11
- import * as lSql from '../lib/sql.js';
12
- import * as lCore from '../lib/core.js';
13
- import * as lText from '../lib/text.js';
14
- import * as sCtr from '../sys/ctr.js';
10
+ import * as lTime from '#lib/time.js';
11
+ import * as lSql from '#lib/sql.js';
12
+ import * as lCore from '#lib/core.js';
13
+ import * as lText from '#lib/text.js';
14
+ import * as sCtr from '#sys/ctr.js';
15
15
  /** --- 连接列表池 --- */
16
16
  const connections = [];
17
17
  /**
@@ -46,12 +46,19 @@ async function checkConnection() {
46
46
  }
47
47
  continue;
48
48
  }
49
- // --- 目前未被使用中的连接 ---
50
- if (connection.getLast() > now - 30) {
51
- // --- 30 秒内使用过,不管 ---
49
+ if (connection.getLast() <= now - 30) {
50
+ // --- 30 秒未被使用,则关闭 ---
51
+ await connection.end();
52
+ connections.splice(i, 1);
53
+ --i;
52
54
  continue;
53
55
  }
54
- // --- 30 秒未被使用,则关闭 ---
56
+ // --- 30 秒内使用过,看看连接是否正常 ---
57
+ if (await connection.isAvailable(false)) {
58
+ // --- 正常 ---
59
+ continue;
60
+ }
61
+ // --- 连接有问题,直接关闭 ---
55
62
  await connection.end();
56
63
  connections.splice(i, 1);
57
64
  --i;
@@ -162,13 +169,15 @@ export class Pool {
162
169
  const c = new Connection(this._etc, link);
163
170
  c.using();
164
171
  link.on('error', function (err) {
172
+ c.setLost();
165
173
  if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
166
- lCore.display('[DB][_getConnection]', err);
174
+ lCore.debug('[DB][_getConnection]', err);
167
175
  }
168
- c.setLost();
169
- }).on('end', function () {
176
+ }).on('end', () => {
170
177
  // lCore.debug('[DB][_getConnection] connection end.');
171
178
  c.setLost();
179
+ }).on('close', () => {
180
+ c.setLost();
172
181
  });
173
182
  conn = c;
174
183
  connections.push(conn);
@@ -389,9 +398,12 @@ export class Connection {
389
398
  }
390
399
  /**
391
400
  * --- 通过执行一条语句判断当前连接是否可用 ---
401
+ * @param last 是否刷新最后使用时间(默认刷新)
392
402
  */
393
- async isAvailable() {
394
- this.refreshLast();
403
+ async isAvailable(last = true) {
404
+ if (last) {
405
+ this.refreshLast();
406
+ }
395
407
  try {
396
408
  await this._link.query('SELECT 1');
397
409
  return true;
@@ -456,7 +468,7 @@ export class Connection {
456
468
  }
457
469
  this._lastSql.push({
458
470
  'sql': sql,
459
- 'values': values
471
+ 'values': values,
460
472
  });
461
473
  const time = Date.now();
462
474
  res = await this._link.execute(sql, values);
package/lib/dns.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * Date: 2019-6-19
4
4
  * Last: 2022-09-12 20:58:07, 2024-2-21 17:55:54, 2025-6-13 19:08:56
5
5
  */
6
- import * as ctr from '../sys/ctr.js';
6
+ import * as ctr from '#sys/ctr.js';
7
7
  /**
8
8
  * 0.DNSPod:https://www.dnspod.cn/docs/index.html(腾讯云也请使用 DNSPod 的 API)
9
9
  * 1.阿里云:https://help.aliyun.com/document_detail/29745.html
package/lib/dns.js CHANGED
@@ -4,11 +4,11 @@
4
4
  * Last: 2022-09-12 20:58:07, 2024-2-21 17:55:54, 2025-6-13 19:08:56
5
5
  */
6
6
  // --- 库和定义 ---
7
- import * as net from '../lib/net.js';
8
- import * as core from '../lib/core.js';
9
- import * as text from '../lib/text.js';
10
- import * as crypto from '../lib/crypto.js';
11
- import * as response from '../lib/net/response.js';
7
+ import * as net from '#lib/net.js';
8
+ import * as core from '#lib/core.js';
9
+ import * as text from '#lib/text.js';
10
+ import * as crypto from '#lib/crypto.js';
11
+ import * as response from '#lib/net/response.js';
12
12
  /**
13
13
  * 0.DNSPod:https://www.dnspod.cn/docs/index.html(腾讯云也请使用 DNSPod 的 API)
14
14
  * 1.阿里云:https://help.aliyun.com/document_detail/29745.html
@@ -87,7 +87,7 @@ export class Dns {
87
87
  }, obj);
88
88
  const path = data['_path'];
89
89
  delete data['_path'];
90
- return net.post('https://dnsapi.cn/' + path, data); // 境外 api 会自动调度到香港服务器
90
+ return await net.post('https://dnsapi.cn/' + path, data); // 境外 api 会自动调度到香港服务器
91
91
  }
92
92
  // --- 阿里云 ---
93
93
  case ESERVICE.ALIBABA: {
@@ -102,7 +102,7 @@ export class Dns {
102
102
  }, obj));
103
103
  const urlRight = text.queryStringify(getData);
104
104
  const signature = crypto.hashHmac('sha1', `GET&${encodeURIComponent('/')}&${encodeURIComponent(urlRight)}`, (this._opt.secretKey ?? '') + '&', 'base64');
105
- return net.get(`https://alidns.aliyuncs.com/?${urlRight}&Signature=${encodeURIComponent(signature)}`); // 境外 api 会自动调度到新加坡服务器
105
+ return await net.get(`https://alidns.aliyuncs.com/?${urlRight}&Signature=${encodeURIComponent(signature)}`); // 境外 api 会自动调度到新加坡服务器
106
106
  }
107
107
  }
108
108
  return new response.Response(null);
package/lib/jwt.d.ts CHANGED
@@ -3,9 +3,9 @@
3
3
  * Date: 2023-1-31 20:34:47
4
4
  * Last: 2023-1-31 20:34:47, 2023-12-8 13:55:09
5
5
  */
6
- import * as kv from '../lib/kv.js';
7
- import * as ctr from '../sys/ctr.js';
8
- import * as types from '../types/index.js';
6
+ import * as kv from '#lib/kv.js';
7
+ import * as ctr from '#sys/ctr.js';
8
+ import * as types from '#types/index.js';
9
9
  export interface IOptions {
10
10
  'name'?: string;
11
11
  'ttl'?: number;
package/lib/jwt.js CHANGED
@@ -4,10 +4,10 @@
4
4
  * Last: 2023-1-31 20:34:47, 2023-12-8 13:55:09
5
5
  */
6
6
  // --- 库和定义 ---
7
- import * as lCore from '../lib/core.js';
8
- import * as lTime from '../lib/time.js';
9
- import * as lText from '../lib/text.js';
10
- import * as lCrypto from '../lib/crypto.js';
7
+ import * as lCore from '#lib/core.js';
8
+ import * as lTime from '#lib/time.js';
9
+ import * as lText from '#lib/text.js';
10
+ import * as lCrypto from '#lib/crypto.js';
11
11
  export class Jwt {
12
12
  /**
13
13
  * --- 初始化函数,相当于 construct ---
package/lib/kv.d.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  * Last: 2020-3-28 18:54:04, 2022-09-12 23:24:45, 2022-09-22 01:06:22, 2024-2-21 13:32:56, 2024-8-21 16:59:57
5
5
  */
6
6
  import * as redis from '@litert/redis';
7
- import * as sCtr from '../sys/ctr.js';
8
- import * as types from '../types/index.js';
7
+ import * as sCtr from '#sys/ctr.js';
8
+ import * as types from '#types/index.js';
9
9
  /** --- 连接信息 --- */
10
10
  export interface IConnectionInfo {
11
11
  'id': number;
@@ -380,8 +380,9 @@ export declare class Connection {
380
380
  flushDb(): Promise<boolean>;
381
381
  /**
382
382
  * --- 发送 ping ---
383
+ * @param last 是否刷新最后使用时间(默认刷新)
383
384
  */
384
- ping(): Promise<false | string>;
385
+ ping(last?: boolean): Promise<false | string>;
385
386
  /**
386
387
  * --- 设置哈希表值 ---
387
388
  * @param key key 名
package/lib/kv.js CHANGED
@@ -8,9 +8,9 @@
8
8
  // --- 第三方 ---
9
9
  import * as redis from '@litert/redis';
10
10
  // --- 库和定义 ---
11
- import * as lTime from '../lib/time.js';
12
- import * as lText from '../lib/text.js';
13
- import * as lCore from '../lib/core.js';
11
+ import * as lTime from '#lib/time.js';
12
+ import * as lText from '#lib/text.js';
13
+ import * as lCore from '#lib/core.js';
14
14
  /** --- 连接列表(同一个 host、port、index、auth 只有一个连接) --- */
15
15
  const connections = [];
16
16
  /**
@@ -40,12 +40,19 @@ async function checkConnection() {
40
40
  }
41
41
  continue;
42
42
  }
43
- // --- 检测 30 秒内是否使用过 ---
44
- if (connection.getLast() > now - 30) {
45
- // --- 30 秒内使用过,不管 ---
43
+ if (connection.getLast() <= now - 30) {
44
+ // --- 30 秒未被使用,则关闭 ---
45
+ await connection.end();
46
+ connections.splice(i, 1);
47
+ --i;
48
+ continue;
49
+ }
50
+ // --- 30 秒内使用过,看看连接是否正常 ---
51
+ if (await connection.ping(false)) {
52
+ // --- 正常 ---
46
53
  continue;
47
54
  }
48
- // --- 30 秒未被使用,则关闭 ---
55
+ // --- 连接有问题,直接关闭 ---
49
56
  await connection.end();
50
57
  connections.splice(i, 1);
51
58
  --i;
@@ -613,6 +620,8 @@ export class Pool {
613
620
  conn.setLost();
614
621
  // console.log(`--- redis [${conn._etc.host}:${conn._etc.port}] error ---`);
615
622
  lCore.debug('[KV][ERROR]', err);
623
+ }).on('end', () => {
624
+ conn.setLost();
616
625
  }).on('close', () => {
617
626
  conn.setLost();
618
627
  });
@@ -1051,9 +1060,12 @@ end`;
1051
1060
  }
1052
1061
  /**
1053
1062
  * --- 发送 ping ---
1063
+ * @param last 是否刷新最后使用时间(默认刷新)
1054
1064
  */
1055
- async ping() {
1056
- this.refreshLast();
1065
+ async ping(last = true) {
1066
+ if (last) {
1067
+ this.refreshLast();
1068
+ }
1057
1069
  try {
1058
1070
  return (await this._link.ping()) === 'PONG' ? 'PONG' : false;
1059
1071
  }
package/lib/lan.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as os from 'os';
2
- import * as lCore from '../lib/core.js';
2
+ import * as lCore from '#lib/core.js';
3
3
  /**
4
4
  * --- 获取当前网卡的 IP、MAC 信息 ---
5
5
  */
@@ -5,8 +5,8 @@
5
5
  */
6
6
  import * as stream from 'stream';
7
7
  import * as mime from '@litert/mime';
8
- import * as core from '../../lib/core.js';
9
- import * as fs from '../../lib/fs.js';
8
+ import * as core from '#lib/core.js';
9
+ import * as fs from '#lib/fs.js';
10
10
  export class FormData extends stream.Readable {
11
11
  constructor() {
12
12
  super(...arguments);
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import * as stream from 'stream';
7
7
  import * as response from './response.js';
8
- import * as types from '../../types/index.js';
8
+ import * as types from '#types/index.js';
9
9
  export declare class Request {
10
10
  /** --- get 或 post 的数据 --- */
11
11
  private _data;
@@ -1,4 +1,4 @@
1
- import * as net from '../../lib/net.js';
1
+ import * as net from '#lib/net.js';
2
2
  export class Request {
3
3
  constructor(url) {
4
4
  /** --- get 或 post 的数据 --- */
@@ -113,7 +113,7 @@ export class Request {
113
113
  * --- 发起请求 ---
114
114
  * @param cookie
115
115
  */
116
- async request(cookie) {
116
+ request(cookie) {
117
117
  this._opt.cookie = cookie;
118
118
  return net.request(this._url, this._data, this._opt);
119
119
  }
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import * as hc from '@litert/http-client';
7
7
  import * as nStream from 'stream';
8
- import * as types from '../../types/index.js';
8
+ import * as types from '#types/index.js';
9
9
  export declare class Response {
10
10
  /** --- httpClient 请求对象 --- */
11
11
  private readonly _req;
package/lib/net.d.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  import * as stream from 'stream';
8
8
  import * as http from 'http';
9
9
  import * as http2 from 'http2';
10
- import * as ctr from '../sys/ctr.js';
11
- import * as types from '../types/index.js';
10
+ import * as ctr from '#sys/ctr.js';
11
+ import * as types from '#types/index.js';
12
12
  import * as fd from './net/formdata.js';
13
13
  import * as lRequest from './net/request.js';
14
14
  import * as response from './net/response.js';