code splitting

This commit is contained in:
mmacierzanka committed 2021-08-07 01:19:12 +02:00
1 parent 6e966b243b
commit ff14817f32
9 files changed
+245 -234

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
import { Bot } from "./src/Bot.js"; import { Bot } from "./src/Bot.js";
import { Command } from "./src/Command.js"; import { Command } from "./src/Command.js";
import { ParameterResolvable, ParameterType } from "./src/Parameter.js"; import { ParameterResolvable, ParameterType } from "./src/types.js";
import { MessageEmbed } from "discord.js"; import { MessageEmbed } from "discord.js";
export default Bot; export default Bot;
+11 -16
View File
@@ -1,13 +1,17 @@
//IMPORTS import { Client, Message } from "discord.js";
import { Client, ClientOptions, Message } from "discord.js"; import { Command } from "./Command.js";
import { Command, CommandManager, CommandMessageStructure } from "./Command.js"; import { CommandManager } from "./CommandManager.js";
import { PermissionsError } from "./Error.js"; import {
import { HelpMessage, HelpMessageParams } from "./Help.js"; CommandMessageStructure,
InitOptions,
HelpMessageParams,
} from "./types.js";
import { PermissionsError } from "./errors.js";
import { HelpMessage } from "./Help.js";
import * as http from "http"; import * as http from "http";
import { SystemMessageManager } from "./SystemMessage.js"; import { SystemMessageManager } from "./SystemMessage.js";
import { EventEmitter } from "events"; import { EventEmitter } from "events";
//TYPE DEFINITIONS
export declare interface Bot { export declare interface Bot {
on(event: "READY", listener: Function): this; on(event: "READY", listener: Function): this;
on(event: "MESSAGE", listener: (m: Message) => void): this; on(event: "MESSAGE", listener: (m: Message) => void): this;
@@ -17,15 +21,7 @@ export declare interface Bot {
): this; ): this;
on(event: "ERROR", listener: (e: any) => void): this; on(event: "ERROR", listener: (e: any) => void): this;
} }
interface ConstructorOptions {
name: string;
prefix: string;
argumentSeparator?: string;
clientOptions?: ClientOptions;
token?: string;
}
//MAIN CLASS
export class Bot extends EventEmitter { export class Bot extends EventEmitter {
name: string; name: string;
client: Client; client: Client;
@@ -46,7 +42,7 @@ export class Bot extends EventEmitter {
* @param {ClientOptions} [options.clientOptions] - client options from Discord.js * @param {ClientOptions} [options.clientOptions] - client options from Discord.js
* @param {string} [options.token] - bot token from Discord Developer Portal * @param {string} [options.token] - bot token from Discord Developer Portal
*/ */
constructor(options: ConstructorOptions) { constructor(options: InitOptions) {
super(); super();
this.name = options.name; this.name = options.name;
this.client = new Client(options.clientOptions); this.client = new Client(options.clientOptions);
@@ -156,5 +152,4 @@ export class Bot extends EventEmitter {
} }
} }
//EXPORTS
export default Bot; export default Bot;
+6 -200
View File
@@ -1,43 +1,12 @@
//IMPORTS //IMPORTS
import { Permissions, Message, MessageEmbed } from "discord.js";
import { import {
Permissions, CommandBuilder,
PermissionResolvable, PermissionCheckTypes,
Message,
MessageEmbed,
} from "discord.js";
import { MissingParameterError, PermissionsError } from "./Error.js";
import {
Parameter,
ParameterResolvable, ParameterResolvable,
ProcessArgument, } from "./types.js";
} from "./Parameter.js"; import { MissingParameterError, PermissionsError } from "./errors.js";
import { Parameter, ProcessArgument } from "./Parameter.js";
//TYPE DEFINITIONS
type GetMode = "ALL" | "PREFIX" | "NO_PREFIX";
type PermissionCheckTypes = "ALL" | "ANY";
export interface CommandMessageStructure {
command: Command;
parameters: string[];
}
interface CommandBuilder {
name: string;
parameters?: Parameter[];
aliases?: string[] | string;
keywords?: string[] | string;
description?: string;
usage?: string;
permissionCheck?: PermissionCheckTypes;
permissions?: PermissionResolvable;
visible?: boolean;
function: (
message?: Message,
cmdParams?: ParameterResolvable[]
) => void | string | MessageEmbed | Promise<void | string | MessageEmbed>;
}
interface PhraseOccurrenceData {
command: Command;
type: "NAME" | "ALIAS";
}
//CLASSES //CLASSES
export class Command { export class Command {
@@ -153,166 +122,3 @@ export class Command {
return usageTemplate; return usageTemplate;
} }
} }
export class CommandManager {
list: Command[];
prefix: string;
argumentSeparator: string;
constructor(prefix: string, argumentSeparator?: string) {
this.list = [];
this.prefix = prefix;
this.argumentSeparator = argumentSeparator || ",";
}
/**
* Retrieves the command by name, alias or keyword
* @param {string} phrase - command name, alias or keyword
* @param {GetMode} [mode='ALL'] - specifies which types of command triggers will be used to find the command [*NO_PREFIX* - only keywords; *PREFIX* - names and aliases]
* @returns *Command* | *null*
*/
get(phrase: string, mode?: GetMode): Command | null {
if (!mode) mode = "ALL";
let command: Command | null = null;
this.list.map((c) => {
switch (mode) {
case "PREFIX":
if (c.name == phrase) {
command = c;
}
c.aliases.map((a) => {
if (a == phrase) {
command = c;
}
});
break;
case "NO_PREFIX":
c.keywords.map((k) => {
if (k == phrase) {
command = c;
}
});
break;
case "ALL":
if (c.name == phrase) {
command = c;
}
c.aliases.map((a) => {
if (a == phrase) {
command = c;
}
});
c.keywords.map((k) => {
if (k == phrase) {
command = c;
}
});
break;
}
});
return command;
}
/**
* Adds the given command to the instance manager
* @param {Command} command - *Command* or *HelpMessage* object
* @returns *boolean*
*/
add(command: Command): boolean {
try {
if (!(command instanceof Command)) {
throw new TypeError("Inavlid 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.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);
}
});
this.list.map((c) => {
command.keywords.map((k, i, a) => {
if (c.keywords.indexOf(k) != -1) {
console.warn(
`[⚠ WARN] The name "${k}" is already a registered KEYWORD for the "${c.name}" command. It will be removed from the "${command.name}" command`
);
a.splice(i, 1);
}
});
});
this.list.push(command);
return true;
} catch (e) {
console.error(`[❌ ERROR] ${e.toString()}`);
return false;
}
}
/**
* Fetches command and parameters from the given *Message* object
* @param {Message} message - *Message* object
* @returns *CommandMessagesStructure* | *null*
*/
fetch(message: Message): CommandMessageStructure | null {
if (!message.author.bot) {
let prefix = false;
if (message.content.startsWith(this.prefix)) {
prefix = true;
}
const content = prefix
? message.content.replace(this.prefix, "")
: message.content;
const name = content.split(" ")[0];
const command = this.get(name, prefix ? "PREFIX" : "NO_PREFIX");
if (command) {
const argumentsText = content.replace(name, "");
const paramsList = argumentsText
.split(this.argumentSeparator)
.map((a) => {
return a.replace(" ", "");
});
if (
(paramsList[0] == "" || paramsList[0] == " ") &&
paramsList.length == 1
) {
paramsList.splice(0, 1);
}
return {
command: command,
parameters: paramsList,
};
} else {
return null;
}
} else {
return null;
}
}
private findPhraseOccurrence(phrase?: string): PhraseOccurrenceData | null {
let returnValue: PhraseOccurrenceData | null = null;
this.list.map((c) => {
if (phrase == c.name) {
returnValue = {
command: c,
type: "NAME",
};
} else if (c.aliases.indexOf(phrase || "") != -1) {
returnValue = {
command: c,
type: "ALIAS",
};
}
});
return returnValue;
}
}
+171
View File
@@ -0,0 +1,171 @@
import { Message } from "discord.js";
import { Command } from "./Command.js";
import {
CommandMessageStructure,
GetMode,
PhraseOccurrenceData,
} from "./types.js";
export class CommandManager {
list: Command[];
prefix: string;
argumentSeparator: string;
constructor(prefix: string, argumentSeparator?: string) {
this.list = [];
this.prefix = prefix;
this.argumentSeparator = argumentSeparator || ",";
}
/**
* Retrieves the command by name, alias or keyword
* @param {string} phrase - command name, alias or keyword
* @param {GetMode} [mode='ALL'] - specifies which types of command triggers will be used to find the command [*NO_PREFIX* - only keywords; *PREFIX* - names and aliases]
* @returns *Command* | *null*
*/
get(phrase: string, mode?: GetMode): Command | null {
if (!mode) mode = "ALL";
let command: Command | null = null;
this.list.map((c) => {
switch (mode) {
case "PREFIX":
if (c.name == phrase) {
command = c;
}
c.aliases.map((a) => {
if (a == phrase) {
command = c;
}
});
break;
case "NO_PREFIX":
c.keywords.map((k) => {
if (k == phrase) {
command = c;
}
});
break;
case "ALL":
if (c.name == phrase) {
command = c;
}
c.aliases.map((a) => {
if (a == phrase) {
command = c;
}
});
c.keywords.map((k) => {
if (k == phrase) {
command = c;
}
});
break;
}
});
return command;
}
/**
* Adds the given command to the instance manager
* @param {Command} command - *Command* or *HelpMessage* object
* @returns *boolean*
*/
add(command: Command): boolean {
try {
if (!(command instanceof Command)) {
throw new TypeError("Inavlid 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.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);
}
});
this.list.map((c) => {
command.keywords.map((k, i, a) => {
if (c.keywords.indexOf(k) != -1) {
console.warn(
`[⚠ WARN] The name "${k}" is already a registered KEYWORD for the "${c.name}" command. It will be removed from the "${command.name}" command`
);
a.splice(i, 1);
}
});
});
this.list.push(command);
return true;
} catch (e) {
console.error(`[❌ ERROR] ${e.toString()}`);
return false;
}
}
/**
* Fetches command and parameters from the given *Message* object
* @param {Message} message - *Message* object
* @returns *CommandMessagesStructure* | *null*
*/
fetch(message: Message): CommandMessageStructure | null {
if (!message.author.bot) {
let prefix = false;
if (message.content.startsWith(this.prefix)) {
prefix = true;
}
const content = prefix
? message.content.replace(this.prefix, "")
: message.content;
const name = content.split(" ")[0];
const command = this.get(name, prefix ? "PREFIX" : "NO_PREFIX");
if (command) {
const argumentsText = content.replace(name, "");
const paramsList = argumentsText
.split(this.argumentSeparator)
.map((a) => {
return a.replace(" ", "");
});
if (
(paramsList[0] == "" || paramsList[0] == " ") &&
paramsList.length == 1
) {
paramsList.splice(0, 1);
}
return {
command: command,
parameters: paramsList,
};
} else {
return null;
}
} else {
return null;
}
}
private findPhraseOccurrence(phrase?: string): PhraseOccurrenceData | null {
let returnValue: PhraseOccurrenceData | null = null;
this.list.map((c) => {
if (phrase == c.name) {
returnValue = {
command: c,
type: "NAME",
};
} else if (c.aliases.indexOf(phrase || "") != -1) {
returnValue = {
command: c,
type: "ALIAS",
};
}
});
return returnValue;
}
}
+4 -11
View File
@@ -1,14 +1,7 @@
import { ColorResolvable, MessageEmbed } from "discord.js"; import { MessageEmbed } from "discord.js";
import { Command, CommandManager } from "./Command.js"; import { Command } from "./Command.js";
import { CommandManager } from "./CommandManager.js";
export interface HelpMessageParams { import { HelpMessageParams } from "./types.js";
enabled: boolean;
title: string;
bottomText: string;
color: ColorResolvable;
description: string;
usage: string;
}
export class HelpMessage extends Command { export class HelpMessage extends Command {
constructor( constructor(
+2 -4
View File
@@ -1,7 +1,5 @@
import { ParameterTypeError } from "./Error.js"; import { ParameterTypeError } from "./errors.js";
import { ParameterType, ParameterResolvable } from "./types.js";
export type ParameterType = "TEXT" | "TRUE/FALSE" | "NUMBER";
export type ParameterResolvable = string | boolean | number;
export interface Parameter { export interface Parameter {
name: string; name: string;
optional: boolean; optional: boolean;
+1 -1
View File
@@ -9,7 +9,7 @@ import {
User, User,
} from "discord.js"; } from "discord.js";
import { Command } from "./Command.js"; import { Command } from "./Command.js";
import { PermissionsError } from "./Error.js"; import { PermissionsError } from "./errors.js";
export type MessageType = "PERMISSION" | "ERROR" | "NOT_FOUND"; export type MessageType = "PERMISSION" | "ERROR" | "NOT_FOUND";
export interface SystemMessageAppearance { export interface SystemMessageAppearance {
+2 -1
View File
@@ -1,6 +1,7 @@
import { Command } from "./Command.js"; import { Command } from "./Command.js";
import { GuildMember } from "discord.js"; import { GuildMember } from "discord.js";
import { Parameter, ParameterType } from "./Parameter.js"; import { Parameter } from "./Parameter.js";
import { ParameterType } from "./types.js";
export class PermissionsError extends Error { export class PermissionsError extends Error {
private command: Command; private command: Command;
+47
View File
@@ -0,0 +1,47 @@
import { ClientOptions, ColorResolvable } from "discord.js";
import { Parameter } from "./Parameter.js";
import { PermissionResolvable, Message, MessageEmbed } from "discord.js";
import type { Command } from "./Command.js";
export interface InitOptions {
name: string;
prefix: string;
argumentSeparator?: string;
clientOptions?: ClientOptions;
token?: string;
}
export type GetMode = "ALL" | "PREFIX" | "NO_PREFIX";
export type PermissionCheckTypes = "ALL" | "ANY";
export interface CommandBuilder {
name: string;
parameters?: Parameter[];
aliases?: string[] | string;
keywords?: string[] | string;
description?: string;
usage?: string;
permissionCheck?: PermissionCheckTypes;
permissions?: PermissionResolvable;
visible?: boolean;
function: (
message?: Message,
cmdParams?: ParameterResolvable[]
) => void | string | MessageEmbed | Promise<void | string | MessageEmbed>;
}
export interface PhraseOccurrenceData {
command: Command;
type: "NAME" | "ALIAS";
}
export interface CommandMessageStructure {
command: Command;
parameters: string[];
}
export interface HelpMessageParams {
enabled: boolean;
title: string;
bottomText: string;
color: ColorResolvable;
description: string;
usage: string;
}
export type ParameterType = "TEXT" | "TRUE/FALSE" | "NUMBER";
export type ParameterResolvable = string | boolean | number;