diff --git a/packages/discord.js/src/managers/GuildChannelManager.js b/packages/discord.js/src/managers/GuildChannelManager.js index 5f5af7c8d..696eaa4b7 100644 --- a/packages/discord.js/src/managers/GuildChannelManager.js +++ b/packages/discord.js/src/managers/GuildChannelManager.js @@ -5,11 +5,14 @@ const { Collection } = require('@discordjs/collection'); const { ChannelType, Routes } = require('discord-api-types/v9'); const CachedManager = require('./CachedManager'); const ThreadManager = require('./ThreadManager'); -const { Error } = require('../errors'); +const { Error, TypeError } = require('../errors'); const GuildChannel = require('../structures/GuildChannel'); const PermissionOverwrites = require('../structures/PermissionOverwrites'); const ThreadChannel = require('../structures/ThreadChannel'); +const Webhook = require('../structures/Webhook'); const { ThreadChannelTypes } = require('../util/Constants'); +const DataResolver = require('../util/DataResolver'); +const Util = require('../util/Util'); let cacheWarningEmitted = false; let storeChannelDeprecationEmitted = false; @@ -169,6 +172,148 @@ class GuildChannelManager extends CachedManager { return this.client.actions.ChannelCreate.handle(data).channel; } + /** + * Creates a webhook for the channel. + * @param {GuildChannelResolvable} channel The channel to create the webhook for + * @param {string} name The name of the webhook + * @param {ChannelWebhookCreateOptions} [options] Options for creating the webhook + * @returns {Promise} Returns the created Webhook + * @example + * // Create a webhook for the current channel + * guild.channels.createWebhook('222197033908436994', 'Snek', { + * avatar: 'https://i.imgur.com/mI8XcpG.jpg', + * reason: 'Needed a cool new Webhook' + * }) + * .then(console.log) + * .catch(console.error) + */ + async createWebhook(channel, name, { avatar, reason } = {}) { + const id = this.resolveId(channel); + if (!id) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable'); + if (typeof avatar === 'string' && !avatar.startsWith('data:')) { + avatar = await DataResolver.resolveImage(avatar); + } + const data = await this.client.rest.post(Routes.channelWebhooks(id), { + body: { + name, + avatar, + }, + reason, + }); + return new Webhook(this.client, data); + } + + /** + * The data for a guild channel. + * @typedef {Object} ChannelData + * @property {string} [name] The name of the channel + * @property {ChannelType} [type] The type of the channel (only conversion between text and news is supported) + * @property {number} [position] The position of the channel + * @property {string} [topic] The topic of the text channel + * @property {boolean} [nsfw] Whether the channel is NSFW + * @property {number} [bitrate] The bitrate of the voice channel + * @property {number} [userLimit] The user limit of the voice channel + * @property {?CategoryChannelResolvable} [parent] The parent of the channel + * @property {boolean} [lockPermissions] + * Lock the permissions of the channel to what the parent's permissions are + * @property {OverwriteResolvable[]|Collection} [permissionOverwrites] + * Permission overwrites for the channel + * @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the channel in seconds + * @property {ThreadAutoArchiveDuration} [defaultAutoArchiveDuration] + * The default auto archive duration for all new threads in this channel + * @property {?string} [rtcRegion] The RTC region of the channel + */ + + /** + * Edits the channel. + * @param {GuildChannelResolvable} channel The channel to edit + * @param {ChannelData} data The new data for the channel + * @param {string} [reason] Reason for editing this channel + * @returns {Promise} + * @example + * // Edit a channel + * guild.channels.edit('222197033908436994', { name: 'new-channel' }) + * .then(console.log) + * .catch(console.error); + */ + async edit(channel, data, reason) { + channel = this.resolve(channel); + if (!channel) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable'); + + const parent = this.client.channels.resolveId(data.parent); + + if (typeof data.position !== 'undefined') await this.setPosition(channel, data.position, { reason }); + + let permission_overwrites = data.permissionOverwrites?.map(o => PermissionOverwrites.resolve(o, this.guild)); + + if (data.lockPermissions) { + if (parent) { + const newParent = this.guild.channels.resolve(parent); + if (newParent?.type === ChannelType.GuildCategory) { + permission_overwrites = newParent.permissionOverwrites.cache.map(o => + PermissionOverwrites.resolve(o, this.guild), + ); + } + } else if (channel.parent) { + permission_overwrites = this.parent.permissionOverwrites.cache.map(o => + PermissionOverwrites.resolve(o, this.guild), + ); + } + } + + const newData = await this.client.rest.patch(Routes.channel(channel.id), { + body: { + name: (data.name ?? channel.name).trim(), + type: data.type, + topic: data.topic, + nsfw: data.nsfw, + bitrate: data.bitrate ?? channel.bitrate, + user_limit: data.userLimit ?? channel.userLimit, + rtc_region: data.rtcRegion ?? channel.rtcRegion, + parent_id: parent, + lock_permissions: data.lockPermissions, + rate_limit_per_user: data.rateLimitPerUser, + default_auto_archive_duration: data.defaultAutoArchiveDuration, + permission_overwrites, + }, + reason, + }); + + return this.client.actions.ChannelUpdate.handle(newData).updated; + } + + /** + * Sets a new position for the guild channel. + * @param {GuildChannelResolvable} channel The channel to set the position for + * @param {number} position The new position for the guild channel + * @param {SetChannelPositionOptions} [options] Options for setting position + * @returns {Promise} + * @example + * // Set a new channel position + * guild.channels.setPosition('222078374472843266', 2) + * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) + * .catch(console.error); + */ + async setPosition(channel, position, { relative, reason } = {}) { + channel = this.resolve(channel); + if (!channel) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable'); + const updatedChannels = await Util.setPosition( + channel, + position, + relative, + this.guild._sortedChannels(channel), + this.client, + Routes.guildChannels(this.guild.id), + reason, + ); + + this.client.actions.GuildChannelsPositionUpdate.handle({ + guild_id: this.guild.id, + channels: updatedChannels, + }); + return channel; + } + /** * Obtains one or more guild channels from Discord, or the channel cache if they're already available. * @param {Snowflake} [id] The channel's id @@ -204,6 +349,23 @@ class GuildChannelManager extends CachedManager { return channels; } + /** + * Fetches all webhooks for the channel. + * @param {GuildChannelResolvable} channel The channel to fetch webhooks for + * @returns {Promise>} + * @example + * // Fetch webhooks + * guild.channels.fetchWebhooks('769862166131245066') + * .then(hooks => console.log(`This channel has ${hooks.size} hooks`)) + * .catch(console.error); + */ + async fetchWebhooks(channel) { + const id = this.resolveId(channel); + if (!id) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable'); + const data = await this.client.rest.get(Routes.channelWebhooks(id)); + return data.reduce((hooks, hook) => hooks.set(hook.id, new Webhook(this.client, hook)), new Collection()); + } + /** * Data that can be resolved to give a Category Channel object. This can be: * * A CategoryChannel object @@ -259,6 +421,23 @@ class GuildChannelManager extends CachedManager { const raw = await this.client.rest.get(Routes.guildActiveThreads(this.guild.id)); return ThreadManager._mapThreads(raw, this.client, { guild: this.guild, cache }); } + + /** + * Deletes the channel. + * @param {GuildChannelResolvable} channel The channel to delete + * @param {string} [reason] Reason for deleting this channel + * @returns {Promise} + * @example + * // Delete the channel + * guild.channels.delete('858850993013260338', 'making room for new channels') + * .then(console.log) + * .catch(console.error); + */ + async delete(channel, reason) { + const id = this.resolveId(channel); + if (!id) throw new TypeError('INVALID_TYPE', 'channel', 'GuildChannelResolvable'); + await this.client.rest.delete(Routes.channel(id), { reason }); + } } module.exports = GuildChannelManager; diff --git a/packages/discord.js/src/managers/GuildEmojiManager.js b/packages/discord.js/src/managers/GuildEmojiManager.js index d08b8bdcd..70302f9ac 100644 --- a/packages/discord.js/src/managers/GuildEmojiManager.js +++ b/packages/discord.js/src/managers/GuildEmojiManager.js @@ -1,9 +1,9 @@ 'use strict'; const { Collection } = require('@discordjs/collection'); -const { Routes } = require('discord-api-types/v9'); +const { Routes, PermissionFlagsBits } = require('discord-api-types/v9'); const BaseGuildEmojiManager = require('./BaseGuildEmojiManager'); -const { TypeError } = require('../errors'); +const { Error, TypeError } = require('../errors'); const DataResolver = require('../util/DataResolver'); /** @@ -140,6 +140,29 @@ class GuildEmojiManager extends BaseGuildEmojiManager { } return this._add(newData); } + + /** + * Fetches the author for this emoji + * @param {EmojiResolvable} emoji The emoji to fetch the author of + * @returns {Promise} + */ + async fetchAuthor(emoji) { + emoji = this.resolve(emoji); + if (!emoji) throw new TypeError('INVALID_TYPE', 'emoji', 'EmojiResolvable', true); + if (emoji.managed) { + throw new Error('EMOJI_MANAGED'); + } + + const { me } = this.guild; + if (!me) throw new Error('GUILD_UNCACHED_ME'); + if (!me.permissions.has(PermissionFlagsBits.ManageEmojisAndStickers)) { + throw new Error('MISSING_MANAGE_EMOJIS_AND_STICKERS_PERMISSION', this.guild); + } + + const data = await this.client.rest.get(Routes.guildEmoji(this.guild.id, emoji.id)); + emoji._patch(data); + return emoji.author; + } } module.exports = GuildEmojiManager; diff --git a/packages/discord.js/src/managers/GuildStickerManager.js b/packages/discord.js/src/managers/GuildStickerManager.js index 184b8d278..7152691aa 100644 --- a/packages/discord.js/src/managers/GuildStickerManager.js +++ b/packages/discord.js/src/managers/GuildStickerManager.js @@ -165,6 +165,19 @@ class GuildStickerManager extends CachedManager { const data = await this.client.rest.get(Routes.guildStickers(this.guild.id)); return new Collection(data.map(sticker => [sticker.id, this._add(sticker, cache)])); } + + /** + * Fetches the user who uploaded this sticker, if this is a guild sticker. + * @param {StickerResolvable} sticker The sticker to fetch the user for + * @returns {Promise} + */ + async fetchUser(sticker) { + sticker = this.resolve(sticker); + if (!sticker) throw new TypeError('INVALID_TYPE', 'sticker', 'StickerResolvable'); + const data = await this.client.rest.get(Routes.guildSticker(this.guildId, sticker.id)); + sticker._patch(data); + return sticker.user; + } } module.exports = GuildStickerManager; diff --git a/packages/discord.js/src/managers/RoleManager.js b/packages/discord.js/src/managers/RoleManager.js index 6582a5900..2e8452bef 100644 --- a/packages/discord.js/src/managers/RoleManager.js +++ b/packages/discord.js/src/managers/RoleManager.js @@ -9,6 +9,7 @@ const { Role } = require('../structures/Role'); const DataResolver = require('../util/DataResolver'); const PermissionsBitField = require('../util/PermissionsBitField'); const { resolveColor } = require('../util/Util'); +const Util = require('../util/Util'); let cacheWarningEmitted = false; @@ -160,7 +161,7 @@ class RoleManager extends CachedManager { guild_id: this.guild.id, role: data, }); - if (position) return role.setPosition(position, reason); + if (position) return this.setPosition(role, position, { reason }); return role; } @@ -181,7 +182,7 @@ class RoleManager extends CachedManager { if (!role) throw new TypeError('INVALID_TYPE', 'role', 'RoleResolvable'); if (typeof data.position === 'number') { - await role.setPosition(data.position, { reason }); + await this.setPosition(role, data.position, { reason }); } let icon = data.icon; @@ -225,7 +226,39 @@ class RoleManager extends CachedManager { this.client.actions.GuildRoleDelete.handle({ guild_id: this.guild.id, role_id: id }); } - /* + /** + * Sets the new position of the role. + * @param {RoleResolvable} role The role to change the position of + * @param {number} position The new position for the role + * @param {SetRolePositionOptions} [options] Options for setting the position + * @returns {Promise} + * @example + * // Set the position of the role + * guild.roles.setPosition('222197033908436994', 1) + * .then(updated => console.log(`Role position: ${updated.position}`)) + * .catch(console.error); + */ + async setPosition(role, position, { relative, reason } = {}) { + role = this.resolve(role); + if (!role) throw new TypeError('INVALID_TYPE', 'role', 'RoleResolvable'); + const updatedRoles = await Util.setPosition( + role, + position, + relative, + this.guild._sortedRoles(), + this.client, + Routes.guildRoles(this.guild.id), + reason, + ); + + this.client.actions.GuildRolesPositionUpdate.handle({ + guild_id: this.guild.id, + roles: updatedRoles, + }); + return role; + } + + /** * The data needed for updating a guild role's position * @typedef {Object} GuildRolePosition * @property {RoleResolvable} role The role's id diff --git a/packages/discord.js/src/structures/BaseGuildTextChannel.js b/packages/discord.js/src/structures/BaseGuildTextChannel.js index 07b0ac890..76fca0a5a 100644 --- a/packages/discord.js/src/structures/BaseGuildTextChannel.js +++ b/packages/discord.js/src/structures/BaseGuildTextChannel.js @@ -1,13 +1,9 @@ 'use strict'; -const { Collection } = require('@discordjs/collection'); -const { Routes } = require('discord-api-types/v9'); const GuildChannel = require('./GuildChannel'); -const Webhook = require('./Webhook'); const TextBasedChannel = require('./interfaces/TextBasedChannel'); const MessageManager = require('../managers/MessageManager'); const ThreadManager = require('../managers/ThreadManager'); -const DataResolver = require('../util/DataResolver'); /** * Represents a text-based guild channel on Discord. @@ -122,11 +118,8 @@ class BaseGuildTextChannel extends GuildChannel { * .then(hooks => console.log(`This channel has ${hooks.size} hooks`)) * .catch(console.error); */ - async fetchWebhooks() { - const data = await this.client.rest.get(Routes.channelWebhooks(this.id)); - const hooks = new Collection(); - for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook)); - return hooks; + fetchWebhooks() { + return this.guild.channels.fetchWebhooks(this.id); } /** @@ -150,18 +143,8 @@ class BaseGuildTextChannel extends GuildChannel { * .then(console.log) * .catch(console.error) */ - async createWebhook(name, { avatar, reason } = {}) { - if (typeof avatar === 'string' && !avatar.startsWith('data:')) { - avatar = await DataResolver.resolveImage(avatar); - } - const data = await this.client.rest.post(Routes.channelWebhooks(this.id), { - body: { - name, - avatar, - }, - reason, - }); - return new Webhook(this.client, data); + createWebhook(name, options = {}) { + return this.guild.channels.createWebhook(this.id, name, options); } /** @@ -179,6 +162,14 @@ class BaseGuildTextChannel extends GuildChannel { return this.edit({ topic }, reason); } + /** + * Data that can be resolved to an Application. This can be: + * * An Application + * * An Activity with associated Application + * * A Snowflake + * @typedef {Application|Snowflake} ApplicationResolvable + */ + /** * Options used to create an invite to a guild channel. * @typedef {Object} CreateInviteOptions diff --git a/packages/discord.js/src/structures/GuildChannel.js b/packages/discord.js/src/structures/GuildChannel.js index e53eefd1e..67c2f9eee 100644 --- a/packages/discord.js/src/structures/GuildChannel.js +++ b/packages/discord.js/src/structures/GuildChannel.js @@ -1,13 +1,11 @@ 'use strict'; -const { ChannelType, Routes, PermissionFlagsBits } = require('discord-api-types/v9'); +const { PermissionFlagsBits } = require('discord-api-types/v9'); const { Channel } = require('./Channel'); -const PermissionOverwrites = require('./PermissionOverwrites'); const { Error } = require('../errors'); const PermissionOverwriteManager = require('../managers/PermissionOverwriteManager'); const { VoiceBasedChannelTypes } = require('../util/Constants'); const PermissionsBitField = require('../util/PermissionsBitField'); -const Util = require('../util/Util'); /** * Represents a guild channel from any of the following: @@ -265,27 +263,6 @@ class GuildChannel extends Channel { return this.guild.members.cache.filter(m => this.permissionsFor(m).has(PermissionFlagsBits.ViewChannel, false)); } - /** - * The data for a guild channel. - * @typedef {Object} ChannelData - * @property {string} [name] The name of the channel - * @property {ChannelType} [type] The type of the channel (only conversion between text and news is supported) - * @property {number} [position] The position of the channel - * @property {string} [topic] The topic of the text channel - * @property {boolean} [nsfw] Whether the channel is NSFW - * @property {number} [bitrate] The bitrate of the voice channel - * @property {number} [userLimit] The user limit of the voice channel - * @property {?CategoryChannelResolvable} [parent] The parent of the channel - * @property {boolean} [lockPermissions] - * Lock the permissions of the channel to what the parent's permissions are - * @property {OverwriteResolvable[]|Collection} [permissionOverwrites] - * Permission overwrites for the channel - * @property {number} [rateLimitPerUser] The rate limit per user (slowmode) for the channel in seconds - * @property {ThreadAutoArchiveDuration} [defaultAutoArchiveDuration] - * The default auto archive duration for all new threads in this channel - * @property {?string} [rtcRegion] The RTC region of the channel - */ - /** * Edits the channel. * @param {ChannelData} data The new data for the channel @@ -297,53 +274,8 @@ class GuildChannel extends Channel { * .then(console.log) * .catch(console.error); */ - async edit(data, reason) { - data.parent &&= this.client.channels.resolveId(data.parent); - - if (typeof data.position !== 'undefined') { - await this.setPosition(data.position, { reason }); - } - - let permission_overwrites; - - if (data.permissionOverwrites) { - permission_overwrites = data.permissionOverwrites.map(o => PermissionOverwrites.resolve(o, this.guild)); - } - - if (data.lockPermissions) { - if (data.parent) { - const newParent = this.guild.channels.resolve(data.parent); - if (newParent?.type === ChannelType.GuildCategory) { - permission_overwrites = newParent.permissionOverwrites.cache.map(o => - PermissionOverwrites.resolve(o, this.guild), - ); - } - } else if (this.parent) { - permission_overwrites = this.parent.permissionOverwrites.cache.map(o => - PermissionOverwrites.resolve(o, this.guild), - ); - } - } - - const newData = await this.client.rest.patch(Routes.channel(this.id), { - body: { - name: (data.name ?? this.name).trim(), - type: data.type, - topic: data.topic, - nsfw: data.nsfw, - bitrate: data.bitrate ?? this.bitrate, - user_limit: data.userLimit ?? this.userLimit, - rtc_region: data.rtcRegion ?? this.rtcRegion, - parent_id: data.parent, - lock_permissions: data.lockPermissions, - rate_limit_per_user: data.rateLimitPerUser, - default_auto_archive_duration: data.defaultAutoArchiveDuration, - permission_overwrites, - }, - reason, - }); - - return this.client.actions.ChannelUpdate.handle(newData).updated; + edit(data, reason) { + return this.guild.channels.edit(this, data, reason); } /** @@ -407,31 +339,10 @@ class GuildChannel extends Channel { * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) * .catch(console.error); */ - async setPosition(position, { relative, reason } = {}) { - const updatedChannels = await Util.setPosition( - this, - position, - relative, - this.guild._sortedChannels(this), - this.client, - Routes.guildChannels(this.guild.id), - reason, - ); - this.client.actions.GuildChannelsPositionUpdate.handle({ - guild_id: this.guild.id, - channels: updatedChannels, - }); - return this; + setPosition(position, options = {}) { + return this.guild.channels.setPosition(this, position, options); } - /** - * Data that can be resolved to an Application. This can be: - * * An Application - * * An Activity with associated Application - * * A Snowflake - * @typedef {Application|Snowflake} ApplicationResolvable - */ - /** * Options used to clone a guild channel. * @typedef {GuildChannelCreateOptions} GuildChannelCloneOptions @@ -537,7 +448,7 @@ class GuildChannel extends Channel { * .catch(console.error); */ async delete(reason) { - await this.client.rest.delete(Routes.channel(this.id), { reason }); + await this.guild.channels.delete(this.id, reason); return this; } } diff --git a/packages/discord.js/src/structures/GuildEmoji.js b/packages/discord.js/src/structures/GuildEmoji.js index 39753fa33..609083bd7 100644 --- a/packages/discord.js/src/structures/GuildEmoji.js +++ b/packages/discord.js/src/structures/GuildEmoji.js @@ -1,6 +1,6 @@ 'use strict'; -const { Routes, PermissionFlagsBits } = require('discord-api-types/v9'); +const { PermissionFlagsBits } = require('discord-api-types/v9'); const BaseGuildEmoji = require('./BaseGuildEmoji'); const { Error } = require('../errors'); const GuildEmojiRoleManager = require('../managers/GuildEmojiRoleManager'); @@ -72,18 +72,8 @@ class GuildEmoji extends BaseGuildEmoji { * Fetches the author for this emoji * @returns {Promise} */ - async fetchAuthor() { - if (this.managed) { - throw new Error('EMOJI_MANAGED'); - } else { - if (!this.guild.me) throw new Error('GUILD_UNCACHED_ME'); - if (!this.guild.me.permissions.has(PermissionFlagsBits.ManageEmojisAndStickers)) { - throw new Error('MISSING_MANAGE_EMOJIS_AND_STICKERS_PERMISSION', this.guild); - } - } - const data = await this.client.rest.get(Routes.guildEmoji(this.guild.id, this.id)); - this._patch(data); - return this.author; + fetchAuthor() { + return this.guild.emojis.fetchAuthor(this); } /** diff --git a/packages/discord.js/src/structures/Role.js b/packages/discord.js/src/structures/Role.js index 3e5d7174c..53259738c 100644 --- a/packages/discord.js/src/structures/Role.js +++ b/packages/discord.js/src/structures/Role.js @@ -1,11 +1,10 @@ 'use strict'; const { DiscordSnowflake } = require('@sapphire/snowflake'); -const { Routes, PermissionFlagsBits } = require('discord-api-types/v9'); +const { PermissionFlagsBits } = require('discord-api-types/v9'); const Base = require('./Base'); const { Error } = require('../errors'); const PermissionsBitField = require('../util/PermissionsBitField'); -const Util = require('../util/Util'); /** * Represents a role on Discord. @@ -359,21 +358,8 @@ class Role extends Base { * .then(updated => console.log(`Role position: ${updated.position}`)) * .catch(console.error); */ - async setPosition(position, { relative, reason } = {}) { - const updatedRoles = await Util.setPosition( - this, - position, - relative, - this.guild._sortedRoles(), - this.client, - Routes.guildRoles(this.guild.id), - reason, - ); - this.client.actions.GuildRolesPositionUpdate.handle({ - guild_id: this.guild.id, - roles: updatedRoles, - }); - return this; + setPosition(position, options = {}) { + return this.guild.roles.setPosition(this, position, options); } /** diff --git a/packages/discord.js/src/structures/Sticker.js b/packages/discord.js/src/structures/Sticker.js index f9398481e..cba2f5f86 100644 --- a/packages/discord.js/src/structures/Sticker.js +++ b/packages/discord.js/src/structures/Sticker.js @@ -190,10 +190,7 @@ class Sticker extends Base { async fetchUser() { if (this.partial) await this.fetch(); if (!this.guildId) throw new Error('NOT_GUILD_STICKER'); - - const data = await this.client.rest.get(Routes.guildSticker(this.guildId, this.id)); - this._patch(data); - return this.user; + return this.guild.stickers.fetchUser(this); } /** diff --git a/packages/discord.js/src/structures/ThreadChannel.js b/packages/discord.js/src/structures/ThreadChannel.js index e6f030ae9..d40abe629 100644 --- a/packages/discord.js/src/structures/ThreadChannel.js +++ b/packages/discord.js/src/structures/ThreadChannel.js @@ -539,7 +539,7 @@ class ThreadChannel extends Channel { * .catch(console.error); */ async delete(reason) { - await this.client.rest.delete(Routes.channel(this.id), { reason }); + await this.guild.channels.delete(this.id, reason); return this; } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index c83568496..f96dbda14 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -2775,12 +2775,24 @@ export class GuildChannelManager extends CachedManager; - public create(name: string, options?: GuildChannelCreateOptions): Promise; + public createWebhook( + channel: GuildChannelResolvable, + name: string, + options?: ChannelWebhookCreateOptions, + ): Promise; + public edit(channel: GuildChannelResolvable, data: ChannelData, reason?: string): Promise; public fetch(id: Snowflake, options?: BaseFetchOptions): Promise; public fetch(id?: undefined, options?: BaseFetchOptions): Promise>; + public fetchWebhooks(channel: GuildChannelResolvable): Promise>; + public setPosition( + channel: GuildChannelResolvable, + position: number, + options?: SetChannelPositionOptions, + ): Promise; public setPositions(channelPositions: readonly ChannelPosition[]): Promise; public fetchActiveThreads(cache?: boolean): Promise; + public delete(channel: GuildChannelResolvable, reason?: string): Promise; } export class GuildEmojiManager extends BaseGuildEmojiManager { @@ -2793,6 +2805,7 @@ export class GuildEmojiManager extends BaseGuildEmojiManager { ): Promise; public fetch(id: Snowflake, options?: BaseFetchOptions): Promise; public fetch(id?: undefined, options?: BaseFetchOptions): Promise>; + public fetchAuthor(emoji: EmojiResolvable): Promise; public delete(emoji: EmojiResolvable, reason?: string): Promise; public edit(emoji: EmojiResolvable, data: GuildEmojiEditData, reason?: string): Promise; } @@ -2893,6 +2906,7 @@ export class GuildStickerManager extends CachedManager; public fetch(id: Snowflake, options?: BaseFetchOptions): Promise; public fetch(id?: Snowflake, options?: BaseFetchOptions): Promise>; + public fetchUser(sticker: StickerResolvable): Promise; } export class GuildMemberRoleManager extends DataManager { @@ -2993,6 +3007,7 @@ export class RoleManager extends CachedManager public create(options?: CreateRoleOptions): Promise; public edit(role: RoleResolvable, options: RoleData, reason?: string): Promise; public delete(role: RoleResolvable, reason?: string): Promise; + public setPosition(role: RoleResolvable, position: number, options?: SetRolePositionOptions): Promise; public setPositions(rolePositions: readonly RolePosition[]): Promise; public comparePositions(role1: RoleResolvable, role2: RoleResolvable): number; }