feat(slash): add SlashModule and sub command support

This commit is contained in:
DjDeveloperr 2020-12-12 17:57:35 +05:30
parent e6be50cdc7
commit 3dcf57c658
6 changed files with 73 additions and 13 deletions

View file

@ -14,6 +14,7 @@ import { ClientEvents } from '../gateway/handlers/index.ts'
import { Extension } from './extensions.ts' import { Extension } from './extensions.ts'
import { SlashClient } from './slashClient.ts' import { SlashClient } from './slashClient.ts'
import { Interaction } from '../structures/slash.ts' import { Interaction } from '../structures/slash.ts'
import { SlashModule } from './slashModule.ts'
/** OS related properties sent with Gateway Identify */ /** OS related properties sent with Gateway Identify */
export interface ClientProperties { export interface ClientProperties {
@ -95,6 +96,8 @@ export class Client extends EventEmitter {
handler: (interaction: Interaction) => any handler: (interaction: Interaction) => any
}> }>
_decoratedSlashModules?: SlashModule[]
private readonly _untypedOn = this.on private readonly _untypedOn = this.on
private readonly _untypedEmit = this.emit private readonly _untypedEmit = this.emit
@ -206,18 +209,34 @@ export function event(name?: string) {
const listener = ((client as unknown) as { const listener = ((client as unknown) as {
[name: string]: (...args: any[]) => any [name: string]: (...args: any[]) => any
})[prop] })[prop]
if (typeof listener !== 'function')
throw new Error('@event decorator requires a function')
if (client._decoratedEvents === undefined) client._decoratedEvents = {} if (client._decoratedEvents === undefined) client._decoratedEvents = {}
client._decoratedEvents[name === undefined ? prop : name] = listener client._decoratedEvents[name === undefined ? prop : name] = listener
} }
} }
export function slash(name?: string, guild?: string) { export function slash(name?: string, guild?: string) {
return function (client: Client, prop: string) { return function (client: Client | SlashModule, prop: string) {
if (client._decoratedSlash === undefined) client._decoratedSlash = [] if (client._decoratedSlash === undefined) client._decoratedSlash = []
client._decoratedSlash.push({ const item = (client as { [name: string]: any })[prop]
name: name ?? prop, if (typeof item !== 'function') {
guild, client._decoratedSlash.push(item)
handler: (client as { [name: string]: any })[prop] } else
}) client._decoratedSlash.push({
name: name ?? prop,
guild,
handler: item
})
}
}
export function slashModule() {
return function (client: Client, prop: string) {
if (client._decoratedSlashModules === undefined)
client._decoratedSlashModules = []
const mod = ((client as unknown) as { [key: string]: any })[prop]
client._decoratedSlashModules.push(mod)
} }
} }

View file

@ -383,18 +383,26 @@ export class CommandClient extends Client implements CommandClientOptions {
export function command(options?: CommandOptions) { export function command(options?: CommandOptions) {
return function (target: CommandClient | Extension, name: string) { return function (target: CommandClient | Extension, name: string) {
if (target._decoratedCommands === undefined) target._decoratedCommands = {}
const prop = ((target as unknown) as {
[name: string]: (ctx: CommandContext) => any
})[name]
if (prop instanceof Command) {
target._decoratedCommands[prop.name] = prop
return
}
const command = new Command() const command = new Command()
command.name = name command.name = name
command.execute = ((target as unknown) as { command.execute = prop
[name: string]: (ctx: CommandContext) => any
})[name]
if (options !== undefined) Object.assign(command, options) if (options !== undefined) Object.assign(command, options)
if (target instanceof Extension) command.extension = target if (target instanceof Extension) command.extension = target
if (target._decoratedCommands === undefined) target._decoratedCommands = {}
target._decoratedCommands[command.name] = command target._decoratedCommands[command.name] = command
} }
} }

View file

@ -7,6 +7,7 @@ import {
APPLICATION_GUILD_COMMANDS APPLICATION_GUILD_COMMANDS
} from '../types/endpoint.ts' } from '../types/endpoint.ts'
import { import {
InteractionType,
SlashCommandOption, SlashCommandOption,
SlashCommandPartial, SlashCommandPartial,
SlashCommandPayload SlashCommandPayload
@ -199,9 +200,12 @@ export class SlashClient {
return this return this
} }
process(interaction: Interaction): any { /** Process an incoming Slash Command (interaction) */
private process(interaction: Interaction): void {
if (!this.enabled) return if (!this.enabled) return
if (interaction.type !== InteractionType.APPLICATION_COMMAND) return
let cmd let cmd
if (interaction.guild !== undefined) if (interaction.guild !== undefined)

18
src/models/slashModule.ts Normal file
View file

@ -0,0 +1,18 @@
import { SlashCommandHandler } from './slashClient.ts'
export class SlashModule {
name: string = ''
commands: SlashCommandHandler[] = []
_decoratedSlash?: SlashCommandHandler[]
constructor() {
if (this._decoratedSlash !== undefined) {
this.commands = this._decoratedSlash
}
}
add(handler: SlashCommandHandler): SlashModule {
this.commands.push(handler)
return this
}
}

View file

@ -76,7 +76,7 @@ export class Interaction {
return this.data.name return this.data.name
} }
option(name: string): any { option<T = any>(name: string): T {
return this.data.options.find((e) => e.name === name)?.value return this.data.options.find((e) => e.name === name)?.value
} }
@ -121,6 +121,16 @@ export class Interaction {
return this return this
} }
async deleteResponse(): Promise<Interaction> {
const url = WEBHOOK_MESSAGE(
this.client.user?.id as string,
this.token,
'@original'
)
await this.client.rest.delete(url)
return this
}
get url(): string { get url(): string {
return `https://discord.com/api/v8/webhooks/${this.client.user?.id}/${this.token}` return `https://discord.com/api/v8/webhooks/${this.client.user?.id}/${this.token}`
} }

View file

@ -8,9 +8,9 @@ export interface InteractionOption {
} }
export interface InteractionData { export interface InteractionData {
options: InteractionOption[]
name: string name: string
id: string id: string
options: InteractionOption[]
} }
export enum InteractionType { export enum InteractionType {
@ -50,6 +50,7 @@ export interface SlashCommandOption {
type: SlashCommandOptionType type: SlashCommandOptionType
required: boolean required: boolean
choices?: SlashCommandChoice[] choices?: SlashCommandChoice[]
options?: SlashCommandOption[]
} }
export interface SlashCommandPartial { export interface SlashCommandPartial {