joining NestedCommand and ChatCommand

This commit is contained in:
mmacierzanka committed 2021-09-23 20:21:28 +02:00
1 parent b39ec45fa5
commit ad8da005bc
4 files changed
+112 -9

No files matched your search

+105 -4
View File
@@ -1,17 +1,22 @@
import { Message, Interaction } from "discord.js";
import { ChatCommandInit } from "./types/InitOptions.js";
import { Message, Interaction, CommandInteractionOption } from "discord.js";
import { ChatCommandInit, SubCommandGroupInit, SubCommandInit } from "./types/InitOptions.js";
import { DefaultParameter, Parameter, TargetID } from "../structures/parameter.js";
import { ChatCommandObject, TextCommandOptionChoiceObject, ChatCommandOptionObject, ChatCommandOptionType } from "../structures/types/api.js";
import { ParameterResolvable } from "../structures/types/Parameter.js";
import { CommandRegExps } from "./types/commands.js";
import { ChildCommandInit, ChildCommandResolvable, ChildCommands, ChildCommandType, CommandInteractionData, CommandRegExps } from "./types/commands.js";
import { CommandManager } from "../structures/CommandManager.js";
import { PermissionGuildCommand } from "./base/PermissionGuildCommand.js";
import { generateUsageFromArguments } from "../utils/generateUsageFromArguments.js";
import { SubCommand } from "./SubCommand.js";
import { SubCommandGroup } from "./SubCommandGroup.js";
import { applicationState } from "../state.js";
import { processArguments } from "../utils/processArguments.js";
/**
* @class A representation of CHAT_INPUT command (also known as a slash command)
*/
export class ChatCommand extends PermissionGuildCommand {
private readonly _children: ChildCommandResolvable[] = [];
/**
* List of parameters that can passed to this command
* @type {Array} {@link Parameter}
@@ -101,6 +106,10 @@ export class ChatCommand extends PermissionGuildCommand {
}
}
get hasSubCommands() {
return this._children.length > 0;
}
/**
* Invoke the command
* @param {ReadonlyMap<string, ParameterResolvable>} args - map of arguments from Discord message or interaction
@@ -114,6 +123,86 @@ export class ChatCommand extends PermissionGuildCommand {
await super.start(args, interaction, target);
}
public append<T extends ChildCommandType>(type: T, options: ChildCommandInit<T>): ChildCommands<T> {
const command =
type === "COMMAND"
? (new SubCommand(this, options as SubCommandInit) as ChildCommands<T>)
: type === "GROUP"
? (new SubCommandGroup(this, options as SubCommandGroupInit) as ChildCommands<T>)
: null;
if (!command) {
throw new Error("Incorrect command type");
}
if (applicationState.running) {
console.warn(`[❌ ERROR] Cannot add command "${command.name}" while the application is running.`);
return command;
}
this._children.push(command);
return command;
}
public fetchSubcommand(options: CommandInteractionOption[]): CommandInteractionData | null {
if (!this.hasSubCommands) return null;
if (options[0]) {
if (options[0].type === "SUB_COMMAND_GROUP") {
const grName = options[0].name;
const group = this._children.filter((c) => c instanceof SubCommandGroup).find((c) => c.name === grName) as SubCommandGroup;
const scOpt = options[0].options;
if (group && scOpt) {
const scName = scOpt[0].name;
const cmd = group.children.filter((c) => c instanceof SubCommand).find((c) => c.name === scName) as SubCommand;
if (cmd && scOpt[0].options) {
return {
command: cmd,
parameters:
processArguments(
cmd,
scOpt[0].options.map((o) => o.value || null)
) || new Map(),
};
} else {
return null;
}
} else {
return null;
}
} else if (options[0].type === "SUB_COMMAND") {
const cmd = this._children.filter((c) => c instanceof SubCommand).find((c) => c.name === options[0].name) as SubCommand;
if (cmd) {
return {
command: cmd,
parameters: options[0].options
? processArguments(
cmd,
options[0].options.map((o) => o.value || null)
)
: new Map(),
};
} else {
return null;
}
} else {
return null;
}
} else {
return null;
}
}
public getSubcommand(name: string, group?: string): SubCommand | null {
if (!this.hasSubCommands) return null;
if (group) {
const gr = this._children.filter((c) => c instanceof SubCommandGroup).find((g) => g.name === group) as SubCommandGroup;
if (gr) {
return gr.children.find((c) => c.name === name) || null;
} else {
return null;
}
} else {
return (this._children.filter((c) => c instanceof SubCommand).find((c) => c.name === name) as SubCommand) || null;
}
}
/**
* Converts {@link ChatCommand} instance to object that is recognized by the Discord API
* @returns {ChatCommandObject} object
@@ -179,7 +268,19 @@ export class ChatCommand extends PermissionGuildCommand {
}
return 0;
});
obj.options = options;
let subCmds: ChatCommandOptionObject[] = [];
if (this.hasSubCommands) {
subCmds = this._children.map((sc) => {
return {
name: sc.name,
default_permission: true,
description: sc.description,
options: [sc.toObject()],
type: sc instanceof SubCommandGroup ? 2 : 1,
};
});
}
obj.options = [...subCmds, ...options];
}
return obj;
}
+3 -2
View File
@@ -8,9 +8,10 @@ import { SubCommandInit } from "./types/InitOptions.js";
import { ChatCommandObject, ChatCommandOptionObject, ChatCommandOptionType, TextCommandOptionChoiceObject } from "../structures/types/api.js";
import { ParameterResolvable } from "../structures/types/Parameter.js";
import { Interaction, Message } from "discord.js";
import { ChatCommand } from "./ChatCommand.js";
export class SubCommand extends PermissionCommand {
private readonly _parent: SubCommandGroup | NestedCommand;
private readonly _parent: SubCommandGroup | NestedCommand | ChatCommand;
/**
* Command description displayed in the help message or in slash commands menu (Default description: "No description")
* @type {string}
@@ -27,7 +28,7 @@ export class SubCommand extends PermissionCommand {
*/
public readonly usage?: string;
constructor(parent: SubCommandGroup | NestedCommand, options: SubCommandInit) {
constructor(parent: SubCommandGroup | NestedCommand | ChatCommand, options: SubCommandInit) {
super(parent instanceof SubCommandGroup ? parent.parent.manager : parent.manager, "CHAT", {
name: options.name,
announceSuccess: options.announceSuccess,
+3 -2
View File
@@ -1,16 +1,17 @@
import { SubCommandGroupObject } from "../structures/types/api.js";
import { Command } from "./base/Command.js";
import { ChatCommand } from "./ChatCommand.js";
import { NestedCommand } from "./NestedCommand.js";
import { SubCommand } from "./SubCommand.js";
import { CommandRegExps } from "./types/commands.js";
import { SubCommandInit, SubCommandGroupInit } from "./types/InitOptions.js";
export class SubCommandGroup extends Command {
protected readonly _parent: NestedCommand;
protected readonly _parent: NestedCommand | ChatCommand;
private readonly _children: SubCommand[] = [];
public readonly description: string;
constructor(parent: NestedCommand, options: SubCommandGroupInit) {
constructor(parent: NestedCommand | ChatCommand, options: SubCommandGroupInit) {
super(parent.manager, "CHAT", {
name: options.name,
default_permission: options.default_permission,
+1 -1
View File
@@ -20,7 +20,7 @@ export interface ChatCommandOptionObject {
options?: ChatCommandOptionObject[];
}
export type ChatCommandOptionType = 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
export type ChatCommandOptionType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
export interface TextCommandOptionChoiceObject {
name: string;