@pikokr/command.ts 3.0.0-dev.522c5bd → 3.0.0-dev.85a29c3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +2 -1
- package/README.md +3 -16
- package/dist/builtinModules/BuiltInModule.d.ts +4 -0
- package/dist/builtinModules/BuiltInModule.js +12 -0
- package/dist/builtinModules/BuiltinCommandConverters.d.ts +14 -0
- package/dist/builtinModules/BuiltinCommandConverters.js +89 -0
- package/dist/builtinModules/CommandHandler.d.ts +9 -0
- package/dist/builtinModules/CommandHandler.js +134 -0
- package/dist/builtinModules/index.d.ts +2 -0
- package/dist/builtinModules/index.js +14 -0
- package/dist/command/ArgumentConverter.d.ts +9 -0
- package/dist/command/ArgumentConverter.js +14 -0
- package/dist/command/Command.d.ts +14 -5
- package/dist/command/Command.js +9 -4
- package/dist/command/decorator.d.ts +11 -2
- package/dist/command/decorator.js +66 -10
- package/dist/command/index.d.ts +2 -0
- package/dist/command/index.js +2 -0
- package/dist/command/utils.d.ts +2 -0
- package/dist/command/utils.js +17 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +9 -2
- package/dist/error/ArgumentConverterNotFound.d.ts +7 -0
- package/dist/error/ArgumentConverterNotFound.js +11 -0
- package/dist/error/ArgumentNotProvided.d.ts +8 -0
- package/dist/error/ArgumentNotProvided.js +12 -0
- package/dist/error/CommandCheckFailed.d.ts +7 -0
- package/dist/error/CommandCheckFailed.js +11 -0
- package/dist/error/CommandNotFound.d.ts +4 -0
- package/dist/error/CommandNotFound.js +10 -0
- package/dist/error/ModuleError.d.ts +5 -0
- package/dist/error/ModuleError.js +12 -0
- package/dist/error/PermissionRequired.d.ts +10 -0
- package/dist/error/PermissionRequired.js +18 -0
- package/dist/error/index.d.ts +5 -0
- package/dist/error/index.js +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/interface/index.d.ts +1 -1
- package/dist/interface/index.js +1 -0
- package/dist/listener/Listener.d.ts +5 -0
- package/dist/listener/Listener.js +10 -0
- package/dist/listener/decorator.d.ts +2 -0
- package/dist/listener/decorator.js +21 -0
- package/dist/listener/index.d.ts +2 -0
- package/dist/listener/index.js +14 -0
- package/dist/structures/CommandClient.d.ts +5 -5
- package/dist/structures/CommandClient.js +18 -29
- package/dist/structures/Module.d.ts +7 -0
- package/dist/structures/Module.js +13 -0
- package/dist/structures/Registry.d.ts +17 -7
- package/dist/structures/Registry.js +126 -7
- package/dist/structures/index.d.ts +2 -1
- package/dist/structures/index.js +2 -1
- package/dist/typings.d.ts +11 -0
- package/dist/{interface/HandlerAdapter.js → typings.js} +0 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +10 -0
- package/package.json +3 -2
- package/src/builtinModules/BuiltInModule.ts +9 -0
- package/src/builtinModules/BuiltinCommandConverters.ts +56 -0
- package/src/builtinModules/CommandHandler.ts +120 -0
- package/src/builtinModules/index.ts +2 -0
- package/src/command/ArgumentConverter.ts +10 -0
- package/src/command/Command.ts +20 -5
- package/src/command/decorator.ts +84 -12
- package/src/command/index.ts +2 -0
- package/src/command/utils.ts +15 -0
- package/src/constants.ts +15 -1
- package/src/error/ArgumentConverterNotFound.ts +8 -0
- package/src/error/ArgumentNotProvided.ts +8 -0
- package/src/error/CommandCheckFailed.ts +8 -0
- package/src/error/CommandNotFound.ts +5 -0
- package/src/error/ModuleError.ts +7 -0
- package/src/error/PermissionRequired.ts +13 -0
- package/src/error/index.ts +5 -0
- package/src/index.ts +3 -0
- package/src/interface/index.ts +3 -1
- package/src/listener/Listener.ts +3 -0
- package/src/listener/decorator.ts +25 -0
- package/src/listener/index.ts +2 -0
- package/src/structures/CommandClient.ts +18 -46
- package/src/structures/Module.ts +21 -0
- package/src/structures/Registry.ts +133 -10
- package/src/structures/index.ts +2 -1
- package/src/typings.ts +12 -0
- package/src/utils.ts +6 -0
- package/test/index.ts +5 -2
- package/test/modules/test.ts +44 -0
- package/dist/adapters/DJSAdapter.d.ts +0 -14
- package/dist/adapters/DJSAdapter.js +0 -31
- package/dist/interface/HandlerAdapter.d.ts +0 -12
- package/src/adapters/DJSAdapter.ts +0 -27
- package/src/interface/HandlerAdapter.ts +0 -14
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { BuiltInModule } from './BuiltInModule'
|
|
2
|
+
import { Registry } from '../structures'
|
|
3
|
+
import { listener } from '../listener'
|
|
4
|
+
import { Message } from 'discord.js'
|
|
5
|
+
import { CommandClient } from '../structures'
|
|
6
|
+
import { Command } from '../command'
|
|
7
|
+
import { ArgumentConverterNotFound, ArgumentNotProvided, CommandCheckFailed } from '../error'
|
|
8
|
+
import { CommandNotFound } from '../error/CommandNotFound'
|
|
9
|
+
|
|
10
|
+
export class CommandHandler extends BuiltInModule {
|
|
11
|
+
private client: CommandClient
|
|
12
|
+
|
|
13
|
+
constructor(private registry: Registry) {
|
|
14
|
+
super()
|
|
15
|
+
this.client = registry.client
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@listener('messageCreate')
|
|
19
|
+
async message(msg: Message) {
|
|
20
|
+
const error = (error: Error) => this.client.client.emit('commandError', error, msg)
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const prefixList: string[] | string =
|
|
24
|
+
typeof this.client.options.command.prefix === 'string'
|
|
25
|
+
? this.client.options.command.prefix
|
|
26
|
+
: typeof this.client.options.command.prefix === 'function'
|
|
27
|
+
? await this.client.options.command.prefix(msg)
|
|
28
|
+
: this.client.options.command.prefix
|
|
29
|
+
let prefix: string
|
|
30
|
+
if (typeof prefixList === 'object') {
|
|
31
|
+
const res = prefixList.find((x) => msg.content.includes(x))
|
|
32
|
+
|
|
33
|
+
if (!res) return
|
|
34
|
+
|
|
35
|
+
prefix = res
|
|
36
|
+
} else {
|
|
37
|
+
if (!msg.content.includes(prefixList)) return
|
|
38
|
+
prefix = prefixList
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!msg.content.startsWith(prefix)) return
|
|
42
|
+
|
|
43
|
+
const args = msg.content.slice(prefix.length).split(' ')
|
|
44
|
+
|
|
45
|
+
const command = args.shift()
|
|
46
|
+
|
|
47
|
+
if (!command) return
|
|
48
|
+
|
|
49
|
+
let cmd: Command | null = null
|
|
50
|
+
|
|
51
|
+
for (const c of this.registry.commands) {
|
|
52
|
+
if (c.name === command) {
|
|
53
|
+
cmd = c
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
if ((typeof c.aliases === 'function' ? await c.aliases(msg) : c.aliases).includes(command)) {
|
|
57
|
+
cmd = c
|
|
58
|
+
break
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!cmd) return error(new CommandNotFound(command))
|
|
63
|
+
|
|
64
|
+
msg.data = {
|
|
65
|
+
cts: this.client,
|
|
66
|
+
command: cmd,
|
|
67
|
+
prefix: prefix,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const module = this.registry.modules.find((x) => x.commands.includes(cmd!))
|
|
71
|
+
|
|
72
|
+
if (!module) return
|
|
73
|
+
|
|
74
|
+
const argList: any[] = []
|
|
75
|
+
|
|
76
|
+
for (const check of cmd.checks) {
|
|
77
|
+
if (!(await check(msg))) return error(new CommandCheckFailed(msg, cmd))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for (let i = 0; i < cmd.argTypes.length; i++) {
|
|
81
|
+
const argType = cmd.argTypes[i]
|
|
82
|
+
const converter = this.registry.argumentConverters.find((x) => x.type === argType.type)
|
|
83
|
+
|
|
84
|
+
if (argType.rest) {
|
|
85
|
+
const i = args.join(' ')
|
|
86
|
+
if (!i) break
|
|
87
|
+
argList.push(i)
|
|
88
|
+
break
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!converter) return error(new ArgumentConverterNotFound(argType, msg))
|
|
92
|
+
|
|
93
|
+
if (converter.withoutParameter) {
|
|
94
|
+
argList.push(await converter.execute(module, msg))
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
const arg = args.shift()
|
|
98
|
+
if (argType.optional && !arg) {
|
|
99
|
+
break
|
|
100
|
+
}
|
|
101
|
+
if (!arg) {
|
|
102
|
+
return error(new ArgumentNotProvided(i, cmd, msg))
|
|
103
|
+
}
|
|
104
|
+
const executed = await converter.execute(module, msg, arg)
|
|
105
|
+
if (!executed === undefined) {
|
|
106
|
+
return error(new ArgumentNotProvided(i, cmd, msg))
|
|
107
|
+
}
|
|
108
|
+
argList.push(executed)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
cmd.execute(module, argList)
|
|
113
|
+
} catch (e: any) {
|
|
114
|
+
return error(e)
|
|
115
|
+
}
|
|
116
|
+
} catch (e) {
|
|
117
|
+
return error(e)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Module } from '../structures'
|
|
2
|
+
import { Message } from 'discord.js'
|
|
3
|
+
|
|
4
|
+
export class ArgumentConverter {
|
|
5
|
+
execute(module: Module, msg: Message, arg?: string) {
|
|
6
|
+
return this.run.apply(module, [msg, arg])
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
constructor(public type: object, private run: Function, public withoutParameter: boolean) {}
|
|
10
|
+
}
|
package/src/command/Command.ts
CHANGED
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import { Module } from '../structures'
|
|
2
|
+
import { Message } from 'discord.js'
|
|
3
|
+
import { KCommandChecks } from '../constants'
|
|
4
|
+
|
|
5
|
+
export type Argument = {
|
|
6
|
+
optional: boolean
|
|
7
|
+
type: any
|
|
8
|
+
rest: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type CheckFunction = (msg: Message) => boolean | Promise<boolean>
|
|
2
12
|
|
|
3
13
|
export class Command {
|
|
4
|
-
execute(args:
|
|
5
|
-
return this.run.
|
|
14
|
+
execute(module: Module, args: any[]) {
|
|
15
|
+
return this.run.apply(module, args)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
get checks(): CheckFunction[] {
|
|
19
|
+
return Reflect.getMetadata(KCommandChecks, this.module, this.key) || []
|
|
6
20
|
}
|
|
7
21
|
|
|
8
22
|
constructor(
|
|
9
|
-
public module: Module,
|
|
10
23
|
private run: Function,
|
|
11
|
-
public argTypes:
|
|
24
|
+
public argTypes: Argument[],
|
|
12
25
|
public name: string,
|
|
13
|
-
public aliases: string[],
|
|
26
|
+
public aliases: string[] | ((msg: Message) => string[]),
|
|
27
|
+
public module: Module,
|
|
28
|
+
public key: symbol | string,
|
|
14
29
|
) {}
|
|
15
30
|
}
|
package/src/command/decorator.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { KCommands } from '../constants'
|
|
2
|
-
import { Module } from '../structures'
|
|
3
|
-
import { InvalidTargetError } from '../error'
|
|
1
|
+
import { KArgumentConverters, KCommands, KOptionals, KRest } from '../constants'
|
|
4
2
|
import { Command } from './Command'
|
|
3
|
+
import { checkTarget } from '../utils'
|
|
4
|
+
import { ArgumentConverter } from './ArgumentConverter'
|
|
5
|
+
import { Module } from '../structures'
|
|
6
|
+
import { createCheckDecorator } from './utils'
|
|
7
|
+
import { Message, PermissionResolvable, Permissions, TextChannel } from 'discord.js'
|
|
8
|
+
import { ClientPermissionRequired, UserPermissionRequired } from '../error'
|
|
5
9
|
|
|
6
10
|
type CommandOptions = {
|
|
7
11
|
name: string
|
|
8
|
-
aliases: string[]
|
|
12
|
+
aliases: string[] | ((msg: Message) => string[])
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
const
|
|
12
|
-
if (!(target instanceof Module)) throw new InvalidTargetError()
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const command = (options: Partial<CommandOptions>) => {
|
|
15
|
+
export const command = (options: Partial<CommandOptions> = {}) => {
|
|
16
16
|
return (
|
|
17
17
|
target: Object,
|
|
18
18
|
propertyKey: string,
|
|
@@ -22,14 +22,23 @@ export const command = (options: Partial<CommandOptions>) => {
|
|
|
22
22
|
|
|
23
23
|
let properties: Command[] = Reflect.getMetadata(KCommands, target)
|
|
24
24
|
|
|
25
|
-
const params = Reflect.getMetadata('design:paramtypes', target, propertyKey)
|
|
25
|
+
const params: any[] = Reflect.getMetadata('design:paramtypes', target, propertyKey)
|
|
26
|
+
|
|
27
|
+
const optionals: number = Reflect.getMetadata(KOptionals, target, propertyKey) || -1
|
|
28
|
+
|
|
29
|
+
const rest = Reflect.getMetadata(KRest, target, propertyKey) || -1
|
|
26
30
|
|
|
27
31
|
const command = new Command(
|
|
28
|
-
target as Module,
|
|
29
32
|
Reflect.get(target, propertyKey),
|
|
30
|
-
params,
|
|
33
|
+
params.map((x, i) => ({
|
|
34
|
+
type: x,
|
|
35
|
+
optional: optionals === -1 ? false : optionals <= i,
|
|
36
|
+
rest: rest === -1 ? false : rest === i,
|
|
37
|
+
})),
|
|
31
38
|
options.name || propertyKey,
|
|
32
39
|
options.aliases || [],
|
|
40
|
+
target as Module,
|
|
41
|
+
propertyKey,
|
|
33
42
|
)
|
|
34
43
|
|
|
35
44
|
if (properties) {
|
|
@@ -40,3 +49,66 @@ export const command = (options: Partial<CommandOptions>) => {
|
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
}
|
|
52
|
+
|
|
53
|
+
export const argumentConverter = (type: object, requireParameter = true) => {
|
|
54
|
+
return (
|
|
55
|
+
target: Object,
|
|
56
|
+
propertyKey: string,
|
|
57
|
+
// descriptor: TypedPropertyDescriptor<any>,
|
|
58
|
+
) => {
|
|
59
|
+
checkTarget(target)
|
|
60
|
+
|
|
61
|
+
let properties: ArgumentConverter[] = Reflect.getMetadata(KArgumentConverters, target)
|
|
62
|
+
|
|
63
|
+
const converter = new ArgumentConverter(type, Reflect.get(target, propertyKey), !requireParameter)
|
|
64
|
+
|
|
65
|
+
if (properties) {
|
|
66
|
+
properties.push(converter)
|
|
67
|
+
} else {
|
|
68
|
+
properties = [converter]
|
|
69
|
+
Reflect.defineMetadata(KArgumentConverters, properties, target)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const optional: ParameterDecorator = (target, propertyKey, parameterIndex) => {
|
|
75
|
+
checkTarget(target)
|
|
76
|
+
|
|
77
|
+
Reflect.defineMetadata(KOptionals, parameterIndex, target, propertyKey)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const rest: ParameterDecorator = (target, propertyKey, parameterIndex) => {
|
|
81
|
+
checkTarget(target)
|
|
82
|
+
|
|
83
|
+
const params: any[] = Reflect.getMetadata('design:paramtypes', target, propertyKey)
|
|
84
|
+
|
|
85
|
+
if (params.length - 1 !== parameterIndex) throw new Error('Rest decorator must be used at last argument.')
|
|
86
|
+
|
|
87
|
+
if (params[parameterIndex] !== String) throw new Error('Rest argument type must be "String"')
|
|
88
|
+
|
|
89
|
+
Reflect.defineMetadata(KRest, parameterIndex, target, propertyKey)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const ownerOnly = createCheckDecorator((msg) => msg.data.cts.owners.includes(msg.author.id))
|
|
93
|
+
|
|
94
|
+
export const guildOnly = createCheckDecorator((msg) => !!msg.guild)
|
|
95
|
+
|
|
96
|
+
export const dmOnly = createCheckDecorator((msg) => !msg.guild)
|
|
97
|
+
|
|
98
|
+
export const requireUserPermissions = (permission: PermissionResolvable) =>
|
|
99
|
+
createCheckDecorator((msg) => {
|
|
100
|
+
if (!msg.guild || !msg.member) throw new Error('This command must be used in serer.')
|
|
101
|
+
if (msg.member.permissionsIn(msg.channel as TextChannel).has(permission)) {
|
|
102
|
+
return true
|
|
103
|
+
}
|
|
104
|
+
throw new UserPermissionRequired(msg.member, new Permissions(permission))
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
export const requireClientPermissions = (permission: PermissionResolvable) =>
|
|
108
|
+
createCheckDecorator((msg) => {
|
|
109
|
+
if (!msg.guild) throw new Error('This command must be used in serer.')
|
|
110
|
+
if (msg.guild.me!.permissionsIn(msg.channel as TextChannel).has(permission)) {
|
|
111
|
+
return true
|
|
112
|
+
}
|
|
113
|
+
throw new ClientPermissionRequired(new Permissions(permission))
|
|
114
|
+
})
|
package/src/command/index.ts
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Message } from 'discord.js'
|
|
2
|
+
import type { CheckFunction } from './Command'
|
|
3
|
+
import { KCommandChecks } from '../constants'
|
|
4
|
+
|
|
5
|
+
export const createCheckDecorator = (execute: (msg: Message) => boolean | Promise<boolean>): MethodDecorator => {
|
|
6
|
+
return (target, propertyKey) => {
|
|
7
|
+
let properties: CheckFunction[] = Reflect.getMetadata(KCommandChecks, target, propertyKey)
|
|
8
|
+
if (properties) {
|
|
9
|
+
properties.push(execute)
|
|
10
|
+
} else {
|
|
11
|
+
properties = [execute]
|
|
12
|
+
Reflect.defineMetadata(KCommandChecks, properties, target, propertyKey)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/constants.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
export const KCommands = Symbol('Command.TS
|
|
1
|
+
export const KCommands = Symbol('Command.TS Commands')
|
|
2
|
+
|
|
3
|
+
export const KListeners = Symbol('Command.TS Listeners')
|
|
2
4
|
|
|
3
5
|
export const KModulePath = Symbol('Command.TS Module Path')
|
|
6
|
+
|
|
7
|
+
export const KListenerExecuteCache = Symbol('Command.TS Module Identifier')
|
|
8
|
+
|
|
9
|
+
export const KBuiltInModule = Symbol('Command.TS Built-In Module')
|
|
10
|
+
|
|
11
|
+
export const KOptionals = Symbol('Command.TS Optional Parameters')
|
|
12
|
+
|
|
13
|
+
export const KRest = Symbol('Command.TS Rest Parameter')
|
|
14
|
+
|
|
15
|
+
export const KArgumentConverters = Symbol('Command.TS Argument Converter')
|
|
16
|
+
|
|
17
|
+
export const KCommandChecks = Symbol('Command.TS Command Checks')
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Message } from 'discord.js'
|
|
2
|
+
import type { Argument } from '../command'
|
|
3
|
+
|
|
4
|
+
export class ArgumentConverterNotFound extends Error {
|
|
5
|
+
constructor(public type: Argument, public msg: Message) {
|
|
6
|
+
super(`Argument converter ${type.type.name} not found.`)
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Message } from 'discord.js'
|
|
2
|
+
import { Command } from '../command'
|
|
3
|
+
|
|
4
|
+
export class ArgumentNotProvided extends Error {
|
|
5
|
+
constructor(public index: number, public command: Command, public msg: Message) {
|
|
6
|
+
super(`Required argument #${index} not provided.`)
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GuildMember, Permissions } from 'discord.js'
|
|
2
|
+
|
|
3
|
+
export class UserPermissionRequired extends Error {
|
|
4
|
+
constructor(public user: GuildMember, public permissions: Permissions) {
|
|
5
|
+
super()
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class ClientPermissionRequired extends Error {
|
|
10
|
+
constructor(public permissions: Permissions) {
|
|
11
|
+
super()
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/error/index.ts
CHANGED
package/src/index.ts
CHANGED
package/src/interface/index.ts
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { checkTarget } from '../utils'
|
|
2
|
+
import { KListeners } from '../constants'
|
|
3
|
+
import { Listener } from './Listener'
|
|
4
|
+
import { Module } from '../structures'
|
|
5
|
+
|
|
6
|
+
export const listener = (event: string) => {
|
|
7
|
+
return (
|
|
8
|
+
target: Module,
|
|
9
|
+
propertyKey: string,
|
|
10
|
+
// descriptor: TypedPropertyDescriptor<any>,
|
|
11
|
+
) => {
|
|
12
|
+
checkTarget(target)
|
|
13
|
+
|
|
14
|
+
let properties: Listener[] = Reflect.getMetadata(KListeners, target)
|
|
15
|
+
|
|
16
|
+
const listener = new Listener(event, Reflect.get(target, propertyKey))
|
|
17
|
+
|
|
18
|
+
if (properties) {
|
|
19
|
+
properties.push(listener)
|
|
20
|
+
} else {
|
|
21
|
+
properties = [listener]
|
|
22
|
+
Reflect.defineMetadata(KListeners, properties, target)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { HandlerAdapter } from '../interface'
|
|
2
1
|
import _ from 'lodash'
|
|
3
2
|
import { Registry } from './Registry'
|
|
3
|
+
import { Client, Message, User } from 'discord.js'
|
|
4
|
+
import { BuiltinCommandConverters, CommandHandler } from '../builtinModules'
|
|
4
5
|
|
|
5
6
|
export interface CommandOptions {
|
|
6
|
-
prefix:
|
|
7
|
-
| string
|
|
8
|
-
| ((msg: any) => string | Promise<string | string[]> | string[])
|
|
9
|
-
| string[]
|
|
7
|
+
prefix: string | ((msg: any) => string | Promise<string | string[]> | string[]) | string[]
|
|
10
8
|
}
|
|
11
9
|
|
|
12
10
|
export interface CommandClientOptions {
|
|
@@ -20,66 +18,40 @@ export interface CommandClientOptionsParam {
|
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
export class CommandClient {
|
|
23
|
-
adapter: HandlerAdapter<any>
|
|
24
21
|
options: CommandClientOptions
|
|
25
22
|
owners: string[] = []
|
|
26
23
|
registry = new Registry(this)
|
|
24
|
+
client: Client
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
const data = this.adapter.getCommandData(msg)
|
|
30
|
-
const prefixList: string[] | string =
|
|
31
|
-
typeof this.options.command.prefix === 'string'
|
|
32
|
-
? this.options.command.prefix
|
|
33
|
-
: typeof this.options.command.prefix === 'function'
|
|
34
|
-
? await this.options.command.prefix(msg)
|
|
35
|
-
: this.options.command.prefix
|
|
36
|
-
let prefix: string
|
|
37
|
-
if (typeof prefixList === 'object') {
|
|
38
|
-
const res = prefixList.find((x) => data.content.includes(x))
|
|
39
|
-
|
|
40
|
-
if (!res) return
|
|
41
|
-
|
|
42
|
-
prefix = res
|
|
43
|
-
} else {
|
|
44
|
-
if (!data.content.includes(prefixList)) return
|
|
45
|
-
prefix = prefixList
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const args = data.content.slice(prefix.length).split(' ')
|
|
49
|
-
|
|
50
|
-
const command = args.shift()
|
|
51
|
-
|
|
52
|
-
if (!command) return
|
|
26
|
+
private _isReady = false
|
|
53
27
|
|
|
54
|
-
|
|
55
|
-
|
|
28
|
+
private async fetchOwners(): Promise<string[]> {
|
|
29
|
+
await this.client.application?.fetch()
|
|
30
|
+
const o = this.client.application?.owner
|
|
31
|
+
if (!o) return []
|
|
32
|
+
if (o instanceof User) return [o.id]
|
|
33
|
+
else return o.members.map((x) => x.id)
|
|
56
34
|
}
|
|
57
35
|
|
|
58
|
-
private _isReady = false
|
|
59
|
-
|
|
60
36
|
async ready() {
|
|
61
37
|
if (this._isReady) return
|
|
62
38
|
this._isReady = true
|
|
63
39
|
if (this.options.owners === 'auto') {
|
|
64
|
-
const owners = await this.
|
|
40
|
+
const owners = await this.fetchOwners()
|
|
65
41
|
this.owners.push(...owners)
|
|
66
42
|
}
|
|
67
43
|
}
|
|
68
44
|
|
|
69
|
-
constructor({
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}: Partial<CommandClientOptionsParam> & { adapter: HandlerAdapter<any> }) {
|
|
73
|
-
this.adapter = adapter
|
|
74
|
-
this.options = _.merge<
|
|
75
|
-
Partial<CommandClientOptionsParam>,
|
|
76
|
-
CommandClientOptions
|
|
77
|
-
>(options, {
|
|
45
|
+
constructor({ client, ...options }: Partial<CommandClientOptionsParam> & { client: Client }) {
|
|
46
|
+
this.client = client
|
|
47
|
+
this.options = _.merge<Partial<CommandClientOptionsParam>, CommandClientOptions>(options, {
|
|
78
48
|
command: {
|
|
79
49
|
prefix: '!',
|
|
80
50
|
},
|
|
81
51
|
owners: 'auto',
|
|
82
52
|
})
|
|
83
|
-
|
|
53
|
+
this.client.once('ready', () => this.ready())
|
|
54
|
+
this.registry.registerModule(new CommandHandler(this.registry))
|
|
55
|
+
this.registry.registerModule(new BuiltinCommandConverters(this))
|
|
84
56
|
}
|
|
85
57
|
}
|
package/src/structures/Module.ts
CHANGED
|
@@ -1,4 +1,25 @@
|
|
|
1
|
+
import { KArgumentConverters, KCommands, KListeners, KModulePath } from '../constants'
|
|
2
|
+
import type { Command } from '../command'
|
|
3
|
+
import { Listener } from '../listener'
|
|
4
|
+
import { ArgumentConverter } from '../command'
|
|
5
|
+
|
|
1
6
|
export abstract class Module {
|
|
7
|
+
get commands(): Command[] {
|
|
8
|
+
return Reflect.getMetadata(KCommands, this) || []
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get listeners(): Listener[] {
|
|
12
|
+
return Reflect.getMetadata(KListeners, this) || []
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get argumentConverters(): ArgumentConverter[] {
|
|
16
|
+
return Reflect.getMetadata(KArgumentConverters, this) || []
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get path(): string | undefined {
|
|
20
|
+
return Reflect.getMetadata(KModulePath, this)
|
|
21
|
+
}
|
|
22
|
+
|
|
2
23
|
load() {}
|
|
3
24
|
unload() {}
|
|
4
25
|
beforeReload() {}
|