@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/sys/route.js CHANGED
@@ -25,6 +25,38 @@ let kebabConfigs = {};
25
25
  export function clearKebabConfigs() {
26
26
  kebabConfigs = {};
27
27
  }
28
+ /**
29
+ * --- 输出 500 错误响应 ---
30
+ * @param res 响应对象
31
+ */
32
+ function respond500(res) {
33
+ const content = '<h1>500 Server Error</h1><hr>Kebab';
34
+ if (!res.headersSent) {
35
+ res.setHeader('content-type', 'text/html; charset=utf-8');
36
+ res.setHeader('content-length', Buffer.byteLength(content));
37
+ lCore.writeHead(res, 500);
38
+ }
39
+ res.end(content);
40
+ }
41
+ /**
42
+ * --- 输出 404 错误响应 ---
43
+ * @param res 响应对象
44
+ * @param config 配置对象(用于检查 #404 路由)
45
+ * @param path 请求路径
46
+ */
47
+ function respond404(res, config, path) {
48
+ if (config?.route?.['#404']) {
49
+ res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
50
+ lCore.writeHead(res, 302);
51
+ res.end('');
52
+ return;
53
+ }
54
+ const content = '[Error] Controller not found, path: ' + path + '.';
55
+ res.setHeader('content-type', 'text/html; charset=utf-8');
56
+ res.setHeader('content-length', Buffer.byteLength(content));
57
+ lCore.writeHead(res, 404);
58
+ res.end(content);
59
+ }
28
60
  /**
29
61
  * --- 若为动态路径则执行此函数,此函数不进行判断 kebab.json 是否存在 ---
30
62
  * @param data 传导的数据
@@ -181,17 +213,7 @@ export async function run(data) {
181
213
  // --- 若文件名为保留的 middle 将不允许进行 ---
182
214
  if (pathLeft.startsWith('middle')) {
183
215
  if (data.res) {
184
- if (config.route['#404']) {
185
- data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
186
- lCore.writeHead(data.res, 302);
187
- data.res.end('');
188
- return true;
189
- }
190
- const content = '[Error] Controller not found, path: ' + path + '.';
191
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
192
- data.res.setHeader('content-length', Buffer.byteLength(content));
193
- lCore.writeHead(data.res, 404);
194
- data.res.end(content);
216
+ respond404(data.res, config, path);
195
217
  }
196
218
  else {
197
219
  data.socket?.destroy();
@@ -411,11 +433,7 @@ export async function run(data) {
411
433
  }
412
434
  catch (e) {
413
435
  lCore.log(middle, '(E03)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
414
- const content = '<h1>500 Server Error</h1><hr>Kebab';
415
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
416
- data.res.setHeader('content-length', Buffer.byteLength(content));
417
- lCore.writeHead(data.res, 500);
418
- data.res.end(content);
436
+ respond500(data.res);
419
437
  return true;
420
438
  }
421
439
  let cacheTTL = middle.getPrototype('_cacheTTL');
@@ -427,11 +445,7 @@ export async function run(data) {
427
445
  }
428
446
  catch (e) {
429
447
  lCore.log(middle, '(E05)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
430
- const content = '<h1>500 Server Error</h1><hr>Kebab';
431
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
432
- data.res.setHeader('content-length', Buffer.byteLength(content));
433
- lCore.writeHead(data.res, 500);
434
- data.res.end(content);
448
+ respond500(data.res);
435
449
  return true;
436
450
  }
437
451
  cacheTTL = middle.getPrototype('_cacheTTL');
@@ -441,17 +455,7 @@ export async function run(data) {
441
455
  const filePath = config.const.ctrPath + pathLeft + '.js';
442
456
  if (!await lFs.isFile(filePath)) {
443
457
  // --- 指定的控制器不存在 ---
444
- if (config.route['#404']) {
445
- data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
446
- lCore.writeHead(data.res, 302);
447
- data.res.end('');
448
- return true;
449
- }
450
- const content = '[Error] Controller not found, path: ' + path + '.';
451
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
452
- data.res.setHeader('content-length', Buffer.byteLength(content));
453
- lCore.writeHead(data.res, 404);
454
- data.res.end(content);
458
+ respond404(data.res, config, path);
455
459
  return true;
456
460
  }
457
461
  // --- 加载控制器文件 ---
@@ -488,34 +492,14 @@ export async function run(data) {
488
492
  // --- 检测 action 是否存在,以及排除内部方法 ---
489
493
  if (pathRight.startsWith('_') || pathRight === 'onUpgrade' || pathRight === 'onLoad' || pathRight === 'onData' || pathRight === 'onDrain' || pathRight === 'onEnd' || pathRight === 'onClose' || pathRight === 'setPrototype' || pathRight === 'getPrototype' || pathRight === 'getAuthorization') {
490
494
  // --- _ 开头的 action 是内部方法,不允许访问 ---
491
- if (config.route['#404']) {
492
- data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
493
- lCore.writeHead(data.res, 302);
494
- data.res.end('');
495
- return true;
496
- }
497
- const content = '[Error] Action not found, path: ' + path + '.';
498
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
499
- data.res.setHeader('content-length', Buffer.byteLength(content));
500
- lCore.writeHead(data.res, 404);
501
- data.res.end(content);
495
+ respond404(data.res, config, path);
502
496
  return true;
503
497
  }
504
498
  pathRight = pathRight.replace(/-([a-zA-Z0-9])/g, function (t, t1) {
505
499
  return t1.toUpperCase();
506
500
  });
507
501
  if ((cctr[pathRight] === undefined) || (typeof cctr[pathRight] !== 'function')) {
508
- if (config.route['#404']) {
509
- data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
510
- lCore.writeHead(data.res, 302);
511
- data.res.end('');
512
- return true;
513
- }
514
- const content = '[Error] Action not found, path: ' + path + '.';
515
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
516
- data.res.setHeader('content-length', Buffer.byteLength(content));
517
- lCore.writeHead(data.res, 404);
518
- data.res.end(content);
502
+ respond404(data.res, config, path);
519
503
  return true;
520
504
  }
521
505
  // --- 执行 onLoad 方法 ---
@@ -538,11 +522,7 @@ export async function run(data) {
538
522
  }
539
523
  catch (e) {
540
524
  lCore.log(cctr, '(E05)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
541
- const content = '<h1>500 Server Error</h1><hr>Kebab';
542
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
543
- data.res.setHeader('content-length', Buffer.byteLength(content));
544
- lCore.writeHead(data.res, 500);
545
- data.res.end(content);
525
+ respond500(data.res);
546
526
  await waitCtr(cctr);
547
527
  return true;
548
528
  }
@@ -553,11 +533,7 @@ export async function run(data) {
553
533
  }
554
534
  catch (e) {
555
535
  lCore.log(cctr, '(E04)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
556
- const content = '<h1>500 Server Error</h1><hr>Kebab';
557
- data.res.setHeader('content-type', 'text/html; charset=utf-8');
558
- data.res.setHeader('content-length', Buffer.byteLength(content));
559
- lCore.writeHead(data.res, 500);
560
- data.res.end(content);
536
+ respond500(data.res);
561
537
  await waitCtr(cctr);
562
538
  return true;
563
539
  }
@@ -47,6 +47,7 @@ export default class extends sCtr.Ctr {
47
47
  coreUpdatecode(): Promise<string>;
48
48
  coreReload(): Promise<string>;
49
49
  coreRestart(): Promise<string>;
50
+ corePm2(): Promise<string>;
50
51
  coreGlobal(): Promise<string>;
51
52
  crypto(): Promise<string>;
52
53
  db(): Promise<kebab.Json>;
@@ -26,10 +26,7 @@ import * as sCtr from '#kebab/sys/ctr.js';
26
26
  import mTest from '../mod/test.js';
27
27
  import mTestData from '../mod/testdata.js';
28
28
  export default class extends sCtr.Ctr {
29
- constructor() {
30
- super(...arguments);
31
- this._internalUrl = '';
32
- }
29
+ _internalUrl = '';
33
30
  onLoad() {
34
31
  if (this._config.const.hostname !== '127.0.0.1' && this._config.const.hostname !== '172.17.0.1' &&
35
32
  this._config.const.hostname !== 'localhost' && !this._config.const.hostname.endsWith('.local.brc-app.com') &&
@@ -142,6 +139,7 @@ export default class extends sCtr.Ctr {
142
139
  `<br><a href="${this._config.const.urlBase}test/core-ls">View "test/core-ls"</a>`,
143
140
  `<br><a href="${this._config.const.urlBase}test/core-reload">View "test/core-reload"</a>`,
144
141
  `<br><a href="${this._config.const.urlBase}test/core-restart">View "test/core-restart"</a>`,
142
+ `<br><a href="${this._config.const.urlBase}test/core-pm2?name=cron&action=restart">View "test/core-pm2"</a>`,
145
143
  `<br><a href="${this._config.const.urlBase}test/core-global">View "test/core-global"</a>`,
146
144
  `<br><a href="${this._config.const.urlBase}test/core-updatecode">View "test/core-updatecode"</a>`,
147
145
  '<br><br><b>Crypto:</b>',
@@ -1278,6 +1276,18 @@ to: ${to}`
1278
1276
  await lCore.sendRestart();
1279
1277
  return 'The restart request has been sent, please review the console.<br><br>' + this._getEnd();
1280
1278
  }
1279
+ async corePm2() {
1280
+ const name = this._get['name'] ?? '';
1281
+ const action = (this._get['action'] ?? 'restart');
1282
+ if (!name) {
1283
+ return 'Please provide the PM2 process name via ?name=xxx&action=restart<br>action: start, stop, restart (default: restart)<br><br>' + this._getEnd();
1284
+ }
1285
+ if (action !== 'start' && action !== 'stop' && action !== 'restart') {
1286
+ return 'Invalid action. Must be: start, stop, restart<br><br>' + this._getEnd();
1287
+ }
1288
+ const list = await lCore.sendPm2(name, action);
1289
+ return `PM2 ${action} request has been sent for "${name}".<br>Success hosts: ${JSON.stringify(list)}<br><br>` + this._getEnd();
1290
+ }
1281
1291
  async coreGlobal() {
1282
1292
  const ts = lTime.stamp().toString();
1283
1293
  const echo = [
@@ -38,10 +38,10 @@ CREATE UNIQUE INDEX "utoken" ON "m"."test" USING btree (
38
38
  );
39
39
  */
40
40
  export default class default_1 extends sMod {
41
- static { this._$table = 'test'; }
42
- static { this._$primary = 'id'; }
43
- static { this._$key = 'token'; }
44
- static { this._$index = 'utoken'; }
41
+ static _$table = 'test';
42
+ static _$primary = 'id';
43
+ static _$key = 'token';
44
+ static _$index = 'utoken';
45
45
  /* eslint-enable */
46
46
  _keyGenerator() {
47
47
  return 'test_' + lCore.rand(0, 3).toString();
@@ -9,6 +9,6 @@ CREATE TABLE `m_test_data_0` (
9
9
  ) ENGINE=InnoDB DEFAULT CHARSET=ascii COLLATE=ascii_bin;
10
10
  */
11
11
  export default class default_1 extends sMod {
12
- static { this._$table = 'test_data'; }
13
- static { this._$primary = 'id'; }
12
+ static _$table = 'test_data';
13
+ static _$primary = 'id';
14
14
  }
@@ -2,10 +2,7 @@ import * as sCtr from '#kebab/sys/ctr.js';
2
2
  import * as lCrypto from '#kebab/lib/crypto.js';
3
3
  import * as lCore from '#kebab/lib/core.js';
4
4
  export default class extends sCtr.Ctr {
5
- constructor() {
6
- super(...arguments);
7
- this._nick = '';
8
- }
5
+ _nick = '';
9
6
  onUpgrade() {
10
7
  lCore.display('[/test] WebSocket test onUpgrade.');
11
8
  return {