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…
	
	Add table
		Add a link
		
	
		Reference in a new issue