diff --git a/src/bot.ts b/src/bot.ts index 1edd3f29d..8a0cae9af 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -11,46 +11,41 @@ import { requireChannelPermissions, highestRole, higherRolePosition, + requireBotChannelPermissions, + requireBotGuildPermissions, } from "./util/permissions.ts"; import { getGatewayBot } from "./helpers/misc/get_gateway_bot.ts"; -import { checkRateLimits } from "./rest/check_rate_limits.ts"; -import { cleanupQueues } from "./rest/cleanup_queues.ts"; -import { createRequestBody } from "./rest/create_request_body.ts"; -import { processRateLimitedPaths } from "./rest/process_rate_limited_paths.ts"; -import { processRequest } from "./rest/process_request.ts"; -import { processRequestHeaders } from "./rest/process_request_headers.ts"; +import { + checkRateLimits, + processQueue, + cleanupQueues, + createRequestBody, + processRateLimitedPaths, + processRequest, + processRequestHeaders, + runMethod, + processGlobalQueue, + simplifyUrl, +} from "./rest/mod.ts"; import type { RestPayload, RestRateLimitedPath, RestRequest } from "./rest/rest.ts"; -import { runMethod } from "./rest/run_method.ts"; -import { simplifyUrl } from "./rest/simplify_url.ts"; import { DiscordGatewayIntents } from "./types/gateway/gateway_intents.ts"; import { GetGatewayBot } from "./types/gateway/get_gateway_bot.ts"; -import { dispatchRequirements } from "./util/dispatch_requirements.ts"; -import { processQueue } from "./rest/process_queue.ts"; import { bigintToSnowflake, snowflakeToBigint } from "./util/bigint.ts"; import { Collection } from "./util/collection.ts"; -import type { DiscordenoMember, DiscordenoUser } from "./transformers/member.ts"; -import { transformMember, transformUser } from "./transformers/member.ts"; -import { SnakeCasedPropertiesDeep } from "./types/util.ts"; -import { Channel } from "./types/channels/channel.ts"; -import { DiscordenoChannel, transformChannel } from "./transformers/channel.ts"; -import { DiscordenoVoiceState, transformVoiceState } from "./transformers/voice_state.ts"; -import { transformRole } from "./transformers/role.ts"; -import { transformMessage } from "./transformers/message.ts"; -import { DiscordenoGuild, transformGuild } from "./transformers/guild.ts"; -import type { DiscordenoShard } from "./ws/ws.ts"; -import { startGateway } from "./ws/start_gateway.ts"; -import { spawnShards } from "./ws/spawn_shards.ts"; -import { createShard } from "./ws/create_shard.ts"; -import { identify } from "./ws/identify.ts"; -import { heartbeat } from "./ws/heartbeat.ts"; -import { resharder } from "./ws/resharder.ts"; -import { tellClusterToIdentify } from "./ws/tell_cluster_to_identify.ts"; -import { log } from "./ws/events.ts"; -import { handleOnMessage } from "./ws/handle_on_message.ts"; -import { closeWS } from "./ws/close_ws.ts"; -import { sendShardMessage } from "./ws/send_shard_message.ts"; -import { resume } from "./ws/resume.ts"; -import { calculateShardId } from "./util/calculate_shard_id.ts"; +import { + DiscordenoMember, + DiscordenoUser, + transformMember, + transformUser, + DiscordenoGuild, + transformGuild, + DiscordenoChannel, + transformChannel, + transformMessage, + transformRole, + DiscordenoVoiceState, + transformVoiceState, +} from "./transformers/mod.ts"; import { baseEndpoints, CHANNEL_MENTION_REGEX, @@ -61,15 +56,27 @@ import { SLASH_COMMANDS_NAME_REGEX, USER_AGENT, } from "./util/constants.ts"; -import { GatewayDispatchEventNames, GatewayEventNames, GatewayPayload } from "./types/gateway/gateway_payload.ts"; -import { delay, validateSlashOptionChoices, validateSlashOptions } from "./util/utils.ts"; -import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts"; +import { Errors } from "./types/discordeno/errors.ts"; +import { GatewayDispatchEventNames, GatewayPayload } from "./types/gateway/gateway_payload.ts"; +import { + closeWS, + handleOnMessage, + resume, + resharder, + log, + startGateway, + spawnShards, + createShard, + identify, + heartbeat, + tellClusterToIdentify, + sendShardMessage, + DiscordenoShard, +} from "./ws/mod.ts"; import { validateLength } from "./util/validate_length.ts"; -import { processGlobalQueue } from "./rest/process_global_queue.ts"; -import { ChannelPinsUpdate } from "./types/channels/channel_pins_update.ts"; -import { ApplicationCommandTypes, Emoji, IntegrationCreateUpdate } from "./types/mod.ts"; -import { ApplicationCommandOption } from "./types/mod.ts"; -import { handleGuildLoaded } from "./handlers/guilds/GUILD_LOADED_DD.ts"; +import { delay, validateComponents, validateSlashOptionChoices, validateSlashOptions } from "./util/utils.ts"; +import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts"; +import { calculateShardId } from "./util/calculate_shard_id.ts"; import { handleReady, handleChannelCreate, @@ -118,9 +125,11 @@ import { handleIntegrationCreate, handleIntegrationUpdate, handleIntegrationDelete, + handleGuildLoaded } from "./handlers/mod.ts"; import { DiscordenoInteraction, transformInteraction } from "./transformers/interaction.ts"; import { DiscordenoIntegration, transformIntegration } from "./transformers/integration.ts"; +import {Emoji} from "./types/emojis/emoji.ts"; import { transformApplication } from "./transformers/application.ts"; import { transformTeam } from "./transformers/team.ts"; import { DiscordenoInvite, transformInvite } from "./transformers/invite.ts"; @@ -239,6 +248,7 @@ export function createEventHandlers(events: Partial): EventHandle function ignore() {} return { + channelCreate: events.channelCreate ?? ignore, debug: events.debug ?? ignore, dispatchRequirements: events.dispatchRequirements ?? ignore, integrationCreate: events.integrationCreate ?? ignore, @@ -365,6 +375,9 @@ export function createUtils(options: Partial) { validateLength, validateSlashOptions, validateSlashOptionChoices, + requireBotChannelPermissions, + requireBotGuildPermissions, + validateComponents, }; } @@ -390,6 +403,9 @@ export interface HelperUtils { validateLength: typeof validateLength; validateSlashOptions: typeof validateSlashOptions; validateSlashOptionChoices: typeof validateSlashOptionChoices; + requireBotChannelPermissions: typeof requireBotChannelPermissions; + requireBotGuildPermissions: typeof requireBotGuildPermissions; + validateComponents: typeof validateComponents; } export function createGatewayManager(options: Partial): GatewayManager { @@ -704,6 +720,7 @@ export function createBotConstants() { CHANNEL_MENTION_REGEX, DISCORD_SNOWFLAKE_REGEX, }, + Errors, }; } diff --git a/src/handlers/channels/CHANNEL_CREATE.ts b/src/handlers/channels/CHANNEL_CREATE.ts index eb1338979..c9a61eb7c 100644 --- a/src/handlers/channels/CHANNEL_CREATE.ts +++ b/src/handlers/channels/CHANNEL_CREATE.ts @@ -2,7 +2,7 @@ import type { Channel } from "../../types/channels/channel.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; export async function handleChannelCreate(bot: Bot, payload: SnakeCasedPropertiesDeep) { const channel = bot.transformers.channel(bot, { channel: payload.d as SnakeCasedPropertiesDeep }); diff --git a/src/handlers/channels/CHANNEL_DELETE.ts b/src/handlers/channels/CHANNEL_DELETE.ts index 627b989fd..5b289d45c 100644 --- a/src/handlers/channels/CHANNEL_DELETE.ts +++ b/src/handlers/channels/CHANNEL_DELETE.ts @@ -1,6 +1,6 @@ import type { Channel } from "../../types/channels/channel.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/channels/CHANNEL_PINS_UPDATE.ts b/src/handlers/channels/CHANNEL_PINS_UPDATE.ts index 261e1a4d5..121da7060 100644 --- a/src/handlers/channels/CHANNEL_PINS_UPDATE.ts +++ b/src/handlers/channels/CHANNEL_PINS_UPDATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { ChannelPinsUpdate } from "../../types/channels/channel_pins_update.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/channels/CHANNEL_UPDATE.ts b/src/handlers/channels/CHANNEL_UPDATE.ts index 19fbb622f..f7e7af816 100644 --- a/src/handlers/channels/CHANNEL_UPDATE.ts +++ b/src/handlers/channels/CHANNEL_UPDATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { Channel } from "../../types/channels/channel.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/channels/STAGE_INSTANCE_CREATE.ts b/src/handlers/channels/STAGE_INSTANCE_CREATE.ts index d65635df2..25e812560 100644 --- a/src/handlers/channels/STAGE_INSTANCE_CREATE.ts +++ b/src/handlers/channels/STAGE_INSTANCE_CREATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/channels/STAGE_INSTANCE_DELETE.ts b/src/handlers/channels/STAGE_INSTANCE_DELETE.ts index fced34649..e40668923 100644 --- a/src/handlers/channels/STAGE_INSTANCE_DELETE.ts +++ b/src/handlers/channels/STAGE_INSTANCE_DELETE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts b/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts index e65cfb498..5b497edea 100644 --- a/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts +++ b/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts b/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts index 2ea8ef84e..fbc82f69c 100644 --- a/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts +++ b/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { GuildEmojisUpdate } from "../../types/emojis/guild_emojis_update.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/guilds/GUILD_BAN_ADD.ts b/src/handlers/guilds/GUILD_BAN_ADD.ts index 6a171f5e9..5e0cda90c 100644 --- a/src/handlers/guilds/GUILD_BAN_ADD.ts +++ b/src/handlers/guilds/GUILD_BAN_ADD.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { GuildBanAddRemove } from "../../types/guilds/guild_ban_add_remove.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/guilds/GUILD_BAN_REMOVE.ts b/src/handlers/guilds/GUILD_BAN_REMOVE.ts index cd2b41961..a3f9a9057 100644 --- a/src/handlers/guilds/GUILD_BAN_REMOVE.ts +++ b/src/handlers/guilds/GUILD_BAN_REMOVE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { GuildBanAddRemove } from "../../types/guilds/guild_ban_add_remove.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/guilds/GUILD_CREATE.ts b/src/handlers/guilds/GUILD_CREATE.ts index b7e7b7c0d..de7deb3f4 100644 --- a/src/handlers/guilds/GUILD_CREATE.ts +++ b/src/handlers/guilds/GUILD_CREATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { Guild } from "../../types/guilds/guild.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/guilds/GUILD_DELETE.ts b/src/handlers/guilds/GUILD_DELETE.ts index 2ded20125..d7c276360 100644 --- a/src/handlers/guilds/GUILD_DELETE.ts +++ b/src/handlers/guilds/GUILD_DELETE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { UnavailableGuild } from "../../types/guilds/unavailable_guild.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts b/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts index 827c629ed..e6a2610d7 100644 --- a/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts +++ b/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { GuildIntegrationsUpdate } from "../../types/integrations/guild_integrations_update.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/guilds/GUILD_LOADED_DD.ts b/src/handlers/guilds/GUILD_LOADED_DD.ts index d8a8c4562..a2c99dc73 100644 --- a/src/handlers/guilds/GUILD_LOADED_DD.ts +++ b/src/handlers/guilds/GUILD_LOADED_DD.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { Guild } from "../../types/guilds/guild.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/handlers/guilds/GUILD_UPDATE.ts b/src/handlers/guilds/GUILD_UPDATE.ts index 7d145ecab..028867c50 100644 --- a/src/handlers/guilds/GUILD_UPDATE.ts +++ b/src/handlers/guilds/GUILD_UPDATE.ts @@ -1,4 +1,4 @@ -import { Bot } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; import type { Guild } from "../../types/guilds/guild.ts"; import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; diff --git a/src/helpers/channels/category_children.ts b/src/helpers/channels/category_children.ts index c0f31ad83..566d0c790 100644 --- a/src/helpers/channels/category_children.ts +++ b/src/helpers/channels/category_children.ts @@ -1,8 +1,9 @@ -import { cache } from "../../cache.ts"; +import {Bot} from "../../bot.ts"; /** Gets an array of all the channels ids that are the children of this category. * ⚠️ This does not work for custom cache users! */ -export function categoryChildren(parentChannelId: bigint) { - return cache.channels.filter((channel) => channel.parentId === parentChannelId); +export function categoryChildren(bot: Bot, parentChannelId: bigint) { + // TODO: Cache Filter ? + return bot.cache.channels.filter((channel) => channel.parentId === parentChannelId); } diff --git a/src/helpers/channels/clone_channel.ts b/src/helpers/channels/clone_channel.ts index 70c2d41a6..1363011d7 100644 --- a/src/helpers/channels/clone_channel.ts +++ b/src/helpers/channels/clone_channel.ts @@ -1,18 +1,15 @@ -import { cacheHandlers } from "../../cache.ts"; +import type { Bot } from "../../bot.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import type { CreateGuildChannel } from "../../types/guilds/create_guild_channel.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { calculatePermissions } from "../../util/permissions.ts"; -import { helpers } from "../mod.ts"; /** Create a copy of a channel */ -export async function cloneChannel(channelId: bigint, reason?: string) { - const channelToClone = await cacheHandlers.get("channels", channelId); - if (!channelToClone) throw new Error(Errors.CHANNEL_NOT_FOUND); +export async function cloneChannel(bot: Bot, channelId: bigint, reason?: string) { + const channelToClone = await bot.cache.channels.get(channelId); + if (!channelToClone) throw new Error(bot.constants.Errors.CHANNEL_NOT_FOUND); //Check for DM channel if (channelToClone.type === DiscordChannelTypes.DM || channelToClone.type === DiscordChannelTypes.GroupDm) { - throw new Error(Errors.CHANNEL_NOT_IN_GUILD); + throw new Error(bot.constants.Errors.CHANNEL_NOT_IN_GUILD); } const createChannelOptions: CreateGuildChannel = { @@ -22,11 +19,11 @@ export async function cloneChannel(channelId: bigint, reason?: string) { permissionOverwrites: channelToClone.permissionOverwrites.map((overwrite) => ({ id: overwrite.id.toString(), type: overwrite.type, - allow: calculatePermissions(overwrite.allow), - deny: calculatePermissions(overwrite.deny), + allow: bot.utils.calculatePermissions(overwrite.allow), + deny: bot.utils.calculatePermissions(overwrite.deny), })), }; //Create the channel (also handles permissions) - return await helpers.createChannel(channelToClone.guildId!, createChannelOptions, reason); + return await bot.helpers.createChannel(bot, channelToClone.guildId!, createChannelOptions, reason); } diff --git a/src/helpers/channels/create_channel.ts b/src/helpers/channels/create_channel.ts index 0561f95c1..7e8f84b8f 100644 --- a/src/helpers/channels/create_channel.ts +++ b/src/helpers/channels/create_channel.ts @@ -1,39 +1,42 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Channel } from "../../types/channels/channel.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import type { CreateGuildChannel, DiscordCreateGuildChannel } from "../../types/guilds/create_guild_channel.ts"; -import { endpoints } from "../../util/constants.ts"; -import { calculateBits, requireOverwritePermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** Create a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */ -export async function createChannel(guildId: bigint, options?: CreateGuildChannel, reason?: string) { - if (options?.permissionOverwrites) { - await requireOverwritePermissions(guildId, options.permissionOverwrites); - } +export async function createChannel(bot: Bot, guildId: bigint, options?: CreateGuildChannel, reason?: string) { + if (options?.permissionOverwrites) { + await bot.utils.requireOverwritePermissions(bot, guildId, options.permissionOverwrites); + } - // BITRATES ARE IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000 - if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000; + // BITRATES ARE IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000 + if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000; - const result = await rest.runMethod( - "post", - endpoints.GUILD_CHANNELS(guildId), - snakelize({ - ...options, - permissionOverwrites: options?.permissionOverwrites?.map((perm) => ({ - ...perm, - allow: calculateBits(perm.allow), - deny: calculateBits(perm.deny), - })), - type: options?.type || DiscordChannelTypes.GuildText, - reason, - }) - ); + const result = await bot.rest.runMethod( + bot.rest, + "post", + bot.constants.endpoints.GUILD_CHANNELS(guildId), + options ? { + name: options.name, + topic: options.topic, + bitrate: options.bitrate, + userLimit: options.userLimit, + rateLimitPerUser: options.rateLimitPerUser, + position: options.position, + parentId: options.parentId, + nsfw: options.nsfw, + permission_overwrites: options?.permissionOverwrites?.map((perm) => ({ + ...perm, + allow: bot.utils.calculateBits(perm.allow), + deny: bot.utils.calculateBits(perm.deny), + })), + type: options?.type || DiscordChannelTypes.GuildText, + reason, + } : {} + ); - const discordenoChannel = await structures.createDiscordenoChannel(result); - await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); + const discordenoChannel = bot.transformers.channel(result); + await bot.cache.channels.set(discordenoChannel.id, discordenoChannel); - return discordenoChannel; + return discordenoChannel; } diff --git a/src/helpers/channels/create_stage_instance.ts b/src/helpers/channels/create_stage_instance.ts index 17728e9a0..bf0aaf56e 100644 --- a/src/helpers/channels/create_stage_instance.ts +++ b/src/helpers/channels/create_stage_instance.ts @@ -1,37 +1,32 @@ -import { validateLength } from "../../util/validate_length.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; -import { cacheHandlers } from "../../cache.ts"; +import type { Bot } from "../../bot.ts"; import { ChannelTypes } from "../../types/channels/channel_types.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; import { PrivacyLevel } from "../../types/channels/privacy_level.ts"; -import { snakelize } from "../../util/utils.ts"; /** Creates a new Stage instance associated to a Stage channel. Requires the user to be a moderator of the Stage channel. */ -export async function createStageInstance(channelId: bigint, topic: string, privacyLevel?: PrivacyLevel) { - const channel = await cacheHandlers.get("channels", channelId); +export async function createStageInstance(bot: Bot, channelId: bigint, topic: string, privacyLevel?: PrivacyLevel) { + const channel = await bot.cache.channels.get(channelId); if (channel) { if (channel.type !== ChannelTypes.GuildStageVoice) { - throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); + throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE); } - await requireBotChannelPermissions(channel, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]); + await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]); } - if (!validateLength(topic, { max: 120, min: 1 })) { - throw new Error(Errors.INVALID_TOPIC_LENGTH); + if (!bot.utils.validateLength(topic, { max: 120, min: 1 })) { + throw new Error(bot.constants.Errors.INVALID_TOPIC_LENGTH); } - return await rest.runMethod( + return await bot.rest.runMethod( + bot.rest, "post", - endpoints.STAGE_INSTANCES, - snakelize({ - channelId, + bot.constants.endpoints.STAGE_INSTANCES, + { + channel_id: channelId, topic, - privacyLevel, - }) + privacy_level: privacyLevel, + } ); } diff --git a/src/helpers/channels/delete_channel.ts b/src/helpers/channels/delete_channel.ts index c9df3bcc1..1a6379303 100644 --- a/src/helpers/channels/delete_channel.ts +++ b/src/helpers/channels/delete_channel.ts @@ -1,27 +1,23 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */ -export async function deleteChannel(channelId: bigint, reason?: string) { +export async function deleteChannel(bot: Bot, channelId: bigint, reason?: string) { const channel = await cacheHandlers.get("channels", channelId); if (channel?.guildId) { const guild = await cacheHandlers.get("guilds", channel.guildId); - if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); + if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND); if (guild.rulesChannelId === channelId) { - throw new Error(Errors.RULES_CHANNEL_CANNOT_BE_DELETED); + throw new Error(bot.constants.Errors.RULES_CHANNEL_CANNOT_BE_DELETED); } if (guild.publicUpdatesChannelId === channelId) { - throw new Error(Errors.UPDATES_CHANNEL_CANNOT_BE_DELETED); + throw new Error(bot.constants.Errors.UPDATES_CHANNEL_CANNOT_BE_DELETED); } - await requireBotGuildPermissions(guild, ["MANAGE_CHANNELS"]); + await bot.utils.requireBotGuildPermissions(bot, guild, ["MANAGE_CHANNELS"]); } - return await rest.runMethod("delete", endpoints.CHANNEL_BASE(channelId), { reason }); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.CHANNEL_BASE(channelId), { reason }); } diff --git a/src/helpers/channels/delete_channel_overwrite.ts b/src/helpers/channels/delete_channel_overwrite.ts index 40dd141f7..0f5d66ec8 100644 --- a/src/helpers/channels/delete_channel_overwrite.ts +++ b/src/helpers/channels/delete_channel_overwrite.ts @@ -1,14 +1,13 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Delete the channel permission overwrites for a user or role in this channel. Requires `MANAGE_ROLES` permission. */ export async function deleteChannelOverwrite( + bot: Bot, guildId: bigint, channelId: bigint, overwriteId: bigint ): Promise { - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - return await rest.runMethod("delete", endpoints.CHANNEL_OVERWRITE(channelId, overwriteId)); + return await bot.rest.runMethod(bot.rest,"delete", bot.constants.endpoints.CHANNEL_OVERWRITE(channelId, overwriteId)); } diff --git a/src/helpers/channels/delete_stage_instance.ts b/src/helpers/channels/delete_stage_instance.ts index 735da6353..c8fb9e4c0 100644 --- a/src/helpers/channels/delete_stage_instance.ts +++ b/src/helpers/channels/delete_stage_instance.ts @@ -1,21 +1,17 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; import { ChannelTypes } from "../../types/channels/channel_types.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Deletes the Stage instance. Requires the user to be a moderator of the Stage channel. */ -export async function deleteStageInstance(channelId: bigint) { - const channel = await cacheHandlers.get("channels", channelId); +export async function deleteStageInstance(bot: Bot, channelId: bigint) { + const channel = await bot.cache.channels.get(channelId); if (channel) { if (channel.type !== ChannelTypes.GuildStageVoice) { - throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); + throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE); } - await requireBotChannelPermissions(channel, ["MUTE_MEMBERS", "MANAGE_CHANNELS", "MOVE_MEMBERS"]); + await bot.utils.requireBotChannelPermissions(bot, channel, ["MUTE_MEMBERS", "MANAGE_CHANNELS", "MOVE_MEMBERS"]); } - return await rest.runMethod("delete", endpoints.STAGE_INSTANCE(channelId)); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.STAGE_INSTANCE(channelId)); } diff --git a/src/helpers/channels/edit_channel.ts b/src/helpers/channels/edit_channel.ts index 05e577954..e7e4defe3 100644 --- a/src/helpers/channels/edit_channel.ts +++ b/src/helpers/channels/edit_channel.ts @@ -1,21 +1,16 @@ -import { eventHandlers } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; import type { DiscordenoChannel } from "../../structures/channel.ts"; -import { structures } from "../../structures/mod.ts"; import type { Channel } from "../../types/channels/channel.ts"; import type { ModifyChannel } from "../../types/channels/modify_channel.ts"; -import { endpoints } from "../../util/constants.ts"; -import { calculateBits, requireOverwritePermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import {SnakeCasedPropertiesDeep} from "../../types/util.ts"; /** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */ -export async function editChannel(channelId: bigint, options: ModifyChannel, reason?: string) { - const channel = await cacheHandlers.get("channels", channelId); +export async function editChannel(bot: Bot, channelId: bigint, options: ModifyChannel, reason?: string) { + const channel = await bot.cache.channels.get(channelId); if (channel) { if (options.permissionOverwrites && Array.isArray(options.permissionOverwrites)) { - await requireOverwritePermissions(channel.guildId, options.permissionOverwrites); + await bot.utils.requireOverwritePermissions(bot, channel.guildId, options.permissionOverwrites); } } @@ -40,16 +35,25 @@ export async function editChannel(channelId: bigint, options: ModifyChannel, rea request.items.push({ channelId, options, resolve, reject }); if (editChannelProcessing) return; editChannelProcessing = true; - processEditChannelQueue(); + processEditChannelQueue(bot); }); } } - const result = await rest.runMethod( + const result = await bot.rest.runMethod>( + bot.rest, "patch", - endpoints.CHANNEL_BASE(channelId), - snakelize({ - ...options, + bot.constants.endpoints.CHANNEL_BASE(channelId), + { + name: options.name, + topic: options.topic, + bitrate: options.bitrate, + userLimit: options.userLimit, + rateLimitPerUser: options.rateLimitPerUser, + position: options.position, + parentId: options.parentId, + nsfw: options.nsfw, + type: options.type, permissionOverwrites: options.permissionOverwrites ? options.permissionOverwrites?.map((overwrite) => { return { @@ -60,10 +64,10 @@ export async function editChannel(channelId: bigint, options: ModifyChannel, rea }) : undefined, reason, - }) + } ); - return await structures.createDiscordenoChannel(result); + return bot.transformers.channel(result); } interface EditChannelRequest { @@ -82,7 +86,7 @@ interface EditChannelRequest { const editChannelNameTopicQueue = new Map(); let editChannelProcessing = false; -function processEditChannelQueue() { +function processEditChannelQueue(bot: Bot) { if (!editChannelProcessing) return; const now = Date.now(); @@ -99,13 +103,13 @@ function processEditChannelQueue() { if (!details) return; - await editChannel(details.channelId, details.options) + await bot.helpers.editChannel(bot, details.channelId, details.options) .then((result) => details.resolve(result)) .catch(details.reject); const secondDetails = request.items.shift(); if (!secondDetails) return; - await editChannel(secondDetails.channelId, secondDetails.options) + await bot.helpers.editChannel(bot, secondDetails.channelId, secondDetails.options) .then((result) => secondDetails.resolve(result)) .catch(secondDetails.reject); return; @@ -114,7 +118,7 @@ function processEditChannelQueue() { if (editChannelNameTopicQueue.size) { setTimeout(() => { eventHandlers.debug?.("loop", `Running setTimeout in EDIT_CHANNEL file.`); - processEditChannelQueue(); + processEditChannelQueue(bot); }, 60000); } else { editChannelProcessing = false; diff --git a/src/helpers/channels/edit_channel_overwrite.ts b/src/helpers/channels/edit_channel_overwrite.ts index c9b6c2db7..bcfe5cf9d 100644 --- a/src/helpers/channels/edit_channel_overwrite.ts +++ b/src/helpers/channels/edit_channel_overwrite.ts @@ -1,20 +1,19 @@ -import { rest } from "../../rest/rest.ts"; import type { Overwrite } from "../../types/channels/overwrite.ts"; -import { endpoints } from "../../util/constants.ts"; -import { calculateBits, requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Edit the channel permission overwrites for a user or role in this channel. Requires `MANAGE_ROLES` permission. */ export async function editChannelOverwrite( + bot: Bot, guildId: bigint, channelId: bigint, overwriteId: bigint, options: Omit ): Promise { - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - return await rest.runMethod("put", endpoints.CHANNEL_OVERWRITE(channelId, overwriteId), { - allow: calculateBits(options.allow), - deny: calculateBits(options.deny), + return await bot.rest.runMethod(bot.rest,"put", bot.constants.endpoints.CHANNEL_OVERWRITE(channelId, overwriteId), { + allow: bot.utils.calculateBits(options.allow), + deny: bot.utils.calculateBits(options.deny), type: options.type, }); } diff --git a/src/helpers/channels/follow_channel.ts b/src/helpers/channels/follow_channel.ts index bd9d7d6ad..9512f4b29 100644 --- a/src/helpers/channels/follow_channel.ts +++ b/src/helpers/channels/follow_channel.ts @@ -1,13 +1,11 @@ -import { rest } from "../../rest/rest.ts"; import type { FollowedChannel } from "../../types/channels/followed_channel.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Follow a News Channel to send messages to a target channel. Requires the `MANAGE_WEBHOOKS` permission in the target channel. Returns the webhook id. */ -export async function followChannel(sourceChannelId: bigint, targetChannelId: bigint) { - await requireBotChannelPermissions(targetChannelId, ["MANAGE_WEBHOOKS"]); +export async function followChannel(bot: Bot, sourceChannelId: bigint, targetChannelId: bigint) { + await bot.utils.requireBotChannelPermissions(bot, targetChannelId, ["MANAGE_WEBHOOKS"]); - const data = await rest.runMethod("post", endpoints.CHANNEL_FOLLOW(sourceChannelId), { + const data = await bot.rest.runMethod(bot.rest,"post", bot.constants.endpoints.CHANNEL_FOLLOW(sourceChannelId), { webhook_channel_id: targetChannelId, }); diff --git a/src/helpers/channels/get_channel.ts b/src/helpers/channels/get_channel.ts index 3b14c40c4..6866a1cf8 100644 --- a/src/helpers/channels/get_channel.ts +++ b/src/helpers/channels/get_channel.ts @@ -1,23 +1,21 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; +import type { Bot } from "../../bot.ts"; import type { Channel } from "../../types/channels/channel.ts"; -import { snowflakeToBigint } from "../../util/bigint.ts"; -import { endpoints } from "../../util/constants.ts"; /** Fetches a single channel object from the api. * * ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your channels will be cached in your guild.** */ -export async function getChannel(channelId: bigint, addToCache = true) { - const result = await rest.runMethod("get", endpoints.CHANNEL_BASE(channelId)); +export async function getChannel(bot: Bot, channelId: bigint, addToCache = true) { + const result = await bot.rest.runMethod(bot.rest,"get", bot.constants.endpoints.CHANNEL_BASE(channelId)); - const discordenoChannel = await structures.createDiscordenoChannel( - result, - result.guildId ? snowflakeToBigint(result.guildId) : undefined + const discordenoChannel = bot.transformers.channel( + { + channel: result, + guildId: result.guildId ? bot.transformers.snowflake(result.guildId) : undefined + } ); if (addToCache) { - await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); + await bot.cache.channels.set(discordenoChannel.id, discordenoChannel); } return discordenoChannel; diff --git a/src/helpers/channels/get_channel_webhooks.ts b/src/helpers/channels/get_channel_webhooks.ts index fc1bac9cb..99da26ab1 100644 --- a/src/helpers/channels/get_channel_webhooks.ts +++ b/src/helpers/channels/get_channel_webhooks.ts @@ -1,14 +1,12 @@ -import { rest } from "../../rest/rest.ts"; import type { Webhook } from "../../types/webhooks/webhook.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Gets the webhooks for this channel. Requires MANAGE_WEBHOOKS */ -export async function getChannelWebhooks(channelId: bigint) { - await requireBotChannelPermissions(channelId, ["MANAGE_WEBHOOKS"]); +export async function getChannelWebhooks(bot: Bot, channelId: bigint) { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]); - const result = await rest.runMethod("get", endpoints.CHANNEL_WEBHOOKS(channelId)); + const result = await bot.rest.runMethod(bot.rest,"get", bot.constants.endpoints.CHANNEL_WEBHOOKS(channelId)); return new Collection(result.map((webhook) => [webhook.id, webhook])); } diff --git a/src/helpers/channels/get_channels.ts b/src/helpers/channels/get_channels.ts index 30c78ecfd..49e9970d3 100644 --- a/src/helpers/channels/get_channels.ts +++ b/src/helpers/channels/get_channels.ts @@ -1,24 +1,21 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Channel } from "../../types/channels/channel.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Returns a list of guild channel objects. * * ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your channels will be cached in your guild.** */ -export async function getChannels(guildId: bigint, addToCache = true) { - const result = await rest.runMethod("get", endpoints.GUILD_CHANNELS(guildId)); +export async function getChannels(bot: Bot, guildId: bigint, addToCache = true) { + const result = await bot.rest.runMethod(bot.rest,"get", bot.constants.endpoints.GUILD_CHANNELS(guildId)); return new Collection( ( await Promise.all( result.map(async (res) => { - const discordenoChannel = await structures.createDiscordenoChannel(res, guildId); + const discordenoChannel = await bot.transformers.channel({channel: res, guildId}); if (addToCache) { - await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); + await bot.cache.channels.set(discordenoChannel.id, discordenoChannel); } return discordenoChannel; diff --git a/src/helpers/channels/get_pins.ts b/src/helpers/channels/get_pins.ts index 1b58916c1..97c8ef1d5 100644 --- a/src/helpers/channels/get_pins.ts +++ b/src/helpers/channels/get_pins.ts @@ -1,11 +1,9 @@ -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Message } from "../../types/messages/message.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Get pinned messages in this channel. */ -export async function getPins(channelId: bigint) { - const result = await rest.runMethod("get", endpoints.CHANNEL_PINS(channelId)); +export async function getPins(bot: Bot, channelId: bigint) { + const result = await bot.rest.runMethod(bot.rest,"get", bot.constants.endpoints.CHANNEL_PINS(channelId)); - return Promise.all(result.map((res) => structures.createDiscordenoMessage(res))); + return result.map(bot.transformers.message); } diff --git a/src/helpers/channels/get_stage_instance.ts b/src/helpers/channels/get_stage_instance.ts index 5a3b4e633..bfb727e31 100644 --- a/src/helpers/channels/get_stage_instance.ts +++ b/src/helpers/channels/get_stage_instance.ts @@ -1,19 +1,16 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { ChannelTypes } from "../../types/channels/channel_types.ts"; +import type { ChannelTypes } from "../../types/channels/channel_types.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Gets the stage instance associated with the Stage channel, if it exists. */ -export async function getStageInstance(channelId: bigint) { - const channel = await cacheHandlers.get("channels", channelId); +export async function getStageInstance(bot: Bot, channelId: bigint) { + const channel = await bot.cache.channels.get(channelId); if (channel) { if (channel.type !== ChannelTypes.GuildStageVoice) { - throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); + throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE); } } - return await rest.runMethod("get", endpoints.STAGE_INSTANCE(channelId)); + return await bot.rest.runMethod(bot.rest,"get", bot.constants.endpoints.STAGE_INSTANCE(channelId)); } diff --git a/src/helpers/channels/is_channel_synced.ts b/src/helpers/channels/is_channel_synced.ts index ed6798f78..b3c4c2a03 100644 --- a/src/helpers/channels/is_channel_synced.ts +++ b/src/helpers/channels/is_channel_synced.ts @@ -1,11 +1,11 @@ -import { cacheHandlers } from "../../cache.ts"; +import type { Bot } from "../../bot.ts"; /** Checks whether a channel is synchronized with its parent/category channel or not. */ -export async function isChannelSynced(channelId: bigint) { - const channel = await cacheHandlers.get("channels", channelId); +export async function isChannelSynced(bot: Bot, channelId: bigint) { + const channel = await bot.cache.channels.get(channelId); if (!channel?.parentId) return false; - const parentChannel = await cacheHandlers.get("channels", channel.parentId); + const parentChannel = await bot.cache.channels.get(channel.parentId); if (!parentChannel) return false; return channel.permissionOverwrites?.every((overwrite) => { diff --git a/src/helpers/channels/start_typing.ts b/src/helpers/channels/start_typing.ts index 5fd7a922e..6999e6cec 100644 --- a/src/helpers/channels/start_typing.ts +++ b/src/helpers/channels/start_typing.ts @@ -1,17 +1,13 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { botHasChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** * Trigger a typing indicator for the specified channel. Generally bots should **NOT** implement this route. * However, if a bot is responding to a command and expects the computation to take a few seconds, * this endpoint may be called to let the user know that the bot is processing their message. */ -export async function startTyping(channelId: bigint) { - const channel = await cacheHandlers.get("channels", channelId); +export async function startTyping(bot: Bot, channelId: bigint) { + const channel = await bot.cache.channels.get(channelId); // If the channel is cached, we can do extra checks/safety if (channel) { if ( @@ -24,14 +20,14 @@ export async function startTyping(channelId: bigint) { DiscordChannelTypes.GuildPublicThread, ].includes(channel.type) ) { - throw new Error(Errors.CHANNEL_NOT_TEXT_BASED); + throw new Error(bot.constants.Errors.CHANNEL_NOT_TEXT_BASED); } - const hasSendMessagesPerm = await botHasChannelPermissions(channelId, ["SEND_MESSAGES"]); + const hasSendMessagesPerm = await bot.utils.botHasChannelPermissions(bots, channelId, ["SEND_MESSAGES"]); if (!hasSendMessagesPerm) { - throw new Error(Errors.MISSING_SEND_MESSAGES); + throw new Error(bot.constants.Errors.MISSING_SEND_MESSAGES); } } - return await rest.runMethod("post", endpoints.CHANNEL_TYPING(channelId)); + return await bot.rest.runMethod(bot.rest,"post", bot.constants.endpoints.CHANNEL_TYPING(channelId)); } diff --git a/src/helpers/channels/swap_channels.ts b/src/helpers/channels/swap_channels.ts index cc515e159..22618b7a0 100644 --- a/src/helpers/channels/swap_channels.ts +++ b/src/helpers/channels/swap_channels.ts @@ -1,13 +1,18 @@ -import { rest } from "../../rest/rest.ts"; import type { ModifyGuildChannelPositions } from "../../types/guilds/modify_guild_channel_position.ts"; -import { endpoints } from "../../util/constants.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; -/** Modify the positions of channels on the guild. Requires MANAGE_CHANNELS permisison. */ -export async function swapChannels(guildId: bigint, channelPositions: ModifyGuildChannelPositions[]) { +/** Modify the positions of channels on the guild. Requires MANAGE_CHANNELS permission. */ +export async function swapChannels(bot: Bot, guildId: bigint, channelPositions: ModifyGuildChannelPositions[]) { if (channelPositions.length < 2) { throw "You must provide at least two channels to be swapped."; } - return await rest.runMethod("patch", endpoints.GUILD_CHANNELS(guildId), snakelize(channelPositions)); + return await bot.rest.runMethod(bot.rest,"patch", bot.constants.endpoints.GUILD_CHANNELS(guildId), channelPositions.map((channelPosition) => { + return { + id: channelPosition.id, + position: channelPosition.position, + lock_positions: channelPosition.lockPositions, + parent_id: channelPosition.parentId + } + })); } diff --git a/src/helpers/channels/threads/add_to_thread.ts b/src/helpers/channels/threads/add_to_thread.ts index 520ad7c1e..7a59e6f2f 100644 --- a/src/helpers/channels/threads/add_to_thread.ts +++ b/src/helpers/channels/threads/add_to_thread.ts @@ -1,22 +1,18 @@ -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../../util/permissions.ts"; +import type { Bot } from "../../../bot.ts"; /** Adds a user to a thread. Requires the ability to send messages in the thread. Requires the thread is not archived. */ -export async function addToThread(threadId: bigint, userId: bigint) { - const thread = await cacheHandlers.get("threads", threadId); +export async function addToThread(bot: Bot, threadId: bigint, userId: bigint) { + const thread = await bot.cache.threads.get(threadId); if (thread) { if (thread.archived) { - throw new Error(Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS); + throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS); } // If a user id is provided SEND_MESSAGES is required. - const channel = await cacheHandlers.get("channels", thread.parentId); + const channel = await bot.cache.channels.get(thread.parentId); // TODO: does MANAGE_THREADS override this???? - if (channel) await requireBotChannelPermissions(channel, ["SEND_MESSAGES"]); + if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]); } - return await rest.runMethod("put", endpoints.THREAD_USER(threadId, userId)); + return await bot.rest.runMethod(bot.rest, "put", bot.constants.endpoints.THREAD_USER(threadId, userId)); } diff --git a/src/helpers/channels/threads/archive_thread.ts b/src/helpers/channels/threads/archive_thread.ts index cc3884546..42987c1a7 100644 --- a/src/helpers/channels/threads/archive_thread.ts +++ b/src/helpers/channels/threads/archive_thread.ts @@ -1,6 +1,6 @@ -import { editThread } from "./edit_thread.ts"; +import type { Bot } from "../../../bot.ts"; /** Sets a thread channel to be archived. */ -export async function archiveThread(threadId: bigint) { - return await editThread(threadId, { archived: true }); +export async function archiveThread(bot: Bot, threadId: bigint) { + return await bot.helpers.editThread(bot, threadId, { archived: true }); } diff --git a/src/helpers/channels/threads/delete_thread.ts b/src/helpers/channels/threads/delete_thread.ts index ea5d01ac3..2ed94ec8b 100644 --- a/src/helpers/channels/threads/delete_thread.ts +++ b/src/helpers/channels/threads/delete_thread.ts @@ -1,15 +1,14 @@ -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../../util/permissions.ts"; +import type { Bot } from "../../../bot.ts"; /** Delete a thread in your server. Bot needs MANAGE_THREADS permissions in the server. */ -export async function deleteThread(threadId: bigint, reason?: string) { - const thread = await cacheHandlers.get("threads", threadId); +export async function deleteThread(bot: Bot, threadId: bigint, reason?: string) { + const thread = await bot.cache.threads.get(threadId); if (thread) { - const channel = await cacheHandlers.get("channels", thread?.parentId); - if (channel?.guildId) await requireBotGuildPermissions(channel.guildId, ["MANAGE_THREADS"]); + const channel = await bot.cache.channels.get(thread?.parentId); + if (channel?.guildId) await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_THREADS"]); } - return await rest.runMethod("delete", endpoints.CHANNEL_BASE(threadId), { reason }); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.CHANNEL_BASE(threadId), { + reason, + }); } diff --git a/src/helpers/channels/threads/edit_thread.ts b/src/helpers/channels/threads/edit_thread.ts index 75a9a93bc..ef32fc3a9 100644 --- a/src/helpers/channels/threads/edit_thread.ts +++ b/src/helpers/channels/threads/edit_thread.ts @@ -1,23 +1,21 @@ -import { rest } from "../../../rest/rest.ts"; -import { ModifyThread } from "../../../types/channels/threads/modify_thread.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { ModifyThread } from "../../../types/channels/threads/modify_thread.ts"; +import type { Bot } from "../../../bot.ts"; import { channelToThread } from "../../../util/transformers/channel_to_thread.ts"; -import { snakelize } from "../../../util/utils.ts"; /** Update a thread's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */ -export async function editThread(threadId: bigint, options: ModifyThread, reason?: string) { +export async function editThread(bot: Bot, threadId: bigint, options: ModifyThread, reason?: string) { // const thread = await cacheHandlers.get("threads", threadId); // TODO: permission checking - const result = await rest.runMethod( - "patch", - endpoints.CHANNEL_BASE(threadId), - snakelize({ - ...options, - reason, - }) - ); + const result = await bot.rest.runMethod(bot.rest, "patch", bot.constants.endpoints.CHANNEL_BASE(threadId), { + name: options.name, + archived: options.archived, + auto_archive_duration: options.autoArchiveDuration, + locked: options.locked, + rate_limit_per_user: options.rateLimitPerUser, + reason, + }); return channelToThread(result); } diff --git a/src/helpers/channels/threads/get_active_threads.ts b/src/helpers/channels/threads/get_active_threads.ts index f1b7e9ef8..391edc336 100644 --- a/src/helpers/channels/threads/get_active_threads.ts +++ b/src/helpers/channels/threads/get_active_threads.ts @@ -1,17 +1,18 @@ -import { rest } from "../../../rest/rest.ts"; -import { ListActiveThreads } from "../../../types/channels/threads/list_active_threads.ts"; -import { snowflakeToBigint } from "../../../util/bigint.ts"; +import type { Bot } from "../../../bot.ts"; +import type { ListActiveThreads } from "../../../types/channels/threads/list_active_threads.ts"; import { Collection } from "../../../util/collection.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../../util/permissions.ts"; import { channelToThread } from "../../../util/transformers/channel_to_thread.ts"; /** Returns all active threads in the channel, including public and private threads. Threads are ordered by their id, in descending order. Requires the VIEW_CHANNEL permission. */ -export async function getActiveThreads(channelId: bigint) { - await requireBotChannelPermissions(channelId, ["VIEW_CHANNEL"]); +export async function getActiveThreads(bot: Bot, channelId: bigint) { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL"]); // TODO: pagination - const result = (await rest.runMethod("get", endpoints.THREAD_ACTIVE(channelId))) as ListActiveThreads; + const result = (await bot.rest.runMethod( + bot.rest, + "get", + bot.constants.endpoints.THREAD_ACTIVE(channelId) + )) as ListActiveThreads; const threads = new Collection( result.threads.map((t) => { @@ -21,9 +22,9 @@ export async function getActiveThreads(channelId: bigint) { ); for (const member of result.members) { - const thread = threads.get(snowflakeToBigint(member.id!)); - thread?.members.set(snowflakeToBigint(member.userId!), { - userId: snowflakeToBigint(member.userId!), + const thread = threads.get(bot.transformers.snowflake(member.id!)); + thread?.members.set(bot.transformers.snowflake(member.userId!), { + userId: bot.transformers.snowflake(member.userId!), flags: member.flags, joinTimestamp: Date.parse(member.joinTimestamp), }); diff --git a/src/helpers/channels/threads/get_archived_threads.ts b/src/helpers/channels/threads/get_archived_threads.ts index 7abd65291..329b2b6ac 100644 --- a/src/helpers/channels/threads/get_archived_threads.ts +++ b/src/helpers/channels/threads/get_archived_threads.ts @@ -1,16 +1,13 @@ -import { rest } from "../../../rest/rest.ts"; import { ListActiveThreads } from "../../../types/channels/threads/list_active_threads.ts"; import { ListPublicArchivedThreads } from "../../../types/channels/threads/list_public_archived_threads.ts"; import { PermissionStrings } from "../../../types/permissions/permission_strings.ts"; -import { snowflakeToBigint } from "../../../util/bigint.ts"; import { Collection } from "../../../util/collection.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../../util/permissions.ts"; +import type { Bot } from "../../../bot.ts"; import { channelToThread } from "../../../util/transformers/channel_to_thread.ts"; -import { snakelize } from "../../../util/utils.ts"; /** Get the archived threads for this channel, defaults to public */ export async function getArchivedThreads( + bot: Bot, channelId: bigint, options?: ListPublicArchivedThreads & { type?: "public" | "private" | "privateJoinedThreads"; @@ -19,18 +16,25 @@ export async function getArchivedThreads( const permissions = new Set(["READ_MESSAGE_HISTORY"]); if (options?.type === "private") permissions.add("MANAGE_THREADS"); - await requireBotChannelPermissions(channelId, [...permissions]); + await bot.utils.requireBotChannelPermissions(bot, channelId, [...permissions]); // TODO: pagination - const result = (await rest.runMethod( + const result = (await bot.rest.runMethod( + bot.rest, "get", options?.type === "privateJoinedThreads" - ? endpoints.THREAD_ARCHIVED_PRIVATE_JOINED(channelId) + ? bot.constants.endpoints.THREAD_ARCHIVED_PRIVATE_JOINED(channelId) : options?.type === "private" - ? endpoints.THREAD_ARCHIVED_PRIVATE(channelId) - : endpoints.THREAD_ARCHIVED_PUBLIC(channelId), - snakelize(options ?? {}) + ? bot.constants.endpoints.THREAD_ARCHIVED_PRIVATE(channelId) + : bot.constants.endpoints.THREAD_ARCHIVED_PUBLIC(channelId), + options + ? { + before: options.before, + limit: options.limit, + type: options.type, + } + : {} )) as ListActiveThreads; const threads = new Collection( @@ -41,9 +45,9 @@ export async function getArchivedThreads( ); for (const member of result.members) { - const thread = threads.get(snowflakeToBigint(member.id!)); - thread?.members.set(snowflakeToBigint(member.userId!), { - userId: snowflakeToBigint(member.userId!), + const thread = threads.get(bot.transformers.snowflake(member.id!)); + thread?.members.set(bot.transformers.snowflake(member.userId!), { + userId: bot.transformers.snowflake(member.userId!), flags: member.flags, joinTimestamp: Date.parse(member.joinTimestamp), }); diff --git a/src/helpers/channels/threads/get_thread_members.ts b/src/helpers/channels/threads/get_thread_members.ts index 202e9c81a..adba7691b 100644 --- a/src/helpers/channels/threads/get_thread_members.ts +++ b/src/helpers/channels/threads/get_thread_members.ts @@ -1,29 +1,30 @@ -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; +import type { Bot } from "../../../bot.ts"; import { ThreadMember } from "../../../types/channels/threads/thread_member.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; import { DiscordGatewayIntents } from "../../../types/gateway/gateway_intents.ts"; import { Collection } from "../../../util/collection.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { botHasChannelPermissions } from "../../../util/permissions.ts"; import { threadMemberModified } from "../../../util/transformers/thread_member_modified.ts"; -import { ws } from "../../../ws/ws.ts"; - /** Returns thread members objects that are members of the thread. */ -export async function getThreadMembers(threadId: bigint) { +export async function getThreadMembers(bot: Bot, threadId: bigint) { // Check if intents is not 0 as proxy ws won't set intents in other instances - if (ws.identifyPayload.intents && !(ws.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)) { - throw new Error(Errors.MISSING_INTENT_GUILD_MEMBERS); + if ( + bot.gateway.identifyPayload.intents && + !(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers) + ) { + throw new Error(bot.constants.Errors.MISSING_INTENT_GUILD_MEMBERS); } - const thread = await cacheHandlers.get("threads", threadId); + const thread = await bot.cache.threads.get(threadId); if (thread?.isPrivate) { - const channel = await cacheHandlers.get("channels", thread.parentId); - if (channel && !(await botHasChannelPermissions(channel, ["MANAGE_THREADS"])) && !thread.botIsMember) - throw new Error(Errors.CANNOT_GET_MEMBERS_OF_AN_UNJOINED_PRIVATE_THREAD); + const channel = await bot.cache.channels.get(thread.parentId); + if (channel && !(await bot.utils.botHasChannelPermissions(bot, channel, ["MANAGE_THREADS"])) && !thread.botIsMember) + throw new Error(bot.constants.Errors.CANNOT_GET_MEMBERS_OF_AN_UNJOINED_PRIVATE_THREAD); } - const result = await rest.runMethod("get", endpoints.THREAD_MEMBERS(threadId)); + const result = await bot.rest.runMethod( + bot.rest, + "get", + bot.constants.endpoints.THREAD_MEMBERS(threadId) + ); const members = result.map((member) => threadMemberModified(member)); diff --git a/src/helpers/channels/threads/join_thread.ts b/src/helpers/channels/threads/join_thread.ts index 815975de5..4bd636368 100644 --- a/src/helpers/channels/threads/join_thread.ts +++ b/src/helpers/channels/threads/join_thread.ts @@ -1,14 +1,11 @@ -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { Bot } from "../../../bot.ts"; /** Adds the bot to the thread. Cannot join an archived thread. */ -export async function joinThread(threadId: bigint) { - const thread = await cacheHandlers.get("threads", threadId); +export async function joinThread(bot: Bot, threadId: bigint) { + const thread = await bot.cache.threads.get(threadId); if (thread?.archived) { - throw new Error(Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS); + throw new Error(bot.contants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS); } - return await rest.runMethod("put", endpoints.THREAD_ME(threadId)); + return await bot.rest.runMethod(bot.rest, "put", bot.constants.endpoints.THREAD_ME(threadId)); } diff --git a/src/helpers/channels/threads/leave_thread.ts b/src/helpers/channels/threads/leave_thread.ts index 867727397..157868221 100644 --- a/src/helpers/channels/threads/leave_thread.ts +++ b/src/helpers/channels/threads/leave_thread.ts @@ -1,12 +1,9 @@ -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { Bot } from "../../../bot.ts"; /** Removes the bot from a thread. Requires the thread is not archived. */ -export async function leaveThread(threadId: bigint) { - const thread = await cacheHandlers.get("threads", threadId); - if (thread?.archived) throw new Error(Errors.CANNOT_LEAVE_ARCHIVED_THREAD); +export async function leaveThread(bot: Bot, threadId: bigint) { + const thread = await bot.cache.threads.get(threadId); + if (thread?.archived) throw new Error(bot.constants.Errors.CANNOT_LEAVE_ARCHIVED_THREAD); - return await rest.runMethod("delete", endpoints.THREAD_ME(threadId)); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.THREAD_ME(threadId)); } diff --git a/src/helpers/channels/threads/lock_thread.ts b/src/helpers/channels/threads/lock_thread.ts index 5a5ca9fae..681335733 100644 --- a/src/helpers/channels/threads/lock_thread.ts +++ b/src/helpers/channels/threads/lock_thread.ts @@ -1,6 +1,6 @@ -import { editThread } from "./edit_thread.ts"; +import type { Bot } from "../../../bot.ts"; /** Sets a thread channel to be locked. */ -export async function lockThread(threadId: bigint) { - return await editThread(threadId, { locked: true }); +export async function lockThread(bot: Bot, threadId: bigint) { + return await bot.utils.editThread(bot, threadId, { locked: true }); } diff --git a/src/helpers/channels/threads/remove_thread_member.ts b/src/helpers/channels/threads/remove_thread_member.ts index 8c338c95e..38c7ae646 100644 --- a/src/helpers/channels/threads/remove_thread_member.ts +++ b/src/helpers/channels/threads/remove_thread_member.ts @@ -1,21 +1,16 @@ -import { botId } from "../../../bot.ts"; -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../../util/permissions.ts"; +import type { Bot } from "../../../bot.ts"; /** Removes a user from a thread. Requires the MANAGE_THREADS permission or that you are the creator of the thread. Also requires the thread is not archived. */ -export async function removeThreadMember(threadId: bigint, userId: bigint) { - const thread = await cacheHandlers.get("threads", threadId); +export async function removeThreadMember(bot: Bot, threadId: bigint, userId: bigint) { + const thread = await bot.cache.threads.get(threadId); if (thread) { - if (thread.archived) throw new Error(Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD); + if (thread.archived) throw new Error(bot.constants.Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD); - if (thread.ownerId !== botId) { - const channel = await cacheHandlers.get("channels", thread.parentId); - if (channel) await requireBotChannelPermissions(channel, ["MANAGE_THREADS"]); + if (thread.ownerId !== bot.id) { + const channel = await bot.cache.channels.get(thread.parentId); + if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_THREADS"]); } } - return await rest.runMethod("delete", endpoints.THREAD_USER(threadId, userId)); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.THREAD_USER(threadId, userId)); } diff --git a/src/helpers/channels/threads/start_private_thread.ts b/src/helpers/channels/threads/start_private_thread.ts index d4653df80..ca1b65ef1 100644 --- a/src/helpers/channels/threads/start_private_thread.ts +++ b/src/helpers/channels/threads/start_private_thread.ts @@ -1,25 +1,23 @@ -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; -import { Channel } from "../../../types/channels/channel.ts"; -import { StartThread } from "../../../types/channels/threads/start_thread.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../../util/permissions.ts"; +import type { Channel } from "../../../types/channels/channel.ts"; +import type { StartThread } from "../../../types/channels/threads/start_thread.ts"; +import type { Bot } from "../../../bot.ts"; import { channelToThread } from "../../../util/transformers/channel_to_thread.ts"; -import { snakelize } from "../../../util/utils.ts"; /** Creates a new private thread. Returns a thread channel. */ -export async function startPrivateThread(channelId: bigint, options: StartThread) { - const channel = await cacheHandlers.get("channels", channelId); +export async function startPrivateThread(bot: Bot, channelId: bigint, options: StartThread) { + const channel = await bot.cache.channels.get(channelId); if (channel) { - if (!channel.isGuildTextBasedChannel) throw new Error(Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE); + if (!channel.isGuildTextBasedChannel) throw new Error(bot.constants.Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE); - if (channel.isNewsChannel) throw new Error(Errors.GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS); + if (channel.isNewsChannel) throw new Error(bot.constants.Errors.GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS); - await requireBotChannelPermissions(channel, ["SEND_MESSAGES", "USE_PRIVATE_THREADS"]); + await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES", "USE_PRIVATE_THREADS"]); } return channelToThread( - await rest.runMethod("post", endpoints.THREAD_START_PRIVATE(channelId), snakelize(options)) + await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.THREAD_START_PRIVATE(channelId), { + name: options.name, + auto_archive_duration: options.autoArchiveDuration, + }) ); } diff --git a/src/helpers/channels/threads/start_thread.ts b/src/helpers/channels/threads/start_thread.ts index 557e7d2f0..4f820d8c0 100644 --- a/src/helpers/channels/threads/start_thread.ts +++ b/src/helpers/channels/threads/start_thread.ts @@ -1,25 +1,28 @@ -import { cacheHandlers } from "../../../cache.ts"; -import { rest } from "../../../rest/rest.ts"; -import { Channel } from "../../../types/channels/channel.ts"; -import { StartThread } from "../../../types/channels/threads/start_thread.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../../util/permissions.ts"; +import type { Channel } from "../../../types/channels/channel.ts"; +import type { StartThread } from "../../../types/channels/threads/start_thread.ts"; +import type { Bot } from "../../../bot.ts"; import { channelToThread } from "../../../util/transformers/channel_to_thread.ts"; -import { snakelize } from "../../../util/utils.ts"; /** Creates a new public thread from an existing message. Returns a thread channel. */ -export async function startThread(channelId: bigint, messageId: bigint, options: StartThread) { - const channel = await cacheHandlers.get("channels", channelId); +export async function startThread(bot: Bot, channelId: bigint, messageId: bigint, options: StartThread) { + const channel = await bot.cache.channels.get(channelId); if (channel) { if (!channel.isGuildTextBasedChannel) { - throw new Error(Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE); + throw new Error(bot.constants.Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE); } - await requireBotChannelPermissions(channel, ["SEND_MESSAGES", "USE_PUBLIC_THREADS"]); + await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES", "USE_PUBLIC_THREADS"]); } return channelToThread( - await rest.runMethod("post", endpoints.THREAD_START_PUBLIC(channelId, messageId), snakelize(options)) + await bot.rest.runMethod( + bot.rest, + "post", + bot.constants.endpoints.THREAD_START_PUBLIC(channelId, messageId), + { + name: options.name, + auto_archive_duration: options.autoArchiveDuration, + } + ) ); } diff --git a/src/helpers/channels/threads/unarchive_thread.ts b/src/helpers/channels/threads/unarchive_thread.ts index d80a56885..4bc5c14ee 100644 --- a/src/helpers/channels/threads/unarchive_thread.ts +++ b/src/helpers/channels/threads/unarchive_thread.ts @@ -1,6 +1,6 @@ -import { editThread } from "./edit_thread.ts"; +import type { Bot } from "../../../bot.ts"; /** Sets a thread channel to be unarchived. */ -export async function unarchiveThread(threadId: bigint) { - return await editThread(threadId, { archived: false }); +export async function unarchiveThread(bot: Bot, threadId: bigint) { + return await bot.helpers.editThread(bot, threadId, { archived: false }); } diff --git a/src/helpers/channels/threads/unlock_thread.ts b/src/helpers/channels/threads/unlock_thread.ts index 277713aec..5e3b08396 100644 --- a/src/helpers/channels/threads/unlock_thread.ts +++ b/src/helpers/channels/threads/unlock_thread.ts @@ -1,6 +1,6 @@ -import { editThread } from "./edit_thread.ts"; +import type { Bot } from "../../../bot.ts"; /** Sets a thread channel to be unlocked. */ -export async function unlockThread(threadId: bigint) { - return await editThread(threadId, { locked: false }); +export async function unlockThread(bot: Bot, threadId: bigint) { + return await bot.helpers.editThread(bot, threadId, { locked: false }); } diff --git a/src/helpers/channels/update_stage_instance.ts b/src/helpers/channels/update_stage_instance.ts index c0cbe8e31..4a98472ed 100644 --- a/src/helpers/channels/update_stage_instance.ts +++ b/src/helpers/channels/update_stage_instance.ts @@ -1,37 +1,35 @@ -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts"; -import { endpoints } from "../../util/constants.ts"; -import { validateLength } from "../../util/validate_length.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { ChannelTypes } from "../../types/channels/channel_types.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import type { ChannelTypes } from "../../types/channels/channel_types.ts"; /** Updates fields of an existing Stage instance. Requires the user to be a moderator of the Stage channel. */ export async function updateStageInstance( + bot: Bot, channelId: bigint, data: Partial> = {} ) { - const channel = await cacheHandlers.get("channels", channelId); + const channel = await bot.cache.channels.get(channelId); if (channel) { if (channel.type !== ChannelTypes.GuildStageVoice) { - throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); + throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE); } - await requireBotChannelPermissions(channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]); + await bot.utils.requireBotChannelPermissions(channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]); } if ( data?.topic && - !validateLength(data.topic, { + !bot.utils.validateLength(data.topic, { min: 1, max: 120, }) ) { - throw new Error(Errors.INVALID_TOPIC_LENGTH); + throw new Error(bot.constants.Errors.INVALID_TOPIC_LENGTH); } - return await rest.runMethod("patch", endpoints.STAGE_INSTANCE(channelId), snakelize(data)); + return await bot.rest.runMethod(bot.rest,"patch", bot.constants.endpoints.STAGE_INSTANCE(channelId), { + topic: data.topic, + privacy_level: data.privacyLevel + }); } diff --git a/src/helpers/channels/update_voice_state.ts b/src/helpers/channels/update_voice_state.ts index f2e37f9cf..7960733ae 100644 --- a/src/helpers/channels/update_voice_state.ts +++ b/src/helpers/channels/update_voice_state.ts @@ -1,8 +1,6 @@ -import { rest } from "../../rest/rest.ts"; -import { UpdateOthersVoiceState } from "../../types/guilds/update_others_voice_state.ts"; +import type { UpdateOthersVoiceState } from "../../types/guilds/update_others_voice_state.ts"; import type { UpdateSelfVoiceState } from "../../types/guilds/update_self_voice_state.ts"; -import { endpoints } from "../../util/constants.ts"; -import { hasOwnProperty, snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** * Updates the a user's voice state, defaults to the current user @@ -19,9 +17,15 @@ export async function updateBotVoiceState( guildId: bigint, options: UpdateSelfVoiceState | ({ userId: bigint } & UpdateOthersVoiceState) ) { - return await rest.runMethod( + return await bot.rest.runMethod( + bot.rest, "patch", - endpoints.UPDATE_VOICE_STATE(guildId, hasOwnProperty(options, "userId") ? options.userId : undefined), - snakelize(options) + bot.constants.endpoints.UPDATE_VOICE_STATE(guildId, bot.utils.hasOwnProperty(options, "userId") ? options.userId : undefined), + { + channel_id: options.channelId, + suppress: options.suppress, + request_to_speak_timestamp: options.requestToSpeakTimestamp, + user_id: options.userId + } ); } diff --git a/src/helpers/discovery/add_discovery_subcategory.ts b/src/helpers/discovery/add_discovery_subcategory.ts index 038431dcf..f960f91c6 100644 --- a/src/helpers/discovery/add_discovery_subcategory.ts +++ b/src/helpers/discovery/add_discovery_subcategory.ts @@ -1,14 +1,14 @@ -import { rest } from "../../rest/rest.ts"; import type { AddGuildDiscoverySubcategory } from "../../types/discovery/add_guild_discovery_subcategory.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Add a discovery subcategory to the guild. Requires the `MANAGE_GUILD` permission. */ -export async function addDiscoverySubcategory(guildId: bigint, categoryId: number) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function addDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - return await rest.runMethod( + return await bot.rest.runMethod>( + bot.rest, "post", - endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId) + bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId) ); } diff --git a/src/helpers/discovery/edit_discovery.ts b/src/helpers/discovery/edit_discovery.ts index d894477df..f71e07df0 100644 --- a/src/helpers/discovery/edit_discovery.ts +++ b/src/helpers/discovery/edit_discovery.ts @@ -1,13 +1,20 @@ -import { rest } from "../../rest/rest.ts"; import type { DiscoveryMetadata } from "../../types/discovery/discovery_metadata.ts"; import type { ModifyGuildDiscoveryMetadata } from "../../types/discovery/modify_guild_discovery_metadata.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; +import type { Bot } from "../../bot.ts"; /** Modify the discovery metadata for the guild. Requires the MANAGE_GUILD permission. Returns the updated discovery metadata object on success. */ -export async function editDiscovery(guildId: bigint, data: ModifyGuildDiscoveryMetadata) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function editDiscovery(bot: Bot, guildId: bigint, data: ModifyGuildDiscoveryMetadata) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - return await rest.runMethod("patch", endpoints.DISCOVERY_METADATA(guildId), snakelize(data)); + return await bot.rest.runMethod>( + bot.rest, + "patch", + bot.constants.endpoints.DISCOVERY_METADATA(guildId), + { + primary_category_id: data.primaryCategoryId, + keywords: data.keywords, + emoji_discoverability_enabled: data.emojiDiscoverabilityEnabled, + } + ); } diff --git a/src/helpers/discovery/get_discovery.ts b/src/helpers/discovery/get_discovery.ts index 967235fa2..746e815ee 100644 --- a/src/helpers/discovery/get_discovery.ts +++ b/src/helpers/discovery/get_discovery.ts @@ -1,11 +1,14 @@ -import { rest } from "../../rest/rest.ts"; import type { DiscoveryMetadata } from "../../types/discovery/discovery_metadata.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; +import type { Bot } from "../../bot.ts"; /** Returns the discovery metadata object for the guild. Requires the `MANAGE_GUILD` permission. */ -export async function getDiscovery(guildId: bigint) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function getDiscovery(bot: Bot, guildId: bigint) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - return await rest.runMethod("get", endpoints.DISCOVERY_METADATA(guildId)); + return await bot.rest.runMethod>( + bot.rest, + "get", + bot.constants.endpoints.DISCOVERY_METADATA(guildId) + ); } diff --git a/src/helpers/discovery/get_discovery_categories.ts b/src/helpers/discovery/get_discovery_categories.ts index 012bafb64..d8af16d77 100644 --- a/src/helpers/discovery/get_discovery_categories.ts +++ b/src/helpers/discovery/get_discovery_categories.ts @@ -1,11 +1,17 @@ -import { rest } from "../../rest/rest.ts"; import type { DiscoveryCategory } from "../../types/discovery/discovery_category.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Returns a Collection (mapped by Id of the discovery category object) of discovery category objects that can be used when editing guilds */ -export async function getDiscoveryCategories() { - const result = await rest.runMethod("get", endpoints.DISCOVERY_CATEGORIES); +export async function getDiscoveryCategories(bot: Bot) { + const result = await bot.rest.runMethod[]>( + bot.rest, + "get", + bot.constants.endpoints.DISCOVERY_CATEGORIES + ); - return new Collection(result.map((category) => [category.id, category])); + return new Collection>( + result.map((category) => [category.id, category]) + ); } diff --git a/src/helpers/discovery/remove_discovery_subcategory.ts b/src/helpers/discovery/remove_discovery_subcategory.ts index aaa9f219c..38fee53f0 100644 --- a/src/helpers/discovery/remove_discovery_subcategory.ts +++ b/src/helpers/discovery/remove_discovery_subcategory.ts @@ -1,10 +1,12 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Removes a discovery subcategory from the guild. Requires the MANAGE_GUILD permission. Returns a 204 No Content on success. */ -export async function removeDiscoverySubcategory(guildId: bigint, categoryId: number) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function removeDiscoverySubcategory(bot: Bot, guildId: bigint, categoryId: number) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - return await rest.runMethod("delete", endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId)); + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.DISCOVERY_SUBCATEGORY(guildId, categoryId) + ); } diff --git a/src/helpers/discovery/valid_discovery_term.ts b/src/helpers/discovery/valid_discovery_term.ts index 9e2a850f6..883d274ac 100644 --- a/src/helpers/discovery/valid_discovery_term.ts +++ b/src/helpers/discovery/valid_discovery_term.ts @@ -1,9 +1,13 @@ -import { rest } from "../../rest/rest.ts"; import type { ValidateDiscoverySearchTerm } from "../../types/discovery/validate_discovery_search_term.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -export async function validDiscoveryTerm(term: string) { - const result = await rest.runMethod("get", endpoints.DISCOVERY_VALID_TERM, { term }); +export async function validDiscoveryTerm(bot: Bot, term: string) { + const result = await bot.rest.runMethod>( + "get", + bot.constants.endpoints.DISCOVERY_VALID_TERM, + { term } + ); return result.valid; } diff --git a/src/helpers/emojis/create_emoji.ts b/src/helpers/emojis/create_emoji.ts index e16adbe5d..ec1b518f3 100644 --- a/src/helpers/emojis/create_emoji.ts +++ b/src/helpers/emojis/create_emoji.ts @@ -1,27 +1,28 @@ -import { rest } from "../../rest/rest.ts"; -import { CreateGuildEmoji } from "../../types/emojis/create_guild_emoji.ts"; +import type { CreateGuildEmoji } from "../../types/emojis/create_guild_emoji.ts"; import type { Emoji } from "../../types/emojis/emoji.ts"; -import { snowflakeToBigint } from "../../util/bigint.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { urlToBase64 } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Create an emoji in the server. Emojis and animated emojis have a maximum file size of 256kb. Attempting to upload an emoji larger than this limit will fail and return 400 Bad Request and an error message, but not a JSON status code. If a URL is provided to the image parameter, Discordeno will automatically convert it to a base64 string internally. */ -export async function createEmoji(guildId: bigint, name: string, image: string, options: CreateGuildEmoji) { - await requireBotGuildPermissions(guildId, ["MANAGE_EMOJIS"]); +export async function createEmoji(bot: Bot, guildId: bigint, name: string, image: string, options: CreateGuildEmoji) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]); if (image && !image.startsWith("data:image/")) { - image = await urlToBase64(image); + image = await bot.utils.urlToBase64(image); } - const emoji = await rest.runMethod("post", endpoints.GUILD_EMOJIS(guildId), { - ...options, - name, - image, - }); + const emoji = await bot.rest.runMethod>( + "post", + bot.constants.endpoints.GUILD_EMOJIS(guildId), + { + ...options, + name, + image, + } + ); return { ...emoji, - id: snowflakeToBigint(emoji.id!), + id: bot.transformers.snowflake(emoji.id!), }; } diff --git a/src/helpers/emojis/delete_emoji.ts b/src/helpers/emojis/delete_emoji.ts index 402a095dd..075a835fa 100644 --- a/src/helpers/emojis/delete_emoji.ts +++ b/src/helpers/emojis/delete_emoji.ts @@ -1,10 +1,10 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Delete the given emoji. Requires the MANAGE_EMOJIS permission. Returns 204 No Content on success. */ -export async function deleteEmoji(guildId: bigint, id: bigint, reason?: string) { - await requireBotGuildPermissions(guildId, ["MANAGE_EMOJIS"]); +export async function deleteEmoji(bot: Bot, guildId: bigint, id: bigint, reason?: string) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]); - return await rest.runMethod("delete", endpoints.GUILD_EMOJI(guildId, id), { reason }); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.GUILD_EMOJI(guildId, id), { + reason, + }); } diff --git a/src/helpers/emojis/edit_emoji.ts b/src/helpers/emojis/edit_emoji.ts index c1917ebef..1c86e0ccb 100644 --- a/src/helpers/emojis/edit_emoji.ts +++ b/src/helpers/emojis/edit_emoji.ts @@ -1,12 +1,15 @@ -import { rest } from "../../rest/rest.ts"; import type { Emoji } from "../../types/emojis/emoji.ts"; import type { ModifyGuildEmoji } from "../../types/emojis/modify_guild_emoji.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Modify the given emoji. Requires the MANAGE_EMOJIS permission. */ -export async function editEmoji(guildId: bigint, id: bigint, options: ModifyGuildEmoji) { - await requireBotGuildPermissions(guildId, ["MANAGE_EMOJIS"]); +export async function editEmoji(bot: Bot, guildId: bigint, id: bigint, options: ModifyGuildEmoji) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]); - return await rest.runMethod("patch", endpoints.GUILD_EMOJI(guildId, id), options); + return await bot.rest.runMethod>( + "patch", + bot.constants.endpoints.GUILD_EMOJI(guildId, id), + options + ); } diff --git a/src/helpers/emojis/get_emoji.ts b/src/helpers/emojis/get_emoji.ts index 7bde027ef..22f4b78b4 100644 --- a/src/helpers/emojis/get_emoji.ts +++ b/src/helpers/emojis/get_emoji.ts @@ -1,22 +1,20 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; import type { Emoji } from "../../types/emojis/emoji.ts"; import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** * Returns an emoji for the given guild and emoji Id. * * ⚠️ **If you need this, you are probably doing something wrong. Always use cache.guilds.get()?.emojis */ -export async function getEmoji(guildId: bigint, emojiId: bigint, addToCache = true) { - const result = await rest.runMethod("get", endpoints.GUILD_EMOJI(guildId, emojiId)); +export async function getEmoji(bot: Bot, guildId: bigint, emojiId: bigint, addToCache = true) { + const result = await bot.rest.runMethod("get", bot.constants.endpoints.GUILD_EMOJI(guildId, emojiId)); if (addToCache) { - const guild = await cacheHandlers.get("guilds", guildId); + const guild = await bot.cache.guilds.get(guildId); if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); guild.emojis.set(emojiId, result); - await cacheHandlers.set("guilds", guildId, guild); + await bot.cache.guilds.set(guildId, guild); } return result; diff --git a/src/helpers/emojis/get_emojis.ts b/src/helpers/emojis/get_emojis.ts index babbeb3c7..e0f2fe6cb 100644 --- a/src/helpers/emojis/get_emojis.ts +++ b/src/helpers/emojis/get_emojis.ts @@ -1,30 +1,26 @@ -import { eventHandlers } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; +import type { Bot } from "../../bot.ts"; import type { Emoji } from "../../types/emojis/emoji.ts"; import { Errors } from "../../types/discordeno/errors.ts"; -import { snowflakeToBigint } from "../../util/bigint.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; /** * Returns a list of emojis for the given guild. * * ⚠️ **If you need this, you are probably doing something wrong. Always use cache.guilds.get()?.emojis */ -export async function getEmojis(guildId: bigint, addToCache = true) { - const result = await rest.runMethod("get", endpoints.GUILD_EMOJIS(guildId)); +export async function getEmojis(bot: Bot, guildId: bigint, addToCache = true) { + const result = await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_EMOJIS(guildId)); if (addToCache) { - const guild = await cacheHandlers.get("guilds", guildId); + const guild = await bot.cache.guilds.get("guilds", guildId); if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); result.forEach((emoji) => { - eventHandlers.debug?.("loop", `Running forEach loop in get_emojis file.`); - guild.emojis.set(snowflakeToBigint(emoji.id!), emoji); + bot.events.debug("loop", `Running forEach loop in get_emojis file.`); + guild.emojis.set(bot.transformers.snowflake(emoji.id!), emoji); }); - await cacheHandlers.set("guilds", guildId, guild); + await bot.cache.guilds.set(guildId, guild); } return new Collection(result.map((e) => [e.id!, e])); diff --git a/src/helpers/guilds/create_guild.ts b/src/helpers/guilds/create_guild.ts index 38bd03165..cf651652d 100644 --- a/src/helpers/guilds/create_guild.ts +++ b/src/helpers/guilds/create_guild.ts @@ -1,22 +1,28 @@ -import { botId } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { CreateGuild } from "../../types/guilds/create_guild.ts"; import type { Guild } from "../../types/guilds/guild.ts"; -import { endpoints } from "../../util/constants.ts"; -import { snakelize } from "../../util/utils.ts"; -import { getMember } from "../members/get_member.ts"; +import type { Bot } from "../../bot.ts"; /** Create a new guild. Returns a guild object on success. Fires a Guild Create Gateway event. This endpoint can be used only by bots in less than 10 guilds. */ -export async function createGuild(options: CreateGuild) { - const result = await rest.runMethod("post", endpoints.GUILDS, snakelize(options)); +export async function createGuild(bot: Bot, options: CreateGuild) { + const result = await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.GUILDS, { + name: options.name, + afk_channel_id: options.afkChannelId, + afk_timeout: options.afkTimeout, + channels: options.channels, + default_message_notifications: options.defaultMessageNotifications, + explicit_content_filter: options.explicitContentFilter, + icon: options.icon, + roles: options.roles, + system_channel_flags: options.systemChannelFlags, + system_channel_id: options.systemChannelId, + verification_level: options.verificationLevel, + }); - const guild = await structures.createDiscordenoGuild(result, 0); + const guild = bot.transformers.guild(bot, { guild: result, shardId: 0 }); // MANUALLY CACHE THE GUILD - await cacheHandlers.set("guilds", guild.id, guild); + await bot.cache.guilds.set(guild.id, guild); // MANUALLY CACHE THE BOT - await getMember(guild.id, botId); + await bot.helpers.getMember(bot, guild.id, bot.id); return guild; } diff --git a/src/helpers/guilds/delete_guild.ts b/src/helpers/guilds/delete_guild.ts index 8e98de769..c1c4d359b 100644 --- a/src/helpers/guilds/delete_guild.ts +++ b/src/helpers/guilds/delete_guild.ts @@ -1,7 +1,6 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Delete a guild permanently. User must be owner. Returns 204 No Content on success. Fires a Guild Delete Gateway event. */ -export async function deleteGuild(guildId: bigint) { - return await rest.runMethod("delete", endpoints.GUILDS_BASE(guildId)); +export async function deleteGuild(bot: Bot, guildId: bigint) { + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.GUILDS_BASE(guildId)); } diff --git a/src/helpers/guilds/edit_guild.ts b/src/helpers/guilds/edit_guild.ts index 760e387ce..e40e78cec 100644 --- a/src/helpers/guilds/edit_guild.ts +++ b/src/helpers/guilds/edit_guild.ts @@ -1,34 +1,29 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; +import type { Bot } from "../../bot.ts"; import type { Guild } from "../../types/guilds/guild.ts"; import type { ModifyGuild } from "../../types/guilds/modify_guild.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize, urlToBase64 } from "../../util/utils.ts"; -import { ws } from "../../ws/ws.ts"; /** Modify a guilds settings. Requires the MANAGE_GUILD permission. */ -export async function editGuild(guildId: bigint, options: ModifyGuild) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function editGuild(bot: Bot, guildId: bigint, options: ModifyGuild) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); if (options.icon && !options.icon.startsWith("data:image/")) { - options.icon = await urlToBase64(options.icon); + options.icon = await bot.utils.urlToBase64(options.icon); } if (options.banner && !options.banner.startsWith("data:image/")) { - options.banner = await urlToBase64(options.banner); + options.banner = await bot.utils.urlToBase64(options.banner); } if (options.splash && !options.splash.startsWith("data:image/")) { - options.splash = await urlToBase64(options.splash); + options.splash = await bot.utils.urlToBase64(options.splash); } - const result = await rest.runMethod("patch", endpoints.GUILDS_BASE(guildId), snakelize(options)); + const result = await bot.rest.runMethod(bot.rest, "patch", bot.constants.endpoints.GUILDS_BASE(guildId), {}); - const cached = await cacheHandlers.get("guilds", guildId); - return structures.createDiscordenoGuild( - result, - cached?.shardId || Number((BigInt(result.id) >> 22n % BigInt(ws.botGatewayData.shards)).toString()) - ); + const cached = await bot.cache.guilds.get(guildId); + return bot.transformers.guild(bot, { + guild: result, + shardId: + cached?.shardId || Number((BigInt(result.id) >> 22n % BigInt(bot.gateway.botGatewayData.shards)).toString()), + }); } diff --git a/src/helpers/guilds/edit_welcome_screen.ts b/src/helpers/guilds/edit_welcome_screen.ts index 8ab1e4759..7a4d517e0 100644 --- a/src/helpers/guilds/edit_welcome_screen.ts +++ b/src/helpers/guilds/edit_welcome_screen.ts @@ -1,9 +1,18 @@ -import { rest } from "../../rest/rest.ts"; import type { ModifyGuildWelcomeScreen } from "../../types/guilds/modify_guild_welcome_screen.ts"; import type { WelcomeScreen } from "../../types/guilds/welcome_screen.ts"; -import { endpoints } from "../../util/constants.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; -export async function editWelcomeScreen(guildId: bigint, options: ModifyGuildWelcomeScreen) { - return await rest.runMethod("patch", endpoints.GUILD_WELCOME_SCREEN(guildId), snakelize(options)); +export async function editWelcomeScreen(bot: Bot, guildId: bigint, options: ModifyGuildWelcomeScreen) { + return await bot.rest.runMethod("patch", bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId), { + enabled: options.enabled, + welcomeScreen: options.welcomeScreen?.map((welcomeScreen) => { + return { + channel_id: welcomeScreen.channelId, + description: welcomeScreen.description, + emoji_id: welcomeScreen.emojiId, + emoji_name: welcomeScreen.emojiName, + }; + }), + description: options.description, + }); } diff --git a/src/helpers/guilds/edit_widget.ts b/src/helpers/guilds/edit_widget.ts index 66cd803e4..2b17cf91e 100644 --- a/src/helpers/guilds/edit_widget.ts +++ b/src/helpers/guilds/edit_widget.ts @@ -1,13 +1,11 @@ -import { rest } from "../../rest/rest.ts"; import type { GuildWidget } from "../../types/guilds/guild_widget.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Modify a guild widget object for the guild. Requires the MANAGE_GUILD permission. */ -export async function editWidget(guildId: bigint, enabled: boolean, channelId?: string | null) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function editWidget(bot: Bot, guildId: bigint, enabled: boolean, channelId?: string | null) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - return await rest.runMethod("patch", endpoints.GUILD_WIDGET(guildId), { + return await bot.rest.runMethod(bot.rest, "patch", bot.constants.endpoints.GUILD_WIDGET(guildId), { enabled, channel_id: channelId, }); diff --git a/src/helpers/guilds/get_audit_logs.ts b/src/helpers/guilds/get_audit_logs.ts index ed8e9ab0d..e83d84c57 100644 --- a/src/helpers/guilds/get_audit_logs.ts +++ b/src/helpers/guilds/get_audit_logs.ts @@ -1,20 +1,15 @@ -import { rest } from "../../rest/rest.ts"; import type { AuditLog } from "../../types/audit_log/audit_log.ts"; import type { GetGuildAuditLog } from "../../types/audit_log/get_guild_audit_log.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** Returns the audit logs for the guild. Requires VIEW AUDIT LOGS permission */ -export async function getAuditLogs(guildId: bigint, options?: GetGuildAuditLog) { - await requireBotGuildPermissions(guildId, ["VIEW_AUDIT_LOG"]); +export async function getAuditLogs(bot: Bot, guildId: bigint, options?: GetGuildAuditLog) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["VIEW_AUDIT_LOG"]); - return await rest.runMethod( - "get", - endpoints.GUILD_AUDIT_LOGS(guildId), - snakelize({ - ...options, - limit: options?.limit && options.limit >= 1 && options.limit <= 100 ? options.limit : 50, - }) - ); + return await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_AUDIT_LOGS(guildId), { + user_id: options.userId, + action_type: options.actionType, + before: options.before, + limit: options?.limit && options.limit >= 1 && options.limit <= 100 ? options.limit : 50, + }); } diff --git a/src/helpers/guilds/get_available_voice_regions.ts b/src/helpers/guilds/get_available_voice_regions.ts index 2111f6a3d..9cebbd367 100644 --- a/src/helpers/guilds/get_available_voice_regions.ts +++ b/src/helpers/guilds/get_available_voice_regions.ts @@ -1,8 +1,7 @@ -import { rest } from "../../rest/rest.ts"; import type { VoiceRegion } from "../../types/voice/voice_region.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Returns an array of voice regions that can be used when creating servers. */ -export async function getAvailableVoiceRegions() { - return await rest.runMethod("get", endpoints.VOICE_REGIONS); +export async function getAvailableVoiceRegions(bot: Bot) { + return await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.VOICE_REGIONS); } diff --git a/src/helpers/guilds/get_ban.ts b/src/helpers/guilds/get_ban.ts index 125277417..cfbbfa88c 100644 --- a/src/helpers/guilds/get_ban.ts +++ b/src/helpers/guilds/get_ban.ts @@ -1,11 +1,9 @@ -import { rest } from "../../rest/rest.ts"; import type { Ban } from "../../types/guilds/ban.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Returns a ban object for the given user or a 404 not found if the ban cannot be found. Requires the BAN_MEMBERS permission. */ -export async function getBan(guildId: bigint, memberId: bigint) { - await requireBotGuildPermissions(guildId, ["BAN_MEMBERS"]); +export async function getBan(bot: Bot, guildId: bigint, memberId: bigint) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]); - return await rest.runMethod("get", endpoints.GUILD_BAN(guildId, memberId)); + return await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_BAN(guildId, memberId)); } diff --git a/src/helpers/guilds/get_bans.ts b/src/helpers/guilds/get_bans.ts index dd158e1aa..95eb3882f 100644 --- a/src/helpers/guilds/get_bans.ts +++ b/src/helpers/guilds/get_bans.ts @@ -1,15 +1,12 @@ -import { rest } from "../../rest/rest.ts"; import type { Ban } from "../../types/guilds/ban.ts"; -import { snowflakeToBigint } from "../../util/bigint.ts"; +import type { Bot } from "../../bot.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; /** Returns a list of ban objects for the users banned from this guild. Requires the BAN_MEMBERS permission. */ -export async function getBans(guildId: bigint) { - await requireBotGuildPermissions(guildId, ["BAN_MEMBERS"]); +export async function getBans(bot: Bot, guildId: bigint) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]); - const results = await rest.runMethod("get", endpoints.GUILD_BANS(guildId)); + const results = await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_BANS(guildId)); - return new Collection(results.map((res) => [snowflakeToBigint(res.user.id), res])); + return new Collection(results.map((res) => [bot.transformers.snowflake(res.user.id), res])); } diff --git a/src/helpers/guilds/get_guild.ts b/src/helpers/guilds/get_guild.ts index 4e38d934d..072567fc0 100644 --- a/src/helpers/guilds/get_guild.ts +++ b/src/helpers/guilds/get_guild.ts @@ -1,9 +1,5 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Guild } from "../../types/guilds/guild.ts"; -import { endpoints } from "../../util/constants.ts"; -import { ws } from "../../ws/ws.ts"; +import type { Bot } from "../../bot.ts"; /** * ⚠️ **If you need this, you are probably doing something wrong. Always use cache.guilds.get() @@ -13,23 +9,24 @@ import { ws } from "../../ws/ws.ts"; * So it does not cache the guild, you must do it manually. * */ export async function getGuild( + bot: Bot, guildId: bigint, options: { counts?: boolean; addToCache?: boolean } = { counts: true, addToCache: true, } ) { - const result = await rest.runMethod("get", endpoints.GUILDS_BASE(guildId), { + const result = await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILDS_BASE(guildId), { with_counts: options.counts, }); - const guild = await structures.createDiscordenoGuild( - result, - Number((BigInt(guildId) >> 22n) % BigInt(ws.botGatewayData.shards)) - ); + const guild = await bot.transformers.guild(bot, { + guild: result, + shardId: Number((BigInt(guildId) >> 22n) % BigInt(ws.botGatewayData.shards)), + }); if (options.addToCache) { - await cacheHandlers.set("guilds", guild.id, guild); + await bot.cache.guilds.set(guild.id, guild); } return guild; diff --git a/src/helpers/guilds/get_guild_preview.ts b/src/helpers/guilds/get_guild_preview.ts index 04238da4d..7ee1d4cfb 100644 --- a/src/helpers/guilds/get_guild_preview.ts +++ b/src/helpers/guilds/get_guild_preview.ts @@ -1,8 +1,7 @@ -import { rest } from "../../rest/rest.ts"; import type { GuildPreview } from "../../types/guilds/guild_preview.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Returns the guild preview object for the given id. If the bot is not in the guild, then the guild must be Discoverable. */ -export async function getGuildPreview(guildId: bigint) { - return await rest.runMethod("get", endpoints.GUILD_PREVIEW(guildId)); +export async function getGuildPreview(bot: Bot, guildId: bigint) { + return await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_PREVIEW(guildId)); } diff --git a/src/helpers/guilds/get_prune_count.ts b/src/helpers/guilds/get_prune_count.ts index 3614aae14..4a23de19b 100644 --- a/src/helpers/guilds/get_prune_count.ts +++ b/src/helpers/guilds/get_prune_count.ts @@ -1,20 +1,26 @@ -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import type { GetGuildPruneCountQuery } from "../../types/guilds/get_guild_prune_count.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** Check how many members would be removed from the server in a prune operation. Requires the KICK_MEMBERS permission */ -export async function getPruneCount(guildId: bigint, options?: GetGuildPruneCountQuery) { - if (options?.days && options.days < 1) throw new Error(Errors.PRUNE_MIN_DAYS); +export async function getPruneCount(bot: Bot, guildId: bigint, options?: GetGuildPruneCountQuery) { + if (options?.days && options.days < 1) throw new Error(bot.constants.Errors.PRUNE_MIN_DAYS); if (options?.days && options.days > 30) { - throw new Error(Errors.PRUNE_MAX_DAYS); + throw new Error(bot.constants.Errors.PRUNE_MAX_DAYS); } - await requireBotGuildPermissions(guildId, ["KICK_MEMBERS"]); + await bot.utils.requireBotGuildPermissions(guildId, ["KICK_MEMBERS"]); - const result = await rest.runMethod("get", endpoints.GUILD_PRUNE(guildId), snakelize(options ?? {})); + const result = await bot.rest.runMethod( + bot.rest, + "get", + bot.constants.endpoints.GUILD_PRUNE(guildId), + options + ? { + days: options.days, + include_roles: options.includeRoles, + } + : {} + ); return result.pruned as number; } diff --git a/src/helpers/guilds/get_vainty_url.ts b/src/helpers/guilds/get_vanity_url.ts similarity index 59% rename from src/helpers/guilds/get_vainty_url.ts rename to src/helpers/guilds/get_vanity_url.ts index 7f5087556..b1aed91d3 100644 --- a/src/helpers/guilds/get_vainty_url.ts +++ b/src/helpers/guilds/get_vanity_url.ts @@ -1,13 +1,12 @@ -import { rest } from "../../rest/rest.ts"; import type { InviteMetadata } from "../../types/invites/invite_metadata.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Returns the code and uses of the vanity url for this server if it is enabled else `code` will be null. Requires the `MANAGE_GUILD` permission. */ -export async function getVanityURL(guildId: bigint) { - return await rest.runMethod< +export async function getVanityURL(bot: Bot, guildId: bigint) { + return await bot.rest.runMethod< | (Partial & Pick) | { code: null; } - >("get", endpoints.GUILD_VANITY_URL(guildId)); + >(bot.rest, "get", bot.constants.endpoints.GUILD_VANITY_URL(guildId)); } diff --git a/src/helpers/guilds/get_voice_regions.ts b/src/helpers/guilds/get_voice_regions.ts index 756d876b3..d978388e9 100644 --- a/src/helpers/guilds/get_voice_regions.ts +++ b/src/helpers/guilds/get_voice_regions.ts @@ -1,11 +1,14 @@ -import { rest } from "../../rest/rest.ts"; import type { VoiceRegion } from "../../types/voice/voice_region.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Returns a list of voice region objects for the guild. Unlike the similar /voice route, this returns VIP servers when the guild is VIP-enabled. */ -export async function getVoiceRegions(guildId: bigint) { - const result = await rest.runMethod("get", endpoints.GUILD_REGIONS(guildId)); +export async function getVoiceRegions(boot: Bot, guildId: bigint) { + const result = await bot.rest.runMethod( + bot.rest, + "get", + bot.constants.endpoints.GUILD_REGIONS(guildId) + ); return new Collection(result.map((region) => [region.id, region])); } diff --git a/src/helpers/guilds/get_welcome_screen.ts b/src/helpers/guilds/get_welcome_screen.ts index d048baf0b..93767c6fd 100644 --- a/src/helpers/guilds/get_welcome_screen.ts +++ b/src/helpers/guilds/get_welcome_screen.ts @@ -1,7 +1,10 @@ -import { rest } from "../../rest/rest.ts"; import type { WelcomeScreen } from "../../types/guilds/welcome_screen.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; -export async function getWelcomeScreen(guildId: bigint) { - return await rest.runMethod("get", endpoints.GUILD_WELCOME_SCREEN(guildId)); +export async function getWelcomeScreen(bot: Bot, guildId: bigint) { + return await bot.rest.runMethod( + bot.rset, + "get", + bot.constants.endpoints.GUILD_WELCOME_SCREEN(guildId) + ); } diff --git a/src/helpers/guilds/get_widget.ts b/src/helpers/guilds/get_widget.ts index c66020cee..c89aa3cb3 100644 --- a/src/helpers/guilds/get_widget.ts +++ b/src/helpers/guilds/get_widget.ts @@ -1,16 +1,17 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; import type { GuildWidgetDetails } from "../../types/guilds/guild_widget_details.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Returns the widget for the guild. */ -export async function getWidget(guildId: bigint, options?: { force: boolean }) { +export async function getWidget(bot: Bot, guildId: bigint, options?: { force: boolean }) { if (!options?.force) { - const guild = await cacheHandlers.get("guilds", guildId); - if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); - if (!guild?.widgetEnabled) throw new Error(Errors.GUILD_WIDGET_NOT_ENABLED); + const guild = await bot.cacahe.guilds.get(guildId); + if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND); + if (!guild?.widgetEnabled) throw new Error(bot.constants.Errors.GUILD_WIDGET_NOT_ENABLED); } - return await rest.runMethod("get", `${endpoints.GUILD_WIDGET(guildId)}.json`); + return await bot.rest.runMethod( + bot.rest, + "get", + `${bot.constants.endpoints.GUILD_WIDGET(guildId)}.json` + ); } diff --git a/src/helpers/guilds/get_widget_image_url.ts b/src/helpers/guilds/get_widget_image_url.ts index 28cd5d94f..454997a4e 100644 --- a/src/helpers/guilds/get_widget_image_url.ts +++ b/src/helpers/guilds/get_widget_image_url.ts @@ -1,15 +1,17 @@ -import { cacheHandlers } from "../../cache.ts"; +import type { Bot } from "../../bot.ts"; import type { GetGuildWidgetImageQuery } from "../../types/guilds/get_guild_widget_image.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; /** Returns the widget image URL for the guild. */ -export async function getWidgetImageURL(guildId: bigint, options?: GetGuildWidgetImageQuery & { force?: boolean }) { +export async function getWidgetImageURL( + bot: Bot, + guildId: bigint, + options?: GetGuildWidgetImageQuery & { force?: boolean } +) { if (!options?.force) { - const guild = await cacheHandlers.get("guilds", guildId); - if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); - if (!guild.widgetEnabled) throw new Error(Errors.GUILD_WIDGET_NOT_ENABLED); + const guild = await bot.cache.guilds.get(guildId); + if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND); + if (!guild.widgetEnabled) throw new Error(bot.constants.Errors.GUILD_WIDGET_NOT_ENABLED); } - return `${endpoints.GUILD_WIDGET(guildId)}.png?style=${options?.style ?? "shield"}`; + return `${bot.constants.endpoints.GUILD_WIDGET(guildId)}.png?style=${options?.style ?? "shield"}`; } diff --git a/src/helpers/guilds/get_widget_settings.ts b/src/helpers/guilds/get_widget_settings.ts index 23417a61a..e03f2e9f4 100644 --- a/src/helpers/guilds/get_widget_settings.ts +++ b/src/helpers/guilds/get_widget_settings.ts @@ -1,11 +1,9 @@ -import { rest } from "../../rest/rest.ts"; import type { GuildWidget } from "../../types/guilds/guild_widget.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Returns the guild widget object. Requires the MANAGE_GUILD permission. */ -export async function getWidgetSettings(guildId: bigint) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function getWidgetSettings(bot: Bot, guildId: bigint) { + await bot.utils.requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); - return await rest.runMethod("get", endpoints.GUILD_WIDGET(guildId)); + return await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_WIDGET(guildId)); } diff --git a/src/helpers/guilds/guild_banner_url.ts b/src/helpers/guilds/guild_banner_url.ts index e4167c3cc..a127c5920 100644 --- a/src/helpers/guilds/guild_banner_url.ts +++ b/src/helpers/guilds/guild_banner_url.ts @@ -1,11 +1,10 @@ import type { DiscordImageFormat } from "../../types/misc/image_format.ts"; import type { DiscordImageSize } from "../../types/misc/image_size.ts"; -import { endpoints } from "../../util/constants.ts"; -import { iconBigintToHash } from "../../util/hash.ts"; -import { formatImageURL } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** The full URL of the banner from Discords CDN. Undefined if no banner is set. */ export function guildBannerURL( + bot: Bot, id: bigint, options: { banner?: string | bigint; @@ -15,12 +14,12 @@ export function guildBannerURL( } ) { return options.banner - ? formatImageURL( - endpoints.GUILD_BANNER( + ? bot.utils.formatImageURL( + bot.constants.endpoints.GUILD_BANNER( id, typeof options.banner === "string" ? options.banner - : iconBigintToHash(options.banner, options.animated ?? true) + : bot.utils.iconBigintToHash(options.banner, options.animated ?? true) ), options.size || 128, options.format diff --git a/src/helpers/guilds/guild_icon_url.ts b/src/helpers/guilds/guild_icon_url.ts index 3d7af4a4d..562454e1f 100644 --- a/src/helpers/guilds/guild_icon_url.ts +++ b/src/helpers/guilds/guild_icon_url.ts @@ -1,11 +1,10 @@ import type { DiscordImageFormat } from "../../types/misc/image_format.ts"; import type { DiscordImageSize } from "../../types/misc/image_size.ts"; -import { endpoints } from "../../util/constants.ts"; -import { iconBigintToHash } from "../../util/hash.ts"; -import { formatImageURL } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** The full URL of the icon from Discords CDN. Undefined when no icon is set. */ export function guildIconURL( + bot: Bot, id: bigint, options: { icon?: string | bigint; @@ -15,10 +14,12 @@ export function guildIconURL( } ) { return options.icon - ? formatImageURL( - endpoints.GUILD_ICON( + ? bot.utils.formatImageURL( + bot.constants.endpoints.GUILD_ICON( id, - typeof options.icon === "string" ? options.icon : iconBigintToHash(options.icon, options.animated ?? true) + typeof options.icon === "string" + ? options.icon + : bot.utils.iconBigintToHash(options.icon, options.animated ?? true) ), options.size || 128, options.format diff --git a/src/helpers/guilds/guild_splash_url.ts b/src/helpers/guilds/guild_splash_url.ts index 86e029982..8a0ab20d4 100644 --- a/src/helpers/guilds/guild_splash_url.ts +++ b/src/helpers/guilds/guild_splash_url.ts @@ -1,11 +1,10 @@ import type { DiscordImageFormat } from "../../types/misc/image_format.ts"; import type { DiscordImageSize } from "../../types/misc/image_size.ts"; -import { endpoints } from "../../util/constants.ts"; -import { iconBigintToHash } from "../../util/hash.ts"; -import { formatImageURL } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** The full URL of the splash from Discords CDN. Undefined if no splash is set. */ export function guildSplashURL( + bot: Bot, id: bigint, options: { splash?: string | bigint; @@ -15,12 +14,12 @@ export function guildSplashURL( } ) { return options.splash - ? formatImageURL( - endpoints.GUILD_SPLASH( + ? bot.utils.formatImageURL( + bot.constants.endpoints.GUILD_SPLASH( id, typeof options.splash === "string" ? options.splash - : iconBigintToHash(options.splash, options.animated ?? true) + : bot.utils.iconBigintToHash(options.splash, options.animated ?? true) ), options.size || 128, options.format diff --git a/src/helpers/guilds/leave_guild.ts b/src/helpers/guilds/leave_guild.ts index 3e8813535..06d6f1756 100644 --- a/src/helpers/guilds/leave_guild.ts +++ b/src/helpers/guilds/leave_guild.ts @@ -1,7 +1,6 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Leave a guild */ -export async function leaveGuild(guildId: bigint) { - return await rest.runMethod("delete", endpoints.GUILD_LEAVE(guildId)); +export async function leaveGuild(bot: Bot, guildId: bigint) { + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.GUILD_LEAVE(guildId)); } diff --git a/src/helpers/integrations/delete_integration.ts b/src/helpers/integrations/delete_integration.ts index 8de324a4b..4cee41844 100644 --- a/src/helpers/integrations/delete_integration.ts +++ b/src/helpers/integrations/delete_integration.ts @@ -1,10 +1,12 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Delete the attached integration object for the guild with this id. Requires MANAGE_GUILD permission. */ -export async function deleteIntegration(guildId: bigint, id: bigint) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function deleteIntegration(bot: Bot, guildId: bigint, id: bigint) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - return await rest.runMethod("delete", endpoints.GUILD_INTEGRATION(guildId, id)); + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.GUILD_INTEGRATION(guildId, id) + ); } diff --git a/src/helpers/integrations/get_integrations.ts b/src/helpers/integrations/get_integrations.ts index c7070e582..8c5d32100 100644 --- a/src/helpers/integrations/get_integrations.ts +++ b/src/helpers/integrations/get_integrations.ts @@ -1,11 +1,14 @@ -import { rest } from "../../rest/rest.ts"; import type { Integration } from "../../types/integrations/integration.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Returns a list of integrations for the guild. Requires the MANAGE_GUILD permission. */ -export async function getIntegrations(guildId: bigint) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function getIntegrations(bot: Bot, guildId: bigint) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - return await rest.runMethod("get", endpoints.GUILD_INTEGRATIONS(guildId)); + return await bot.rest.runMethod>( + bot.rest, + "get", + bot.constants.endpoints.GUILD_INTEGRATIONS(guildId) + ); } diff --git a/src/helpers/interactions/commands/batch_edit_slash_command_permissions.ts b/src/helpers/interactions/commands/batch_edit_slash_command_permissions.ts index 5671947d5..a9682981c 100644 --- a/src/helpers/interactions/commands/batch_edit_slash_command_permissions.ts +++ b/src/helpers/interactions/commands/batch_edit_slash_command_permissions.ts @@ -1,13 +1,16 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; +import type { Bot } from "../../../bot.ts"; import type { ApplicationCommandPermissions } from "../../../types/interactions/commands/application_command_permissions.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { snakelize } from "../../../util/utils.ts"; /** Batch edits permissions for all commands in a guild. Takes an array of partial GuildApplicationCommandPermissions objects including `id` and `permissions`. */ export async function batchEditSlashCommandPermissions( + bot: Bot, guildId: bigint, options: { id: string; permissions: ApplicationCommandPermissions[] }[] ) { - return await rest.runMethod("put", endpoints.COMMANDS_PERMISSIONS(applicationId, guildId), snakelize(options)); + return await bot.rest.runMethod( + bot.rest, + "put", + bot.constants.endpoints.COMMANDS_PERMISSIONS(bot.applicationId, guildId), + options + ); } diff --git a/src/helpers/interactions/commands/create_slash_command.ts b/src/helpers/interactions/commands/create_slash_command.ts index 26a989827..30ce8c170 100644 --- a/src/helpers/interactions/commands/create_slash_command.ts +++ b/src/helpers/interactions/commands/create_slash_command.ts @@ -1,9 +1,6 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; import type { ApplicationCommand } from "../../../types/interactions/commands/application_command.ts"; import type { CreateGlobalApplicationCommand } from "../../../types/interactions/commands/create_global_application_command.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { snakelize, validateSlashCommands } from "../../../util/utils.ts"; +import type { Bot } from "../../../bot.ts"; /** * There are two kinds of Slash Commands: global commands and guild commands. Global commands are available for every guild that adds your app; guild commands are specific to the guild you specify when making them. Command names are unique per application within each scope (global and guild). That means: @@ -16,12 +13,15 @@ import { snakelize, validateSlashCommands } from "../../../util/utils.ts"; * Global commands are cached for **1 hour**. That means that new global commands will fan out slowly across all guilds, and will be guaranteed to be updated in an hour. * Guild commands update **instantly**. We recommend you use guild commands for quick testing, and global commands when they're ready for public use. */ -export async function createSlashCommand(options: CreateGlobalApplicationCommand, guildId?: bigint) { - [options] = validateSlashCommands([options], true) as CreateGlobalApplicationCommand[]; +export async function createSlashCommand(bot: Bot, options: CreateGlobalApplicationCommand, guildId?: bigint) { + [options] = bot.utils.validateSlashCommands([options], true) as CreateGlobalApplicationCommand[]; - return await rest.runMethod( + return await bot.rest.runMethod( + bot.rest, "post", - guildId ? endpoints.COMMANDS_GUILD(applicationId, guildId) : endpoints.COMMANDS(applicationId), - snakelize(options) + guildId + ? bot.constants.endpoints.COMMANDS_GUILD(bot.applicationId, guildId) + : bot.constants.endpoints.COMMANDS(bot.applicationId), + options ); } diff --git a/src/helpers/interactions/commands/delete_slash_command.ts b/src/helpers/interactions/commands/delete_slash_command.ts index d4e8c71b2..6367deb65 100644 --- a/src/helpers/interactions/commands/delete_slash_command.ts +++ b/src/helpers/interactions/commands/delete_slash_command.ts @@ -1,11 +1,12 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { Bot } from "../../../bot.ts"; /** Deletes a slash command. */ -export async function deleteSlashCommand(id: bigint, guildId?: bigint) { - return await rest.runMethod( +export async function deleteSlashCommand(bot: Bot, id: bigint, guildId?: bigint) { + return await bot.rest.runMethod( + bot.rest, "delete", - guildId ? endpoints.COMMANDS_GUILD_ID(applicationId, guildId, id) : endpoints.COMMANDS_ID(applicationId, id) + guildId + ? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, id) + : bot.constants.endpoints.COMMANDS_ID(bot.applicationId, id) ); } diff --git a/src/helpers/interactions/commands/delete_slash_response.ts b/src/helpers/interactions/commands/delete_slash_response.ts index 25f1a1c59..152dba779 100644 --- a/src/helpers/interactions/commands/delete_slash_response.ts +++ b/src/helpers/interactions/commands/delete_slash_response.ts @@ -1,13 +1,12 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { Bot } from "../../../bot.ts"; /** To delete your response to a slash command. If a message id is not provided, it will default to deleting the original response. */ -export async function deleteSlashResponse(token: string, messageId?: bigint) { - return await rest.runMethod( +export async function deleteSlashResponse(bot: Bot, token: string, messageId?: bigint) { + return await bot.rest.runMethod( + bot.rest, "delete", messageId - ? endpoints.INTERACTION_ID_TOKEN_MESSAGE_ID(applicationId, token, messageId) - : endpoints.INTERACTION_ORIGINAL_ID_TOKEN(applicationId, token) + ? bot.constants.endpoints.INTERACTION_ID_TOKEN_MESSAGE_ID(bot.applicationId, token, messageId) + : bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token) ); } diff --git a/src/helpers/interactions/commands/edit_slash_command_permissions.ts b/src/helpers/interactions/commands/edit_slash_command_permissions.ts index d633d7080..0ead8eaf2 100644 --- a/src/helpers/interactions/commands/edit_slash_command_permissions.ts +++ b/src/helpers/interactions/commands/edit_slash_command_permissions.ts @@ -1,16 +1,19 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; import type { ApplicationCommandPermissions } from "../../../types/interactions/commands/application_command_permissions.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { snakelize } from "../../../util/utils.ts"; +import type { Bot } from "../../../bot.ts"; /** Edits command permissions for a specific command for your application in a guild. */ export async function editSlashCommandPermissions( + bot: Bot, guildId: bigint, commandId: bigint, options: ApplicationCommandPermissions[] ) { - return await rest.runMethod("put", endpoints.COMMANDS_PERMISSION(applicationId, guildId, commandId), { - permissions: snakelize(options), - }); + return await bot.rest.runMethod( + bot.rest, + "put", + bot.constants.endpoints.COMMANDS_PERMISSION(bot.applicationId, guildId, commandId), + { + permissions: options, + } + ); } diff --git a/src/helpers/interactions/commands/edit_slash_response.ts b/src/helpers/interactions/commands/edit_slash_response.ts index 22b058875..d3f186b17 100644 --- a/src/helpers/interactions/commands/edit_slash_response.ts +++ b/src/helpers/interactions/commands/edit_slash_response.ts @@ -1,20 +1,15 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; -import { structures } from "../../../structures/mod.ts"; import type { DiscordenoEditWebhookMessage } from "../../../types/discordeno/edit_webhook_message.ts"; -import { Errors } from "../../../types/discordeno/errors.ts"; +import type { Bot } from "../../../bot.ts"; import { DiscordAllowedMentionsTypes } from "../../../types/messages/allowed_mentions_types.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { snakelize, validateComponents } from "../../../util/utils.ts"; /** To edit your response to a slash command. If a messageId is not provided it will default to editing the original response. */ -export async function editSlashResponse(token: string, options: DiscordenoEditWebhookMessage) { +export async function editSlashResponse(bot: Bot, token: string, options: DiscordenoEditWebhookMessage) { if (options.content && options.content.length > 2000) { - throw Error(Errors.MESSAGE_MAX_LENGTH); + throw Error(bot.constants.Errors.MESSAGE_MAX_LENGTH); } if (options.components?.length) { - validateComponents(options.components); + bot.utils.validateComponents(bot, options.components); } if (options.embeds && options.embeds.length > 10) { @@ -43,17 +38,33 @@ export async function editSlashResponse(token: string, options: DiscordenoEditWe } } - const result = await rest.runMethod( + const result = await bot.rest.runMethod( + bot.rest, "patch", options.messageId - ? endpoints.WEBHOOK_MESSAGE(applicationId, token, options.messageId) - : endpoints.INTERACTION_ORIGINAL_ID_TOKEN(applicationId, token), - snakelize(options) + ? bot.constants.endpoints.WEBHOOK_MESSAGE(bot.applicationId, token, options.messageId) + : bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token), + { + content: options.content, + embeds: options.embeds, + file: options.file, + allowed_mentions: options.allowedMentions + ? { + parse: options.allowedMentions.parse, + roles: options.allowedMentions.roles, + users: options.allowedMentions.users, + replied_user: options.allowedMentions.repliedUser, + } + : undefined, + attachments: options.attachments, + // TODO: Snakelize components?? + components: options.components, + message_id: options.messageId, + } ); // If the original message was edited, this will not return a message if (!options.messageId) return result as undefined; - const message = await structures.createDiscordenoMessage(result); - return message; + return bot.transformers.message(bot, result); } diff --git a/src/helpers/interactions/commands/get_slash_command.ts b/src/helpers/interactions/commands/get_slash_command.ts index 80b5fc3d6..30fba39b1 100644 --- a/src/helpers/interactions/commands/get_slash_command.ts +++ b/src/helpers/interactions/commands/get_slash_command.ts @@ -1,21 +1,18 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; import type { ApplicationCommand } from "../../../types/interactions/commands/application_command.ts"; -import { snowflakeToBigint } from "../../../util/bigint.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { Bot } from "../../../bot.ts"; -/** Fetchs the global command for the given Id. If a guildId is provided, the guild command will be fetched. */ -export async function getSlashCommand(commandId: bigint, guildId?: bigint) { - const result = await rest.runMethod( +/** Fetches the global command for the given Id. If a guildId is provided, the guild command will be fetched. */ +export async function getSlashCommand(bot: Bot, commandId: bigint, guildId?: bigint) { + const result = await bot.rest.runMethod( "get", guildId - ? endpoints.COMMANDS_GUILD_ID(applicationId, guildId, commandId) - : endpoints.COMMANDS_ID(applicationId, commandId) + ? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, commandId) + : bot.constants.endpoints.COMMANDS_ID(bot.applicationId, commandId) ); return { ...result, - id: snowflakeToBigint(result.id), - applicationId: snowflakeToBigint(result.applicationId), + id: bot.transformers.snowflake(result.id), + applicationId: bot.transformers.snowflake(result.applicationId), }; } diff --git a/src/helpers/interactions/commands/get_slash_command_permission.ts b/src/helpers/interactions/commands/get_slash_command_permission.ts index 55bc8a7a7..10a4c2a07 100644 --- a/src/helpers/interactions/commands/get_slash_command_permission.ts +++ b/src/helpers/interactions/commands/get_slash_command_permission.ts @@ -1,12 +1,11 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; import type { GuildApplicationCommandPermissions } from "../../../types/interactions/commands/guild_application_command_permissions.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { Bot } from "../../../bot.ts"; /** Fetches command permissions for a specific command for your application in a guild. Returns a GuildApplicationCommandPermissions object. */ -export async function getSlashCommandPermission(guildId: bigint, commandId: bigint) { - return await rest.runMethod( +export async function getSlashCommandPermission(bot: Bot, guildId: bigint, commandId: bigint) { + return await bot.rest.runMethod( + bot.rest, "get", - endpoints.COMMANDS_PERMISSION(applicationId, guildId, commandId) + bot.constants.endpoints.COMMANDS_PERMISSION(bot.applicationId, guildId, commandId) ); } diff --git a/src/helpers/interactions/commands/get_slash_command_permissions.ts b/src/helpers/interactions/commands/get_slash_command_permissions.ts index 1206371e2..56e0a8316 100644 --- a/src/helpers/interactions/commands/get_slash_command_permissions.ts +++ b/src/helpers/interactions/commands/get_slash_command_permissions.ts @@ -1,12 +1,11 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; +import type { Bot } from "../../../bot.ts"; import type { GuildApplicationCommandPermissions } from "../../../types/interactions/commands/guild_application_command_permissions.ts"; -import { endpoints } from "../../../util/constants.ts"; /** Fetches command permissions for all commands for your application in a guild. Returns an array of GuildApplicationCommandPermissions objects. */ -export async function getSlashCommandPermissions(guildId: bigint) { - return await rest.runMethod( +export async function getSlashCommandPermissions(bot: Bot, guildId: bigint) { + return await bot.rest.runMethod( + bot.rest, "get", - endpoints.COMMANDS_PERMISSIONS(applicationId, guildId) + bot.constants.endpoints.COMMANDS_PERMISSIONS(bot.applicationId, guildId) ); } diff --git a/src/helpers/interactions/commands/get_slash_commands.ts b/src/helpers/interactions/commands/get_slash_commands.ts index 11cf8f6d4..e037ea2ac 100644 --- a/src/helpers/interactions/commands/get_slash_commands.ts +++ b/src/helpers/interactions/commands/get_slash_commands.ts @@ -1,21 +1,25 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; import type { ApplicationCommand } from "../../../types/interactions/commands/application_command.ts"; -import { snowflakeToBigint } from "../../../util/bigint.ts"; import { Collection } from "../../../util/collection.ts"; -import { endpoints } from "../../../util/constants.ts"; +import type { Bot } from "../../../bot.ts"; -/** Fetch all of the global commands for your application. */ -export async function getSlashCommands(guildId?: bigint) { - const result = await rest.runMethod( +/** Fetch all the global commands for your application. */ +export async function getSlashCommands(bot: Bot, guildId?: bigint) { + const result = await bot.rest.runMethod( + bot.rest, "get", - guildId ? endpoints.COMMANDS_GUILD(applicationId, guildId) : endpoints.COMMANDS(applicationId) + guildId + ? bot.constants.endpoints.COMMANDS_GUILD(bot.applicationId, guildId) + : bot.constants.endpoints.COMMANDS(bot.applicationId) ); return new Collection( result.map((command) => [ command.name, - { ...command, id: snowflakeToBigint(command.id), applicationId: snowflakeToBigint(command.applicationId) }, + { + ...command, + id: bot.transformers.snowflake(command.id), + applicationId: bot.transformers.snowflake(command.applicationId), + }, ]) ); } diff --git a/src/helpers/interactions/commands/upsert_slash_command.ts b/src/helpers/interactions/commands/upsert_slash_command.ts index 9b6c40e7e..7bd3c34ba 100644 --- a/src/helpers/interactions/commands/upsert_slash_command.ts +++ b/src/helpers/interactions/commands/upsert_slash_command.ts @@ -1,21 +1,24 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; import type { ApplicationCommand } from "../../../types/interactions/commands/application_command.ts"; import type { EditGlobalApplicationCommand } from "../../../types/interactions/commands/edit_global_application_command.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { validateSlashCommands } from "../../../util/utils.ts"; +import type { Bot } from "../../../bot.ts"; /** * Edit an existing slash command. If this command did not exist, it will create it. */ -export async function upsertSlashCommand(commandId: bigint, options: EditGlobalApplicationCommand, guildId?: bigint) { - [options] = validateSlashCommands([options]); +export async function upsertSlashCommand( + bot: Bot, + commandId: bigint, + options: EditGlobalApplicationCommand, + guildId?: bigint +) { + [options] = bot.utils.validateSlashCommands([options]); - return await rest.runMethod( + return await bot.rest.runMethod( + bot.rest, "patch", guildId - ? endpoints.COMMANDS_GUILD_ID(applicationId, guildId, commandId) - : endpoints.COMMANDS_ID(applicationId, commandId), + ? bot.constants.endpoints.COMMANDS_GUILD_ID(bot.applicationId, guildId, commandId) + : bot.constants.endpoints.COMMANDS_ID(bot.applicationId, commandId), options ); } diff --git a/src/helpers/interactions/commands/upsert_slash_commands.ts b/src/helpers/interactions/commands/upsert_slash_commands.ts index a3604c7cd..f7cd4e83f 100644 --- a/src/helpers/interactions/commands/upsert_slash_commands.ts +++ b/src/helpers/interactions/commands/upsert_slash_commands.ts @@ -1,10 +1,7 @@ -import { applicationId } from "../../../bot.ts"; -import { rest } from "../../../rest/rest.ts"; import type { ApplicationCommand } from "../../../types/interactions/commands/application_command.ts"; import type { EditGlobalApplicationCommand } from "../../../types/interactions/commands/edit_global_application_command.ts"; -import { MakeRequired } from "../../../types/util.ts"; -import { endpoints } from "../../../util/constants.ts"; -import { validateSlashCommands } from "../../../util/utils.ts"; +import type { MakeRequired } from "../../../types/util.ts"; +import type { Bot } from "../../../bot.ts"; /** * Bulk edit existing slash commands. If a command does not exist, it will create it. @@ -12,14 +9,18 @@ import { validateSlashCommands } from "../../../util/utils.ts"; * **NOTE:** Any slash commands that are not specified in this function will be **deleted**. If you don't provide the commandId and rename your command, the command gets a new Id. */ export async function upsertSlashCommands( + bot: Bot, options: MakeRequired[], guildId?: bigint ) { - options = validateSlashCommands(options) as MakeRequired[]; + options = bot.utils.validateSlashCommands(options) as MakeRequired[]; - return await rest.runMethod( + return await bot.rest.runMethod( + bot.rest, "put", - guildId ? endpoints.COMMANDS_GUILD(applicationId, guildId) : endpoints.COMMANDS(applicationId), + guildId + ? bot.constants.endpoints.COMMANDS_GUILD(bot.applicationId, guildId) + : bot.constants.endpoints.COMMANDS(bot.applicationId), options ); } diff --git a/src/helpers/interactions/get_original_interaction_response.ts b/src/helpers/interactions/get_original_interaction_response.ts index 51a72d268..accb0cf65 100644 --- a/src/helpers/interactions/get_original_interaction_response.ts +++ b/src/helpers/interactions/get_original_interaction_response.ts @@ -1,12 +1,14 @@ -import { applicationId } from "../../bot.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; +import type { Bot } from "../../bot.ts"; import type { Message } from "../../types/messages/message.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; -/** Returns the initial Interactio response. Functions the same as Get Webhook Message */ -export async function getOriginalInteractionResponse(token: string) { - const result = await rest.runMethod("get", endpoints.INTERACTION_ORIGINAL_ID_TOKEN(applicationId, token)); +/** Returns the initial Interaction response. Functions the same as Get Webhook Message */ +export async function getOriginalInteractionResponse(bot: Bot, token: string) { + const result = await bot.rest.runMethod>( + bot.rest, + "get", + bot.constants.endpoints.INTERACTION_ORIGINAL_ID_TOKEN(bot.applicationId, token) + ); - return await structures.createDiscordenoMessage(result); + return bot.transformers.message(bot, result); } diff --git a/src/helpers/interactions/send_interaction_response.ts b/src/helpers/interactions/send_interaction_response.ts index ebf995ee6..335fdc0d2 100644 --- a/src/helpers/interactions/send_interaction_response.ts +++ b/src/helpers/interactions/send_interaction_response.ts @@ -1,9 +1,10 @@ -import { applicationId, eventHandlers } from "../../bot.ts"; -import { cache } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; import type { DiscordenoInteractionResponse } from "../../types/discordeno/interaction_response.ts"; -import { endpoints } from "../../util/constants.ts"; -import { snakelize, validateComponents } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import { Embed } from "../../types/embeds/embed.ts"; +import { AllowedMentions } from "../../types/messages/allowed_mentions.ts"; +import { MessageReference } from "../../types/messages/message_reference.ts"; +import { FileContent } from "../../types/discordeno/file_content.ts"; +import { MessageComponents } from "../../types/messages/components/message_components.ts"; // TODO: v12 remove | string /** @@ -13,12 +14,13 @@ import { snakelize, validateComponents } from "../../util/utils.ts"; * NOTE: By default we will suppress mentions. To enable mentions, just pass any mentions object. */ export async function sendInteractionResponse( + bot: Bot, id: bigint | string, token: string, options: DiscordenoInteractionResponse ) { // TODO: add more options validations - if (options.data?.components) validateComponents(options.data?.components); + if (options.data?.components) bot.utils.validateComponents(bot, options.data?.components); // If the user wants this as a private message mark it ephemeral if (options.private) { @@ -31,8 +33,32 @@ export async function sendInteractionResponse( } // If its already been executed, we need to send a followup response - if (cache.executedSlashCommands.has(token)) { - return await rest.runMethod("post", endpoints.WEBHOOK(applicationId, token), snakelize(options.data)); + if (bot.cache.executedSlashCommands.has(token)) { + return await bot.rest.runMethod(bot.rest, "post", bot.cosntants.endpoints.WEBHOOK(bot.applicationId, token), { + content: options.data.content, + tts: options.data.tts, + embeds: options.data.embeds, + allowed_mentions: { + parse: options.data.allowedMentions.parse, + roles: options.data.allowedMentions.roles, + users: options.data.allowedMentions.users, + replied_user: options.data.allowedMentions.repliedUser, + }, + ...(options.data.messageReference?.messageId + ? { + message_reference: { + message_id: options.data.messageReference.messageId, + channel_id: options.data.messageReference.channelId, + guild_id: options.data.messageReference.guildId, + fail_if_not_exists: options.data.messageReference.failIfNotExists === true, + }, + } + : {}), + file: options.data.file, + // TODO: Snakelize components?? + components: options.data.components, + flags: options.data.flags, + }); } // Expire in 15 minutes @@ -42,9 +68,34 @@ export async function sendInteractionResponse( cache.executedSlashCommands.delete(token); }, 900000); - return await rest.runMethod( + return await bot.rest.runMethod( + bot.rest, "post", - endpoints.INTERACTION_ID_TOKEN(typeof id === "bigint" ? id : BigInt(id), token), - snakelize(options) + bot.constants.endpoints.INTERACTION_ID_TOKEN(typeof id === "bigint" ? id : bot.transformers.snowflake(id), token), + { + content: options.data.content, + tts: options.data.tts, + embeds: options.data.embeds, + allowed_mentions: { + parse: options.data.allowedMentions.parse, + roles: options.data.allowedMentions.roles, + users: options.data.allowedMentions.users, + replied_user: options.data.allowedMentions.repliedUser, + }, + ...(options.data.messageReference?.messageId + ? { + message_reference: { + message_id: options.data.messageReference.messageId, + channel_id: options.data.messageReference.channelId, + guild_id: options.data.messageReference.guildId, + fail_if_not_exists: options.data.messageReference.failIfNotExists === true, + }, + } + : {}), + file: options.data.file, + // TODO: Snakelize components?? + components: options.data.components, + flags: options.data.flags, + } ); } diff --git a/src/helpers/interactions/verify_signature.ts b/src/helpers/interactions/verify_signature.ts index 18fe8febe..f6f4a1806 100644 --- a/src/helpers/interactions/verify_signature.ts +++ b/src/helpers/interactions/verify_signature.ts @@ -1,5 +1,4 @@ -export { verify } from "https://unpkg.com/@evan/wasm@0.0.65/target/ed25519/deno.js"; -import { verify } from "./deps.ts"; +import { verify } from "https://unpkg.com/@evan/wasm@0.0.87/target/ed25519/deno.js"; export function verifySignature({ publicKey, signature, timestamp, body }: VerifySignatureOptions): { isValid: boolean; diff --git a/src/helpers/invites/create_invite.ts b/src/helpers/invites/create_invite.ts index 9060a0822..8523cf00c 100644 --- a/src/helpers/invites/create_invite.ts +++ b/src/helpers/invites/create_invite.ts @@ -1,14 +1,12 @@ -import { rest } from "../../rest/rest.ts"; import type { CreateChannelInvite } from "../../types/invites/create_channel_invite.ts"; import type { InviteMetadata } from "../../types/invites/invite_metadata.ts"; import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Creates a new invite for this channel. Requires CREATE_INSTANT_INVITE */ -export async function createInvite(channelId: bigint, options: CreateChannelInvite = {}) { - await requireBotChannelPermissions(channelId, ["CREATE_INSTANT_INVITE"]); +export async function createInvite(bot: Bot, channelId: bigint, options: CreateChannelInvite = {}) { + await bot.utils.requireBotChannelPermissions(channelId, ["CREATE_INSTANT_INVITE"]); if (options.maxAge && (options.maxAge < 0 || options.maxAge > 604800)) { throw new Error(Errors.INVITE_MAX_AGE_INVALID); @@ -17,5 +15,18 @@ export async function createInvite(channelId: bigint, options: CreateChannelInvi throw new Error(Errors.INVITE_MAX_USES_INVALID); } - return await rest.runMethod("post", endpoints.CHANNEL_INVITES(channelId), snakelize(options)); + return await bot.rest.runMethod>( + bot.rest, + "post", + bot.constants.endpoints.CHANNEL_INVITES(channelId), + { + max_age: options.maxAge, + max_uses: options.maxUses, + temporary: options.temporary, + unique: options.unique, + target_type: options.targetType, + target_user_id: options.targetUserId, + target_application_id: options.targetUserId, + } + ); } diff --git a/src/helpers/invites/delete_invite.ts b/src/helpers/invites/delete_invite.ts index fe033ddf6..48af20d99 100644 --- a/src/helpers/invites/delete_invite.ts +++ b/src/helpers/invites/delete_invite.ts @@ -1,19 +1,21 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; import type { InviteMetadata } from "../../types/invites/invite_metadata.ts"; -import { endpoints } from "../../util/constants.ts"; -import { botHasChannelPermissions, requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Deletes an invite for the given code. Requires `MANAGE_CHANNELS` or `MANAGE_GUILD` permission */ -export async function deleteInvite(channelId: bigint, inviteCode: string) { - const channel = await cacheHandlers.get("channels", channelId); +export async function deleteInvite(bot: Bot, channelId: bigint, inviteCode: string) { + const channel = await bot.cache.channels.get(channelId); if (channel) { - const hasPerm = await botHasChannelPermissions(channel, ["MANAGE_CHANNELS"]); + const hasPerm = await bot.utils.botHasChannelPermissions(channel, ["MANAGE_CHANNELS"]); if (!hasPerm) { - await requireBotGuildPermissions(channel.guildId, ["MANAGE_GUILD"]); + await bot.utils.requireBotGuildPermissions(channel.guildId, ["MANAGE_GUILD"]); } } - return await rest.runMethod("delete", endpoints.INVITE(inviteCode)); + return await bot.rest.runMethod>( + bot.rest, + "delete", + bot.constants.endpoints.INVITE(inviteCode) + ); } diff --git a/src/helpers/invites/get_channel_invites.ts b/src/helpers/invites/get_channel_invites.ts index 3877b6c7f..6c56df480 100644 --- a/src/helpers/invites/get_channel_invites.ts +++ b/src/helpers/invites/get_channel_invites.ts @@ -1,14 +1,17 @@ -import { rest } from "../../rest/rest.ts"; import type { InviteMetadata } from "../../types/invites/invite_metadata.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Gets the invites for this channel. Requires MANAGE_CHANNEL */ -export async function getChannelInvites(channelId: bigint) { - await requireBotChannelPermissions(channelId, ["MANAGE_CHANNELS"]); +export async function getChannelInvites(bot: Bot, channelId: bigint) { + await bot.utils.requireBotChannelPermissions(channelId, ["MANAGE_CHANNELS"]); - const result = await rest.runMethod("get", endpoints.CHANNEL_INVITES(channelId)); + const result = await bot.rest.runMethod[]>( + bot.rest, + "get", + bot.constants.endpoints.CHANNEL_INVITES(channelId) + ); return new Collection(result.map((invite) => [invite.code, invite])); } diff --git a/src/helpers/invites/get_invite.ts b/src/helpers/invites/get_invite.ts index dbe9c7062..aead6734c 100644 --- a/src/helpers/invites/get_invite.ts +++ b/src/helpers/invites/get_invite.ts @@ -1,10 +1,16 @@ -import { rest } from "../../rest/rest.ts"; import { GetInvite } from "../../types/invites/get_invite.ts"; import type { InviteMetadata } from "../../types/invites/invite_metadata.ts"; -import { endpoints } from "../../util/constants.ts"; -import { snakelize } from "../../util/utils.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; +import type { Bot } from "../../bot.ts"; /** Returns an invite for the given code or throws an error if the invite doesn't exists. */ -export async function getInvite(inviteCode: string, options?: GetInvite) { - return await rest.runMethod("get", endpoints.INVITE(inviteCode), snakelize(options ?? {})); +export async function getInvite(bot: Bot, inviteCode: string, options?: GetInvite) { + return await bot.rest.runMethod>( + "get", + bot.constants.endpoints.INVITE(inviteCode), + { + with_counts: options.withCounts, + with_expiration: options.withExpiration, + } + ); } diff --git a/src/helpers/invites/get_invites.ts b/src/helpers/invites/get_invites.ts index 59098bfbf..71926a2c1 100644 --- a/src/helpers/invites/get_invites.ts +++ b/src/helpers/invites/get_invites.ts @@ -1,14 +1,16 @@ -import { rest } from "../../rest/rest.ts"; import type { InviteMetadata } from "../../types/invites/invite_metadata.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; +import type { Bot } from "../../bot.ts"; /** Get all the invites for this guild. Requires MANAGE_GUILD permission */ -export async function getInvites(guildId: bigint) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function getInvites(bot: Bot, guildId: bigint) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); - const result = await rest.runMethod("get", endpoints.GUILD_INVITES(guildId)); + const result = await bot.rest.runMethod[]>( + "get", + bot.constants.endpoints.GUILD_INVITES(guildId) + ); return new Collection(result.map((invite) => [invite.code, invite])); } diff --git a/src/helpers/members/avatar_url.ts b/src/helpers/members/avatar_url.ts index c6c950cdc..2dc138c2b 100644 --- a/src/helpers/members/avatar_url.ts +++ b/src/helpers/members/avatar_url.ts @@ -1,11 +1,10 @@ import type { DiscordImageFormat } from "../../types/misc/image_format.ts"; import type { DiscordImageSize } from "../../types/misc/image_size.ts"; -import { endpoints } from "../../util/constants.ts"; -import { iconBigintToHash } from "../../util/hash.ts"; -import { formatImageURL } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** The users custom avatar or the default avatar if you don't have a member object. */ export function avatarURL( + bot: Bot, userId: bigint, discriminator: number, options: { @@ -16,15 +15,15 @@ export function avatarURL( } ) { return options.avatar - ? formatImageURL( - endpoints.USER_AVATAR( + ? bot.utils.formatImageURL( + bot.constants.endpoints.USER_AVATAR( userId, typeof options.avatar === "string" ? options.avatar - : iconBigintToHash(options.avatar, options.animated ?? true) + : bot.utils.iconBigintToHash(options.avatar, options.animated ?? true) ), options.size || 128, options.format ) - : endpoints.USER_DEFAULT_AVATAR(Number(discriminator) % 5); + : bot.constants.endpoints.USER_DEFAULT_AVATAR(Number(discriminator) % 5); } diff --git a/src/helpers/members/ban_member.ts b/src/helpers/members/ban_member.ts index a94f73d41..06a986f0a 100644 --- a/src/helpers/members/ban_member.ts +++ b/src/helpers/members/ban_member.ts @@ -1,14 +1,21 @@ -import { rest } from "../../rest/rest.ts"; import type { CreateGuildBan } from "../../types/guilds/create_guild_ban.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** Ban a user from the guild and optionally delete previous messages sent by the user. Requires the BAN_MEMBERS permission. */ -export async function ban(guildId: bigint, id: bigint, options?: CreateGuildBan) { - await requireBotGuildPermissions(guildId, ["BAN_MEMBERS"]); +export async function ban(bot: Bot, guildId: bigint, id: bigint, options?: CreateGuildBan) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]); - return await rest.runMethod("put", endpoints.GUILD_BAN(guildId, id), snakelize(options ?? {})); + return await bot.rest.runMethod( + bot.rest, + "put", + bot.constants.endpoints.GUILD_BAN(guildId, id), + options + ? { + delete_message_days: options.deleteMessageDays, + reason: options.reason, + } + : {} + ); } // aliases diff --git a/src/helpers/members/disconnect_member.ts b/src/helpers/members/disconnect_member.ts index a1d4b0b9c..71bc6897e 100644 --- a/src/helpers/members/disconnect_member.ts +++ b/src/helpers/members/disconnect_member.ts @@ -1,6 +1,6 @@ -import { editMember } from "./edit_member.ts"; +import type { Bot } from "../../bot.ts"; /** Kicks a member from a voice channel */ -export function disconnectMember(guildId: bigint, memberId: bigint) { - return editMember(guildId, memberId, { channelId: null }); +export function disconnectMember(bot: Bot, guildId: bigint, memberId: bigint) { + return bot.helpers.editMember(bot, guildId, memberId, { channelId: null }); } diff --git a/src/helpers/members/edit_bot_nickname.ts b/src/helpers/members/edit_bot_nickname.ts index 9ab18893b..822cc6e42 100644 --- a/src/helpers/members/edit_bot_nickname.ts +++ b/src/helpers/members/edit_bot_nickname.ts @@ -1,14 +1,17 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Edit the nickname of the bot in this guild */ -export async function editBotNickname(guildId: bigint, nickname: string | null) { - await requireBotGuildPermissions(guildId, ["CHANGE_NICKNAME"]); +export async function editBotNickname(bot: Bot, guildId: bigint, nickname: string | null) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["CHANGE_NICKNAME"]); - const response = await rest.runMethod<{ nick: string }>("patch", endpoints.USER_NICK(guildId), { - nick: nickname, - }); + const response = await bot.rest.runMethod<{ nick: string }>( + bot.rest, + "patch", + bot.constants.endpoints.USER_NICK(guildId), + { + nick: nickname, + } + ); return response.nick; } diff --git a/src/helpers/members/edit_member.ts b/src/helpers/members/edit_member.ts index 2be793376..d38d93eb2 100644 --- a/src/helpers/members/edit_member.ts +++ b/src/helpers/members/edit_member.ts @@ -1,22 +1,16 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import type { ModifyGuildMember } from "../../types/guilds/modify_guild_member.ts"; import type { GuildMemberWithUser } from "../../types/members/guild_member.ts"; import type { PermissionStrings } from "../../types/permissions/permission_strings.ts"; -import { bigintToSnowflake } from "../../util/bigint.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions, requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Edit the member */ -export async function editMember(guildId: bigint, memberId: bigint, options: ModifyGuildMember) { +export async function editMember(bot: Bot, guildId: bigint, memberId: bigint, options: ModifyGuildMember) { const requiredPerms: Set = new Set(); if (options.nick) { if (options.nick.length > 32) { - throw new Error(Errors.NICKNAMES_MAX_LENGTH); + throw new Error(bot.constants.Errors.NICKNAMES_MAX_LENGTH); } requiredPerms.add("MANAGE_NICKNAMES"); } @@ -24,10 +18,10 @@ export async function editMember(guildId: bigint, memberId: bigint, options: Mod if (options.roles) requiredPerms.add("MANAGE_ROLES"); if (options.mute !== undefined || options.deaf !== undefined || options.channelId !== undefined) { - const memberVoiceState = (await cacheHandlers.get("guilds", guildId))?.voiceStates.get(memberId); + const memberVoiceState = (await bot.cache.guilds.get(guildId))?.voiceStates.get(memberId); if (!memberVoiceState?.channelId) { - throw new Error(Errors.MEMBER_NOT_IN_VOICE_CHANNEL); + throw new Error(bot.constants.Errors.MEMBER_NOT_IN_VOICE_CHANNEL); } if (options.mute !== undefined) { @@ -41,21 +35,26 @@ export async function editMember(guildId: bigint, memberId: bigint, options: Mod if (options.channelId) { const requiredVoicePerms: Set = new Set(["CONNECT", "MOVE_MEMBERS"]); if (memberVoiceState) { - await requireBotChannelPermissions(memberVoiceState?.channelId, [...requiredVoicePerms]); + await bot.utils.requireBotChannelPermissions(bot, memberVoiceState?.channelId, [...requiredVoicePerms]); } - await requireBotChannelPermissions(options.channelId, [...requiredVoicePerms]); + await bot.utils.requireBotChannelPermissions(bot, options.channelId, [...requiredVoicePerms]); } } - await requireBotGuildPermissions(guildId, [...requiredPerms]); + await bot.utils.requireBotGuildPermissions(bot, guildId, [...requiredPerms]); - const result = await rest.runMethod( + const result = await bot.rest.runMethod>( + bot.rest, "patch", - endpoints.GUILD_MEMBER(guildId, memberId), - snakelize(options) as ModifyGuildMember + bot.constants.endpoints.GUILD_MEMBER(guildId, memberId), + { + nick: options.nick, + roles: options.roles, + mute: options.mute, + deaf: options.deaf, + channel_id: options.channelId, + } ); - const member = await structures.createDiscordenoMember(result, guildId); - - return member; + return bot.transformers.member(bot, result, guildId); } diff --git a/src/helpers/members/fetch_members.ts b/src/helpers/members/fetch_members.ts index cfec6a943..421614bce 100644 --- a/src/helpers/members/fetch_members.ts +++ b/src/helpers/members/fetch_members.ts @@ -1,11 +1,9 @@ -import { cache } from "../../cache.ts"; -import { DiscordenoMember } from "../../structures/member.ts"; -import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { DiscordGatewayIntents } from "../../types/gateway/gateway_intents.ts"; import type { RequestGuildMembers } from "../../types/members/request_guild_members.ts"; import { Collection } from "../../util/collection.ts"; -import { ws } from "../../ws/ws.ts"; +import type { Bot } from "../../bot.ts"; +import { DiscordGatewayIntents } from "../../types/gateway/gateway_intents.ts"; +import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts"; +import type { DiscordenoMember } from "../../transformers/member.ts"; /** * ⚠️ BEGINNER DEVS!! YOU SHOULD ALMOST NEVER NEED THIS AND YOU CAN GET FROM cache.members.get() @@ -15,15 +13,20 @@ import { ws } from "../../ws/ws.ts"; * REST: 50/s global(across all shards) rate limit with ALL requests this included * GW(this function): 120/m(PER shard) rate limit. Meaning if you have 8 shards your limit is now 960/m. */ -export function fetchMembers(guildId: bigint, shardId: number, options?: Omit) { +export function fetchMembers( + bot: Bot, + guildId: bigint, + shardId: number, + options?: Omit +) { // You can request 1 member without the intent // Check if intents is not 0 as proxy ws won't set intents in other instances if ( - ws.identifyPayload.intents && + bot.gateway.identifyPayload.intents && (!options?.limit || options.limit > 1) && - !(ws.identifyPayload.intents & DiscordGatewayIntents.GuildMembers) + !(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers) ) { - throw new Error(Errors.MISSING_INTENT_GUILD_MEMBERS); + throw new Error(bot.constants.Errors.MISSING_INTENT_GUILD_MEMBERS); } if (options?.userIds?.length) { @@ -32,9 +35,10 @@ export function fetchMembers(guildId: bigint, shardId: number, options?: Omit { const nonce = `${guildId}-${Date.now()}`; + // TODO: FIND A BETTER WAY TO DO THAT? cache.fetchAllMembersProcessingRequests.set(nonce, resolve); - ws.sendShardMessage(shardId, { + bot.gateway.sendShardMessage(shardId, { op: DiscordGatewayOpcodes.RequestGuildMembers, d: { guild_id: guildId, diff --git a/src/helpers/members/get_member.ts b/src/helpers/members/get_member.ts index 0aff1bde9..3620e611a 100644 --- a/src/helpers/members/get_member.ts +++ b/src/helpers/members/get_member.ts @@ -1,21 +1,23 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { GuildMemberWithUser } from "../../types/members/guild_member.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Returns a guild member object for the specified user. * * ⚠️ **ADVANCED USE ONLY: Your members will be cached in your guild most likely. Only use this when you are absolutely sure the member is not cached.** */ -export async function getMember(guildId: bigint, id: bigint, options?: { force?: boolean }) { - const guild = await cacheHandlers.get("guilds", guildId); +export async function getMember(bot: Bot, guildId: bigint, id: bigint, options?: { force?: boolean }) { + const guild = await bot.cache.guilds.get(guildId); if (!guild && !options?.force) return; - const data = await rest.runMethod("get", endpoints.GUILD_MEMBER(guildId, id)); + const data = await bot.rest.runMethod>( + bot.rest, + "get", + bot.constants.endpoints.GUILD_MEMBER(guildId, id) + ); - const discordenoMember = await structures.createDiscordenoMember(data, guildId); - await cacheHandlers.set("members", discordenoMember.id, discordenoMember); + const discordenoMember = await bot.transformers.member(bot, data, guildId); + await bot.cache.members.set(discordenoMember.id, discordenoMember); return discordenoMember; } diff --git a/src/helpers/members/get_members.ts b/src/helpers/members/get_members.ts index 5de01de80..00ec95836 100644 --- a/src/helpers/members/get_members.ts +++ b/src/helpers/members/get_members.ts @@ -1,16 +1,10 @@ -import { eventHandlers } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { DiscordenoMember } from "../../structures/member.ts"; -import { structures } from "../../structures/mod.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import { DiscordGatewayIntents } from "../../types/gateway/gateway_intents.ts"; import type { GuildMemberWithUser } from "../../types/members/guild_member.ts"; import type { ListGuildMembers } from "../../types/members/list_guild_members.ts"; -import { bigintToSnowflake } from "../../util/bigint.ts"; +import type { Bot } from "../../bot.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; -import { ws } from "../../ws/ws.ts"; +import type { DiscordenoMember } from "../../transformers/member.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** * ⚠️ BEGINNER DEVS!! YOU SHOULD ALMOST NEVER NEED THIS AND YOU CAN GET FROM cache.members.get() @@ -20,14 +14,17 @@ import { ws } from "../../ws/ws.ts"; * REST(this function): 50/s global(across all shards) rate limit with ALL requests this included * GW(fetchMembers): 120/m(PER shard) rate limit. Meaning if you have 8 shards your limit is 960/m. */ -export async function getMembers(guildId: bigint, options?: ListGuildMembers & { addToCache?: boolean }) { +export async function getMembers(bot: Bot, guildId: bigint, options?: ListGuildMembers & { addToCache?: boolean }) { // Check if intents is not 0 as proxy ws won't set intents in other instances - if (ws.identifyPayload.intents && !(ws.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)) { - throw new Error(Errors.MISSING_INTENT_GUILD_MEMBERS); + if ( + bot.gateway.identifyPayload.intents && + !(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers) + ) { + throw new Error(bot.cache.Errors.MISSING_INTENT_GUILD_MEMBERS); } const guild = await cacheHandlers.get("guilds", guildId); - if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); + if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND); const members = new Collection(); @@ -40,19 +37,20 @@ export async function getMembers(guildId: bigint, options?: ListGuildMembers & { console.log(`Paginating get members from REST. #${loops} / ${Math.ceil((options?.limit ?? 1) / 1000)}`); } - const result = await rest.runMethod( + const result = await bot.rest.runMethod[]>( + bot.rest, "get", - `${endpoints.GUILD_MEMBERS(guildId)}?limit=${membersLeft > 1000 ? 1000 : membersLeft}${ + `${bot.constants.endpoints.GUILD_MEMBERS(guildId)}?limit=${membersLeft > 1000 ? 1000 : membersLeft}${ options?.after ? `&after=${options.after}` : "" }` ); const discordenoMembers = await Promise.all( result.map(async (member) => { - const discordenoMember = await structures.createDiscordenoMember(member, guildId); + const discordenoMember = bot.transformers.member(member, guildId); if (options?.addToCache !== false) { - await cacheHandlers.set("members", discordenoMember.id, discordenoMember); + await bot.cache.members.set(discordenoMember.id, discordenoMember); } return discordenoMember; @@ -62,13 +60,13 @@ export async function getMembers(guildId: bigint, options?: ListGuildMembers & { if (!discordenoMembers.length) break; discordenoMembers.forEach((member) => { - eventHandlers.debug?.("loop", `Running forEach loop in get_members file.`); + bot.events.debug("loop", `Running forEach loop in get_members file.`); members.set(member.id, member); }); options = { limit: options?.limit, - after: bigintToSnowflake(discordenoMembers[discordenoMembers.length - 1].id), + after: bot.transformers.snowflake(discordenoMembers[discordenoMembers.length - 1].id), }; membersLeft -= 1000; diff --git a/src/helpers/members/kick_member.ts b/src/helpers/members/kick_member.ts index 4f9306a9a..f746ee3a9 100644 --- a/src/helpers/members/kick_member.ts +++ b/src/helpers/members/kick_member.ts @@ -1,20 +1,20 @@ -import { botId } from "../../bot.ts"; -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { highestRole, requireBotGuildPermissions } from "../../util/permissions.ts"; - +import { Bot } from "../../bot.ts"; /** Kick a member from the server */ -export async function kick(guildId: bigint, memberId: bigint, reason?: string) { - const botsHighestRole = await highestRole(guildId, botId); - const membersHighestRole = await highestRole(guildId, memberId); +export async function kick(bot: Bot, guildId: bigint, memberId: bigint, reason?: string) { + const botsHighestRole = await bot.utils.highestRole(bot, guildId, botId); + const membersHighestRole = await bot.utils.highestRole(bot, guildId, memberId); if (botsHighestRole && membersHighestRole && botsHighestRole.position <= membersHighestRole.position) { - throw new Error(Errors.BOTS_HIGHEST_ROLE_TOO_LOW); + throw new Error(bot.constants.Errors.BOTS_HIGHEST_ROLE_TOO_LOW); } - await requireBotGuildPermissions(guildId, ["KICK_MEMBERS"]); + await bot.utils.requireBotGuildPermissions(bot, guildId, ["KICK_MEMBERS"]); - return await rest.runMethod("delete", endpoints.GUILD_MEMBER(guildId, memberId), { reason }); + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.GUILD_MEMBER(guildId, memberId), + { reason } + ); } // aliases diff --git a/src/helpers/members/move_member.ts b/src/helpers/members/move_member.ts index fd1b871d1..ce0b061ea 100644 --- a/src/helpers/members/move_member.ts +++ b/src/helpers/members/move_member.ts @@ -1,11 +1,12 @@ -import { editMember } from "./edit_member.ts"; +import type { Bot } from "../../bot.ts"; /** * Move a member from a voice channel to another. + * @param bot the bot * @param guildId the id of the guild which the channel exists in * @param memberId the id of the member to move. * @param channelId id of channel to move user to (if they are connected to voice) */ -export function moveMember(guildId: bigint, memberId: bigint, channelId: bigint) { - return editMember(guildId, memberId, { channelId }); +export function moveMember(bot: Bot, guildId: bigint, memberId: bigint, channelId: bigint) { + return bot.helpers.editMember(bot, guildId, memberId, { channelId }); } diff --git a/src/helpers/members/prune_members.ts b/src/helpers/members/prune_members.ts index c6ad13bc7..22924ac9f 100644 --- a/src/helpers/members/prune_members.ts +++ b/src/helpers/members/prune_members.ts @@ -1,22 +1,27 @@ -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import type { BeginGuildPrune } from "../../types/guilds/begin_guild_prune.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** * Begin a prune operation. Requires the KICK_MEMBERS permission. Returns an object with one 'pruned' key indicating the number of members that were removed in the prune operation. For large guilds it's recommended to set the computePruneCount option to false, forcing 'pruned' to null. Fires multiple Guild Member Remove Gateway events. * * By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the roles (resolved to include_roles internally) parameter. Any inactive user that has a subset of the provided role(s) will be included in the prune and users with additional roles will not. */ -export async function pruneMembers(guildId: bigint, options: BeginGuildPrune) { - if (options.days && options.days < 1) throw new Error(Errors.PRUNE_MIN_DAYS); - if (options.days && options.days > 30) throw new Error(Errors.PRUNE_MAX_DAYS); +export async function pruneMembers(bot: Bot, guildId: bigint, options: BeginGuildPrune) { + if (options.days && options.days < 1) throw new Error(bot.constants.Errors.PRUNE_MIN_DAYS); + if (options.days && options.days > 30) throw new Error(bot.constants.Errors.PRUNE_MAX_DAYS); - await requireBotGuildPermissions(guildId, ["KICK_MEMBERS"]); + await bot.utils.requireBotGuildPermissions(bot, guildId, ["KICK_MEMBERS"]); - const result = await rest.runMethod<{ pruned: number }>("post", endpoints.GUILD_PRUNE(guildId), snakelize(options)); + const result = await bot.rest.runMethod<{ pruned: number }>( + bot.rest, + "post", + bot.constants.endpoints.GUILD_PRUNE(guildId), + { + days: options.days, + compute_prune_count: options.computePruneCount, + include_roles: options.includeRoles, + } + ); return result.pruned; } diff --git a/src/helpers/members/search_members.ts b/src/helpers/members/search_members.ts index 06c389a23..785911300 100644 --- a/src/helpers/members/search_members.ts +++ b/src/helpers/members/search_members.ts @@ -1,39 +1,45 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { DiscordenoMember } from "../../structures/member.ts"; -import { structures } from "../../structures/mod.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; import type { GuildMemberWithUser } from "../../types/members/guild_member.ts"; import type { SearchGuildMembers } from "../../types/members/search_guild_members.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; +import { Bot } from "../../bot.ts"; +import { DiscordenoMember } from "../../transformers/member.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** * ⚠️ BEGINNER DEVS!! YOU SHOULD ALMOST NEVER NEED THIS AND YOU CAN GET FROM cache.members.filter() + * @param bot + * @param guildId * @param query Query string to match username(s) and nickname(s) against + * @param options */ export async function searchMembers( + bot: Bot, guildId: bigint, query: string, options?: Omit & { cache?: boolean } ) { if (options?.limit) { - if (options.limit < 1) throw new Error(Errors.MEMBER_SEARCH_LIMIT_TOO_LOW); + if (options.limit < 1) throw new Error(bot.constants.Errors.MEMBER_SEARCH_LIMIT_TOO_LOW); if (options.limit > 1000) { - throw new Error(Errors.MEMBER_SEARCH_LIMIT_TOO_HIGH); + throw new Error(bot.constants.Errors.MEMBER_SEARCH_LIMIT_TOO_HIGH); } } - const result = await rest.runMethod("get", endpoints.GUILD_MEMBERS_SEARCH(guildId), { - ...options, - query, - }); + const result = await bot.rest.runMethod[]>( + bot.rest, + "get", + bot.constants.endpoints.GUILD_MEMBERS_SEARCH(guildId), + { + ...options, + query, + } + ); const members = await Promise.all( result.map(async (member) => { - const discordenoMember = await structures.createDiscordenoMember(member, guildId); + const discordenoMember = bot.transformers.member(bot, member, guildId); if (options?.cache) { - await cacheHandlers.set("members", discordenoMember.id, discordenoMember); + await bot.cache.members.set(discordenoMember.id, discordenoMember); } return discordenoMember; diff --git a/src/helpers/members/send_direct_message.ts b/src/helpers/members/send_direct_message.ts index d38a6027d..ff5262b48 100644 --- a/src/helpers/members/send_direct_message.ts +++ b/src/helpers/members/send_direct_message.ts @@ -1,29 +1,29 @@ -import { botId } from "../../bot.ts"; -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Channel } from "../../types/channels/channel.ts"; import type { CreateMessage } from "../../types/messages/create_message.ts"; -import { Errors } from "../../types/mod.ts"; -import { endpoints } from "../../util/constants.ts"; -import { sendMessage } from "../messages/send_message.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Send a message to a users DM. Note: this takes 2 API calls. 1 is to fetch the users dm channel. 2 is to send a message to that channel. */ -export async function sendDirectMessage(memberId: bigint, content: string | CreateMessage) { - if (memberId === botId) throw new Error(Errors.YOU_CAN_NOT_DM_THE_BOT_ITSELF); - - let dmChannel = await cacheHandlers.get("channels", memberId); +export async function sendDirectMessage(bot: Bot, memberId: bigint, content: string | CreateMessage) { + if (memberId === bot.id) throw new Error(bot.constants.Errors.YOU_CAN_NOT_DM_THE_BOT_ITSELF); + + let dmChannel = await bot.cache.channels.get(memberId); if (!dmChannel) { // If not available in cache create a new one. - const dmChannelData = await rest.runMethod("post", endpoints.USER_DM, { - recipient_id: memberId, - }); - const discordenoChannel = await structures.createDiscordenoChannel(dmChannelData); + const dmChannelData = await bot.rest.runMethod>( + bot.rest, + "post", + bot.constants.endpoints.USER_DM, + { + recipient_id: memberId, + } + ); + const discordenoChannel = await bot.transformers.channel(bot, { channel: dmChannelData }); // Recreate the channel and add it under the users id - await cacheHandlers.set("channels", memberId, discordenoChannel); + await bot.cache.channels.set(memberId, discordenoChannel); dmChannel = discordenoChannel; } // If it does exist try sending a message to this user - return await sendMessage(dmChannel.id, content); + return await bot.helpers.sendMessage(dmChannel.id, content); } diff --git a/src/helpers/members/unban_member.ts b/src/helpers/members/unban_member.ts index 75beb27a6..f3ada1e2d 100644 --- a/src/helpers/members/unban_member.ts +++ b/src/helpers/members/unban_member.ts @@ -1,12 +1,10 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Remove the ban for a user. Requires BAN_MEMBERS permission */ -export async function unban(guildId: bigint, id: bigint) { - await requireBotGuildPermissions(guildId, ["BAN_MEMBERS"]); +export async function unban(bot: Bot, guildId: bigint, id: bigint) { + await bot.utils.requireBotGuildPermissions(guildId, ["BAN_MEMBERS"]); - return await rest.runMethod("delete", endpoints.GUILD_BAN(guildId, id)); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.GUILD_BAN(guildId, id)); } // aliases diff --git a/src/helpers/messages/add_reaction.ts b/src/helpers/messages/add_reaction.ts index cc8691179..c832b53c3 100644 --- a/src/helpers/messages/add_reaction.ts +++ b/src/helpers/messages/add_reaction.ts @@ -1,10 +1,8 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Create a reaction for the message. Reaction takes the form of **name:id** for custom guild emoji, or Unicode characters. Requires READ_MESSAGE_HISTORY and ADD_REACTIONS */ -export async function addReaction(channelId: bigint, messageId: bigint, reaction: string) { - await requireBotChannelPermissions(channelId, ["ADD_REACTIONS", "READ_MESSAGE_HISTORY"]); +export async function addReaction(bot: Bot, channelId: bigint, messageId: bigint, reaction: string) { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["ADD_REACTIONS", "READ_MESSAGE_HISTORY"]); if (reaction.startsWith("<:")) { reaction = reaction.substring(2, reaction.length - 1); @@ -12,5 +10,9 @@ export async function addReaction(channelId: bigint, messageId: bigint, reaction reaction = reaction.substring(3, reaction.length - 1); } - return await rest.runMethod("put", endpoints.CHANNEL_MESSAGE_REACTION_ME(channelId, messageId, reaction)); + return await bot.rest.runMethod( + bot.rest, + "put", + bot.constants.endpoints.CHANNEL_MESSAGE_REACTION_ME(channelId, messageId, reaction) + ); } diff --git a/src/helpers/messages/add_reactions.ts b/src/helpers/messages/add_reactions.ts index 00d3d6803..4fe1fbff0 100644 --- a/src/helpers/messages/add_reactions.ts +++ b/src/helpers/messages/add_reactions.ts @@ -1,14 +1,19 @@ -import { eventHandlers } from "../../bot.ts"; -import { addReaction } from "./add_reaction.ts"; +import type { Bot } from "../../bot.ts"; /** Adds multiple reactions to a message. If `ordered` is true(default is false), it will add the reactions one at a time in the order provided. Note: Reaction takes the form of **name:id** for custom guild emoji, or Unicode characters. Requires READ_MESSAGE_HISTORY and ADD_REACTIONS */ -export async function addReactions(channelId: bigint, messageId: bigint, reactions: string[], ordered = false) { +export async function addReactions( + bot: Bot, + channelId: bigint, + messageId: bigint, + reactions: string[], + ordered = false +) { if (!ordered) { - await Promise.all(reactions.map((reaction) => addReaction(channelId, messageId, reaction))); + await Promise.all(reactions.map((reaction) => bot.helpers.addReaction(bot, channelId, messageId, reaction))); } else { for (const reaction of reactions) { - eventHandlers.debug?.("loop", "Running for of loop in addReactions function."); - await addReaction(channelId, messageId, reaction); + bot.events.debug("loop", "Running for of loop in addReactions function."); + await bot.helpers.addReaction(bot, channelId, messageId, reaction); } } } diff --git a/src/helpers/messages/delete_message.ts b/src/helpers/messages/delete_message.ts index 1753254cf..6926f1011 100644 --- a/src/helpers/messages/delete_message.ts +++ b/src/helpers/messages/delete_message.ts @@ -1,19 +1,26 @@ -import { botId } from "../../bot.ts"; import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { delay } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; /** Delete a message with the channel id and message id only. */ -export async function deleteMessage(channelId: bigint, messageId: bigint, reason?: string, delayMilliseconds = 0) { +export async function deleteMessage( + bot: Bot, + channelId: bigint, + messageId: bigint, + reason?: string, + delayMilliseconds = 0 +) { const message = await cacheHandlers.get("messages", messageId); - if (message && message.authorId !== botId) { - await requireBotChannelPermissions(message.channelId, ["MANAGE_MESSAGES"]); + if (message && message.authorId !== bot.id) { + await bot.utils.requireBotChannelPermissions(bot, message.channelId, ["MANAGE_MESSAGES"]); } - if (delayMilliseconds) await delay(delayMilliseconds); + if (delayMilliseconds) await bot.utils.delay(delayMilliseconds); - return await rest.runMethod("delete", endpoints.CHANNEL_MESSAGE(channelId, messageId), { reason }); + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId), + { reason } + ); } diff --git a/src/helpers/messages/delete_messages.ts b/src/helpers/messages/delete_messages.ts index f95ec54dd..57159b481 100644 --- a/src/helpers/messages/delete_messages.ts +++ b/src/helpers/messages/delete_messages.ts @@ -1,21 +1,18 @@ -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Delete messages from the channel. 2-100. Requires the MANAGE_MESSAGES permission */ -export async function deleteMessages(channelId: bigint, ids: bigint[], reason?: string) { - await requireBotChannelPermissions(channelId, ["MANAGE_MESSAGES"]); +export async function deleteMessages(bot: Bot, channelId: bigint, ids: bigint[], reason?: string) { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]); if (ids.length < 2) { - throw new Error(Errors.DELETE_MESSAGES_MIN); + throw new Error(bot.constants.Errors.DELETE_MESSAGES_MIN); } if (ids.length > 100) { console.warn(`This endpoint only accepts a maximum of 100 messages. Deleting the first 100 message ids provided.`); } - return await rest.runMethod("post", endpoints.CHANNEL_BULK_DELETE(channelId), { + return await bot.rest.runMethod(bot.rest, "post", bot.constants.endpoints.CHANNEL_BULK_DELETE(channelId), { messages: ids.splice(0, 100), reason, }); diff --git a/src/helpers/messages/edit_message.ts b/src/helpers/messages/edit_message.ts index bd58ba51f..c8e227cf3 100644 --- a/src/helpers/messages/edit_message.ts +++ b/src/helpers/messages/edit_message.ts @@ -1,45 +1,41 @@ -import { botId } from "../../bot.ts"; import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { EditMessage } from "../../types/messages/edit_message.ts"; +import type { EditMessage } from "../../types/messages/edit_message.ts"; import type { Message } from "../../types/messages/message.ts"; import type { PermissionStrings } from "../../types/permissions/permission_strings.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { snakelize, validateComponents } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Edit the message. */ -export async function editMessage(channelId: bigint, messageId: bigint, content: string | EditMessage) { +export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint, content: string | EditMessage) { const message = await cacheHandlers.get("messages", messageId); if (message) { - if (message.authorId !== botId) { + if (message.authorId !== bot.id) { throw new Error("You can only edit a message that was sent by the bot."); } const requiredPerms: PermissionStrings[] = ["SEND_MESSAGES"]; - await requireBotChannelPermissions(message.channelId, requiredPerms); + await bot.utils.requireBotChannelPermissions(bot, message.channelId, requiredPerms); } if (typeof content === "string") content = { content }; if (content.components?.length) { - validateComponents(content.components); + bot.utils.validateComponents(bot, content.components); } content.embeds?.splice(10); if (content.content && content.content.length > 2000) { - throw new Error(Errors.MESSAGE_MAX_LENGTH); + throw new Error(bot.constants.Errors.MESSAGE_MAX_LENGTH); } - const result = await rest.runMethod( + const result = await bot.rest.runMethod>( + bot.rest, "patch", - endpoints.CHANNEL_MESSAGE(channelId, messageId), - snakelize(content) + bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId), + bot.utils.snakelize(content) ); - return await structures.createDiscordenoMessage(result); + return bot.transformers.message(bot, result); } diff --git a/src/helpers/messages/get_message.ts b/src/helpers/messages/get_message.ts index b925abf98..2267ef9f4 100644 --- a/src/helpers/messages/get_message.ts +++ b/src/helpers/messages/get_message.ts @@ -1,17 +1,19 @@ import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Message } from "../../types/messages/message.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Fetch a single message from the server. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */ -export async function getMessage(channelId: bigint, id: bigint) { +export async function getMessage(bot: Bot, channelId: bigint, id: bigint) { if (await cacheHandlers.has("channels", channelId)) { - await requireBotChannelPermissions(channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]); + await bot.utils.requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]); } - const result = await rest.runMethod("get", endpoints.CHANNEL_MESSAGE(channelId, id)); + const result = await bot.rest.runMethod>( + bot.rest, + "get", + bot.constants.endpoints.CHANNEL_MESSAGE(channelId, id) + ); - return await structures.createDiscordenoMessage(result); + return bot.transformers.message(bot, result); } diff --git a/src/helpers/messages/get_messages.ts b/src/helpers/messages/get_messages.ts index 38e9c2ea8..d5ece4f63 100644 --- a/src/helpers/messages/get_messages.ts +++ b/src/helpers/messages/get_messages.ts @@ -1,28 +1,31 @@ -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { +import type { GetMessagesAfter, GetMessagesAround, GetMessagesBefore, GetMessagesLimit, } from "../../types/messages/get_messages.ts"; import type { Message } from "../../types/messages/message.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Fetches between 2-100 messages. Requires VIEW_CHANNEL and READ_MESSAGE_HISTORY */ export async function getMessages( + bot: Bot, channelId: bigint, options?: GetMessagesAfter | GetMessagesBefore | GetMessagesAround | GetMessagesLimit ) { - await requireBotChannelPermissions(channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]); + await bot.utils.requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]); if (options?.limit && (options.limit < 0 || options.limit > 100)) { - throw new Error(Errors.INVALID_GET_MESSAGES_LIMIT); + throw new Error(bot.constants.Errors.INVALID_GET_MESSAGES_LIMIT); } - const result = await rest.runMethod("get", endpoints.CHANNEL_MESSAGES(channelId), options); + const result = await bot.rest.runMethod[]>( + bot.rest, + "get", + bot.constants.endpoints.CHANNEL_MESSAGES(channelId), + options + ); - return await Promise.all(result.map((res) => structures.createDiscordenoMessage(res))); + return await Promise.all(result.map((res) => bot.transformers.message(bot, res))); } diff --git a/src/helpers/messages/get_reactions.ts b/src/helpers/messages/get_reactions.ts index 7bf1ba976..600d682e9 100644 --- a/src/helpers/messages/get_reactions.ts +++ b/src/helpers/messages/get_reactions.ts @@ -1,14 +1,14 @@ -import { rest } from "../../rest/rest.ts"; import type { GetReactions } from "../../types/messages/message_get_reactions.ts"; import type { User } from "../../types/users/user.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; /** Get a list of users that reacted with this emoji. */ -export async function getReactions(channelId: bigint, messageId: bigint, reaction: string, options?: GetReactions) { - const users = await rest.runMethod( +export async function getReactions(bot: Bot, channelId: bigint, messageId: bigint, reaction: string, options?: GetReactions) { + const users = await bot.rest.runMethod( + bot.rest, "get", - endpoints.CHANNEL_MESSAGE_REACTION(channelId, messageId, reaction), + bot.constants.endpoints.CHANNEL_MESSAGE_REACTION(channelId, messageId, reaction), options ); diff --git a/src/helpers/messages/pin_message.ts b/src/helpers/messages/pin_message.ts index 9bc16270c..2ef455fc2 100644 --- a/src/helpers/messages/pin_message.ts +++ b/src/helpers/messages/pin_message.ts @@ -1,12 +1,10 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Pin a message in a channel. Requires MANAGE_MESSAGES. Max pins allowed in a channel = 50. */ -export async function pin(channelId: bigint, messageId: bigint) { - await requireBotChannelPermissions(channelId, ["MANAGE_MESSAGES"]); +export async function pin(bot: Bot, channelId: bigint, messageId: bigint) { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]); - return await rest.runMethod("put", endpoints.CHANNEL_PIN(channelId, messageId)); + return await bot.rest.runMethod(bot.rest,"put", bot.constants.endpoints.CHANNEL_PIN(channelId, messageId)); } // aliases diff --git a/src/helpers/messages/publish_message.ts b/src/helpers/messages/publish_message.ts index e2c858c43..6cbc735ed 100644 --- a/src/helpers/messages/publish_message.ts +++ b/src/helpers/messages/publish_message.ts @@ -1,11 +1,14 @@ -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Message } from "../../types/messages/message.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Crosspost a message in a News Channel to following channels. */ -export async function publishMessage(channelId: bigint, messageId: bigint) { - const data = await rest.runMethod("post", endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId)); +export async function publishMessage(bot: Bot, channelId: bigint, messageId: bigint) { + const data = await bot.rest.runMethod>( + bot.rest, + "post", + bot.constants.endpoints.CHANNEL_MESSAGE_CROSSPOST(channelId, messageId) + ); - return await structures.createDiscordenoMessage(data); + return bot.transformers.message(bot, data); } diff --git a/src/helpers/messages/remove_all_reactions.ts b/src/helpers/messages/remove_all_reactions.ts index a2682e71b..16d8d5b80 100644 --- a/src/helpers/messages/remove_all_reactions.ts +++ b/src/helpers/messages/remove_all_reactions.ts @@ -1,10 +1,12 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Removes all reactions for all emojis on this message. */ -export async function removeAllReactions(channelId: bigint, messageId: bigint) { - await requireBotChannelPermissions(channelId, ["MANAGE_MESSAGES"]); +export async function removeAllReactions(bot: Bot, channelId: bigint, messageId: bigint) { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]); - return await rest.runMethod("delete", endpoints.CHANNEL_MESSAGE_REACTIONS(channelId, messageId)); + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.CHANNEL_MESSAGE_REACTIONS(channelId, messageId) + ); } diff --git a/src/helpers/messages/remove_reaction.ts b/src/helpers/messages/remove_reaction.ts index 081488cad..ada16b884 100644 --- a/src/helpers/messages/remove_reaction.ts +++ b/src/helpers/messages/remove_reaction.ts @@ -1,16 +1,15 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Removes a reaction from the given user on this message, defaults to bot. Reaction takes the form of **name:id** for custom guild emoji, or Unicode characters. */ export async function removeReaction( + bot: Bot, channelId: bigint, messageId: bigint, reaction: string, options?: { userId?: bigint } ) { if (options?.userId) { - await requireBotChannelPermissions(channelId, ["MANAGE_MESSAGES"]); + await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]); } if (reaction.startsWith("<:")) { @@ -19,10 +18,11 @@ export async function removeReaction( reaction = reaction.substring(3, reaction.length - 1); } - return await rest.runMethod( + return await bot.rest.runMethod( + bot.rest, "delete", options?.userId - ? endpoints.CHANNEL_MESSAGE_REACTION_USER(channelId, messageId, reaction, options.userId) - : endpoints.CHANNEL_MESSAGE_REACTION_ME(channelId, messageId, reaction) + ? bot.constants.endpoints.CHANNEL_MESSAGE_REACTION_USER(channelId, messageId, reaction, options.userId) + : bot.constants.endpoints.CHANNEL_MESSAGE_REACTION_ME(channelId, messageId, reaction) ); } diff --git a/src/helpers/messages/remove_reaction_emoji.ts b/src/helpers/messages/remove_reaction_emoji.ts index 69a70805d..a3c80c4ba 100644 --- a/src/helpers/messages/remove_reaction_emoji.ts +++ b/src/helpers/messages/remove_reaction_emoji.ts @@ -1,10 +1,8 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; - /** Removes all reactions for a single emoji on this message. Reaction takes the form of **name:id** for custom guild emoji, or Unicode characters. */ -export async function removeReactionEmoji(channelId: bigint, messageId: bigint, reaction: string) { - await requireBotChannelPermissions(channelId, ["MANAGE_MESSAGES"]); +import type { Bot } from "../../bot.ts"; + +export async function removeReactionEmoji(bot: Bot, channelId: bigint, messageId: bigint, reaction: string) { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]); if (reaction.startsWith("<:")) { reaction = reaction.substring(2, reaction.length - 1); @@ -12,5 +10,9 @@ export async function removeReactionEmoji(channelId: bigint, messageId: bigint, reaction = reaction.substring(3, reaction.length - 1); } - return await rest.runMethod("delete", endpoints.CHANNEL_MESSAGE_REACTION(channelId, messageId, reaction)); + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.CHANNEL_MESSAGE_REACTION(channelId, messageId, reaction) + ); } diff --git a/src/helpers/messages/send_message.ts b/src/helpers/messages/send_message.ts index 0b4ae5f48..c9e0f5b99 100644 --- a/src/helpers/messages/send_message.ts +++ b/src/helpers/messages/send_message.ts @@ -1,19 +1,15 @@ import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import { Errors } from "../../types/discordeno/errors.ts"; import { DiscordAllowedMentionsTypes } from "../../types/messages/allowed_mentions_types.ts"; import type { CreateMessage } from "../../types/messages/create_message.ts"; import type { Message } from "../../types/messages/message.ts"; import type { PermissionStrings } from "../../types/permissions/permission_strings.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { snakelize, validateComponents } from "../../util/utils.ts"; -import { validateLength } from "../../util/validate_length.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Send a message to the channel. Requires SEND_MESSAGES permission. */ -export async function sendMessage(channelId: bigint, content: string | CreateMessage) { +export async function sendMessage(bot: Bot, channelId: bigint, content: string | CreateMessage) { if (typeof content === "string") content = { content }; const channel = await cacheHandlers.get("channels", channelId); @@ -43,16 +39,16 @@ export async function sendMessage(channelId: bigint, content: string | CreateMes requiredPerms.add("READ_MESSAGE_HISTORY"); } - await requireBotChannelPermissions(channelId, [...requiredPerms]); + await bot.utils.requireBotChannelPermissions(bot, channelId, [...requiredPerms]); } // Use ... for content length due to unicode characters and js .length handling - if (content.content && !validateLength(content.content, { max: 2000 })) { - throw new Error(Errors.MESSAGE_MAX_LENGTH); + if (content.content && !bot.utils.validateLength(content.content, { max: 2000 })) { + throw new Error(bot.constants.Errors.MESSAGE_MAX_LENGTH); } if (content.components?.length) { - validateComponents(content.components); + bot.utils.validateComponents(bot, content.components); } if (content.allowedMentions) { @@ -77,21 +73,35 @@ export async function sendMessage(channelId: bigint, content: string | CreateMes } } - const result = await rest.runMethod( + const result = await bot.rest.runMethod>( + bot.rest, "post", - endpoints.CHANNEL_MESSAGES(channelId), - snakelize({ - ...content, + bot.constants.endpoints.CHANNEL_MESSAGES(channelId), + bot.utils.snakelize({ + content: content.content, + tts: content.tts, + embeds: content.embeds, + allowed_mentions: { + parse: content.allowedMentions.parse, + roles: content.allowedMentions.roles, + users: content.allowedMentions.users, + replied_user: content.allowedMentions.repliedUser, + }, + file: content.file, + // TODO: Snakelize components?? + components: content.components, ...(content.messageReference?.messageId ? { - messageReference: { - ...content.messageReference, - failIfNotExists: content.messageReference.failIfNotExists === true, + message_reference: { + message_id: content.messageReference.messageId, + channel_id: content.messageReference.channelId, + guild_id: content.messageReference.guildId, + fail_if_not_exists: content.messageReference.failIfNotExists === true, }, } : {}), }) ); - return structures.createDiscordenoMessage(result); + return bot.transformers.message(bot, result); } diff --git a/src/helpers/messages/suppress_embeds.ts b/src/helpers/messages/suppress_embeds.ts index c4d0efdcd..a89457222 100644 --- a/src/helpers/messages/suppress_embeds.ts +++ b/src/helpers/messages/suppress_embeds.ts @@ -1,26 +1,20 @@ -import { botId } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { EditMessage } from "../../types/messages/edit_message.ts"; import type { Message } from "../../types/messages/message.ts"; -import type { PermissionStrings } from "../../types/permissions/permission_strings.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { snakelize, validateComponents } from "../../util/utils.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Suppress all the embeds in this message */ -export async function suppressEmbeds(channelId: bigint, messageId: bigint) { +export async function suppressEmbeds(bot: Bot, channelId: bigint, messageId: bigint) { const message = await cacheHandlers.get("messages", messageId); - await requireBotChannelPermissions(channelId, message ? ["MANAGE_MESSAGES"] : ["SEND_MESSAGES"]); + await bot.utils.requireBotChannelPermissions(bot, channelId, message ? ["MANAGE_MESSAGES"] : ["SEND_MESSAGES"]); - const result = await rest.runMethod( + const result = await bot.rest.runMethod>( + bot.rest, "patch", - endpoints.CHANNEL_MESSAGE(channelId, messageId), - snakelize({ flags: 4 }) + bot.constants.endpoints.CHANNEL_MESSAGE(channelId, messageId), + { flags: 4 } ); - return await structures.createDiscordenoMessage(result); + return bot.transformers.message(bot, result); } diff --git a/src/helpers/messages/unpin_message.ts b/src/helpers/messages/unpin_message.ts index ee7542c42..5511c79c5 100644 --- a/src/helpers/messages/unpin_message.ts +++ b/src/helpers/messages/unpin_message.ts @@ -1,12 +1,14 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; - /** Unpin a message in a channel. Requires MANAGE_MESSAGES. */ -export async function unpin(channelId: bigint, messageId: bigint): Promise { - await requireBotChannelPermissions(channelId, ["MANAGE_MESSAGES"]); +import type { Bot } from "../../bot.ts"; - return await rest.runMethod("delete", endpoints.CHANNEL_PIN(channelId, messageId)); +export async function unpin(bot: Bot, channelId: bigint, messageId: bigint): Promise { + await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]); + + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.CHANNEL_PIN(channelId, messageId) + ); } // aliases diff --git a/src/helpers/misc/edit_bot_profile.ts b/src/helpers/misc/edit_bot_profile.ts index 886de902f..297566354 100644 --- a/src/helpers/misc/edit_bot_profile.ts +++ b/src/helpers/misc/edit_bot_profile.ts @@ -1,13 +1,12 @@ -import { rest } from "../../rest/rest.ts"; import { Errors } from "../../types/discordeno/errors.ts"; import type { User } from "../../types/users/user.ts"; -import { endpoints } from "../../util/constants.ts"; -import { urlToBase64 } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Modifies the bot's username or avatar. * NOTE: username: if changed may cause the bot's discriminator to be randomized. */ -export async function editBotProfile(options: { username?: string; botAvatarURL?: string | null }) { +export async function editBotProfile(bot: Bot, options: { username?: string; botAvatarURL?: string | null }) { // Nothing was edited if (!options.username && options.botAvatarURL === undefined) return; // Check username requirements if username was provided @@ -26,9 +25,9 @@ export async function editBotProfile(options: { username?: string; botAvatarURL? } } - const avatar = options?.botAvatarURL ? await urlToBase64(options?.botAvatarURL) : options?.botAvatarURL; + const avatar = options?.botAvatarURL ? await bot.utils.urlToBase64(options?.botAvatarURL) : options?.botAvatarURL; - return await rest.runMethod("patch", endpoints.USER_BOT, { + return await bot.rest.runMethod>(bot, "patch", bot.constants.endpoints.USER_BOT, { username: options.username?.trim(), avatar, }); diff --git a/src/helpers/misc/edit_bot_status.ts b/src/helpers/misc/edit_bot_status.ts index 0b2664085..3908fefc1 100644 --- a/src/helpers/misc/edit_bot_status.ts +++ b/src/helpers/misc/edit_bot_status.ts @@ -1,19 +1,18 @@ -import { eventHandlers } from "../../bot.ts"; +import type { Bot } from "../../bot.ts"; import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts"; import type { StatusUpdate } from "../../types/gateway/status_update.ts"; -import { snakelize } from "../../util/utils.ts"; -import { ws } from "../../ws/ws.ts"; -export function editBotStatus(data: Omit) { - ws.shards.forEach((shard) => { - eventHandlers.debug?.("loop", `Running forEach loop in editBotStatus function.`); +export function editBotStatus(bot: Bot, data: Omit) { + bot.ws.shards.forEach((shard) => { + bot.events.debug("loop", `Running forEach loop in editBotStatus function.`); - ws.sendShardMessage(shard, { + bot.ws.sendShardMessage(shard, { op: DiscordGatewayOpcodes.StatusUpdate, d: { since: null, afk: false, - ...snakelize>(data), + activities: data.activities, + status: data.status, }, }); }); diff --git a/src/helpers/misc/get_gateway_bot.ts b/src/helpers/misc/get_gateway_bot.ts index ac7594177..1281d08e5 100644 --- a/src/helpers/misc/get_gateway_bot.ts +++ b/src/helpers/misc/get_gateway_bot.ts @@ -1,8 +1,12 @@ -import { rest } from "../../rest/rest.ts"; import type { GetGatewayBot } from "../../types/gateway/get_gateway_bot.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Get the bots Gateway metadata that can help during the operation of large or sharded bots. */ -export async function getGatewayBot() { - return await rest.runMethod("get", endpoints.GATEWAY_BOT); +export async function getGatewayBot(bot: Bot) { + return await bot.rest.runMethod>( + bot.rest, + "get", + bot.constants.endpoints.GATEWAY_BOT + ); } diff --git a/src/helpers/misc/get_user.ts b/src/helpers/misc/get_user.ts index f4632beb5..2208b7da6 100644 --- a/src/helpers/misc/get_user.ts +++ b/src/helpers/misc/get_user.ts @@ -1,8 +1,12 @@ -import { rest } from "../../rest/rest.ts"; import type { User } from "../../types/users/user.ts"; -import { endpoints } from "../../util/constants.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** This function will return the raw user payload in the rare cases you need to fetch a user directly from the API. */ -export async function getUser(userId: bigint) { - return await rest.runMethod("get", endpoints.USER(userId)); +export async function getUser(bot: Bot, userId: bigint) { + return await bot.rest.runMethod>( + bot.rest, + "get", + bot.constants.endpoints.USER(userId) + ); } diff --git a/src/helpers/mod.ts b/src/helpers/mod.ts index 37825487b..3c7a37fde 100644 --- a/src/helpers/mod.ts +++ b/src/helpers/mod.ts @@ -37,7 +37,7 @@ import { getBans } from "./guilds/get_bans.ts"; import { getGuild } from "./guilds/get_guild.ts"; import { getGuildPreview } from "./guilds/get_guild_preview.ts"; import { getPruneCount } from "./guilds/get_prune_count.ts"; -import { getVanityURL } from "./guilds/get_vainty_url.ts"; +import { getVanityURL } from "./guilds/get_vanity_url.ts"; import { getVoiceRegions } from "./guilds/get_voice_regions.ts"; import { getWelcomeScreen } from "./guilds/get_welcome_screen.ts"; import { getWidget } from "./guilds/get_widget.ts"; diff --git a/src/helpers/oauth/get_application.ts b/src/helpers/oauth/get_application.ts index 425819ad0..5a011d43f 100644 --- a/src/helpers/oauth/get_application.ts +++ b/src/helpers/oauth/get_application.ts @@ -1,8 +1,12 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; import { Application } from "../../types/applications/application.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Get the applications info */ -export async function getApplicationInfo() { - return await rest.runMethod>("get", endpoints.OAUTH2_APPLICATION); +export async function getApplicationInfo(bot: Bot) { + return await bot.rest.runMethod>>( + bot.rest, + "get", + bot.constants.endpoints.OAUTH2_APPLICATION + ); } diff --git a/src/helpers/roles/add_role.ts b/src/helpers/roles/add_role.ts index 367e3911c..95445e230 100644 --- a/src/helpers/roles/add_role.ts +++ b/src/helpers/roles/add_role.ts @@ -1,17 +1,18 @@ -import { botId } from "../../bot.ts"; -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { isHigherPosition, requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Add a role to the member */ -export async function addRole(guildId: bigint, memberId: bigint, roleId: bigint, reason?: string) { - const isHigherRolePosition = await isHigherPosition(guildId, botId, roleId); +export async function addRole(bot: Bot, guildId: bigint, memberId: bigint, roleId: bigint, reason?: string) { + const isHigherRolePosition = await bot.utils.isHigherPosition(guildId, bot.id, roleId); if (!isHigherRolePosition) { - throw new Error(Errors.BOTS_HIGHEST_ROLE_TOO_LOW); + throw new Error(bot.constants.Errors.BOTS_HIGHEST_ROLE_TOO_LOW); } - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - return await rest.runMethod("put", endpoints.GUILD_MEMBER_ROLE(guildId, memberId, roleId), { reason }); + return await bot.rest.runMethod( + bot.rest, + "put", + bot.constants.endpoints.GUILD_MEMBER_ROLE(guildId, memberId, roleId), + { reason } + ); } diff --git a/src/helpers/roles/create_role.ts b/src/helpers/roles/create_role.ts index 978a790f3..6a8fec736 100644 --- a/src/helpers/roles/create_role.ts +++ b/src/helpers/roles/create_role.ts @@ -1,31 +1,35 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; -import { CreateGuildRole } from "../../types/guilds/create_guild_role.ts"; +import type { CreateGuildRole } from "../../types/guilds/create_guild_role.ts"; import type { Role } from "../../types/permissions/role.ts"; -import { endpoints } from "../../util/constants.ts"; -import { calculateBits, requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import type { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Create a new role for the guild. Requires the MANAGE_ROLES permission. */ -export async function createRole(guildId: bigint, options: CreateGuildRole, reason?: string) { - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); +export async function createRole(bot: Bot, guildId: bigint, options: CreateGuildRole, reason?: string) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - const result = await rest.runMethod("post", endpoints.GUILD_ROLES(guildId), { - ...options, - permissions: calculateBits(options?.permissions || []), - reason, - }); + const result = await bot.rest.runMethod>( + "post", + bot.constants.endpoints.GUILD_ROLES(guildId), + { + name: options.name, + color: options.color, + hoist: options.hoist, + mentionable: options.mentionable, + permissions: bot.utils.calculateBits(options?.permissions || []), + reason, + } + ); - const role = await structures.createDiscordenoRole({ + const role = await bot.transformers.role(bot, { role: result, guildId, }); - const guild = await cacheHandlers.get("guilds", guildId); + const guild = await bot.cache.guilds.get(guildId); if (guild) { guild.roles.set(role.id, role); - await cacheHandlers.set("guilds", guildId, guild); + await bot.cache.guilds.set(guildId, guild); } return role; diff --git a/src/helpers/roles/delete_role.ts b/src/helpers/roles/delete_role.ts index 8825234f9..698da0987 100644 --- a/src/helpers/roles/delete_role.ts +++ b/src/helpers/roles/delete_role.ts @@ -1,10 +1,8 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Delete a guild role. Requires the MANAGE_ROLES permission. */ -export async function deleteRole(guildId: bigint, id: bigint) { - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); +export async function deleteRole(bot: Bot, guildId: bigint, id: bigint) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - return await rest.runMethod("delete", endpoints.GUILD_ROLE(guildId, id)); + return await bot.rest.runMethod(bot.rest, "delete", bot.constants.endpoints.GUILD_ROLE(guildId, id)); } diff --git a/src/helpers/roles/edit_role.ts b/src/helpers/roles/edit_role.ts index 35ef00dbf..3b46bbe0a 100644 --- a/src/helpers/roles/edit_role.ts +++ b/src/helpers/roles/edit_role.ts @@ -1,18 +1,24 @@ -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { CreateGuildRole } from "../../types/guilds/create_guild_role.ts"; import type { Role } from "../../types/permissions/role.ts"; -import { endpoints } from "../../util/constants.ts"; -import { calculateBits, requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; +import { SnakeCasedPropertiesDeep } from "../../types/util.ts"; /** Edit a guild role. Requires the MANAGE_ROLES permission. */ -export async function editRole(guildId: bigint, id: bigint, options: CreateGuildRole) { - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); +export async function editRole(bot: Bot, guildId: bigint, id: bigint, options: CreateGuildRole) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - const result = await rest.runMethod("patch", endpoints.GUILD_ROLE(guildId, id), { - ...options, - permissions: options.permissions ? calculateBits(options.permissions) : undefined, - }); + const result = await bot.rest.runMethod>( + bot.rest, + "patch", + bot.constants.endpoints.GUILD_ROLE(guildId, id), + { + name: options.name, + color: options.color, + hoist: options.hoist, + mentionable: options.mentionable, + permissions: options.permissions ? bot.utils.calculateBits(options.permissions) : undefined, + } + ); - return await structures.createDiscordenoRole({ role: result, guildId }); + return bot.transformers.role(bot, { role: result, guildId }); } diff --git a/src/helpers/roles/get_roles.ts b/src/helpers/roles/get_roles.ts index 5dc55535e..d0b6cb2a5 100644 --- a/src/helpers/roles/get_roles.ts +++ b/src/helpers/roles/get_roles.ts @@ -1,31 +1,25 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Role } from "../../types/permissions/role.ts"; +import type { Bot } from "../../bot.ts"; import { Collection } from "../../util/collection.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; - +import { DiscordenoRole } from "../../transformers/role.ts"; /** Returns a list of role objects for the guild. * * ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your roles will be cached in your guild.** */ -export async function getRoles(guildId: bigint, addToCache = true) { - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); +export async function getRoles(bot: Bot, guildId: bigint, addToCache = true) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - const result = await rest.runMethod("get", endpoints.GUILD_ROLES(guildId)); + const result = await bot.rest.runMethod(bot.rest, "get", bot.constants.endpoints.GUILD_ROLES(guildId)); - const roleStructures = await Promise.all( - result.map(async (role) => await structures.createDiscordenoRole({ role, guildId })) - ); + const roleStructures = result.map((role: Role) => bot.transformers.role({ role, guildId })); - const roles = new Collection(roleStructures.map((role) => [role.id, role])); + const roles = new Collection(roleStructures.map((role: DiscordenoRole) => [role.id, role])); if (addToCache) { - const guild = await cacheHandlers.get("guilds", guildId); + const guild = await bot.cache.guilds.get(guildId); if (guild) { guild.roles = roles; - await cacheHandlers.set("guilds", guild.id, guild); + await bot.cache.guilds.set(guild.id, guild); } } diff --git a/src/helpers/roles/remove_role.ts b/src/helpers/roles/remove_role.ts index d97c78314..6cdc3602f 100644 --- a/src/helpers/roles/remove_role.ts +++ b/src/helpers/roles/remove_role.ts @@ -1,17 +1,18 @@ -import { botId } from "../../bot.ts"; -import { rest } from "../../rest/rest.ts"; -import { Errors } from "../../types/discordeno/errors.ts"; -import { endpoints } from "../../util/constants.ts"; -import { isHigherPosition, requireBotGuildPermissions } from "../../util/permissions.ts"; +import type { Bot } from "../../bot.ts"; /** Remove a role from the member */ -export async function removeRole(guildId: bigint, memberId: bigint, roleId: bigint, reason?: string) { - const isHigherRolePosition = await isHigherPosition(guildId, botId, roleId); +export async function removeRole(bot: Bot, guildId: bigint, memberId: bigint, roleId: bigint, reason?: string) { + const isHigherRolePosition = await bot.utils.isHigherPosition(bot, guildId, bot.id, roleId); if (!isHigherRolePosition) { - throw new Error(Errors.BOTS_HIGHEST_ROLE_TOO_LOW); + throw new Error(bot.constants.Errors.BOTS_HIGHEST_ROLE_TOO_LOW); } - await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]); - return await rest.runMethod("delete", endpoints.GUILD_MEMBER_ROLE(guildId, memberId, roleId), { reason }); + return await bot.rest.runMethod( + bot.rest, + "delete", + bot.constants.endpoints.GUILD_MEMBER_ROLE(guildId, memberId, roleId), + { reason } + ); } diff --git a/src/helpers/templates/create_guild_from_template.ts b/src/helpers/templates/create_guild_from_template.ts index f3ef0d468..aac271d25 100644 --- a/src/helpers/templates/create_guild_from_template.ts +++ b/src/helpers/templates/create_guild_from_template.ts @@ -1,29 +1,29 @@ -import { cacheHandlers } from "../../cache.ts"; -import { rest } from "../../rest/rest.ts"; -import { structures } from "../../structures/mod.ts"; import type { Guild } from "../../types/guilds/guild.ts"; import type { CreateGuildFromTemplate } from "../../types/templates/create_guild_from_template.ts"; -import { endpoints } from "../../util/constants.ts"; -import { urlToBase64 } from "../../util/utils.ts"; -import { ws } from "../../ws/ws.ts"; +import type { Bot } from "../../bot.ts"; /** * Create a new guild based on a template * NOTE: This endpoint can be used only by bots in less than 10 guilds. */ -export async function createGuildFromTemplate(templateCode: string, data: CreateGuildFromTemplate) { - if ((await cacheHandlers.size("guilds")) >= 10) { +export async function createGuildFromTemplate(bot: Bot, templateCode: string, data: CreateGuildFromTemplate) { + if ((await bot.cache.guilds.size()) >= 10) { throw new Error("This function can only be used by bots in less than 10 guilds."); } if (data.icon) { - data.icon = await urlToBase64(data.icon); + data.icon = await bot.utils.urlToBase64(data.icon); } - const createdGuild = await rest.runMethod("post", endpoints.GUILD_TEMPLATE(templateCode), data); + const createdGuild = await bot.rest.runMethod( + bot.rest, + "post", + bot.constants.endpoints.GUILD_TEMPLATE(templateCode), + data + ); - return await structures.createDiscordenoGuild( + return bot.transformers.guild( createdGuild, - Number((BigInt(createdGuild.id) >> 22n % BigInt(ws.botGatewayData.shards)).toString()) + Number((BigInt(createdGuild.id) >> 22n % BigInt(bot.ws.botGatewayData.shards)).toString()) ); } diff --git a/src/helpers/templates/create_guild_template.ts b/src/helpers/templates/create_guild_template.ts index bc09064b8..1c971601c 100644 --- a/src/helpers/templates/create_guild_template.ts +++ b/src/helpers/templates/create_guild_template.ts @@ -1,17 +1,17 @@ -import { rest } from "../../rest/rest.ts"; import type { Template } from "../../types/templates/template.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; -import { snakelize } from "../../util/utils.ts"; +import type { Bot } from "../../bot.ts"; +import { User } from "../../types/users/user.ts"; +import { Guild } from "../../types/guilds/guild.ts"; /** * Creates a template for the guild. * Requires the `MANAGE_GUILD` permission. - * @param name name of the template (1-100 characters) - * @param description description for the template (0-120 characters + * @param bot + * @param guildId + * @param data */ -export async function createGuildTemplate(guildId: bigint, data: Template) { - await requireBotGuildPermissions(guildId, ["MANAGE_GUILD"]); +export async function createGuildTemplate(bot: Bot, guildId: bigint, data: Template) { + await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]); if (data.name.length < 1 || data.name.length > 100) { throw new Error("The name can only be in between 1-100 characters."); @@ -21,5 +21,17 @@ export async function createGuildTemplate(guildId: bigint, data: Template) { throw new Error("The description can only be in between 0-120 characters."); } - return await rest.runMethod