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 { 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
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
|
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}`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue