node-karin 0.11.4 → 0.11.5
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/lib/cli/karin.js +48 -28
- package/lib/core/init/config.js +1 -1
- package/lib/core/karin/karin.d.ts +6 -3
- package/lib/core/listener/listener.js +10 -3
- package/lib/core/plugin/loader.d.ts +1 -1
- package/lib/core/plugin/loader.js +10 -11
- package/lib/event/handler/base.js +15 -6
- package/lib/event/handler/message.js +8 -1
- package/lib/event/handler/review.js +3 -3
- package/lib/types/plugin/plugin.d.ts +28 -24
- package/lib/utils/common/common.d.ts +10 -0
- package/lib/utils/common/common.js +28 -2
- package/lib/utils/core/handler.js +1 -1
- package/package.json +4 -4
package/lib/cli/karin.js
CHANGED
|
@@ -175,14 +175,12 @@ class KarinCli {
|
|
|
175
175
|
async update () {
|
|
176
176
|
/** 屏蔽的依赖包列表 */
|
|
177
177
|
const pkgdependencies = [
|
|
178
|
-
'@grpc/grpc-js',
|
|
179
|
-
'@grpc/proto-loader',
|
|
180
178
|
'art-template',
|
|
181
179
|
'axios',
|
|
182
180
|
'chalk',
|
|
183
181
|
'chokidar',
|
|
182
|
+
'commander',
|
|
184
183
|
'express',
|
|
185
|
-
'kritor-proto',
|
|
186
184
|
'level',
|
|
187
185
|
'lodash',
|
|
188
186
|
'log4js',
|
|
@@ -192,38 +190,23 @@ class KarinCli {
|
|
|
192
190
|
'ws',
|
|
193
191
|
'yaml',
|
|
194
192
|
]
|
|
195
|
-
let cmd = ''
|
|
196
193
|
const list = Object.keys(this.pkg(false).dependencies).filter(key => !pkgdependencies.includes(key))
|
|
197
194
|
/** 获取包管理器 */
|
|
198
195
|
const pkg = new KarinCfgInit().getRegistry()
|
|
199
|
-
|
|
200
|
-
case 'pnpm': {
|
|
201
|
-
cmd = 'pnpm update'
|
|
202
|
-
break
|
|
203
|
-
}
|
|
204
|
-
case 'yarn': {
|
|
205
|
-
cmd = 'yarn upgrade'
|
|
206
|
-
break
|
|
207
|
-
}
|
|
208
|
-
case 'npm': {
|
|
209
|
-
cmd = 'npm update'
|
|
210
|
-
break
|
|
211
|
-
}
|
|
212
|
-
case 'cnpm': {
|
|
213
|
-
cmd = 'cnpm update'
|
|
214
|
-
break
|
|
215
|
-
}
|
|
216
|
-
}
|
|
196
|
+
const cmd = pkg === 'yarn' ? 'yarn upgrade' : `${pkg} update`
|
|
217
197
|
/** 异步并发更新依赖 */
|
|
218
198
|
await Promise.all(list.map(async (item) => {
|
|
219
199
|
try {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
200
|
+
/** 检查是否已经是最新版本 */
|
|
201
|
+
const local = await this.getLocalVersion(item, pkg)
|
|
202
|
+
const remote = await this.getRemoteVersion(item, pkg)
|
|
203
|
+
if (local === remote) {
|
|
223
204
|
console.log(`[依赖更新] ${item} 已经是最新~`)
|
|
224
|
-
|
|
225
|
-
console.log(`[依赖更新] ${item} 更新完成~`)
|
|
205
|
+
return
|
|
226
206
|
}
|
|
207
|
+
console.log(`[依赖更新] ${item} 当前版本: ${local} 最新版本: ${remote}`)
|
|
208
|
+
await this.exec(`${cmd} ${item}@latest`)
|
|
209
|
+
console.log(`[依赖更新] ${item} 更新完成~`)
|
|
227
210
|
} catch (error) {
|
|
228
211
|
console.error(`[依赖更新] ${item} 更新失败:`)
|
|
229
212
|
console.error(`error.stack: ${error.stack}`)
|
|
@@ -233,6 +216,43 @@ class KarinCli {
|
|
|
233
216
|
console.log('所有依赖已更新完成~')
|
|
234
217
|
}
|
|
235
218
|
|
|
219
|
+
/**
|
|
220
|
+
* 获取指定包的本地版本
|
|
221
|
+
* @param name - 包名
|
|
222
|
+
* @param pkg - 包管理器
|
|
223
|
+
* @returns - 版本号
|
|
224
|
+
*/
|
|
225
|
+
async getLocalVersion (name, pkg) {
|
|
226
|
+
const cmd = pkg === 'yarn' ? `yarn list --pattern ${name}` : `${pkg} list ${name} --depth=0`
|
|
227
|
+
const text = await this.exec(cmd)
|
|
228
|
+
/** pnpm特殊处理 */
|
|
229
|
+
if (pkg === 'pnpm') {
|
|
230
|
+
const reg = new RegExp(`${name}\\s+([\\d.]+)`, 'gm')
|
|
231
|
+
const res = reg.exec(text)
|
|
232
|
+
return res?.[1] || '0.0.0'
|
|
233
|
+
}
|
|
234
|
+
const reg = new RegExp(`${name}@(\\d+\\.\\d+\\.\\d+)`, 'gm')
|
|
235
|
+
const res = reg.exec(text)
|
|
236
|
+
return res?.[1] || '0.0.0'
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 获取指定包的最新版本
|
|
241
|
+
* @param name - 包名
|
|
242
|
+
* @param pkg - 包管理器
|
|
243
|
+
*/
|
|
244
|
+
async getRemoteVersion (name, pkg) {
|
|
245
|
+
const cmd = `${pkg} info ${name} version`
|
|
246
|
+
const text = await this.exec(cmd)
|
|
247
|
+
/** yarn特殊处理 */
|
|
248
|
+
if (pkg === 'yarn') {
|
|
249
|
+
const lines = text.split('\n').map(line => line.trim())
|
|
250
|
+
const ver = lines.find(line => /^\d+\.\d+\.\d+$/.test(line))
|
|
251
|
+
return ver || ''
|
|
252
|
+
}
|
|
253
|
+
return text.trim()
|
|
254
|
+
}
|
|
255
|
+
|
|
236
256
|
/**
|
|
237
257
|
* 封装exec
|
|
238
258
|
* @param cmd - 命令
|
|
@@ -240,7 +260,7 @@ class KarinCli {
|
|
|
240
260
|
exec (cmd) {
|
|
241
261
|
return new Promise((resolve, reject) => {
|
|
242
262
|
execCmd(cmd, (error, stdout, stderr) => {
|
|
243
|
-
if (stdout) { return resolve(stdout) }
|
|
263
|
+
if (stdout) { return resolve(stdout.trim()) }
|
|
244
264
|
if (error) { return reject(error) }
|
|
245
265
|
return reject(stderr)
|
|
246
266
|
})
|
package/lib/core/init/config.js
CHANGED
|
@@ -154,7 +154,7 @@ export class KarinCfgInit {
|
|
|
154
154
|
console.log('检测到已安装pnpm,开始安装依赖...');
|
|
155
155
|
}
|
|
156
156
|
/** 安装依赖 */
|
|
157
|
-
if (!(await this.shell(`${type} -P --force`))) {
|
|
157
|
+
if (!(await this.shell(`${type} install -P --force`))) {
|
|
158
158
|
console.log('安装依赖失败,请手动安装依赖!');
|
|
159
159
|
console.log(`可尝试手动执行 【 ${type} install -P 】 安装依赖~`);
|
|
160
160
|
console.log('如中国大陆用户安装失败,请尝试执行换源 【 npm config set registry https://registry.npmmirror.com 】后再安装依赖~');
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Contact, KarinElement, KarinMessage, KarinRenderType, PermissionType, RenderResult, KarinNoticeType, KarinRequestType, KarinMessageType, AllMessageSubType, CommandInfo, TaskInfo, HandlerInfo, AcceptInfo, UseInfo, AllNoticeSubType, AllRequestSubType } from '../../types/index.js';
|
|
2
2
|
type FncFunction = (e: KarinMessage) => Promise<boolean>;
|
|
3
3
|
type FncElement = string | KarinElement | Array<KarinElement>;
|
|
4
|
+
type UseReceive = (e: KarinMessageType, next: Function, exit: Function) => Promise<void>;
|
|
5
|
+
type UseReply = (e: KarinMessageType, element: KarinElement[], next: Function, exit: Function) => Promise<void>;
|
|
6
|
+
type UseRecord = (uid: string, contact: Contact, elements: KarinElement[], next: Function, exit: Function) => Promise<void>;
|
|
4
7
|
/**
|
|
5
8
|
* 中间件类型
|
|
6
9
|
*/
|
|
@@ -156,9 +159,9 @@ export declare class Karin {
|
|
|
156
159
|
* @param fn - 实现函数
|
|
157
160
|
*/
|
|
158
161
|
accept(event: AllNoticeSubType | AllRequestSubType, fn: (e: KarinNoticeType | KarinRequestType) => Promise<boolean>, options?: Options): AcceptInfo;
|
|
159
|
-
use(type: `${MiddlewareType.ReceiveMsg}`, fn:
|
|
160
|
-
use(type: `${MiddlewareType.ReplyMsg}`, fn:
|
|
161
|
-
use(type: `${MiddlewareType.SendMsg}`, fn:
|
|
162
|
+
use(type: `${MiddlewareType.ReceiveMsg}`, fn: UseReceive, options?: Omit<Options, 'log'>): UseInfo;
|
|
163
|
+
use(type: `${MiddlewareType.ReplyMsg}`, fn: UseReply, options?: Omit<Options, 'log'>): UseInfo;
|
|
164
|
+
use(type: `${MiddlewareType.SendMsg}`, fn: UseRecord, options?: Omit<Options, 'log'>): UseInfo;
|
|
162
165
|
/**
|
|
163
166
|
* - 启动
|
|
164
167
|
*/
|
|
@@ -176,12 +176,21 @@ export class Listeners extends EventEmitter {
|
|
|
176
176
|
* @param options.retry_count - 重试次数
|
|
177
177
|
*/
|
|
178
178
|
async sendMsg(uid, contact, elements, options = { recallMsg: 0, retry_count: 1 }) {
|
|
179
|
+
/** 结果 */
|
|
180
|
+
let result = {};
|
|
179
181
|
/** 先调用中间件 */
|
|
180
182
|
for (const info of pluginLoader.use.sendMsg) {
|
|
181
183
|
try {
|
|
182
184
|
let next = false;
|
|
185
|
+
let exit = false;
|
|
183
186
|
const nextFn = () => { next = true; };
|
|
184
|
-
|
|
187
|
+
const exitFn = () => { exit = true; };
|
|
188
|
+
await info.fn(uid, contact, elements, nextFn, exitFn);
|
|
189
|
+
if (exit) {
|
|
190
|
+
const plugin = pluginLoader.plugin.get(info.key);
|
|
191
|
+
logger.debug(`[消息中间件][${plugin.plugin}][${plugin.file}] 主动操作退出`);
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
185
194
|
if (!next)
|
|
186
195
|
break;
|
|
187
196
|
}
|
|
@@ -196,8 +205,6 @@ export class Listeners extends EventEmitter {
|
|
|
196
205
|
const { recallMsg, retry_count } = options;
|
|
197
206
|
/** 标准化 */
|
|
198
207
|
const NewElements = common.makeMessage(elements);
|
|
199
|
-
/** 结果 */
|
|
200
|
-
let result = {};
|
|
201
208
|
const reply_log = common.makeMessageLog(NewElements);
|
|
202
209
|
const self_id = bot.account.uid || bot.account.uin;
|
|
203
210
|
if (contact.scene === 'group') {
|
|
@@ -49,7 +49,7 @@ class PluginLoader {
|
|
|
49
49
|
this.button = [];
|
|
50
50
|
this.command = [];
|
|
51
51
|
this.handler = {};
|
|
52
|
-
this.plugin =
|
|
52
|
+
this.plugin = new Map();
|
|
53
53
|
this.task = [];
|
|
54
54
|
this.use = {
|
|
55
55
|
recvMsg: [],
|
|
@@ -312,7 +312,7 @@ class PluginLoader {
|
|
|
312
312
|
try {
|
|
313
313
|
const index = ++this.index;
|
|
314
314
|
/** 缓存基本信息 */
|
|
315
|
-
this.plugin
|
|
315
|
+
this.plugin.set(index, { type, plugin, path: _path, file });
|
|
316
316
|
const list = [];
|
|
317
317
|
let rootPath = 'file://' + path.join(process.cwd(), type === 'npm' ? 'node_modules' : 'plugins', plugin, _path, file);
|
|
318
318
|
if (isOrderBy)
|
|
@@ -422,7 +422,7 @@ class PluginLoader {
|
|
|
422
422
|
name: info.name,
|
|
423
423
|
event: info.event,
|
|
424
424
|
fn: info.fn,
|
|
425
|
-
key: index
|
|
425
|
+
key: index,
|
|
426
426
|
log: info.log,
|
|
427
427
|
rank: info.rank,
|
|
428
428
|
});
|
|
@@ -433,7 +433,7 @@ class PluginLoader {
|
|
|
433
433
|
name: info.name,
|
|
434
434
|
reg: info.reg,
|
|
435
435
|
fn: info.fn,
|
|
436
|
-
key: index
|
|
436
|
+
key: index,
|
|
437
437
|
rank: info.rank,
|
|
438
438
|
});
|
|
439
439
|
return true;
|
|
@@ -444,7 +444,7 @@ class PluginLoader {
|
|
|
444
444
|
this.handler[info.key].push({
|
|
445
445
|
name: info.name,
|
|
446
446
|
fn: info.fn,
|
|
447
|
-
key: index
|
|
447
|
+
key: index,
|
|
448
448
|
rank: info.rank,
|
|
449
449
|
});
|
|
450
450
|
return true;
|
|
@@ -456,7 +456,7 @@ class PluginLoader {
|
|
|
456
456
|
event: info.event,
|
|
457
457
|
fn: info.fn,
|
|
458
458
|
fnname: info.fnname,
|
|
459
|
-
key: index
|
|
459
|
+
key: index,
|
|
460
460
|
log: info.log,
|
|
461
461
|
perm: info.perm,
|
|
462
462
|
rank: info.rank,
|
|
@@ -470,7 +470,7 @@ class PluginLoader {
|
|
|
470
470
|
name: info.name,
|
|
471
471
|
cron: info.cron,
|
|
472
472
|
fn: info.fn,
|
|
473
|
-
key: index
|
|
473
|
+
key: index,
|
|
474
474
|
taskname: info.fnname,
|
|
475
475
|
data: App,
|
|
476
476
|
log: info.log,
|
|
@@ -498,7 +498,7 @@ class PluginLoader {
|
|
|
498
498
|
this.use[info.key].push({
|
|
499
499
|
name: info.name,
|
|
500
500
|
fn: info.fn,
|
|
501
|
-
key: index
|
|
501
|
+
key: index,
|
|
502
502
|
rank: info.rank,
|
|
503
503
|
});
|
|
504
504
|
return true;
|
|
@@ -530,11 +530,10 @@ class PluginLoader {
|
|
|
530
530
|
* 卸载插件
|
|
531
531
|
*/
|
|
532
532
|
uninstallApp(plugin, _path, file) {
|
|
533
|
-
|
|
534
|
-
const info = this.plugin[key];
|
|
533
|
+
this.plugin.forEach((info, key) => {
|
|
535
534
|
if (info.plugin === plugin && info.path === _path && info.file === file) {
|
|
536
535
|
/** 删除缓存 */
|
|
537
|
-
|
|
536
|
+
this.plugin.delete(key);
|
|
538
537
|
this.accept = this.accept.filter(val => val.key !== key);
|
|
539
538
|
this.button = this.button.filter(val => val.key !== key);
|
|
540
539
|
this.command = this.command.filter(val => val.key !== key);
|
|
@@ -132,13 +132,27 @@ export class EventBaseHandler {
|
|
|
132
132
|
* @param options 回复选项
|
|
133
133
|
*/
|
|
134
134
|
this.e.reply = async (elements = '', options = { reply: false, recallMsg: 0, at: false, retry_count: 1 }) => {
|
|
135
|
+
const request = {
|
|
136
|
+
message_id: '',
|
|
137
|
+
message_time: 0,
|
|
138
|
+
raw_data: undefined,
|
|
139
|
+
};
|
|
135
140
|
const message = common.makeMessage(elements);
|
|
136
141
|
/** 先调用中间件 */
|
|
137
142
|
for (const info of pluginLoader.use.replyMsg) {
|
|
138
143
|
try {
|
|
139
144
|
let next = false;
|
|
145
|
+
let exit = false;
|
|
140
146
|
const nextFn = () => { next = true; };
|
|
141
|
-
|
|
147
|
+
const exitFn = () => { exit = true; };
|
|
148
|
+
await info.fn(this.e, message, nextFn, exitFn);
|
|
149
|
+
if (exit) {
|
|
150
|
+
const plugin = pluginLoader.plugin.get(info.key);
|
|
151
|
+
logger.debug(`[消息中间件][${plugin.plugin}][${plugin.file}] 主动操作退出`);
|
|
152
|
+
return request;
|
|
153
|
+
}
|
|
154
|
+
if (!next)
|
|
155
|
+
break;
|
|
142
156
|
if (!next)
|
|
143
157
|
break;
|
|
144
158
|
}
|
|
@@ -162,11 +176,6 @@ export class EventBaseHandler {
|
|
|
162
176
|
else {
|
|
163
177
|
this.e.self_id !== 'input' && logger.bot('info', this.e.self_id, `${logger.green(`Send private ${this.e.user_id}: `)}${ReplyLog}`);
|
|
164
178
|
}
|
|
165
|
-
const request = {
|
|
166
|
-
message_id: '',
|
|
167
|
-
message_time: 0,
|
|
168
|
-
raw_data: undefined,
|
|
169
|
-
};
|
|
170
179
|
try {
|
|
171
180
|
listener.emit('karin:count:send', 1);
|
|
172
181
|
/** 取结果 */
|
|
@@ -199,8 +199,15 @@ export class MessageHandler extends EventBaseHandler {
|
|
|
199
199
|
for (const info of pluginLoader.use.recvMsg) {
|
|
200
200
|
try {
|
|
201
201
|
let next = false;
|
|
202
|
+
let exit = false;
|
|
202
203
|
const nextFn = () => { next = true; };
|
|
203
|
-
|
|
204
|
+
const exitFn = () => { exit = true; };
|
|
205
|
+
await info.fn(this.e, nextFn, exitFn);
|
|
206
|
+
if (exit) {
|
|
207
|
+
const plugin = pluginLoader.plugin.get(info.key);
|
|
208
|
+
logger.debug(`[消息中间件][${plugin.plugin}][${plugin.file}] 主动操作退出`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
204
211
|
if (!next)
|
|
205
212
|
break;
|
|
206
213
|
}
|
|
@@ -194,7 +194,7 @@ export const review = new (class Handler {
|
|
|
194
194
|
/** 同时启用 */
|
|
195
195
|
if (this.App.GroupConfig.enable && this.App.GroupConfig.disable) {
|
|
196
196
|
this.PluginEnable = (app, config) => {
|
|
197
|
-
const plugin = pluginLoader.plugin
|
|
197
|
+
const plugin = pluginLoader.plugin.get(app.key);
|
|
198
198
|
/** 白名单不为空 */
|
|
199
199
|
if (Array.isArray(config.enable) && config.enable.length) {
|
|
200
200
|
/** 插件包是否处于功能白名单 */
|
|
@@ -229,7 +229,7 @@ export const review = new (class Handler {
|
|
|
229
229
|
/** 白名单启用 */
|
|
230
230
|
if (this.App.GroupConfig.enable) {
|
|
231
231
|
this.PluginEnable = (app, config) => {
|
|
232
|
-
const plugin = pluginLoader.plugin
|
|
232
|
+
const plugin = pluginLoader.plugin.get(app.key);
|
|
233
233
|
if (Array.isArray(config.enable) && config.enable.length) {
|
|
234
234
|
for (const key of config.enable) {
|
|
235
235
|
if (key.plugin === plugin.plugin)
|
|
@@ -247,7 +247,7 @@ export const review = new (class Handler {
|
|
|
247
247
|
/** 黑名单启用 */
|
|
248
248
|
if (this.App.GroupConfig.disable) {
|
|
249
249
|
this.PluginEnable = (app, config) => {
|
|
250
|
-
const plugin = pluginLoader.plugin
|
|
250
|
+
const plugin = pluginLoader.plugin.get(app.key);
|
|
251
251
|
if (Array.isArray(config.disable) && config.disable.length) {
|
|
252
252
|
for (const key of config.disable) {
|
|
253
253
|
if (key.plugin === plugin.plugin) {
|
|
@@ -40,23 +40,21 @@ export declare const enum MethodType {
|
|
|
40
40
|
* plugin基本信息
|
|
41
41
|
*/
|
|
42
42
|
export interface PluginInfoType {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
file: string;
|
|
52
|
-
};
|
|
43
|
+
/** 插件包类型 */
|
|
44
|
+
type: `${AppsType}`;
|
|
45
|
+
/** 插件包名称 例: `karin-plugin-example` `@karinjs/adapter-qqbot` */
|
|
46
|
+
plugin: string;
|
|
47
|
+
/** 插件路径 在type为js下,path为空 */
|
|
48
|
+
path: string;
|
|
49
|
+
/** 插件文件名称 index.js index.ts */
|
|
50
|
+
file: string;
|
|
53
51
|
}
|
|
54
52
|
/**
|
|
55
53
|
* Command规则集信息
|
|
56
54
|
*/
|
|
57
55
|
export interface PluginCommandInfoType {
|
|
58
56
|
/** 插件基本信息的映射key */
|
|
59
|
-
key:
|
|
57
|
+
key: number;
|
|
60
58
|
/** 插件包名称 */
|
|
61
59
|
name: string;
|
|
62
60
|
/** 插件正则 */
|
|
@@ -83,7 +81,7 @@ export interface PluginCommandInfoType {
|
|
|
83
81
|
*/
|
|
84
82
|
export interface PluginAcceptInfoType {
|
|
85
83
|
/** 插件基本信息的映射key */
|
|
86
|
-
key:
|
|
84
|
+
key: number;
|
|
87
85
|
/** 插件包名称 */
|
|
88
86
|
name: string;
|
|
89
87
|
/** 插件执行方法 */
|
|
@@ -100,7 +98,7 @@ export interface PluginAcceptInfoType {
|
|
|
100
98
|
*/
|
|
101
99
|
export interface PluginTaskInfoType {
|
|
102
100
|
/** 插件基本信息的映射key */
|
|
103
|
-
key:
|
|
101
|
+
key: number;
|
|
104
102
|
/** 插件包名称 */
|
|
105
103
|
name: string;
|
|
106
104
|
/** 任务名称 */
|
|
@@ -121,7 +119,7 @@ export interface PluginTaskInfoType {
|
|
|
121
119
|
*/
|
|
122
120
|
export interface PluginButtonInfoType {
|
|
123
121
|
/** 插件基本信息的映射key */
|
|
124
|
-
key:
|
|
122
|
+
key: number;
|
|
125
123
|
/** 插件包名称 */
|
|
126
124
|
name: string;
|
|
127
125
|
/** 插件正则 */
|
|
@@ -136,7 +134,7 @@ export interface PluginButtonInfoType {
|
|
|
136
134
|
*/
|
|
137
135
|
export interface PluginHandlerInfoType {
|
|
138
136
|
/** 插件基本信息的映射key */
|
|
139
|
-
key:
|
|
137
|
+
key: number;
|
|
140
138
|
/** 插件包名称 */
|
|
141
139
|
name: string;
|
|
142
140
|
/** handler的处理方法 */
|
|
@@ -151,22 +149,24 @@ export interface PluginMiddlewareInfoType {
|
|
|
151
149
|
/** 初始化消息前 */
|
|
152
150
|
recvMsg: Array<{
|
|
153
151
|
/** 插件基本信息的映射key */
|
|
154
|
-
key:
|
|
152
|
+
key: number;
|
|
155
153
|
/** 插件包名称 */
|
|
156
154
|
name: string;
|
|
157
155
|
/** 插件执行方法 */
|
|
158
156
|
fn: (
|
|
159
157
|
/** 消息事件方法 */
|
|
160
158
|
e: KarinMessageType,
|
|
161
|
-
/**
|
|
162
|
-
next: Function
|
|
159
|
+
/** 是否继续执行下一个中间件 */
|
|
160
|
+
next: Function,
|
|
161
|
+
/** 是否退出此条消息 不再执行匹配插件 */
|
|
162
|
+
exit: Function) => Promise<boolean>;
|
|
163
163
|
/** 优先级 */
|
|
164
164
|
rank: number;
|
|
165
165
|
}>;
|
|
166
166
|
/** 回复消息前 */
|
|
167
167
|
replyMsg: Array<{
|
|
168
168
|
/** 插件基本信息的映射key */
|
|
169
|
-
key:
|
|
169
|
+
key: number;
|
|
170
170
|
/** 插件包名称 */
|
|
171
171
|
name: string;
|
|
172
172
|
/** 插件执行方法 */
|
|
@@ -175,15 +175,17 @@ export interface PluginMiddlewareInfoType {
|
|
|
175
175
|
e: KarinMessageType,
|
|
176
176
|
/** 回复的消息体 */
|
|
177
177
|
element: KarinElement[],
|
|
178
|
-
/**
|
|
179
|
-
next: Function
|
|
178
|
+
/** 是否继续执行下一个中间件 */
|
|
179
|
+
next: Function,
|
|
180
|
+
/** 是否不发送此条消息 */
|
|
181
|
+
exit: Function) => Promise<boolean>;
|
|
180
182
|
/** 优先级 */
|
|
181
183
|
rank: number;
|
|
182
184
|
}>;
|
|
183
185
|
/** 发送主动消息前 */
|
|
184
186
|
sendMsg: Array<{
|
|
185
187
|
/** 插件基本信息的映射key */
|
|
186
|
-
key:
|
|
188
|
+
key: number;
|
|
187
189
|
/** 插件包名称 */
|
|
188
190
|
name: string;
|
|
189
191
|
/** 插件执行方法 */
|
|
@@ -194,8 +196,10 @@ export interface PluginMiddlewareInfoType {
|
|
|
194
196
|
contact: Contact,
|
|
195
197
|
/** 发送的消息体 */
|
|
196
198
|
element: KarinElement[],
|
|
197
|
-
/**
|
|
198
|
-
next: Function
|
|
199
|
+
/** 是否继续执行下一个中间件 */
|
|
200
|
+
next: Function,
|
|
201
|
+
/** 是否不发送此条消息 */
|
|
202
|
+
exit: Function) => Promise<boolean>;
|
|
199
203
|
/** 优先级 */
|
|
200
204
|
rank: number;
|
|
201
205
|
}>;
|
|
@@ -85,6 +85,16 @@ declare class Common {
|
|
|
85
85
|
* - 写入yaml文件
|
|
86
86
|
*/
|
|
87
87
|
writeYaml(file: string, data: any): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* 输入包名 返回包根目录的绝对路径 仅简单查找
|
|
90
|
+
* @param name - 包名
|
|
91
|
+
* @param _path - 导入包的路径 此项适用于在插件中读取插件的依赖包
|
|
92
|
+
* @returns - 包根目录的绝对路径
|
|
93
|
+
* @example
|
|
94
|
+
* common.pkgroot('axios')
|
|
95
|
+
* common.pkgroot('axios', import.meta.url)
|
|
96
|
+
*/
|
|
97
|
+
pkgroot(name: string, _path?: string): string;
|
|
88
98
|
/**
|
|
89
99
|
* 根据文件后缀名从指定路径下读取符合要求的文件
|
|
90
100
|
* @param path - 路径
|
|
@@ -5,6 +5,7 @@ import axios from 'axios';
|
|
|
5
5
|
import lodash from 'lodash';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
|
+
import { createRequire } from 'module';
|
|
8
9
|
import { pipeline, Readable } from 'stream';
|
|
9
10
|
import { logger, segment, YamlEditor } from '../../utils/index.js';
|
|
10
11
|
/**
|
|
@@ -190,6 +191,32 @@ class Common {
|
|
|
190
191
|
return false;
|
|
191
192
|
}
|
|
192
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* 输入包名 返回包根目录的绝对路径 仅简单查找
|
|
196
|
+
* @param name - 包名
|
|
197
|
+
* @param _path - 导入包的路径 此项适用于在插件中读取插件的依赖包
|
|
198
|
+
* @returns - 包根目录的绝对路径
|
|
199
|
+
* @example
|
|
200
|
+
* common.pkgroot('axios')
|
|
201
|
+
* common.pkgroot('axios', import.meta.url)
|
|
202
|
+
*/
|
|
203
|
+
pkgroot(name, _path) {
|
|
204
|
+
const require = createRequire(_path || import.meta.url);
|
|
205
|
+
let dir = require.resolve(name);
|
|
206
|
+
if (fs.existsSync(path.join(dir, 'package.json')))
|
|
207
|
+
return path.resolve(dir);
|
|
208
|
+
/** 递归查找 如果跳过了node_modules 则返回null */
|
|
209
|
+
while (true) {
|
|
210
|
+
/** 向上 */
|
|
211
|
+
dir = path.dirname(dir);
|
|
212
|
+
if (fs.existsSync(path.join(dir, 'package.json')))
|
|
213
|
+
return path.resolve(dir);
|
|
214
|
+
/** 加个处理 防止无线递归 */
|
|
215
|
+
if (dir === path.dirname(dir)) {
|
|
216
|
+
throw new Error(`[common] 未找到包${name}的根目录`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
193
220
|
/**
|
|
194
221
|
* 根据文件后缀名从指定路径下读取符合要求的文件
|
|
195
222
|
* @param path - 路径
|
|
@@ -204,7 +231,6 @@ class Common {
|
|
|
204
231
|
const list = [];
|
|
205
232
|
if (!Array.isArray(ext))
|
|
206
233
|
ext = [ext];
|
|
207
|
-
// 排除文件夹 和不符合后缀名的文件
|
|
208
234
|
files.forEach(v => {
|
|
209
235
|
if (v.isDirectory())
|
|
210
236
|
return;
|
|
@@ -380,7 +406,7 @@ class Common {
|
|
|
380
406
|
*/
|
|
381
407
|
async getNpmPlugins(showDetails) {
|
|
382
408
|
/** 屏蔽的依赖包列表 */
|
|
383
|
-
const exclude = ['art-template', 'axios', 'chalk', 'chokidar', 'express', 'level', 'lodash', 'log4js', 'moment', 'node-karin', 'node-schedule', 'redis', 'ws', 'yaml'];
|
|
409
|
+
const exclude = ['art-template', 'axios', 'chalk', 'chokidar', 'commander', 'express', 'level', 'lodash', 'log4js', 'moment', 'node-karin', 'node-schedule', 'redis', 'ws', 'yaml'];
|
|
384
410
|
const pkg = this.readJson('./package.json');
|
|
385
411
|
const dependencies = Object.keys(pkg.dependencies).filter((name) => !exclude.includes(name));
|
|
386
412
|
if (!showDetails) {
|
|
@@ -12,7 +12,7 @@ export const handler = new (class EventHandler {
|
|
|
12
12
|
async call(key, args) {
|
|
13
13
|
let res;
|
|
14
14
|
for (const info of loader.handler[key] || []) {
|
|
15
|
-
const plugin = loader.plugin
|
|
15
|
+
const plugin = loader.plugin.get(info.key);
|
|
16
16
|
try {
|
|
17
17
|
let done = true;
|
|
18
18
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-karin",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "基于 Kritor 进行开发的nodejs机器人框架",
|
|
6
6
|
"homepage": "https://github.com/KarinJS/Karin",
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
},
|
|
141
141
|
"dependencies": {
|
|
142
142
|
"art-template": "4.13.2",
|
|
143
|
-
"axios": "1.7.
|
|
143
|
+
"axios": "1.7.3",
|
|
144
144
|
"chalk": "5.3.0",
|
|
145
145
|
"chokidar": "3.6.0",
|
|
146
146
|
"commander": "^12.1.0",
|
|
@@ -150,9 +150,9 @@
|
|
|
150
150
|
"log4js": "6.9.1",
|
|
151
151
|
"moment": "2.30.1",
|
|
152
152
|
"node-schedule": "2.1.1",
|
|
153
|
-
"redis": "4.
|
|
153
|
+
"redis": "4.7.0",
|
|
154
154
|
"ws": "8.18.0",
|
|
155
|
-
"yaml": "2.
|
|
155
|
+
"yaml": "2.5.0"
|
|
156
156
|
},
|
|
157
157
|
"devDependencies": {
|
|
158
158
|
"@types/express": "^4.17.21",
|