node-karin 0.10.6 → 0.11.0

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 (41) hide show
  1. package/config/defSet/group.yaml +6 -6
  2. package/lib/adapter/onebot/11/convert.js +1 -1
  3. package/lib/core/index.d.ts +1 -1
  4. package/lib/core/index.js +1 -1
  5. package/lib/core/karin/karin.d.ts +41 -54
  6. package/lib/core/karin/karin.js +61 -54
  7. package/lib/core/listener/listener.d.ts +1 -2
  8. package/lib/core/listener/listener.js +15 -1
  9. package/lib/core/plugin/base.d.ts +10 -23
  10. package/lib/core/plugin/base.js +6 -15
  11. package/lib/core/plugin/loader.d.ts +79 -102
  12. package/lib/core/plugin/loader.js +440 -404
  13. package/lib/core/server/server.d.ts +1 -1
  14. package/lib/event/handler/base.d.ts +13 -4
  15. package/lib/event/handler/base.js +38 -20
  16. package/lib/event/handler/message.d.ts +11 -7
  17. package/lib/event/handler/message.js +111 -80
  18. package/lib/event/handler/notice.d.ts +1 -0
  19. package/lib/event/handler/notice.js +37 -36
  20. package/lib/event/handler/request.d.ts +1 -0
  21. package/lib/event/handler/request.js +32 -36
  22. package/lib/event/handler/review.d.ts +10 -10
  23. package/lib/event/handler/review.js +34 -39
  24. package/lib/types/config/config.d.ts +12 -2
  25. package/lib/types/event/contact.d.ts +1 -1
  26. package/lib/types/event/event.d.ts +9 -106
  27. package/lib/types/index.d.ts +1 -0
  28. package/lib/types/index.js +1 -0
  29. package/lib/types/plugin/app.d.ts +71 -0
  30. package/lib/types/plugin/app.js +1 -0
  31. package/lib/types/plugin/plugin.d.ts +192 -12
  32. package/lib/utils/common/common.d.ts +19 -7
  33. package/lib/utils/common/common.js +74 -73
  34. package/lib/utils/config/config.d.ts +2 -2
  35. package/lib/utils/core/handler.d.ts +0 -14
  36. package/lib/utils/core/handler.js +7 -76
  37. package/lib/utils/tools/button.d.ts +1 -1
  38. package/lib/utils/tools/button.js +18 -29
  39. package/package.json +1 -1
  40. package/lib/core/plugin/app.d.ts +0 -19
  41. package/lib/core/plugin/app.js +0 -19
@@ -1,7 +1,13 @@
1
1
  import fs from 'fs';
2
2
  import { AxiosRequestConfig } from 'axios';
3
3
  import { Readable } from 'stream';
4
- import { ButtonElement, ButtonType, dirName, fileName, KarinElement, NodeElement, KeyBoardElement } from '../../types/index.js';
4
+ import { ButtonElement, ButtonType, dirName, KarinElement, NodeElement, KeyBoardElement } from '../../types/index.js';
5
+ export interface NpmInfo {
6
+ plugin: string;
7
+ path: string;
8
+ file: string;
9
+ isMain: boolean;
10
+ }
5
11
  /**
6
12
  * 常用方法
7
13
  */
@@ -52,6 +58,11 @@ declare class Common {
52
58
  * @returns 返回true为插件包
53
59
  */
54
60
  isPlugin(path: string): boolean;
61
+ /**
62
+ * 去掉相对路径的前缀和后缀
63
+ * @param root - 相对路径路径
64
+ */
65
+ getRelPath(root: string): string;
55
66
  /**
56
67
  * 判断路径是否存在
57
68
  * @param path - 路径
@@ -142,16 +153,17 @@ declare class Common {
142
153
  * @param isPack - 是否屏蔽不带package.json的插件,默认为false
143
154
  */
144
155
  getPlugins(isPack?: boolean): Array<dirName>;
156
+ /**
157
+ * 获取git插件列表
158
+ * @param isPack - 是否屏蔽不带package.json的插件,默认为false
159
+ */
160
+ getGitPlugins(isPack?: boolean): Array<dirName>;
145
161
  /**
146
162
  * 获取npm插件列表
147
- * @param showDetails - 是否返回详细信息,默认为false
163
+ * @param showDetails - 是否返回详细信息
148
164
  * 默认只返回插件npm包名,为true时返回详细的{dir, name}[]
149
165
  */
150
- getNpmPlugins<T extends boolean>(showDetails: T): Promise<T extends true ? {
151
- dir: string;
152
- name: fileName;
153
- isMain: boolean;
154
- }[] : string[]>;
166
+ getNpmPlugins<T extends boolean>(showDetails: T): Promise<T extends true ? NpmInfo[] : string[]>;
155
167
  /**
156
168
  * 获取运行时间
157
169
  */
@@ -120,6 +120,13 @@ class Common {
120
120
  isPlugin(path) {
121
121
  return this.exists(`${path}/package.json`);
122
122
  }
123
+ /**
124
+ * 去掉相对路径的前缀和后缀
125
+ * @param root - 相对路径路径
126
+ */
127
+ getRelPath(root) {
128
+ return root.replace(/\\+/g, '/').replace(/\.+\/+|\/+$/g, '');
129
+ }
123
130
  /**
124
131
  * 判断路径是否存在
125
132
  * @param path - 路径
@@ -269,7 +276,7 @@ class Common {
269
276
  /** file:// */
270
277
  const files = file.replace(/^file:\/\//, '');
271
278
  if (fs.existsSync(files))
272
- return fs.readFileSync(file).toString('base64');
279
+ return fs.readFileSync(files).toString('base64');
273
280
  /** 无前缀base64:// */
274
281
  return Buffer.from(file, 'base64').toString('base64');
275
282
  }
@@ -359,78 +366,72 @@ class Common {
359
366
  list.map(v => arr.push(v.name));
360
367
  return arr;
361
368
  }
369
+ /**
370
+ * 获取git插件列表
371
+ * @param isPack - 是否屏蔽不带package.json的插件,默认为false
372
+ */
373
+ getGitPlugins(isPack = false) {
374
+ return this.getPlugins(isPack);
375
+ }
362
376
  /**
363
377
  * 获取npm插件列表
364
- * @param showDetails - 是否返回详细信息,默认为false
378
+ * @param showDetails - 是否返回详细信息
365
379
  * 默认只返回插件npm包名,为true时返回详细的{dir, name}[]
366
380
  */
367
381
  async getNpmPlugins(showDetails) {
368
382
  /** 屏蔽的依赖包列表 */
369
- const pkgdependencies = [
370
- '@grpc/grpc-js',
371
- '@grpc/proto-loader',
372
- 'art-template',
373
- 'axios',
374
- 'chalk',
375
- 'chokidar',
376
- 'express',
377
- 'kritor-proto',
378
- 'level',
379
- 'lodash',
380
- 'log4js',
381
- 'moment',
382
- 'node-karin',
383
- 'node-schedule',
384
- 'redis',
385
- 'ws',
386
- 'yaml',
387
- ];
388
- const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
389
- const dependencies = Object.keys(pkg.dependencies).filter((name) => !pkgdependencies.includes(name));
383
+ const exclude = ['art-template', 'axios', 'chalk', 'chokidar', 'express', 'level', 'lodash', 'log4js', 'moment', 'node-karin', 'node-schedule', 'redis', 'ws', 'yaml'];
384
+ const pkg = this.readJson('./package.json');
385
+ const dependencies = Object.keys(pkg.dependencies).filter((name) => !exclude.includes(name));
390
386
  if (!showDetails) {
391
387
  const list = [];
392
- // 检查pkg是否存在karin字段
393
388
  const readPackageJson = async (name) => {
394
389
  try {
395
390
  const pkgPath = path.join(process.cwd(), 'node_modules', name, 'package.json');
396
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
391
+ const pkg = this.readJson(pkgPath);
397
392
  if (pkg?.karin)
398
393
  list.push(name);
399
394
  }
400
- catch { }
395
+ catch (error) {
396
+ logger.error(`[common] 解析 package.json 时出错:${error.stack || error.message || JSON.stringify(error)}`);
397
+ }
401
398
  };
402
399
  await Promise.all(dependencies.map(readPackageJson));
403
400
  return list;
404
401
  }
405
- else {
406
- const list = [];
407
- const readPackageJson = async (files) => {
408
- try {
409
- const pkgPath = path.join(process.cwd(), 'node_modules', files, 'package.json');
410
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
411
- if (pkg?.karin) {
412
- if (pkg?.main) {
413
- const dir = `${files}/${path.dirname(pkg.main).replace(/\.\//, '')}`;
414
- list.push({ dir, name: path.basename(pkg.main), isMain: true });
415
- }
416
- if (pkg?.karin?.apps?.length) {
417
- pkg.karin.apps.forEach((app) => {
418
- fs.readdirSync(`./node_modules/${files}/${app}`).forEach((filename) => {
419
- /** 忽略非js */
420
- if (!filename.endsWith('.js'))
421
- return;
422
- const dir = `${files}/${app}`;
423
- list.push({ dir, name: filename, isMain: false });
424
- });
425
- });
402
+ const list = [];
403
+ /** 获取详细的npm信息 */
404
+ const readPackageJson = async (files) => {
405
+ try {
406
+ const root = path.join(process.cwd(), 'node_modules', files);
407
+ const pkgPath = path.join(root, 'package.json');
408
+ const pkg = this.readJson(pkgPath);
409
+ if (!pkg?.karin)
410
+ return;
411
+ if (pkg?.main) {
412
+ list.push({ plugin: files, path: path.dirname(pkg.main), file: path.basename(pkg.main), isMain: true });
413
+ }
414
+ if (pkg?.karin?.apps?.length) {
415
+ pkg.karin.apps.forEach((app) => {
416
+ if (!fs.existsSync(path.join(root, app))) {
417
+ logger.error(`[common] npm插件${files}的app目录${app}不存在 已跳过`);
418
+ return;
426
419
  }
427
- }
420
+ fs.readdirSync(path.join(root, app)).forEach((filename) => {
421
+ /** 忽略非js文件 npm包不考虑ts */
422
+ if (!filename.endsWith('.js'))
423
+ return;
424
+ list.push({ plugin: files, path: app, file: filename, isMain: false });
425
+ });
426
+ });
428
427
  }
429
- catch { }
430
- };
431
- await Promise.all(dependencies.map(readPackageJson));
432
- return list;
433
- }
428
+ }
429
+ catch (error) {
430
+ logger.error(`[common] 获取npm插件列表时出错:${error.stack || error.message || JSON.stringify(error)}`);
431
+ }
432
+ };
433
+ await Promise.all(dependencies.map(readPackageJson));
434
+ return list;
434
435
  }
435
436
  /**
436
437
  * 获取运行时间
@@ -456,7 +457,7 @@ class Common {
456
457
  logs.push(val.text);
457
458
  break;
458
459
  case 'face':
459
- logs.push(`[face:${val.id}]`);
460
+ logs.push(`[face: ${val.id}]`);
460
461
  break;
461
462
  case 'video':
462
463
  case 'image':
@@ -472,47 +473,47 @@ class Common {
472
473
  else {
473
474
  file = 'base64://...';
474
475
  }
475
- logs.push(`[${val.type}:${file}]`);
476
+ logs.push(`[${val.type}: ${file}]`);
476
477
  break;
477
478
  }
478
479
  case 'at':
479
- logs.push(`[at:${val.uid}]`);
480
+ logs.push(`[at: ${val.uid}]`);
480
481
  break;
481
482
  case 'rps':
482
- logs.push(`[rps:${val.id}]`);
483
+ logs.push(`[rps: ${val.id}]`);
483
484
  break;
484
485
  case 'dice':
485
- logs.push(`[dice:${val.id}]`);
486
+ logs.push(`[dice: ${val.id}]`);
486
487
  break;
487
488
  case 'poke':
488
- logs.push(`[poke:${val.id}]`);
489
+ logs.push(`[poke: ${val.id}]`);
489
490
  break;
490
491
  case 'share':
491
- logs.push(`[share:${JSON.stringify(val)}]`);
492
+ logs.push(`[share: ${JSON.stringify(val)}]`);
492
493
  break;
493
494
  case 'contact':
494
- logs.push(`[contact:${JSON.stringify(val)}]`);
495
+ logs.push(`[contact: ${JSON.stringify(val)}]`);
495
496
  break;
496
497
  case 'location':
497
- logs.push(`[location:${JSON.stringify(val)}]`);
498
+ logs.push(`[location: ${JSON.stringify(val)}]`);
498
499
  break;
499
500
  case 'music':
500
- logs.push(`[music:${JSON.stringify(val)}]`);
501
+ logs.push(`[music: ${JSON.stringify(val)}]`);
501
502
  break;
502
503
  case 'reply':
503
- logs.push(`[reply:${val.message_id}]`);
504
+ logs.push(`[reply: ${val.message_id}]`);
504
505
  break;
505
506
  case 'forward':
506
- logs.push(`[forward:${val.res_id}]`);
507
+ logs.push(`[forward: ${val.res_id}]`);
507
508
  break;
508
509
  case 'xml':
509
- logs.push(`[xml:${val.data}]`);
510
+ logs.push(`[xml: ${val.data}]`);
510
511
  break;
511
512
  case 'json':
512
- logs.push(`[json:${val.data}]`);
513
+ logs.push(`[json: ${val.data}]`);
513
514
  break;
514
515
  case 'markdown': {
515
- logs.push(`[markdown:${val.content}]`);
516
+ logs.push(`[markdown: ${val.content}]`);
516
517
  break;
517
518
  }
518
519
  case 'markdown_tpl': {
@@ -522,21 +523,21 @@ class Common {
522
523
  const content = { id: val.custom_template_id };
523
524
  for (const v of params)
524
525
  content[v.key] = v.values[0];
525
- logs.push(`[markdown_tpl:${JSON.stringify(content)}]`);
526
+ logs.push(`[markdown_tpl: ${JSON.stringify(content)}]`);
526
527
  break;
527
528
  }
528
529
  case 'keyboard': {
529
- logs.push(`[rows:${JSON.stringify(val.rows)}]`);
530
+ logs.push(`[rows: ${JSON.stringify(val.rows)}]`);
530
531
  break;
531
532
  }
532
533
  case 'button':
533
- logs.push(`[button:${JSON.stringify(val.data)}]`);
534
+ logs.push(`[button: ${JSON.stringify(val.data)}]`);
534
535
  break;
535
536
  case 'long_msg':
536
- logs.push(`[long_msg:${val.id}]`);
537
+ logs.push(`[long_msg: ${val.id}]`);
537
538
  break;
538
539
  default:
539
- logs.push(`[未知:${JSON.stringify(val)}]`);
540
+ logs.push(`[未知: ${JSON.stringify(val)}]`);
540
541
  }
541
542
  }
542
543
  return logs.join('');
@@ -95,7 +95,7 @@ export declare const config: {
95
95
  changeApp(): Promise<void>;
96
96
  changeCfg(): Promise<void>;
97
97
  changeGroup(): Promise<void>;
98
- "__#2@#review"(): Promise<void>;
98
+ "__#15@#review"(): Promise<void>;
99
99
  };
100
100
  export declare const Cfg: {
101
101
  /**
@@ -189,5 +189,5 @@ export declare const Cfg: {
189
189
  changeApp(): Promise<void>;
190
190
  changeCfg(): Promise<void>;
191
191
  changeGroup(): Promise<void>;
192
- "__#2@#review"(): Promise<void>;
192
+ "__#15@#review"(): Promise<void>;
193
193
  };
@@ -1,21 +1,7 @@
1
- import { PluginType, PluginApps } from '../../types/index.js';
2
1
  /**
3
2
  * 事件处理器类
4
3
  */
5
4
  export declare const handler: {
6
- /**
7
- * 添加事件处理器
8
- * @param index 插件索引
9
- * @param Class 插件类
10
- */
11
- add(index: string, Class: PluginType | PluginApps): Promise<void>;
12
- /**
13
- * 删除事件处理器
14
- * 如果不传参数则删除所有处理器
15
- * @param index 插件索引
16
- * @param key 事件键
17
- */
18
- del(index?: string, key?: string): boolean;
19
5
  /**
20
6
  * 调用事件处理器
21
7
  * @param key 事件键
@@ -1,70 +1,9 @@
1
- import lodash from 'lodash';
2
1
  import logger from './logger.js';
3
2
  import { pluginLoader as loader } from '../../core/index.js';
4
3
  /**
5
4
  * 事件处理器类
6
5
  */
7
6
  export const handler = new (class EventHandler {
8
- /**
9
- * 添加事件处理器
10
- * @param index 插件索引
11
- * @param Class 插件类
12
- */
13
- async add(index, Class) {
14
- lodash.forEach(Class.handler, val => {
15
- if (!val.key)
16
- logger.error(`[Handler][Add]: [${Class.name}] 缺少 key`);
17
- if (!val.fnc)
18
- logger.error(`[Handler][Add]: [${Class.name}] 缺少 fnc`);
19
- logger.debug(`[Handler][Reg]: [${Class.name}][${val.key}]`);
20
- if (!Array.isArray(loader.handlerIds[val.key]))
21
- loader.handlerIds[val.key] = [];
22
- loader.handlerIds[val.key].push({ index, fnc: val.fnc, priority: val.priority || Class.priority });
23
- loader.handlerIds[val.key] = lodash.orderBy(loader.handlerIds[val.key], ['priority'], ['asc']);
24
- });
25
- }
26
- /**
27
- * 删除事件处理器
28
- * 如果不传参数则删除所有处理器
29
- * @param index 插件索引
30
- * @param key 事件键
31
- */
32
- del(index = '', key = '') {
33
- /** 无参 */
34
- if (!key && !index) {
35
- loader.handlerIds = {};
36
- return true;
37
- }
38
- /** 删除指定索引插件 */
39
- if (!key) {
40
- for (const v of Object.keys(loader.handlerIds)) {
41
- loader.handlerIds[v] = loader.handlerIds[v].filter(v => v.index !== index);
42
- // 如果处理器为空则删除键
43
- if (!loader.handlerIds[v].length) {
44
- delete loader.handlerIds[v];
45
- }
46
- else {
47
- loader.handlerIds[v] = lodash.orderBy(loader.handlerIds[v], ['priority'], ['asc']);
48
- }
49
- }
50
- return true;
51
- }
52
- /** 删除指定key */
53
- if (!index) {
54
- loader.handlerIds[key] && delete loader.handlerIds[key];
55
- return true;
56
- }
57
- /** 删除指定key的index */
58
- if (!loader.handlerIds[key])
59
- return false;
60
- loader.handlerIds[key] = loader.handlerIds[key].filter(v => v.index !== index);
61
- if (!loader.handlerIds[key].length) {
62
- delete loader.handlerIds[key];
63
- return true;
64
- }
65
- loader.handlerIds[key] = lodash.orderBy(loader.handlerIds[key], ['priority'], ['asc']);
66
- return true;
67
- }
68
7
  /**
69
8
  * 调用事件处理器
70
9
  * @param key 事件键
@@ -72,8 +11,8 @@ export const handler = new (class EventHandler {
72
11
  */
73
12
  async call(key, args) {
74
13
  let res;
75
- for (const v of loader.handlerIds[key] || []) {
76
- const info = loader.PluginList[v.index];
14
+ for (const info of loader.handler[key] || []) {
15
+ const plugin = loader.plugin[info.key];
77
16
  try {
78
17
  let done = true;
79
18
  /**
@@ -82,26 +21,18 @@ export const handler = new (class EventHandler {
82
21
  */
83
22
  const reject = (msg = '') => {
84
23
  if (msg)
85
- logger.mark(`[Handler][Reject]: [${info.file.dir}][${info.file.name}][${key}] ${msg}`);
24
+ logger.mark(`[Handler][Reject]: [${plugin.plugin}][${info.name}][${key}] ${msg}`);
86
25
  done = false;
87
26
  };
88
- if (info.file.type === 'function' && typeof v.fnc === 'function') {
89
- res = await v.fnc(args, reject);
90
- }
91
- else {
92
- const cla = new info.file.Fnc();
93
- if (args.e)
94
- cla.e = args.e;
95
- res = await cla[v.fnc](args, reject);
96
- }
27
+ res = await info.fn(args, reject);
97
28
  if (done) {
98
- logger.mark(`[Handler][Done]: [${info.file.dir}][${info.file.name}][${key}]`);
29
+ logger.mark(`[Handler][Done]: [${plugin.plugin}][${info.name}][${key}]`);
99
30
  return res;
100
31
  }
101
32
  }
102
33
  catch (e) {
103
34
  // 产生错误继续下一个处理器
104
- logger.error(`[Handler][Error]: [${info.file.dir}][${info.file.name}][${key}] ${e}`);
35
+ logger.error(`[Handler][Error]: [${plugin.plugin}][${info.name}][${key}] ${e}`);
105
36
  }
106
37
  }
107
38
  return res;
@@ -110,6 +41,6 @@ export const handler = new (class EventHandler {
110
41
  * 检查是否存在指定键的事件处理器
111
42
  */
112
43
  has(key) {
113
- return !!loader.handlerIds[key];
44
+ return !!loader.handler[key];
114
45
  }
115
46
  })();
@@ -1,2 +1,2 @@
1
1
  import { KarinMessageType } from '../../types/index.js';
2
- export declare const button: (e: KarinMessageType) => Promise<any>;
2
+ export declare const button: (msg: string, e?: KarinMessageType) => Promise<any>;
@@ -1,35 +1,24 @@
1
1
  import logger from '../core/logger.js';
2
2
  import { pluginLoader as loader } from '../../core/index.js';
3
- export const button = async (e) => {
3
+ export const button = async (msg, e) => {
4
4
  const button = [];
5
- for (const v of loader.buttonIds) {
6
- const info = loader.PluginList[v];
7
- for (const v of info.button) {
8
- const reg = v.reg;
9
- if (reg.test(e.msg)) {
10
- try {
11
- let res;
12
- let done = true;
13
- /**
14
- * 标记函数 如果调用则继续执行 循环下一个按钮插件处理
15
- */
16
- const reject = () => { done = false; };
17
- if (typeof v.fnc === 'function') {
18
- res = await v.fnc(e, reject);
19
- }
20
- else {
21
- const cla = new info.file.Fnc();
22
- cla.e = e;
23
- res = await cla[v.fnc](e, reject);
24
- }
25
- if (res)
26
- button.push(res);
27
- if (done)
28
- return res;
29
- }
30
- catch (error) {
31
- logger.error(error);
32
- }
5
+ for (const info of loader.button) {
6
+ const reg = info.reg;
7
+ if (reg.test(msg)) {
8
+ try {
9
+ let done = true;
10
+ /**
11
+ * 标记函数 如果调用则继续执行 循环下一个按钮插件处理
12
+ */
13
+ const reject = () => { done = false; };
14
+ const res = await info.fn(reject, e);
15
+ if (res)
16
+ button.push(res);
17
+ if (done)
18
+ return res;
19
+ }
20
+ catch (error) {
21
+ logger.error(error);
33
22
  }
34
23
  }
35
24
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-karin",
3
- "version": "0.10.6",
3
+ "version": "0.11.0",
4
4
  "private": false,
5
5
  "description": "基于 Kritor 进行开发的nodejs机器人框架",
6
6
  "homepage": "https://github.com/KarinJS/Karin",
@@ -1,19 +0,0 @@
1
- import { dirName, fileName, PluginApps } from '../../types/index.js';
2
- export interface PluginAppType {
3
- file?: {
4
- dir?: dirName;
5
- name?: fileName;
6
- type?: PluginApps['file']['type'];
7
- fnc?: PluginApps['file']['Fnc'];
8
- };
9
- name?: string;
10
- event?: PluginApps['event'];
11
- priority?: number;
12
- accept?: boolean | Function;
13
- log?: boolean;
14
- rule?: PluginApps['rule'];
15
- task?: PluginApps['task'];
16
- handler?: PluginApps['handler'];
17
- button?: PluginApps['button'];
18
- }
19
- export default function PluginApp(options: PluginAppType): PluginApps;
@@ -1,19 +0,0 @@
1
- export default function PluginApp(options) {
2
- return {
3
- file: {
4
- dir: options?.file?.dir || '',
5
- name: options?.file?.name || '',
6
- type: options?.file?.type || 'function',
7
- Fnc: options?.file?.fnc || '',
8
- },
9
- name: options.name || '',
10
- event: options.event || "message" /* EventType.Message */,
11
- priority: options.priority || 10000,
12
- accept: options.accept ?? false,
13
- log: options.log ?? true,
14
- rule: options.rule || [],
15
- task: options.task || [],
16
- handler: options.handler || [],
17
- button: options.button || [],
18
- };
19
- }