Skip to content

Commit

Permalink
refa: enhance official plugin schema
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Feb 12, 2022
1 parent 242c91f commit b854ff2
Show file tree
Hide file tree
Showing 32 changed files with 161 additions and 123 deletions.
5 changes: 4 additions & 1 deletion plugins/a11y/admin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { difference, enumKeys, template, Context, User, Channel, Command } from 'koishi'
import { difference, enumKeys, template, Context, User, Channel, Command, Schema } from 'koishi'
import { adminChannel, adminUser, parsePlatform } from '@koishijs/helpers'

/* eslint-disable quote-props */
Expand Down Expand Up @@ -47,8 +47,11 @@ function adminFlag<U extends User.Field, G extends Channel.Field, A extends any[
})
}

export interface Config {}

export const name = 'admin'
export const using = ['database'] as const
export const Config: Schema<Config> = Schema.object({})

export function apply(ctx: Context) {
ctx.command('user', '用户管理', { authority: 3 })
Expand Down
5 changes: 4 additions & 1 deletion plugins/a11y/bind/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, Dict, Random, Session, template, Time, User } from 'koishi'
import { Context, Dict, Random, Schema, Session, template, Time, User } from 'koishi'

template.set('bind', {
'generated-1': [
Expand All @@ -23,6 +23,9 @@ export interface Config {

export const name = 'bind'
export const using = ['database'] as const
export const Config: Schema<Config> = Schema.object({
generateToken: Schema.function().hidden(),
})

export function apply(ctx: Context, config: Config = {}) {
// 1: group (1st step)
Expand Down
5 changes: 4 additions & 1 deletion plugins/a11y/callme/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, KoishiError, template } from 'koishi'
import { Context, KoishiError, Schema, template } from 'koishi'

declare module 'koishi' {
interface EventMap {
Expand All @@ -17,8 +17,11 @@ template.set('callme', {
'failed': '修改称呼失败。',
})

export interface Config {}

export const name = 'callme'
export const using = ['database'] as const
export const Config: Schema<Config> = Schema.object({})

export function apply(ctx: Context) {
ctx.command('callme [name:text]', '修改自己的称呼')
Expand Down
5 changes: 4 additions & 1 deletion plugins/a11y/rate-limit/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Argv, Command, Context, Dict, Session, template, Time, User } from 'koishi'
import { Argv, Command, Context, Dict, Schema, Session, template, Time, User } from 'koishi'
import { adminUser } from '@koishijs/helpers'

declare module 'koishi' {
Expand Down Expand Up @@ -40,8 +40,11 @@ template.set('timer', {
'none': '当前没有生效的定时器。',
})

export interface Config {}

export const name = 'rate-limit'
export const using = ['database'] as const
export const Config: Schema<Config> = Schema.object({})

export function apply(ctx: Context) {
ctx.model.extend('user', {
Expand Down
2 changes: 1 addition & 1 deletion plugins/a11y/schedule/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface Config {
minInterval?: number
}

export const Config = Schema.object({
export const Config: Schema<Config> = Schema.object({
minInterval: Schema.natural().role('ms').description('允许的最小时间间隔。').default(Time.minute),
})

Expand Down
5 changes: 4 additions & 1 deletion plugins/a11y/sudo/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, Session, template } from 'koishi'
import { Context, Schema, Session, template } from 'koishi'
import { parsePlatform } from '@koishijs/helpers'

template.set('sudo', {
Expand All @@ -7,8 +7,11 @@ template.set('sudo', {
'invalid-private-member': '无法在私聊上下文使用 --member 选项。',
})

export interface Config {}

export const name = 'sudo'
export const using = ['database'] as const
export const Config: Schema<Config> = Schema.object({})

export function apply(ctx: Context) {
ctx.command('sudo <command:text>', '在特定上下文中触发指令', { authority: 3 })
Expand Down
4 changes: 3 additions & 1 deletion plugins/a11y/switch/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, template, deduplicate, difference, intersection, Argv } from 'koishi'
import { Context, template, deduplicate, difference, intersection, Argv, Schema } from 'koishi'
import { adminChannel } from '@koishijs/helpers'

declare module 'koishi' {
Expand All @@ -20,6 +20,8 @@ template.set('switch', {
export interface Config {}

export const name = 'switch'
export const using = ['database'] as const
export const Config: Schema<Config> = Schema.object({})

export function apply(ctx: Context, config: Config = {}) {
ctx.model.extend('channel', {
Expand Down
15 changes: 8 additions & 7 deletions plugins/a11y/verifier/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import { Context, Session, Awaitable } from 'koishi'

declare module 'koishi' {
interface Modules {
verifier: typeof import('.')
}
}
import { Context, Session, Awaitable, Schema } from 'koishi'

type RequestHandler = string | boolean | ((session: Session) => Awaitable<string | boolean | void>)
type Response = [boolean, string?]
Expand Down Expand Up @@ -40,6 +34,13 @@ export interface Config {
onGuildRequest?: number | RequestHandler
}

export const name = 'verifier'
export const Config: Schema<Config> = Schema.object({
onFriendRequest: Schema.union([Number, Function]).description('通过好友请求所需的权限等级。'),
onGuildMemberRequest: Schema.union([Number, Function]).description('通过入群申请所需的权限等级。'),
onGuildRequest: Schema.union([Number, Function]).description('通过入群邀请所需的权限等级。'),
})

export function apply(ctx: Context, config: Config = {}) {
const { onFriendRequest, onGuildRequest, onGuildMemberRequest } = config

Expand Down
7 changes: 4 additions & 3 deletions plugins/adapter/kaiheila/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const attachmentTypes = ['image', 'video', 'audio', 'file']

type SendHandle = [string, KHL.MessageParams, Session]

export interface BotConfig extends Bot.BaseConfig {
export interface BotConfig extends Bot.BaseConfig, Quester.Config {
token?: string
verifyToken?: string
attachMode?: 'separate' | 'card' | 'mixed'
Expand All @@ -38,12 +38,13 @@ export class KaiheilaBot extends Bot<BotConfig> {
constructor(adapter: Adapter, config: BotConfig) {
super(adapter, config)
this._sn = 0
this.http = adapter.http.extend({
this.http = adapter.ctx.http.extend({
endpoint: 'https://www.kaiheila.cn/api/v3',
headers: {
'Authorization': `Bot ${config.token}`,
'Content-Type': 'application/json',
},
})
}).extend(config)
}

async request<T = any>(method: Method, path: string, data?: any, headers: any = {}): Promise<T> {
Expand Down
17 changes: 8 additions & 9 deletions plugins/adapter/kaiheila/src/http.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import { Adapter, Logger, assertProperty, sanitize, Schema, Context } from 'koishi'
import { Adapter, Logger, assertProperty, sanitize, Schema, Context, Quester } from 'koishi'
import { BotConfig, KaiheilaBot } from './bot'
import { adaptSession, AdapterConfig } from './utils'

const logger = new Logger('kaiheila')

export default class HttpServer extends Adapter<BotConfig, AdapterConfig> {
static schema = Schema.object({
token: Schema.string().description('机器人的用户令牌。').role('secret').required(),
verifyToken: Schema.string().description('机器人的验证令牌。').required(),
})
static schema = Schema.intersect([
Schema.object({
token: Schema.string().description('机器人的用户令牌。').role('secret').required(),
verifyToken: Schema.string().description('机器人的验证令牌。').required(),
}),
Quester.Config,
])

constructor(ctx: Context, config: AdapterConfig) {
assertProperty(ctx.app.options, 'port')
config.path = sanitize(config.path || '/kaiheila')
super(ctx, config)
this.http = ctx.http.extend({
endpoint: 'https://www.kaiheila.cn/api/v3',
...config.request,
})
}

async connect(bot: KaiheilaBot) {
Expand Down
3 changes: 1 addition & 2 deletions plugins/adapter/kaiheila/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Adapter, Bot, Session, segment, camelCase, Schema, App } from 'koishi'
import * as KHL from './types'

export interface AdapterConfig extends Adapter.WebSocketClient.Config, App.Config.Request {
export interface AdapterConfig extends Adapter.WebSocketClient.Config {
path?: string
}

Expand All @@ -10,7 +10,6 @@ export const AdapterConfig: Schema<AdapterConfig> = Schema.intersect([
path: Schema.string().description('服务器监听的路径,仅用于 http 协议。').default('/kaiheila'),
}),
Adapter.WebSocketClient.Config,
App.Config.Request,
])

export const adaptGroup = (data: KHL.Guild): Bot.Guild => ({
Expand Down
10 changes: 1 addition & 9 deletions plugins/adapter/kaiheila/src/ws.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Adapter, Context, Logger, Schema, Time } from 'koishi'
import { Adapter, Logger, Schema, Time } from 'koishi'
import { BotConfig, KaiheilaBot } from './bot'
import { adaptSession, AdapterConfig } from './utils'
import { Payload, Signal } from './types'
Expand All @@ -13,14 +13,6 @@ export default class WebSocketClient extends Adapter.WebSocketClient<BotConfig,
token: Schema.string().description('机器人的用户令牌。').role('secret').required(),
})

constructor(ctx: Context, config: AdapterConfig) {
super(ctx, config)
this.http = ctx.http.extend({
endpoint: 'https://www.kaiheila.cn/api/v3',
...config.request,
})
}

async prepare(bot: KaiheilaBot) {
const { url } = await bot.request('GET', '/gateway/index?compress=0')
const headers = { Authorization: `Bot ${bot.config.token}` }
Expand Down
3 changes: 1 addition & 2 deletions plugins/adapter/onebot/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ export class HttpServer extends Adapter<BotConfig, AdapterConfig> {
constructor(ctx: Context, config: AdapterConfig = {}) {
super(ctx, config)
assertProperty(ctx.app.options, 'port')
this.http = ctx.http.extend(config.request)
}

async connect(bot: OneBotBot) {
const { endpoint, token } = bot.config
if (!endpoint) return

const http = this.http.extend(bot.config).extend({
const http = this.ctx.http.extend(bot.config).extend({
headers: {
'Content-Type': 'application/json',
'Authorization': `Token ${token}`,
Expand Down
4 changes: 0 additions & 4 deletions plugins/adapter/onebot/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import { HttpServer } from './http'
import * as OneBot from './types'

declare module 'koishi' {
interface Modules {
'adapter-onebot': typeof import('.')
}

interface Session {
onebot?: OneBot.Payload & OneBot.Internal
}
Expand Down
3 changes: 1 addition & 2 deletions plugins/adapter/onebot/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as OneBot from './types'

export * from './types'

export interface AdapterConfig extends Adapter.WebSocketClient.Config, App.Config.Request {
export interface AdapterConfig extends Adapter.WebSocketClient.Config {
path?: string
secret?: string
responseTimeout?: number
Expand All @@ -17,7 +17,6 @@ export const AdapterConfig: Schema<AdapterConfig> = Schema.intersect([
secret: Schema.string().description('接收事件推送时用于验证的字段,应该与 OneBot 的 secret 配置保持一致。').role('secret'),
}),
Adapter.WebSocketClient.Config,
App.Config.Request,
])

export const adaptUser = (user: OneBot.AccountInfo): Bot.User => ({
Expand Down
8 changes: 3 additions & 5 deletions plugins/adapter/qqguild/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { Bot as GBot } from '@qq-guild-sdk/core'
import { Bot } from 'koishi'
import { WebSocketClient } from './ws'
import { renameProperty } from '@koishijs/utils'
import { adaptGuild, adaptUser } from './utils'

export interface BotConfig extends Bot.BaseConfig, GBot.AppConfig {
indents: GBot.Intents | number
}
import { AdapterConfig, adaptGuild, adaptUser, BotConfig } from './utils'

export class QQGuildBot extends Bot<BotConfig> {
static schema = AdapterConfig

$innerBot: GBot

constructor(adapter: WebSocketClient, app: BotConfig) {
Expand Down
7 changes: 1 addition & 6 deletions plugins/adapter/qqguild/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import { Adapter } from 'koishi'
import { QQGuildBot } from './bot'
import { WebSocketClient } from './ws'

declare module 'koishi' {
interface Modules {
'adapter-qqguild': typeof import('.')
}
}

export * from '@qq-guild-sdk/core'

export default Adapter.define('qqguild', QQGuildBot, WebSocketClient)
29 changes: 27 additions & 2 deletions plugins/adapter/qqguild/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
import { Guild as GGuild, User as GUser } from '@qq-guild-sdk/core/dist/common'
import { Bot } from 'koishi'
import { Adapter, Bot, Schema } from 'koishi'
import * as QQGuild from '@qq-guild-sdk/core'

export interface AdapterConfig extends Adapter.WebSocketClient.Config, Omit<QQGuild.Bot.Options, 'app'> {}

export const AdapterConfig: Schema<AdapterConfig> = Schema.intersect([
Schema.object({
sandbox: Schema.boolean().description('是否开启沙箱模式。').default(true),
endpoint: Schema.string().role('url').description('API 入口地址。').default('https://api.sgroup.qq.com/'),
authType: Schema.union(['bot', 'bearer']).description('采用的验证方式。').default('bot'),
}),
Adapter.WebSocketClient.Config,
])

export interface BotConfig extends Bot.BaseConfig, QQGuild.Bot.AppConfig {
indents: number
}

export const BotConfig = Schema.intersect([
Schema.object({
id: Schema.string().description('机器人 id。').required(),
key: Schema.string().description('机器人 key。').role('secret').required(),
token: Schema.string().description('机器人令牌。').role('secret').required(),
}),
])

export const adaptGuild = (guild: GGuild): Bot.Guild => ({
guildId: guild.id, guildName: guild.name,
guildId: guild.id,
guildName: guild.name,
})

export const adaptUser = (user: GUser): Bot.User => ({
Expand Down
28 changes: 6 additions & 22 deletions plugins/adapter/qqguild/src/ws.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
import { Bot as GBot, Message } from '@qq-guild-sdk/core'
import { Message } from '@qq-guild-sdk/core'
import { Logger, segment } from '@koishijs/utils'
import { Adapter, Schema, Session } from 'koishi'
import { BotConfig, QQGuildBot } from './bot'
import { adaptUser } from './utils'
import { Adapter, Session } from 'koishi'
import { QQGuildBot } from './bot'
import { adaptUser, AdapterConfig, BotConfig } from './utils'

const logger = new Logger('qqguild')

export interface AdapterConfig extends Adapter.WebSocketClient.Config, Omit<GBot.Options, 'app'> {
}

export const AdapterConfig: Schema<AdapterConfig> = Schema.intersect([
Schema.object({
sandbox: Schema.boolean()
.description('是否开启沙盒')
.default(true),
endpoint: Schema.string().role('url')
.description('API 入口地址')
.default('https://api.sgroup.qq.com/'),
authType: Schema.union(['bot', 'bearer'])
.description('验证方式')
.default('bot'),
}),
Adapter.WebSocketClient.Config,
])

const createSession = (bot: QQGuildBot, msg: Message) => {
const {
id: messageId, author, guildId, channelId, timestamp,
Expand All @@ -47,6 +29,8 @@ const createSession = (bot: QQGuildBot, msg: Message) => {
}

export class WebSocketClient extends Adapter<BotConfig, AdapterConfig> {
static schema = BotConfig

async connect(bot: QQGuildBot) {
Object.assign(bot, await bot.getSelf())
bot.resolve()
Expand Down
Loading

0 comments on commit b854ff2

Please sign in to comment.