feat: Thoroughly type ContextCommand
This commit is contained in:
parent
f83a6dd1a3
commit
c1670b8abd
3 changed files with 20 additions and 8 deletions
|
|
@ -1,11 +1,15 @@
|
||||||
import { AutocompleteFocusedOption, AutocompleteInteraction, ChatInputCommandInteraction, ContextMenuCommandBuilder, ContextMenuCommandInteraction, SharedSlashCommand, Snowflake, User } from "discord.js";
|
import { ApplicationCommandType, AutocompleteFocusedOption, AutocompleteInteraction, ChatInputCommandInteraction, ContextMenuCommandBuilder, ContextMenuCommandInteraction, Message, SharedSlashCommand, Snowflake, User } from "discord.js";
|
||||||
import { Config } from "./config";
|
import { Config } from "./config";
|
||||||
|
|
||||||
export abstract class ICommand { }
|
export abstract class ICommand { }
|
||||||
|
|
||||||
export abstract class ContextCommand extends ICommand {
|
export abstract class ContextCommand<T extends User | Message> extends ICommand {
|
||||||
|
abstract targetType:
|
||||||
|
T extends User ? ApplicationCommandType.User :
|
||||||
|
T extends Message ? ApplicationCommandType.Message :
|
||||||
|
never;
|
||||||
abstract contextDefinition: ContextMenuCommandBuilder
|
abstract contextDefinition: ContextMenuCommandBuilder
|
||||||
abstract run(interaction: ContextMenuCommandInteraction, target: Snowflake): Promise<void>
|
abstract run(interaction: ContextMenuCommandInteraction, target: T extends User ? User : T extends Message ? Message : never): Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class Command extends ICommand {
|
export abstract class Command extends ICommand {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
import { ApplicationCommandType, ContextMenuCommandBuilder, ContextMenuCommandInteraction, InteractionContextType, Snowflake } from "discord.js";
|
import { ApplicationCommandType, ContextMenuCommandBuilder, ContextMenuCommandInteraction, InteractionContextType, Snowflake, User } from "discord.js";
|
||||||
import { ContextCommand } from "../command.ts";
|
import { ContextCommand } from "../command.ts";
|
||||||
|
|
||||||
export default class RailUser extends ContextCommand {
|
export default class RailUser extends ContextCommand<User> {
|
||||||
|
targetType: ApplicationCommandType.User = ApplicationCommandType.User;
|
||||||
contextDefinition: ContextMenuCommandBuilder =
|
contextDefinition: ContextMenuCommandBuilder =
|
||||||
new ContextMenuCommandBuilder()
|
new ContextMenuCommandBuilder()
|
||||||
.setName('rail')
|
.setName('rail')
|
||||||
.setType(ApplicationCommandType.User)
|
.setType(ApplicationCommandType.User)
|
||||||
async run(interaction: ContextMenuCommandInteraction, target: Snowflake): Promise<void> {
|
async run(interaction: ContextMenuCommandInteraction, target: User): Promise<void> {
|
||||||
await interaction.reply(`Raililng <@${target}>.`)
|
await interaction.reply(`Raililng <@${target.id}>.`)
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
await interaction.editReply(`UHGhghgghghgh. Railing successfull.`)
|
await interaction.editReply(`UHGhghgghghgh. Railing successfull.`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import {
|
import {
|
||||||
|
ApplicationCommand,
|
||||||
|
ApplicationCommandType,
|
||||||
Client,
|
Client,
|
||||||
Events,
|
Events,
|
||||||
GatewayIntentBits,
|
GatewayIntentBits,
|
||||||
|
|
@ -43,6 +45,8 @@ const contextCommands = allCommands.filter(it => it instanceof ContextCommand);
|
||||||
const contextCommandLUT = Object.fromEntries(contextCommands.map(it => [it.contextDefinition.name, it]))
|
const contextCommandLUT = Object.fromEntries(contextCommands.map(it => [it.contextDefinition.name, it]))
|
||||||
const commandLookup = Object.fromEntries(commands.map(it => [it.slashCommand.name, it]))
|
const commandLookup = Object.fromEntries(commands.map(it => [it.slashCommand.name, it]))
|
||||||
|
|
||||||
|
contextCommands.forEach(it => it.contextDefinition.type === it.targetType)
|
||||||
|
|
||||||
function makeDefaultAvailableEverywhere<T extends { setContexts(...contexts: Array<InteractionContextType>): any, readonly contexts?: InteractionContextType[] }>(t: T): T {
|
function makeDefaultAvailableEverywhere<T extends { setContexts(...contexts: Array<InteractionContextType>): any, readonly contexts?: InteractionContextType[] }>(t: T): T {
|
||||||
if (!t.contexts)
|
if (!t.contexts)
|
||||||
t.setContexts(InteractionContextType.BotDM, InteractionContextType.Guild, InteractionContextType.PrivateChannel)
|
t.setContexts(InteractionContextType.BotDM, InteractionContextType.Guild, InteractionContextType.PrivateChannel)
|
||||||
|
|
@ -69,8 +73,11 @@ client.on(Events.InteractionCreate, async (interaction) => {
|
||||||
console.error("unknown context command: " + commandName)
|
console.error("unknown context command: " + commandName)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// The <any> cast here is valid, since the type of the interaction is set in accordance to the definition
|
||||||
|
if (command.targetType != (interaction.isUserContextMenuCommand() ? ApplicationCommandType.User : ApplicationCommandType.Message))
|
||||||
|
console.error("Out of date discord definition of this context command")
|
||||||
try {
|
try {
|
||||||
await command.run(interaction, interaction.targetId)
|
await command.run(interaction, interaction.isUserContextMenuCommand() ? interaction.targetUser : interaction.targetMessage)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("error during context command execution: " + commandName, e)
|
console.error("error during context command execution: " + commandName, e)
|
||||||
interaction.reply("something sharted itself")
|
interaction.reply("something sharted itself")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue