feat(slash): add SlashModule and sub command support
This commit is contained in:
parent
e6be50cdc7
commit
3dcf57c658
6 changed files with 73 additions and 13 deletions
|
@ -14,6 +14,7 @@ import { ClientEvents } from '../gateway/handlers/index.ts'
|
|||
import { Extension } from './extensions.ts'
|
||||
import { SlashClient } from './slashClient.ts'
|
||||
import { Interaction } from '../structures/slash.ts'
|
||||
import { SlashModule } from './slashModule.ts'
|
||||
|
||||
/** OS related properties sent with Gateway Identify */
|
||||
export interface ClientProperties {
|
||||
|
@ -95,6 +96,8 @@ export class Client extends EventEmitter {
|
|||
handler: (interaction: Interaction) => any
|
||||
}>
|
||||
|
||||
_decoratedSlashModules?: SlashModule[]
|
||||
|
||||
private readonly _untypedOn = this.on
|
||||
|
||||
private readonly _untypedEmit = this.emit
|
||||
|
@ -206,18 +209,34 @@ export function event(name?: string) {
|
|||
const listener = ((client as unknown) as {
|
||||
[name: string]: (...args: any[]) => any
|
||||
})[prop]
|
||||
if (typeof listener !== 'function')
|
||||
throw new Error('@event decorator requires a function')
|
||||
if (client._decoratedEvents === undefined) client._decoratedEvents = {}
|
||||
client._decoratedEvents[name === undefined ? prop : name] = listener
|
||||
}
|
||||
}
|
||||
|
||||
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 = []
|
||||
client._decoratedSlash.push({
|
||||
name: name ?? prop,
|
||||
guild,
|
||||
handler: (client as { [name: string]: any })[prop]
|
||||
})
|
||||
const item = (client as { [name: string]: any })[prop]
|
||||
if (typeof item !== 'function') {
|
||||
client._decoratedSlash.push(item)
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,18 +383,26 @@ export class CommandClient extends Client implements CommandClientOptions {
|
|||
|
||||
export function command(options?: CommandOptions) {
|
||||
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()
|
||||
|
||||
command.name = name
|
||||
command.execute = ((target as unknown) as {
|
||||
[name: string]: (ctx: CommandContext) => any
|
||||
})[name]
|
||||
command.execute = prop
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
APPLICATION_GUILD_COMMANDS
|
||||
} from '../types/endpoint.ts'
|
||||
import {
|
||||
InteractionType,
|
||||
SlashCommandOption,
|
||||
SlashCommandPartial,
|
||||
SlashCommandPayload
|
||||
|
@ -199,9 +200,12 @@ export class SlashClient {
|
|||
return this
|
||||
}
|
||||
|
||||
process(interaction: Interaction): any {
|
||||
/** Process an incoming Slash Command (interaction) */
|
||||
private process(interaction: Interaction): void {
|
||||
if (!this.enabled) return
|
||||
|
||||
if (interaction.type !== InteractionType.APPLICATION_COMMAND) return
|
||||
|
||||
let cmd
|
||||
|
||||
if (interaction.guild !== undefined)
|
||||
|
|
18
src/models/slashModule.ts
Normal file
18
src/models/slashModule.ts
Normal 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
|
||||
}
|
||||
}
|
|
@ -76,7 +76,7 @@ export class Interaction {
|
|||
return this.data.name
|
||||
}
|
||||
|
||||
option(name: string): any {
|
||||
option<T = any>(name: string): T {
|
||||
return this.data.options.find((e) => e.name === name)?.value
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,16 @@ export class Interaction {
|
|||
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 {
|
||||
return `https://discord.com/api/v8/webhooks/${this.client.user?.id}/${this.token}`
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ export interface InteractionOption {
|
|||
}
|
||||
|
||||
export interface InteractionData {
|
||||
options: InteractionOption[]
|
||||
name: string
|
||||
id: string
|
||||
options: InteractionOption[]
|
||||
}
|
||||
|
||||
export enum InteractionType {
|
||||
|
@ -50,6 +50,7 @@ export interface SlashCommandOption {
|
|||
type: SlashCommandOptionType
|
||||
required: boolean
|
||||
choices?: SlashCommandChoice[]
|
||||
options?: SlashCommandOption[]
|
||||
}
|
||||
|
||||
export interface SlashCommandPartial {
|
||||
|
|
Loading…
Reference in a new issue