@maiyunnet/kebab 2.0.7 → 2.0.8

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 +6 -1
  58. package/main.js +11 -1
  59. package/package.json +1 -1
  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/sys/master.js CHANGED
@@ -33,9 +33,15 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ /**
37
+ * Project: Kebab, User: JianSuoQiYue
38
+ * Date: 2019-5-2 21:03:42
39
+ * Last: 2020-3-7 10:33:17, 2022-07-22 13:40:10, 2022-09-06 22:40:58, 2024-2-7 01:44:59, 2024-7-2 15:17:09, 2025-6-13 13:06:43
40
+ */
36
41
  const os = __importStar(require("os"));
37
42
  const cluster = __importStar(require("cluster"));
38
43
  const http = __importStar(require("http"));
44
+ // --- 库和定义 ---
39
45
  const kebab = __importStar(require("../index"));
40
46
  const sRoute = __importStar(require("../sys/route"));
41
47
  const lCore = __importStar(require("../lib/core"));
@@ -44,22 +50,31 @@ const lText = __importStar(require("../lib/text"));
44
50
  const lCrypto = __importStar(require("../lib/crypto"));
45
51
  const lTime = __importStar(require("../lib/time"));
46
52
  const lZip = __importStar(require("../lib/zip"));
53
+ /** --- 当前运行中的子进程列表 --- */
47
54
  const workerList = {};
55
+ /**
56
+ * --- 最终调用执行的函数块 ---
57
+ */
48
58
  async function run() {
59
+ // --- 读取配置文件 ---
49
60
  const configContent = await lFs.getContent(kebab.CONF_CWD + 'config.json', 'utf8');
50
61
  if (!configContent) {
51
62
  throw `File '${kebab.CONF_CWD}config.json' not found.`;
52
63
  }
64
+ /** --- 系统 config.json --- */
53
65
  const config = lText.parseJson(configContent);
54
66
  for (const key in config) {
55
67
  lCore.globalConfig[key] = config[key];
56
68
  }
69
+ // --- 监听 RPC 命令 ---
57
70
  createRpcListener();
71
+ // --- 30 秒检测一次是否有丢失的子进程 ---
58
72
  setInterval(function () {
59
73
  checkWorkerLost().catch(function (e) {
60
74
  lCore.display('[master] [run] [checkWorkerLost]', e);
61
75
  });
62
76
  }, 30000);
77
+ // --- 启动进程 ---
63
78
  const cpuLength = os.cpus().length;
64
79
  lCore.display('[master] [run] CPU LENGTH: ' + cpuLength.toString());
65
80
  const cpuLengthMax = cpuLength > lCore.globalConfig.max ? lCore.globalConfig.max : cpuLength;
@@ -67,16 +82,20 @@ async function run() {
67
82
  await createChildProcess(i);
68
83
  }
69
84
  cluster.default.on('listening', function (worker, address) {
85
+ // --- 子进程开始监听 ---
70
86
  lCore.display(`[master] Listening: worker ${worker.process.pid ?? 'undefined'}, Address: ${address.address}:${address.port}.`);
71
87
  }).on('exit', function (worker, code) {
72
88
  (async function () {
73
89
  if (!worker.process.pid) {
74
90
  return;
75
91
  }
92
+ // --- 有子线程退出 ---
76
93
  if (code === 0) {
94
+ // --- 正常关闭,证明关闭前主进程已经重启新进程了,这里无需在 fork ---
77
95
  lCore.display(`[master] Worker ${worker.process.pid} has been disconnected.`);
78
96
  }
79
97
  else {
98
+ // --- 中断,致命错误,需要重新启动一个新线程 ---
80
99
  lCore.display(`[master] Worker ${worker.process.pid} has collapsed.`);
81
100
  const cpu = workerList[worker.process.pid].cpu;
82
101
  delete workerList[worker.process.pid];
@@ -87,10 +106,15 @@ async function run() {
87
106
  });
88
107
  });
89
108
  }
109
+ /**
110
+ * --- 创建 RPC 监听,用来监听 cmd 或局域网传递过来的数据,并广播给所有子进程,cmd 部分代码在 cmd 中实现 ---
111
+ */
90
112
  function createRpcListener() {
91
113
  http.createServer(function (req, res) {
92
114
  (async function () {
115
+ /** --- 当前时间戳 --- */
93
116
  const time = lTime.stamp();
117
+ /** --- cmd 数据对象 --- */
94
118
  const cmd = lCrypto.aesDecrypt((req.url ?? '').slice(1), lCore.globalConfig.rpcSecret);
95
119
  if (!cmd) {
96
120
  res.end('Error');
@@ -111,6 +135,7 @@ function createRpcListener() {
111
135
  }
112
136
  switch (msg.action) {
113
137
  case 'reload': {
138
+ // --- 为所有子线程发送 reload 信息 ---
114
139
  for (const pid in workerList) {
115
140
  workerList[pid].worker.send({
116
141
  'action': 'reload'
@@ -119,16 +144,20 @@ function createRpcListener() {
119
144
  break;
120
145
  }
121
146
  case 'restart': {
147
+ // --- 为所有子线程发送 stop 信息 ---
122
148
  for (const pid in workerList) {
123
149
  workerList[pid].worker.send({
124
150
  'action': 'stop'
125
151
  });
152
+ // --- 开启新线程 ---
126
153
  await createChildProcess(workerList[pid].cpu);
154
+ // --- 删除记录 ---
127
155
  delete workerList[pid];
128
156
  }
129
157
  break;
130
158
  }
131
159
  case 'global': {
160
+ // --- 为所有子进程更新 global 变量 ---
132
161
  for (const pid in workerList) {
133
162
  workerList[pid].worker.send({
134
163
  'action': 'global',
@@ -136,6 +165,7 @@ function createRpcListener() {
136
165
  'data': msg.data
137
166
  });
138
167
  }
168
+ // --- 更新 master 的数据 ---
139
169
  if (msg.data === undefined || msg.data === null) {
140
170
  delete lCore.global[msg.key];
141
171
  break;
@@ -144,6 +174,7 @@ function createRpcListener() {
144
174
  break;
145
175
  }
146
176
  case 'code': {
177
+ // --- 更新 code 代码包 ---
147
178
  const rtn = await sRoute.getFormData(req);
148
179
  if (!rtn) {
149
180
  res.end('Abnormal');
@@ -162,6 +193,7 @@ function createRpcListener() {
162
193
  if (path.endsWith('/')) {
163
194
  path = path.slice(0, -1);
164
195
  }
196
+ /** --- 最终更新的根目录,以 / 结尾,但用户传入的无所谓 --- */
165
197
  let to = kebab.ROOT_CWD + path;
166
198
  if (!to.endsWith('/')) {
167
199
  to += '/';
@@ -185,22 +217,31 @@ function createRpcListener() {
185
217
  }
186
218
  const ls = await zip.getList();
187
219
  for (const path in ls) {
220
+ /** --- 带 / 开头的 zip 中文件完整路径 --- */
188
221
  const fpath = path.startsWith('/') ? path : '/' + path;
222
+ /** --- 最后一个 / 的所在位置 --- */
189
223
  const lio = fpath.lastIndexOf('/');
224
+ /** --- 纯路径,不以 / 开头,以 / 结尾,若是根路径就是空字符串 --- */
190
225
  const pat = fpath.slice(1, lio + 1);
226
+ /** --- 纯文件名 --- */
191
227
  const fname = fpath.slice(lio + 1);
192
228
  if ((pat === 'conf/' && fname === 'config.json') || fname === 'kebab.json') {
229
+ // --- 特殊文件不能覆盖 ---
193
230
  continue;
194
231
  }
195
232
  if (fname.endsWith('.js.map') || fname.endsWith('.ts') || fname.endsWith('.gitignore')) {
233
+ // --- 测试或开发文件不覆盖 ---
196
234
  continue;
197
235
  }
236
+ // --- 看文件夹是否存在 ---
198
237
  if (pat && !await lFs.isDir(to + pat)) {
199
238
  await lFs.mkdir(to + pat);
200
239
  }
240
+ // --- 覆盖或创建文件 ---
201
241
  await lFs.putContent(to + pat + fname, ls[path]);
202
242
  }
203
243
  await sRoute.unlinkUploadFiles(rtn.files);
244
+ // --- 检查是否更新 config ---
204
245
  if (rtn.post['config'] === '1') {
205
246
  const configContent = await lFs.getContent(kebab.CONF_CWD + 'config.json', 'utf8');
206
247
  if (configContent) {
@@ -222,12 +263,18 @@ function createRpcListener() {
222
263
  });
223
264
  }).listen(lCore.globalConfig.rpcPort);
224
265
  }
266
+ /**
267
+ * --- 检测是否有死掉丢失的子进程,复活之 ---
268
+ */
225
269
  async function checkWorkerLost() {
226
270
  const now = Date.now();
227
271
  for (const pid in workerList) {
228
272
  if (now - workerList[pid].hbtime < 30000) {
273
+ // --- 距离上次心跳,小于 30 秒,正常 ---
274
+ // --- 子线程 10 秒发送一次心跳 ---
229
275
  continue;
230
276
  }
277
+ // --- 异常,也可能主线程因为各种原因休眠,不过无论如何都要将原线程关闭,要不然原线程又发心跳包,就捕获不到了 ---
231
278
  lCore.display(`[master] Worker ${pid} lost.`);
232
279
  workerList[pid].worker.send({
233
280
  'action': 'stop'
@@ -236,6 +283,10 @@ async function checkWorkerLost() {
236
283
  delete workerList[pid];
237
284
  }
238
285
  }
286
+ /**
287
+ * --- 创建一个新的子进程 ---
288
+ * @param cpu CPU ID
289
+ */
239
290
  async function createChildProcess(cpu) {
240
291
  const worker = cluster.default.fork();
241
292
  if (!worker.process.pid) {
@@ -246,15 +297,19 @@ async function createChildProcess(cpu) {
246
297
  'cpu': cpu,
247
298
  'hbtime': Date.now()
248
299
  };
300
+ // --- 如果是支持将线程放到对应的 CPU,则执行相关操作 ---
249
301
  if (!os.type().toLowerCase().includes('windows')) {
302
+ // --- 非 Windows ---
250
303
  const cpr = await lCore.exec(`taskset -cp ${cpu} ${worker.process.pid}`);
251
304
  lCore.display(cpr);
252
305
  lCore.display(`[master] Worker ${worker.process.pid} start on cpu #${cpu}.`);
253
306
  }
307
+ // --- 监听子进程发来的讯息,并扩散给所有子进程 ---
254
308
  worker.on('message', function (msg) {
255
309
  (async function () {
256
310
  switch (msg.action) {
257
311
  case 'reload': {
312
+ // --- 为所有子线程发送 reload 信息 ---
258
313
  for (const pid in workerList) {
259
314
  workerList[pid].worker.send({
260
315
  'action': msg.action
@@ -263,16 +318,20 @@ async function createChildProcess(cpu) {
263
318
  break;
264
319
  }
265
320
  case 'restart': {
321
+ // --- 为所有子进程发送 restart 信息 ---
266
322
  for (const pid in workerList) {
267
323
  workerList[pid].worker.send({
268
324
  'action': 'stop'
269
325
  });
326
+ // --- 开启新线程 ---
270
327
  await createChildProcess(workerList[pid].cpu);
328
+ // --- 删除记录 ---
271
329
  delete workerList[pid];
272
330
  }
273
331
  break;
274
332
  }
275
333
  case 'global': {
334
+ // --- 为所有子进程更新 global 变量 ---
276
335
  for (const pid in workerList) {
277
336
  workerList[pid].worker.send({
278
337
  'action': 'global',
@@ -280,6 +339,7 @@ async function createChildProcess(cpu) {
280
339
  'data': msg.data
281
340
  });
282
341
  }
342
+ // --- 更新 master 的数据 ---
283
343
  if (msg.data === undefined || msg.data === null) {
284
344
  delete lCore.global[msg.key];
285
345
  break;
@@ -288,7 +348,9 @@ async function createChildProcess(cpu) {
288
348
  break;
289
349
  }
290
350
  case 'hbtime': {
351
+ // --- 获得子进程发来的 10 秒一次的心跳 ---
291
352
  if (!workerList[msg.pid]) {
353
+ // --- 线程存在,主进程记录里没找到 ---
292
354
  lCore.display(`[master] Worker ${msg.pid} not found.`);
293
355
  break;
294
356
  }
@@ -300,6 +362,7 @@ async function createChildProcess(cpu) {
300
362
  lCore.display('[createChildProcess] [message]', e);
301
363
  });
302
364
  });
365
+ // --- 将主线程的全局变量传给这个新建的子线程 ---
303
366
  if (Object.keys(lCore.global).length) {
304
367
  worker.send({
305
368
  'action': 'global',
package/sys/mod.d.ts CHANGED
@@ -1,33 +1,64 @@
1
+ /**
2
+ * Project: Mutton, User: JianSuoQiYue
3
+ * Date: 2019-6-4 21:35
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
+ */
1
6
  import * as lSql from '../lib/sql';
2
7
  import * as lDb from '../lib/db';
3
8
  import * as sCtr from '../sys/ctr';
4
9
  import * as types from '../types';
10
+ /** --- 条数列表 --- */
5
11
  declare class Rows<T extends Mod> implements types.Rows<T> {
6
12
  private readonly _items;
7
13
  constructor(initialItems?: T[]);
14
+ /** --- 总行数 --- */
8
15
  get length(): number;
16
+ /** --- 通过索引获取一个对象 --- */
9
17
  item(index: number): T;
18
+ /** --- 转换为数组对象 --- */
10
19
  toArray(): Array<Record<string, any>>;
20
+ /** --- 根据规则筛掉项,predicate 返回 true 代表保留 --- */
11
21
  filter(predicate: (value: T, index: number) => boolean): Rows<T>;
22
+ /** --- 重塑对象内容 --- */
12
23
  map<TU>(allbackfn: (value: T, index: number) => TU): TU[];
13
24
  [Symbol.iterator](): Iterator<T>;
14
25
  }
26
+ /**
27
+ * --- 开启软更需要在表添加字段:ALTER TABLE `table_name` ADD `time_remove` bigint NOT NULL DEFAULT '0' AFTER `xxx`; ---
28
+ */
15
29
  export default class Mod {
30
+ /** --- 表名 --- */
16
31
  protected static _$table: string;
32
+ /** --- 主键字段名 --- */
17
33
  protected static _$primary: string;
34
+ /** --- 设置后将由 _keyGenerator 函数生成唯一字段 --- */
18
35
  protected static _$key: string;
36
+ /** ---- 可开启软删软更新软新增 --- */
19
37
  protected static _$soft: boolean;
38
+ /** --- 要 update 的内容 --- */
20
39
  protected _updates: Record<string, boolean>;
40
+ /** --- 模型获取的属性 --- */
21
41
  protected _data: Record<string, any>;
42
+ /** --- 当前选择的分表 _ 后缀,多个代表联查 --- */
22
43
  protected _index: string[] | null;
44
+ /** --- 必须追加的数据筛选 key 与 values,仅单表模式有效 --- */
23
45
  protected _contain: {
24
46
  'key': string;
25
47
  'list': string[];
26
48
  } | null;
49
+ /** --- 已算出的 total --- */
27
50
  protected _total: number[];
51
+ /** --- 数据库连接对象 --- */
28
52
  protected _db: lDb.Pool | lDb.Transaction;
53
+ /** --- Sql 对象 --- */
29
54
  protected _sql: lSql.Sql;
55
+ /** --- ctr 对象, Mutton: false, Kebab: true --- */
30
56
  protected _ctr?: sCtr.Ctr;
57
+ /**
58
+ * --- 构造函数 ---
59
+ * @param ctr Ctr 对象
60
+ * @param opt 选项
61
+ */
31
62
  constructor(opt: {
32
63
  'db': lDb.Pool | lDb.Transaction;
33
64
  'ctr'?: sCtr.Ctr;
@@ -43,23 +74,50 @@ export default class Mod {
43
74
  'raw'?: boolean;
44
75
  'pre'?: string;
45
76
  });
77
+ /** --- 创建字段对象 --- */
46
78
  static column(field: string): {
47
79
  'type': 'column';
48
80
  'token': string;
49
81
  'value': string;
50
82
  };
83
+ /**
84
+ * --- 添加一个序列 ---
85
+ * @param db 数据库对象
86
+ * @param cs 字段列表
87
+ * @param vs 数据列表
88
+ * @param opt 选项
89
+ */
51
90
  static insert(db: lDb.Pool | lDb.Transaction, cs: string[] | Record<string, any>, vs?: any[] | any[][], opt?: {
52
91
  'pre'?: sCtr.Ctr | string;
53
92
  'index'?: string;
54
93
  }): Promise<boolean | null | false>;
94
+ /**
95
+ * --- 获取添加一个序列的模拟 SQL ---
96
+ * @param cs 字段列表
97
+ * @param vs 数据列表
98
+ * @param opt 选项
99
+ */
55
100
  static insertSql(cs: string[] | Record<string, any>, vs?: any[] | any[][], opt?: {
56
101
  'pre'?: sCtr.Ctr | string;
57
102
  'index'?: string;
58
103
  }): string;
104
+ /**
105
+ * --- 插入数据如果唯一键冲突则更新 ---
106
+ * @param db 数据库对象
107
+ * @param data 要插入的数据
108
+ * @param update 要更新的数据
109
+ * @param opt 选项
110
+ */
59
111
  static insertDuplicate(db: lDb.Pool | lDb.Transaction, data: Record<string, any>, update: types.Json, opt?: {
60
112
  'pre'?: sCtr.Ctr | string;
61
113
  'index'?: string;
62
114
  }): Promise<boolean | null>;
115
+ /**
116
+ * --- 根据条件移除条目 ---
117
+ * @param db 数据库对象
118
+ * @param where 筛选条件
119
+ * @param opt 选项
120
+ */
63
121
  static removeByWhere(db: lDb.Pool | lDb.Transaction, where: string | types.Json, opt?: {
64
122
  'raw'?: boolean;
65
123
  'pre'?: sCtr.Ctr | string;
@@ -67,6 +125,12 @@ export default class Mod {
67
125
  'by'?: [string | string[], 'DESC' | 'ASC'];
68
126
  'limit'?: [number, number?];
69
127
  }): Promise<number | false | null>;
128
+ /**
129
+ * --- 根据条件移除条目(仅获取 SQL 对象) ---
130
+ * @param db 数据库对象
131
+ * @param where 筛选条件
132
+ * @param opt 选项
133
+ */
70
134
  static removeByWhereSql(db: lDb.Pool | lDb.Transaction, where: string | types.Json, opt?: {
71
135
  'raw'?: boolean;
72
136
  'pre'?: sCtr.Ctr | string;
@@ -74,6 +138,13 @@ export default class Mod {
74
138
  'by'?: [string | string[], 'DESC' | 'ASC'];
75
139
  'limit'?: [number, number?];
76
140
  }): lSql.Sql;
141
+ /**
142
+ * --- 根据条件更新数据 ---
143
+ * @param db 数据库对象
144
+ * @param data 要更新的数据
145
+ * @param where 筛选条件
146
+ * @param opt 选项
147
+ */
77
148
  static updateByWhere(db: lDb.Pool | lDb.Transaction, data: types.Json, where: string | types.Json, opt?: {
78
149
  'raw'?: boolean;
79
150
  'pre'?: sCtr.Ctr | string;
@@ -81,6 +152,12 @@ export default class Mod {
81
152
  'by'?: [string | string[], 'DESC' | 'ASC'];
82
153
  'limit'?: [number, number?];
83
154
  }): Promise<number | false | null>;
155
+ /**
156
+ * --- 根据条件更新数据(仅获取 SQL 对象) ---
157
+ * @param data 要更新的数据
158
+ * @param where 筛选条件
159
+ * @param opt 选项
160
+ */
84
161
  static updateByWhereSql(data: types.Json, where: string | types.Json, opt?: {
85
162
  'raw'?: boolean;
86
163
  'pre'?: sCtr.Ctr | string;
@@ -88,6 +165,12 @@ export default class Mod {
88
165
  'by'?: [string | string[], 'DESC' | 'ASC'];
89
166
  'limit'?: [number, number?];
90
167
  }): lSql.Sql;
168
+ /**
169
+ * --- select 自定字段 ---
170
+ * @param db 数据库对象
171
+ * @param c 字段字符串或字段数组
172
+ * @param opt 选项
173
+ */
91
174
  static select<T extends Mod>(db: lDb.Pool | lDb.Transaction, c: string | string[], opt?: {
92
175
  'ctr'?: sCtr.Ctr;
93
176
  'pre'?: string;
@@ -98,6 +181,12 @@ export default class Mod {
98
181
  'list': string[];
99
182
  };
100
183
  }): T & Record<string, any>;
184
+ /**
185
+ * --- 通过 where 条件获取模型 ---
186
+ * @param db 数据库对象
187
+ * @param s 筛选条件数组或字符串
188
+ * @param opt 选项
189
+ */
101
190
  static where<T extends Mod>(db: lDb.Pool | lDb.Transaction, s?: string | types.Json, opt?: {
102
191
  'ctr'?: sCtr.Ctr;
103
192
  'raw'?: boolean;
@@ -108,11 +197,23 @@ export default class Mod {
108
197
  'list': string[];
109
198
  };
110
199
  }): T & Record<string, any>;
200
+ /**
201
+ * --- 获取创建对象,通常用于新建数据库条目 ---
202
+ * @param db 数据库对象
203
+ * @param opt 选项
204
+ */
111
205
  static getCreate<T extends Mod>(db: lDb.Pool | lDb.Transaction, opt?: {
112
206
  'ctr'?: sCtr.Ctr;
113
207
  'pre'?: string;
114
208
  'index'?: string;
115
209
  }): T;
210
+ /**
211
+ * --- 根据主键获取对象 ---
212
+ * @param db 数据库对象
213
+ * @param val 主键值
214
+ * @param lock 是否加锁
215
+ * @param opt 选项
216
+ */
116
217
  static find<T extends Mod>(db: lDb.Pool | lDb.Transaction, val: string | number | null, opt?: {
117
218
  'ctr'?: sCtr.Ctr;
118
219
  'lock'?: boolean;
@@ -138,6 +239,12 @@ export default class Mod {
138
239
  'by'?: [string | string[], 'DESC' | 'ASC'];
139
240
  'array'?: false;
140
241
  }): Promise<false | null | (T & Record<string, any>)>;
242
+ /**
243
+ * --- 通过 where 条件筛选单条数据返回原生对象 ---
244
+ * @param db 数据库对象
245
+ * @param s 筛选条件数组或字符串
246
+ * @param opt 选项
247
+ */
141
248
  static oneArray(db: lDb.Pool | lDb.Transaction, s: string | types.Json, opt?: {
142
249
  'ctr'?: sCtr.Ctr;
143
250
  'raw'?: boolean;
@@ -145,25 +252,71 @@ export default class Mod {
145
252
  'index'?: string | string[];
146
253
  'select'?: string | string[];
147
254
  }): Promise<false | null | Record<string, any>>;
255
+ /**
256
+ * --- 根据 where 条件获取主键值列表 ---
257
+ * @param db 数据库对象
258
+ * @param where where 条件
259
+ * @param opt 选项
260
+ */
148
261
  static primarys(db: lDb.Pool | lDb.Transaction, where?: string | types.Json, opt?: {
149
262
  'ctr'?: sCtr.Ctr;
150
263
  'raw'?: boolean;
151
264
  'pre'?: string;
152
265
  'index'?: string;
153
266
  }): Promise<any[] | false>;
267
+ /**
268
+ * --- 将 key val 组成的数据列表转换为原生对象模式 ---
269
+ * @param obj 要转换的 kv 数据列表
270
+ */
154
271
  static toArrayByRecord<T extends Mod>(obj: Record<string, T>): Record<string, Record<string, any>>;
155
272
  set<T extends this, TK extends keyof T>(n: Record<TK, T[TK] | undefined>): void;
156
273
  set<T extends this, TK extends keyof T>(n: TK, v: T[TK]): void;
274
+ /**
275
+ * --- 获取一个字段值
276
+ * @param n 字段名
277
+ */
157
278
  get(n: string): any;
279
+ /**
280
+ * --- 创建数据 ---
281
+ * @param notWhere 若要不存在才成功,则要传入限定条件
282
+ * @param table 可对限定条件传入适当的表
283
+ */
158
284
  create(notWhere?: string | types.Json, table?: string): Promise<boolean>;
285
+ /**
286
+ * --- 唯一键冲突则替换,不冲突则创建数据 ---
287
+ */
159
288
  replace(): Promise<boolean>;
289
+ /**
290
+ * --- 刷新当前模型获取最新数据 ---
291
+ * @param lock 是否加锁
292
+ */
160
293
  refresh(lock?: boolean): Promise<boolean | null>;
294
+ /**
295
+ * --- 更新 set 的数据到数据库,有未保存数据时才保存 ---
296
+ */
161
297
  save(): Promise<boolean>;
298
+ /**
299
+ * --- 移除本条目 ---
300
+ * @param raw 是否真实移除
301
+ */
162
302
  remove(raw?: boolean): Promise<boolean>;
163
303
  first(lock: boolean, array: true): Promise<false | null | Record<string, any>>;
164
304
  first(lock?: boolean, array?: false): Promise<false | null | (this & Record<string, any>)>;
305
+ /**
306
+ * --- 获取数据库第一个原生对象 ---
307
+ * @param lock 是否加锁
308
+ */
165
309
  firstArray(lock?: boolean): Promise<Record<string, any> | false | null>;
310
+ /**
311
+ * --- 联合查询表数据 ---
312
+ * @param f 要联合查询的表列表、单个表、sql 对象
313
+ * @param type 类型
314
+ */
166
315
  union(f: lSql.Sql | string | types.IModUnionItem | string[] | types.IModUnionItem[], type?: string): this;
316
+ /**
317
+ * --- 所有联合查询表数据 ---
318
+ * @param f 要联合查询的表列表、单个表、sql 对象
319
+ */
167
320
  unionAll(f: lSql.Sql | string | types.IModUnionItem | string[] | types.IModUnionItem[]): this;
168
321
  all(): Promise<false | Rows<this>>;
169
322
  all(key: string): Promise<false | Record<string, this>>;
@@ -172,34 +325,147 @@ export default class Mod {
172
325
  explain(all?: false): Promise<false | string>;
173
326
  explain(all: true): Promise<false | Record<string, any>>;
174
327
  private _formatTotal;
328
+ /**
329
+ * --- 获取总条数,自动抛弃 LIMIT,仅用于获取数据的情况(select) ---
330
+ */
175
331
  total(f?: string): Promise<number>;
332
+ /**
333
+ * --- 根据当前条件,筛选出当前条目该有的数据条数 ---
334
+ */
176
335
  count(): Promise<number>;
336
+ /**
337
+ * @param f 表名
338
+ * @param s ON 信息
339
+ * @param type 类型
340
+ * @param index 给本表增加 index 分表项
341
+ * @param pre 前缀
342
+ */
177
343
  join(f: string, s?: types.Json, type?: string, index?: string, pre?: string): this;
344
+ /**
345
+ * --- left join 方法 ---
346
+ * @param f 表名
347
+ * @param s ON 信息
348
+ * @param index 给本表增加 index 分表项
349
+ */
178
350
  leftJoin(f: string, s: types.Json, index?: string, pre?: string): this;
351
+ /**
352
+ * --- right join 方法 ---
353
+ * @param f 表名
354
+ * @param s ON 信息
355
+ * @param index 给本表增加 index 分表项
356
+ */
179
357
  rightJoin(f: string, s: types.Json, index?: string, pre?: string): this;
358
+ /**
359
+ * --- inner join 方法 ---
360
+ * @param f 表名
361
+ * @param s ON 信息
362
+ * @param index 给本表增加 index 分表项
363
+ */
180
364
  innerJoin(f: string, s: types.Json, index?: string, pre?: string): this;
365
+ /**
366
+ * --- full join 方法 ---
367
+ * @param f 表名
368
+ * @param s ON 信息
369
+ * @param index 给本表增加 index 分表项
370
+ */
181
371
  fullJoin(f: string, s: types.Json, index?: string, pre?: string): this;
372
+ /**
373
+ * --- cross join 方法 ---
374
+ * @param f 表名
375
+ * @param s ON 信息
376
+ * @param index 给本表增加 index 分表项
377
+ */
182
378
  crossJoin(f: string, s: types.Json, index?: string, pre?: string): this;
379
+ /**
380
+ * --- 筛选器 ---
381
+ * @param s 筛选条件数组或字符串
382
+ */
183
383
  having(s: types.Json): this;
384
+ /**
385
+ * --- 筛选器 ---
386
+ * @param s 筛选条件数组或字符串
387
+ * @param raw 是否包含已被软删除的数据
388
+ */
184
389
  filter(s: types.Json, raw?: boolean): this;
390
+ /**
391
+ * --- 是 filter 的别名 ---
392
+ * @param s 筛选条件数组或字符串
393
+ * @param raw 是否包含已被软删除的数据
394
+ */
185
395
  where(s: types.Json, raw?: boolean): this;
396
+ /**
397
+ * --- ORDER BY ---
398
+ * @param c 字段字符串或数组
399
+ * @param d 排序规则
400
+ */
186
401
  by(c: string | Array<string | string[]>, d?: 'DESC' | 'ASC'): this;
402
+ /**
403
+ * --- GROUP BY ---
404
+ * @param c 字段字符串或数组
405
+ */
187
406
  group(c: string | string[]): this;
407
+ /** --- 设置的 limit --- */
188
408
  private _limit;
409
+ /**
410
+ * --- LIMIT ---
411
+ * @param a 起始
412
+ * @param b 长度
413
+ */
189
414
  limit(a: number, b?: number): this;
415
+ /**
416
+ * --- 分页 ---
417
+ * @param count 每页条数
418
+ * @param page 当前页数
419
+ */
190
420
  page(count: number, page?: number): this;
421
+ /**
422
+ * --- 在 sql 最后追加字符串 ---
423
+ * @param sql
424
+ */
191
425
  append(sql: string): this;
426
+ /**
427
+ * --- 设置闭包含数据 ---
428
+ * @param contain 设置项
429
+ */
192
430
  contain(contain: {
193
431
  'key': string;
194
432
  'list': string[];
195
433
  }): this;
434
+ /**
435
+ * --- 获取 sql 语句 ---
436
+ */
196
437
  getSql(): string;
438
+ /**
439
+ * --- 获取全部 data ---
440
+ */
197
441
  getData(): any[];
442
+ /**
443
+ * --- 获取带 data 的 sql 语句 ---
444
+ * @param sql sql 语句
445
+ * @param data 数据
446
+ */
198
447
  format(sql?: string, data?: any[]): string;
448
+ /**
449
+ * --- 获取值对象 ---
450
+ */
199
451
  toArray(): Record<string, any>;
452
+ /**
453
+ * --- 获取当前设置要提交的数据 ---
454
+ */
200
455
  updates(): Record<string, any>;
456
+ /**
457
+ * --- 当前是否设置了未保存 --=
458
+ */
201
459
  unsaved(): boolean;
460
+ /**
461
+ * --- 获取字段的可用语种文本 ---
462
+ * @param col 字段名
463
+ * @param lang 当前请求语种,如 sc
464
+ */
202
465
  langText(col: string, lang: string): string;
466
+ /**
467
+ * --- 当 _key 不为空时,则依据继承此方法的方法自动生成填充 key ---
468
+ */
203
469
  protected _keyGenerator(): string;
204
470
  }
205
471
  export {};