1- import type { APIApplicationCommand , APIApplicationCommandOption , ChatInputCommandInteraction , ClientOptions , RESTGetAPIApplicationCommandsResult , RESTPatchAPIApplicationCommandResult , RESTPutAPIApplicationCommandsResult } from 'discord.js'
2- import type { SlashCommandOption , SlashCommandOptionType , SlashCommandReturnType , SlashCommandRuntime } from '~/src/types'
1+ import type { APIApplicationCommand , APIApplicationCommandOption , ChatInputCommandInteraction , RESTGetAPIApplicationCommandsResult , RESTPatchAPIApplicationCommandResult , RESTPutAPIApplicationCommandsResult } from 'discord.js'
2+ import type { NuxtDiscordOptions , SlashCommandOption , SlashCommandOptionType , SlashCommandReturnType , SlashCommandRuntime } from '~/src/types'
33import process from 'node:process'
44import { ApplicationCommandOptionType , Events , Client as InternalClient , REST , Routes , SlashCommandBuilder } from 'discord.js'
55import { useNitroApp } from 'nitropack/runtime'
@@ -76,9 +76,11 @@ export class DiscordClient {
7676 } )
7777 }
7878
79- public async start ( options : ClientOptions ) : Promise < undefined > {
80- await this . #nitro. hooks . callHook ( 'discord:client:config' , options )
81- this . #client = new InternalClient ( options )
79+ #clientOptions?: NuxtDiscordOptions [ 'client' ]
80+ public async start ( options : NuxtDiscordOptions [ 'client' ] ) : Promise < undefined > {
81+ this . #clientOptions = { ...options }
82+ await this . #nitro. hooks . callHook ( 'discord:client:config' , this . #clientOptions)
83+ this . #client = new InternalClient ( this . #clientOptions)
8284 this . #client. on ( Events . InteractionCreate , ( interaction ) => {
8385 if ( ! interaction . isChatInputCommand ( ) )
8486 return
@@ -205,9 +207,14 @@ export class DiscordClient {
205207
206208 try {
207209 currentInteraction = interaction
208- const result = await command . execute ! ( ...args )
210+ const result = command . execute ! ( ...args )
209211 currentInteraction = null
210- this . #handleSlashCommandReturn( result , interaction , command )
212+
213+ if ( this . #clientOptions?. deferOnPromise && isPromise ( result ) ) {
214+ await interaction . deferReply ( )
215+ }
216+
217+ await this . #handleSlashCommandReturn( result , interaction , command )
211218 }
212219 catch ( error ) {
213220 this . #nitro. hooks . callHook ( 'discord:client:error' , {
@@ -222,11 +229,14 @@ export class DiscordClient {
222229
223230 async #handleSlashCommandReturn(
224231 // not sure why Awaited<SlashCommandReturnType> does't work here
225- result : Exclude < SlashCommandReturnType , Promise < SlashCommandReturnType > > ,
232+ result : SlashCommandReturnType ,
226233 interaction : ChatInputCommandInteraction ,
227234 command : SlashCommandRuntime ,
228235 // TODO: type this
229236 ) : Promise < unknown > {
237+ // @ts -expect-error - i don't know why this error occurs
238+ result = await result
239+
230240 if ( ! result ) {
231241 return
232242 }
@@ -237,7 +247,7 @@ export class DiscordClient {
237247 }
238248 else if ( typeof result === 'function' ) {
239249 const newResult = result . call ( this , interaction , this )
240- return this . #handleSlashCommandReturn( await newResult , interaction , command )
250+ return this . #handleSlashCommandReturn( newResult , interaction , command )
241251 }
242252 else if ( Symbol . iterator in result && typeof result [ Symbol . iterator ] === 'function' ) {
243253 const gen = result [ Symbol . iterator ] ( )
@@ -532,3 +542,8 @@ function optionEqual(a: SlashCommandOption, b: APIApplicationCommandOption): boo
532542
533543 return true
534544}
545+
546+ // https://stackoverflow.com/a/53955664/14835397
547+ export function isPromise ( value : any ) : value is Promise < unknown > {
548+ return typeof value ?. then === 'function'
549+ }
0 commit comments