MessageCommand

This commit is contained in:
mmacierzanka committed 2021-09-04 19:17:51 +02:00
1 parent e7ce848325
commit d898ddc81d
6 files changed
+69 -36

No files matched your search

+36 -33
View File
@@ -1,15 +1,19 @@
import { CommandInteraction, Message } from "discord.js"; import { CommandInteraction, Message } from "discord.js";
import { BaseCommand } from "../structures/BaseCommand.js";
import { MissingParameterError } from "../errors.js"; import { MissingParameterError } from "../errors.js";
import { BooleanParameter, InputParameter, NumberParameter, ObjectParameter, StringParameter } from "../structures/Parameter.js"; import { BooleanParameter, InputParameter, NumberParameter, ObjectParameter, StringParameter } from "../structures/Parameter.js";
import { TextCommand } from "../structures/TextCommand.js"; import { TextCommand } from "../structures/TextCommand.js";
import { CommandMessageStructure, PhraseOccurrenceData } from "../types/TextCommand.js"; import { CommandMessageStructure, PhraseOccurrenceData } from "../types/TextCommand.js";
import { applicationState } from "../state.js"; import { applicationState } from "../state.js";
import { MessageCommand } from "../structures/MessageCommand.js";
/** /**
* @class Command manager * @class Command manager
*/ */
export class CommandManager { export class CommandManager {
private readonly _list: TextCommand[] = []; private readonly _textCommandsList: TextCommand[] = [];
private readonly _messagesCommandsList: BaseCommand[] = [];
private readonly _userCommandsList: BaseCommand[] = [];
/** /**
* Prefix used as a way to trigger the bot using messages * Prefix used as a way to trigger the bot using messages
* @type {string} * @type {string}
@@ -38,7 +42,7 @@ export class CommandManager {
*/ */
public get(phrase: string): TextCommand | null { public get(phrase: string): TextCommand | null {
let command: TextCommand | null = null; let command: TextCommand | null = null;
this._list.map((c) => { this._textCommandsList.map((c) => {
if (c.name == phrase) { if (c.name == phrase) {
command = c; command = c;
} }
@@ -57,47 +61,46 @@ export class CommandManager {
* @type {Array} {@link Command} * @type {Array} {@link Command}
*/ */
get list() { get list() {
return Object.freeze([...this._list]); return Object.freeze([...this._textCommandsList]);
} }
/** /**
* Adds the given {@link Command} to the instance manager with initial processing * Adds the given {@link Command} to the instance manager with initial processing
* @param {TextCommand} command - {@link Command} instance object * @param {BaseCommand} command - {@link Command} instance object
* @returns {boolean} Whether this command has been added successfully * @returns {boolean} Whether this command has been added successfully
*/ */
public add(command: TextCommand): boolean { public add(command: TextCommand | MessageCommand): void {
try { try {
if (applicationState.running) { if (applicationState.running) {
throw new Error("Cannot add command while the application is running"); throw new Error("Cannot add a command while the application is running");
} }
if (!(command instanceof TextCommand)) { if (command instanceof TextCommand) {
throw new TypeError("Inavlid argument type"); const nameOccurrence: PhraseOccurrenceData | null = this.findTextPhraseOccurrence(command.name);
if (nameOccurrence) {
throw new Error(`The name "${command.name}" has already been registered as ${nameOccurrence.type} in the "${nameOccurrence.command.name}" command.`);
}
command.aliases &&
command.aliases.map((a, i, ar) => {
const aliasOccurrence: PhraseOccurrenceData | null = this.findTextPhraseOccurrence(a);
if (aliasOccurrence) {
console.warn(
`[⚠ WARN] The name "${a}" is already registered as ${aliasOccurrence.type} in the "${aliasOccurrence.command.name}" command. It will be removed from the "${command.name}" command.`
);
ar.splice(i, 1);
}
});
command.parameters &&
command.parameters.map((p) => {
if (p.type != "string" && p.choices) {
throw new Error('Parameter with defined choices must have a "string" type');
}
});
this._textCommandsList.push(command);
} else {
throw new TypeError("Invalid argument type");
} }
const nameOccurrence: PhraseOccurrenceData | null = this.findPhraseOccurrence(command.name);
if (nameOccurrence) {
throw new Error(`The name "${command.name}" has already been registered as ${nameOccurrence.type} in the "${nameOccurrence.command.name}" command.`);
}
command.aliases &&
command.aliases.map((a, i, ar) => {
const aliasOccurrence: PhraseOccurrenceData | null = this.findPhraseOccurrence(a);
if (aliasOccurrence) {
console.warn(
`[⚠ WARN] The name "${a}" is already registered as ${aliasOccurrence.type} in the "${aliasOccurrence.command.name}" command. It will be removed from the "${command.name}" command.`
);
ar.splice(i, 1);
}
});
command.parameters &&
command.parameters.map((p) => {
if (p.type != "string" && p.choices) {
throw new Error('Parameter with defined choices must have a "string" type');
}
});
this._list.push(command);
return true;
} catch (e) { } catch (e) {
console.error(`[❌ ERROR] ${e}`); console.error(`[❌ ERROR] ${e}`);
return false;
} }
} }
@@ -210,9 +213,9 @@ export class CommandManager {
return null; return null;
} }
private findPhraseOccurrence(phrase?: string): PhraseOccurrenceData | null { private findTextPhraseOccurrence(phrase?: string): PhraseOccurrenceData | null {
let returnValue: PhraseOccurrenceData | null = null; let returnValue: PhraseOccurrenceData | null = null;
this._list.map((c) => { this._textCommandsList.map((c) => {
if (phrase == c.name) { if (phrase == c.name) {
returnValue = { returnValue = {
command: c, command: c,
+17
View File
@@ -0,0 +1,17 @@
import { CommandInteraction } from "discord.js";
import { MessageCommandInit } from "../types/MessageCommand.js";
import { CommandFunctionReturnTypes } from "../types/BaseCommand.js";
import { BaseCommand } from "./BaseCommand.js";
export class MessageCommand extends BaseCommand {
private readonly function: (i: CommandInteraction) => CommandFunctionReturnTypes;
public static nameRegExp: RegExp = /^[a-zA-Z]{1,32}$/;
constructor(o: MessageCommandInit) {
super({
name: o.name,
type: "MESSAGE",
});
this.function = o.function;
}
}
+2 -1
View File
@@ -5,6 +5,7 @@ import { ParameterResolvable } from "../types/Parameter.js";
import { PermissionCheckTypes } from "../types/permissions.js"; import { PermissionCheckTypes } from "../types/permissions.js";
import { OperationSuccess, PermissionsError } from "../errors.js"; import { OperationSuccess, PermissionsError } from "../errors.js";
import { DefaultParameter, InputParameter, Parameter } from "./Parameter.js"; import { DefaultParameter, InputParameter, Parameter } from "./Parameter.js";
import { CommandFunctionReturnTypes } from "../types/BaseCommand.js";
/** /**
* @class Class that represents a command instance * @class Class that represents a command instance
@@ -72,7 +73,7 @@ export class TextCommand extends BaseCommand {
private readonly function: ( private readonly function: (
params: (query: string, returnType?: "value" | "object") => ParameterResolvable | InputParameter | null, params: (query: string, returnType?: "value" | "object") => ParameterResolvable | InputParameter | null,
interaction?: Message | CommandInteraction interaction?: Message | CommandInteraction
) => void | string | MessageEmbed | ReplyMessageOptions | Promise<void | string | MessageEmbed | ReplyMessageOptions>; ) => CommandFunctionReturnTypes;
public static nameRegExp: RegExp = /^[\w-]{1,32}$/; public static nameRegExp: RegExp = /^[\w-]{1,32}$/;
public static descriptionRegExp: RegExp = /^[a-zA-Z]{1,100}$/; public static descriptionRegExp: RegExp = /^[a-zA-Z]{1,100}$/;
+4
View File
@@ -1,6 +1,10 @@
import { MessageEmbed, ReplyMessageOptions } from "discord.js";
export interface BaseCommandInit { export interface BaseCommandInit {
name: string; name: string;
type: CommandType; type: CommandType;
} }
export type CommandType = "CHAT" | "MESSAGE" | "USER"; export type CommandType = "CHAT" | "MESSAGE" | "USER";
export type CommandFunctionReturnTypes = void | string | MessageEmbed | ReplyMessageOptions | Promise<void | string | MessageEmbed | ReplyMessageOptions>;
+7
View File
@@ -0,0 +1,7 @@
import { CommandInteraction } from "discord.js";
import { CommandFunctionReturnTypes } from "./BaseCommand.js";
export interface MessageCommandInit {
name: string;
function: (i: CommandInteraction) => CommandFunctionReturnTypes;
}
+3 -2
View File
@@ -1,8 +1,9 @@
import { CommandInteraction, ReplyMessageOptions, PermissionResolvable, Message, MessageEmbed } from "discord.js"; import { CommandInteraction, PermissionResolvable, Message } from "discord.js";
import { ParameterSchema, ParameterResolvable } from "./Parameter.js"; import { ParameterSchema, ParameterResolvable } from "./Parameter.js";
import { InputParameter } from "../structures/Parameter.js"; import { InputParameter } from "../structures/Parameter.js";
import { TextCommand } from "../structures/TextCommand.js"; import { TextCommand } from "../structures/TextCommand.js";
import { PermissionCheckTypes } from "./permissions.js"; import { PermissionCheckTypes } from "./permissions.js";
import { CommandFunctionReturnTypes } from "./BaseCommand.js";
/** /**
* @interface * @interface
@@ -74,7 +75,7 @@ export interface TextCommandInit {
function: ( function: (
params: (query: string, returnType?: "value" | "object") => ParameterResolvable | InputParameter | null, params: (query: string, returnType?: "value" | "object") => ParameterResolvable | InputParameter | null,
interaction?: Message | CommandInteraction interaction?: Message | CommandInteraction
) => void | string | MessageEmbed | ReplyMessageOptions | Promise<void | string | MessageEmbed | ReplyMessageOptions>; ) => CommandFunctionReturnTypes;
} }
export interface CommandMessageStructure { export interface CommandMessageStructure {