From af94acfed670f6e41d457c8d671cb6f4bb9c4a54 Mon Sep 17 00:00:00 2001 From: Quentin Nicolini Date: Sat, 9 Oct 2021 18:06:47 +0200 Subject: [PATCH] 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