@maiyunnet/kebab 7.0.2 → 7.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.
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/ai.js +3 -0
- package/lib/buffer.js +6 -4
- package/lib/captcha.js +1 -0
- package/lib/consistent.js +6 -6
- package/lib/core.d.ts +9 -0
- package/lib/core.js +59 -44
- package/lib/db/conn.js +14 -10
- package/lib/db/pool.js +6 -2
- package/lib/db/tran.js +10 -7
- package/lib/dns.js +2 -0
- package/lib/kv.d.ts +2 -1
- package/lib/kv.js +7 -1
- package/lib/net/formdata.js +14 -17
- package/lib/net/request.js +6 -6
- package/lib/net/response.js +7 -7
- package/lib/s3.js +4 -2
- package/lib/scan.js +9 -8
- package/lib/session.js +12 -6
- package/lib/sql.js +16 -12
- package/lib/ssh/sftp.js +4 -0
- package/lib/ssh/shell.js +2 -0
- package/lib/ssh.js +4 -0
- package/lib/text.js +2 -7
- package/lib/time.js +4 -2
- package/lib/vector.js +2 -0
- package/lib/ws.js +30 -28
- package/lib/zip.js +6 -4
- package/package.json +3 -3
- package/sys/child.js +21 -72
- package/sys/ctr.d.ts +7 -0
- package/sys/ctr.js +112 -189
- package/sys/master.js +23 -0
- package/sys/mod.js +25 -18
- package/sys/route.js +40 -64
- package/www/example/ctr/test.d.ts +1 -0
- package/www/example/ctr/test.js +14 -4
- package/www/example/mod/test.js +4 -4
- package/www/example/mod/testdata.js +2 -2
- package/www/example/ws/test.js +1 -4
package/sys/ctr.js
CHANGED
|
@@ -20,54 +20,46 @@ export function clearLocaleData() {
|
|
|
20
20
|
localeData = {};
|
|
21
21
|
}
|
|
22
22
|
export class Ctr {
|
|
23
|
+
/** --- 路由参数序列数组 --- */
|
|
24
|
+
_param = [];
|
|
25
|
+
/** --- 当前的 action 名 --- */
|
|
26
|
+
_action = '';
|
|
27
|
+
/** --- 请求的 header 列表,key 均为小写 --- */
|
|
28
|
+
_headers = {};
|
|
29
|
+
/** --- GET 数据 --- */
|
|
30
|
+
_get;
|
|
31
|
+
/** --- 原始 POST 数据 --- */
|
|
32
|
+
_rawPost = {};
|
|
33
|
+
/** --- POST 数据 --- */
|
|
34
|
+
_post = {};
|
|
35
|
+
/** --- 原始 input 字符串 */
|
|
36
|
+
_input = '';
|
|
37
|
+
/** --- 上传的文件列表 --- */
|
|
38
|
+
_files = {};
|
|
39
|
+
/** --- Cookie 数组 --- */
|
|
40
|
+
_cookie = {};
|
|
41
|
+
/** --- Session 数组 --- */
|
|
42
|
+
_session = {};
|
|
43
|
+
/** --- Session --- 对象 */
|
|
44
|
+
_sess = null;
|
|
45
|
+
/** --- 页面浏览器客户端缓存 --- */
|
|
46
|
+
_cacheTTL;
|
|
47
|
+
/** --- XSRF TOKEN 值 --- */
|
|
48
|
+
_xsrf = '';
|
|
49
|
+
/** --- 自定义 http code --- */
|
|
50
|
+
_httpCode = 0;
|
|
51
|
+
/** --- 当前语言名 --- */
|
|
52
|
+
_locale = 'en';
|
|
53
|
+
/** --- vhost 的 kebab.json 以及全局常量 --- */
|
|
54
|
+
_config;
|
|
55
|
+
_req;
|
|
56
|
+
_res;
|
|
57
|
+
_socket;
|
|
58
|
+
/** --- 本 ctr 已加载的语言文件列表 --- */
|
|
59
|
+
_localeFiles = [];
|
|
60
|
+
/** --- 本 ctr 的 locale data --- */
|
|
61
|
+
_localeData = {};
|
|
23
62
|
constructor(config, req, res) {
|
|
24
|
-
/** --- 路由参数序列数组 --- */
|
|
25
|
-
this._param = [];
|
|
26
|
-
/** --- 当前的 action 名 --- */
|
|
27
|
-
this._action = '';
|
|
28
|
-
/** --- 请求的 header 列表,key 均为小写 --- */
|
|
29
|
-
this._headers = {};
|
|
30
|
-
/** --- 原始 POST 数据 --- */
|
|
31
|
-
this._rawPost = {};
|
|
32
|
-
/** --- POST 数据 --- */
|
|
33
|
-
this._post = {};
|
|
34
|
-
/** --- 原始 input 字符串 */
|
|
35
|
-
this._input = '';
|
|
36
|
-
/** --- 上传的文件列表 --- */
|
|
37
|
-
this._files = {};
|
|
38
|
-
/** --- Cookie 数组 --- */
|
|
39
|
-
this._cookie = {};
|
|
40
|
-
/** --- Session 数组 --- */
|
|
41
|
-
this._session = {};
|
|
42
|
-
/** --- Session --- 对象 */
|
|
43
|
-
this._sess = null;
|
|
44
|
-
/** --- XSRF TOKEN 值 --- */
|
|
45
|
-
this._xsrf = '';
|
|
46
|
-
/** --- 自定义 http code --- */
|
|
47
|
-
this._httpCode = 0;
|
|
48
|
-
/** --- 当前语言名 --- */
|
|
49
|
-
this._locale = 'en';
|
|
50
|
-
/** --- 本 ctr 已加载的语言文件列表 --- */
|
|
51
|
-
this._localeFiles = [];
|
|
52
|
-
/** --- 本 ctr 的 locale data --- */
|
|
53
|
-
this._localeData = {};
|
|
54
|
-
/** --- 一些需要等待的事项的记录(异步任务、事务) --- */
|
|
55
|
-
this._waitInfo = {
|
|
56
|
-
'asyncTask': {
|
|
57
|
-
'count': 0,
|
|
58
|
-
'resolve': () => {
|
|
59
|
-
// --- NOTHING ---
|
|
60
|
-
},
|
|
61
|
-
'callback': function () {
|
|
62
|
-
return new Promise((resolve) => {
|
|
63
|
-
this.resolve = resolve;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
'transaction': 0
|
|
68
|
-
};
|
|
69
|
-
/** --- auth 对象,user, pwd --- */
|
|
70
|
-
this._authorization = null;
|
|
71
63
|
this._config = config;
|
|
72
64
|
this._req = req;
|
|
73
65
|
if (res) {
|
|
@@ -79,6 +71,8 @@ export class Ctr {
|
|
|
79
71
|
get _isAvail() {
|
|
80
72
|
return this._req.socket.writable;
|
|
81
73
|
}
|
|
74
|
+
/** --- timeout 的 timer --- */
|
|
75
|
+
_timer;
|
|
82
76
|
/** --- 获取当前过期时间 --- */
|
|
83
77
|
get timeout() {
|
|
84
78
|
return this._timer?.timeout ?? 30_000;
|
|
@@ -94,6 +88,21 @@ export class Ctr {
|
|
|
94
88
|
clearTimeout(this._timer.timer);
|
|
95
89
|
this._timer.timer = setTimeout(this._timer.callback, num);
|
|
96
90
|
}
|
|
91
|
+
/** --- 一些需要等待的事项的记录(异步任务、事务) --- */
|
|
92
|
+
_waitInfo = {
|
|
93
|
+
'asyncTask': {
|
|
94
|
+
'count': 0,
|
|
95
|
+
'resolve': () => {
|
|
96
|
+
// --- NOTHING ---
|
|
97
|
+
},
|
|
98
|
+
'callback': function () {
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
this.resolve = resolve;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
'transaction': 0
|
|
105
|
+
};
|
|
97
106
|
/**
|
|
98
107
|
* --- 执行一段跳出堆栈的异步代码,代码执行完成前,热更新不会杀死当面进程 且 ftmp 临时文件不会被清除 ---
|
|
99
108
|
* @param func 异步代码
|
|
@@ -213,6 +222,19 @@ export class Ctr {
|
|
|
213
222
|
};
|
|
214
223
|
return lCore.purify(ejs.render(content, data, {}));
|
|
215
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* --- 设置校验错误返回值 ---
|
|
227
|
+
* @param rtn 返回值数组
|
|
228
|
+
* @param lastVal 规则最后一项
|
|
229
|
+
* @param msgSuffix 可选的消息后缀
|
|
230
|
+
*/
|
|
231
|
+
_setCheckError(rtn, lastVal, msgSuffix) {
|
|
232
|
+
rtn[0] = lastVal[0];
|
|
233
|
+
rtn[1] = msgSuffix ? lastVal[1] + msgSuffix : lastVal[1];
|
|
234
|
+
if (lastVal[2]) {
|
|
235
|
+
rtn[2] = lastVal[2];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
216
238
|
/**
|
|
217
239
|
* --- 检测提交的数据类型 ---
|
|
218
240
|
* @param input 要校验的输入项
|
|
@@ -225,10 +247,7 @@ export class Ctr {
|
|
|
225
247
|
for (const key in rule) {
|
|
226
248
|
const val = rule[key];
|
|
227
249
|
// --- key 就是上面的 xx ---
|
|
228
|
-
|
|
229
|
-
// --- 原值不存在则设定为 null ---
|
|
230
|
-
input[key] = null;
|
|
231
|
-
}
|
|
250
|
+
input[key] ??= null;
|
|
232
251
|
// --- 判断是否需要遍历 val ---
|
|
233
252
|
const c = val.length;
|
|
234
253
|
if (c === 0) {
|
|
@@ -236,20 +255,17 @@ export class Ctr {
|
|
|
236
255
|
}
|
|
237
256
|
// --- ['require', '> 6', [0, 'xx 必须大于 6']] ---
|
|
238
257
|
const lastK = c - 1;
|
|
239
|
-
|
|
258
|
+
const lastVal = val[lastK];
|
|
259
|
+
if ((lastVal[0] === undefined) || (lastVal[1] === undefined) || !Number.isInteger(lastVal[0]) || (typeof lastVal[1] !== 'string')) {
|
|
240
260
|
rtn[0] = 0;
|
|
241
|
-
rtn[1] =
|
|
261
|
+
rtn[1] = `Param error(${key})`;
|
|
242
262
|
return false;
|
|
243
263
|
}
|
|
244
264
|
for (let k = 0; k < lastK; ++k) {
|
|
245
265
|
const v = val[k] ?? '';
|
|
246
266
|
if (Array.isArray(v)) {
|
|
247
267
|
if (v.length === 0) {
|
|
248
|
-
rtn
|
|
249
|
-
rtn[1] = val[lastK][1];
|
|
250
|
-
if (val[lastK][2]) {
|
|
251
|
-
rtn[2] = val[lastK][2];
|
|
252
|
-
}
|
|
268
|
+
this._setCheckError(rtn, lastVal);
|
|
253
269
|
return false;
|
|
254
270
|
}
|
|
255
271
|
// --- 判断提交的数据是否在此 array 之内,若没有提交数据,则自动设置为第一个项 ---
|
|
@@ -257,23 +273,14 @@ export class Ctr {
|
|
|
257
273
|
input[key] = v[0];
|
|
258
274
|
}
|
|
259
275
|
else if (!v.includes(input[key])) {
|
|
260
|
-
|
|
261
|
-
rtn[0] = val[lastK][0];
|
|
262
|
-
rtn[1] = val[lastK][1];
|
|
263
|
-
if (val[lastK][2]) {
|
|
264
|
-
rtn[2] = val[lastK][2];
|
|
265
|
-
}
|
|
276
|
+
this._setCheckError(rtn, lastVal);
|
|
266
277
|
return false;
|
|
267
278
|
}
|
|
268
279
|
}
|
|
269
280
|
else if (v instanceof RegExp) {
|
|
270
281
|
// --- 正则 ---
|
|
271
282
|
if (input[key] !== null && !v.test(input[key])) {
|
|
272
|
-
rtn
|
|
273
|
-
rtn[1] = val[lastK][1];
|
|
274
|
-
if (val[lastK][2]) {
|
|
275
|
-
rtn[2] = val[lastK][2];
|
|
276
|
-
}
|
|
283
|
+
this._setCheckError(rtn, lastVal);
|
|
277
284
|
return false;
|
|
278
285
|
}
|
|
279
286
|
}
|
|
@@ -282,197 +289,111 @@ export class Ctr {
|
|
|
282
289
|
if (input[key] !== null) {
|
|
283
290
|
const r = lCore.checkType(input[key], v.type);
|
|
284
291
|
if (r) {
|
|
285
|
-
rtn[
|
|
286
|
-
rtn[1] = typeof val[lastK][1] === 'string' ? val[lastK][1] + '(' + r + ')' : val[lastK][1];
|
|
287
|
-
if (val[lastK][2]) {
|
|
288
|
-
rtn[2] = val[lastK][2];
|
|
289
|
-
}
|
|
292
|
+
this._setCheckError(rtn, lastVal, typeof lastVal[1] === 'string' ? `(${r})` : undefined);
|
|
290
293
|
return false;
|
|
291
294
|
}
|
|
292
295
|
}
|
|
293
296
|
}
|
|
294
297
|
else {
|
|
298
|
+
/** --- 是否需要返回错误 --- */
|
|
299
|
+
let needReturn = false;
|
|
295
300
|
switch (v) {
|
|
296
301
|
case 'require': {
|
|
297
|
-
|
|
298
|
-
rtn[0] = val[lastK][0];
|
|
299
|
-
rtn[1] = val[lastK][1];
|
|
300
|
-
if (val[lastK][2]) {
|
|
301
|
-
rtn[2] = val[lastK][2];
|
|
302
|
-
}
|
|
303
|
-
return false;
|
|
304
|
-
}
|
|
302
|
+
needReturn = (input[key] === null) || (input[key] === '');
|
|
305
303
|
break;
|
|
306
304
|
}
|
|
307
305
|
case 'int':
|
|
308
306
|
case 'integer': {
|
|
309
307
|
// --- 必须是数字型且是整数 ---
|
|
310
|
-
|
|
311
|
-
rtn[0] = val[lastK][0];
|
|
312
|
-
rtn[1] = val[lastK][1];
|
|
313
|
-
if (val[lastK][2]) {
|
|
314
|
-
rtn[2] = val[lastK][2];
|
|
315
|
-
}
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
308
|
+
needReturn = input[key] && !Number.isSafeInteger(input[key]);
|
|
318
309
|
break;
|
|
319
310
|
}
|
|
320
311
|
case 'float':
|
|
321
312
|
case 'double': {
|
|
322
313
|
// --- 必须是数字型 ---
|
|
323
|
-
|
|
324
|
-
rtn[0] = val[lastK][0];
|
|
325
|
-
rtn[1] = val[lastK][1];
|
|
326
|
-
if (val[lastK][2]) {
|
|
327
|
-
rtn[2] = val[lastK][2];
|
|
328
|
-
}
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
314
|
+
needReturn = input[key] && (typeof input[key] !== 'number');
|
|
331
315
|
break;
|
|
332
316
|
}
|
|
333
317
|
case 'num':
|
|
334
318
|
case 'number': {
|
|
335
319
|
// --- 可字符串数字 ---
|
|
336
|
-
|
|
337
|
-
rtn[0] = val[lastK][0];
|
|
338
|
-
rtn[1] = val[lastK][1];
|
|
339
|
-
if (val[lastK][2]) {
|
|
340
|
-
rtn[2] = val[lastK][2];
|
|
341
|
-
}
|
|
342
|
-
return false;
|
|
343
|
-
}
|
|
320
|
+
needReturn = input[key] && (typeof input[key] !== 'number') && !/^[0-9]+\.?[0-9]*$/.test(input[key]);
|
|
344
321
|
break;
|
|
345
322
|
}
|
|
346
323
|
case 'array': {
|
|
347
|
-
|
|
348
|
-
rtn[0] = val[lastK][0];
|
|
349
|
-
rtn[1] = val[lastK][1];
|
|
350
|
-
if (val[lastK][2]) {
|
|
351
|
-
rtn[2] = val[lastK][2];
|
|
352
|
-
}
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
324
|
+
needReturn = input[key] !== null && !Array.isArray(input[key]);
|
|
355
325
|
break;
|
|
356
326
|
}
|
|
357
327
|
case 'bool':
|
|
358
328
|
case 'boolean': {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
rtn[0] = val[lastK][0];
|
|
362
|
-
rtn[1] = val[lastK][1];
|
|
363
|
-
if (val[lastK][2]) {
|
|
364
|
-
rtn[2] = val[lastK][2];
|
|
365
|
-
}
|
|
366
|
-
return false;
|
|
367
|
-
}
|
|
329
|
+
// --- 如果不是 bool 直接失败,字符串的 true, false 也会失败 ---
|
|
330
|
+
needReturn = input[key] !== null && (typeof input[key] !== 'boolean');
|
|
368
331
|
break;
|
|
369
332
|
}
|
|
370
333
|
case 'string': {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
rtn[0] = val[lastK][0];
|
|
374
|
-
rtn[1] = val[lastK][1];
|
|
375
|
-
if (val[lastK][2]) {
|
|
376
|
-
rtn[2] = val[lastK][2];
|
|
377
|
-
}
|
|
378
|
-
return false;
|
|
379
|
-
}
|
|
334
|
+
// --- 如果不是 string 直接失败 ---
|
|
335
|
+
needReturn = input[key] !== null && (typeof input[key] !== 'string');
|
|
380
336
|
break;
|
|
381
337
|
}
|
|
382
338
|
case 'ascii': {
|
|
383
339
|
// --- 必须是 ASCII 字符 ---
|
|
384
|
-
|
|
385
|
-
rtn[0] = val[lastK][0];
|
|
386
|
-
rtn[1] = val[lastK][1];
|
|
387
|
-
if (val[lastK][2]) {
|
|
388
|
-
rtn[2] = val[lastK][2];
|
|
389
|
-
}
|
|
390
|
-
return false;
|
|
391
|
-
}
|
|
340
|
+
needReturn = input[key] !== null && !lText.isAscii(input[key]);
|
|
392
341
|
break;
|
|
393
342
|
}
|
|
394
343
|
default: {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
return false;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
else if ((match = /^([><=]+) *([0-9]+)$/.exec(v))) {
|
|
344
|
+
if (input[key] === null) {
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
if (v[0] === '/') {
|
|
348
|
+
// --- 正则 ---
|
|
349
|
+
needReturn = !(new RegExp(v.slice(1, -1))).test(input[key]);
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
const match = /^([><=]+) *([0-9]+)$/.exec(v);
|
|
353
|
+
if (match) {
|
|
409
354
|
// --- 判断表达式 ---
|
|
410
|
-
let needReturn = false;
|
|
411
355
|
const inputNum = Number(input[key]);
|
|
412
356
|
const num = Number(match[2]);
|
|
413
357
|
switch (match[1]) {
|
|
414
358
|
case '>': {
|
|
415
|
-
|
|
416
|
-
needReturn = true;
|
|
417
|
-
}
|
|
359
|
+
needReturn = inputNum <= num;
|
|
418
360
|
break;
|
|
419
361
|
}
|
|
420
362
|
case '<': {
|
|
421
|
-
|
|
422
|
-
needReturn = true;
|
|
423
|
-
}
|
|
363
|
+
needReturn = inputNum >= num;
|
|
424
364
|
break;
|
|
425
365
|
}
|
|
426
366
|
case '>=': {
|
|
427
|
-
|
|
428
|
-
needReturn = true;
|
|
429
|
-
}
|
|
367
|
+
needReturn = inputNum < num;
|
|
430
368
|
break;
|
|
431
369
|
}
|
|
432
370
|
case '<=': {
|
|
433
|
-
|
|
434
|
-
needReturn = true;
|
|
435
|
-
}
|
|
371
|
+
needReturn = inputNum > num;
|
|
436
372
|
break;
|
|
437
373
|
}
|
|
438
374
|
case '=':
|
|
439
375
|
case '==':
|
|
440
376
|
case '===': {
|
|
441
|
-
|
|
442
|
-
needReturn = true;
|
|
443
|
-
}
|
|
377
|
+
needReturn = inputNum !== num;
|
|
444
378
|
break;
|
|
445
379
|
}
|
|
446
380
|
case '!=':
|
|
447
381
|
case '<>': {
|
|
448
|
-
|
|
449
|
-
needReturn = true;
|
|
450
|
-
}
|
|
382
|
+
needReturn = inputNum === num;
|
|
451
383
|
break;
|
|
452
384
|
}
|
|
453
385
|
}
|
|
454
|
-
if (needReturn) {
|
|
455
|
-
rtn[0] = val[lastK][0];
|
|
456
|
-
rtn[1] = val[lastK][1];
|
|
457
|
-
if (val[lastK][2]) {
|
|
458
|
-
rtn[2] = val[lastK][2];
|
|
459
|
-
}
|
|
460
|
-
return false;
|
|
461
|
-
}
|
|
462
386
|
}
|
|
463
387
|
else {
|
|
464
|
-
|
|
465
|
-
rtn[0] = val[lastK][0];
|
|
466
|
-
rtn[1] = val[lastK][1];
|
|
467
|
-
if (val[lastK][2]) {
|
|
468
|
-
rtn[2] = val[lastK][2];
|
|
469
|
-
}
|
|
470
|
-
return false;
|
|
471
|
-
}
|
|
388
|
+
needReturn = input[key] !== v;
|
|
472
389
|
}
|
|
473
390
|
}
|
|
474
391
|
}
|
|
475
392
|
}
|
|
393
|
+
if (needReturn) {
|
|
394
|
+
this._setCheckError(rtn, lastVal);
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
476
397
|
}
|
|
477
398
|
}
|
|
478
399
|
}
|
|
@@ -532,6 +453,8 @@ export class Ctr {
|
|
|
532
453
|
}
|
|
533
454
|
return 'unknown';
|
|
534
455
|
}
|
|
456
|
+
/** --- auth 对象,user, pwd --- */
|
|
457
|
+
_authorization = null;
|
|
535
458
|
/**
|
|
536
459
|
* --- 通过 header 或 _auth 获取鉴权信息或 JWT 信息(不解析) ---
|
|
537
460
|
*/
|
package/sys/master.js
CHANGED
|
@@ -138,6 +138,29 @@ function createRpcListener() {
|
|
|
138
138
|
lCore.global[msg.key] = msg.data;
|
|
139
139
|
break;
|
|
140
140
|
}
|
|
141
|
+
case 'pm2': {
|
|
142
|
+
// --- 执行 PM2 操作 ---
|
|
143
|
+
if (!msg.name || typeof msg.name !== 'string') {
|
|
144
|
+
res.end('Invalid name');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// --- 安全过滤,只允许字母、数字、下划线、短横线 ---
|
|
148
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(msg.name)) {
|
|
149
|
+
res.end('Invalid name format');
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// --- 校验 pm2Action ---
|
|
153
|
+
if (msg.pm2Action !== 'start' && msg.pm2Action !== 'stop' && msg.pm2Action !== 'restart') {
|
|
154
|
+
res.end('Invalid pm2Action');
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const rtn = await lCore.exec(`pm2 ${msg.pm2Action} ${msg.name}`);
|
|
158
|
+
if (rtn === false) {
|
|
159
|
+
res.end('Exec failed');
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
141
164
|
case 'code': {
|
|
142
165
|
// --- 更新 code 代码包 ---
|
|
143
166
|
const rtn = await sRoute.getFormData(req);
|
package/sys/mod.js
CHANGED
|
@@ -9,6 +9,7 @@ import * as lCore from '#kebab/lib/core.js';
|
|
|
9
9
|
import * as lText from '#kebab/lib/text.js';
|
|
10
10
|
/** --- 条数列表 --- */
|
|
11
11
|
export class Rows {
|
|
12
|
+
_items;
|
|
12
13
|
constructor(initialItems = []) {
|
|
13
14
|
this._items = initialItems;
|
|
14
15
|
}
|
|
@@ -46,32 +47,36 @@ export class Rows {
|
|
|
46
47
|
*/
|
|
47
48
|
export default class Mod {
|
|
48
49
|
/** --- 表名 --- */
|
|
49
|
-
static
|
|
50
|
+
static _$table = '';
|
|
50
51
|
/** --- 主键字段名 --- */
|
|
51
|
-
static
|
|
52
|
+
static _$primary = 'id';
|
|
52
53
|
/** --- 设置后将由 _keyGenerator 函数生成唯一字段 --- */
|
|
53
|
-
static
|
|
54
|
+
static _$key = '';
|
|
54
55
|
/** --- 若使用 _$key 并且有多个 unique 索引,这里指定 _$key 的索引名 --- */
|
|
55
|
-
static
|
|
56
|
+
static _$index = '';
|
|
57
|
+
/** --- 前缀,顺序:选项前缀 -> 本前缀 -> 配置文件前缀 --- */
|
|
58
|
+
static _$pre;
|
|
59
|
+
/** --- 要 update 的内容 --- */
|
|
60
|
+
_updates = {};
|
|
61
|
+
/** --- 模型获取的属性 --- */
|
|
62
|
+
_data = {};
|
|
63
|
+
/** --- 当前选择的分表 _ 后缀,多个代表联查 --- */
|
|
64
|
+
_index = null;
|
|
65
|
+
/** --- 必须追加的数据筛选 key 与 values,仅单表模式有效 --- */
|
|
66
|
+
_contain = null;
|
|
67
|
+
/** --- 已算出的 total --- */
|
|
68
|
+
_total = [];
|
|
69
|
+
/** --- 数据库连接对象 --- */
|
|
70
|
+
_db;
|
|
71
|
+
/** --- Sql 对象 --- */
|
|
72
|
+
_sql;
|
|
73
|
+
/** --- ctr 对象 --- */
|
|
74
|
+
_ctr = undefined;
|
|
56
75
|
/**
|
|
57
76
|
* --- 构造函数 ---
|
|
58
77
|
* @param opt 选项
|
|
59
78
|
*/
|
|
60
79
|
constructor(opt) {
|
|
61
|
-
/** --- 要 update 的内容 --- */
|
|
62
|
-
this._updates = {};
|
|
63
|
-
/** --- 模型获取的属性 --- */
|
|
64
|
-
this._data = {};
|
|
65
|
-
/** --- 当前选择的分表 _ 后缀,多个代表联查 --- */
|
|
66
|
-
this._index = null;
|
|
67
|
-
/** --- 必须追加的数据筛选 key 与 values,仅单表模式有效 --- */
|
|
68
|
-
this._contain = null;
|
|
69
|
-
/** --- 已算出的 total --- */
|
|
70
|
-
this._total = [];
|
|
71
|
-
/** --- ctr 对象 --- */
|
|
72
|
-
this._ctr = undefined;
|
|
73
|
-
/** --- 设置的 limit --- */
|
|
74
|
-
this._limit = [0, 0];
|
|
75
80
|
/** --- 导入 ctr 对象 --- */
|
|
76
81
|
this._ctr = opt.ctr;
|
|
77
82
|
/** --- 导入数据库连接 --- */
|
|
@@ -1303,6 +1308,8 @@ export default class Mod {
|
|
|
1303
1308
|
this._sql.group(c);
|
|
1304
1309
|
return this;
|
|
1305
1310
|
}
|
|
1311
|
+
/** --- 设置的 limit --- */
|
|
1312
|
+
_limit = [0, 0];
|
|
1306
1313
|
/**
|
|
1307
1314
|
* --- LIMIT ---
|
|
1308
1315
|
* @param a 起始
|