Skip to content

Commit

Permalink
feat(commands): add command command
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Oct 15, 2023
1 parent 24dd326 commit 3b3e9a2
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 9 deletions.
2 changes: 1 addition & 1 deletion plugins/commands/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@koishijs/plugin-commands",
"description": "Override Command Config for Koishi",
"version": "3.3.4",
"version": "3.4.0",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"files": [
Expand Down
37 changes: 37 additions & 0 deletions plugins/commands/src/command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Context } from 'koishi'
import CommandManager from '.'

export default function (ctx: Context, manager: CommandManager) {
ctx.command('command <name>', '修改指令配置', { authority: 4 })
// .option('option', '-o [key] 修改指令选项')
// .option('create', '-c 创建指令')
// .option('force', '-f 当指令不存在时延迟修改')
.option('alias', '-a [name] 添加指令别名')
.option('unalias', '-A [name] 移除指令别名')
.option('name', '-n [name] 修改指令显示名')
.option('parent', '-p [name] 修改指令父级')
.option('parent', '-P 移除指令父级', { value: '' })
.action(async ({ options }, name) => {
const snapshot = manager.ensure(name)
const command = snapshot.command
if (options.alias) {
const item = command._aliases[options.name] || {}
const aliases = { ...command._aliases, [options.alias]: item }
manager.alias(command, aliases, true)
}
if (options.unalias) {
const aliases = { ...command._aliases }
delete aliases[options.unalias]
manager.alias(command, aliases, true)
}
if (options.name) {
const item = command._aliases[options.name] || {}
const aliases = { [options.name]: item, ...command._aliases }
manager.alias(command, aliases, true)
}
if (typeof options.parent === 'string') {
manager.teleport(command, options.parent, true)
}
return '已修改指令配置。'
})
}
12 changes: 9 additions & 3 deletions plugins/commands/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Argv, Command, Context, Dict, remove, Schema } from 'koishi'
import CommandProvider from './console'
import ConsoleExtension from './console'
import CommandExtension from './command'

export * from './console'

Expand Down Expand Up @@ -99,7 +100,8 @@ export class CommandManager {
}
}, true)

ctx.plugin(CommandProvider, this)
ctx.plugin(ConsoleExtension, this)
ctx.plugin(CommandExtension, this)
}

ensure(name: string, create?: boolean) {
Expand Down Expand Up @@ -147,6 +149,10 @@ export class CommandManager {

alias(command: Command, aliases: Dict<Command.Alias>, write = false) {
const { initial, override } = this.snapshots[command.name]
for (const name in command._aliases) {
if (aliases[name]) continue
this.ctx.$commander._commands.delete(name)
}
command._aliases = override.aliases = aliases
for (const name in aliases) {
this.ctx.$commander.set(name, command)
Expand Down Expand Up @@ -237,7 +243,7 @@ export class CommandManager {
if (override.options && !Object.keys(override.options).length) {
delete override.options
}
if (override.aliases && !override.aliases.length) {
if (override.aliases && !Object.keys(override.aliases).length) {
delete override.aliases
}
if (override.name) {
Expand Down
97 changes: 92 additions & 5 deletions plugins/commands/tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { App } from 'koishi'
import mock from '@koishijs/plugin-mock'
import * as help from '@koishijs/plugin-help'
import commands from '@koishijs/plugin-commands'
import { expect } from 'chai'
import { expect, use } from 'chai'
import shape from 'chai-shape'

use(shape)

const app = new App()

Expand All @@ -14,6 +17,14 @@ const client = app.mock.client('123')
before(() => app.start())
after(() => app.stop())

afterEach(() => {
for (const command of app.$commander._commandList.slice()) {
if (command.name === 'help') continue
command.dispose()
}
app.dispose(commands)
})

describe('@koishijs/plugin-commands', () => {
describe('basic usage', () => {
it('dispose command', async () => {
Expand All @@ -33,8 +44,6 @@ describe('@koishijs/plugin-commands', () => {

await client.shouldNotReply('bar')
await client.shouldNotReply('baz')

app.dispose(commands)
})

it('dispose plugin', async () => {
Expand All @@ -54,12 +63,29 @@ describe('@koishijs/plugin-commands', () => {

await client.shouldReply('bar', 'test')
await client.shouldNotReply('baz')
})

cmd.dispose()
it('edit command', async () => {
const fork = app.plugin(commands)

const cmd = app.command('bar').action(() => 'test')
await client.shouldNotReply('baz')
await client.shouldReply('command bar -a baz', '已修改指令配置。')
await client.shouldReply('baz', 'test')
expect(fork.config).to.have.shape({
bar: {
aliases: {
baz: {},
},
},
})

await client.shouldReply('command bar -A baz', '已修改指令配置。')
await client.shouldNotReply('baz')
})
})

describe('subcommand', () => {
describe('teleport (config)', () => {
it('leaf to root', async () => {
const foo = app.command('foo')
const bar = app.command('foo/bar').action(() => 'test')
Expand Down Expand Up @@ -132,6 +158,67 @@ describe('@koishijs/plugin-commands', () => {
})
})

describe('teleport (command)', () => {
it('leaf to root', async () => {
const foo = app.command('foo')
const bar = app.command('foo/bar').action(() => 'test')
expect(foo.children).to.have.length(1)

const fork = app.plugin(commands)
await client.shouldReply('command bar -P -a baz', '已修改指令配置。')
expect(foo.children).to.have.length(0)
await client.shouldReply('bar', 'test')
await client.shouldReply('baz', 'test')

fork.dispose()
await client.shouldReply('bar', 'test')
await client.shouldNotReply('baz')
expect(foo.children).to.have.length(1)
})

it('root to leaf', async () => {
const foo = app.command('foo')
const bar = app.command('bar').action(() => 'test')
expect(foo.children).to.have.length(0)

const fork = app.plugin(commands)
await client.shouldReply('command bar -p foo -a baz', '已修改指令配置。')
expect(foo.children).to.have.length(1)
await client.shouldReply('bar', 'test')
await client.shouldReply('baz', 'test')

fork.dispose()
await client.shouldReply('bar', 'test')
await client.shouldNotReply('baz')
expect(foo.children).to.have.length(0)
})

it('leaf to leaf', async () => {
const bar = app.command('bar')
const foo = app.command('bar/foo').action(() => 'test')
expect(bar.children).to.have.length(1)

const fork = app.plugin(commands)
await client.shouldReply('command foo -p baz', '已修改指令配置。')
expect(bar.children).to.have.length(1)
const baz = app.command('baz')
expect(bar.children).to.have.length(0)
expect(baz.children).to.have.length(1)
await client.shouldReply('foo', 'test')

baz.dispose()
expect(bar.children).to.have.length(1)

fork.dispose()
await client.shouldReply('foo', 'test')
expect(bar.children).to.have.length(1)
expect(baz.children).to.have.length(0)

foo.dispose()
bar.dispose()
})
})

describe('create', () => {
it('basic usage', async () => {
const bar = app.command('bar').action(() => 'test')
Expand Down

0 comments on commit 3b3e9a2

Please sign in to comment.