@khurvity/khur-core v0.2.0
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-coreGetting 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.mdConfiguration 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
| Property | Type | Description |
|---|---|---|
| prefix | string | Bot prefix |
| Method | Return | Description |
|---|---|---|
| getStatus() | boolean | static Getting bot status |
| setStatus(status: boolean) | void | static Change bot status |
| getClient() | Client | static Getting client instance |
| setClient(Client) | void | static Set client instance |
| getPrefix() | string | Getting bot prefix |
Class: Commands
| Method | Return | Description |
|---|---|---|
| all() | Array | static Retrieve command list |
| get(key: string) | CommandData | undefined | static If it exists, retrieve the information from a command |
| rawList() | Array | static Retrieve command list (classes version) |
| has(key: string) | boolean | static Check if a command has been registered |
Class: Events
| Method | Return | Description |
|---|---|---|
| all() | Array | static Retrieve event list |
| get(key: string) | EventData | undefined | static If it exists, retrieve the information from a event |
| has(key: string) | boolean | static Check if a event has been registered |
Class: Khur
| Method | Return | Description |
|---|---|---|
| config(data: KhurConfig) | Promise | static Initialize all application configuration |
| getAppRoot() | string | static Getting application path |
| getDefaultPrefix() | string | static Getting default prefix |
| beforeInit(initCallback: () => Promise) | Promise | static Set initialize function |
Class: Register
| Method | Return | Description |
|---|---|---|
| group(params: RegisterGroupParams, callback: (params: RegisterGroupParams) => void) | void | static Callback function to group commands |
| command(path: string, newConfig: CommandConfig) | void | static Register new command |
| event(name: string, path: string) | void | static Register new event. More details |
Class: Request
| Property | Type | Description |
|---|---|---|
| bot | Bot | Instance: Bot |
| message | Message | Discord message |
| prefix | string | Current prefix |
| Method | Return | Description |
|---|---|---|
| data(message?: string) | RequestData | Extract and parse message content |
| isCommand(prefix: string, message: string) | boolean | static 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}}';| Property | Type | Description |
|---|---|---|
| current | string | Current translation language |
| Method | Return | Description |
|---|---|---|
| getSupported() | Array | static Getting list of supported languages |
| setSupported(supported: Array) | void | static Set list of supported languages |
| getCurrent() | string | Getting current language |
| globals(key: string, replace: TranslationReplaceParams = {}) | any | Use globals translations |
| locals(key: string, replace: TranslationReplaceParams = {}) | any | Use locals translations |
| checkLocaleFormat(locale: string) | boolean | static Check if language key to use has a valid format |
Class: CommandHandler
| Method | Return | Description |
|---|---|---|
| init(message: Message, config?: CommandHandlerConfig) | Promise | static Initialize handler |
Structure of features (utilities)
import {
checkMentions,
extractMentions,
extractParams,
getAuthorAvatar,
getBotAvatar,
getGuildBanner,
getGuildIcon,
} from '@khurvity/khur-core';| Function | Return | Description |
|---|---|---|
| checkMentions(content: string) | RequestValidations | Check for mentions |
| extractMentions(content: string) | RequestMentions | Extract mentions from message content |
| extractParams(content: string) | RequestParams | Extract params from message content |
| getAuthorAvatar(request: Message | User) | string | Getting user avatar |
| getBotAvatar() | string | Getting Bot avatar |
| getGuildBanner(request: Guild | Message) | string | Getting guild banner |
| getGuildIcon(request: Guild | Message) | string | Getting guild icon |
API Reference
- In the main file, the last thing to be running must be
Khur.configdue 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
BaseCommandandBaseEventrespectively, in addition to being exported by defaultexport 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
| Property | type | Description |
|---|---|---|
| appRoot | string | Main directory of the project |
| bot | BotCredentials | Credentials of your application. See Discord Developers |
| bot.client.id | string | Client ID |
| bot.client.secret | string | Client Secret |
| bot.token | string | Bot Token |
| defaultPrefix | string | Bot prefix |
| discordClient | Client | Client instance |
| i18n | Translation config | |
| i18n.globalTranslationsPath | string | Path to global translations folder |
| i18n.supported | Array | Languages supported |
| onReady?(client: Client) | Promise | Callback. 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
| Property | Type | Description |
|---|---|---|
| prefix? | string | Prefix (any context) |
| key: string | any | Custom 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
| Property | Type | Description |
|---|---|---|
| allowDynamicAliases? | boolean | Allow dynamic alias |
| middlewares? | Array | Middleware to use |
| names | Array | required Aliases |
| key: string | any | Custom 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 = truethe aliases should coincide withsample:dynamic,sample:bye,non:sample,non:test,sample-dynamic,sample-bye. - Middleware
OnlyGuildindicates 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
| Property | Type | Description |
|---|---|---|
| currentTranslation? | string | Key of current translation (es, en, es-ES, en-US, etc) |
| middlewares? | Array | Middlewares to evaluate before command |
| prefix | string | required 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.