From 35ec425916295da00aa021a1d7999270fc0f1cc9 Mon Sep 17 00:00:00 2001 From: socram03 Date: Mon, 4 Jul 2022 19:34:55 -0400 Subject: [PATCH] feacture: Builders fix: fmt --- deno.json | 2 +- handlers/Actions.ts | 24 ++++----- mod.ts | 5 ++ structures/Message.ts | 3 +- structures/MessageReaction.ts | 2 +- structures/StageInstance.ts | 6 +-- .../builders/InputTextComponentBuilder.ts | 49 +++++++++++++++++ structures/builders/MessageActionRow.ts | 29 ++++++++++ structures/builders/MessageButton.ts | 44 +++++++++++++++ structures/builders/MessageSelectMenu.ts | 53 +++++++++++++++++++ .../builders/SelectMenuOptionBuilder.ts | 38 +++++++++++++ structures/channels/GuildChannel.ts | 14 +++-- structures/channels/TextChannel.ts | 38 ++++++------- structures/guilds/Guild.ts | 30 +++++------ tests/mod.ts | 3 +- util/Routes.ts | 9 ++-- util/builders.ts | 9 ++++ vendor/types/discord.ts | 2 + 18 files changed, 296 insertions(+), 64 deletions(-) create mode 100644 structures/builders/InputTextComponentBuilder.ts create mode 100644 structures/builders/MessageActionRow.ts create mode 100644 structures/builders/MessageButton.ts create mode 100644 structures/builders/MessageSelectMenu.ts create mode 100644 structures/builders/SelectMenuOptionBuilder.ts create mode 100644 util/builders.ts diff --git a/deno.json b/deno.json index 25bec05..b115d2b 100644 --- a/deno.json +++ b/deno.json @@ -1,7 +1,7 @@ { "fmt": { "files": { - "exclude": "vendor" + "exclude": ["vendor"] }, "options": { "indentWidth": 4, diff --git a/handlers/Actions.ts b/handlers/Actions.ts index e1dd524..a5cf1e8 100644 --- a/handlers/Actions.ts +++ b/handlers/Actions.ts @@ -1,17 +1,16 @@ import type { DiscordChannel, DiscordChannelPinsUpdate, + DiscordEmoji, DiscordGuild, + DiscordGuildBanAddRemove, + DiscordGuildEmojisUpdate, DiscordGuildMemberAdd, DiscordGuildMemberRemove, DiscordGuildMemberUpdate, - DiscordGuildBanAddRemove, - DiscordGuildEmojisUpdate, DiscordGuildRoleCreate, - DiscordGuildRoleUpdate, DiscordGuildRoleDelete, - DiscordUser, - DiscordEmoji, + DiscordGuildRoleUpdate, DiscordInteraction, DiscordMemberWithUser, DiscordMessage, @@ -25,7 +24,8 @@ import type { // DiscordThreadMemberUpdate, // DiscordThreadMembersUpdate, DiscordThreadListSync, - DiscordWebhookUpdate + DiscordUser, + DiscordWebhookUpdate, } from "../vendor/external.ts"; import type { Snowflake } from "../util/Snowflake.ts"; import type { Session } from "../session/Session.ts"; @@ -37,7 +37,7 @@ import ThreadMember from "../structures/ThreadMember.ts"; import Member from "../structures/Member.ts"; import Message from "../structures/Message.ts"; import User from "../structures/User.ts"; -import Guild from "../structures/guilds/Guild.ts"; +import Guild from "../structures/guilds/Guild.ts"; import Interaction from "../structures/interactions/Interaction.ts"; export type RawHandler = (...args: [Session, number, T]) => void; @@ -90,20 +90,20 @@ export const GUILD_BAN_REMOVE: RawHandler = (session, }; export const GUILD_EMOJIS_UPDATE: RawHandler = (session, _shardId, data) => { - session.emit("guildEmojisUpdate", { guildId: data.guild_id, emojis: data.emojis}) + session.emit("guildEmojisUpdate", { guildId: data.guild_id, emojis: data.emojis }); }; export const GUILD_ROLE_CREATE: RawHandler = (session, _shardId, data) => { session.emit("guildRoleCreate", { guildId: data.guild_id, role: data.role }); -} +}; export const GUILD_ROLE_UPDATE: RawHandler = (session, _shardId, data) => { session.emit("guildRoleUpdate", { guildId: data.guild_id, role: data.role }); -} +}; export const GUILD_ROLE_DELETE: RawHandler = (session, _shardId, data) => { session.emit("guildRoleDelete", { guildId: data.guild_id, roleId: data.role_id }); -} +}; export const INTERACTION_CREATE: RawHandler = (session, _shardId, interaction) => { session.unrepliedInteractions.add(BigInt(interaction.id)); @@ -164,7 +164,7 @@ export const CHANNEL_PINS_UPDATE: RawHandler = (sessio }; export const WEBHOOKS_UPDATE: RawHandler = (session, _shardId, webhook) => { - session.emit("webhooksUpdate", { guildId: webhook.guild_id, channelId: webhook.channel_id }) + session.emit("webhooksUpdate", { guildId: webhook.guild_id, channelId: webhook.channel_id }); }; /* diff --git a/mod.ts b/mod.ts index ab987f5..93499a6 100644 --- a/mod.ts +++ b/mod.ts @@ -36,6 +36,11 @@ export * from "./structures/guilds/Guild.ts"; export * from "./structures/guilds/InviteGuild.ts"; export * from "./structures/builders/EmbedBuilder.ts"; +export * from "./structures/builders/InputTextComponentBuilder.ts"; +export * from "./structures/builders/MessageActionRow.ts"; +export * from "./structures/builders/MessageButton.ts"; +export * from "./structures/builders/MessageSelectMenu.ts"; +export * from "./structures/builders/SelectMenuOptionBuilder.ts"; export * from "./structures/interactions/Interaction.ts"; diff --git a/structures/Message.ts b/structures/Message.ts index e193d73..d13e095 100644 --- a/structures/Message.ts +++ b/structures/Message.ts @@ -6,8 +6,8 @@ import type { DiscordMessage, DiscordUser, FileContent, - MessageTypes, MessageActivityTypes, + MessageTypes, } from "../vendor/external.ts"; import type { Component } from "./components/Component.ts"; import type { GetReactions } from "../util/Routes.ts"; @@ -181,7 +181,6 @@ export class Message implements Model { return this.editedTimestamp; } - get url() { return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`; } diff --git a/structures/MessageReaction.ts b/structures/MessageReaction.ts index d819d2c..5decdf4 100644 --- a/structures/MessageReaction.ts +++ b/structures/MessageReaction.ts @@ -5,7 +5,7 @@ import Emoji from "./Emoji.ts"; /** * Represents a reaction * @link https://discord.com/developers/docs/resources/channel#reaction-object - * */ + */ export class MessageReaction { constructor(session: Session, data: DiscordReaction) { this.session = session; diff --git a/structures/StageInstance.ts b/structures/StageInstance.ts index c82bb56..5c2b91e 100644 --- a/structures/StageInstance.ts +++ b/structures/StageInstance.ts @@ -39,15 +39,15 @@ export class StageInstance implements Model { discoverableDisabled: boolean; guildScheduledEventId: Snowflake; - async edit(options: { topic?: string, privacyLevel?: PrivacyLevels }) { + async edit(options: { topic?: string; privacyLevel?: PrivacyLevels }) { const stageInstance = await this.session.rest.runMethod( this.session.rest, "PATCH", Routes.STAGE_INSTANCE(this.id), { topic: options.topic, - privacy_level: options.privacyLevel - } + privacy_level: options.privacyLevel, + }, ); return new StageInstance(this.session, stageInstance); diff --git a/structures/builders/InputTextComponentBuilder.ts b/structures/builders/InputTextComponentBuilder.ts new file mode 100644 index 0000000..3bba80d --- /dev/null +++ b/structures/builders/InputTextComponentBuilder.ts @@ -0,0 +1,49 @@ +import { DiscordInputTextComponent, MessageComponentTypes, TextStyles } from "../../vendor/external.ts"; + +export class InputTextBuilder { + constructor() { + this.#data = {} as DiscordInputTextComponent; + this.type = 4; + } + #data: DiscordInputTextComponent; + type: MessageComponentTypes.InputText; + + setStyle(style: TextStyles) { + this.#data.style = style; + return this; + } + + setLabel(label: string) { + this.#data.label = label; + return this; + } + + setPlaceholder(placeholder: string) { + this.#data.placeholder = placeholder; + return this; + } + + setLength(max?: number, min?: number) { + this.#data.max_length = max; + this.#data.min_length = min; + return this; + } + + setCustomId(id: string) { + this.#data.custom_id = id; + return this; + } + + setValue(value: string) { + this.#data.value = value; + return this; + } + + setRequired(required = true) { + this.#data.required = required; + return this; + } + toJSON() { + return { ...this.#data }; + } +} diff --git a/structures/builders/MessageActionRow.ts b/structures/builders/MessageActionRow.ts new file mode 100644 index 0000000..856929a --- /dev/null +++ b/structures/builders/MessageActionRow.ts @@ -0,0 +1,29 @@ +import { MessageComponentTypes } from "../../vendor/external.ts"; +import { AnyComponentBuilder } from "../../util/builders.ts"; + +export class ActionRowBuilder { + constructor() { + this.components = [] as T[]; + this.type = 1; + } + components: T[]; + type: MessageComponentTypes.ActionRow; + + addComponents(...components: T[]) { + this.components.push(...components); + return this; + } + + setComponents(...components: T[]) { + this.components.splice( + 0, + this.components.length, + ...components, + ); + return this; + } + + toJSON() { + return { type: this.type, components: this.components.map((c) => c.toJSON()) }; + } +} diff --git a/structures/builders/MessageButton.ts b/structures/builders/MessageButton.ts new file mode 100644 index 0000000..4ef0910 --- /dev/null +++ b/structures/builders/MessageButton.ts @@ -0,0 +1,44 @@ +import { ButtonStyles, type DiscordButtonComponent, MessageComponentTypes } from "../../vendor/external.ts"; +import { ComponentEmoji } from "../../util/builders.ts"; + +export class ButtonBuilder { + constructor() { + this.#data = {} as DiscordButtonComponent; + this.type = 2; + } + #data: DiscordButtonComponent; + type: MessageComponentTypes.Button; + setStyle(style: ButtonStyles) { + this.#data.style = style; + return this; + } + + setLabel(label: string) { + this.#data.label = label; + return this; + } + + setCustomId(id: string) { + this.#data.custom_id = id; + return this; + } + + setEmoji(emoji: ComponentEmoji) { + this.#data.emoji = emoji; + return this; + } + + setDisabled(disabled = true) { + this.#data.disabled = disabled; + return this; + } + + setURL(url: string) { + this.#data.url = url; + return this; + } + + toJSON(): DiscordButtonComponent { + return { ...this.#data }; + } +} diff --git a/structures/builders/MessageSelectMenu.ts b/structures/builders/MessageSelectMenu.ts new file mode 100644 index 0000000..a932131 --- /dev/null +++ b/structures/builders/MessageSelectMenu.ts @@ -0,0 +1,53 @@ +import { type DiscordSelectMenuComponent, MessageComponentTypes } from "../../vendor/external.ts"; +import { SelectMenuOptionBuilder } from "./SelectMenuOptionBuilder.ts"; + +export class SelectMenuBuilder { + constructor() { + this.#data = {} as DiscordSelectMenuComponent; + this.type = 3; + this.options = []; + } + #data: DiscordSelectMenuComponent; + type: MessageComponentTypes.SelectMenu; + options: SelectMenuOptionBuilder[]; + + setPlaceholder(placeholder: string) { + this.#data.placeholder = placeholder; + return this; + } + + setValues(max?: number, min?: number) { + this.#data.max_values = max; + this.#data.min_values = min; + return this; + } + + setDisabled(disabled = true) { + this.#data.disabled = disabled; + return this; + } + + setCustomId(id: string) { + this.#data.custom_id = id; + return this; + } + + setOptions(...options: SelectMenuOptionBuilder[]) { + this.options.splice( + 0, + this.options.length, + ...options, + ); + return this; + } + + addOptions(...options: SelectMenuOptionBuilder[]) { + this.options.push( + ...options, + ); + } + + toJSON() { + return { ...this.#data, options: this.options.map((option) => option.toJSON()) }; + } +} diff --git a/structures/builders/SelectMenuOptionBuilder.ts b/structures/builders/SelectMenuOptionBuilder.ts new file mode 100644 index 0000000..ad84ff6 --- /dev/null +++ b/structures/builders/SelectMenuOptionBuilder.ts @@ -0,0 +1,38 @@ +import type { DiscordSelectOption } from "../../vendor/external.ts"; +import type { ComponentEmoji } from "../../util/builders.ts"; + +export class SelectMenuOptionBuilder { + constructor() { + this.#data = {} as DiscordSelectOption; + } + #data: DiscordSelectOption; + + setLabel(label: string) { + this.#data.label = label; + return this; + } + + setValue(value: string) { + this.#data.value = value; + return this; + } + + setDescription(description: string) { + this.#data.description = description; + return this; + } + + setDefault(Default = true) { + this.#data.default = Default; + return this; + } + + setEmoji(emoji: ComponentEmoji) { + this.#data.emoji = emoji; + return this; + } + + toJSON() { + return { ...this.#data }; + } +} diff --git a/structures/channels/GuildChannel.ts b/structures/channels/GuildChannel.ts index 3609b15..6dde8ff 100644 --- a/structures/channels/GuildChannel.ts +++ b/structures/channels/GuildChannel.ts @@ -1,7 +1,12 @@ import type { Model } from "../Base.ts"; import type { Snowflake } from "../../util/Snowflake.ts"; import type { Session } from "../../session/Session.ts"; -import type { ChannelTypes, DiscordChannel, DiscordInviteMetadata, DiscordListArchivedThreads } from "../../vendor/external.ts"; +import type { + ChannelTypes, + DiscordChannel, + DiscordInviteMetadata, + DiscordListArchivedThreads, +} from "../../vendor/external.ts"; import type { ListArchivedThreads } from "../../util/Routes.ts"; import BaseChannel from "./BaseChannel.ts"; import ThreadChannel from "./ThreadChannel.ts"; @@ -25,7 +30,7 @@ export interface ThreadCreateOptions { /** * Represents the option object to create a thread channel from a message * @link https://discord.com/developers/docs/resources/channel#start-thread-from-message - * */ + */ export interface ThreadCreateOptions { name: string; autoArchiveDuration?: 60 | 1440 | 4320 | 10080; @@ -59,7 +64,6 @@ export class GuildChannel extends BaseChannel implements Model { return invites.map((invite) => new Invite(this.session, invite)); } - async getArchivedThreads(options: ListArchivedThreads & { type: "public" | "private" | "privateJoinedThreads" }) { let func: (channelId: Snowflake, options: ListArchivedThreads) => string; @@ -78,10 +82,10 @@ export class GuildChannel extends BaseChannel implements Model { const { threads, members, has_more } = await this.session.rest.runMethod( this.session.rest, "GET", - func(this.id, options) + func(this.id, options), ); - return { + return { threads: Object.fromEntries( threads.map((thread) => [thread.id, new ThreadChannel(this.session, thread, this.id)]), ) as Record, diff --git a/structures/channels/TextChannel.ts b/structures/channels/TextChannel.ts index 5b5bd7d..e2ae955 100644 --- a/structures/channels/TextChannel.ts +++ b/structures/channels/TextChannel.ts @@ -88,27 +88,27 @@ export class TextChannel { * Mixin */ static applyTo(klass: Function, ignore: Array = []) { - const methods: Array = [ - "fetchPins", - "createInvite", - "fetchMessages", - "sendTyping", - "pinMessage", - "unpinMessage", - "addReaction", - "removeReaction", - "nukeReactions", - "fetchPins", - "sendMessage", - "editMessage", - "createWebhook", - ]; + const methods: Array = [ + "fetchPins", + "createInvite", + "fetchMessages", + "sendTyping", + "pinMessage", + "unpinMessage", + "addReaction", + "removeReaction", + "nukeReactions", + "fetchPins", + "sendMessage", + "editMessage", + "createWebhook", + ]; - for (const method of methods) { - if (ignore.includes(method)) continue; + for (const method of methods) { + if (ignore.includes(method)) continue; - klass.prototype[method] = TextChannel.prototype[method]; - } + klass.prototype[method] = TextChannel.prototype[method]; + } } async fetchPins(): Promise { diff --git a/structures/guilds/Guild.ts b/structures/guilds/Guild.ts index 2254e0a..bae102c 100644 --- a/structures/guilds/Guild.ts +++ b/structures/guilds/Guild.ts @@ -6,14 +6,14 @@ import type { DiscordEmoji, DiscordGuild, DiscordInviteMetadata, - DiscordMemberWithUser, - DiscordRole, DiscordListActiveThreads, - GuildFeatures, - SystemChannelFlags, - MakeRequired, - VideoQualityModes, + DiscordMemberWithUser, DiscordOverwrite, + DiscordRole, + GuildFeatures, + MakeRequired, + SystemChannelFlags, + VideoQualityModes, } from "../../vendor/external.ts"; import type { GetInvite } from "../../util/Routes.ts"; import { @@ -136,7 +136,7 @@ export interface GuildCreateOptionsChannel { /** * @link https://discord.com/developers/docs/resources/guild#create-guild - * */ + */ export interface GuildCreateOptions { name: string; afkChannelId?: Snowflake; @@ -167,7 +167,7 @@ export interface GuildCreateOptions { /** * @link https://discord.com/developers/docs/resources/guild#modify-guild-json-params - * */ + */ export interface GuildEditOptions extends Omit { ownerId?: Snowflake; splashURL?: string; @@ -473,10 +473,10 @@ export class Guild extends BaseGuild implements Model { const { threads, members } = await this.session.rest.runMethod( this.session.rest, "GET", - Routes.THREAD_ACTIVE(this.id) + Routes.THREAD_ACTIVE(this.id), ); - return { + return { threads: Object.fromEntries( threads.map((thread) => [thread.id, new ThreadChannel(this.session, thread, this.id)]), ) as Record, @@ -488,13 +488,13 @@ export class Guild extends BaseGuild implements Model { /*** * Makes the bot leave the guild - * */ + */ async leave() { } /*** * Deletes a guild - * */ + */ async delete() { await this.session.rest.runMethod( this.session.rest, @@ -507,7 +507,7 @@ export class Guild extends BaseGuild implements Model { * Creates a guild and returns its data, the bot joins the guild * This was modified from discord.js to make it compatible * precondition: Bot should be in less than 10 servers - * */ + */ static async create(session: Session, options: GuildCreateOptions) { const guild = await session.rest.runMethod(session.rest, "POST", Routes.GUILDS(), { name: options.name, @@ -540,7 +540,7 @@ export class Guild extends BaseGuild implements Model { hoist: role.hoist, position: role.position, unicode_emoji: role.unicodeEmoji, - icon: options.iconURL || urlToBase64(options.iconURL!), + icon: options.iconURL || urlToBase64(options.iconURL!), })), }); @@ -549,7 +549,7 @@ export class Guild extends BaseGuild implements Model { /** * Edits a guild and returns its data - * */ + */ async edit(session: Session, options: GuildEditOptions) { const guild = await session.rest.runMethod(session.rest, "PATCH", Routes.GUILDS(), { name: options.name, diff --git a/tests/mod.ts b/tests/mod.ts index d1f7a69..1cef8bc 100644 --- a/tests/mod.ts +++ b/tests/mod.ts @@ -7,7 +7,8 @@ if (!token) { throw new Error("Please provide a token"); } -const intents = GatewayIntents.MessageContent | GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.GuildMembers | GatewayIntents.GuildBans +const intents = GatewayIntents.MessageContent | GatewayIntents.Guilds | GatewayIntents.GuildMessages | + GatewayIntents.GuildMembers | GatewayIntents.GuildBans; const session = new Session({ token, intents }); session.on("ready", (payload) => { diff --git a/util/Routes.ts b/util/Routes.ts index 146f944..2748cbc 100644 --- a/util/Routes.ts +++ b/util/Routes.ts @@ -233,7 +233,6 @@ export function CHANNEL_WEBHOOKS(channelId: Snowflake) { return `/channels/${channelId}/webhooks`; } - export function THREAD_START_PUBLIC(channelId: Snowflake, messageId: Snowflake) { return `/channels/${channelId}/messages/${messageId}/threads`; } @@ -271,8 +270,8 @@ export function THREAD_ARCHIVED_PUBLIC(channelId: Snowflake, options?: ListArchi let url = `/channels/${channelId}/threads/archived/public?`; if (options) { - if (options.before) url += `before=${new Date(options.before).toISOString()}`; - if (options.limit) url += `&limit=${options.limit}`; + if (options.before) url += `before=${new Date(options.before).toISOString()}`; + if (options.limit) url += `&limit=${options.limit}`; } return url; @@ -293,8 +292,8 @@ export function THREAD_ARCHIVED_PRIVATE_JOINED(channelId: Snowflake, options?: L let url = `/channels/${channelId}/users/@me/threads/archived/private?`; if (options) { - if (options.before) url += `before=${new Date(options.before).toISOString()}`; - if (options.limit) url += `&limit=${options.limit}`; + if (options.before) url += `before=${new Date(options.before).toISOString()}`; + if (options.limit) url += `&limit=${options.limit}`; } return url; diff --git a/util/builders.ts b/util/builders.ts new file mode 100644 index 0000000..19c9e8c --- /dev/null +++ b/util/builders.ts @@ -0,0 +1,9 @@ +import { ButtonBuilder, InputTextBuilder, SelectMenuBuilder } from "../mod.ts"; +import { Snowflake } from "./Snowflake.ts"; + +export type AnyComponentBuilder = InputTextBuilder | SelectMenuBuilder | ButtonBuilder; +export type ComponentEmoji = { + id: Snowflake; + name: string; + animated?: boolean; +}; diff --git a/vendor/types/discord.ts b/vendor/types/discord.ts index 5123cbb..496e294 100644 --- a/vendor/types/discord.ts +++ b/vendor/types/discord.ts @@ -1171,6 +1171,8 @@ export interface DiscordSelectMenuComponent { max_values?: number; /** The choices! Maximum of 25 items. */ options: DiscordSelectOption[]; + /** Whether or not this select menu is disabled */ + disabled?: boolean; } export interface DiscordSelectOption {