From fb0b980f362e4a541dcd283969b0cfe59c813daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=87=89=E8=8F=9C?= <1659488338@qq.com> Date: Mon, 17 Feb 2025 21:33:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=80=82=E9=85=8D=E5=99=A8=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/app.ts | 12 ++++-------- core/src/middleware.ts | 18 ++++-------------- core/src/plugin.ts | 2 +- core/src/prompt.ts | 6 +++--- packages/adapters/com-wechat/src/index.ts | 2 +- packages/adapters/dingtalk/src/index.ts | 2 +- packages/adapters/discord/src/index.ts | 2 +- packages/adapters/email/src/index.ts | 2 +- packages/adapters/icqq/src/index.ts | 2 +- packages/adapters/kritor/src/index.ts | 2 +- packages/adapters/onebot-11/src/index.ts | 2 +- packages/adapters/onebot-12/src/index.ts | 2 +- packages/adapters/qq/src/index.ts | 2 +- packages/adapters/web-wechat/src/index.ts | 2 +- packages/plugins/qa/src/index.ts | 2 +- packages/plugins/transfer/src/index.ts | 6 +++--- packages/services/github/src/index.ts | 2 +- test/package.json | 3 ++- test/plugins/foo.ts | 3 +-- test/plugins/test.ts | 8 +++++--- zhin/src/index.ts | 1 + zhin/src/plugins/commandParser.ts | 2 +- zhin/src/plugins/database/index.ts | 2 +- zhin/src/plugins/functionParser.ts | 2 +- zhin/src/plugins/processAdapter.ts | 2 +- zhin/src/plugins/setup.ts | 18 +++++++++++++++++- 26 files changed, 57 insertions(+), 52 deletions(-) diff --git a/core/src/app.ts b/core/src/app.ts index 31d5e7c3..fa15143b 100644 --- a/core/src/app.ts +++ b/core/src/app.ts @@ -112,11 +112,7 @@ export class App extends EventEmitter { return this.commandList.find(command => command.name === name); } - getSupportMiddlewares

( - adapter: Adapter

, - bot: Adapter.Bot

, - event: Message

, - ): Middleware

[] { + getSupportMiddlewares

({ bot, adapter }: Message

): Middleware

[] { return ( this.pluginList // 过滤不支持当前适配器的插件 @@ -139,9 +135,9 @@ export class App extends EventEmitter { .flatMap(plugin => plugin.commandList); } - handleMessage

(adapter: Adapter

, bot: Adapter.Bot

, event: Message

) { - const middleware = Middleware.compose(this.getSupportMiddlewares(adapter, bot, event)); - middleware(adapter, bot, event); + handleMessage

(event: Message

) { + const middleware = Middleware.compose(this.getSupportMiddlewares(event)); + middleware(event); } plugin(plugin: Plugin): this { diff --git a/core/src/middleware.ts b/core/src/middleware.ts index f408772b..dc430a0d 100644 --- a/core/src/middleware.ts +++ b/core/src/middleware.ts @@ -10,7 +10,7 @@ export namespace Middleware { for (const fn of middlewares) { if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!'); } - return (adapter: Adapter

, bot: Adapter.Bot

, event: Message

, next?: Next) => { + return (event: Message

, next?: Next) => { let index = -1; const dispatch: (i: number, ctx?: Message

) => Promise = (i: number, ctx: Message

= event) => { if (i <= index) return Promise.reject(new Error('next() called multiple times')); @@ -19,7 +19,7 @@ export namespace Middleware { if (i === middlewares.length) fn = next; if (!fn) return Promise.resolve(); try { - return Promise.resolve(fn(adapter, bot, ctx, dispatch.bind(null, i + 1))); + return Promise.resolve(fn(ctx, dispatch.bind(null, i + 1))); } catch (err) { return Promise.reject(err); } @@ -29,16 +29,6 @@ export namespace Middleware { } } export namespace Compose { - export type Middleware

= ( - adapter: Adapter

, - bot: Adapter.Bot

, - event: Message

, - next: Next, - ) => any; - export type ComposedMiddleware

= ( - adapter: Adapter

, - bot: Adapter.Bot

, - event: Message

, - next?: Next, - ) => Promise; + export type Middleware

= (event: Message

, next: Next) => any; + export type ComposedMiddleware

= (event: Message

, next?: Next) => Promise; } diff --git a/core/src/plugin.ts b/core/src/plugin.ts index 4431cf73..1b647205 100644 --- a/core/src/plugin.ts +++ b/core/src/plugin.ts @@ -55,7 +55,7 @@ export class Plugin extends EventEmitter { set display_name(name: string) { this.name = name; } - useConfig(configPath: string, schema: Schema): T | undefined { + useConfig(configPath: string, schema: Schema): T { if (schema.meta.type !== 'object') throw new Error(`config schema root must be type object`); const config = new Config(configPath, schema.meta.default as any); return schema(config.data); diff --git a/core/src/prompt.ts b/core/src/prompt.ts index 5e4889b4..ca99075d 100644 --- a/core/src/prompt.ts +++ b/core/src/prompt.ts @@ -31,7 +31,7 @@ export class Prompt

{ }); } middleware(callback: (input: string | Error) => any, timeout: number = 3 * 60 * 1000, timeoutText = '输入超时') { - const middleware: Middleware = (adapter, bot, event, next) => { + const middleware: Middleware = (event, next) => { if (this.getChannelAddress(event) !== this.getChannelAddress(this.event)) return next(); callback(event.raw_message); dispose(); @@ -214,7 +214,7 @@ export namespace Prompt { } export interface PickConfig { type: T; - defaultValue?: M extends true ? SingleMap[T] : SingleMap[T][]; + defaultValue?: PickResult; separator?: string; timeout?: number; options: PickOption[]; @@ -229,7 +229,7 @@ export namespace Prompt { export type Result = SingleMap[T]; export type Config = { tips: string; - defaultValue: any; + defaultValue?: R; timeout?: number; timeoutText?: string; format: (input: string) => R; diff --git a/packages/adapters/com-wechat/src/index.ts b/packages/adapters/com-wechat/src/index.ts index 066f7cd2..331f9a34 100644 --- a/packages/adapters/com-wechat/src/index.ts +++ b/packages/adapters/com-wechat/src/index.ts @@ -72,7 +72,7 @@ const messageHandler = (bot: WechatClient, event: ClientMessage) => { raw_message: ClientMessage.formatToString(event.message), message_type: event.detail_type as any, }); - adapter.app!.emit('message', adapter, bot, message); + adapter.app!.emit('message', message); }; const stopBots = () => { for (const bot of adapter.bots) { diff --git a/packages/adapters/dingtalk/src/index.ts b/packages/adapters/dingtalk/src/index.ts index cb3ef40c..ea2d584f 100644 --- a/packages/adapters/dingtalk/src/index.ts +++ b/packages/adapters/dingtalk/src/index.ts @@ -66,7 +66,7 @@ const messageHandler = (bot: Adapter.Bot<'dingtalk'>, event: DingMsgEvent) => { permissions: [], }, }); - dingTalkAdapter.app!.emit('message', dingTalkAdapter, bot, message); + dingTalkAdapter.app!.emit('message', message); }; const stopBots = () => { for (const bot of dingTalkAdapter.bots) { diff --git a/packages/adapters/discord/src/index.ts b/packages/adapters/discord/src/index.ts index e664c0dd..0ead5660 100644 --- a/packages/adapters/discord/src/index.ts +++ b/packages/adapters/discord/src/index.ts @@ -68,7 +68,7 @@ const messageHandler = (bot: Adapter.Bot<'discord'>, event: DiscordMessageEvent) raw_message: sendableToString(event.message).trim(), message_type: event.message_type, }); - discordAdapter.app!.emit('message', discordAdapter, bot, message); + discordAdapter.app!.emit('message', message); }; const stopBots = () => { for (const bot of discordAdapter.bots) { diff --git a/packages/adapters/email/src/index.ts b/packages/adapters/email/src/index.ts index 5aca619e..7b2fc710 100644 --- a/packages/adapters/email/src/index.ts +++ b/packages/adapters/email/src/index.ts @@ -52,7 +52,7 @@ const startBots = (configs: Adapter.BotConfig<'email'>[]) => { for (const config of configs) { const bot = new EmailClient(config) as Adapter.Bot<'email'>; bot.on('message', (message: Message<'email'>) => { - adapter.app?.emit('message', adapter, bot, message); + adapter.app?.emit('message', message); }); bot .start() diff --git a/packages/adapters/icqq/src/index.ts b/packages/adapters/icqq/src/index.ts index bc4c5503..3055de17 100644 --- a/packages/adapters/icqq/src/index.ts +++ b/packages/adapters/icqq/src/index.ts @@ -154,7 +154,7 @@ const startBots = async (configs: Adapter.BotConfig<'icqq'>[]) => { }; const messageHandler = (bot: QQClient, event: QQMessageEvent) => { const message = Message.from(icqqAdapter, bot, createMessageBase(event)); - icqqAdapter.app!.emit('message', icqqAdapter, bot, message); + icqqAdapter.app!.emit('message', message); }; const botLogin = async (bot: QQClient) => { return new Promise(resolve => { diff --git a/packages/adapters/kritor/src/index.ts b/packages/adapters/kritor/src/index.ts index 033ebcc3..bceb084a 100644 --- a/packages/adapters/kritor/src/index.ts +++ b/packages/adapters/kritor/src/index.ts @@ -50,7 +50,7 @@ const messageHandler = (bot: Adapter.Bot<'kritor'>, event: kritor.common.IPushMe }, }); bot.logger.info(`recv [${message.channel})]: ${message.raw_message}`); - adapter.app!.emit('message', adapter, bot, message); + adapter.app!.emit('message', message); }; const startBots = (configs: Adapter.BotConfig<'kritor'>[]) => { for (const config of configs) { diff --git a/packages/adapters/onebot-11/src/index.ts b/packages/adapters/onebot-11/src/index.ts index 3cf15c8c..10f2b395 100644 --- a/packages/adapters/onebot-11/src/index.ts +++ b/packages/adapters/onebot-11/src/index.ts @@ -71,7 +71,7 @@ const messageHandler = (bot: OneBotClient, event: MessageV11) => { }, message_type: event.message_type, }); - oneBotV11.app!.emit('message', oneBotV11, bot, message); + oneBotV11.app!.emit('message', message); }; const stopBots = () => { for (const bot of oneBotV11.bots) { diff --git a/packages/adapters/onebot-12/src/index.ts b/packages/adapters/onebot-12/src/index.ts index 1329e602..db568d7f 100644 --- a/packages/adapters/onebot-12/src/index.ts +++ b/packages/adapters/onebot-12/src/index.ts @@ -72,7 +72,7 @@ const messageHandler = (bot: OneBotClient, event: MessageV12) => { }, raw_message: MessageV12.formatToString(event.message), }); - oneBotV12Adapter.app!.emit('message', oneBotV12Adapter, bot, message); + oneBotV12Adapter.app!.emit('message', message); }; const stopBots = () => { for (const bot of oneBotV12Adapter.bots) { diff --git a/packages/adapters/qq/src/index.ts b/packages/adapters/qq/src/index.ts index 3d963014..8442104c 100644 --- a/packages/adapters/qq/src/index.ts +++ b/packages/adapters/qq/src/index.ts @@ -131,7 +131,7 @@ const messageHandler = (bot: QQClient, event: QQMessageEvent) => { if (event.source) { message.quote = event.source; } - qqAdapter.app!.emit('message', qqAdapter, bot, message); + qqAdapter.app!.emit('message', message); }; const stopBots = () => { for (const bot of qqAdapter.bots) { diff --git a/packages/adapters/web-wechat/src/index.ts b/packages/adapters/web-wechat/src/index.ts index b6ed1176..e1ed1029 100644 --- a/packages/adapters/web-wechat/src/index.ts +++ b/packages/adapters/web-wechat/src/index.ts @@ -58,7 +58,7 @@ const messageHandler = (bot: WechatClient, event: DingMsgEvent) => { permissions: [], }, }); - wechatAdapter.app!.emit('message', wechatAdapter, bot, message); + wechatAdapter.app!.emit('message', message); }; const stopBots = () => { for (const bot of wechatAdapter.bots) { diff --git a/packages/plugins/qa/src/index.ts b/packages/plugins/qa/src/index.ts index 3bc080f5..c4ddf7a1 100644 --- a/packages/plugins/qa/src/index.ts +++ b/packages/plugins/qa/src/index.ts @@ -175,7 +175,7 @@ qaCommand.command('问答详情 ').action(async (_, no) => { 2, )}`; }); -qaPlugin.middleware(async (adapter, bot, message, next) => { +qaPlugin.middleware(async (message, next) => { const beforeMessage = message.raw_message; await next(); const afterMessage = message.raw_message; diff --git a/packages/plugins/transfer/src/index.ts b/packages/plugins/transfer/src/index.ts index 2214c6aa..863021fa 100644 --- a/packages/plugins/transfer/src/index.ts +++ b/packages/plugins/transfer/src/index.ts @@ -65,17 +65,17 @@ transferPlugin }, }); }); -transferPlugin.middleware(async (adapter, bot, message, next) => { +transferPlugin.middleware(async (message, next) => { const transferList = await transferPlugin.database.get('transfer', []); const transfer = transferList.find( - transfer => transfer.from.adapter === adapter.name && transfer.from.bot_id === bot.unique_id, + transfer => transfer.from.adapter === message.adapter.name && transfer.from.bot_id === message.bot.unique_id, ); if (!transfer) return next(); const toAdapter = transferPlugin.app?.adapters.get(transfer.to.adapter); if (!toAdapter) return next(); const toBot = toAdapter.bots.find(b => b.unique_id === transfer.to.bot_id); if (!toBot) return next(); - adapter.app?.emit('message', toAdapter, toBot, message); + transferPlugin.app?.emit('message', message); return next(); }); export default transferPlugin; diff --git a/packages/services/github/src/index.ts b/packages/services/github/src/index.ts index 95c14bd0..9268b94d 100644 --- a/packages/services/github/src/index.ts +++ b/packages/services/github/src/index.ts @@ -16,7 +16,7 @@ const config = plugin.useConfig( }), ); plugin.mounted(app => { - plugin.middleware(async (_a, _b, message, next) => { + plugin.middleware(async (message, next) => { await next(); const mathReg = /^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/]+)\/([^/]+)\/?$/; const match = message.raw_message.match(mathReg); diff --git a/test/package.json b/test/package.json index c7ccd1e8..866ed7dd 100644 --- a/test/package.json +++ b/test/package.json @@ -31,6 +31,7 @@ "@zhinjs/plugin-schedule": "workspace:^", "@zhinjs/plugin-qa": "workspace:^", "@zhinjs/plugin-guild-manage": "workspace:^", - "@zhinjs/plugin-group-manage": "workspace:^" + "@zhinjs/plugin-group-manage": "workspace:^", + "@zhinjs/plugin-ollama": "workspace:^" } } diff --git a/test/plugins/foo.ts b/test/plugins/foo.ts index 9465561f..08dd1866 100644 --- a/test/plugins/foo.ts +++ b/test/plugins/foo.ts @@ -12,7 +12,6 @@ useCommand('bar') return '我不知道该说啥呀'; }); -registerMiddleware((_adapter, _bot, message, next) => { - // console.log(_adapter, _bot, message); +registerMiddleware((message, next) => { next(); }); diff --git a/test/plugins/test.ts b/test/plugins/test.ts index 64b79175..ddab2edf 100644 --- a/test/plugins/test.ts +++ b/test/plugins/test.ts @@ -1,9 +1,11 @@ import { Plugin, Message } from 'zhin'; import '@zhinjs/plugin-sandbox'; +import type {} from '@zhinjs/plugin-ollama'; import * as path from 'path'; import type {} from '@zhinjs/web'; const test = new Plugin('测试插件'); // 定义插件 +test.ollama.chat; test .command('test-confirm') // 插件功能 .hidden() @@ -84,15 +86,15 @@ test }) .join('\n==============\n'); }); -test.with('web', app => { +test.waitServices('web', app => { app.web.addEntry(path.resolve(__dirname, '../client/index.ts')); }); -test.with('register', async app => { +test.waitServices('register', async app => { app.register('hello', function (this: Message, foo, bar, isExist = false) { return `receive from ${this.message_type},args is ${foo},${bar},${isExist}`; }); }); -test.with('component', app => { +test.waitServices('component', app => { app.component({ name: 'test2', render(_, context) { diff --git a/zhin/src/index.ts b/zhin/src/index.ts index b734be6b..e13a640a 100644 --- a/zhin/src/index.ts +++ b/zhin/src/index.ts @@ -19,6 +19,7 @@ export { useCommand, waitServices, logger, + useConfig, } from './plugins/setup'; export * from './constants'; import { diff --git a/zhin/src/plugins/commandParser.ts b/zhin/src/plugins/commandParser.ts index 80451652..1ccc4a40 100644 --- a/zhin/src/plugins/commandParser.ts +++ b/zhin/src/plugins/commandParser.ts @@ -22,7 +22,7 @@ const executeCommand = async (message: Message) => { } }; const commandParser = new Plugin('commandParser'); -commandParser.middleware(async (_a, _b, message, next) => { +commandParser.middleware(async (message, next) => { const result = await executeCommand(message); if (result) return; return next(); diff --git a/zhin/src/plugins/database/index.ts b/zhin/src/plugins/database/index.ts index d054e1e3..c904ffe8 100644 --- a/zhin/src/plugins/database/index.ts +++ b/zhin/src/plugins/database/index.ts @@ -40,7 +40,7 @@ database.mounted(async app => { // 初始化用户、群表 await db.get('group', []); await db.get('user', []); - app.middleware(async (_a, _b, message, next) => { + app.middleware(async (message, next) => { const userInfo = await db.find('user', user => { return user.user_id === message.sender.user_id; }); diff --git a/zhin/src/plugins/functionParser.ts b/zhin/src/plugins/functionParser.ts index 90434f5a..a6b22486 100644 --- a/zhin/src/plugins/functionParser.ts +++ b/zhin/src/plugins/functionParser.ts @@ -133,7 +133,7 @@ plugin.mounted(app => { plugin.service('functions', functionManager.functions); plugin.service('register', functionManager.register); }); -plugin.middleware(async (_1, _2, event, next) => { +plugin.middleware(async (event, next) => { await next(); return plugin.functionManager.match(event); }); diff --git a/zhin/src/plugins/processAdapter.ts b/zhin/src/plugins/processAdapter.ts index 401a9608..96901ea0 100644 --- a/zhin/src/plugins/processAdapter.ts +++ b/zhin/src/plugins/processAdapter.ts @@ -27,7 +27,7 @@ processAdapter.on('start', () => { message_type: 'private', }); processAdapter.logger.info(`recv [${message.channel}]: ${message.raw_message}`); - processAdapter.app!.emit('message', processAdapter, bot, message); + processAdapter.app!.emit('message', message); }); setTimeout(() => { processAdapter.emit('bot-ready', bot); diff --git a/zhin/src/plugins/setup.ts b/zhin/src/plugins/setup.ts index 6feb8f6a..a749380b 100644 --- a/zhin/src/plugins/setup.ts +++ b/zhin/src/plugins/setup.ts @@ -1,4 +1,15 @@ -import { Adapter, Adapters, App, ArgsType, Command, getCallerStack, Message, Middleware, Plugin } from '@zhinjs/core'; +import { + Adapter, + Adapters, + App, + ArgsType, + Command, + getCallerStack, + Message, + Middleware, + Plugin, + Schema, +} from '@zhinjs/core'; import * as path from 'path'; const setup = new Plugin('setup'); const resolveCallerPlugin = (): [boolean, Plugin] => { @@ -83,6 +94,7 @@ export interface Context { message: string, source?: Message, ): Promise; + useConfig(configPath: string, schema: Schema): T; onMount(callback: Plugin.CallBack): Plugin; onUnmount(callback: Plugin.CallBack): Plugin; listen(event: E, callback: App.EventMap[E]): Plugin; @@ -103,6 +115,9 @@ export const context = { inject(name: T) { return context.plugin.service(name); }, + useConfig(configPath: string, schema: Schema): T { + return context.plugin.useConfig(configPath, schema); + }, waitServices(...args: [...T[], callabck: (app: App) => void]) { return context.plugin.waitServices(...args); }, @@ -202,6 +217,7 @@ export const sendDirectMessage = context.sendDirectMessage; export const onMount = context.onMount; export const onUnmount = context.onUnmount; export const listen = context.listen; +export const useConfig = context.useConfig; export const logger = { trace(message: any, ...args: any[]): void { context.plugin.logger.debug(message, ...args);