diff --git a/README.md b/README.md index 240bdfb..aef5530 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # CommandBot -**1.1.2** +**1.1.3** Discord.js framework that helps you build your own Discord bot. diff --git a/package-lock.json b/package-lock.json index cd8d9d8..d70ccf8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "commandbot", - "version": "1.1.2", + "version": "1.1.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "commandbot", - "version": "1.1.2", + "version": "1.1.3", "license": "MIT", "dependencies": { "discord.js": "^12.5.3" diff --git a/package.json b/package.json index 08a8e35..b2879b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "commandbot", - "version": "1.1.2", + "version": "1.1.3", "description": "A framework that helps you create your own Discord bot easier.", "type": "module", "main": "dist/index.js", diff --git a/src/Bot.ts b/src/Bot.ts index 41f8184..5fc3efe 100644 --- a/src/Bot.ts +++ b/src/Bot.ts @@ -34,6 +34,17 @@ class Bot { command: (m: Message, cmdInfo?: CommandMessageStructure) => any } + /** + * Bot instance initializer + * @constructor + * @param {ConstructorOptions} options - instance properties + * @param {string} options.name - name of your bot + * @param {string} options.prefix - prefix used to call commands + * @param {string} [options.argumentSeparator=','] - used to get arguments from message + * @param {boolean} [options.helpCommand = true] - enable or disable the *help* command + * @param {ClientOptions} [options.clientOptions] - client options from Discord.js + * @param {string} [options.token] - bot token from Discord Developer Portal + */ constructor(options: ConstructorOptions) { this.name = options.name; this.client = new Client(options.clientOptions); @@ -57,6 +68,13 @@ class Bot { command: (m: Message, cmdInfo?: CommandMessageStructure) => {} } } + + /** + * Starts your Discord bot + * @param {number} [port] - if specified, the app will create a http server that will be listening on the specified port + * @param {string} [token] - app token from Discord Developer Portal + * @returns *Promise* + */ async start(port?: number, token?: string) : Promise { try { console.log(`Bot name: ${this.name}`); diff --git a/src/Command.ts b/src/Command.ts index 16e1967..bb4a1b7 100644 --- a/src/Command.ts +++ b/src/Command.ts @@ -50,6 +50,20 @@ class Command { visible: boolean; private function: (message?: Message, cmdArguments?: string[]) => void | string | MessageEmbed | Promise; + /** + * Command constructor + * @constructor + * @param {CommandBuilder} options - all command properties + * @param {string} options.name - command name (used to trigger the command) + * @param {string | string[]} [options.aliases] - other words that can trigger the command with prefix + * @param {string | string[]} [options.keywords] - other words that can trigger the command without prefix + * @param {string} [options.description="No description"] - command description shown in the help message + * @param {string} [options.usage] - command usage description shown in the help message + * @param {PermissionCheckTypes} [options.permissionCheck='ANY'] - specifies if the caller has to have all of the specified permissions or any of that + * @param {PermissionResolvable} [options.permissions] - permissions needed to run the command + * @param {boolean} [options.visible=true] - show command in the help message + * @param {Function} options.function - function that will trigger when the commands gets called + */ constructor(options: CommandBuilder) { this.name = options.name.split(' ').join('_'); this.aliases = Command.processPhrase(options.aliases); @@ -61,6 +75,13 @@ class Command { this.visible = options.visible != undefined ? options.visible : true; this.function = options.function; } + + /** + * Starts the command + * @param {Message} [message] - a *Message* object used to check caller's permissions. It will get passed to the execution function (specified in *function* property of command's constructor) + * @param {string[]} [cmdArguments] - list of processed arguments passed in a Discord message + * @returns *Promise* + */ async start(message?: Message, cmdArguments?: string[]) : Promise { const memberPermissions : Readonly = message?.member?.permissions || new Permissions(0); if(this.permissionCheck == 'ALL' ? memberPermissions.has(this.permissions, true) : memberPermissions.any(this.permissions, true)) { @@ -76,6 +97,7 @@ class Command { throw new PermissionsError(this, message?.member); } } + private static processPhrase(phrase?: string | string[]) : string[] { if(Array.isArray(phrase)) { const buff = phrase.map((p) => { @@ -109,6 +131,13 @@ class CommandManager { 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; @@ -150,6 +179,12 @@ class CommandManager { }); 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)) { @@ -184,6 +219,12 @@ class CommandManager { return false; } } + + /** + * Fetches command and arguments from the given *Message* object + * @param {Message} message - *Message* object + * @returns *CommandMessagesStructure* | *null* + */ fetch(message: Message) : CommandMessageStructure | null { if(!message.author.bot && message.content.startsWith(this.prefix)) { let msgContent = message.content.replace(this.prefix, ''); @@ -229,6 +270,7 @@ class CommandManager { return null; } } + private findPhraseOccurrence(phrase?: string) : PhraseOccurrenceData | null { let returnValue: PhraseOccurrenceData | null = null; this.list.map(c => { diff --git a/src/SystemMessage.ts b/src/SystemMessage.ts index 50130b9..381994e 100644 --- a/src/SystemMessage.ts +++ b/src/SystemMessage.ts @@ -21,6 +21,7 @@ class SystemMessageManager { ERROR: SystemMessageAppearance; NOT_FOUND: SystemMessageAppearance; deleteTimeout: number; + constructor(botName?: string) { this.PERMISSION = { title: '👮‍♂️ Insufficient permissions', @@ -44,6 +45,14 @@ class SystemMessageManager { } this.deleteTimeout = Infinity; } + + /** + * Generates and sends a system message + * @param {MessageType} type - 'ERROR' | 'PERMISSION' | 'NOT_FOUND' + * @param {SystemMessageData} [data] - additional data to include in the message + * @param {TextChannel | DMChannel | NewsChannel} [channel] - if specified, the generated message will be sent in this channel + * @returns *Promise* + */ async send(type: MessageType, data?: SystemMessageData, channel?: TextChannel | DMChannel | NewsChannel) : Promise { if(this[type]) { const embed = new MessageEmbed();