From 733a0f97e265bccde03620cb92e694d598fb99fd Mon Sep 17 00:00:00 2001 From: Shigma Date: Tue, 21 Jun 2022 21:10:04 +0800 Subject: [PATCH] fix(core): re-add missing context apis --- packages/core/package.json | 2 +- packages/core/src/command/index.ts | 9 +++--- packages/core/src/database.ts | 46 ++++++++++++++++++++------- packages/core/src/protocol/adapter.ts | 9 +++--- packages/core/src/protocol/index.ts | 9 +++--- packages/core/src/selector.ts | 41 ++++++------------------ packages/koishi/src/patch.ts | 2 +- 7 files changed, 60 insertions(+), 58 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index b5e7047032..273dbd5b1e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -36,7 +36,7 @@ }, "dependencies": { "@koishijs/utils": "^5.4.5", - "cordis": "^1.5.5", + "cordis": "^1.6.0", "fastest-levenshtein": "^1.0.12", "minato": "^1.2.1" } diff --git a/packages/core/src/command/index.ts b/packages/core/src/command/index.ts index d6e91bc31b..aec84957bb 100644 --- a/packages/core/src/command/index.ts +++ b/packages/core/src/command/index.ts @@ -17,7 +17,7 @@ interface CommandMap extends Map { } declare module 'cordis' { - interface Context extends Commander.Delegates { + interface Context extends Commander.Mixin { $commander: Commander } @@ -35,7 +35,7 @@ declare module 'cordis' { export namespace Commander { export interface Config {} - export interface Delegates { + export interface Mixin { command(def: D, config?: Command.Config): Command> command(def: D, desc: string, config?: Command.Config): Command> } @@ -49,12 +49,13 @@ export class Commander { _shortcuts: Command.Shortcut[] = [] constructor(private ctx: Context, private config: Commander.Config = {}) { + this[Context.current] = ctx ctx.plugin(runtime) ctx.plugin(validate) } - protected get caller(): Context { - return this[Context.current] || this.ctx + protected get caller() { + return this[Context.current] } resolve(key: string) { diff --git a/packages/core/src/database.ts b/packages/core/src/database.ts index 2b44da9681..41f5efbefc 100644 --- a/packages/core/src/database.ts +++ b/packages/core/src/database.ts @@ -8,7 +8,7 @@ declare module 'cordis' { 'model'(name: keyof Tables): void } - interface Context { + interface Context extends DatabaseService.Mixin { database: DatabaseService model: DatabaseService } @@ -59,14 +59,17 @@ export interface Tables { } export namespace DatabaseService { - export interface Delegates { + export interface Mixin { getSelfIds(type?: string, assignees?: string[]): Dict + broadcast(content: string, forced?: boolean): Promise + broadcast(channels: readonly string[], content: string, forced?: boolean): Promise } } export class DatabaseService extends Database { - constructor(protected ctx: Context) { + constructor(protected app: Context) { super() + this[Context.current] = app this.extend('user', { // TODO v5: change to number @@ -91,10 +94,6 @@ export class DatabaseService extends Database { }) } - get caller(): Context { - return this[Context.current] || this.ctx - } - getUser(platform: T, id: string, modifier?: Driver.Cursor): Promise & Record> getUser(platform: T, ids: string[], modifier?: Driver.Cursor): Promise[]> async getUser(platform: string, id: MaybeArray, modifier?: Driver.Cursor) { @@ -123,11 +122,11 @@ export class DatabaseService extends Database { getSelfIds(type?: string, assignees?: string[]): Dict { if (type) { - assignees ||= this.ctx.bots.filter(bot => bot.platform === type).map(bot => bot.selfId) + assignees ||= this.app.bots.filter(bot => bot.platform === type).map(bot => bot.selfId) return { [type]: assignees } } const platforms: Dict = {} - for (const bot of this.ctx.bots) { + for (const bot of this.app.bots) { (platforms[bot.platform] ||= []).push(bot.selfId) } return platforms @@ -147,20 +146,43 @@ export class DatabaseService extends Database { createChannel(platform: string, id: string, data: Partial) { return this.create('channel', { platform, id, ...data }) } + + async broadcast(...args: [string, boolean?] | [readonly string[], string, boolean?]) { + let channels: string[] + if (Array.isArray(args[0])) channels = args.shift() as any + const [content, forced] = args as [string, boolean] + if (!content) return [] + + const data = await this.getAssignedChannels(['id', 'assignee', 'flag', 'platform', 'guildId']) + const assignMap: Dict> = {} + for (const { id, assignee, flag, platform, guildId } of data) { + if (channels && !channels.includes(`${platform}:${id}`)) continue + if (!forced && (flag & Channel.Flag.silent)) continue + ((assignMap[platform] ||= {})[assignee] ||= []).push([id, guildId]) + } + + return (await Promise.all(Object.entries(assignMap).flatMap(([platform, map]) => { + return this.app.bots.map((bot) => { + if (bot.platform !== platform) return Promise.resolve([]) + return bot.broadcast(map[bot.selfId] || [], content) + }) + }))).flat(1) + } } // workaround typings DatabaseService.prototype.extend = function extend(this: DatabaseService, name, fields, config) { Database.prototype.extend.call(this, name, fields, { ...config, - driver: this.caller.mapping.database, + driver: this[Context.current].mapping.database, }) - this.ctx.emit('model', name) + this.app.emit('model', name) } Context.service('database') Context.service('model', { constructor: DatabaseService, + methods: ['getSelfIds', 'broadcast'], }) export const defineDriver = (constructor: Driver.Constructor, schema?: utils.Schema, prepare?: Plugin.Function): Plugin.Object => ({ @@ -170,7 +192,7 @@ export const defineDriver = (constructor: Driver.Constructor, schema?: uti apply(ctx, config) { prepare?.(ctx, config) const driver = new constructor(ctx.model, config) - const key = ctx.state.uid + const key = ctx.mapping.database || 'default' ctx.on('ready', async () => { await driver.start() diff --git a/packages/core/src/protocol/adapter.ts b/packages/core/src/protocol/adapter.ts index 75ba70bb77..629b522e69 100644 --- a/packages/core/src/protocol/adapter.ts +++ b/packages/core/src/protocol/adapter.ts @@ -142,12 +142,13 @@ export namespace Adapter { export class BotList extends Array { adapters: Dict = {} - get caller(): Context { - return this[Context.current] || this.ctx + constructor(private app: Context) { + super() + this[Context.current] = app } - constructor(private ctx: Context) { - super() + protected get caller() { + return this[Context.current] } get(sid: string) { diff --git a/packages/core/src/protocol/index.ts b/packages/core/src/protocol/index.ts index ecdae028c0..30571f8bc7 100644 --- a/packages/core/src/protocol/index.ts +++ b/packages/core/src/protocol/index.ts @@ -10,7 +10,7 @@ export * from './bot' export * from './session' declare module 'cordis' { - interface Context extends Internal.Delegates { + interface Context extends Internal.Mixin { $internal: Internal } @@ -49,7 +49,7 @@ export namespace Internal { prefix?: Computed } - export interface Delegates { + export interface Mixin { middleware(middleware: Middleware, prepend?: boolean): () => boolean } } @@ -62,6 +62,7 @@ export class Internal { _channelCache = new SharedCache>() constructor(private ctx: Context, private config: Internal.Config) { + this[Context.current] = ctx this.prepare() // bind built-in event listeners @@ -83,8 +84,8 @@ export class Internal { }) } - protected get caller(): Context { - return this[Context.current] || this.ctx + protected get caller() { + return this[Context.current] } middleware(middleware: Middleware, prepend = false) { diff --git a/packages/core/src/selector.ts b/packages/core/src/selector.ts index 8820030f10..859fee5a85 100644 --- a/packages/core/src/selector.ts +++ b/packages/core/src/selector.ts @@ -1,11 +1,10 @@ -import { Dict, Logger, Promisify, remove } from '@koishijs/utils' +import { Logger, Promisify, remove } from '@koishijs/utils' import { Context, Events } from 'cordis' -import { Channel } from './database' import { Session } from './protocol/session' declare module 'cordis' { - interface Context extends SelectorService.Delegates { - $selector: SelectorService + interface Context extends SelectorService.Mixin { + selector: SelectorService } namespace Context { @@ -18,7 +17,7 @@ declare module 'cordis' { export type Filter = (session: Session) => boolean export namespace SelectorService { - export interface Delegates { + export interface Mixin { logger(name: string): Logger any(): Context never(): Context @@ -38,8 +37,6 @@ export namespace SelectorService { before(name: K, listener: BeforeEventMap[K], append?: boolean): () => boolean setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): () => boolean setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): () => boolean - broadcast(content: string, forced?: boolean): Promise - broadcast(channels: readonly string[], content: string, forced?: boolean): Promise } } @@ -56,6 +53,8 @@ function property(ctx: Context, key: K, ...values: Sess export class SelectorService { constructor(private app: Context) { + this[Context.current] = app + app.filter = () => true app.on('internal/warning', (format, ...args) => { @@ -70,8 +69,8 @@ export class SelectorService { }) } - protected get caller(): Context { - return this[Context.current] || this.app + protected get caller() { + return this[Context.current] } any() { @@ -175,31 +174,9 @@ export class SelectorService { setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]) { return this.createTimerDispose(setInterval(callback, ms, ...args)) } - - async broadcast(...args: [string, boolean?] | [readonly string[], string, boolean?]) { - let channels: string[] - if (Array.isArray(args[0])) channels = args.shift() as any - const [content, forced] = args as [string, boolean] - if (!content) return [] - - const data = await this.caller.database.getAssignedChannels(['id', 'assignee', 'flag', 'platform', 'guildId']) - const assignMap: Dict> = {} - for (const { id, assignee, flag, platform, guildId } of data) { - if (channels && !channels.includes(`${platform}:${id}`)) continue - if (!forced && (flag & Channel.Flag.silent)) continue - ((assignMap[platform] ||= {})[assignee] ||= []).push([id, guildId]) - } - - return (await Promise.all(Object.entries(assignMap).flatMap(([platform, map]) => { - return this.caller.bots.map((bot) => { - if (bot.platform !== platform) return Promise.resolve([]) - return bot.broadcast(map[bot.selfId] || [], content) - }) - }))).flat(1) - } } -Context.service('$selector', { +Context.service('selector', { constructor: SelectorService, methods: [ 'any', 'never', 'union', 'intersect', 'exclude', 'select', diff --git a/packages/koishi/src/patch.ts b/packages/koishi/src/patch.ts index 3721be9696..165bca99b9 100644 --- a/packages/koishi/src/patch.ts +++ b/packages/koishi/src/patch.ts @@ -9,7 +9,7 @@ declare module '@koishijs/core' { } namespace Registry { - interface Delegates { + interface Mixin { plugin(path: string, config?: any): Fork } }