mirror of
https://github.com/discordeno/discordeno.git
synced 2026-09-17 08:47:22 +00:00
shtuff
This commit is contained in:
+3
-2
@@ -114,8 +114,9 @@ import { getGuildTemplates } from "./templates/get_guild_templates.ts";
|
|||||||
import { getTemplate } from "./templates/get_template.ts";
|
import { getTemplate } from "./templates/get_template.ts";
|
||||||
import { syncGuildTemplate } from "./templates/sync_guild_template.ts";
|
import { syncGuildTemplate } from "./templates/sync_guild_template.ts";
|
||||||
// Type Guards
|
// Type Guards
|
||||||
import { isActionRow } from "./type_guards/is_action_row.ts";
|
|
||||||
import { isButton } from "./type_guards/is_button.ts";
|
import { isButton } from "./type_guards/is_button.ts";
|
||||||
|
import { isSelectMenu } from "./type_guards/is_select_menu.ts";
|
||||||
|
|
||||||
import { createWebhook } from "./webhooks/create_webhook.ts";
|
import { createWebhook } from "./webhooks/create_webhook.ts";
|
||||||
import { deleteWebhook } from "./webhooks/delete_webhook.ts";
|
import { deleteWebhook } from "./webhooks/delete_webhook.ts";
|
||||||
import { deleteWebhookMessage } from "./webhooks/delete_webhook_message.ts";
|
import { deleteWebhookMessage } from "./webhooks/delete_webhook_message.ts";
|
||||||
@@ -239,8 +240,8 @@ export {
|
|||||||
guildBannerURL,
|
guildBannerURL,
|
||||||
guildIconURL,
|
guildIconURL,
|
||||||
guildSplashURL,
|
guildSplashURL,
|
||||||
isActionRow,
|
|
||||||
isButton,
|
isButton,
|
||||||
|
isSelectMenu,
|
||||||
isChannelSynced,
|
isChannelSynced,
|
||||||
kick,
|
kick,
|
||||||
kickMember,
|
kickMember,
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import type { ActionRow } from "../../types/messages/components/action_row.ts";
|
|
||||||
import type { MessageComponent } from "../../types/messages/components/message_components.ts";
|
|
||||||
import { MessageComponentTypes } from "../../types/messages/components/message_component_types.ts";
|
|
||||||
|
|
||||||
/** A type guard function to tell if it is a action row component */
|
|
||||||
export function isActionRow(component: MessageComponent): component is ActionRow {
|
|
||||||
return component.type === MessageComponentTypes.ActionRow;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
import type { ButtonComponent } from "../../types/messages/components/button_component.ts";
|
import type { ButtonComponent } from "../../types/messages/components/button_component.ts";
|
||||||
import type { MessageComponent } from "../../types/messages/components/message_components.ts";
|
import type { ActionRoleComponents } from "../../types/messages/components/message_components.ts";
|
||||||
import { MessageComponentTypes } from "../../types/messages/components/message_component_types.ts";
|
|
||||||
|
|
||||||
/** A type guard function to tell if it is a button component */
|
/** A type guard function to tell if it is a button component */
|
||||||
export function isButton(component: MessageComponent): component is ButtonComponent {
|
export function isButton(component: ActionRoleComponents): component is ButtonComponent {
|
||||||
return component.type === MessageComponentTypes.Button;
|
return Reflect.has(component, "type");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import type { ActionRoleComponents } from "../../types/messages/components/message_components.ts";
|
||||||
|
import { SelectMenuComponent } from "../../types/messages/components/select_menu.ts";
|
||||||
|
|
||||||
|
/** A type guard function to tell if it is a button component */
|
||||||
|
export function isSelectMenu(component: ActionRoleComponents): component is SelectMenuComponent {
|
||||||
|
return !Reflect.has(component, "type");
|
||||||
|
}
|
||||||
@@ -11,8 +11,4 @@ export interface ApplicationCommandInteractionData {
|
|||||||
resolved?: ApplicationCommandInteractionDataResolved;
|
resolved?: ApplicationCommandInteractionDataResolved;
|
||||||
/** The params + values from the user */
|
/** The params + values from the user */
|
||||||
options?: ApplicationCommandInteractionDataOption[];
|
options?: ApplicationCommandInteractionDataOption[];
|
||||||
/** with the value you defined for this component */
|
|
||||||
customId?: string;
|
|
||||||
/** The type of this component */
|
|
||||||
componentType?: 2;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,32 @@ import { User } from "../users/user.ts";
|
|||||||
import { ApplicationCommandInteractionData } from "./commands/application_command_interaction_data.ts";
|
import { ApplicationCommandInteractionData } from "./commands/application_command_interaction_data.ts";
|
||||||
import { InteractionGuildMember } from "./interaction_guild_member.ts";
|
import { InteractionGuildMember } from "./interaction_guild_member.ts";
|
||||||
import { DiscordInteractionTypes } from "./interaction_types.ts";
|
import { DiscordInteractionTypes } from "./interaction_types.ts";
|
||||||
|
import { SelectMenuData } from "../messages/components/select_data.ts";
|
||||||
|
import { ButtonData } from "../messages/components/button_data.ts";
|
||||||
|
|
||||||
/** https://discord.com/developers/docs/interactions/slash-commands#interaction */
|
/** https://discord.com/developers/docs/interactions/slash-commands#interaction */
|
||||||
export interface Interaction {
|
export interface Interaction {
|
||||||
|
/** The command data payload */
|
||||||
|
data?: ApplicationCommandInteractionData | ButtonData | SelectMenuData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SlashCommandInteraction extends BaseInteraction {
|
||||||
|
type: DiscordInteractionTypes.ApplicationCommand;
|
||||||
|
data?: ApplicationCommandInteractionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ComponentInteraction extends BaseInteraction {
|
||||||
|
type: DiscordInteractionTypes.MessageComponent;
|
||||||
|
data?: ButtonData | SelectMenuData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BaseInteraction {
|
||||||
/** Id of the interaction */
|
/** Id of the interaction */
|
||||||
id: string;
|
id: string;
|
||||||
/** Id of the application this interaction is for */
|
/** Id of the application this interaction is for */
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
/** The type of interaction */
|
/** The type of interaction */
|
||||||
type: DiscordInteractionTypes;
|
type: DiscordInteractionTypes;
|
||||||
/** The command data payload */
|
|
||||||
data?: ApplicationCommandInteractionData;
|
|
||||||
/** The guild it was sent from */
|
/** The guild it was sent from */
|
||||||
guildId?: string;
|
guildId?: string;
|
||||||
/** The channel it was sent from */
|
/** The channel it was sent from */
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
import { ButtonComponent } from "./button_component.ts";
|
import { ButtonComponent } from "./button_component.ts";
|
||||||
|
import { SelectMenuComponent } from "./select_menu.ts";
|
||||||
|
|
||||||
// TODO: add docs link
|
// TODO: add docs link
|
||||||
export interface ActionRow {
|
export interface ActionRow {
|
||||||
/** Action rows are a group of buttons. */
|
/** Action rows are a group of buttons. */
|
||||||
type: 1;
|
type: 1;
|
||||||
/** The button components */
|
/** The components in this row */
|
||||||
components: ButtonComponent[];
|
components:
|
||||||
|
| [SelectMenuComponent | ButtonComponent]
|
||||||
|
| [ButtonComponent, ButtonComponent]
|
||||||
|
| [ButtonComponent, ButtonComponent, ButtonComponent]
|
||||||
|
| [ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent]
|
||||||
|
| [ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export interface ButtonData {
|
||||||
|
/** with the value you defined for this component */
|
||||||
|
customId: string;
|
||||||
|
/** The type of this component */
|
||||||
|
componentType: 2;
|
||||||
|
}
|
||||||
@@ -4,6 +4,8 @@ export enum DiscordMessageComponentTypes {
|
|||||||
ActionRow = 1,
|
ActionRow = 1,
|
||||||
/** A button! */
|
/** A button! */
|
||||||
Button,
|
Button,
|
||||||
|
/** A select menu. */
|
||||||
|
SelectMenu,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MessageComponentTypes = DiscordMessageComponentTypes;
|
export type MessageComponentTypes = DiscordMessageComponentTypes;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { ActionRow } from "./action_row.ts";
|
import { ActionRow } from "./action_row.ts";
|
||||||
import { ButtonComponent } from "./button_component.ts";
|
import { ButtonComponent } from "./button_component.ts";
|
||||||
|
import { SelectMenuComponent } from "./select_menu.ts";
|
||||||
|
|
||||||
export type MessageComponent = ActionRow | ButtonComponent;
|
export type ActionRoleComponents = ButtonComponent | SelectMenuComponent;
|
||||||
|
|
||||||
export type MessageComponents = MessageComponent[];
|
export type MessageComponents = ActionRow[];
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export interface SelectMenuData {
|
||||||
|
/** The type of component */
|
||||||
|
componentType: 3;
|
||||||
|
/** The custom id provided for this component. */
|
||||||
|
customId: string;
|
||||||
|
/** The values chosen by the user. */
|
||||||
|
values: string[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { SelectOption } from "./select_option.ts";
|
||||||
|
|
||||||
|
export interface SelectMenuComponent {
|
||||||
|
/** A custom identifier for this component. Maximum 100 characters. */
|
||||||
|
customId: string;
|
||||||
|
/** A custom placeholder text if nothing is selected. Maximum 100 characters. */
|
||||||
|
placeholder?: string;
|
||||||
|
/** The minimum number of items that must be selected. Default 1. Between 1-25. */
|
||||||
|
minValues?: number;
|
||||||
|
/** The maximum number of items that can be selected. Default 1. Between 1-25. */
|
||||||
|
maxValues?: number;
|
||||||
|
/** The choices! Maximum of 25 items. */
|
||||||
|
options: SelectOption[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
export interface SelectOption {
|
||||||
|
/** The user-facing name of the option. Maximum 25 characters. */
|
||||||
|
label: string;
|
||||||
|
/** The dev-defined value of the option. Maximum 100 characters. */
|
||||||
|
value: string;
|
||||||
|
/** An additional description of the option. Maximum 50 characters. */
|
||||||
|
description?: string;
|
||||||
|
/** The id, name, and animated properties of an emoji. */
|
||||||
|
emoji?:
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
/** Emoji id */
|
||||||
|
id?: string;
|
||||||
|
/** Emoji name */
|
||||||
|
name?: string;
|
||||||
|
/** Whether this emoji is animated */
|
||||||
|
animated?: boolean;
|
||||||
|
};
|
||||||
|
/** Will render this option as already-selected by default. */
|
||||||
|
default: boolean;
|
||||||
|
}
|
||||||
@@ -6,6 +6,9 @@ export * from "./components/button_component.ts";
|
|||||||
export * from "./components/button_styles.ts";
|
export * from "./components/button_styles.ts";
|
||||||
export * from "./components/message_component_types.ts";
|
export * from "./components/message_component_types.ts";
|
||||||
export * from "./components/message_components.ts";
|
export * from "./components/message_components.ts";
|
||||||
|
export * from "./components/select_data.ts";
|
||||||
|
export * from "./components/select_menu.ts";
|
||||||
|
export * from "./components/select_option.ts";
|
||||||
export * from "./create_message.ts";
|
export * from "./create_message.ts";
|
||||||
export * from "./edit_message.ts";
|
export * from "./edit_message.ts";
|
||||||
export * from "./get_messages.ts";
|
export * from "./get_messages.ts";
|
||||||
|
|||||||
+35
-38
@@ -1,6 +1,5 @@
|
|||||||
import { encode } from "./deps.ts";
|
import { encode } from "./deps.ts";
|
||||||
import { eventHandlers } from "../bot.ts";
|
import { eventHandlers } from "../bot.ts";
|
||||||
import { isActionRow } from "../helpers/type_guards/is_action_row.ts";
|
|
||||||
import { isButton } from "../helpers/type_guards/is_button.ts";
|
import { isButton } from "../helpers/type_guards/is_button.ts";
|
||||||
import { Errors } from "../types/discordeno/errors.ts";
|
import { Errors } from "../types/discordeno/errors.ts";
|
||||||
import type { ApplicationCommandOption } from "../types/interactions/commands/application_command_option.ts";
|
import type { ApplicationCommandOption } from "../types/interactions/commands/application_command_option.ts";
|
||||||
@@ -215,43 +214,6 @@ export function validateComponents(components: MessageComponents) {
|
|||||||
let actionRowCounter = 0;
|
let actionRowCounter = 0;
|
||||||
|
|
||||||
for (const component of components) {
|
for (const component of components) {
|
||||||
// 5 Link buttons can not have a customId
|
|
||||||
if (isButton(component)) {
|
|
||||||
if (component.type === ButtonStyles.Link && component.customId) {
|
|
||||||
throw new Error(Errors.LINK_BUTTON_CANNOT_HAVE_CUSTOM_ID);
|
|
||||||
}
|
|
||||||
// Other buttons must have a customId
|
|
||||||
if (!component.customId && component.type !== ButtonStyles.Link) {
|
|
||||||
throw new Error(Errors.BUTTON_REQUIRES_CUSTOM_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!validateLength(component.label, { max: 80 })) {
|
|
||||||
throw new Error(Errors.COMPONENT_LABEL_TOO_BIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (component.customId && !validateLength(component.customId, { max: 100 })) {
|
|
||||||
throw new Error(Errors.COMPONENT_CUSTOM_ID_TOO_BIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof component.emoji === "string") {
|
|
||||||
// A snowflake id was provided
|
|
||||||
if (/^[0-9]+$/.test(component.emoji)) {
|
|
||||||
component.emoji = {
|
|
||||||
id: component.emoji,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// A unicode emoji was provided
|
|
||||||
component.emoji = {
|
|
||||||
name: component.emoji,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isActionRow(component)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
actionRowCounter++;
|
actionRowCounter++;
|
||||||
// Max of 5 ActionRows per message
|
// Max of 5 ActionRows per message
|
||||||
if (actionRowCounter > 5) throw new Error(Errors.TOO_MANY_ACTION_ROWS);
|
if (actionRowCounter > 5) throw new Error(Errors.TOO_MANY_ACTION_ROWS);
|
||||||
@@ -260,5 +222,40 @@ export function validateComponents(components: MessageComponents) {
|
|||||||
if (component.components?.length > 5) {
|
if (component.components?.length > 5) {
|
||||||
throw new Error(Errors.TOO_MANY_COMPONENTS);
|
throw new Error(Errors.TOO_MANY_COMPONENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const subcomponent of component.components) {
|
||||||
|
// 5 Link buttons can not have a customId
|
||||||
|
if (isButton(subcomponent)) {
|
||||||
|
if (subcomponent.type === ButtonStyles.Link && subcomponent.customId) {
|
||||||
|
throw new Error(Errors.LINK_BUTTON_CANNOT_HAVE_CUSTOM_ID);
|
||||||
|
}
|
||||||
|
// Other buttons must have a customId
|
||||||
|
if (!subcomponent.customId && subcomponent.type !== ButtonStyles.Link) {
|
||||||
|
throw new Error(Errors.BUTTON_REQUIRES_CUSTOM_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validateLength(subcomponent.label, { max: 80 })) {
|
||||||
|
throw new Error(Errors.subcomponent_LABEL_TOO_BIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subcomponent.customId && !validateLength(subcomponent.customId, { max: 100 })) {
|
||||||
|
throw new Error(Errors.subcomponent_CUSTOM_ID_TOO_BIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof subcomponent.emoji === "string") {
|
||||||
|
// A snowflake id was provided
|
||||||
|
if (/^[0-9]+$/.test(subcomponent.emoji)) {
|
||||||
|
subcomponent.emoji = {
|
||||||
|
id: subcomponent.emoji,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// A unicode emoji was provided
|
||||||
|
subcomponent.emoji = {
|
||||||
|
name: subcomponent.emoji,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user