feat(extensions): add sub prefix

This commit is contained in:
DjDeveloperr 2020-12-08 12:13:06 +05:30
parent 1119379fb5
commit 0eadfd829e
6 changed files with 92 additions and 35 deletions

View file

@ -9,6 +9,7 @@ export const ready: GatewayEventHandler = async (
) => {
await gateway.client.guilds.flush()
await gateway.client.users.set(d.user.id, d.user)
gateway.client.user = new User(gateway.client, d.user)
gateway.sessionID = d.session_id
gateway.debug(`Received READY. Session: ${gateway.sessionID}`)

View file

@ -139,21 +139,6 @@ export class Client extends EventEmitter {
this.emit('debug', `[${tag}] ${msg}`)
}
/**
* EXPERIMENTAL Decorators support for listening to events.
* @param event Event name to listen for
*/
event(event: string): CallableFunction {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const parent = this
return function (
target: { [name: string]: CallableFunction },
prop: string
) {
parent.addListener(event, target[prop] as (...args: any[]) => any)
}
}
// TODO(DjDeveloperr): Implement this
// fetchApplication(): Promise<Application>

View file

@ -101,7 +101,7 @@ export class Command implements CommandOptions {
toString(): string {
return `Command: ${this.name}${
this.extension !== undefined
this.extension !== undefined && this.extension.name !== ''
? ` [${this.extension.name}]`
: this.category !== undefined
? ` [${this.category}]`
@ -290,38 +290,86 @@ export class CommandsManager {
return this.list.size
}
/** Find a Command by name/alias */
find(search: string): Command | undefined {
/** Filter out Commands by name/alias */
filter(search: string, subPrefix?: string): Collection<string, Command> {
if (this.client.caseSensitive === false) search = search.toLowerCase()
return this.list.find((cmd: Command): boolean => {
return this.list.filter((cmd: Command): boolean => {
if (subPrefix !== undefined) {
if (
this.client.caseSensitive === true
? subPrefix !== cmd.extension?.subPrefix
: subPrefix.toLowerCase() !==
cmd.extension?.subPrefix?.toLowerCase()
) {
return false
}
} else if (
subPrefix === undefined &&
cmd.extension?.subPrefix !== undefined
) {
return false
}
const name =
this.client.caseSensitive === true ? cmd.name : cmd.name.toLowerCase()
if (name === search) return true
else if (cmd.aliases !== undefined) {
if (name === search) {
return true
} else if (cmd.aliases !== undefined) {
let aliases: string[]
if (typeof cmd.aliases === 'string') aliases = [cmd.aliases]
else aliases = cmd.aliases
if (this.client.caseSensitive === false)
aliases = aliases.map((e) => e.toLowerCase())
return aliases.includes(search)
} else return false
} else {
return false
}
})
}
/** Fetch a Command including disable checks */
fetch(name: string, bypassDisable?: boolean): Command | undefined {
const cmd = this.find(name)
/** Find a Command by name/alias */
find(search: string, subPrefix?: string): Command | undefined {
const filtered = this.filter(search, subPrefix)
return filtered.first()
}
/** Fetch a Command including disable checks and subPrefix implementation */
fetch(parsed: ParsedCommand, bypassDisable?: boolean): Command | undefined {
let cmd = this.find(parsed.name)
if (cmd?.extension?.subPrefix !== undefined) cmd = undefined
if (cmd === undefined && parsed.args.length > 0) {
cmd = this.find(parsed.args[0], parsed.name)
if (cmd === undefined || cmd.extension?.subPrefix === undefined) return
if (
this.client.caseSensitive === true
? cmd.extension.subPrefix !== parsed.name
: cmd.extension.subPrefix.toLowerCase() !== parsed.name.toLowerCase()
)
return
parsed.args.shift()
}
if (cmd === undefined) return
if (this.isDisabled(cmd) && bypassDisable !== true) return
return cmd
}
/** Check whether a Command exists or not */
exists(search: Command | string): boolean {
exists(search: Command | string, subPrefix?: string): boolean {
let exists = false
if (typeof search === 'string') return this.find(search) !== undefined
if (typeof search === 'string')
return this.find(search, subPrefix) !== undefined
else {
exists = this.find(search.name) !== undefined
exists =
this.find(
search.name,
subPrefix === undefined ? search.extension?.subPrefix : subPrefix
) !== undefined
if (search.aliases !== undefined) {
const aliases: string[] =
typeof search.aliases === 'string' ? [search.aliases] : search.aliases
@ -330,6 +378,7 @@ export class CommandsManager {
.map((alias) => this.find(alias) !== undefined)
.find((e) => e) ?? false
}
return exists
}
}
@ -338,11 +387,20 @@ export class CommandsManager {
add(cmd: Command | typeof Command): boolean {
// eslint-disable-next-line new-cap
if (!(cmd instanceof Command)) cmd = new cmd()
if (this.exists(cmd))
if (this.exists(cmd, cmd.extension?.subPrefix))
throw new Error(
`Failed to add Command '${cmd.toString()}' with name/alias already exists.`
)
this.list.set(cmd.name, cmd)
this.list.set(
`${cmd.name}-${
this.list.filter((e) =>
this.client.caseSensitive === true
? e.name === cmd.name
: e.name.toLowerCase() === cmd.name.toLowerCase()
).size
}`,
cmd
)
return true
}

View file

@ -164,7 +164,7 @@ export class CommandClient extends Client implements CommandClientOptions {
if (typeof prefix !== 'string') return
const parsed = parseCommand(this, msg, prefix)
const command = this.commands.find(parsed.name)
const command = this.commands.fetch(parsed)
if (command === undefined) return
const category =
@ -362,6 +362,8 @@ export function command(options?: CommandOptions) {
if (options !== undefined) Object.assign(command, options)
if (target instanceof Extension) command.extension = target
if (target._decoratedCommands === undefined) target._decoratedCommands = {}
target._decoratedCommands[command.name] = command
}

View file

@ -67,6 +67,8 @@ export class Extension {
description?: string
/** Extensions's Commands Manager */
commands: ExtensionCommands = new ExtensionCommands(this)
/** Sub-Prefix to be used for ALL of Extenion's Commands. */
subPrefix?: string
/** Events registered by this Extension */
events: { [name: string]: (...args: any[]) => {} } = {}
@ -77,6 +79,7 @@ export class Extension {
this.client = client
if (this._decoratedCommands !== undefined) {
Object.entries(this._decoratedCommands).forEach((entry) => {
entry[1].extension = this
this.commands.add(entry[1])
})
this._decoratedCommands = undefined

View file

@ -4,7 +4,8 @@ import {
Intents,
command,
CommandContext,
Extension
Extension,
CommandBuilder
} from '../../mod.ts'
import { TOKEN } from './config.ts'
@ -21,15 +22,16 @@ class MyClient extends CommandClient {
console.log(`Logged in as ${this.user?.tag}!`)
}
@command({
aliases: 'pong'
})
@command({ aliases: 'pong' })
Ping(ctx: CommandContext): void {
ctx.message.reply('Pong!')
}
}
class VCExtension extends Extension {
name = 'VC'
subPrefix = 'vc'
@command()
async join(ctx: CommandContext): Promise<void> {
const userVS = await ctx.guild?.voiceStates.get(ctx.author.id)
@ -59,4 +61,10 @@ const client = new MyClient()
client.extensions.load(VCExtension)
client.commands.add(
new CommandBuilder()
.setName('join')
.onExecute((ctx) => ctx.message.reply('haha'))
)
client.connect(TOKEN, Intents.All)