///
import { GuildMember, Message, PermissionString, Snowflake, TextChannel, User } from 'discord.js';
import { CommandHandler } from '../../CommandHandler';
import { Argument } from '../arguments';
import { CommandContext, SubCommandContext } from '../contexts';
import { CommandError, CommandErrorBuilder } from '../errors';
import { RunSubCommandFunction, SubCommandOptions } from './SubCommand';
import CommandCooldown = CommandHandler.CommandCooldown;
/**
* # How tags should work ?
*
* When using commands, you want certain commands to only run on a server or in private messages etc.
* Most other CommandHandlers uses boolean properties like `guildOnly`.
* To avoid having a ton of these, I imagined a system where you have command tags and for every call, tags of the command are verified one by one.
* And this system works very smoothly !
* So if you're using the default message event
* ({@link https://ayfri.gitbook.io/advanced-command-handler/defaults | see how to use defaults events }), tags will be checked.
*
* @example
* ```ts
* if (command.tags.includes(Tag.guildOnly) && !message.guild) {
* message.channel.send(`You must be on a guild to execute the ${command.name} command !`);
* }
* ```
*/
export declare enum Tag {
/**
* Tag for commands to not run in a thread.
*/
channelOnly = "channelOnly",
/**
* Tag for commands to only run in private messages.
*/
dmOnly = "dmOnly",
/**
* Tag for commands to only run on a guild.
*/
guildOnly = "guildOnly",
/**
* Tag for commands to only run on a guild and if the author is the owner of the guild.
*/
guildOwnerOnly = "guildOwnerOnly",
/**
* Tag for commands to only run if author is an owner defined in {@link CommandHandler.owners}.
*/
ownerOnly = "ownerOnly",
/**
* Tag for commands to only run on a guild and in an NSFW channel.
*/
nsfw = "nsfw",
/**
* Tag for commands to only run in a thread.
*/
threadOnly = "threadOnly"
}
export declare namespace Tag {
/**
* Check if some tags are validated in the command context.
*
* @param ctx - The command context.
* @param tags - The tags to test.
* @returns - The tags not validated.
*/
function check(ctx: CommandContext, tags: Array): Tag[];
}
/**
* The cooldown object.
*/
export interface Cooldown extends CommandCooldown {
/**
* The time to wait, in seconds & milliseconds.
*/
waitMore: number;
}
/**
* Options for the Command#deleteMessage method.
*/
export interface DeleteMessageOptions {
/**
* The message to delete.
*/
message: Message;
/**
* How long to wait to delete the message in milliseconds.
*/
timeout?: number;
}
/**
* The object for missing permissions.
*/
export interface MissingPermissions {
/**
* Missing permissions of the client.
*/
client: PermissionString[];
/**
* Missing permissions of the user.
*/
user: PermissionString[];
}
/**
* An interface to put optional methods for the {@link Command} class.
*/
export interface Command {
/**
* Override this method to register your subCommands.
*/
registerSubCommands?(): any | Promise;
}
export interface CommandSignatureOptions {
showDefaultValues?: boolean;
showTypes?: boolean;
}
/**
* @see {@link https://ayfri.gitbook.io/advanced-command-handler/concepts/commands}
*/
export declare abstract class Command {
/**
* The aliases of the command.
*/
aliases?: string[];
/**
* The arguments of the command.
* You can put your own custom arguments but you must add the type to the {@link ArgumentType | argument types}.
*/
arguments: Record>;
/**
* The category of the command.
*
* @defaultValue The command parent directory.
*/
category?: string;
/**
* The channels where the command should only be executed if used (if using the default message event).
*/
channels?: Array;
/**
* The client permissions needed to run the command (if using the default message event).
*
* @defaultValue `['SEND_MESSAGES']`
*/
clientPermissions?: Array;
/**
* The cooldown of the command in seconds.
*
* @defaultValue 0
* @remarks
* Every cooldown should be saved in {@link CommandHandler.cooldowns}.
*/
cooldown?: number;
/**
* The description of the command.
*/
description?: string;
/**
* The name of the command.
*/
abstract readonly name: string;
/**
* The SubCommands of this command.
*
* @remarks Register SubCommands using the {@link Command#registerSubCommands} method.
*/
subCommands: SubCommand[];
/**
* The tags of the command.
*
* @remarks
* How tags works ?
* @see {@link Tag}
*/
tags?: Array;
/**
* The usage of the command.
*
* @example
* ```
* userinfo
* userinfo me
* userinfo
* ```
*
* @remarks If no value is set, in most places it will use the result of the {@link Command#signatures} method.
*/
usage?: string;
/**
* The user permissions needed to run the command (if using the default message event).
*
* @defaultValue `['SEND_MESSAGES']`
*/
userPermissions?: Array;
/**
* Returns the names and aliases of this command in an array.
*/
get nameAndAliases(): string[];
/**
* Returns the names and aliases of the subCommands of this command in an array flatted.
*/
get subCommandsNamesAndAliases(): string[];
/**
* Get a user ID from different sources, only here to simplify code.
*
* @param from - Where to get ID from.
* @returns - The ID.
* @internal
*/
private static getSnowflake;
/**
* Deletes a message if deletable.
*
* @param options - The options, see {@link DeleteMessageOptions}.
* @returns - If not deletable nothing, else the deleted message or the Node.js Timer if a timeout is set.
*/
deleteMessage(options: DeleteMessageOptions): Promise | NodeJS.Timeout | undefined;
/**
* Execute the run method, but perform validations before, prefer using this method in your custom Message Event.
*
* @param ctx - The CContext.
* @returns - An error related to the command if any, for example : a tag not satisfied.
*/
execute(ctx: CommandContext): Promise;
/**
* Get the actual cooldown of the user for this command plus when command has been executed and how many seconds to wait.
*
* @param from - Where to get the cooldown from, can be a user/guild/message, see types.
* @returns - The user's cooldown.
*/
getCooldown(from: Message | User | Snowflake | GuildMember): Cooldown;
/**
* Returns the invalid permissions (not presents in {@link https://discord.js.org/#/docs/main/stable/class/Permissions?scrollTo=s-FLAGS | Permissions.FLAGS}).
*
* @returns - The invalid permissions put in {@link clientPermissions} & {@link userPermissions}.
* @internal
*/
getInvalidPermissions(): {
user: string[];
client: string[];
};
/**
* Returns the missing permissions from the client & user for a context.
*
* @param ctx - The context to validate permissions for.
* @returns - The missing permissions.
*/
getMissingPermissions(ctx: CommandContext): MissingPermissions;
/**
* Gives the {@link tags} of this command which are not validated by the context.
* i.e. If a command is executed on a guild and the command has the `dmOnly` Tag, it will be returned.
*
* @param ctx - The context to test tags from.
* @returns - Tags that are not validated by the message.
*/
getMissingTags(ctx: CommandContext): Tag[];
/**
* Returns true if the user is in a cooldown for this command.
*
* @remarks
* If {@link cooldown} not set, this will always return `false`.
* @param from - From where to test if user/guild/message is in a cooldown, see types.
* @returns - Is user in a cooldown.
*/
isInCooldown(from: Message | User | Snowflake | GuildMember): boolean;
/**
* Returns false if {@link channels} are defined for this command but the message doesn't come from one of it.
*
* @param ctx - The context to test where it comes from.
* @returns - If it is on a channel required if used.
*/
isInRightChannel(ctx: CommandContext): boolean;
/**
* The function to run when executing the command.
*
* @remarks Use the {@link Command#execute} method if you want to have a validation before executing the run method.
* @param ctx - The command context.
*/
abstract run(ctx: CommandContext): any | Promise;
/**
* Put all the required properties in {@link CommandHandler.cooldowns} plus the `setTimeout` to remove the user from the cooldowns.
*
* @param from - What to use to select the user to set the cooldown from, can be a guild/message/member.
*/
setCooldown(from: Message | User | Snowflake | GuildMember): void;
/**
* Get the signature of this command.
*
* @example
* // The `help` command with an optional `command` commandArgument argument.
* ```
* help [command]
* ```
* @param options - The options for the signature, show the type of the arguments or the default values.
* @returns - The signature of this command or subCommand.
*/
signature(options?: CommandSignatureOptions): string;
/**
* Returns the signature of the command plus the signature of the subCommands of this command.
*
* @example
* // The `help` command with an optional `command` commandArgument argument and a `all` subCommand with no arguments.
* ```
* help [command]
* help all
* ```
* @param options - The options for the signature, show the type of the arguments or the default values.
* @returns - The signatures of the command.
*/
signatures(options?: CommandSignatureOptions): string;
/**
* Validate a command, returning an error if any of the validation methods are not valid.
*
* @param ctx - The CommandContext.
* @returns - The error if any.
*/
validate(ctx: CommandContext): Promise;
protected subCommand(name: string, callback: RunSubCommandFunction): void;
protected subCommand(name: string, options: SubCommandOptions, callback: RunSubCommandFunction): void;
}
/**
* @see {@link https://ayfri.gitbook.io/advanced-command-handler/concepts/commands/subcommands}
* @remarks
* This class is not in the SubCommand file because otherwise it won't compile because of circular because of the {@link Command.subCommands} property.
*/
export declare class SubCommand extends Command {
/**
* The name of the SubCommand.
*/
readonly name: string;
/**
* The method executed when the SubCommand is executed.
*
* @param ctx - The SubCommandContext.
* @returns - Any.
*/
run(ctx: SubCommandContext): Promise;
/**
* The function executed when the SubCommand is executed.
*/
readonly runFunction: RunSubCommandFunction;
/**
* Creates a new SubCommand.
*
* @remarks Make sure to creates the Subcommands in the {@link Command#registerSubCommands} method.
* @param name - The name of the SubCommand.
* @param options - The options of the Subcommand.
* @param runFunction - The callback executed when the SubCommand is executed.
*/
constructor(name: string, options: SubCommandOptions | undefined, runFunction: RunSubCommandFunction);
}