@maiyunnet/kebab 2.0.7 → 2.0.9

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 (83) hide show
  1. package/index.d.ts +11 -1
  2. package/index.js +13 -1
  3. package/lib/buffer.d.ts +25 -0
  4. package/lib/buffer.js +30 -5
  5. package/lib/captcha.d.ts +15 -0
  6. package/lib/captcha.js +20 -0
  7. package/lib/consistent.d.ts +51 -0
  8. package/lib/consistent.js +59 -0
  9. package/lib/core.d.ts +134 -0
  10. package/lib/core.js +176 -0
  11. package/lib/crypto.d.ts +75 -6
  12. package/lib/crypto.js +206 -38
  13. package/lib/db.d.ts +104 -0
  14. package/lib/db.js +126 -0
  15. package/lib/dns.d.ts +51 -0
  16. package/lib/dns.js +54 -2
  17. package/lib/fs.d.ts +100 -0
  18. package/lib/fs.js +118 -0
  19. package/lib/jwt.d.ts +43 -0
  20. package/lib/jwt.js +45 -0
  21. package/lib/kv.d.ts +362 -0
  22. package/lib/kv.js +377 -0
  23. package/lib/lan.d.ts +6 -0
  24. package/lib/lan.js +7 -0
  25. package/lib/net/formdata.d.ts +38 -0
  26. package/lib/net/formdata.js +43 -0
  27. package/lib/net/request.d.ts +62 -0
  28. package/lib/net/request.js +57 -0
  29. package/lib/net/response.d.ts +21 -0
  30. package/lib/net/response.js +16 -0
  31. package/lib/net.d.ts +86 -0
  32. package/lib/net.js +140 -0
  33. package/lib/s3.d.ts +52 -0
  34. package/lib/s3.js +51 -0
  35. package/lib/scan.d.ts +52 -0
  36. package/lib/scan.js +84 -0
  37. package/lib/session.d.ts +31 -0
  38. package/lib/session.js +52 -1
  39. package/lib/sql.d.ts +176 -0
  40. package/lib/sql.js +287 -2
  41. package/lib/ssh/sftp.d.ts +106 -0
  42. package/lib/ssh/sftp.js +106 -0
  43. package/lib/ssh/shell.d.ts +37 -0
  44. package/lib/ssh/shell.js +31 -0
  45. package/lib/ssh.d.ts +32 -0
  46. package/lib/ssh.js +32 -0
  47. package/lib/text.d.ts +131 -0
  48. package/lib/text.js +188 -0
  49. package/lib/time.d.ts +53 -0
  50. package/lib/time.js +55 -0
  51. package/lib/ws.d.ts +68 -0
  52. package/lib/ws.js +74 -0
  53. package/lib/zip.d.ts +53 -0
  54. package/lib/zip.js +73 -0
  55. package/lib/zlib.d.ts +76 -0
  56. package/lib/zlib.js +78 -0
  57. package/main.d.ts +5 -0
  58. package/main.js +12 -0
  59. package/package.json +3 -2
  60. package/sys/child.js +104 -0
  61. package/sys/cmd.js +28 -0
  62. package/sys/ctr.d.ts +166 -0
  63. package/sys/ctr.js +177 -0
  64. package/sys/master.js +63 -0
  65. package/sys/mod.d.ts +266 -0
  66. package/sys/mod.js +335 -0
  67. package/sys/route.d.ts +34 -0
  68. package/sys/route.js +164 -0
  69. package/www/example/ctr/test.d.ts +3 -0
  70. package/www/example/ctr/test.js +63 -1
  71. package/www/example/mod/test.js +14 -0
  72. package/www/example/mod/testdata.js +9 -0
  73. package/www/example/ws/test.js +1 -0
  74. package/.VSCodeCounter/2025-02-14_14-46-44/details.md +0 -82
  75. package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +0 -15
  76. package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +0 -2
  77. package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +0 -19
  78. package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +0 -22
  79. package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +0 -69
  80. package/.VSCodeCounter/2025-02-14_14-46-44/results.json +0 -1
  81. package/.VSCodeCounter/2025-02-14_14-46-44/results.md +0 -48
  82. package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +0 -118
  83. package/.vscode/tasks.json +0 -15
package/lib/dns.js CHANGED
@@ -1,4 +1,9 @@
1
1
  "use strict";
2
+ /**
3
+ * Project: Kebab, User: JianSuoQiYue
4
+ * Date: 2019-6-19
5
+ * Last: 2022-09-12 20:58:07, 2024-2-21 17:55:54, 2025-6-13 19:08:56
6
+ */
2
7
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
8
  if (k2 === undefined) k2 = k;
4
9
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -35,16 +40,25 @@ var __importStar = (this && this.__importStar) || (function () {
35
40
  Object.defineProperty(exports, "__esModule", { value: true });
36
41
  exports.Dns = exports.ERecordLine = exports.RECORD_TYPE = exports.ESERVICE = void 0;
37
42
  exports.get = get;
43
+ // --- 库和定义 ---
38
44
  const net = __importStar(require("../lib/net"));
39
45
  const core = __importStar(require("../lib/core"));
40
46
  const text = __importStar(require("../lib/text"));
41
47
  const crypto = __importStar(require("../lib/crypto"));
42
48
  const response = __importStar(require("../lib/net/response"));
49
+ /**
50
+ * 0.DNSPod:https://www.dnspod.cn/docs/index.html(腾讯云也请使用 DNSPod 的 API)
51
+ * 1.阿里云:https://help.aliyun.com/document_detail/29745.html
52
+ */
53
+ /** --- 服务商定义 --- */
43
54
  var ESERVICE;
44
55
  (function (ESERVICE) {
45
56
  ESERVICE[ESERVICE["DNSPOD"] = 0] = "DNSPOD";
46
57
  ESERVICE[ESERVICE["ALIBABA"] = 1] = "ALIBABA";
47
58
  })(ESERVICE || (exports.ESERVICE = ESERVICE = {}));
59
+ /**
60
+ * --- 记录值类型 ---
61
+ */
48
62
  exports.RECORD_TYPE = {
49
63
  'A': 'A',
50
64
  'NS': 'NS',
@@ -54,6 +68,9 @@ exports.RECORD_TYPE = {
54
68
  'SRV': 'SRV',
55
69
  'AAAA': 'AAAA'
56
70
  };
71
+ /**
72
+ * --- 记录值线路 ---
73
+ */
57
74
  var ERecordLine;
58
75
  (function (ERecordLine) {
59
76
  ERecordLine[ERecordLine["DEFAULT"] = 0] = "DEFAULT";
@@ -88,6 +105,10 @@ class Dns {
88
105
  opt.secretKey ??= config.dns?.[ESERVICE[opt.service]].skey;
89
106
  this._opt = opt;
90
107
  }
108
+ /**
109
+ * --- 最终发送 ---
110
+ * @param obj 要发送的信息
111
+ */
91
112
  async _send(obj) {
92
113
  for (const key in obj) {
93
114
  if (obj[key] === null || obj[key] === undefined) {
@@ -95,6 +116,7 @@ class Dns {
95
116
  }
96
117
  }
97
118
  switch (this._opt.service) {
119
+ // --- DNSPod ---
98
120
  case ESERVICE.DNSPOD: {
99
121
  const data = Object.assign({
100
122
  'login_token': (this._opt.secretId ?? '') + '.' + (this._opt.secretKey ?? ''),
@@ -102,8 +124,9 @@ class Dns {
102
124
  }, obj);
103
125
  const path = data['_path'];
104
126
  delete data['_path'];
105
- return net.post('https://dnsapi.cn/' + path, data);
127
+ return net.post('https://dnsapi.cn/' + path, data); // 境外 api 会自动调度到香港服务器
106
128
  }
129
+ // --- 阿里云 ---
107
130
  case ESERVICE.ALIBABA: {
108
131
  const getData = core.objectSort(Object.assign({
109
132
  'Format': 'JSON',
@@ -116,13 +139,18 @@ class Dns {
116
139
  }, obj));
117
140
  const urlRight = text.queryStringify(getData);
118
141
  const signature = crypto.hashHmac('sha1', `GET&${encodeURIComponent('/')}&${encodeURIComponent(urlRight)}`, (this._opt.secretKey ?? '') + '&', 'base64');
119
- return net.get(`https://alidns.aliyuncs.com/?${urlRight}&Signature=${encodeURIComponent(signature)}`);
142
+ return net.get(`https://alidns.aliyuncs.com/?${urlRight}&Signature=${encodeURIComponent(signature)}`); // 境外 api 会自动调度到新加坡服务器
120
143
  }
121
144
  }
122
145
  return new response.Response(null);
123
146
  }
147
+ /**
148
+ * --- 获取域名列表 ---
149
+ * @param opt 参数
150
+ */
124
151
  async getDomainList(opt) {
125
152
  switch (this._opt.service) {
153
+ // --- DNSPod ---
126
154
  case ESERVICE.DNSPOD: {
127
155
  const rtn = await this._send({
128
156
  '_path': 'Domain.List',
@@ -148,6 +176,7 @@ class Dns {
148
176
  }
149
177
  return r;
150
178
  }
179
+ // --- 阿里云 ---
151
180
  case ESERVICE.ALIBABA: {
152
181
  const length = opt.length ?? 20;
153
182
  const rtn = await this._send({
@@ -177,10 +206,15 @@ class Dns {
177
206
  }
178
207
  return null;
179
208
  }
209
+ /**
210
+ * --- 添加记录 ---
211
+ * @param opt 参数
212
+ */
180
213
  async addDomainRecord(opt) {
181
214
  const line = opt.line ?? ERecordLine.DEFAULT;
182
215
  const ttl = opt.ttl ?? 600;
183
216
  switch (this._opt.service) {
217
+ // --- DNSPod ---
184
218
  case ESERVICE.DNSPOD: {
185
219
  const rtn = await this._send({
186
220
  '_path': 'Record.Create',
@@ -203,6 +237,7 @@ class Dns {
203
237
  };
204
238
  return r;
205
239
  }
240
+ // --- 阿里云 ---
206
241
  case ESERVICE.ALIBABA: {
207
242
  const rtn = await this._send({
208
243
  'Action': 'AddDomainRecord',
@@ -228,11 +263,17 @@ class Dns {
228
263
  }
229
264
  return null;
230
265
  }
266
+ /**
267
+ * --- 修改记录 ---
268
+ * @param opt 参数
269
+ */
231
270
  async updateDomainRecord(opt) {
232
271
  const line = opt.line ?? ERecordLine.DEFAULT;
233
272
  const ttl = opt.ttl ?? 600;
234
273
  switch (this._opt.service) {
274
+ // --- DNSPod ---
235
275
  case ESERVICE.DNSPOD: {
276
+ // --- DNSPod 必须传 domain ---
236
277
  const rtn = await this._send({
237
278
  '_path': 'Record.Modify',
238
279
  'domain': opt.domain,
@@ -255,6 +296,7 @@ class Dns {
255
296
  };
256
297
  return r;
257
298
  }
299
+ // --- 阿里云 ---
258
300
  case ESERVICE.ALIBABA: {
259
301
  const rtn = await this._send({
260
302
  'Action': 'UpdateDomainRecord',
@@ -280,8 +322,13 @@ class Dns {
280
322
  }
281
323
  return null;
282
324
  }
325
+ /**
326
+ * --- 删除记录 ---
327
+ * @param opt 参数
328
+ */
283
329
  async deleteDomainRecord(opt) {
284
330
  switch (this._opt.service) {
331
+ // --- DNSPod ---
285
332
  case ESERVICE.DNSPOD: {
286
333
  const rtn = await this._send({
287
334
  '_path': 'Record.Remove',
@@ -297,6 +344,7 @@ class Dns {
297
344
  'success': json.status.code === '1' ? true : false
298
345
  };
299
346
  }
347
+ // --- 阿里云 ---
300
348
  case ESERVICE.ALIBABA: {
301
349
  const rtn = await this._send({
302
350
  'Action': 'DeleteDomainRecord',
@@ -316,6 +364,10 @@ class Dns {
316
364
  }
317
365
  }
318
366
  exports.Dns = Dns;
367
+ /**
368
+ * --- 创建一个第三方 Dns 对象 ---
369
+ * @param opt 选项
370
+ */
319
371
  function get(ctr, opt) {
320
372
  return new Dns(ctr, opt);
321
373
  }
package/lib/fs.d.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Project: Kebab, User: JianSuoQiYue
3
+ * Date: 2019-3-29 23:03:07
4
+ * Last: 2020-3-11 22:21:51, 2022-12-29 01:18:25, 2023-12-13 20:50:09
5
+ */
1
6
  import * as fs from 'fs';
2
7
  import * as http from 'http';
3
8
  import * as http2 from 'http2';
@@ -10,25 +15,102 @@ export declare function getContent(path: string, options: BufferEncoding | {
10
15
  'start'?: number;
11
16
  'end'?: number;
12
17
  }): Promise<string | null>;
18
+ /**
19
+ * --- 写入文件内容 ---
20
+ * @param path 文件路径
21
+ * @param data 要写入的内容
22
+ * @param options 选项
23
+ */
13
24
  export declare function putContent(path: string, data: string | Buffer, options?: {
14
25
  'encoding'?: BufferEncoding;
15
26
  'mode'?: number;
16
27
  'flag'?: string;
17
28
  }): Promise<boolean>;
29
+ /**
30
+ * --- 读取链接的 target ---
31
+ * @param path 要读取的路径
32
+ * @param encoding 编码
33
+ */
18
34
  export declare function readLink(path: string, encoding?: BufferEncoding): Promise<string | null>;
35
+ /**
36
+ * --- 把源文件创建一个 link ---
37
+ * @param filePath 源文件
38
+ * @param linkPath 连接路径
39
+ * @param type 仅 Windows,类型,默认 file
40
+ */
19
41
  export declare function symlink(filePath: string, linkPath: string, type?: 'dir' | 'file' | 'junction'): Promise<boolean>;
42
+ /**
43
+ * --- 删除一个文件 ---
44
+ * @param path 要删除的文件路径
45
+ */
20
46
  export declare function unlink(path: string): Promise<boolean>;
47
+ /**
48
+ * --- 获取对象是否存在,存在则返回 stats 对象,否则返回 null ---
49
+ * @param path 对象路径
50
+ */
21
51
  export declare function stats(path: string): Promise<fs.Stats | null>;
52
+ /**
53
+ * --- 判断是否是目录或目录是否存在,是的话返回 stats ---
54
+ * @param path 判断路径
55
+ */
22
56
  export declare function isDir(path: string): Promise<fs.Stats | false>;
57
+ /**
58
+ * --- 判断是否是文件或文件是否存在,是的话返回 stats ---
59
+ * @param path 判断路径
60
+ */
23
61
  export declare function isFile(path: string): Promise<fs.Stats | false>;
62
+ /**
63
+ * --- 深度创建目录,如果最末目录存在,则自动创建成功 ---
64
+ * @param path 要创建的路径,如 /a/b/c/
65
+ * @param mode 权限
66
+ */
24
67
  export declare function mkdir(path: string, mode?: number): Promise<boolean>;
68
+ /**
69
+ * --- 删除空目录 ---
70
+ * @param path 要删除的目录
71
+ */
25
72
  export declare function rmdir(path: string): Promise<boolean>;
73
+ /**
74
+ * --- Danger 危险:危险函数,尽量不要使用 ---
75
+ * --- This f**king is a danger function, please don't use it ---
76
+ * --- 删除一个非空目录 ---
77
+ */
26
78
  export declare function rmdirDeep(path: string): Promise<boolean>;
79
+ /**
80
+ * --- 修改权限
81
+ * @param path 要修改的路径
82
+ * @param mod 权限
83
+ */
27
84
  export declare function chmod(path: string, mod: string | number): Promise<boolean>;
85
+ /**
86
+ * --- 重命名/移动 文件文件夹 ---
87
+ * @param oldPath 老名
88
+ * @param newPath 新名
89
+ */
28
90
  export declare function rename(oldPath: string, newPath: string): Promise<boolean>;
91
+ /**
92
+ * --- 获取文件夹下文件列表 ---
93
+ * @param path 文件夹路径
94
+ */
29
95
  export declare function readDir(path: string, encoding?: BufferEncoding): Promise<fs.Dirent[]>;
96
+ /**
97
+ * --- 复制文件夹里的内容到另一个地方,失败不会回滚 ---
98
+ * @param from 源,末尾加 /
99
+ * @param to 目标,末尾加 /
100
+ * @param ignore 忽略的文件
101
+ */
30
102
  export declare function copyFolder(from: string, to: string, ignore?: RegExp[]): Promise<number>;
103
+ /**
104
+ * --- 复制文件 ---
105
+ * @param src 源文件
106
+ * @param dest 目标文件
107
+ */
31
108
  export declare function copyFile(src: string, dest: string): Promise<boolean>;
109
+ /**
110
+ * --- 创建读取文件的流 ---
111
+ * @param path 文件地址
112
+ * @param options 编码或配置
113
+ */
32
114
  export declare function createReadStream(path: string, options?: BufferEncoding | {
33
115
  'flags'?: string;
34
116
  'encoding'?: BufferEncoding;
@@ -36,9 +118,20 @@ export declare function createReadStream(path: string, options?: BufferEncoding
36
118
  'start'?: number;
37
119
  'end'?: number;
38
120
  }): fs.ReadStream;
121
+ /**
122
+ * --- 读取文件写入到流,并等待写入完成 ---
123
+ * @param path 文件地址
124
+ * @param destination 要写入的流
125
+ * @param options 写入后是否终止写入流,默认终止
126
+ */
39
127
  export declare function pipe(path: string, destination: NodeJS.WritableStream, options?: {
40
128
  'end'?: boolean;
41
129
  }): Promise<boolean>;
130
+ /**
131
+ * --- 创建写入文件的流 ---
132
+ * @param path 文件地址
133
+ * @param options 编码或配置
134
+ */
42
135
  export declare function createWriteStream(path: string, options?: BufferEncoding | {
43
136
  'flags'?: string;
44
137
  'encoding'?: BufferEncoding;
@@ -46,4 +139,11 @@ export declare function createWriteStream(path: string, options?: BufferEncoding
46
139
  'autoClose'?: boolean;
47
140
  'start'?: number;
48
141
  }): fs.WriteStream;
142
+ /**
143
+ * --- 读取文件并输出到 http 的 response ---
144
+ * @param path 文件绝对路径
145
+ * @param req http 请求对象
146
+ * @param res http 响应对象
147
+ * @param stat 文件的 stat(如果有)
148
+ */
49
149
  export declare function readToResponse(path: string, req: http2.Http2ServerRequest | http.IncomingMessage, res: http2.Http2ServerResponse | http.ServerResponse, stat?: fs.Stats | null): Promise<void>;
package/lib/fs.js CHANGED
@@ -53,12 +53,22 @@ exports.createReadStream = createReadStream;
53
53
  exports.pipe = pipe;
54
54
  exports.createWriteStream = createWriteStream;
55
55
  exports.readToResponse = readToResponse;
56
+ /**
57
+ * Project: Kebab, User: JianSuoQiYue
58
+ * Date: 2019-3-29 23:03:07
59
+ * Last: 2020-3-11 22:21:51, 2022-12-29 01:18:25, 2023-12-13 20:50:09
60
+ */
56
61
  const fs = __importStar(require("fs"));
57
62
  const http2 = __importStar(require("http2"));
58
63
  const mime = __importStar(require("@litert/mime"));
59
64
  const text = __importStar(require("./text"));
60
65
  const core = __importStar(require("./core"));
61
66
  const zlib = __importStar(require("./zlib"));
67
+ /**
68
+ * --- 读取完整文件或一段 ---
69
+ * @param path 文件路径
70
+ * @param options 编码或选项
71
+ */
62
72
  async function getContent(path, options) {
63
73
  if (typeof options === 'string') {
64
74
  options = {
@@ -113,6 +123,12 @@ async function getContent(path, options) {
113
123
  }
114
124
  }
115
125
  }
126
+ /**
127
+ * --- 写入文件内容 ---
128
+ * @param path 文件路径
129
+ * @param data 要写入的内容
130
+ * @param options 选项
131
+ */
116
132
  async function putContent(path, data, options = {}) {
117
133
  try {
118
134
  await fs.promises.writeFile(path, data, options);
@@ -122,6 +138,11 @@ async function putContent(path, data, options = {}) {
122
138
  return false;
123
139
  }
124
140
  }
141
+ /**
142
+ * --- 读取链接的 target ---
143
+ * @param path 要读取的路径
144
+ * @param encoding 编码
145
+ */
125
146
  async function readLink(path, encoding) {
126
147
  try {
127
148
  return await fs.promises.readlink(path, {
@@ -132,6 +153,12 @@ async function readLink(path, encoding) {
132
153
  return null;
133
154
  }
134
155
  }
156
+ /**
157
+ * --- 把源文件创建一个 link ---
158
+ * @param filePath 源文件
159
+ * @param linkPath 连接路径
160
+ * @param type 仅 Windows,类型,默认 file
161
+ */
135
162
  async function symlink(filePath, linkPath, type) {
136
163
  try {
137
164
  await fs.promises.symlink(filePath, linkPath, type);
@@ -141,6 +168,10 @@ async function symlink(filePath, linkPath, type) {
141
168
  return false;
142
169
  }
143
170
  }
171
+ /**
172
+ * --- 删除一个文件 ---
173
+ * @param path 要删除的文件路径
174
+ */
144
175
  async function unlink(path) {
145
176
  for (let i = 0; i <= 2; ++i) {
146
177
  try {
@@ -159,6 +190,10 @@ async function unlink(path) {
159
190
  return false;
160
191
  }
161
192
  }
193
+ /**
194
+ * --- 获取对象是否存在,存在则返回 stats 对象,否则返回 null ---
195
+ * @param path 对象路径
196
+ */
162
197
  async function stats(path) {
163
198
  try {
164
199
  return await fs.promises.lstat(path);
@@ -167,6 +202,10 @@ async function stats(path) {
167
202
  return null;
168
203
  }
169
204
  }
205
+ /**
206
+ * --- 判断是否是目录或目录是否存在,是的话返回 stats ---
207
+ * @param path 判断路径
208
+ */
170
209
  async function isDir(path) {
171
210
  const pstats = await stats(path);
172
211
  if (!pstats?.isDirectory()) {
@@ -174,6 +213,10 @@ async function isDir(path) {
174
213
  }
175
214
  return pstats;
176
215
  }
216
+ /**
217
+ * --- 判断是否是文件或文件是否存在,是的话返回 stats ---
218
+ * @param path 判断路径
219
+ */
177
220
  async function isFile(path) {
178
221
  const pstats = await stats(path);
179
222
  if (!pstats?.isFile()) {
@@ -181,10 +224,16 @@ async function isFile(path) {
181
224
  }
182
225
  return pstats;
183
226
  }
227
+ /**
228
+ * --- 深度创建目录,如果最末目录存在,则自动创建成功 ---
229
+ * @param path 要创建的路径,如 /a/b/c/
230
+ * @param mode 权限
231
+ */
184
232
  async function mkdir(path, mode = 0o755) {
185
233
  if (await isDir(path)) {
186
234
  return true;
187
235
  }
236
+ // --- 深度创建目录 ---
188
237
  try {
189
238
  await fs.promises.mkdir(path, {
190
239
  'recursive': true,
@@ -196,6 +245,10 @@ async function mkdir(path, mode = 0o755) {
196
245
  return false;
197
246
  }
198
247
  }
248
+ /**
249
+ * --- 删除空目录 ---
250
+ * @param path 要删除的目录
251
+ */
199
252
  async function rmdir(path) {
200
253
  if (!(await isDir(path))) {
201
254
  return true;
@@ -208,6 +261,11 @@ async function rmdir(path) {
208
261
  return false;
209
262
  }
210
263
  }
264
+ /**
265
+ * --- Danger 危险:危险函数,尽量不要使用 ---
266
+ * --- This f**king is a danger function, please don't use it ---
267
+ * --- 删除一个非空目录 ---
268
+ */
211
269
  async function rmdirDeep(path) {
212
270
  if (!path.endsWith('/')) {
213
271
  path += '/';
@@ -219,6 +277,7 @@ async function rmdirDeep(path) {
219
277
  return false;
220
278
  }
221
279
  if (stat.isDirectory()) {
280
+ // --- 目录 ---
222
281
  const rtn = await rmdirDeep(path + item.name);
223
282
  if (!rtn) {
224
283
  return false;
@@ -233,6 +292,11 @@ async function rmdirDeep(path) {
233
292
  }
234
293
  return rmdir(path);
235
294
  }
295
+ /**
296
+ * --- 修改权限
297
+ * @param path 要修改的路径
298
+ * @param mod 权限
299
+ */
236
300
  async function chmod(path, mod) {
237
301
  try {
238
302
  await fs.promises.chmod(path, mod);
@@ -242,6 +306,11 @@ async function chmod(path, mod) {
242
306
  return false;
243
307
  }
244
308
  }
309
+ /**
310
+ * --- 重命名/移动 文件文件夹 ---
311
+ * @param oldPath 老名
312
+ * @param newPath 新名
313
+ */
245
314
  async function rename(oldPath, newPath) {
246
315
  try {
247
316
  await fs.promises.rename(oldPath, newPath);
@@ -251,6 +320,10 @@ async function rename(oldPath, newPath) {
251
320
  return false;
252
321
  }
253
322
  }
323
+ /**
324
+ * --- 获取文件夹下文件列表 ---
325
+ * @param path 文件夹路径
326
+ */
254
327
  async function readDir(path, encoding) {
255
328
  try {
256
329
  const list = [];
@@ -270,12 +343,21 @@ async function readDir(path, encoding) {
270
343
  return [];
271
344
  }
272
345
  }
346
+ /**
347
+ * --- 复制文件夹里的内容到另一个地方,失败不会回滚 ---
348
+ * @param from 源,末尾加 /
349
+ * @param to 目标,末尾加 /
350
+ * @param ignore 忽略的文件
351
+ */
273
352
  async function copyFolder(from, to, ignore = []) {
274
353
  let num = 0;
354
+ // --- 如果源目录不存在或不是目录,则直接成功 :) ---
275
355
  if (!await isDir(from)) {
276
356
  return 0;
277
357
  }
358
+ // --- 遍历源目录文件和文件夹,准备复制 ---
278
359
  const flist = await readDir(from);
360
+ /** --- to 目录是否检查是否存在,空目录不复制,所以确定有 item file 的时候才创建 --- */
279
361
  let checkTo = false;
280
362
  for (const item of flist) {
281
363
  if (item.isDirectory()) {
@@ -288,6 +370,7 @@ async function copyFolder(from, to, ignore = []) {
288
370
  }
289
371
  }
290
372
  else if (item.isFile()) {
373
+ // --- 先判断本文件是否被排除 ---
291
374
  if (ignore.length > 0 && text.match(item.name, ignore)) {
292
375
  continue;
293
376
  }
@@ -305,6 +388,11 @@ async function copyFolder(from, to, ignore = []) {
305
388
  }
306
389
  return num;
307
390
  }
391
+ /**
392
+ * --- 复制文件 ---
393
+ * @param src 源文件
394
+ * @param dest 目标文件
395
+ */
308
396
  async function copyFile(src, dest) {
309
397
  try {
310
398
  await fs.promises.copyFile(src, dest);
@@ -314,6 +402,11 @@ async function copyFile(src, dest) {
314
402
  return false;
315
403
  }
316
404
  }
405
+ /**
406
+ * --- 创建读取文件的流 ---
407
+ * @param path 文件地址
408
+ * @param options 编码或配置
409
+ */
317
410
  function createReadStream(path, options) {
318
411
  if (typeof options === 'string') {
319
412
  options = {
@@ -331,6 +424,12 @@ function createReadStream(path, options) {
331
424
  'end': options.end
332
425
  });
333
426
  }
427
+ /**
428
+ * --- 读取文件写入到流,并等待写入完成 ---
429
+ * @param path 文件地址
430
+ * @param destination 要写入的流
431
+ * @param options 写入后是否终止写入流,默认终止
432
+ */
334
433
  function pipe(path, destination, options) {
335
434
  return new Promise((resolve) => {
336
435
  createReadStream(path).on('error', function () {
@@ -340,6 +439,11 @@ function pipe(path, destination, options) {
340
439
  }).pipe(destination, options);
341
440
  });
342
441
  }
442
+ /**
443
+ * --- 创建写入文件的流 ---
444
+ * @param path 文件地址
445
+ * @param options 编码或配置
446
+ */
343
447
  function createWriteStream(path, options) {
344
448
  if (typeof options === 'string') {
345
449
  options = {
@@ -357,6 +461,13 @@ function createWriteStream(path, options) {
357
461
  'start': options.start
358
462
  });
359
463
  }
464
+ /**
465
+ * --- 读取文件并输出到 http 的 response ---
466
+ * @param path 文件绝对路径
467
+ * @param req http 请求对象
468
+ * @param res http 响应对象
469
+ * @param stat 文件的 stat(如果有)
470
+ */
360
471
  async function readToResponse(path, req, res, stat) {
361
472
  if (!stat) {
362
473
  stat = await stats(path);
@@ -367,14 +478,17 @@ async function readToResponse(path, req, res, stat) {
367
478
  res.end('<h1>404 Not found</h1><hr>Kebab');
368
479
  return;
369
480
  }
481
+ // --- 判断缓存以及 MIME 和编码 ---
370
482
  let charset = '';
371
483
  const mimeData = mime.getData(path);
372
484
  if (['htm', 'html', 'css', 'js', 'xml', 'jpg', 'jpeg', 'svg', 'gif', 'png'].includes(mimeData.extension)) {
373
485
  charset = '; charset=utf-8';
486
+ // --- 这些文件可能需要缓存 ---
374
487
  const hash = `W/"${stat.size.toString(16)}-${stat.mtime.getTime().toString(16)}"`;
375
488
  const lastModified = stat.mtime.toUTCString();
376
489
  res.setHeader('etag', hash);
377
490
  res.setHeader('cache-control', 'public, max-age=600');
491
+ // --- 判断返回 304 吗 ---
378
492
  const noneMatch = req.headers['if-none-match'];
379
493
  const modifiedSince = req.headers['if-modified-since'];
380
494
  if ((hash === noneMatch) && (lastModified === modifiedSince)) {
@@ -387,9 +501,12 @@ async function readToResponse(path, req, res, stat) {
387
501
  else {
388
502
  res.setHeader('cache-control', 'no-cache, must-revalidate');
389
503
  }
504
+ // --- 设置 type ---
390
505
  res.setHeader('content-type', mimeData.mime + charset);
506
+ // --- 判断客户端支持的压缩模式 ---
391
507
  const encoding = req.headers['accept-encoding'] ?? '';
392
508
  if (mimeData.compressible && (stat.size >= 1024)) {
509
+ // --- 压缩 ---
393
510
  const compress = await zlib.compress(encoding, await getContent(path));
394
511
  if (compress) {
395
512
  res.setHeader('content-encoding', compress.type);
@@ -399,6 +516,7 @@ async function readToResponse(path, req, res, stat) {
399
516
  return;
400
517
  }
401
518
  }
519
+ // --- 不压缩 ---
402
520
  res.setHeader('content-length', stat.size);
403
521
  res.writeHead(200);
404
522
  await pipe(path, res instanceof http2.Http2ServerResponse ? (res.stream ?? res) : res);
package/lib/jwt.d.ts CHANGED
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Project: Kebab, User: JianSuoQiYue
3
+ * Date: 2023-1-31 20:34:47
4
+ * Last: 2023-1-31 20:34:47, 2023-12-8 13:55:09
5
+ */
1
6
  import * as kv from '../lib/kv';
2
7
  import * as ctr from '../sys/ctr';
3
8
  import * as types from '../types';
@@ -9,22 +14,60 @@ export interface IOptions {
9
14
  'auth'?: boolean;
10
15
  }
11
16
  export declare class Jwt {
17
+ /** --- Kv --- */
12
18
  private _link?;
19
+ /** --- 在前端或 Kv 中储存的名前缀 --- */
13
20
  private _name;
21
+ /** --- 有效期 --- */
14
22
  private _ttl;
23
+ /** --- cookie 模式时是否仅支持 SSL --- */
15
24
  private _ssl;
25
+ /** --- 验证密钥 --- */
16
26
  private _secret;
27
+ /** --- 是否从头部读取 --- */
17
28
  private _auth;
29
+ /** --- ctr 对象 --- */
18
30
  private _ctr;
31
+ /**
32
+ * --- 初始化函数,相当于 construct ---
33
+ * @param ctr 模型实例
34
+ * @param link Kv 或 Db 实例
35
+ * @param auth 设为 true 则优先从头 Authorization 或 post _auth 值读取 token
36
+ * @param opt 选项
37
+ */
19
38
  init(ctr: ctr.Ctr, opt?: IOptions, link?: kv.Pool): Promise<boolean>;
39
+ /**
40
+ * --- 将 _jwt 数据封装并返回(创建新的或者续期老的 token),默认会同时设置一个 cookie(data 值会自动设置 token、exp) ---
41
+ */
20
42
  renew(): string;
43
+ /**
44
+ * --- 清除 cookie,仅仅清除 cookie,jwt 并不会失效 ---
45
+ */
21
46
  clearCookie(): void;
47
+ /**
48
+ * --- 销毁 jwt,其实就是将 token block 信息写入 redis,如果没有 redis 则不能销毁,返回数组代表销毁成功的 token 和原 exp,否则失败返回 false ---
49
+ */
22
50
  destory(): Promise<{
23
51
  token: string;
24
52
  exp: number;
25
53
  } | boolean>;
26
54
  }
55
+ /**
56
+ * --- 获取 jwt 原始字符串,不保证有效 ---
57
+ */
27
58
  export declare function getOrigin(ctr: ctr.Ctr, name?: string, auth?: boolean): string;
59
+ /**
60
+ * --- decode ---
61
+ * 不传入 link 的话,将不做 block 有效校验,只做本身的 exp 有效校验
62
+ */
28
63
  export declare function decode(ctr: ctr.Ctr, val: string, link?: kv.Pool, name?: string, secret?: string): Promise<Record<string, types.DbValue> | false>;
64
+ /**
65
+ * --- 仅往 redis 写禁止相关 token 的数据,一般用于异步通知时在异处的服务器来调用的 ---
66
+ */
29
67
  export declare function block(ctr: ctr.Ctr, token: string, exp: number, link: kv.Pool, name?: string): Promise<boolean>;
68
+ /**
69
+ * @param ctr 模型实例
70
+ * @param opt name, ttl, ssl, secret, auth: false, true 则优先从头 Authorization 或 post _auth 值读取 token
71
+ * @param link 实例
72
+ */
30
73
  export declare function get(ctr: ctr.Ctr, opt?: IOptions, link?: kv.Pool): Promise<Jwt>;