0.2.0 • Published 4 years ago

@khurvity/khur-core v0.2.0

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
4 years ago

GitHub release (latest by date) GitHub Workflow Status GitHub Workflow Status GitHub

Khur Core

Set of base tools to work with the discord.js library.

This library contains some features to facilitate the event log and commands, besides using middlewares for the command handler (including the individual commands) to provide a better extension of functionality.

Note: As of version >= 0.2.0 it will not include the Discord.js package so it must be installed in your project separately.

Features

  • Command handler
  • Event handler
  • Translations by command or global
  • Custom middlewares
  • Support to:
    • Multi prefix
    • Command aliases (and dynamic alias)
  • Custom project structure
  • Simple command structure
  • TypeScript support

Installation

Node.js 14 or newer is required.

yarn add @khurvity/khur-core

Getting Started

At the moment of registering events, commands or any other feature, it is required to be done before configuring the library (Khur.config(...)).

Configuration

The Client class forms part of the library discord.js.

import { Khur, Client } from '@khurvity/khur-core';

Khur.config({
  appRoot: __dirname,
  defaultPrefix: '!',
  i18n: {
    supported: ['es', 'en'],
    globalTranslationsPath: 'PATH_TO_TRANSLATIONS_FOLDER',
  },
  bot: {
    client: {
      id: 'EXAMPLE_ID',
      secret: 'EXAMPLE_SECRET',
    },
    token: 'EXAMPLE_TOKEN',
    scopes: ['bot'],
    permissions: '8',
  },
  discordClient: new Client(), // Discord Client
});

The parameters that the Khur.config method receives are:

Khur.config(<KhurConfig>);

interface KhurConfig {
  appRoot: string;
  bot: BotCredentials;
  defaultPrefix: string;
  discordClient: Client;
  i18n: {
    globalTranslationsPath: string;
    supported: Array<string>;
  };
  onReady?(client: Client): Promise<void>;
}

interface BotCredentials {
  client: {
    id: string;
    secret: string;
  };
  token: string;
  scopes: Array<BotScopeOptions>; // type ['bot']
  permissions: string;
}

Register event

The event's name must be one available from the following documentation shown in the Client class.

Register.event(<event>, 'PATH_TO_EVENT_FILE');

Register command

The category and names properties are required.

Register.command('PATH_TO_COMMAND_FOLDER', {
  category: 'Test',
  names: ['test', 'alias1', 'alias2'],
});

The criteria received for the the method Register.command are the following:

Register.command(<string>, <CommandConfig>);

interface CommandConfig {
  allowDynamicAliases?: boolean;
  middlewares?: Array<typeof BaseMiddleware>;
  names: Array<string>;
  [key: string]: any;
}

Example usage

Keep in mind the following structure of files:

.
├── src
│   ├── app
│   │   ├── commands
│   │   │   └── Sample
│   │   │       └── index.ts <── Command
│   │   └── events
│   │       └── Message.ts <── EventMessage
│   └── index.ts <── MainFile
└──README.md

Configuration for ./src/app/events/Message.ts:

import {
  BaseEvent,
  CommandHandler,
  Khur,
  Message as MessageData,
} from '@khurvity/khur-core';

export default class Message extends BaseEvent {
  protected async handle(message: MessageData): Promise<void> {
    try {
      await CommandHandler.init(message, {
        prefix: Khur.getDefaultPrefix(),
      });
    } catch (error) {
      console.error(error);
    }
  }
}

Configuration for ./src/app/commands/Sample/index.ts:

import { BaseCommand } from '@khurvity/khur-core';

export default class Sample extends BaseCommand {
  public async handle(): Promise<void> {
    // this.deleteCommandUse(); // uncomment to remove usage of the command
    this.message.channel.send('Sample!');
  }
}

Note: An alias will be used for the importation of files.

Configuration for ./src/index.ts:

import { Register, Khur, Client } from '@khurvity/khur-core';

Register.event('message', '@app-event/Message');

Register.command('@app-command/Sample', {
  category: 'Test',
  names: ['sample', 'alias1', 'alias2'],
});

// It is recommended to use this method if you want to run some features before starting the Bot
Khur.beforeInit(async (): Promise<void> => {
  console.log('Hi!');
});

Khur.config({
  appRoot: __dirname,
  defaultPrefix: '!',
  i18n: {
    supported: ['es', 'en'],
    globalTranslationsPath: '@app-translation',
  },
  bot: {
    client: {
      id: 'EXAMPLE_ID',
      secret: 'EXAMPLE_SECRET',
    },
    token: 'EXAMPLE_TOKEN',
    scopes: ['bot'],
    permissions: '8', // Administrator
  },
  discordClient: new Client(),
});

To execute this code and test on your Discord server, the command !sample should reply with a message saying Sample!

Structure of classes

The classes for @khurvity/khur-core contain utility properties and methods, which are shown below:

Class: Bot

PropertyTypeDescription
prefixstringBot prefix
MethodReturnDescription
getStatus()booleanstatic Getting bot status
setStatus(status: boolean)voidstatic Change bot status
getClient()Clientstatic Getting client instance
setClient(Client)voidstatic Set client instance
getPrefix()stringGetting bot prefix

Class: Commands

MethodReturnDescription
all()Arraystatic Retrieve command list
get(key: string)CommandData | undefinedstatic If it exists, retrieve the information from a command
rawList()Arraystatic Retrieve command list (classes version)
has(key: string)booleanstatic Check if a command has been registered

Class: Events

MethodReturnDescription
all()Arraystatic Retrieve event list
get(key: string)EventData | undefinedstatic If it exists, retrieve the information from a event
has(key: string)booleanstatic Check if a event has been registered

Class: Khur

MethodReturnDescription
config(data: KhurConfig)Promisestatic Initialize all application configuration
getAppRoot()stringstatic Getting application path
getDefaultPrefix()stringstatic Getting default prefix
beforeInit(initCallback: () => Promise)Promisestatic Set initialize function

Class: Register

MethodReturnDescription
group(params: RegisterGroupParams, callback: (params: RegisterGroupParams) => void)voidstatic Callback function to group commands
command(path: string, newConfig: CommandConfig)voidstatic Register new command
event(name: string, path: string)voidstatic Register new event. More details

Class: Request

PropertyTypeDescription
botBotInstance: Bot
messageMessageDiscord message
prefixstringCurrent prefix
MethodReturnDescription
data(message?: string)RequestDataExtract and parse message content
isCommand(prefix: string, message: string)booleanstatic Verify that it is a possible command

Class: Translation

const translation = new Translation(current: null | string = null, commandPath?: string);

// translation.globals('<filename>.<property>.<property>', { name: 'John' });
translation.globals('info.author', { name: 'John' });

// PATH_TO/info.ts
export const author = 'Hello! My name is {{name}}';
PropertyTypeDescription
currentstringCurrent translation language
MethodReturnDescription
getSupported()Arraystatic Getting list of supported languages
setSupported(supported: Array)voidstatic Set list of supported languages
getCurrent()stringGetting current language
globals(key: string, replace: TranslationReplaceParams = {})anyUse globals translations
locals(key: string, replace: TranslationReplaceParams = {})anyUse locals translations
checkLocaleFormat(locale: string)booleanstatic Check if language key to use has a valid format

Class: CommandHandler

MethodReturnDescription
init(message: Message, config?: CommandHandlerConfig)Promisestatic Initialize handler

Structure of features (utilities)

import {
  checkMentions,
  extractMentions,
  extractParams,
  getAuthorAvatar,
  getBotAvatar,
  getGuildBanner,
  getGuildIcon,
} from '@khurvity/khur-core';
FunctionReturnDescription
checkMentions(content: string)RequestValidationsCheck for mentions
extractMentions(content: string)RequestMentionsExtract mentions from message content
extractParams(content: string)RequestParamsExtract params from message content
getAuthorAvatar(request: Message | User)stringGetting user avatar
getBotAvatar()stringGetting Bot avatar
getGuildBanner(request: Guild | Message)stringGetting guild banner
getGuildIcon(request: Guild | Message)stringGetting guild icon

API Reference

  • In the main file, the last thing to be running must be Khur.config due to it being in charge of starting the settings of the Bot.
  • Middlewares Array<Middleware>: if the returned value is false, the command won't be executed.
  • The commands/events will always be extended to its base class such as BaseCommand and BaseEvent respectively, in addition to being exported by default export default class ....

Khur.beforeInit

Do execute each feature before starting the Bot. This must be run before Khur.config(...)

Khur.beforeInit(async (): Promise<void> => {
  console.log('{beforeInit} -> Hi!');
})

Khur.config

Register each setting to start the client and internal components:

Khur.config(<KhurConfig>)

Interface: KhurConfig

PropertytypeDescription
appRootstringMain directory of the project
botBotCredentialsCredentials of your application. See Discord Developers
bot.client.idstringClient ID
bot.client.secretstringClient Secret
bot.tokenstringBot Token
defaultPrefixstringBot prefix
discordClientClientClient instance
i18nTranslation config
i18n.globalTranslationsPathstringPath to global translations folder
i18n.supportedArrayLanguages supported
onReady?(client: Client)PromiseCallback. Bot is ready

Register.event

To register an event. See the documentation (Client) to know about the list of available events.

Register.event(<event>, 'PATH_TO_EVENT_FILE');

Register.group

To group the record of commands.

Register.group(<RegisterGroupParams>, callback: (params: RegisterGroupParams) => void);

Interface: RegisterGroupParams

PropertyTypeDescription
prefix?stringPrefix (any context)
key: stringanyCustom value
Register.group({
  prefix: '@app-command/Information',
}, (params: RegisterGroupParams): void => {
  Register.command(`${params.prefix}/Help`, {
    category: 'Information',
    names: ['help', 'h'],
  });

  Register.command(`${params.prefix}/Support`, {
    category: 'Information',
    names: ['support'],
  });
});

Register.command

Register command. The properties of these settings can be accessed through the middlewares (including the command) to add validations.

Register.command('PATH_TO_COMMAND_FOLDER', <CommandConfig>);

Interface: CommandConfig

PropertyTypeDescription
allowDynamicAliases?booleanAllow dynamic alias
middlewares?ArrayMiddleware to use
namesArrayrequired Aliases
key: stringanyCustom value
// Using alias (directory)
Register.command('@app-command/Sample', {
  allowDynamicAliases: true,
  category: 'Test',
  cooldown: 5, // Seconds
  middlewares: [OnlyGuild], // Details below
  names: ['sample', 'non'], // Two aliases
  nsfw: {
    current: true, // This command has NSFW content
  },
});

Note: Dynamic aliases are detected with after the ":" or "-" character, for example: name:dynamicalias, name:non, name-dynamicalias, name-non, etc.

  • If allowDynamicAliases = true the aliases should coincide with sample:dynamic, sample:bye, non:sample, non:test, sample-dynamic, sample-bye.
  • Middleware OnlyGuild indicates that the command could be executed if it is in a server.

CommandHandler.init

Use the command handler.

await CommandHandler.init(<EventMessage>, <CommandHandlerConfig>);

Interface: CommandHandlerConfig

PropertyTypeDescription
currentTranslation?stringKey of current translation (es, en, es-ES, en-US, etc)
middlewares?ArrayMiddlewares to evaluate before command
prefixstringrequired Current prefix or custom by Guild
try {
  await CommandHandler.init(message, {
    // currentTranslation: 'en', // Or dynamic (by database)
    prefix: Khur.getDefaultPrefix(), // Or dynamic (by database)
    // middlewares: [],
  });
} catch (error) {
  console.error(error);
}

Credits

This project generate a build using TSDX a zero-config CLI for TypeScript package development.