From ebe3882a78e08757cb050c1be966f48017a094c4 Mon Sep 17 00:00:00 2001 From: TriForMine Date: Fri, 8 Oct 2021 17:49:28 +0200 Subject: [PATCH 01/16] Role transformer --- src/transformers/role.ts | 169 +++------------------------------------ 1 file changed, 13 insertions(+), 156 deletions(-) diff --git a/src/transformers/role.ts b/src/transformers/role.ts index 2138146ca..bfc0e367b 100644 --- a/src/transformers/role.ts +++ b/src/transformers/role.ts @@ -1,171 +1,28 @@ -// import { eventHandlers } from "../bot.ts"; -// import { cache } from "../cache.ts"; -// import { deleteRole } from "../helpers/roles/delete_role.ts"; -// import { editRole } from "../helpers/roles/edit_role.ts"; -// import { CreateGuildRole } from "../types/guilds/create_guild_role.ts"; -// import { Errors } from "../types/discordeno/errors.ts"; -// import type { Role } from "../types/permissions/role.ts"; -// import { snowflakeToBigint } from "../util/bigint.ts"; -// import { Collection } from "../util/collection.ts"; -// import { highestRole } from "../util/permissions.ts"; -// import { createNewProp } from "../util/utils.ts"; -// import { DiscordenoGuild } from "./guild.ts"; -// import { DiscordenoMember } from "./member.ts"; - import { Bot } from "../bot.ts"; import { Role } from "../types/mod.ts"; -// const ROLE_SNOWFLAKES = ["id", "botId", "integrationId", "guildId"]; - -// const roleToggles = { -// /** If this role is showed seperately in the user listing */ -// hoist: 1n, -// /** Whether this role is managed by an integration */ -// managed: 2n, -// /** Whether this role is mentionable */ -// mentionable: 4n, -// /** If this role is the nitro boost role. */ -// isNitroBoostRole: 8n, -// }; - -// const baseRole: Partial = { -// get guild() { -// return cache.guilds.get(this.guildId!); -// }, -// get hexColor() { -// return this.color!.toString(16); -// }, -// get members() { -// return cache.members.filter((m) => m.guilds.some((g) => g.roles.includes(this.id!))); -// }, -// get mention() { -// return `<@&${this.id}>`; -// }, - -// // METHODS -// delete() { -// return deleteRole(this.guildId!, this.id!); -// }, -// edit(options) { -// return editRole(this.guildId!, this.id!, options); -// }, -// higherThanRole(roleId: bigint, position?: number) { -// // If no position try and find one from cache -// if (!position) position = this.guild?.roles.get(roleId)?.position; -// // If still none error out. -// if (!position) { -// throw new Error( -// "role.higherThanRoleId() did not have a position provided and the role or guild was not found in cache. Please provide a position like role.higherThanRoleId(roleId, position)" -// ); -// } - -// // Rare edge case handling -// if (this.position === position) { -// return this.id! < roleId; -// } - -// return this.position! > position; -// }, -// async higherThanMember(memberId: bigint) { -// const guild = this.guild; -// if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); - -// if (guild.ownerId === memberId) return false; - -// const memberHighestRole = await highestRole(guild, memberId); -// return this.higherThanRole!(memberHighestRole.id, memberHighestRole.position); -// }, -// get hoist() { -// return Boolean(this.bitfield! & roleToggles.hoist); -// }, -// get managed() { -// return Boolean(this.bitfield! & roleToggles.managed); -// }, -// get mentionable() { -// return Boolean(this.bitfield! & roleToggles.mentionable); -// }, -// get isNitroBoostRole() { -// return Boolean(this.bitfield! & roleToggles.isNitroBoostRole); -// }, -// toJSON() { -// return { -// guildId: this.guildId?.toString(), -// id: this.id?.toString(), -// name: this.name, -// color: this.color, -// hoist: this.hoist, -// position: this.position, -// permissions: this.permissions?.toString(), -// managed: this.managed, -// mentionable: this.mentionable, -// tags: { -// botId: this.botId?.toString(), -// integrationId: this.integrationId?.toString(), -// premiumSubscriber: this.isNitroBoostRole, -// }, -// } as Role & { guildId: string }; -// }, -// }; - -// // deno-lint-ignore require-await -// export async function createDiscordenoRole( -// data: { role: Role } & { -// guildId: bigint; -// } -// ) { -// const { tags = {}, ...rest } = { guildId: data.guildId, ...data.role }; - -// let bitfield = 0n; - -// const props: Record> = {}; -// for (const key of Object.keys(rest) as (keyof typeof rest)[]) { -// eventHandlers.debug?.("loop", `Running for of loop in createDiscordenoRole function.`); - -// const toggleBits = roleToggles[key as keyof typeof roleToggles]; -// if (toggleBits) { -// bitfield |= rest[key] ? toggleBits : 0n; -// continue; -// } - -// props[key] = createNewProp( -// ROLE_SNOWFLAKES.includes(key) ? (rest[key] ? snowflakeToBigint(rest[key] as string) : undefined) : rest[key] -// ); -// } - -// if (!cache.requiredStructureProperties.roles.size || cache.requiredStructureProperties.roles.has("permissions")) -// props.permissions = createNewProp(BigInt(rest.permissions)); - -// if (!cache.requiredStructureProperties.roles.size || cache.requiredStructureProperties.roles.has("botId")) -// props.botId = createNewProp(tags.botId ? snowflakeToBigint(tags.botId) : undefined); - -// if (!cache.requiredStructureProperties.roles.size || cache.requiredStructureProperties.roles.has("isNitroBoostRole")) -// props.isNitroBoostRole = createNewProp("premiumSubscriber" in tags); - -// if (!cache.requiredStructureProperties.roles.size || cache.requiredStructureProperties.roles.has("integrationId")) -// props.integrationId = createNewProp(tags.integrationId ? snowflakeToBigint(tags.integrationId) : undefined); - -// if (!cache.requiredStructureProperties.roles.size || cache.requiredStructureProperties.roles.has("bitfield")) -// props.bitfield = createNewProp(bitfield); - -// return Object.create(baseRole, props) as DiscordenoRole; -// } - export function transformRole( - bot: Bot, - payload: { role: Role } & { - guildId: bigint; - } + bot: Bot, + payload: { role: Role } & { + guildId: bigint; + } ) { return { // TODO: decide if its better to spread like this or do manually - ...payload, + // ...payload, // UNTRANSFORMED STUFF HERE // TODO: decide if we should use spread above or do manually - // name: payload.role.name, + name: payload.role.name, + guildId: payload.guildId, + position: payload.role.position, + color: payload.role.color, // TRANSFORMED STUFF BELOW id: bot.transformers.snowflake(payload.role.id), - botId: payload.role.tags?.botId ? bot.transformers.snowflake(payload.role.tags?.botId) : undefined, + botId: payload.role.tags?.botId ? bot.transformers.snowflake(payload.role.tags.botId) : undefined, + integrationId: payload.role.tags?.integrationId ? bot.transformers.snowflake(payload.role.tags.integrationId) : undefined, + permissions: payload.role.permissions ? bot.transformers.snowflake(payload.role.permissions) : undefined, + bitfield: 0n & (payload.role?.hoist ? 1n : 0n) & (payload.role?.managed ? 2n : 0n) & (payload.role?.mentionable ? 4n : 0n) & (payload.role.tags?.premiumSubscriber ? 8n : 0n) }; } From 39e039789d853a7c2e3bd0cff437c0abb2e7dfbe Mon Sep 17 00:00:00 2001 From: TriForMine Date: Fri, 8 Oct 2021 15:50:19 +0000 Subject: [PATCH 02/16] change: prettier code --- src/transformers/role.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/transformers/role.ts b/src/transformers/role.ts index bfc0e367b..8d8f2f2cd 100644 --- a/src/transformers/role.ts +++ b/src/transformers/role.ts @@ -2,10 +2,10 @@ import { Bot } from "../bot.ts"; import { Role } from "../types/mod.ts"; export function transformRole( - bot: Bot, - payload: { role: Role } & { - guildId: bigint; - } + bot: Bot, + payload: { role: Role } & { + guildId: bigint; + } ) { return { // TODO: decide if its better to spread like this or do manually @@ -20,9 +20,16 @@ export function transformRole( // TRANSFORMED STUFF BELOW id: bot.transformers.snowflake(payload.role.id), botId: payload.role.tags?.botId ? bot.transformers.snowflake(payload.role.tags.botId) : undefined, - integrationId: payload.role.tags?.integrationId ? bot.transformers.snowflake(payload.role.tags.integrationId) : undefined, + integrationId: payload.role.tags?.integrationId + ? bot.transformers.snowflake(payload.role.tags.integrationId) + : undefined, permissions: payload.role.permissions ? bot.transformers.snowflake(payload.role.permissions) : undefined, - bitfield: 0n & (payload.role?.hoist ? 1n : 0n) & (payload.role?.managed ? 2n : 0n) & (payload.role?.mentionable ? 4n : 0n) & (payload.role.tags?.premiumSubscriber ? 8n : 0n) + bitfield: + 0n & + (payload.role?.hoist ? 1n : 0n) & + (payload.role?.managed ? 2n : 0n) & + (payload.role?.mentionable ? 4n : 0n) & + (payload.role.tags?.premiumSubscriber ? 8n : 0n), }; } From 4339bd8e4e4a4d916b643e21ef4fee0fe6c018ec Mon Sep 17 00:00:00 2001 From: TriForMine Date: Fri, 8 Oct 2021 18:03:21 +0200 Subject: [PATCH 03/16] Fix bitfields --- src/transformers/role.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/transformers/role.ts b/src/transformers/role.ts index 8d8f2f2cd..f0e84ccc9 100644 --- a/src/transformers/role.ts +++ b/src/transformers/role.ts @@ -25,10 +25,9 @@ export function transformRole( : undefined, permissions: payload.role.permissions ? bot.transformers.snowflake(payload.role.permissions) : undefined, bitfield: - 0n & - (payload.role?.hoist ? 1n : 0n) & - (payload.role?.managed ? 2n : 0n) & - (payload.role?.mentionable ? 4n : 0n) & + (payload.role?.hoist ? 1n : 0n) | + (payload.role?.managed ? 2n : 0n) | + (payload.role?.mentionable ? 4n : 0n) | (payload.role.tags?.premiumSubscriber ? 8n : 0n), }; } From 58f1817ed500bebde7815df1d5444656a0c17d3d Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Fri, 8 Oct 2021 23:12:35 +0200 Subject: [PATCH 04/16] Message structure -> Message Transformer --- src/transformers/message.ts | 390 +++++------------------------------- src/transformers/role.ts | 13 +- 2 files changed, 54 insertions(+), 349 deletions(-) diff --git a/src/transformers/message.ts b/src/transformers/message.ts index 464a1f038..4a28d93cb 100644 --- a/src/transformers/message.ts +++ b/src/transformers/message.ts @@ -1,296 +1,58 @@ -import { eventHandlers } from "../bot.ts"; -import { cache, cacheHandlers } from "../cache.ts"; -import { sendDirectMessage } from "../helpers/members/send_direct_message.ts"; -import { addReaction } from "../helpers/messages/add_reaction.ts"; -import { addReactions } from "../helpers/messages/add_reactions.ts"; -import { deleteMessage } from "../helpers/messages/delete_message.ts"; -import { editMessage } from "../helpers/messages/edit_message.ts"; -import { pinMessage } from "../helpers/messages/pin_message.ts"; -import { removeAllReactions } from "../helpers/messages/remove_all_reactions.ts"; -import { removeReaction } from "../helpers/messages/remove_reaction.ts"; -import { removeReactionEmoji } from "../helpers/messages/remove_reaction_emoji.ts"; -import { sendMessage } from "../helpers/messages/send_message.ts"; -import type { GuildMember } from "../types/members/guild_member.ts"; -import type { CreateMessage } from "../types/messages/create_message.ts"; -import type { EditMessage } from "../types/messages/edit_message.ts"; -import type { Message } from "../types/messages/message.ts"; -import { bigintToSnowflake, snowflakeToBigint } from "../util/bigint.ts"; +import { Bot } from "../bot.ts"; +import { Message } from "../types/messages/message.ts"; import { CHANNEL_MENTION_REGEX } from "../util/constants.ts"; -import { iconBigintToHash } from "../util/hash.ts"; -import { channelToThread, DiscordenoThread } from "../util/transformers/channel_to_thread.ts"; -import { createNewProp } from "../util/utils.ts"; -import { DiscordenoChannel } from "./channel.ts"; -import { DiscordenoGuild } from "./guild.ts"; -import { DiscordenoMember } from "./member.ts"; -import { DiscordenoRole } from "./role.ts"; -const MESSAGE_SNOWFLAKES = ["id", "channelId", "guildId", "webhookId", "applicationId"]; +export function transformMessage( + bot: Bot, + data: Message + ) { + return { + // UNTRANSFORMED STUFF HERE + content: data.content || "", + isBot: data.author.bot || false, + tag: `${data.author.username}#${data.author.discriminator.toString().padStart(4, "0")}`, + timestamp: Date.parse(data.timestamp), + editedTimestamp: data.editedTimestamp ? Date.parse(data.editedTimestamp) : undefined, + bitfield: + (data.tts ? 1n : 0n) | + (data.mentionEveryone ? 2n : 0n) | + (data.pinned ? 4n : 0n), + attachments: data.attachments, + embeds: data.embeds, + reactions: data.reactions, + type: data.type, + activity: data.activity, + application: data.application, + flags: data.flags, + interaction: data.interaction, + thread: data.thread, + components: data.components, + stickerItems: data.stickerItems, -const messageToggles = { - /** Whether this was a TTS message */ - tts: 1n, - /** Whether this message mentions everyone */ - mentionEveryone: 2n, - /** Whether this message is pinned */ - pinned: 4n, -}; - -const baseMessage: Partial = { - get channel() { - if (this.guildId) return cache.channels.get(this.channelId!); - return cache.channels.get(this.authorId!); - }, - get guild() { - if (!this.guildId) return undefined; - return cache.guilds.get(this.guildId); - }, - get member() { - if (!this.authorId) return undefined; - return cache.members.get(this.authorId); - }, - get guildMember() { - if (!this.guildId) return undefined; - return this.member?.guilds.get(this.guildId); - }, - get link() { - return `https://discord.com/channels/${this.guildId || "@me"}/${this.channelId}/${this.id}`; - }, - get mentionedRoles() { - return this.mentionedRoleIds?.map((id) => this.guild?.roles.get(id)) || []; - }, - get mentionedChannels() { - return this.mentionedChannelIds?.map((id) => cache.channels.get(id)) || []; - }, - get mentionedMembers() { - return this.mentionedUserIds?.map((id) => cache.members.get(id)) || []; - }, - - // METHODS - delete(reason, delayMilliseconds) { - return deleteMessage(this.channelId!, this.id!, reason, delayMilliseconds); - }, - edit(content) { - return editMessage(this.channelId!, this.id!, content); - }, - pin() { - return pinMessage(this.channelId!, this.id!); - }, - addReaction(reaction) { - return addReaction(this.channelId!, this.id!, reaction); - }, - addReactions(reactions, ordered) { - return addReactions(this.channelId!, this.id!, reactions, ordered); - }, - reply(content, mentionUser = true) { - const contentWithMention: CreateMessage = - typeof content === "string" - ? { - content, - allowedMentions: { - repliedUser: mentionUser, - }, - messageReference: { - messageId: bigintToSnowflake(this.id!), - failIfNotExists: false, - }, - } - : { - ...content, - allowedMentions: { - repliedUser: mentionUser, - ...(content.allowedMentions || {}), - }, - messageReference: { - messageId: bigintToSnowflake(this.id!), - failIfNotExists: content.messageReference?.failIfNotExists === true, - }, - }; - - if (this.guildId) return sendMessage(this.channelId!, contentWithMention); - return sendDirectMessage(this.authorId!, contentWithMention); - }, - send(content) { - if (this.guildId) return sendMessage(this.channelId!, content); - return sendDirectMessage(this.authorId!, content); - }, - async alert(content, timeout = 10, reason = "") { - if (this.guildId) { - return await sendMessage(this.channelId!, content).then((response) => { - response?.delete(reason, timeout * 1000).catch(console.error); - }); - } - - return await sendDirectMessage(this.authorId!, content).then((response) => { - response?.delete(reason, timeout * 1000).catch(console.error); - }); - }, - async alertReply(content, timeout = 10, reason = "") { - return await this.reply!(content).then((response) => response?.delete(reason, timeout * 1000).catch(console.error)); - }, - removeAllReactions() { - return removeAllReactions(this.channelId!, this.id!); - }, - removeReactionEmoji(reaction) { - return removeReactionEmoji(this.channelId!, this.id!, reaction); - }, - removeReaction(reaction, userId) { - return removeReaction(this.channelId!, this.id!, reaction, { userId }); - }, - get tts() { - return Boolean(this.bitfield! & messageToggles.tts); - }, - get mentionEveryone() { - return Boolean(this.bitfield! & messageToggles.mentionEveryone); - }, - get pinned() { - return Boolean(this.bitfield! & messageToggles.pinned); - }, - get thread() { - return cache.threads.get(this.id!); - }, - toJSON() { - return { - id: this.id?.toString(), - channelId: this.channelId?.toString(), - guildId: this.guildId?.toString(), - author: { - id: this.authorId?.toString(), - username: this.tag?.substring(0, this.tag.length - 5), - discriminator: this.tag?.substring(this.tag.length - 4), - avatar: this.member?.avatar ? iconBigintToHash(this.member.avatar) : undefined, - bot: this.member?.bot, - system: this.member?.system, - mfaEnabled: this.member?.mfaEnabled, - locale: this.member?.locale, - verified: this.member?.verified, - email: this.member?.email, - flags: this.member?.flags, - premiumType: this.member?.premiumType, - publicFlags: this.member?.publicFlags, - }, - member: this.member, - content: this.content, - timestamp: this.timestamp ? new Date(this.timestamp).toISOString() : undefined, - editedTimestamp: this.editedTimestamp ? new Date(this.editedTimestamp).toISOString() : undefined, - tts: this.tts, - mentionEveryone: this.mentionEveryone, - mentions: this.mentions, - mentionRoles: this.mentionRoles, - mentionChannels: this.mentionChannels, - attachments: this.attachments, - embeds: this.embeds, - reactions: this.reactions, - nonce: this.nonce, - pinned: this.pinned, - webhookId: this.webhookId, - type: this.type, - activity: this.activity, - application: this.application, - applicationId: this.applicationId, - messageReference: this.messageReference, - flags: this.flags, - stickers: this.stickers, - referencedMessage: this.referencedMessage, - interaction: this.interaction, - thread: this.thread, - components: this.components, - } as Message; - }, -}; - -export async function createDiscordenoMessage(data: Message) { - const { - guildId = "", - mentionChannels = [], - mentions = [], - mentionRoles = [], - editedTimestamp, - author, - messageReference, - ...rest - } = data; - - let bitfield = 0n; - - const props: Record> = {}; - - const requiredPropsSize = cache.requiredStructureProperties.messages.size; - - for (const key of Object.keys(rest) as (keyof typeof rest)[]) { - eventHandlers.debug?.("loop", `Running for of loop in createDiscordenoMessage function.`); - - // If empty all are allowed, otherwise check if this prop is allowed - if (requiredPropsSize && !cache.requiredStructureProperties.messages.has(key)) continue; - - const toggleBits = messageToggles[key as keyof typeof messageToggles]; - if (toggleBits) { - bitfield |= rest[key] ? toggleBits : 0n; - continue; - } - - // Don't add member to props since it would overwrite the message.member getter - // thread should not be cached on a message - if (["member", "thread"].includes(key)) continue; - - props[key] = createNewProp( - MESSAGE_SNOWFLAKES.includes(key) ? (rest[key] ? snowflakeToBigint(rest[key] as string) : undefined) : rest[key] - ); - } - - if (rest.thread) await cacheHandlers.set("threads", snowflakeToBigint(data.id), channelToThread(rest.thread)); - - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("authorId")) - props.authorId = createNewProp(snowflakeToBigint(author.id)); - - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("isBot")) - props.isBot = createNewProp(author.bot || false); - - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("tag")) - props.tag = createNewProp(`${author.username}#${author.discriminator.toString().padStart(4, "0")}`); - - // Discord doesnt give guild id for getMessage() so this will fill it in - const guildIdFinal = - snowflakeToBigint(guildId) || - (await cacheHandlers.get("channels", snowflakeToBigint(data.channelId)))?.guildId || - 0n; - - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("content")) - props.content = createNewProp(data.content || ""); - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("guildId")) - props.guildId = createNewProp(guildIdFinal); - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("mentionedUserIds")) - props.mentionedUserIds = createNewProp(mentions.map((m) => snowflakeToBigint(m.id))); - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("mentionedRoleIds")) - props.mentionedRoleIds = createNewProp(mentionRoles.map((id) => snowflakeToBigint(id))); - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("mentionedChannelIds")) - props.mentionedChannelIds = createNewProp([ - // Keep any ids that discord sends - ...mentionChannels.map((m) => snowflakeToBigint(m.id)), + // TRANSFORMED STUFF BELOW + id: bot.transformers.snowflake(data.id), + guildId: data.guildId ? bot.transformers.snowflake(data.guildId) : undefined, + channelId: bot.transformers.snowflake(data.channelId), + webhookId: data.webhookId ? bot.transformers.snowflake(data.webhookId) : undefined, + authorId: bot.transformers.snowflake(data.author.id), + applicationId: data.applicationId ? bot.transformers.snowflake(data.applicationId) : undefined, + messageReference: data.messageReference ? { + messageId: data.messageReference.messageId ? bot.transformers.snowflake(data.messageReference.messageId) : undefined, + channelId: data.messageReference.channelId ? bot.transformers.snowflake(data.messageReference.channelId) : undefined, + guildId: data.messageReference.guildId ? bot.transformers.snowflake(data.messageReference.guildId) : undefined, + } : undefined, + mentionedUserIds: data.mentions.map((m) => bot.transformers.snowflake(m.id)), + mentionedRoleIds: data.mentionRoles.map((id) => bot.transformers.snowflake(id)), + mentionedChannelIds: [ + // Keep any ids tht discord sends + ...data.mentionChannels.map((m) => bot.transformers.snowflake(m.id)), // Add any other ids that can be validated in a channel mention format - ...(rest.content?.match(CHANNEL_MENTION_REGEX) || []).map((text) => + ...(data.content?.match(CHANNEL_MENTION_REGEX) || []).map((text) => // converts the <#123> into 123 - snowflakeToBigint(text.substring(2, text.length - 1)) + bot.transformers.snowflake(text.substring(2, text.length - 1)) ), - ]); - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("timestamp")) - props.timestamp = createNewProp(Date.parse(data.timestamp)); - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("editedTimestamp")) - props.editedTimestamp = createNewProp(editedTimestamp ? Date.parse(editedTimestamp) : undefined); - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("messageReference")) - props.messageReference = createNewProp( - messageReference - ? { - messageId: messageReference.messageId ? snowflakeToBigint(messageReference.messageId) : undefined, - channelId: messageReference.channelId ? snowflakeToBigint(messageReference.channelId) : undefined, - guildId: messageReference.guildId ? snowflakeToBigint(messageReference.guildId) : undefined, - } - : undefined - ); - - if (!requiredPropsSize || cache.requiredStructureProperties.messages.has("bitfield")) - props.bitfield = createNewProp(bitfield); - - return Object.create(baseMessage, props) as DiscordenoMessage; + ] + } } export interface DiscordenoMessage @@ -339,58 +101,4 @@ export interface DiscordenoMessage timestamp: number; /** When this message was edited (or undefined if never) */ editedTimestamp?: number; - - // GETTERS - - /** The channel where this message was sent. Can be undefined if uncached. */ - channel?: DiscordenoChannel; - /** The guild of this message. Can be undefined if not in cache or in DM */ - guild?: DiscordenoGuild; - /** The member for the user who sent the message. Can be undefined if not in cache or in dm. */ - member?: DiscordenoMember; - /** The guild member details for this guild and member. Can be undefined if not in cache or in dm. */ - guildMember?: Omit & { - joinedAt?: number; - premiumSince?: number; - roles: bigint[]; - }; - /** The url link to this message */ - link: string; - /** The role objects for all the roles that were mentioned in this message */ - mentionedRoles: (DiscordenoRole | undefined)[]; - /** The channel objects for all the channels that were mentioned in this message. */ - mentionedChannels: (DiscordenoChannel | undefined)[]; - /** The member objects for all the members that were mentioned in this message. */ - mentionedMembers: (DiscordenoMember | undefined)[]; - /** The thread if this message has a thread. */ - thread?: DiscordenoThread; - - // METHODS - - /** Delete the message */ - delete(reason?: string, delayMilliseconds?: number): ReturnType; - /** Edit the message */ - edit(content: string | EditMessage): ReturnType; - /** Pins the message in the channel */ - pin(): ReturnType; - /** Add a reaction to the message */ - addReaction(reaction: string): ReturnType; - /** Add multiple reactions to the message without or without order. */ - addReactions(reactions: string[], ordered?: boolean): ReturnType; - /** Send a inline reply to this message */ - reply(content: string | CreateMessage, mentionUser?: boolean): ReturnType; - /** Send a message to this channel where this message is */ - send(content: string | CreateMessage): ReturnType; - /** Send a message to this channel and then delete it after a bit. By default it will delete after 10 seconds with no reason provided. */ - alert(content: string | CreateMessage, timeout?: number, reason?: string): Promise; - /** Send a inline reply to this message but then delete it after a bit. By default it will delete after 10 seconds with no reason provided. */ - alertReply(content: string | CreateMessage, timeout?: number, reason?: string): Promise; - /** Removes all reactions for all emojis on this message */ - removeAllReactions(): ReturnType; - /** Removes all reactions for a single emoji on this message */ - removeReactionEmoji(reaction: string): ReturnType; - /** Removes a reaction from the given user on this message, defaults to bot */ - removeReaction(reaction: string, userId?: bigint): ReturnType; - /** Convert to json */ - toJSON(): Message; } diff --git a/src/transformers/role.ts b/src/transformers/role.ts index f0e84ccc9..b2fa82a82 100644 --- a/src/transformers/role.ts +++ b/src/transformers/role.ts @@ -8,14 +8,16 @@ export function transformRole( } ) { return { - // TODO: decide if its better to spread like this or do manually - // ...payload, // UNTRANSFORMED STUFF HERE - // TODO: decide if we should use spread above or do manually name: payload.role.name, guildId: payload.guildId, position: payload.role.position, color: payload.role.color, + bitfield: + (payload.role.hoist ? 1n : 0n) | + (payload.role.managed ? 2n : 0n) | + (payload.role.mentionable ? 4n : 0n) | + (payload.role.tags?.premiumSubscriber ? 8n : 0n), // TRANSFORMED STUFF BELOW id: bot.transformers.snowflake(payload.role.id), @@ -24,11 +26,6 @@ export function transformRole( ? bot.transformers.snowflake(payload.role.tags.integrationId) : undefined, permissions: payload.role.permissions ? bot.transformers.snowflake(payload.role.permissions) : undefined, - bitfield: - (payload.role?.hoist ? 1n : 0n) | - (payload.role?.managed ? 2n : 0n) | - (payload.role?.mentionable ? 4n : 0n) | - (payload.role.tags?.premiumSubscriber ? 8n : 0n), }; } From b9bae8da8955de4c8372f78c09c1b5ae3141f3e8 Mon Sep 17 00:00:00 2001 From: TriForMine Date: Fri, 8 Oct 2021 21:13:18 +0000 Subject: [PATCH 05/16] change: prettier code --- src/transformers/message.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/transformers/message.ts b/src/transformers/message.ts index 4a28d93cb..b953e2462 100644 --- a/src/transformers/message.ts +++ b/src/transformers/message.ts @@ -2,10 +2,7 @@ import { Bot } from "../bot.ts"; import { Message } from "../types/messages/message.ts"; import { CHANNEL_MENTION_REGEX } from "../util/constants.ts"; -export function transformMessage( - bot: Bot, - data: Message - ) { +export function transformMessage(bot: Bot, data: Message) { return { // UNTRANSFORMED STUFF HERE content: data.content || "", @@ -13,10 +10,7 @@ export function transformMessage( tag: `${data.author.username}#${data.author.discriminator.toString().padStart(4, "0")}`, timestamp: Date.parse(data.timestamp), editedTimestamp: data.editedTimestamp ? Date.parse(data.editedTimestamp) : undefined, - bitfield: - (data.tts ? 1n : 0n) | - (data.mentionEveryone ? 2n : 0n) | - (data.pinned ? 4n : 0n), + bitfield: (data.tts ? 1n : 0n) | (data.mentionEveryone ? 2n : 0n) | (data.pinned ? 4n : 0n), attachments: data.attachments, embeds: data.embeds, reactions: data.reactions, @@ -36,11 +30,19 @@ export function transformMessage( webhookId: data.webhookId ? bot.transformers.snowflake(data.webhookId) : undefined, authorId: bot.transformers.snowflake(data.author.id), applicationId: data.applicationId ? bot.transformers.snowflake(data.applicationId) : undefined, - messageReference: data.messageReference ? { - messageId: data.messageReference.messageId ? bot.transformers.snowflake(data.messageReference.messageId) : undefined, - channelId: data.messageReference.channelId ? bot.transformers.snowflake(data.messageReference.channelId) : undefined, - guildId: data.messageReference.guildId ? bot.transformers.snowflake(data.messageReference.guildId) : undefined, - } : undefined, + messageReference: data.messageReference + ? { + messageId: data.messageReference.messageId + ? bot.transformers.snowflake(data.messageReference.messageId) + : undefined, + channelId: data.messageReference.channelId + ? bot.transformers.snowflake(data.messageReference.channelId) + : undefined, + guildId: data.messageReference.guildId + ? bot.transformers.snowflake(data.messageReference.guildId) + : undefined, + } + : undefined, mentionedUserIds: data.mentions.map((m) => bot.transformers.snowflake(m.id)), mentionedRoleIds: data.mentionRoles.map((id) => bot.transformers.snowflake(id)), mentionedChannelIds: [ @@ -51,8 +53,8 @@ export function transformMessage( // converts the <#123> into 123 bot.transformers.snowflake(text.substring(2, text.length - 1)) ), - ] - } + ], + }; } export interface DiscordenoMessage From c9e8ed21b839f795aede71ea0b53b74557183881 Mon Sep 17 00:00:00 2001 From: TriForMine Date: Sat, 9 Oct 2021 14:42:42 +0000 Subject: [PATCH 06/16] change: prettier code --- src/util/hash.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/hash.ts b/src/util/hash.ts index 281371e3e..449958d8a 100644 --- a/src/util/hash.ts +++ b/src/util/hash.ts @@ -16,4 +16,4 @@ export function iconBigintToHash(icon: bigint) { const hash = icon.toString(16); // Hashes starting with a are animated and with b are not so need to handle that return hash.startsWith("a") ? `a_${hash.substring(1)}` : hash.substring(1); -} \ No newline at end of file +} From af94acfed670f6e41d457c8d671cb6f4bb9c4a54 Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Sat, 9 Oct 2021 18:06:47 +0200 Subject: [PATCH 07/16] Channel structure + fixes --- src/transformers/channel.ts | 231 ++++++------------------------------ src/transformers/message.ts | 37 +++--- src/transformers/role.ts | 17 +-- 3 files changed, 61 insertions(+), 224 deletions(-) diff --git a/src/transformers/channel.ts b/src/transformers/channel.ts index fb84fc755..abe3d18f1 100644 --- a/src/transformers/channel.ts +++ b/src/transformers/channel.ts @@ -1,144 +1,39 @@ -import { eventHandlers } from "../bot.ts"; -import { cache } from "../cache.ts"; -import { channelOverwriteHasPermission } from "../helpers/channels/channel_overwrite_has_permission.ts"; -import { cloneChannel } from "../helpers/channels/clone_channel.ts"; -import { deleteChannel } from "../helpers/channels/delete_channel.ts"; -import { deleteChannelOverwrite } from "../helpers/channels/delete_channel_overwrite.ts"; -import { editChannel } from "../helpers/channels/edit_channel.ts"; -import { editChannelOverwrite } from "../helpers/channels/edit_channel_overwrite.ts"; -import { sendMessage } from "../helpers/messages/send_message.ts"; -import { disconnectMember } from "../helpers/mod.ts"; -import type { Channel } from "../types/channels/channel.ts"; -import { DiscordChannelTypes } from "../types/channels/channel_types.ts"; -import type { ModifyChannel } from "../types/channels/modify_channel.ts"; -import type { DiscordOverwrite, Overwrite } from "../types/channels/overwrite.ts"; -import type { CreateMessage } from "../types/messages/create_message.ts"; -import type { PermissionStrings } from "../types/permissions/permission_strings.ts"; -import { snowflakeToBigint } from "../util/bigint.ts"; -import { Collection } from "../util/collection.ts"; -import { createNewProp } from "../util/utils.ts"; -import { DiscordenoGuild } from "./guild.ts"; -import { DiscordenoMember } from "./member.ts"; -import { DiscordenoMessage } from "./message.ts"; -import { DiscordenoVoiceState } from "./voice_state.ts"; +import { Channel } from "../types/channels/channel.ts"; +import { Bot } from "../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; +import { DiscordOverwrite } from "../types/channels/overwrite.ts"; -const CHANNEL_SNOWFLAKES = ["id", "guildId", "lastMessageId", "ownerId", "applicationId", "parentId"]; +export function transformChannel(bot: Bot, payload: { channel: SnakeCasedPropertiesDeep } & { guildId?: bigint }) { + return { + // UNTRANSFORMED STUFF HERE + type: payload.channel.type, + position: payload.channel.position, + name: payload.channel.name, + topic: payload.channel.topic, + nsfw: payload.channel.nsfw, + bitrate: payload.channel.bitrate, + userLimit: payload.channel.user_limit, + rateLimitPerUser: payload.channel.rate_limit_per_user, + recipients: payload.channel.recipients, + icon: payload.channel.icon, + rtcRegion: payload.channel.rtc_region, + videoQualityMode: payload.channel.video_quality_mode, + guildId: payload.guildId || (payload.channel.guild_id ? bot.transformers.snowflake(payload.channel.guild_id) : 0n), + lastPinTimestamp: payload.channel.last_pin_timestamp, + permissionOverwrites: payload.channel.permission_overwrites ? payload.channel.permission_overwrites.map((o) => ({ + type: o.type, + id: bot.transformers.snowflake(o.id), + allow: bot.transformers.snowflake(o.allow), + deny: bot.transformers.snowflake(o.deny), + })) : [], -const baseChannel: Partial = { - toJSON() { - return { - id: this.id?.toString(), - type: this.type, - guildId: this.guildId?.toString(), - position: this.position, - permissionOverwrites: this.permissionOverwrites?.map((o) => ({ - ...o, - id: o.id.toString(), - allow: o.allow.toString(), - deny: o.deny.toString(), - })), - name: this.name, - topic: this.topic, - nsfw: this.nsfw, - lastMessageId: this.lastMessageId?.toString(), - bitrate: this.bitrate, - userLimit: this.userLimit, - rateLimitPerUser: this.rateLimitPerUser, - recipients: this.recipients, - icon: this.icon, - ownerId: this.ownerId, - applicationId: this.applicationId, - parentId: this.parentId, - lastPinTimestamp: this.lastPinTimestamp ? new Date(this.lastPinTimestamp).toISOString() : undefined, - rtcRegion: this.rtcRegion, - videoQualityMode: this.videoQualityMode, - } as Channel; - }, - get guild() { - return cache.guilds.get(this.guildId!); - }, - get messages() { - return cache.messages.filter((m) => m.channelId === this.id!); - }, - get mention() { - return `<#${this.id!}>`; - }, - get voiceStates() { - return this.guild?.voiceStates.filter((voiceState) => voiceState.channelId === this.id!); - }, - get connectedMembers() { - const voiceStates = this.voiceStates; - if (!voiceStates) return undefined; - - return new Collection(voiceStates.map((vs) => [vs.userId, cache.members.get(vs.userId)])); - }, - get isNewsChannel() { - return this.type === DiscordChannelTypes.GuildNews; - }, - get isGuildTextBasedChannel() { - return [DiscordChannelTypes.GuildNews, DiscordChannelTypes.GuildText].includes(this.type!); - }, - send(content) { - return sendMessage(this.id!, content); - }, - disconnect(memberId) { - return disconnectMember(this.guildId!, memberId); - }, - delete(reason) { - return deleteChannel(this.id!, reason); - }, - editOverwrite(id, options) { - return editChannelOverwrite(this.guildId!, this.id!, id, options); - }, - deleteOverwrite(id) { - return deleteChannelOverwrite(this.guildId!, this.id!, id); - }, - hasPermission(overwrites, permissions) { - return channelOverwriteHasPermission(this.guildId!, this.id!, overwrites, permissions); - }, - edit(options, reason) { - return editChannel(this.id!, options, reason); - }, - clone(reason) { - return cloneChannel(this.id!, reason); - }, -}; - -/** Create a structure object */ -// deno-lint-ignore require-await -export async function createDiscordenoChannel(data: Channel, guildId?: bigint) { - const { lastPinTimestamp, permissionOverwrites = [], ...rest } = data; - - const requiredPropsSize = cache.requiredStructureProperties.channels.size; - - const props: Record = {}; - for (const key of Object.keys(rest) as (keyof typeof rest)[]) { - eventHandlers.debug?.("loop", `Running forEach loop in createDiscordenoChannel function.`); - // If empty then support all, otherwise we only allow the ones user added - if (requiredPropsSize && !cache.requiredStructureProperties.channels.has(key)) continue; - - props[key] = createNewProp( - CHANNEL_SNOWFLAKES.includes(key) ? (rest[key] ? snowflakeToBigint(rest[key] as string) : undefined) : rest[key] - ); + // TRANSFORMED STUFF BELOW + id: bot.transformers.snowflake(payload.channel.id), + lastMessageId: payload.channel.last_message_id ? bot.transformers.snowflake(payload.channel.last_message_id) : undefined, + ownerId: payload.channel.owner_id ? bot.transformers.snowflake(payload.channel.owner_id) : undefined, + applicationId: payload.channel.application_id ? bot.transformers.snowflake(payload.channel.application_id) : undefined, + parentId: payload.channel.parent_id ? bot.transformers.snowflake(payload.channel.parent_id) : undefined, } - - // Set the guildId seperately because sometimes guildId is not included - if (!requiredPropsSize || cache.requiredStructureProperties.channels.has("guildId")) - props.guildId = createNewProp(snowflakeToBigint(guildId?.toString() || data.guildId || "")); - - if (!requiredPropsSize || cache.requiredStructureProperties.channels.has("lastPinTimestamp")) - props.lastPinTimestamp = createNewProp(lastPinTimestamp ? Date.parse(lastPinTimestamp) : undefined); - if (!requiredPropsSize || cache.requiredStructureProperties.channels.has("permissionOverwrites")) - props.permissionOverwrites = createNewProp( - permissionOverwrites.map((o) => ({ - ...o, - id: snowflakeToBigint(o.id), - allow: snowflakeToBigint(o.allow), - deny: snowflakeToBigint(o.deny), - })) - ); - - return Object.create(baseChannel, props) as DiscordenoChannel; } export interface DiscordenoChannel @@ -173,64 +68,4 @@ export interface DiscordenoChannel applicationId?: bigint; /** Id of the parent category for a channel (each parent category can contain up to 50 channels) */ parentId?: bigint; - // GETTERS - - /** - * Gets the guild object for this channel. - * - * ⚠️ ADVANCED: If you use the custom cache, these will not work for you. Getters can not be async and custom cache requires async. - */ - guild?: DiscordenoGuild; - /** - * Gets the messages from cache that were sent in this channel - * - * ⚠️ ADVANCED: If you use the custom cache, these will not work for you. Getters can not be async and custom cache requires async. - */ - messages: Collection; - /** The mention of the channel */ - mention: string; - /** - * Gets the voice states for this channel - * - * ⚠️ ADVANCED: If you use the custom cache, these will not work for you. Getters can not be async and custom cache requires async. - */ - voiceStates?: Collection; - /** - * Gets the connected members for this channel undefined if member is not cached - * - * ⚠️ ADVANCED: If you use the custom cache, these will not work for you. Getters can not be async and custom cache requires async. - */ - connectedMembers?: Collection; - /** Whether the channel is a news channel. */ - isNewsChannel: boolean; - /** Whether the channel is a news or text channel in a guild. */ - isGuildTextBasedChannel: boolean; - - // METHODS - - /** Send a message to the channel. Requires SEND_MESSAGES permission. */ - send(content: string | CreateMessage): ReturnType; - /** Disconnect a member from a voice channel. Requires MOVE_MEMBERS permission. */ - disconnect(memberId: bigint): ReturnType; - /** Delete the channel */ - delete(reason?: string): ReturnType; - /** Edit a channel Overwrite */ - editOverwrite(overwriteId: bigint, options: Omit): ReturnType; - /** Delete a channel Overwrite */ - deleteOverwrite(overwriteId: bigint): ReturnType; - /** Checks if a channel overwrite for a user id or a role id has permission in this channel */ - hasPermission( - overwrites: (Omit & { - id: bigint; - allow: bigint; - deny: bigint; - })[], - permissions: PermissionStrings[] - ): ReturnType; - /** Edit the channel */ - edit(options: ModifyChannel, reason?: string): ReturnType; - /** Create a new channel with the same properties */ - clone(reason?: string): ReturnType; - /** Returns the Channel object json value */ - toJSON(): Channel; } diff --git a/src/transformers/message.ts b/src/transformers/message.ts index b953e2462..e441ab264 100644 --- a/src/transformers/message.ts +++ b/src/transformers/message.ts @@ -1,16 +1,17 @@ import { Bot } from "../bot.ts"; import { Message } from "../types/messages/message.ts"; import { CHANNEL_MENTION_REGEX } from "../util/constants.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -export function transformMessage(bot: Bot, data: Message) { +export function transformMessage(bot: Bot, data: SnakeCasedPropertiesDeep) { return { // UNTRANSFORMED STUFF HERE content: data.content || "", isBot: data.author.bot || false, tag: `${data.author.username}#${data.author.discriminator.toString().padStart(4, "0")}`, timestamp: Date.parse(data.timestamp), - editedTimestamp: data.editedTimestamp ? Date.parse(data.editedTimestamp) : undefined, - bitfield: (data.tts ? 1n : 0n) | (data.mentionEveryone ? 2n : 0n) | (data.pinned ? 4n : 0n), + editedTimestamp: data.edited_timestamp ? Date.parse(data.edited_timestamp) : undefined, + bitfield: (data.tts ? 1n : 0n) | (data.mention_everyone ? 2n : 0n) | (data.pinned ? 4n : 0n), attachments: data.attachments, embeds: data.embeds, reactions: data.reactions, @@ -21,33 +22,33 @@ export function transformMessage(bot: Bot, data: Message) { interaction: data.interaction, thread: data.thread, components: data.components, - stickerItems: data.stickerItems, + stickerItems: data.sticker_items, // TRANSFORMED STUFF BELOW id: bot.transformers.snowflake(data.id), - guildId: data.guildId ? bot.transformers.snowflake(data.guildId) : undefined, - channelId: bot.transformers.snowflake(data.channelId), - webhookId: data.webhookId ? bot.transformers.snowflake(data.webhookId) : undefined, + guildId: data.guild_id ? bot.transformers.snowflake(data.guild_id) : undefined, + channelId: bot.transformers.snowflake(data.channel_id), + webhookId: data.webhook_id ? bot.transformers.snowflake(data.webhook_id) : undefined, authorId: bot.transformers.snowflake(data.author.id), - applicationId: data.applicationId ? bot.transformers.snowflake(data.applicationId) : undefined, - messageReference: data.messageReference + applicationId: data.application_id ? bot.transformers.snowflake(data.application_id) : undefined, + messageReference: data.message_reference ? { - messageId: data.messageReference.messageId - ? bot.transformers.snowflake(data.messageReference.messageId) + messageId: data.message_reference.message_id + ? bot.transformers.snowflake(data.message_reference.message_id) : undefined, - channelId: data.messageReference.channelId - ? bot.transformers.snowflake(data.messageReference.channelId) + channelId: data.message_reference.channel_id + ? bot.transformers.snowflake(data.message_reference.channel_id) : undefined, - guildId: data.messageReference.guildId - ? bot.transformers.snowflake(data.messageReference.guildId) + guildId: data.message_reference.guild_id + ? bot.transformers.snowflake(data.message_reference.guild_id) : undefined, } : undefined, - mentionedUserIds: data.mentions.map((m) => bot.transformers.snowflake(m.id)), - mentionedRoleIds: data.mentionRoles.map((id) => bot.transformers.snowflake(id)), + mentionedUserIds: data.mentions ? data.mentions.map((m) => bot.transformers.snowflake(m.id)) : [], + mentionedRoleIds: data.mention_roles ? data.mention_roles.map((id) => bot.transformers.snowflake(id)) : [], mentionedChannelIds: [ // Keep any ids tht discord sends - ...data.mentionChannels.map((m) => bot.transformers.snowflake(m.id)), + ...(data.mention_channels ?? []).map((m) => bot.transformers.snowflake(m.id)), // Add any other ids that can be validated in a channel mention format ...(data.content?.match(CHANNEL_MENTION_REGEX) || []).map((text) => // converts the <#123> into 123 diff --git a/src/transformers/role.ts b/src/transformers/role.ts index b2fa82a82..d17b885c8 100644 --- a/src/transformers/role.ts +++ b/src/transformers/role.ts @@ -1,12 +1,13 @@ import { Bot } from "../bot.ts"; import { Role } from "../types/mod.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; export function transformRole( bot: Bot, - payload: { role: Role } & { + payload: { role: SnakeCasedPropertiesDeep } & { guildId: bigint; } -) { +): DiscordenoRole { return { // UNTRANSFORMED STUFF HERE name: payload.role.name, @@ -17,15 +18,15 @@ export function transformRole( (payload.role.hoist ? 1n : 0n) | (payload.role.managed ? 2n : 0n) | (payload.role.mentionable ? 4n : 0n) | - (payload.role.tags?.premiumSubscriber ? 8n : 0n), + (payload.role.tags?.premium_subscriber ? 8n : 0n), // TRANSFORMED STUFF BELOW id: bot.transformers.snowflake(payload.role.id), - botId: payload.role.tags?.botId ? bot.transformers.snowflake(payload.role.tags.botId) : undefined, - integrationId: payload.role.tags?.integrationId - ? bot.transformers.snowflake(payload.role.tags.integrationId) + botId: payload.role.tags?.bot_id ? bot.transformers.snowflake(payload.role.tags.bot_id) : undefined, + integrationId: payload.role.tags?.integration_id + ? bot.transformers.snowflake(payload.role.tags.integration_id) : undefined, - permissions: payload.role.permissions ? bot.transformers.snowflake(payload.role.permissions) : undefined, + permissions: bot.transformers.snowflake(payload.role.permissions), }; } @@ -37,7 +38,7 @@ export interface DiscordenoRole extends Omit Date: Sat, 9 Oct 2021 16:07:33 +0000 Subject: [PATCH 08/16] change: prettier code --- src/transformers/channel.ts | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/transformers/channel.ts b/src/transformers/channel.ts index abe3d18f1..c790fe28a 100644 --- a/src/transformers/channel.ts +++ b/src/transformers/channel.ts @@ -3,7 +3,10 @@ import { Bot } from "../bot.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; import { DiscordOverwrite } from "../types/channels/overwrite.ts"; -export function transformChannel(bot: Bot, payload: { channel: SnakeCasedPropertiesDeep } & { guildId?: bigint }) { +export function transformChannel( + bot: Bot, + payload: { channel: SnakeCasedPropertiesDeep } & { guildId?: bigint } +) { return { // UNTRANSFORMED STUFF HERE type: payload.channel.type, @@ -20,20 +23,26 @@ export function transformChannel(bot: Bot, payload: { channel: SnakeCasedPropert videoQualityMode: payload.channel.video_quality_mode, guildId: payload.guildId || (payload.channel.guild_id ? bot.transformers.snowflake(payload.channel.guild_id) : 0n), lastPinTimestamp: payload.channel.last_pin_timestamp, - permissionOverwrites: payload.channel.permission_overwrites ? payload.channel.permission_overwrites.map((o) => ({ - type: o.type, - id: bot.transformers.snowflake(o.id), - allow: bot.transformers.snowflake(o.allow), - deny: bot.transformers.snowflake(o.deny), - })) : [], + permissionOverwrites: payload.channel.permission_overwrites + ? payload.channel.permission_overwrites.map((o) => ({ + type: o.type, + id: bot.transformers.snowflake(o.id), + allow: bot.transformers.snowflake(o.allow), + deny: bot.transformers.snowflake(o.deny), + })) + : [], // TRANSFORMED STUFF BELOW id: bot.transformers.snowflake(payload.channel.id), - lastMessageId: payload.channel.last_message_id ? bot.transformers.snowflake(payload.channel.last_message_id) : undefined, + lastMessageId: payload.channel.last_message_id + ? bot.transformers.snowflake(payload.channel.last_message_id) + : undefined, ownerId: payload.channel.owner_id ? bot.transformers.snowflake(payload.channel.owner_id) : undefined, - applicationId: payload.channel.application_id ? bot.transformers.snowflake(payload.channel.application_id) : undefined, + applicationId: payload.channel.application_id + ? bot.transformers.snowflake(payload.channel.application_id) + : undefined, parentId: payload.channel.parent_id ? bot.transformers.snowflake(payload.channel.parent_id) : undefined, - } + }; } export interface DiscordenoChannel From ee2fff68117016490ec80a3b9468c825887c3e6e Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Sat, 9 Oct 2021 18:25:26 +0200 Subject: [PATCH 09/16] VoiceState transformer --- src/transformers/voice_state.ts | 143 ++++---------------------------- 1 file changed, 16 insertions(+), 127 deletions(-) diff --git a/src/transformers/voice_state.ts b/src/transformers/voice_state.ts index a83867570..9537c1249 100644 --- a/src/transformers/voice_state.ts +++ b/src/transformers/voice_state.ts @@ -1,123 +1,24 @@ -import { eventHandlers } from "../bot.ts"; -import { cache } from "../cache.ts"; -import type { GuildMember } from "../types/members/guild_member.ts"; import type { VoiceState } from "../types/voice/voice_state.ts"; -import { snowflakeToBigint } from "../util/bigint.ts"; -import { createNewProp } from "../util/utils.ts"; -import { DiscordenoGuild } from "./guild.ts"; -import { DiscordenoMember } from "./member.ts"; +import { Bot } from "../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -const VOICE_STATE_SNOWFLAKES = ["userId", "channelId", "guildId"]; +export function transformVoiceState(bot: Bot, payload: {voiceState: SnakeCasedPropertiesDeep } & {guildId: bigint}): DiscordenoVoiceState { + return { + bitfield: (payload.voiceState.deaf ? 1n : 0n) | + (payload.voiceState.mute ? 2n : 0n) | + (payload.voiceState.selfDeaf ? 4n : 0n) | + (payload.voiceState.selfMute ? 8n : 0n) | + (payload.voiceState.selfStream ? 16 : 0n) | + (payload.voiceState.selfVideo ? 32 : 0n) | + (payload.voiceState.suppress ? 64 : 0n), -export const voiceStateToggles = { - /** Whether this user is deafened by the server */ - deaf: 1n, - /** Whether this user is muted by the server */ - mute: 2n, - /** Whether this user is locally deafened */ - selfDeaf: 4n, - /** Whether this user is locally muted */ - selfMute: 8n, - /** Whether this user is streaming using "Go Live" */ - selfStream: 16n, - /** Whether this user's camera is enabled */ - selfVideo: 32n, - /** Whether this user is muted by the current user */ - suppress: 64n, -}; + requestToSpeakTimestamp: payload.voiceState.request_to_speak_timestamp, + sessionId: payload.voiceState.session_id, -const baseRole: Partial = { - get member() { - return cache.members.get(this.userId!); - }, - get guildMember() { - return this.member?.guilds.get(this.guildId!); - }, - get guild() { - return cache.guilds.get(this.guildId!); - }, - get deaf() { - return Boolean(this.bitfield! & voiceStateToggles.deaf); - }, - get mute() { - return Boolean(this.bitfield! & voiceStateToggles.mute); - }, - get selfDeaf() { - return Boolean(this.bitfield! & voiceStateToggles.selfDeaf); - }, - get selfMute() { - return Boolean(this.bitfield! & voiceStateToggles.selfMute); - }, - get selfStream() { - return Boolean(this.bitfield! & voiceStateToggles.selfStream); - }, - get selfVideo() { - return Boolean(this.bitfield! & voiceStateToggles.selfVideo); - }, - get suppress() { - return Boolean(this.bitfield! & voiceStateToggles.suppress); - }, - toJSON() { - return { - guildId: this.guildId?.toString(), - channelId: this.channelId?.toString(), - userId: this.userId?.toString(), - member: this.member, - sessionId: this.sessionId, - deaf: this.deaf, - mute: this.mute, - selfDeaf: this.selfDeaf, - selfMute: this.selfMute, - selfStream: this.selfStream, - selfVideo: this.selfVideo, - suppress: this.suppress, - requestToSpeakTimestamp: this.requestToSpeakTimestamp, - } as VoiceState; - }, -}; - -// deno-lint-ignore require-await -export async function createDiscordenoVoiceState(guildId: bigint, data: VoiceState) { - let bitfield = 0n; - - const props: Record> = {}; - for (const key of Object.keys(data) as (keyof typeof data)[]) { - eventHandlers.debug?.("loop", `Running for of loop in createDiscordenoVoiceState function.`); - - // if is empty allow all, otherwise check if prop is required - if (cache.requiredStructureProperties.voiceStates.size && !cache.requiredStructureProperties.voiceStates.has(key)) - continue; - - // We don't need to cache member twice. It will be in cache.members - if (key === "member") continue; - - const toggleBits = voiceStateToggles[key as keyof typeof voiceStateToggles]; - if (toggleBits) { - bitfield |= data[key] ? toggleBits : 0n; - continue; - } - - props[key] = createNewProp( - VOICE_STATE_SNOWFLAKES.includes(key) - ? data[key] - ? snowflakeToBigint(data[key] as string) - : undefined - : data[key] - ); + channelId: payload.voiceState.channel_id ? bot.transformers.snowflake(payload.voiceState.channel_id) : undefined, + guildId: payload.guildId || (payload.voiceState.guild_id ? bot.transformers.snowflake(payload.voiceState.guild_id) : 0n), + userId: payload.guildId || (payload.voiceState.user_id ? bot.transformers.snowflake(payload.voiceState.user_id) : 0n) } - - if ( - !cache.requiredStructureProperties.voiceStates.size || - cache.requiredStructureProperties.voiceStates.has("guildId") - ) - props.guildId = createNewProp(guildId); - if ( - !cache.requiredStructureProperties.voiceStates.size || - cache.requiredStructureProperties.voiceStates.has("bitfield") - ) - props.bitfield = createNewProp(bitfield); - - return Object.create(baseRole, props) as DiscordenoVoiceState; } export interface DiscordenoVoiceState extends Omit { @@ -129,16 +30,4 @@ export interface DiscordenoVoiceState extends Omit & { - joinedAt?: number; - premiumSince?: number; - roles: bigint[]; - }; - /** The guild where this role is. If undefined, the guild is not cached */ - guild?: DiscordenoGuild; - /** Converts to the raw JSON format. */ - toJSON(): VoiceState; } From f38880c5c9078619a46b95dc496d6c6f145a0086 Mon Sep 17 00:00:00 2001 From: TriForMine Date: Sat, 9 Oct 2021 16:26:04 +0000 Subject: [PATCH 10/16] change: prettier code --- src/transformers/voice_state.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/transformers/voice_state.ts b/src/transformers/voice_state.ts index 9537c1249..c1232fb25 100644 --- a/src/transformers/voice_state.ts +++ b/src/transformers/voice_state.ts @@ -2,9 +2,13 @@ import type { VoiceState } from "../types/voice/voice_state.ts"; import { Bot } from "../bot.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -export function transformVoiceState(bot: Bot, payload: {voiceState: SnakeCasedPropertiesDeep } & {guildId: bigint}): DiscordenoVoiceState { +export function transformVoiceState( + bot: Bot, + payload: { voiceState: SnakeCasedPropertiesDeep } & { guildId: bigint } +): DiscordenoVoiceState { return { - bitfield: (payload.voiceState.deaf ? 1n : 0n) | + bitfield: + (payload.voiceState.deaf ? 1n : 0n) | (payload.voiceState.mute ? 2n : 0n) | (payload.voiceState.selfDeaf ? 4n : 0n) | (payload.voiceState.selfMute ? 8n : 0n) | @@ -16,9 +20,11 @@ export function transformVoiceState(bot: Bot, payload: {voiceState: SnakeCasedPr sessionId: payload.voiceState.session_id, channelId: payload.voiceState.channel_id ? bot.transformers.snowflake(payload.voiceState.channel_id) : undefined, - guildId: payload.guildId || (payload.voiceState.guild_id ? bot.transformers.snowflake(payload.voiceState.guild_id) : 0n), - userId: payload.guildId || (payload.voiceState.user_id ? bot.transformers.snowflake(payload.voiceState.user_id) : 0n) - } + guildId: + payload.guildId || (payload.voiceState.guild_id ? bot.transformers.snowflake(payload.voiceState.guild_id) : 0n), + userId: + payload.guildId || (payload.voiceState.user_id ? bot.transformers.snowflake(payload.voiceState.user_id) : 0n), + }; } export interface DiscordenoVoiceState extends Omit { From fb4bfeadff245a76547e0f9016d497506876c688 Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Sat, 9 Oct 2021 18:26:54 +0200 Subject: [PATCH 11/16] Fixes --- src/transformers/voice_state.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transformers/voice_state.ts b/src/transformers/voice_state.ts index 9537c1249..8069b3ddf 100644 --- a/src/transformers/voice_state.ts +++ b/src/transformers/voice_state.ts @@ -8,9 +8,9 @@ export function transformVoiceState(bot: Bot, payload: {voiceState: SnakeCasedPr (payload.voiceState.mute ? 2n : 0n) | (payload.voiceState.selfDeaf ? 4n : 0n) | (payload.voiceState.selfMute ? 8n : 0n) | - (payload.voiceState.selfStream ? 16 : 0n) | - (payload.voiceState.selfVideo ? 32 : 0n) | - (payload.voiceState.suppress ? 64 : 0n), + (payload.voiceState.selfStream ? 16n : 0n) | + (payload.voiceState.selfVideo ? 32n : 0n) | + (payload.voiceState.suppress ? 64n : 0n), requestToSpeakTimestamp: payload.voiceState.request_to_speak_timestamp, sessionId: payload.voiceState.session_id, From f110951d18c8c135772bcb5280b7c260efe42a18 Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Sat, 9 Oct 2021 18:28:47 +0200 Subject: [PATCH 12/16] Fixes --- src/transformers/voice_state.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/transformers/voice_state.ts b/src/transformers/voice_state.ts index 55b1b2ec2..e19a67304 100644 --- a/src/transformers/voice_state.ts +++ b/src/transformers/voice_state.ts @@ -5,15 +5,15 @@ import { SnakeCasedPropertiesDeep } from "../types/util.ts"; export function transformVoiceState( bot: Bot, payload: { voiceState: SnakeCasedPropertiesDeep } & { guildId: bigint } -): DiscordenoVoiceState { +) { return { bitfield: (payload.voiceState.deaf ? 1n : 0n) | (payload.voiceState.mute ? 2n : 0n) | - (payload.voiceState.selfDeaf ? 4n : 0n) | - (payload.voiceState.selfMute ? 8n : 0n) | - (payload.voiceState.selfStream ? 16n : 0n) | - (payload.voiceState.selfVideo ? 32n : 0n) | + (payload.voiceState.self_deaf ? 4n : 0n) | + (payload.voiceState.self_mute ? 8n : 0n) | + (payload.voiceState.self_stream ? 16n : 0n) | + (payload.voiceState.self_video ? 32n : 0n) | (payload.voiceState.suppress ? 64n : 0n), requestToSpeakTimestamp: payload.voiceState.request_to_speak_timestamp, From 85c6b53189ba715bf2fc339c603a15387ce23ccf Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Sat, 9 Oct 2021 19:58:32 +0200 Subject: [PATCH 13/16] Guild Transformer --- src/transformers/guild.ts | 461 +++++--------------------------------- 1 file changed, 57 insertions(+), 404 deletions(-) diff --git a/src/transformers/guild.ts b/src/transformers/guild.ts index 29af36450..ea5a30a67 100644 --- a/src/transformers/guild.ts +++ b/src/transformers/guild.ts @@ -1,360 +1,72 @@ -import { botId, eventHandlers } from "../bot.ts"; -import { cache, cacheHandlers } from "../cache.ts"; -import { deleteGuild } from "../helpers/guilds/delete_guild.ts"; -import { editGuild } from "../helpers/guilds/edit_guild.ts"; -import { getAuditLogs } from "../helpers/guilds/get_audit_logs.ts"; -import { getBan } from "../helpers/guilds/get_ban.ts"; -import { getBans } from "../helpers/guilds/get_bans.ts"; -import { guildBannerURL } from "../helpers/guilds/guild_banner_url.ts"; -import { guildIconURL } from "../helpers/guilds/guild_icon_url.ts"; -import { guildSplashURL } from "../helpers/guilds/guild_splash_url.ts"; -import { leaveGuild } from "../helpers/guilds/leave_guild.ts"; -import { getInvites } from "../helpers/invites/get_invites.ts"; -import { banMember } from "../helpers/members/ban_member.ts"; -import { unbanMember } from "../helpers/members/unban_member.ts"; +import { Bot } from "../bot.ts"; import type { PresenceUpdate } from "../types/activity/presence_update.ts"; -import { GetGuildAuditLog } from "../types/audit_log/get_guild_audit_log.ts"; import type { Emoji } from "../types/emojis/emoji.ts"; -import type { CreateGuildBan } from "../types/guilds/create_guild_ban.ts"; import type { Guild } from "../types/guilds/guild.ts"; -import { DiscordGuildFeatures } from "../types/guilds/guild_features.ts"; -import type { ModifyGuild } from "../types/guilds/modify_guild.ts"; -import type { GuildMember, GuildMemberWithUser } from "../types/members/guild_member.ts"; -import type { DiscordImageFormat } from "../types/misc/image_format.ts"; -import type { DiscordImageSize } from "../types/misc/image_size.ts"; -import { snowflakeToBigint } from "../util/bigint.ts"; -import { cacheMembers } from "../util/cache_members.ts"; import { Collection } from "../util/collection.ts"; import { iconHashToBigInt } from "../util/hash.ts"; import { channelToThread } from "../util/transformers/channel_to_thread.ts"; -import { createNewProp } from "../util/utils.ts"; -import { DiscordenoChannel } from "./channel.ts"; -import { DiscordenoMember } from "./member.ts"; -import { structures } from "./mod.ts"; -import { DiscordenoRole } from "./role.ts"; -import { DiscordenoVoiceState } from "./voice_state.ts"; +import { transformChannel } from "./channel.ts"; +import { DiscordenoRole, transformRole } from "./role.ts"; +import { DiscordenoVoiceState, transformVoiceState } from "./voice_state.ts"; +import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -const GUILD_SNOWFLAKES = [ - "id", - "ownerId", - "permissions", - "afkChannelId", - "widgetChannelId", - "applicationId", - "systemChannelId", - "rulesChannelId", - "publicUpdatesChannelId", -]; +export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesDeep } & { shardId : number }): DiscordenoGuild { + return { + afkTimeout: payload.guild.afk_timeout, + approximateMemberCount: payload.guild.approximate_member_count, + approximatePresenceCount: payload.guild.approximate_presence_count, + defaultMessageNotifications: payload.guild.default_message_notifications, + description: payload.guild.description, + explicitContentFilter: payload.guild.explicit_content_filter, + features: payload.guild.features, + maxMembers: payload.guild.max_members, + maxPresences: payload.guild.max_presences, + maxVideoChannelUsers: payload.guild.max_video_channel_users, + mfaLevel: payload.guild.mfa_level, + name: payload.guild.name, + nsfwLevel: payload.guild.nsfw_level, + preferredLocale: payload.guild.preferred_locale, + premiumSubscriptionCount: payload.guild.premium_subscription_count, + premiumTier: payload.guild.premium_tier, + stageInstances: payload.guild.stage_instances, + systemChannelFlags: payload.guild.system_channel_flags, + vanityUrlCode: payload.guild.vanity_url_code, + verificationLevel: payload.guild.verification_level, + welcomeScreen: payload.guild.welcome_screen, + discoverySplash: payload.guild.discovery_splash, -export const guildToggles = { - /** Whether this user is owner of this guild */ - owner: 1n, - /** Whether the guild widget is enabled */ - widgetEnabled: 2n, - /** Whether this is a large guild */ - large: 4n, - /** Whether this guild is unavailable due to an outage */ - unavailable: 8n, - /** Whether this server's icon is animated */ - animatedIcon: 16n, - /** Whether this server's banner is animated. */ - animatedBanner: 32n, - /** Whether this server's splash is animated. */ - animatedSplash: 64n, -}; + bitfield: (payload.guild.owner ? 1n : 0n) | + (payload.guild.widget_enabled ? 2n : 0n) | + (payload.guild.large ? 4n : 0n) | + (payload.guild.unavailable ? 8n : 0n), -const baseGuild: Partial = { - toJSON() { - return { - shardId: this.shardId!, - id: this.id?.toString(), - name: this.name, - icon: this.icon, - iconHash: undefined, - splash: this.splash, - discoverySplash: this.discoverySplash, - owner: this.owner, - ownerId: this.ownerId?.toString(), - permissions: this.permissions, - afkChannelId: this.afkChannelId?.toString(), - afkTimeout: this.afkTimeout, - widgetEnabled: this.widgetEnabled, - widgetChannelId: this.widgetChannelId?.toString(), - verificationLevel: this.verificationLevel, - defaultMessageNotifications: this.defaultMessageNotifications, - explicitContentFilter: this.explicitContentFilter, - roles: this.roles?.map((r) => r.toJSON()) || [], - emojis: this.emojis?.array() || [], - features: this.features, - mfaLevel: this.mfaLevel, - applicationId: this.applicationId?.toString(), - systemChannelId: this.systemChannelId?.toString(), - systemChannelFlags: this.systemChannelFlags, - rulesChannelId: this.rulesChannelId?.toString(), - joinedAt: this.joinedAt ? new Date(this.joinedAt).toISOString() : undefined, - large: this.large, - unavailable: this.unavailable, - memberCount: this.memberCount, - voiceStates: this.voiceStates, - members: this.members, - channels: this.channels, - threads: this.threads, - presences: this.presences, - maxPresences: this.maxPresences, - maxMembers: this.maxMembers, - vanityUrlCode: this.vanityUrlCode, - description: this.description, - banner: this.banner, - premiumTier: this.premiumTier, - premiumSubscriptionCount: this.premiumSubscriptionCount, - preferredLocale: this.preferredLocale, - publicUpdatesChannelId: this.publicUpdatesChannelId?.toString(), - maxVideoChannelUsers: this.maxVideoChannelUsers, - approximateMemberCount: this.approximateMemberCount, - approximatePresenceCount: this.approximatePresenceCount, - welcomeScreen: this.welcomeScreen, - nsfwLevel: this.nsfwLevel, - stageInstances: this.stageInstances, - } as Guild & { shardId: number }; - }, - get members() { - return cache.members.filter((member) => member.guilds.has(this.id!)); - }, - get channels() { - return cache.channels.filter((channel) => channel.guildId === this.id); - }, - get afkChannel() { - return cache.channels.get(this.afkChannelId!); - }, - get publicUpdatesChannel() { - return cache.channels.get(this.publicUpdatesChannelId!); - }, - get rulesChannel() { - return cache.channels.get(this.rulesChannelId!); - }, - get systemChannel() { - return cache.channels.get(this.systemChannelId!); - }, - get bot() { - return cache.members.get(botId); - }, - get botMember() { - return this.bot?.guilds.get(this.id!); - }, - get botVoice() { - return this.voiceStates?.get(botId); - }, - get owner() { - return cache.members.get(this.ownerId!); - }, - get partnered() { - return Boolean(this.features?.includes(DiscordGuildFeatures.Partnered)); - }, - get verified() { - return Boolean(this.features?.includes(DiscordGuildFeatures.Verified)); - }, - bannerURL(size, format) { - return guildBannerURL(this.id!, { - banner: this.banner!, - size, - format, - animated: this.animatedBanner!, - }); - }, - splashURL(size, format) { - return guildSplashURL(this.id!, { - splash: this.splash!, - size, - format, - animated: this.animatedSplash, - }); - }, - delete() { - return deleteGuild(this.id!); - }, - edit(options) { - return editGuild(this.id!, options); - }, - auditLogs(options) { - return getAuditLogs(this.id!, options); - }, - getBan(memberId) { - return getBan(this.id!, memberId); - }, - bans() { - return getBans(this.id!); - }, - ban(memberId, options) { - return banMember(this.id!, memberId, options); - }, - unban(memberId) { - return unbanMember(this.id!, memberId); - }, - invites() { - return getInvites(this.id!); - }, - iconURL(size, format) { - return guildIconURL(this.id!, { - icon: this.icon!, - size, - format, - animated: this.animatedIcon!, - }); - }, - leave() { - return leaveGuild(this.id!); - }, - get isOwner() { - return Boolean(this.bitfield! & guildToggles.owner); - }, - get widgetEnabled() { - return Boolean(this.bitfield! & guildToggles.widgetEnabled); - }, - get large() { - return Boolean(this.bitfield! & guildToggles.large); - }, - get unavailable() { - return Boolean(this.bitfield! & guildToggles.unavailable); - }, - get animatedIcon() { - return Boolean(this.bitfield! & guildToggles.animatedIcon); - }, - get animatedBanner() { - return Boolean(this.bitfield! & guildToggles.animatedBanner); - }, - get animatedSplash() { - return Boolean(this.bitfield! & guildToggles.animatedSplash); - }, -}; + joinedAt: payload.guild.joined_at ? Date.parse(payload.guild.joined_at) : undefined, + memberCount: payload.guild.member_count ?? 0, + shardId: payload.shardId, + icon: payload.guild.icon ? iconHashToBigInt(payload.guild.icon) : undefined, + banner: payload.guild.banner ? iconHashToBigInt(payload.guild.banner) : undefined, + splash: payload.guild.icon ? iconHashToBigInt(payload.guild.splash) : undefined, -export async function createDiscordenoGuild(data: Guild, shardId: number) { - const { - memberCount = 0, - voiceStates = [], - channels = [], - threads = [], - presences = [], - joinedAt = "", - emojis = [], - members = [], - icon, - splash, - banner, - ...rest - } = data; + // TRANSFORMED STUFF BELOW + // TODO: Handle channels/threads in a better way? + channels: (payload.guild.channels || []).map((channel) => transformChannel(bot, { channel, guildId: bot.transformers.snowflake(payload.guild.id) })), + threads: (payload.guild.threads || []).map((channel) => channelToThread(channel)), - let bitfield = 0n; - const guildId = snowflakeToBigint(rest.id); + roles: new Collection((payload.guild.roles || []).map(role => transformRole(bot, {role, guildId: bot.transformers.snowflake(payload.guild.id)})).map(role => [role.id, role])), + presences: new Collection((payload.guild.presences || []).map((p) => [bot.transformers.snowflake(p.user!.id), p])), + emojis: new Collection((payload.guild.emojis || []).map((emoji) => [bot.transformers.snowflake(emoji.id!), emoji])), + voiceStates: new Collection((payload.guild.voice_states || []).map((vs) => transformVoiceState(bot, {voiceState: vs, guildId: bot.transformers.snowflake(payload.guild.id)})).map((vs) => [vs.userId, vs])), - const promises = []; - - for (const channel of channels) { - promises.push(async () => { - const discordenoChannel = await structures.createDiscordenoChannel(channel, guildId); - - return cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); - }); + id: bot.transformers.snowflake(payload.guild.id), + ownerId: bot.transformers.snowflake(payload.guild.owner_id), + permissions: payload.guild.permissions ? bot.transformers.snowflake(payload.guild.permissions) : 0n, + afkChannelId: payload.guild.afk_channel_id ? bot.transformers.snowflake(payload.guild.afk_channel_id) : undefined, + widgetChannelId: payload.guild.widget_channel_id ? bot.transformers.snowflake(payload.guild.widget_channel_id) : undefined, + applicationId: payload.guild.application_id ? bot.transformers.snowflake(payload.guild.application_id) : undefined, + systemChannelId: payload.guild.system_channel_id ? bot.transformers.snowflake(payload.guild.system_channel_id) : undefined, + rulesChannelId: payload.guild.rules_channel_id ? bot.transformers.snowflake(payload.guild.rules_channel_id) : undefined, + publicUpdatesChannelId: payload.guild.public_updates_channel_id ? bot.transformers.snowflake(payload.guild.public_updates_channel_id) : undefined } - - for (const thread of threads) { - promises.push(() => { - const discordenoThread = channelToThread(thread); - - return cacheHandlers.set("threads", discordenoThread.id, discordenoThread); - }); - } - - await Promise.all( - promises.map(async (promise) => { - return await promise(); - }) - ); - - const roles = await Promise.all( - (data.roles || []).map((role) => - structures.createDiscordenoRole({ - role, - guildId, - }) - ) - ); - - const voiceStateStructs = await Promise.all( - voiceStates.map((vs) => { - if (vs.member?.joinedAt) members.push(vs.member); - return structures.createDiscordenoVoiceState(guildId, vs); - }) - ); - - const props: Record> = {}; - for (const key of Object.keys(rest) as (keyof typeof rest)[]) { - eventHandlers.debug?.("loop", `Running for of loop in createDiscordenoGuild function.`); - - // If its empty default allows all, otherwise only allow those users required. - if (cache.requiredStructureProperties.guilds.size && !cache.requiredStructureProperties.guilds.has(key)) { - continue; - } - - const toggleBits = guildToggles[key as keyof typeof guildToggles]; - if (toggleBits) { - bitfield |= rest[key] ? toggleBits : 0n; - continue; - } - - props[key] = createNewProp( - GUILD_SNOWFLAKES.includes(key) ? (rest[key] ? snowflakeToBigint(rest[key] as string) : undefined) : rest[key] - ); - } - - const hashes = [ - { name: "icon", toggle: guildToggles.animatedIcon, value: icon }, - { name: "banner", toggle: guildToggles.animatedBanner, value: banner }, - { name: "splash", toggle: guildToggles.animatedSplash, value: splash }, - ] as const; - - for (const hash of hashes) { - // If its empty default allows all, otherwise only allow those users required. - if (cache.requiredStructureProperties.guilds.size && !cache.requiredStructureProperties.guilds.has(hash.name)) { - continue; - } - - const transformed = hash.value ? iconHashToBigInt(hash.value) : undefined; - if (transformed) { - props[hash.name] = createNewProp(hash.value); - if (transformed.animated) bitfield |= hash.toggle; - } - } - - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("roles")) { - props.roles = createNewProp(new Collection(roles.map((r: DiscordenoRole) => [r.id, r]))); - } - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("joinedAt")) { - props.joinedAt = createNewProp(Date.parse(joinedAt)); - } - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("presences")) { - props.presences = createNewProp(new Collection(presences.map((p) => [snowflakeToBigint(p.user!.id), p]))); - } - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("memberCount")) { - props.memberCount = createNewProp(memberCount); - } - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("emojis")) { - props.emojis = createNewProp(new Collection(emojis.map((emoji) => [snowflakeToBigint(emoji.id!), emoji]))); - } - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("voiceStates")) { - props.voiceStates = createNewProp(new Collection(voiceStateStructs.map((vs) => [vs.userId, vs]))); - } - - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("shardId")) { - props.shardId = createNewProp(shardId); - } - - if (!cache.requiredStructureProperties.guilds.size || cache.requiredStructureProperties.guilds.has("bitfield")) { - props.bitfield = createNewProp(bitfield); - } - - const guild: DiscordenoGuild = Object.create(baseGuild, props); - await cacheMembers(guild.id, members as GuildMemberWithUser[]); - return guild; } export interface DiscordenoGuild @@ -377,7 +89,7 @@ export interface DiscordenoGuild | "systemChannelId" | "rulesChannelId" | "publicUpdatesChannelId" - > { + > { /** Guild id */ id: bigint; /** Id of the owner */ @@ -418,63 +130,4 @@ export interface DiscordenoGuild isOwner: boolean; /** Holds all the boolean toggles. */ bitfield: bigint; - - // GETTERS - /** Members in this guild. */ - members: Collection; - /** Channels in this guild. */ - channels: Collection; - /** The afk channel if one is set */ - afkChannel?: DiscordenoChannel; - /** The public update channel if one is set */ - publicUpdatesChannel?: DiscordenoChannel; - /** The rules channel in this guild if one is set */ - rulesChannel?: DiscordenoChannel; - /** The system channel in this guild if one is set */ - systemChannel?: DiscordenoChannel; - /** The bot member in this guild if cached */ - bot?: DiscordenoMember; - /** The bot guild member in this guild if cached */ - botMember?: Omit & { - joinedAt?: number; - premiumSince?: number; - roles: bigint[]; - }; - /** The bots voice state if there is one in this guild */ - botVoice?: DiscordenoVoiceState; - /** The owner member of this guild */ - owner?: DiscordenoMember; - /** Whether or not this guild is partnered */ - partnered: boolean; - /** Whether or not this guild is verified */ - verified: boolean; - - // METHODS - - /** The banner url for this server */ - bannerURL(size?: DiscordImageSize, format?: DiscordImageFormat): string | undefined; - /** The splash url for this server */ - splashURL(size?: DiscordImageSize, format?: DiscordImageFormat): string | undefined; - /** The full URL of the icon from Discords CDN. Undefined when no icon is set. */ - iconURL(size?: DiscordImageSize, format?: DiscordImageFormat): string | undefined; - /** Delete a guild permanently. User must be owner. Returns 204 No Content on success. Fires a Guild Delete Gateway event. */ - delete(): ReturnType; - /** Leave a guild */ - leave(): ReturnType; - /** Edit the server. Requires the MANAGE_GUILD permission. */ - edit(options: ModifyGuild): ReturnType; - /** Returns the audit logs for the guild. Requires VIEW AUDIT LOGS permission */ - auditLogs(options?: GetGuildAuditLog): ReturnType; - /** Returns a ban object for the given user or a 404 not found if the ban cannot be found. Requires the BAN_MEMBERS permission. */ - getBan(memberId: bigint): ReturnType; - /** Returns a list of ban objects for the users banned from this guild. Requires the BAN_MEMBERS permission. */ - bans(): ReturnType; - /** Ban a user from the guild and optionally delete previous messages sent by the user. Requires the BAN_MEMBERS permission. */ - ban(memberId: bigint, options?: CreateGuildBan): ReturnType; - /** Remove the ban for a user. Requires BAN_MEMBERS permission */ - unban(memberId: bigint): ReturnType; - /** Get all the invites for this guild. Requires MANAGE_GUILD permission */ - invites(): ReturnType; - /** Get the JSON version of the Guild object used to create this. Includes the shardId as well */ - toJSON(): Guild & { shardId: number }; } From 39a294bd2a67737baadeb7a75589996952a9195a Mon Sep 17 00:00:00 2001 From: TriForMine Date: Sat, 9 Oct 2021 17:59:22 +0000 Subject: [PATCH 14/16] change: prettier code --- src/transformers/guild.ts | 46 +++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/transformers/guild.ts b/src/transformers/guild.ts index ea5a30a67..239761988 100644 --- a/src/transformers/guild.ts +++ b/src/transformers/guild.ts @@ -10,7 +10,10 @@ import { DiscordenoRole, transformRole } from "./role.ts"; import { DiscordenoVoiceState, transformVoiceState } from "./voice_state.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesDeep } & { shardId : number }): DiscordenoGuild { +export function transformGuild( + bot: Bot, + payload: { guild: SnakeCasedPropertiesDeep } & { shardId: number } +): DiscordenoGuild { return { afkTimeout: payload.guild.afk_timeout, approximateMemberCount: payload.guild.approximate_member_count, @@ -35,7 +38,8 @@ export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesD welcomeScreen: payload.guild.welcome_screen, discoverySplash: payload.guild.discovery_splash, - bitfield: (payload.guild.owner ? 1n : 0n) | + bitfield: + (payload.guild.owner ? 1n : 0n) | (payload.guild.widget_enabled ? 2n : 0n) | (payload.guild.large ? 4n : 0n) | (payload.guild.unavailable ? 8n : 0n), @@ -49,24 +53,44 @@ export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesD // TRANSFORMED STUFF BELOW // TODO: Handle channels/threads in a better way? - channels: (payload.guild.channels || []).map((channel) => transformChannel(bot, { channel, guildId: bot.transformers.snowflake(payload.guild.id) })), + channels: (payload.guild.channels || []).map((channel) => + transformChannel(bot, { channel, guildId: bot.transformers.snowflake(payload.guild.id) }) + ), threads: (payload.guild.threads || []).map((channel) => channelToThread(channel)), - roles: new Collection((payload.guild.roles || []).map(role => transformRole(bot, {role, guildId: bot.transformers.snowflake(payload.guild.id)})).map(role => [role.id, role])), + roles: new Collection( + (payload.guild.roles || []) + .map((role) => transformRole(bot, { role, guildId: bot.transformers.snowflake(payload.guild.id) })) + .map((role) => [role.id, role]) + ), presences: new Collection((payload.guild.presences || []).map((p) => [bot.transformers.snowflake(p.user!.id), p])), emojis: new Collection((payload.guild.emojis || []).map((emoji) => [bot.transformers.snowflake(emoji.id!), emoji])), - voiceStates: new Collection((payload.guild.voice_states || []).map((vs) => transformVoiceState(bot, {voiceState: vs, guildId: bot.transformers.snowflake(payload.guild.id)})).map((vs) => [vs.userId, vs])), + voiceStates: new Collection( + (payload.guild.voice_states || []) + .map((vs) => + transformVoiceState(bot, { voiceState: vs, guildId: bot.transformers.snowflake(payload.guild.id) }) + ) + .map((vs) => [vs.userId, vs]) + ), id: bot.transformers.snowflake(payload.guild.id), ownerId: bot.transformers.snowflake(payload.guild.owner_id), permissions: payload.guild.permissions ? bot.transformers.snowflake(payload.guild.permissions) : 0n, afkChannelId: payload.guild.afk_channel_id ? bot.transformers.snowflake(payload.guild.afk_channel_id) : undefined, - widgetChannelId: payload.guild.widget_channel_id ? bot.transformers.snowflake(payload.guild.widget_channel_id) : undefined, + widgetChannelId: payload.guild.widget_channel_id + ? bot.transformers.snowflake(payload.guild.widget_channel_id) + : undefined, applicationId: payload.guild.application_id ? bot.transformers.snowflake(payload.guild.application_id) : undefined, - systemChannelId: payload.guild.system_channel_id ? bot.transformers.snowflake(payload.guild.system_channel_id) : undefined, - rulesChannelId: payload.guild.rules_channel_id ? bot.transformers.snowflake(payload.guild.rules_channel_id) : undefined, - publicUpdatesChannelId: payload.guild.public_updates_channel_id ? bot.transformers.snowflake(payload.guild.public_updates_channel_id) : undefined - } + systemChannelId: payload.guild.system_channel_id + ? bot.transformers.snowflake(payload.guild.system_channel_id) + : undefined, + rulesChannelId: payload.guild.rules_channel_id + ? bot.transformers.snowflake(payload.guild.rules_channel_id) + : undefined, + publicUpdatesChannelId: payload.guild.public_updates_channel_id + ? bot.transformers.snowflake(payload.guild.public_updates_channel_id) + : undefined, + }; } export interface DiscordenoGuild @@ -89,7 +113,7 @@ export interface DiscordenoGuild | "systemChannelId" | "rulesChannelId" | "publicUpdatesChannelId" - > { + > { /** Guild id */ id: bigint; /** Id of the owner */ From 938c0f4e638ea4f8e2f25a6588b6d0ae39ea5846 Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Sat, 9 Oct 2021 20:06:50 +0200 Subject: [PATCH 15/16] Fixes --- src/transformers/guild.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transformers/guild.ts b/src/transformers/guild.ts index ea5a30a67..de79685db 100644 --- a/src/transformers/guild.ts +++ b/src/transformers/guild.ts @@ -10,7 +10,7 @@ import { DiscordenoRole, transformRole } from "./role.ts"; import { DiscordenoVoiceState, transformVoiceState } from "./voice_state.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesDeep } & { shardId : number }): DiscordenoGuild { +export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesDeep } & { shardId : number }) { return { afkTimeout: payload.guild.afk_timeout, approximateMemberCount: payload.guild.approximate_member_count, @@ -45,7 +45,7 @@ export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesD shardId: payload.shardId, icon: payload.guild.icon ? iconHashToBigInt(payload.guild.icon) : undefined, banner: payload.guild.banner ? iconHashToBigInt(payload.guild.banner) : undefined, - splash: payload.guild.icon ? iconHashToBigInt(payload.guild.splash) : undefined, + splash: payload.guild.splash ? iconHashToBigInt(payload.guild.splash) : undefined, // TRANSFORMED STUFF BELOW // TODO: Handle channels/threads in a better way? From 1f404541834c97847779baf5ba8a8c49cdf7f1c4 Mon Sep 17 00:00:00 2001 From: TriForMine Date: Sat, 9 Oct 2021 18:08:12 +0000 Subject: [PATCH 16/16] change: prettier code --- src/transformers/guild.ts | 46 +++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/transformers/guild.ts b/src/transformers/guild.ts index 7da52ae66..5b5f1c025 100644 --- a/src/transformers/guild.ts +++ b/src/transformers/guild.ts @@ -10,10 +10,7 @@ import { DiscordenoRole, transformRole } from "./role.ts"; import { DiscordenoVoiceState, transformVoiceState } from "./voice_state.ts"; import { SnakeCasedPropertiesDeep } from "../types/util.ts"; -export function transformGuild( - bot: Bot, - payload: { guild: SnakeCasedPropertiesDeep } & { shardId: number } -) { +export function transformGuild(bot: Bot, payload: { guild: SnakeCasedPropertiesDeep } & { shardId: number }) { return { afkTimeout: payload.guild.afk_timeout, approximateMemberCount: payload.guild.approximate_member_count, @@ -38,7 +35,8 @@ export function transformGuild( welcomeScreen: payload.guild.welcome_screen, discoverySplash: payload.guild.discovery_splash, - bitfield: (payload.guild.owner ? 1n : 0n) | + bitfield: + (payload.guild.owner ? 1n : 0n) | (payload.guild.widget_enabled ? 2n : 0n) | (payload.guild.large ? 4n : 0n) | (payload.guild.unavailable ? 8n : 0n), @@ -52,24 +50,44 @@ export function transformGuild( // TRANSFORMED STUFF BELOW // TODO: Handle channels/threads in a better way? - channels: (payload.guild.channels || []).map((channel) => transformChannel(bot, { channel, guildId: bot.transformers.snowflake(payload.guild.id) })), + channels: (payload.guild.channels || []).map((channel) => + transformChannel(bot, { channel, guildId: bot.transformers.snowflake(payload.guild.id) }) + ), threads: (payload.guild.threads || []).map((channel) => channelToThread(channel)), - roles: new Collection((payload.guild.roles || []).map(role => transformRole(bot, {role, guildId: bot.transformers.snowflake(payload.guild.id)})).map(role => [role.id, role])), + roles: new Collection( + (payload.guild.roles || []) + .map((role) => transformRole(bot, { role, guildId: bot.transformers.snowflake(payload.guild.id) })) + .map((role) => [role.id, role]) + ), presences: new Collection((payload.guild.presences || []).map((p) => [bot.transformers.snowflake(p.user!.id), p])), emojis: new Collection((payload.guild.emojis || []).map((emoji) => [bot.transformers.snowflake(emoji.id!), emoji])), - voiceStates: new Collection((payload.guild.voice_states || []).map((vs) => transformVoiceState(bot, {voiceState: vs, guildId: bot.transformers.snowflake(payload.guild.id)})).map((vs) => [vs.userId, vs])), + voiceStates: new Collection( + (payload.guild.voice_states || []) + .map((vs) => + transformVoiceState(bot, { voiceState: vs, guildId: bot.transformers.snowflake(payload.guild.id) }) + ) + .map((vs) => [vs.userId, vs]) + ), id: bot.transformers.snowflake(payload.guild.id), ownerId: bot.transformers.snowflake(payload.guild.owner_id), permissions: payload.guild.permissions ? bot.transformers.snowflake(payload.guild.permissions) : 0n, afkChannelId: payload.guild.afk_channel_id ? bot.transformers.snowflake(payload.guild.afk_channel_id) : undefined, - widgetChannelId: payload.guild.widget_channel_id ? bot.transformers.snowflake(payload.guild.widget_channel_id) : undefined, + widgetChannelId: payload.guild.widget_channel_id + ? bot.transformers.snowflake(payload.guild.widget_channel_id) + : undefined, applicationId: payload.guild.application_id ? bot.transformers.snowflake(payload.guild.application_id) : undefined, - systemChannelId: payload.guild.system_channel_id ? bot.transformers.snowflake(payload.guild.system_channel_id) : undefined, - rulesChannelId: payload.guild.rules_channel_id ? bot.transformers.snowflake(payload.guild.rules_channel_id) : undefined, - publicUpdatesChannelId: payload.guild.public_updates_channel_id ? bot.transformers.snowflake(payload.guild.public_updates_channel_id) : undefined - } + systemChannelId: payload.guild.system_channel_id + ? bot.transformers.snowflake(payload.guild.system_channel_id) + : undefined, + rulesChannelId: payload.guild.rules_channel_id + ? bot.transformers.snowflake(payload.guild.rules_channel_id) + : undefined, + publicUpdatesChannelId: payload.guild.public_updates_channel_id + ? bot.transformers.snowflake(payload.guild.public_updates_channel_id) + : undefined, + }; } export interface DiscordenoGuild @@ -92,7 +110,7 @@ export interface DiscordenoGuild | "systemChannelId" | "rulesChannelId" | "publicUpdatesChannelId" - > { + > { /** Guild id */ id: bigint; /** Id of the owner */