mirror of
https://github.com/discordeno/discordeno.git
synced 2026-05-31 16:00:07 +00:00
179 lines
5.0 KiB
TypeScript
179 lines
5.0 KiB
TypeScript
import {
|
|
Bot,
|
|
ButtonStyles,
|
|
MessageComponents,
|
|
MessageComponentTypes,
|
|
} from "../deps.ts";
|
|
|
|
export function validateComponents(bot: Bot, components: MessageComponents) {
|
|
if (!components?.length) return;
|
|
|
|
let actionRowCounter = 0;
|
|
|
|
for (const component of components) {
|
|
actionRowCounter++;
|
|
// Max of 5 ActionRows per message
|
|
if (actionRowCounter > 5) throw new Error("Too many action rows.");
|
|
|
|
// Max of 5 Buttons (or any component type) within an ActionRow
|
|
if (component.components?.length > 5) {
|
|
throw new Error("Too many components.");
|
|
} else if (
|
|
component.components?.length > 1 &&
|
|
component.components.some((subcomponent) =>
|
|
subcomponent.type === MessageComponentTypes.SelectMenu
|
|
)
|
|
) {
|
|
throw new Error("Select component must be alone.");
|
|
}
|
|
|
|
for (const subcomponent of component.components) {
|
|
if (
|
|
subcomponent.customId &&
|
|
!bot.utils.validateLength(subcomponent.customId, { max: 100 })
|
|
) {
|
|
throw new Error("The custom id in the component is too big.");
|
|
}
|
|
|
|
// 5 Link buttons can not have a customId
|
|
if (subcomponent.type === MessageComponentTypes.Button) {
|
|
if (subcomponent.style === ButtonStyles.Link && subcomponent.customId) {
|
|
throw new Error("Link buttons can not have custom ids.");
|
|
}
|
|
// Other buttons must have a customId
|
|
if (
|
|
!subcomponent.customId && subcomponent.style !== ButtonStyles.Link
|
|
) {
|
|
throw new Error(
|
|
"The button requires a custom id if it is not a link button.",
|
|
);
|
|
}
|
|
|
|
if (!bot.utils.validateLength(subcomponent.label, { max: 80 })) {
|
|
throw new Error("The label can not be longer than 80 characters.");
|
|
}
|
|
|
|
subcomponent.emoji = makeEmojiFromString(subcomponent.emoji);
|
|
}
|
|
|
|
if (subcomponent.type === MessageComponentTypes.SelectMenu) {
|
|
if (
|
|
subcomponent.placeholder &&
|
|
!bot.utils.validateLength(subcomponent.placeholder, { max: 100 })
|
|
) {
|
|
throw new Error(
|
|
"The component placeholder can not be longer than 100 characters.",
|
|
);
|
|
}
|
|
|
|
if (subcomponent.minValues) {
|
|
if (subcomponent.minValues < 1) {
|
|
throw new Error(
|
|
"The min values must be more than 1 in a select component.",
|
|
);
|
|
}
|
|
|
|
if (subcomponent.minValues > 25) {
|
|
throw new Error(
|
|
"The min values must be less than 25 in a select component.",
|
|
);
|
|
}
|
|
|
|
if (!subcomponent.maxValues) {
|
|
subcomponent.maxValues = subcomponent.minValues;
|
|
}
|
|
if (subcomponent.minValues > subcomponent.maxValues) {
|
|
throw new Error(
|
|
"The select component can not have a min values higher than a max values.",
|
|
);
|
|
}
|
|
}
|
|
|
|
if (subcomponent.maxValues) {
|
|
if (subcomponent.maxValues < 1) {
|
|
throw new Error(
|
|
"The max values must be more than 1 in a select component.",
|
|
);
|
|
}
|
|
|
|
if (subcomponent.maxValues > 25) {
|
|
throw new Error(
|
|
"The max values must be less than 25 in a select component.",
|
|
);
|
|
}
|
|
}
|
|
|
|
if (subcomponent.options.length < 1) {
|
|
throw new Error("You need atleast 1 option in the select component.");
|
|
}
|
|
|
|
if (subcomponent.options.length > 25) {
|
|
throw new Error(
|
|
"You can not have more than 25 options in the select component.",
|
|
);
|
|
}
|
|
|
|
let defaults = 0;
|
|
|
|
for (const option of subcomponent.options) {
|
|
if (option.default) {
|
|
defaults++;
|
|
if (defaults > (subcomponent.maxValues || 25)) {
|
|
throw new Error("You chose too many default options.");
|
|
}
|
|
}
|
|
|
|
if (!bot.utils.validateLength(option.label, { max: 25 })) {
|
|
throw new Error(
|
|
"The select component label can not exceed 25 characters.",
|
|
);
|
|
}
|
|
|
|
if (!bot.utils.validateLength(option.value, { max: 100 })) {
|
|
throw new Error(
|
|
"The select component value can not exceed 100 characters.",
|
|
);
|
|
}
|
|
|
|
if (
|
|
option.description &&
|
|
!bot.utils.validateLength(option.description, { max: 50 })
|
|
) {
|
|
throw new Error(
|
|
"The select option description can not exceed 50 characters.",
|
|
);
|
|
}
|
|
|
|
option.emoji = makeEmojiFromString(option.emoji);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function makeEmojiFromString(
|
|
emoji?:
|
|
| string
|
|
| {
|
|
id?: string | undefined;
|
|
name?: string | undefined;
|
|
animated?: boolean | undefined;
|
|
},
|
|
) {
|
|
if (typeof emoji !== "string") return emoji;
|
|
|
|
// A snowflake id was provided
|
|
if (/^[0-9]+$/.test(emoji)) {
|
|
emoji = {
|
|
id: emoji,
|
|
};
|
|
} else {
|
|
// A unicode emoji was provided
|
|
emoji = {
|
|
name: emoji,
|
|
};
|
|
}
|
|
|
|
return emoji;
|
|
}
|