diff --git a/src/bot.ts b/src/bot.ts index e539566ef..d24a6ebd4 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -12,6 +12,7 @@ import { highestRole, higherRolePosition, requireBotChannelPermissions, + requireBotGuildPermissions } from "./util/permissions.ts"; import { getGatewayBot } from "./helpers/misc/get_gateway_bot.ts"; import { @@ -284,6 +285,7 @@ export function createUtils(options: Partial) { validateSlashOptions, validateSlashOptionChoices, requireBotChannelPermissions, + requireBotGuildPermissions, validateComponents, }; } @@ -311,6 +313,7 @@ export interface HelperUtils { validateSlashOptions: typeof validateSlashOptions; validateSlashOptionChoices: typeof validateSlashOptionChoices; requireBotChannelPermissions: typeof requireBotChannelPermissions; + requireBotGuildPermissions: typeof requireBotGuildPermissions; validateComponents: typeof validateComponents; } diff --git a/src/helpers/integrations/delete_integration.ts b/src/helpers/integrations/delete_integration.ts index 8de324a4b..68893fd1c 100644 --- a/src/helpers/integrations/delete_integration.ts +++ b/src/helpers/integrations/delete_integration.ts @@ -1,10 +1,8 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; -import { requireBotGuildPermissions } from "../../util/permissions.ts"; +import {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/invites/create_invite.ts b/src/helpers/invites/create_invite.ts index 9060a0822..fe3189b71 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 { 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,13 @@ 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..aecd9f62a 100644 --- a/src/helpers/invites/delete_invite.ts +++ b/src/helpers/invites/delete_invite.ts @@ -1,19 +1,17 @@ -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 {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..8fdfadf0d 100644 --- a/src/helpers/invites/get_channel_invites.ts +++ b/src/helpers/invites/get_channel_invites.ts @@ -1,14 +1,13 @@ -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 {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..0a26a311e 100644 --- a/src/helpers/invites/get_invite.ts +++ b/src/helpers/invites/get_invite.ts @@ -1,10 +1,12 @@ -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 {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..43e5c6ae4 100644 --- a/src/helpers/invites/get_invites.ts +++ b/src/helpers/invites/get_invites.ts @@ -1,14 +1,13 @@ -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 {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(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/misc/edit_bot_profile.ts b/src/helpers/misc/edit_bot_profile.ts index 886de902f..769e8dc90 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 {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..aadbeab10 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 {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..79e4bed05 100644 --- a/src/helpers/misc/get_gateway_bot.ts +++ b/src/helpers/misc/get_gateway_bot.ts @@ -1,8 +1,8 @@ -import { rest } from "../../rest/rest.ts"; import type { GetGatewayBot } from "../../types/gateway/get_gateway_bot.ts"; -import { endpoints } from "../../util/constants.ts"; +import {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..5a96dfc7d 100644 --- a/src/helpers/misc/get_user.ts +++ b/src/helpers/misc/get_user.ts @@ -1,8 +1,8 @@ -import { rest } from "../../rest/rest.ts"; import type { User } from "../../types/users/user.ts"; -import { endpoints } from "../../util/constants.ts"; +import {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/oauth/get_application.ts b/src/helpers/oauth/get_application.ts index 425819ad0..4262eba04 100644 --- a/src/helpers/oauth/get_application.ts +++ b/src/helpers/oauth/get_application.ts @@ -1,8 +1,8 @@ -import { rest } from "../../rest/rest.ts"; -import { endpoints } from "../../util/constants.ts"; import { Application } from "../../types/applications/application.ts"; +import { 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/voice/connect_to_voice_channel.ts b/src/helpers/voice/connect_to_voice_channel.ts index eb815c083..510d45be9 100644 --- a/src/helpers/voice/connect_to_voice_channel.ts +++ b/src/helpers/voice/connect_to_voice_channel.ts @@ -1,26 +1,23 @@ -import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts"; import type { UpdateVoiceState } from "../../types/voice/update_voice_state.ts"; -import { requireBotChannelPermissions } from "../../util/permissions.ts"; -import { calculateShardId } from "../../util/calculate_shard_id.ts"; -import { snakelize } from "../../util/utils.ts"; -import { ws } from "../../ws/ws.ts"; import type { AtLeastOne } from "../../types/util.ts"; +import {Bot} from "../../bot.ts"; /** Connect or join a voice channel inside a guild. By default, the "selfDeaf" option is true. Requires `CONNECT` and `VIEW_CHANNEL` permissions. */ export async function connectToVoiceChannel( + bot: Bot, guildId: bigint, channelId: bigint, options?: AtLeastOne> ) { - await requireBotChannelPermissions(channelId, ["CONNECT", "VIEW_CHANNEL"]); + await bot.utils.requireBotChannelPermissions(bot, channelId, ["CONNECT", "VIEW_CHANNEL"]); - ws.sendShardMessage(calculateShardId(guildId), { - op: DiscordGatewayOpcodes.VoiceStateUpdate, - d: snakelize({ - guildId, - channelId, - selfMute: Boolean(options?.selfMute), - selfDeaf: options?.selfDeaf ?? true, - }), + bot.ws.sendShardMessage(bot.utils.calculateShardId(guildId), { + op: bot.constants.DiscordGatewayOpcodes.VoiceStateUpdate, + d: { + guild_id: guildId, + channel_id: channelId, + self_mute: Boolean(options?.selfMute), + self_deaf: options?.selfDeaf ?? true, + }, }); }