Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Aug 27, 2020
2 parents 0d2a06a + fa727eb commit 8a1bcf6
Show file tree
Hide file tree
Showing 57 changed files with 1,004 additions and 476 deletions.
5 changes: 4 additions & 1 deletion .mocharc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@ module.exports = {
'packages/plugin-eval/tests/*.spec.ts',
'packages/plugin-teach/tests/*.spec.ts',
],
require: 'ts-node/register/transpile-only',
require: [
'ts-node/register/transpile-only',
'tsconfig-paths/register',
],
}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@
"private": true,
"workspaces": [
"atri",
"addons",
"shiki",
"shiki/core",
"shiki/cosmos",
"shiki/games",
"shiki/others",
"packages/*"
],
"scripts": {
"atri": "yarn workspace atri",
"addons": "yarn workspace addons",
"build": "tsc -b && yarn workspace koishi-plugin-eval wrap",
"build:ci": "tsc -b --listEmittedFiles && yarn workspace koishi-plugin-eval wrap",
"bump": "ts-node build/bump",
"dep": "ts-node build/dep",
"docs": "cd docs && yarn dev",
"test": "mocha --experimental-vm-modules --enable-source-maps",
"test": "cross-env TS_NODE_PROJECT=tsconfig.test.json mocha --experimental-vm-modules --enable-source-maps",
"test:json": "c8 -r json yarn test",
"test:lcov": "rimraf coverage && c8 -r lcov yarn test",
"test:text": "c8 -r text yarn test",
Expand All @@ -41,6 +44,7 @@
"cac": "^6.6.1",
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"cross-env": "^7.0.2",
"cross-spawn": "^7.0.3",
"del": "^5.1.0",
"eslint": "^7.7.0",
Expand All @@ -64,6 +68,7 @@
"rimraf": "^3.0.2",
"semver": "^7.3.2",
"ts-node": "^9.0.0",
"tsconfig-paths": "^3.9.0",
"typescript": "^4.0.2"
}
}
6 changes: 3 additions & 3 deletions packages/adapter-cqhttp/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-adapter-cqhttp",
"description": "CQHTTP adapter for Koishi",
"version": "1.0.0",
"version": "1.0.1",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
Expand Down Expand Up @@ -31,7 +31,7 @@
"koishi"
],
"peerDependencies": {
"koishi-core": "^2.0.0"
"koishi-core": "^2.0.1"
},
"devDependencies": {
"@types/ms": "^0.7.31",
Expand All @@ -43,6 +43,6 @@
"axios": "^0.20.0",
"ms": "^2.1.2",
"ws": "^7.3.1",
"koishi-utils": "^3.1.0"
"koishi-utils": "^3.1.1"
}
}
5 changes: 3 additions & 2 deletions packages/adapter-cqhttp/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ export interface ImageInfo {
}

export interface VersionInfo {
version?: string
goCqhttp?: boolean
runtimeVersion?: string
runtimeOs?: string
Expand Down Expand Up @@ -395,9 +396,9 @@ interface CQNode {
defineAsync('set_group_name', 'group_id', 'name')

export function toVersion(data: VersionInfo) {
const { coolqEdition, pluginVersion, goCqhttp } = data
const { coolqEdition, pluginVersion, goCqhttp, version } = data
if (goCqhttp) {
return `Go-CQHTTP`
return `Go-CQHTTP/${version.slice(1)}`
} else {
return `CoolQ/${capitalize(coolqEdition)} CQHTTP/${pluginVersion}`
}
Expand Down
4 changes: 2 additions & 2 deletions packages/koishi-core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-core",
"description": "Core features for Koishi",
"version": "2.0.0",
"version": "2.0.1",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"engines": {
Expand Down Expand Up @@ -44,7 +44,7 @@
"koa": "^2.13.0",
"koa-bodyparser": "^4.3.0",
"koa-router": "^9.4.0",
"koishi-utils": "^3.1.0",
"koishi-utils": "^3.1.1",
"leven": "^3.1.0",
"lru-cache": "^6.0.0"
}
Expand Down
36 changes: 18 additions & 18 deletions packages/koishi-core/src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ type Extend<O extends {}, K extends string, T> = {
[P in K | keyof O]: (P extends keyof O ? O[P] : unknown) & (P extends K ? T : unknown)
}

type ArgvInferred<T> = Iterable<T> | ((argv: ParsedArgv, fields: Set<T>) => Iterable<T>)
export type FieldCollector<T extends TableType, K = keyof Tables[T], O extends {} = {}> =
| Iterable<K>
| ((argv: ParsedArgv<never, never, O>, fields: Set<keyof Tables[T]>) => void)

export type CommandAction<U extends User.Field = never, G extends Group.Field = never, O = {}> =
(this: Command<U, G>, config: ParsedArgv<U, G, O>, ...args: string[]) => void | string | Promise<void | string>

Expand All @@ -117,36 +120,37 @@ export class Command<U extends User.Field = never, G extends Group.Field = never

private _optionNameMap: Record<string, CommandOption> = {}
private _optionSymbolMap: Record<string, CommandOption> = {}
private _userFields: ArgvInferred<User.Field>[] = []
private _groupFields: ArgvInferred<Group.Field>[] = []
private _userFields: FieldCollector<'user'>[] = []
private _groupFields: FieldCollector<'group'>[] = []

_action?: CommandAction<U, G>

static defaultConfig: CommandConfig = {}
static defaultOptionConfig: OptionConfig = {}

private static _userFields: ArgvInferred<User.Field>[] = []
private static _groupFields: ArgvInferred<Group.Field>[] = []
private static _userFields: FieldCollector<'user'>[] = []
private static _groupFields: FieldCollector<'group'>[] = []

static userFields(fields: ArgvInferred<User.Field>) {
static userFields(fields: FieldCollector<'user'>) {
this._userFields.push(fields)
return this
}

static groupFields(fields: ArgvInferred<Group.Field>) {
static groupFields(fields: FieldCollector<'group'>) {
this._groupFields.push(fields)
return this
}

static collect<T extends TableType>(argv: ParsedArgv, key: T, fields = new Set<keyof Tables[T]>()) {
if (!argv) return
const values: ArgvInferred<keyof Tables[T]>[] = [
const values: FieldCollector<T>[] = [
...this[`_${key}Fields`],
...argv.command[`_${key}Fields`],
]
for (let value of values) {
for (const value of values) {
if (typeof value === 'function') {
value = value(argv, fields)
value(argv, fields)
continue
}
for (const field of value) {
fields.add(field)
Expand Down Expand Up @@ -183,18 +187,14 @@ export class Command<U extends User.Field = never, G extends Group.Field = never
return `Command <${this.name}>`
}

userFields<T extends User.Field = never>(fields: Iterable<T>): Command<U | T, G, O>
userFields<T extends User.Field = never>(fields: (argv: ParsedArgv<never, never, O>, fields: Set<User.Field>) => Iterable<T>): Command<U | T, G, O>
userFields(fields: ArgvInferred<User.Field>) {
userFields<T extends User.Field = never>(fields: FieldCollector<'user', T, O>): Command<U | T, G, O> {
this._userFields.push(fields)
return this
return this as any
}

groupFields<T extends Group.Field = never>(fields: Iterable<T>): Command<U, G | T, O>
groupFields<T extends Group.Field = never>(fields: (argv: ParsedArgv<never, never, O>, fields: Set<Group.Field>) => Iterable<T>): Command<U, G | T, O>
groupFields(fields: ArgvInferred<Group.Field>) {
groupFields<T extends Group.Field = never>(fields: FieldCollector<'group', T, O>): Command<U, G | T, O> {
this._groupFields.push(fields)
return this
return this as any
}

alias(...names: string[]) {
Expand Down
6 changes: 3 additions & 3 deletions packages/koishi-core/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export namespace User {

export type Field = keyof User
export const fields: Field[] = []
export type Observed<K extends Field = Field> = utils.Observed<Pick<User, K>>
export type Observed<K extends Field = Field> = utils.Observed<Pick<User, K>, Promise<void>>
type Getter = (id: number, authority: number) => Partial<User>
const getters: Getter[] = []

Expand Down Expand Up @@ -94,13 +94,13 @@ export interface Database {
getUser<K extends User.Field>(userId: number, defaultAuthority?: number, fields?: readonly K[]): Promise<Pick<User, K | 'id'>>
getUsers<K extends User.Field>(fields?: readonly K[]): Promise<Pick<User, K>[]>
getUsers<K extends User.Field>(ids: readonly number[], fields?: readonly K[]): Promise<Pick<User, K>[]>
setUser(userId: number, data: Partial<User>): Promise<any>
setUser(userId: number, data: Partial<User>): Promise<void>

getGroup<K extends Group.Field>(groupId: number, fields?: readonly K[]): Promise<Pick<Group, K | 'id'>>
getGroup<K extends Group.Field>(groupId: number, selfId?: number, fields?: readonly K[]): Promise<Pick<Group, K | 'id'>>
getAllGroups<K extends Group.Field>(assignees?: readonly number[]): Promise<Pick<Group, K>[]>
getAllGroups<K extends Group.Field>(fields?: readonly K[], assignees?: readonly number[]): Promise<Pick<Group, K>[]>
setGroup(groupId: number, data: Partial<Group>): Promise<any>
setGroup(groupId: number, data: Partial<Group>): Promise<void>
}

type DatabaseExtensionMethods<I> = {
Expand Down
17 changes: 8 additions & 9 deletions packages/koishi-core/src/plugins/help.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getUsage, getUsageName, ValidationField } from './validate'
import { User, Group, TableType, Tables } from '../database'
import { Command, ParsedArgv } from '../command'
import { Command, FieldCollector, ParsedArgv } from '../command'
import { Session } from '../session'
import { App } from '../app'
import { Message } from './message'
Expand Down Expand Up @@ -59,17 +59,15 @@ export default function apply(app: App) {
return ''
})

function createCollector<T extends TableType>(key: T) {
return function* (argv: ParsedArgv, fields: Set<keyof Tables[T]>) {
const { args: [name] } = argv
const command = app._commandMap[name] || app._shortcutMap[name]
if (!command) return
yield* Command.collect({ ...argv, args: [], options: { help: true } }, key, fields)
}
const createCollector = <T extends TableType>(key: T): FieldCollector<T> => (argv, fields) => {
const { args: [name] } = argv
const command = app._commandMap[name] || app._shortcutMap[name]
if (!command) return
Command.collect({ ...argv, command, args: [], options: { help: true } }, key, fields)
}

app.command('help [command]', '显示帮助信息', { authority: 0 })
.userFields(['authority'])
.userFields<ValidationField>(['authority'])
.userFields(createCollector('user'))
.groupFields(createCollector('group'))
.shortcut('帮助', { fuzzy: true })
Expand Down Expand Up @@ -98,6 +96,7 @@ export default function apply(app: App) {
},
})
}

return showHelp(command, session, options)
})
}
Expand Down
8 changes: 4 additions & 4 deletions packages/koishi-core/src/plugins/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Object.assign(Command.defaultOptionConfig, {
authority: 0,
})

Command.userFields(function* ({ command, options = {} }, fields) {
Command.userFields(({ command, options = {} }, fields) => {
const { maxUsage, minInterval, authority } = command.config
let shouldFetchAuthority = !fields.has('authority') && authority > 0
let shouldFetchUsage = !!(maxUsage || minInterval)
Expand All @@ -69,10 +69,10 @@ Command.userFields(function* ({ command, options = {} }, fields) {
if (notUsage) shouldFetchUsage = false
}
}
if (shouldFetchAuthority) yield 'authority'
if (shouldFetchAuthority) fields.add('authority')
if (shouldFetchUsage) {
if (maxUsage) yield 'usage'
if (minInterval) yield 'timers'
if (maxUsage) fields.add('usage')
if (minInterval) fields.add('timers')
}
})

Expand Down
2 changes: 1 addition & 1 deletion packages/koishi-core/src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export class Session<U extends User.Field = never, G extends Group.Field = never

// 确保匿名消息不会写回数据库
if (this.anonymous) {
const user = observe(User.create(userId, defaultAuthority))
const user = observe(User.create(userId, defaultAuthority), () => Promise.resolve())
return this.$user = user
}

Expand Down
34 changes: 31 additions & 3 deletions packages/koishi-core/tests/command.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { App } from 'koishi-test-utils'
import { inspect } from 'util'
import { expect } from 'chai'
import '@shigma/chai-extended'

let app: App

describe('Command API', () => {
describe('Register Commands', () => {
before(() => app = new App())
const app = new App()

it('constructor checks', () => {
expect(() => app.command('')).to.throw()
Expand All @@ -26,6 +25,10 @@ describe('Command API', () => {
expect(app._commandMap.c.context).to.equal(ctx2)
})

it('custom inspect', () => {
expect(inspect(app.command('a'))).to.equal('Command <a>')
})

it('modify commands', () => {
const d1 = app.command('d', 'foo', { authority: 1 })
expect(app._commandMap.d.config.description).to.equal('foo')
Expand Down Expand Up @@ -63,6 +66,7 @@ describe('Command API', () => {
})

describe('Register Subcommands', () => {
let app: App
beforeEach(() => app = new App())

it('command.subcommand', () => {
Expand Down Expand Up @@ -123,4 +127,28 @@ describe('Command API', () => {
expect(() => app.command('a/d')).not.to.throw()
})
})

describe('Dispose Commands', () => {
const app = new App()
const foo = app.command('foo')
const bar = foo.subcommand('bar')
const test = bar.subcommand('test')
bar.alias('baz').shortcut('1')
test.alias('it').shortcut('2')

it('before dispose', () => {
// don't forget help
expect(app._commands).to.have.length(4)
expect(app._shortcuts).to.have.length(3)
expect(foo.children).to.have.length(1)
})

it('after dispose', () => {
bar.dispose()
// don't forget help
expect(app._commands).to.have.length(2)
expect(app._shortcuts).to.have.length(1)
expect(foo.children).to.have.length(0)
})
})
})
2 changes: 1 addition & 1 deletion packages/koishi-core/tests/hook.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { expect } from 'chai'

const app = new App()

Logger.baseLevel = 1
Logger.baseLevel = Logger.ERROR
const appLogger = new Logger('app')
const appWarn = spyOn(appLogger, 'warn')
const midLogger = new Logger('middleware')
Expand Down
Loading

0 comments on commit 8a1bcf6

Please sign in to comment.