djs-message-commands
Version:
Build easy, safe, and testable message commands for discord.js
210 lines (209 loc) • 7.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageCommandOptionErrors = exports.MessageCommandRoleOption = exports.MessageCommandChannelOption = exports.MessageCommandMemberOption = exports.MessageCommandBooleanOption = exports.MessageCommandNumberOption = exports.MessageCommandStringOption = exports.MessageCommandOptionChoiceable = exports.MessageCommandOption = void 0;
const discord_js_1 = require("discord.js");
/**
* A composable option/argument to add to a message command.
* @abstract
*/
class MessageCommandOption {
/**
* The name of the option.
*/
name;
/**
* The description of the option.
*/
description;
/**
* The type of the option.
*/
type;
constructor(data) {
this.name = typeof data === "object" ? data.name : "No name implemented";
this.description = typeof data === "object" ? data.description : "No description implemented";
this.type = typeof data === "object" ? data.type : data;
}
/**
* Sets the name of the option. Cannot be empty.
* @param name The name of the option.
* @returns The option instance.
*/
setName(name) {
if (name === "") {
throw new Error("Option name must be at least one character long.");
}
this.name = name;
return this;
}
/**
* Sets the name of the option. Cannot be empty.
* @param description The description of the option.
* @returns The option instance.
*/
setDescription(description) {
if (description === "") {
throw new Error("Option description must be at least one character long.");
}
this.description = description;
return this;
}
}
exports.MessageCommandOption = MessageCommandOption;
/**
* A option that can be supplied with pre-defined values for the user to choose from.
* @abstract
* @extends MessageCommandOption
*/
class MessageCommandOptionChoiceable extends MessageCommandOption {
/**
* The available pre-determined choices for this option.
*/
choices;
constructor(type) {
super(type);
this.choices = [];
}
/**
* Add a choice for this option. Chain this multiple times to add more options OR use {@link MessageCommandOptionChoiceable.setChoices}.
* @param choice The choice to add.
* @returns The option instance.
*/
addChoice(...choice) {
if (choice.length <= 0) {
throw new Error("There must be at least one choice provided in the array.");
}
if (choice.every(c => c === "")) {
throw new Error("You must provide a name and value for the option choice.");
}
if (choice[0] === "") {
throw new Error("You must provide a name for the option choice.");
}
if (choice[1] === "") {
throw new Error("You must provide a value for the option choice.");
}
this.choices.push(choice);
return this;
}
/**
* Add multiple choices for this option. Use this either once OR chain {@link MessageCommandOptionChoiceable.addChoice}.
* @param choices The choices to add.
* @returns The option instance.
*/
setChoices(choices) {
if (choices.length <= 0) {
throw new Error("You must provide at least one choice.");
}
for (const choice of choices) {
if (choice.some(c => c === "")) {
throw new Error("You must provide a name and value for every option choice.");
}
}
this.choices = choices;
return this;
}
}
exports.MessageCommandOptionChoiceable = MessageCommandOptionChoiceable;
/**
* A string option. Allows choices.
* @extends MessageCommandOptionChoiceable
*/
class MessageCommandStringOption extends MessageCommandOptionChoiceable {
constructor() {
super("text" /* STRING */);
}
validate(option) {
for (const choice of this.choices) {
if (choice[1] === option) {
return choice[1];
}
}
const matches = option.matchAll(/^"(.+)"$/gi).next().value;
return matches ? matches[1] : undefined;
}
}
exports.MessageCommandStringOption = MessageCommandStringOption;
/**
* A number option. Allows choices.
* @extends MessageCommandOptionChoiceable
*/
class MessageCommandNumberOption extends MessageCommandOptionChoiceable {
constructor() {
super("number" /* NUMBER */);
}
validate(option) {
const number = Number.parseInt(option);
return Number.isNaN(number) ? undefined : number;
}
}
exports.MessageCommandNumberOption = MessageCommandNumberOption;
/**
* A boolean option.
* @extends MessageCommandOption
*/
class MessageCommandBooleanOption extends MessageCommandOption {
constructor() {
super("true/false" /* BOOLEAN */);
}
validate(option) {
const matches = option.match(/^(true|false)$/g);
if (matches) {
if (matches[0] === "true") {
return true;
}
if (matches[0] === "false") {
return false;
}
}
return undefined;
}
}
exports.MessageCommandBooleanOption = MessageCommandBooleanOption;
/**
* A member mentionable option.
* @extends MessageCommandOption
*/
class MessageCommandMemberOption extends MessageCommandOption {
constructor() {
super("member" /* MEMBER */);
}
validate(option) {
const matches = option.matchAll(discord_js_1.MessageMentions.USERS_PATTERN).next().value;
return matches ? matches[1] : undefined;
}
}
exports.MessageCommandMemberOption = MessageCommandMemberOption;
/**
* A channel mentionable option.
* @extends MessageCommandOption
*/
class MessageCommandChannelOption extends MessageCommandOption {
constructor() {
super("channel" /* CHANNEL */);
}
validate(option) {
const matches = option.matchAll(discord_js_1.MessageMentions.CHANNELS_PATTERN).next().value;
return matches ? matches[1] : undefined;
}
}
exports.MessageCommandChannelOption = MessageCommandChannelOption;
/**
* A role mentionable option.
* @extends MessageCommandOption
*/
class MessageCommandRoleOption extends MessageCommandOption {
constructor() {
super("role" /* ROLE */);
}
validate(option) {
const matches = option.matchAll(discord_js_1.MessageMentions.ROLES_PATTERN).next().value;
return matches ? matches[1] : undefined;
}
}
exports.MessageCommandRoleOption = MessageCommandRoleOption;
exports.MessageCommandOptionErrors = {
INVALID_ARG_TYPE: "INVALID_ARG_TYPE",
MISSING_ARGS: "MISSING_ARGS",
MISSING_PERMISSIONS: "MISSING_PERMISSIONS",
MISSING_ROLES: "MISSING_ROLES",
};