import { ConfigureError } from '../errors';
import { ICommand, IContext, Context, THandlerCommand } from '../../types';
/**
* @description Класс команды
* @class
* @param {ICommand} data
*
* @example
* new Command({
*
* name: 'test',
* description: 'test command',
* categories: ['test'],
*
* params: {
* emoji: '📄'
* },
*
* handler(context) {
* context.send('test');
* }
* })
* pattern: /test/i,
*/
export class Command {
/**
* паттерн команды
* @property {RegExp | string}
* @memberof Command
*/
public pattern: RegExp | string;
/**
* название
* @property {string}
*/
public name: string;
/**
* @description описание
* @property {string} description
*/
public description: string;
/**
* @type {string[]}
*/
public categories: string[];
/**
* @description дополнительные параметры
* @type {Record<string, unknown>}
*/
public params: Record<string, unknown>;
/**
* массив подкоманд
* @property {Command[]} commands
*/
public commands: Command[];
/**
* обработчик комманды
* @property {THandlerCommand} handler
*/
public handler: THandlerCommand;
constructor(data: ICommand) {
if (!data.pattern) {
throw new ConfigureError(
'Не указан pattern команды (регулярное выражение)',
);
}
if (!(data.pattern instanceof RegExp)) {
data.pattern = new RegExp(data.pattern);
}
if (!data.handler) {
throw new ConfigureError('Не указан обработчик команды');
}
if (typeof data.handler !== 'function') {
throw new ConfigureError('Обработчик команды не является функцией');
}
const {
pattern,
name,
description,
categories,
params,
commands,
handler,
} = data;
this.pattern = pattern;
this.name = name;
this.description = description || '';
this.categories = categories || [];
this.params = params || {};
this.commands = <Command[] | []>commands || [];
this.handler = handler;
}
get [Symbol.toStringTag](): string {
return 'Command';
}
/**
* @description поиск подкоманд
* @param {Record<string, unknown>} context
* @return {Command}
*/
findSubCommand<c extends Context>(context: c & IContext): Command {
let command: Command;
for (const subCommand of this.commands) {
if ((<RegExp>subCommand.pattern).test(context.body[1])) {
command = subCommand;
}
}
if (!command) {
return this;
}
context.body = context.body[1].match(command.pattern);
if (command.commands.length) {
command = (<Command>command).findSubCommand<c>(context);
}
return command;
}
}
Source