diff --git a/src/client/actions/ChannelUpdate.js b/src/client/actions/ChannelUpdate.js index 6fd2e95ccd6c..d44239973f86 100644 --- a/src/client/actions/ChannelUpdate.js +++ b/src/client/actions/ChannelUpdate.js @@ -12,7 +12,7 @@ class ChannelUpdateAction extends Action { if (channel) { const old = channel._update(data); - if (ChannelTypes[channel.type.toUpperCase()] !== data.type) { + if (ChannelTypes[channel.type] !== data.type) { const newChannel = Channel.create(this.client, data, channel.guild); for (const [id, message] of channel.messages.cache) newChannel.messages.cache.set(id, message); newChannel._typing = new Map(channel._typing); diff --git a/src/client/actions/GuildDelete.js b/src/client/actions/GuildDelete.js index 057acbce7349..a6a98d57a664 100644 --- a/src/client/actions/GuildDelete.js +++ b/src/client/actions/GuildDelete.js @@ -1,7 +1,7 @@ 'use strict'; const Action = require('./Action'); -const { Events } = require('../../util/Constants'); +const { Events, TextBasedChannelTypes } = require('../../util/Constants'); class GuildDeleteAction extends Action { constructor(client) { @@ -15,7 +15,7 @@ class GuildDeleteAction extends Action { let guild = client.guilds.cache.get(data.id); if (guild) { for (const channel of guild.channels.cache.values()) { - if (channel.type === 'text') channel.stopTyping(true); + if (channel.type in TextBasedChannelTypes) channel.stopTyping(true); } if (data.unavailable) { diff --git a/src/client/actions/MessageReactionAdd.js b/src/client/actions/MessageReactionAdd.js index e483ff5128d5..a3638ce30e5d 100644 --- a/src/client/actions/MessageReactionAdd.js +++ b/src/client/actions/MessageReactionAdd.js @@ -1,7 +1,7 @@ 'use strict'; const Action = require('./Action'); -const { Events } = require('../../util/Constants'); +const { Events, VoiceBasedChannelTypes } = require('../../util/Constants'); const { PartialTypes } = require('../../util/Constants'); /* @@ -23,7 +23,7 @@ class MessageReactionAdd extends Action { // Verify channel const channel = this.getChannel(data); - if (!channel || channel.type === 'voice') return false; + if (!channel || channel.type in VoiceBasedChannelTypes) return false; // Verify message const message = this.getMessage(data, channel); diff --git a/src/client/actions/MessageReactionRemove.js b/src/client/actions/MessageReactionRemove.js index 8740246576ec..c21c2cc5ca0c 100644 --- a/src/client/actions/MessageReactionRemove.js +++ b/src/client/actions/MessageReactionRemove.js @@ -1,7 +1,7 @@ 'use strict'; const Action = require('./Action'); -const { Events } = require('../../util/Constants'); +const { Events, VoiceBasedChannelTypes } = require('../../util/Constants'); /* { user_id: 'id', @@ -20,7 +20,7 @@ class MessageReactionRemove extends Action { // Verify channel const channel = this.getChannel(data); - if (!channel || channel.type === 'voice') return false; + if (!channel || channel.type in VoiceBasedChannelTypes) return false; // Verify message const message = this.getMessage(data, channel); diff --git a/src/client/actions/MessageReactionRemoveAll.js b/src/client/actions/MessageReactionRemoveAll.js index 14b79bf089e4..70ab720a263e 100644 --- a/src/client/actions/MessageReactionRemoveAll.js +++ b/src/client/actions/MessageReactionRemoveAll.js @@ -1,13 +1,13 @@ 'use strict'; const Action = require('./Action'); -const { Events } = require('../../util/Constants'); +const { Events, VoiceBasedChannelTypes } = require('../../util/Constants'); class MessageReactionRemoveAll extends Action { handle(data) { // Verify channel const channel = this.getChannel(data); - if (!channel || channel.type === 'voice') return false; + if (!channel || channel.type in VoiceBasedChannelTypes) return false; // Verify message const message = this.getMessage(data, channel); diff --git a/src/client/actions/MessageReactionRemoveEmoji.js b/src/client/actions/MessageReactionRemoveEmoji.js index 6b2076ef0c57..fff47611d7e2 100644 --- a/src/client/actions/MessageReactionRemoveEmoji.js +++ b/src/client/actions/MessageReactionRemoveEmoji.js @@ -1,12 +1,12 @@ 'use strict'; const Action = require('./Action'); -const { Events } = require('../../util/Constants'); +const { Events, VoiceBasedChannelTypes } = require('../../util/Constants'); class MessageReactionRemoveEmoji extends Action { handle(data) { const channel = this.getChannel(data); - if (!channel || channel.type === 'voice') return false; + if (!channel || channel.type in VoiceBasedChannelTypes) return false; const message = this.getMessage(data, channel); if (!message) return false; diff --git a/src/client/actions/TypingStart.js b/src/client/actions/TypingStart.js index 07c540fd5b81..6e6495cf5618 100644 --- a/src/client/actions/TypingStart.js +++ b/src/client/actions/TypingStart.js @@ -1,8 +1,7 @@ 'use strict'; const Action = require('./Action'); -const { Events } = require('../../util/Constants'); -const textBasedChannelTypes = ['dm', 'text', 'news', 'news_thread', 'public_thread', 'private_thread']; +const { Events, TextBasedChannelTypes } = require('../../util/Constants'); class TypingStart extends Action { handle(data) { @@ -10,7 +9,7 @@ class TypingStart extends Action { if (!channel) { return; } - if (!textBasedChannelTypes.includes(channel.type)) { + if (!(channel.type in TextBasedChannelTypes)) { this.client.emit(Events.WARN, `Discord sent a typing packet to a ${channel.type} channel ${channel.id}`); return; } diff --git a/src/managers/GuildChannelManager.js b/src/managers/GuildChannelManager.js index be5ea053148a..46fdd6cdaaee 100644 --- a/src/managers/GuildChannelManager.js +++ b/src/managers/GuildChannelManager.js @@ -80,8 +80,8 @@ class GuildChannelManager extends CachedManager { /** * Options used to create a new channel in a guild. * @typedef {Object} GuildChannelCreateOptions - * @property {string} [type='text'] The type of the new channel, either `text`, `voice`, `category`, `news`, - * `store`, or `stage` + * @property {string|number} [type='GUILD_TEXT'] The type of the new channel, either `GUILD_TEXT`, `GUILD_VOICE`, + * `GUILD_CATEGORY`, `GUILD_NEWS`, `GUILD_STORE`, or `GUILD_STAGE_VOICE` * @property {string} [topic] The topic for the new channel * @property {boolean} [nsfw] Whether the new channel is nsfw * @property {number} [bitrate] Bitrate of the new channel in bits (only voice) @@ -107,7 +107,7 @@ class GuildChannelManager extends CachedManager { * @example * // Create a new channel with permission overwrites * guild.channels.create('new-voice', { - * type: 'voice', + * type: 'GUILD_VOICE', * permissionOverwrites: [ * { * id: message.author.id, @@ -129,7 +129,7 @@ class GuildChannelManager extends CachedManager { data: { name, topic, - type: type ? ChannelTypes[type.toUpperCase()] : ChannelTypes.TEXT, + type: typeof type === 'number' ? type : ChannelTypes[type] ?? ChannelTypes.GUILD_TEXT, nsfw, bitrate, user_limit: userLimit, diff --git a/src/managers/GuildManager.js b/src/managers/GuildManager.js index 39f77034bc0b..7f380278c4e1 100644 --- a/src/managers/GuildManager.js +++ b/src/managers/GuildManager.js @@ -75,7 +75,7 @@ class GuildManager extends CachedManager { * @property {Snowflake|number} [id] The channel's id, used to set its parent, * this is a placeholder and will be replaced by the API after consumption * @property {Snowflake|number} [parentId] The parent id for this channel - * @property {string} [type] The type of the channel + * @property {ChannelType} [type] The type of the channel * @property {string} name The name of the channel * @property {string} [topic] The topic of the text channel * @property {boolean} [nsfw] Whether the channel is NSFW diff --git a/src/managers/ThreadManager.js b/src/managers/ThreadManager.js index 2e334f0516a9..4853791cfa73 100644 --- a/src/managers/ThreadManager.js +++ b/src/managers/ThreadManager.js @@ -77,9 +77,9 @@ class ThreadManager extends CachedManager { * should automatically archive in case of no recent activity * @property {MessageResolvable} [startMessage] The message to start a thread from. If this is defined then type * of thread gets automatically defined and cannot be changed. The provided `type` field will be ignored - * @property {ThreadChannelType|number} [type] The type of thread to create. Defaults to `public_thread` if created in - * a {@link TextChannel} When creating threads in a {@link NewsChannel} this is ignored and is always - * `news_thread` + * @property {ThreadChannelTypes|number} [type] The type of thread to create. Defaults to `GUILD_PUBLIC_THREAD` if + * created in a {@link TextChannel} When creating threads in a {@link NewsChannel} this is ignored and is always + * `GUILD_NEWS_THREAD` * @property {string} [reason] Reason for creating the thread */ @@ -103,7 +103,7 @@ class ThreadManager extends CachedManager { * .create({ * name: 'mod-talk', * autoArchiveDuration: 60, - * type: 'private_thread', + * type: 'GUILD_PRIVATE_THREAD', * reason: 'Needed a separate thread for moderation', * }) * .then(threadChannel => console.log(threadChannel)) @@ -114,13 +114,14 @@ class ThreadManager extends CachedManager { if (type && typeof type !== 'string' && typeof type !== 'number') { throw new TypeError('INVALID_TYPE', 'type', 'ThreadChannelType or Number'); } - let resolvedType = this.channel.type === 'news' ? ChannelTypes.NEWS_THREAD : ChannelTypes.PUBLIC_THREAD; + let resolvedType = + this.channel.type === 'GUILD_NEWS' ? ChannelTypes.GUILD_NEWS_THREAD : ChannelTypes.GUILD_PUBLIC_THREAD; if (startMessage) { const startMessageId = this.channel.messages.resolveId(startMessage); if (!startMessageId) throw new TypeError('INVALID_TYPE', 'startMessage', 'MessageResolvable'); path = path.messages(startMessageId); - } else if (this.channel.type !== 'news') { - resolvedType = typeof type === 'string' ? ChannelTypes[type.toUpperCase()] : type ?? resolvedType; + } else if (this.channel.type !== 'GUILD_NEWS') { + resolvedType = typeof type === 'string' ? ChannelTypes[type] : type ?? resolvedType; } const data = await path.threads.post({ diff --git a/src/structures/Channel.js b/src/structures/Channel.js index 37a7e5e73dcb..c862e1a941bb 100644 --- a/src/structures/Channel.js +++ b/src/structures/Channel.js @@ -23,21 +23,10 @@ class Channel extends Base { const type = ChannelTypes[data.type]; /** - * The type of the channel, either: - * * `dm` - a DM channel - * * `text` - a guild text channel - * * `voice` - a guild voice channel - * * `category` - a guild category channel - * * `news` - a guild news channel - * * `store` - a guild store channel - * * `news_thread` - a guild news channel's public thread channel - * * `public_thread` - a guild text channel's public thread channel - * * `private_thread` - a guild text channel's private thread channel - * * `stage` - a guild stage channel - * * `unknown` - a generic channel of unknown type, could be Channel or GuildChannel - * @type {string} + * The type of the channel + * @type {ChannelType} */ - this.type = type?.toLowerCase() ?? 'unknown'; + this.type = type ?? 'UNKNOWN'; /** * Whether the channel has been deleted @@ -139,9 +128,9 @@ class Channel extends Base { let channel; if (!data.guild_id && !guild) { - if ((data.recipients && data.type !== ChannelTypes.GROUP) || data.type === ChannelTypes.DM) { + if ((data.recipients && data.type !== ChannelTypes.GROUP_DM) || data.type === ChannelTypes.DM) { channel = new DMChannel(client, data); - } else if (data.type === ChannelTypes.GROUP) { + } else if (data.type === ChannelTypes.GROUP_DM) { const PartialGroupDMChannel = require('./PartialGroupDMChannel'); channel = new PartialGroupDMChannel(client, data); } @@ -150,33 +139,33 @@ class Channel extends Base { if (guild || allowUnknownGuild) { switch (data.type) { - case ChannelTypes.TEXT: { + case ChannelTypes.GUILD_TEXT: { channel = new TextChannel(guild, data, client); break; } - case ChannelTypes.VOICE: { + case ChannelTypes.GUILD_VOICE: { channel = new VoiceChannel(guild, data, client); break; } - case ChannelTypes.CATEGORY: { + case ChannelTypes.GUILD_CATEGORY: { channel = new CategoryChannel(guild, data, client); break; } - case ChannelTypes.NEWS: { + case ChannelTypes.GUILD_NEWS: { channel = new NewsChannel(guild, data, client); break; } - case ChannelTypes.STORE: { + case ChannelTypes.GUILD_STORE: { channel = new StoreChannel(guild, data, client); break; } - case ChannelTypes.STAGE: { + case ChannelTypes.GUILD_STAGE_VOICE: { channel = new StageChannel(guild, data, client); break; } - case ChannelTypes.NEWS_THREAD: - case ChannelTypes.PUBLIC_THREAD: - case ChannelTypes.PRIVATE_THREAD: { + case ChannelTypes.GUILD_NEWS_THREAD: + case ChannelTypes.GUILD_PUBLIC_THREAD: + case ChannelTypes.GUILD_PRIVATE_THREAD: { channel = new ThreadChannel(guild, data, client); if (!allowUnknownGuild) channel.parent?.threads.cache.set(channel.id, channel); break; diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js index f4b635eff411..6aeb50c0ee37 100644 --- a/src/structures/DMChannel.js +++ b/src/structures/DMChannel.js @@ -17,7 +17,7 @@ class DMChannel extends Channel { constructor(client, data) { super(client, data); // Override the channel type so partials have a known type - this.type = 'dm'; + this.type = 'DM'; /** * A manager of the messages belonging to this channel * @type {MessageManager} diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 57b1e5d00b06..5004c86a3869 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -1358,12 +1358,12 @@ class Guild extends AnonymousGuild { * @private */ _sortedChannels(channel) { - const category = channel.type === ChannelTypes.CATEGORY; + const category = channel.type === ChannelTypes.GUILD_CATEGORY; return Util.discordSort( this.channels.cache.filter( c => - (['text', 'news', 'store'].includes(channel.type) - ? ['text', 'news', 'store'].includes(c.type) + (['GUILD_TEXT', 'GUILD_NEWS', 'GUILD_STORE'].includes(channel.type) + ? ['GUILD_TEXT', 'GUILD_NEWS', 'GUILD_STORE'].includes(c.type) : c.type === channel.type) && (category || c.parent === channel.parent), ), diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index e97962e3a675..f5c049969068 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -5,7 +5,7 @@ const PermissionOverwrites = require('./PermissionOverwrites'); const { Error } = require('../errors'); const PermissionOverwriteManager = require('../managers/PermissionOverwriteManager'); const Collection = require('../util/Collection'); -const { ChannelTypes } = require('../util/Constants'); +const { ChannelTypes, VoiceBasedChannelTypes } = require('../util/Constants'); const Permissions = require('../util/Permissions'); const Util = require('../util/Util'); @@ -265,7 +265,7 @@ class GuildChannel extends Channel { * The data for a guild channel. * @typedef {Object} ChannelData * @property {string} [name] The name of the channel - * @property {string} [type] The type of the the channel (only conversion between text and news is supported) + * @property {ChannelType} [type] The type of the 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 @@ -319,7 +319,7 @@ class GuildChannel extends Channel { if (data.lockPermissions) { if (data.parentId) { const newParent = this.guild.channels.resolve(data.parentId); - if (newParent?.type === 'category') { + if (newParent?.type === 'GUILD_CATEGORY') { permission_overwrites = newParent.permissionOverwrites.cache.map(o => PermissionOverwrites.resolve(o, this.guild), ); @@ -334,7 +334,7 @@ class GuildChannel extends Channel { const newData = await this.client.api.channels(this.id).patch({ data: { name: (data.name ?? this.name).trim(), - type: ChannelTypes[data.type?.toUpperCase()], + type: ChannelTypes[data.type], topic: data.topic, nsfw: data.nsfw, bitrate: data.bitrate ?? this.bitrate, @@ -567,7 +567,7 @@ class GuildChannel extends Channel { */ get manageable() { if (this.client.user.id === this.guild.ownerId) return true; - if (this.type === 'voice' || this.type === 'stage') { + if (this.type in VoiceBasedChannelTypes) { if (!this.permissionsFor(this.client.user).has(Permissions.FLAGS.CONNECT, false)) { return false; } diff --git a/src/structures/Message.js b/src/structures/Message.js index cdd8b7cd63ad..41fd35208328 100644 --- a/src/structures/Message.js +++ b/src/structures/Message.js @@ -552,7 +552,7 @@ class Message extends Base { */ get crosspostable() { return ( - this.channel.type === 'news' && + this.channel.type === 'GUILD_NEWS' && !this.flags.has(MessageFlags.FLAGS.CROSSPOSTED) && this.type === 'DEFAULT' && this.channel.viewable && @@ -595,7 +595,7 @@ class Message extends Base { * @returns {Promise} * @example * // Crosspost a message - * if (message.channel.type === 'news') { + * if (message.channel.type === 'GUILD_NEWS') { * message.crosspost() * .then(() => console.log('Crossposted message')) * .catch(console.error); @@ -713,7 +713,7 @@ class Message extends Base { * @returns {Promise} */ startThread(name, autoArchiveDuration, reason) { - if (!['text', 'news'].includes(this.channel.type)) { + if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(this.channel.type)) { return Promise.reject(new Error('MESSAGE_THREAD_PARENT')); } return this.channel.threads.create({ name, autoArchiveDuration, startMessage: this, reason }); diff --git a/src/structures/MessageMentions.js b/src/structures/MessageMentions.js index 957437d19c63..4c9d75f60cbb 100644 --- a/src/structures/MessageMentions.js +++ b/src/structures/MessageMentions.js @@ -117,7 +117,7 @@ class MessageMentions { this.crosspostedChannels.set(d.id, { channelId: d.id, guildId: d.guild_id, - type: type?.toLowerCase() ?? 'unknown', + type: type ?? 'UNKNOWN', name: d.name, }); } diff --git a/src/structures/NewsChannel.js b/src/structures/NewsChannel.js index 822d805ab9b6..453141b9c09d 100644 --- a/src/structures/NewsChannel.js +++ b/src/structures/NewsChannel.js @@ -21,7 +21,7 @@ class NewsChannel extends TextChannel { * @param {string} [reason] Reason for creating the webhook * @returns {Promise} * @example - * if (channel.type === 'news') { + * if (channel.type === 'GUILD_NEWS') { * channel.addFollower('222197033908436994', 'Important announcements') * .then(() => console.log('Added follower')) * .catch(console.error); diff --git a/src/structures/ThreadChannel.js b/src/structures/ThreadChannel.js index b98a5525b58c..2c47232c02e9 100644 --- a/src/structures/ThreadChannel.js +++ b/src/structures/ThreadChannel.js @@ -346,7 +346,7 @@ class ThreadChannel extends Channel { !this.archived && !this.joined && this.permissionsFor(this.client.user)?.has( - this.type === 'private_thread' ? Permissions.FLAGS.MANAGE_THREADS : Permissions.FLAGS.VIEW_CHANNEL, + this.type === 'GUILD_PRIVATE_THREAD' ? Permissions.FLAGS.MANAGE_THREADS : Permissions.FLAGS.VIEW_CHANNEL, false, ) ); @@ -373,7 +373,9 @@ class ThreadChannel extends Channel { this.permissionsFor(this.client.user)?.any( [ Permissions.FLAGS.SEND_MESSAGES, - this.type === 'private_thread' ? Permissions.FLAGS.USE_PRIVATE_THREADS : Permissions.FLAGS.USE_PUBLIC_THREADS, + this.type === 'GUILD_PRIVATE_THREAD' + ? Permissions.FLAGS.USE_PRIVATE_THREADS + : Permissions.FLAGS.USE_PUBLIC_THREADS, ], false, ) diff --git a/src/structures/User.js b/src/structures/User.js index 62d5dbad441c..9fc048fa21bd 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -193,7 +193,7 @@ class User extends Base { * @readonly */ get dmChannel() { - return this.client.channels.cache.find(c => c.type === 'dm' && c.recipient.id === this.id) ?? null; + return this.client.channels.cache.find(c => c.type === 'DM' && c.recipient.id === this.id) ?? null; } /** diff --git a/src/structures/VoiceState.js b/src/structures/VoiceState.js index 7e611fb264a5..9f15ef2ae074 100644 --- a/src/structures/VoiceState.js +++ b/src/structures/VoiceState.js @@ -171,7 +171,7 @@ class VoiceState extends Base { * @returns {Promise} */ async setRequestToSpeak(request) { - if (this.channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL'); + if (this.channel?.type !== 'GUILD_STAGE_VOICE') throw new Error('VOICE_NOT_STAGE_CHANNEL'); if (this.client.user.id !== this.id) throw new Error('VOICE_STATE_NOT_OWN'); @@ -203,7 +203,7 @@ class VoiceState extends Base { async setSuppressed(suppressed) { if (typeof suppressed !== 'boolean') throw new TypeError('VOICE_STATE_INVALID_TYPE', 'suppressed'); - if (this.channel?.type !== 'stage') throw new Error('VOICE_NOT_STAGE_CHANNEL'); + if (this.channel?.type !== 'GUILD_STAGE_VOICE') throw new Error('VOICE_NOT_STAGE_CHANNEL'); const target = this.client.user.id === this.id ? '@me' : this.id; diff --git a/src/util/Constants.js b/src/util/Constants.js index ee2e744f9457..9fbb1dfbe491 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -415,31 +415,73 @@ exports.SystemMessageTypes = exports.MessageTypes.filter( */ exports.ActivityTypes = createEnum(['PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM', 'COMPETING']); +/** + * All available channel types: + * * `GUILD_TEXT` - a guild text channel + * * `DM` - a DM channel + * * `GUILD_VOICE` - a guild voice channel + * * `GROUP_DM` - a group DM channel + * * `GUILD_CATEGORY` - a guild category channel + * * `GUILD_NEWS` - a guild news channel + * * `GUILD_STORE` - a guild store channel + * * `GUILD_NEWS_THREAD` - a guild news channel's public thread channel + * * `GUILD_PUBLIC_THREAD` - a guild text channel's public thread channel + * * `GUILD_PRIVATE_THREAD` - a guild text channel's private thread channel + * * `GUILD_STAGE_VOICE` - a guild stage voice channel + * * `UNKNOWN` - a generic channel of unknown type, could be Channel or GuildChannel + * @typedef {string} ChannelType + */ exports.ChannelTypes = createEnum([ - 'TEXT', + 'GUILD_TEXT', 'DM', - 'VOICE', - 'GROUP', - 'CATEGORY', - 'NEWS', - // 6 - 'STORE', + 'GUILD_VOICE', + 'GROUP_DM', + 'GUILD_CATEGORY', + 'GUILD_NEWS', + 'GUILD_STORE', ...Array(3).fill(null), // 10 - 'NEWS_THREAD', - 'PUBLIC_THREAD', - 'PRIVATE_THREAD', - 'STAGE', + 'GUILD_NEWS_THREAD', + 'GUILD_PUBLIC_THREAD', + 'GUILD_PRIVATE_THREAD', + 'GUILD_STAGE_VOICE', ]); +/** + * The types of channels that are text-based. The available types are: + * * DM + * * GUILD_TEXT + * * GUILD_NEWS + * * GUILD_NEWS_THREAD + * * GUILD_PUBLIC_THREAD + * * GUILD_PRIVATE_THREAD + * @typedef {string} TextBasedChannelTypes + */ +exports.TextBasedChannelTypes = [ + 'DM', + 'GUILD_TEXT', + 'GUILD_NEWS', + 'GUILD_NEWS_THREAD', + 'GUILD_PUBLIC_THREAD', + 'GUILD_PRIVATE_THREAD', +]; + /** * The types of channels that are threads. The available types are: - * * news_thread - * * public_thread - * * private_thread - * @typedef {string} ThreadChannelType + * * GUILD_NEWS_THREAD + * * GUILD_PUBLIC_THREAD + * * GUILD_PRIVATE_THREAD + * @typedef {string} ThreadChannelTypes + */ +exports.ThreadChannelTypes = ['GUILD_NEWS_THREAD', 'GUILD_PUBLIC_THREAD', 'GUILD_PRIVATE_THREAD']; + +/** + * The types of channels that are voice-based. The available types are: + * * GUILD_VOICE + * * GUILD_STAGE_VOICE + * @typedef {string} VoiceBasedChannelTypes */ -exports.ThreadChannelTypes = ['news_thread', 'public_thread', 'private_thread']; +exports.VoiceBasedChannelTypes = ['GUILD_VOICE', 'GUILD_STAGE_VOICE']; exports.ClientApplicationAssetTypes = { SMALL: 1, diff --git a/src/util/Util.js b/src/util/Util.js index 4b30ec0ed4af..2e06fef4c543 100644 --- a/src/util/Util.js +++ b/src/util/Util.js @@ -582,7 +582,7 @@ class Util extends null { str = str .replace(/<@!?[0-9]+>/g, input => { const id = input.replace(/<|!|>|@/g, ''); - if (channel.type === 'dm') { + if (channel.type === 'DM') { const user = channel.client.users.cache.get(id); return user ? Util.removeMentions(`@${user.username}`) : input; } @@ -600,7 +600,7 @@ class Util extends null { return mentionedChannel ? `#${mentionedChannel.name}` : input; }) .replace(/<@&[0-9]+>/g, input => { - if (channel.type === 'dm') return input; + if (channel.type === 'DM') return input; const role = channel.guild.roles.cache.get(input.replace(/<|@|>|&/g, '')); return role ? `@${role.name}` : input; }); diff --git a/test/createGuild.js b/test/createGuild.js index 4e8255e20cdd..fdb61804aa25 100644 --- a/test/createGuild.js +++ b/test/createGuild.js @@ -10,7 +10,7 @@ client.on('ready', async () => { try { const guild = await client.guilds.create('testing', { channels: [ - { name: 'afk channel', type: 'voice', id: 0 }, + { name: 'afk channel', type: 'GUILD_VOICE', id: 0 }, { name: 'system-channel', id: 1 }, ], afkChannelId: 0, diff --git a/test/random.js b/test/random.js index 4aa9d823f02a..53162dd11d72 100644 --- a/test/random.js +++ b/test/random.js @@ -46,7 +46,7 @@ client.on('messageCreate', message => { if (true) { if (message.content === 'makechann') { if (message.channel.guild) { - message.channel.guild.channels.create('hi', { type: 'text' }).then(console.log); + message.channel.guild.channels.create('hi', { type: 'GUILD_TEXT' }).then(console.log); } } diff --git a/typings/enums.d.ts b/typings/enums.d.ts index 70b96f6ec954..fc14499a853c 100644 --- a/typings/enums.d.ts +++ b/typings/enums.d.ts @@ -27,33 +27,19 @@ export enum ApplicationCommandPermissionTypes { USER = 2, } -export enum ChannelType { - text = 0, - dm = 1, - voice = 2, - group = 3, - category = 4, - news = 5, - store = 6, - unknown = 7, - news_thread = 10, - public_thread = 11, - private_thread = 12, - stage = 13, -} - export enum ChannelTypes { - TEXT = 0, + GUILD_TEXT = 0, DM = 1, - VOICE = 2, - GROUP = 3, - CATEGORY = 4, - NEWS = 5, - STORE = 6, - NEWS_THREAD = 10, - PUBLIC_THREAD = 11, - PRIVATE_THREAD = 12, - STAGE = 13, + GUILD_VOICE = 2, + GROUP_DM = 3, + GUILD_CATEGORY = 4, + GUILD_NEWS = 5, + GUILD_STORE = 6, + UNKNOWN = 7, + GUILD_NEWS_THREAD = 10, + GUILD_PUBLIC_THREAD = 11, + GUILD_PRIVATE_THREAD = 12, + GUILD_STAGE_VOICE = 13, } export enum DefaultMessageNotificationLevels { diff --git a/typings/index.d.ts b/typings/index.d.ts index 934ed09d9663..ac9bb429f300 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -37,7 +37,6 @@ import { ActivityTypes, ApplicationCommandOptionTypes, ApplicationCommandPermissionTypes, - ChannelType, ChannelTypes, ConstantsClientApplicationAssetTypes, ConstantsColors, @@ -259,7 +258,7 @@ export class ButtonInteraction extends MessageComponentInteraction { export class CategoryChannel extends GuildChannel { public readonly children: Collection; - public type: 'category'; + public type: 'GUILD_CATEGORY'; } export type CategoryChannelResolvable = Snowflake | CategoryChannel; @@ -270,7 +269,7 @@ export class Channel extends Base { public readonly createdTimestamp: number; public deleted: boolean; public id: Snowflake; - public type: keyof typeof ChannelType; + public type: keyof typeof ChannelTypes; public delete(): Promise; public fetch(force?: boolean): Promise; public isText(): this is TextChannel | DMChannel | NewsChannel | ThreadChannel; @@ -458,7 +457,7 @@ export class DMChannel extends TextBasedChannel(Channel, ['bulkDelete']) { public messages: MessageManager; public recipient: User; public readonly partial: false; - public type: 'dm'; + public type: 'DM'; public fetch(force?: boolean): Promise; } @@ -646,7 +645,7 @@ export class GuildChannel extends Channel { public readonly permissionsLocked: boolean | null; public readonly position: number; public rawPosition: number; - public type: Exclude; + public type: Exclude; public readonly viewable: boolean; public clone(options?: GuildChannelCloneOptions): Promise; public createInvite(options?: CreateInviteOptions): Promise; @@ -1229,14 +1228,14 @@ export class NewsChannel extends TextBasedChannel(GuildChannel) { public nsfw: boolean; public threads: ThreadManager; public topic: string | null; - public type: 'news'; + public type: 'GUILD_NEWS'; public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise; public setDefaultAutoArchiveDuration( defaultAutoArchiveDuration: ThreadAutoArchiveDuration, reason?: string, ): Promise; public setNSFW(nsfw: boolean, reason?: string): Promise; - public setType(type: Pick, reason?: string): Promise; + public setType(type: Pick, reason?: string): Promise; public fetchWebhooks(): Promise>; public addFollower(channel: GuildChannelResolvable, reason?: string): Promise; } @@ -1492,7 +1491,7 @@ export class SnowflakeUtil extends null { export class StageChannel extends BaseGuildVoiceChannel { public topic: string | null; - public type: 'stage'; + public type: 'GUILD_STAGE_VOICE'; public readonly stageInstance: StageInstance | null; public createStageInstance(options: StageInstanceCreateOptions): Promise; } @@ -1532,7 +1531,7 @@ export class Sticker extends Base { export class StoreChannel extends GuildChannel { public constructor(guild: Guild, data?: unknown, client?: Client); public nsfw: boolean; - public type: 'store'; + public type: 'GUILD_STORE'; } export class SystemChannelFlags extends BitField { @@ -1573,7 +1572,7 @@ export class TextChannel extends TextBasedChannel(GuildChannel) { public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration; public messages: MessageManager; public nsfw: boolean; - public type: 'text'; + public type: 'GUILD_TEXT'; public rateLimitPerUser: number; public threads: ThreadManager; public topic: string | null; @@ -1584,7 +1583,7 @@ export class TextChannel extends TextBasedChannel(GuildChannel) { ): Promise; public setNSFW(nsfw: boolean, reason?: string): Promise; public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise; - public setType(type: Pick, reason?: string): Promise; + public setType(type: Pick, reason?: string): Promise; public fetchWebhooks(): Promise>; } @@ -1612,7 +1611,7 @@ export class ThreadChannel extends TextBasedChannel(Channel) { public readonly parent: TextChannel | NewsChannel | null; public parentId: Snowflake; public rateLimitPerUser: number; - public type: ThreadChannelType; + public type: ThreadChannelTypes; public readonly unarchivable: boolean; public delete(reason?: string): Promise; public edit(data: ThreadEditData, reason?: string): Promise; @@ -1742,7 +1741,7 @@ export class Formatters extends null { export class VoiceChannel extends BaseGuildVoiceChannel { public readonly editable: boolean; public readonly speakable: boolean; - public type: 'voice'; + public type: 'GUILD_VOICE'; public setBitrate(bitrate: number, reason?: string): Promise; public setUserLimit(userLimit: number, reason?: string): Promise; } @@ -2005,7 +2004,9 @@ export const Constants: { Opcodes: typeof ConstantsOpcodes; APIErrors: APIErrors; ChannelTypes: typeof ChannelTypes; - ThreadChannelTypes: ThreadChannelType[]; + ThreadChannelTypes: ThreadChannelTypes[]; + TextBasedChannelTypes: TextBasedChannelTypes[]; + VoiceBasedChannelTypes: VoiceBasedChannelTypes[]; ClientApplicationAssetTypes: typeof ConstantsClientApplicationAssetTypes; InviteScopes: InviteScope[]; MessageTypes: MessageType[]; @@ -2168,12 +2169,18 @@ export class GuildChannelManager extends CachedManager< public constructor(guild: Guild, iterable?: Iterable); public readonly channelCountWithoutThreads: number; public guild: Guild; - public create(name: string, options: GuildChannelCreateOptions & { type: 'voice' }): Promise; - public create(name: string, options: GuildChannelCreateOptions & { type: 'category' }): Promise; - public create(name: string, options?: GuildChannelCreateOptions & { type?: 'text' }): Promise; - public create(name: string, options: GuildChannelCreateOptions & { type: 'news' }): Promise; - public create(name: string, options: GuildChannelCreateOptions & { type: 'store' }): Promise; - public create(name: string, options: GuildChannelCreateOptions & { type: 'stage' }): Promise; + public create(name: string, options: GuildChannelCreateOptions & { type: 'GUILD_VOICE' }): Promise; + public create( + name: string, + options: GuildChannelCreateOptions & { type: 'GUILD_CATEGORY' }, + ): Promise; + public create(name: string, options?: GuildChannelCreateOptions & { type?: 'GUILD_TEXT' }): Promise; + public create(name: string, options: GuildChannelCreateOptions & { type: 'GUILD_NEWS' }): Promise; + public create(name: string, options: GuildChannelCreateOptions & { type: 'GUILD_STORE' }): Promise; + public create( + name: string, + options: GuildChannelCreateOptions & { type: 'GUILD_STAGE_VOICE' }, + ): Promise; public create( name: string, options: GuildChannelCreateOptions, @@ -2486,9 +2493,9 @@ export interface AddGuildMemberOptions { export type AllowedImageFormat = 'webp' | 'png' | 'jpg' | 'jpeg' | 'gif'; -export type AllowedThreadTypeForNewsChannel = 'news_thread' | 10; +export type AllowedThreadTypeForNewsChannel = 'GUILD_NEWS_THREAD' | 10; -export type AllowedThreadTypeForTextChannel = 'public_thread' | 'private_thread' | 11 | 12; +export type AllowedThreadTypeForTextChannel = 'GUILD_PUBLIC_THREAD' | 'GUILD_PRIVATE_THREAD' | 11 | 12; export interface APIErrors { UNKNOWN_ACCOUNT: 10001; @@ -2727,7 +2734,7 @@ export interface ChannelCreationOverwrites { export interface ChannelData { name?: string; - type?: Pick; + type?: Pick; position?: number; topic?: string; nsfw?: boolean; @@ -2957,7 +2964,7 @@ export interface StageInstanceCreateOptions { export interface CrosspostedChannel { channelId: Snowflake; guildId: Snowflake; - type: keyof typeof ChannelType; + type: keyof typeof ChannelTypes; name: string; } @@ -3182,17 +3189,17 @@ export interface GuildChannelCreateOptions { permissionOverwrites?: OverwriteResolvable[] | Collection; topic?: string; type?: Exclude< - keyof typeof ChannelType | ChannelType, - | 'dm' - | 'group' - | 'unknown' - | 'public_thread' - | 'private_thread' - | ChannelType.dm - | ChannelType.group - | ChannelType.unknown - | ChannelType.public_thread - | ChannelType.private_thread + keyof typeof ChannelTypes | ChannelTypes, + | 'DM' + | 'GROUP_DM' + | 'UNKNOWN' + | 'GUILD_PUBLIC_THREAD' + | 'GUILD_PRIVATE_THREAD' + | ChannelTypes.DM + | ChannelTypes.GROUP_DM + | ChannelTypes.UNKNOWN + | ChannelTypes.GUILD_PUBLIC_THREAD + | ChannelTypes.GUILD_PRIVATE_THREAD >; nsfw?: boolean; parent?: ChannelResolvable; @@ -3807,7 +3814,7 @@ export interface PartialDMChannel lastMessageId: undefined; messages: MessageManager; recipient: User | PartialUser; - type: 'dm'; + type: 'DM'; readonly typing: boolean; readonly typingCount: number; } @@ -3816,7 +3823,7 @@ export interface PartialChannelData { id?: Snowflake | number; name: string; topic?: string; - type?: ChannelType; + type?: ChannelTypes; parentId?: Snowflake | number; permissionOverwrites?: PartialOverwriteData[]; } @@ -4033,11 +4040,19 @@ export interface StageInstanceEditOptions { privacyLevel?: PrivacyLevel | number; } +export type TextBasedChannelTypes = + | 'DM' + | 'GUILD_TEXT' + | 'GUILD_NEWS' + | 'GUILD_NEWS_THREAD' + | 'GUILD_PUBLIC_THREAD' + | 'GUILD_PRIVATE_THREAD'; + export type ThreadAutoArchiveDuration = 60 | 1440 | 4320 | 10080; export type ThreadChannelResolvable = ThreadChannel | Snowflake; -export type ThreadChannelType = 'news_thread' | 'public_thread' | 'private_thread'; +export type ThreadChannelTypes = 'GUILD_NEWS_THREAD' | 'GUILD_PUBLIC_THREAD' | 'GUILD_PRIVATE_THREAD'; export interface ThreadCreateOptions { name: string; @@ -4085,6 +4100,8 @@ export interface Vanity { export type VerificationLevel = keyof typeof VerificationLevels; +export type VoiceBasedChannelTypes = 'GUILD_VOICE' | 'GUILD_STAGE_VOICE'; + export type WebhookClientOptions = Pick< ClientOptions, 'allowedMentions' | 'restTimeOffset' | 'restRequestTimeout' | 'retryLimit' | 'http'