You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
5.0 KiB
154 lines
5.0 KiB
import {
|
|
ApplicationCommand,
|
|
ApplicationCommandSubCommandData,
|
|
ApplicationCommandSubGroupData,
|
|
ChatInputApplicationCommandData,
|
|
ChatInputCommandInteraction,
|
|
} from "discord.js"
|
|
|
|
export const noSubcommandError = "No subcommand was provided, but one is required."
|
|
export const invalidSubcommandGroupError = "The subcommand group provided does not exist."
|
|
export const invalidSubcommandError = "The subcommand provided does not exist."
|
|
|
|
export const adminId = "126936953789743104"
|
|
|
|
export abstract class CommandData {
|
|
private _cachedGlobal: ApplicationCommand | null = null
|
|
private _cacheByGuild: Record<string, ApplicationCommand> = {}
|
|
|
|
abstract get definition(): ChatInputApplicationCommandData
|
|
|
|
getCached(guildId: string | null): ApplicationCommand {
|
|
if (guildId === null) {
|
|
if (this._cachedGlobal === null) {
|
|
throw Error("Not yet cached")
|
|
}
|
|
return this._cachedGlobal
|
|
} else if (this._cacheByGuild.hasOwnProperty(guildId)) {
|
|
return this._cacheByGuild[guildId]
|
|
} else {
|
|
throw Error("Not yet cached")
|
|
}
|
|
}
|
|
|
|
setCached(command: ApplicationCommand) {
|
|
if (command.guildId === null) {
|
|
this._cachedGlobal = command
|
|
} else {
|
|
this._cacheByGuild[command.guildId] = command
|
|
}
|
|
}
|
|
|
|
abstract execute(b: ChatInputCommandInteraction): Promise<void>
|
|
}
|
|
|
|
export type BaseChatInputCommandData = Omit<ChatInputApplicationCommandData, "options">
|
|
|
|
export abstract class CommandWithSubcommandsData extends CommandData {
|
|
private _subcommandGroupsCache: Record<string, SubcommandGroupData> | null = null
|
|
private _subcommandsCache: Record<string, SubcommandData> | null = null
|
|
|
|
get definition(): ChatInputApplicationCommandData {
|
|
return {
|
|
options: this.subcommands.map((s) => s.definition),
|
|
...this.baseDefinition,
|
|
}
|
|
}
|
|
|
|
protected abstract get baseDefinition(): BaseChatInputCommandData
|
|
|
|
protected abstract get subcommands(): (SubcommandData | SubcommandGroupData)[]
|
|
|
|
async execute(b: ChatInputCommandInteraction) {
|
|
const group = b.options.getSubcommandGroup()
|
|
const subcommand = b.options.getSubcommand()
|
|
if (group !== null) {
|
|
await this.resolveSubcommandGroup(group).execute(b)
|
|
} else if (subcommand !== null) {
|
|
await this.resolveSubcommand(subcommand).execute(b)
|
|
} else {
|
|
throw noSubcommandError
|
|
}
|
|
}
|
|
|
|
protected resolveSubcommandGroup(name: string): SubcommandGroupData {
|
|
let cache = this._subcommandGroupsCache
|
|
if (cache === null) {
|
|
cache = {}
|
|
for (const item of this.subcommands) {
|
|
if (item instanceof SubcommandGroupData) {
|
|
cache[item.definition.name] = item
|
|
}
|
|
}
|
|
this._subcommandGroupsCache = cache
|
|
}
|
|
if (!cache.hasOwnProperty(name)) {
|
|
throw invalidSubcommandGroupError
|
|
}
|
|
return cache[name]
|
|
}
|
|
|
|
protected resolveSubcommand(name: string): SubcommandData {
|
|
let cache = this._subcommandsCache
|
|
if (cache === null) {
|
|
cache = {}
|
|
for (const item of this.subcommands) {
|
|
if (item instanceof SubcommandData) {
|
|
cache[item.definition.name] = item
|
|
}
|
|
}
|
|
this._subcommandsCache = cache
|
|
}
|
|
if (!cache.hasOwnProperty(name)) {
|
|
throw invalidSubcommandGroupError
|
|
}
|
|
return cache[name]
|
|
}
|
|
}
|
|
|
|
export type BaseSubcommandGroupData = Omit<ApplicationCommandSubGroupData, "options">
|
|
|
|
export abstract class SubcommandGroupData {
|
|
private _subcommandsCache: Record<string, SubcommandData> | null = null
|
|
|
|
get definition(): ApplicationCommandSubGroupData {
|
|
return {
|
|
...this.baseDefinition,
|
|
options: this.subcommands.map((s) => s.definition),
|
|
}
|
|
}
|
|
|
|
protected abstract get baseDefinition(): BaseSubcommandGroupData
|
|
|
|
protected abstract get subcommands(): SubcommandData[]
|
|
|
|
async execute(b: ChatInputCommandInteraction): Promise<void> {
|
|
const subcommand = b.options.getSubcommand()
|
|
if (subcommand !== null) {
|
|
await this.resolveSubcommand(subcommand).execute(b)
|
|
} else {
|
|
throw noSubcommandError
|
|
}
|
|
}
|
|
|
|
protected resolveSubcommand(name: string): SubcommandData {
|
|
let cache = this._subcommandsCache
|
|
if (cache === null) {
|
|
cache = {}
|
|
for (const item of this.subcommands) {
|
|
cache[item.definition.name] = item
|
|
}
|
|
this._subcommandsCache = cache
|
|
}
|
|
if (!cache.hasOwnProperty(name)) {
|
|
throw invalidSubcommandError
|
|
}
|
|
return cache[name]
|
|
}
|
|
}
|
|
|
|
export abstract class SubcommandData {
|
|
abstract get definition(): ApplicationCommandSubCommandData
|
|
|
|
abstract execute(b: ChatInputCommandInteraction): Promise<void>
|
|
} |