Skip to content

Commit

Permalink
types(MessageManager): Allow comparison of messages again (#9612)
Browse files Browse the repository at this point in the history
* types(MessageManager): allow comparison of messages again

* feat: match TypeScript

* docs: update wording

* chore: revert breaking change

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
Jiralite and kodiakhq[bot] authored Jul 7, 2023
1 parent a73d54e commit a48d0ef
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 33 deletions.
2 changes: 2 additions & 0 deletions packages/discord.js/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ exports.CachedManager = require('./managers/CachedManager');
exports.ChannelManager = require('./managers/ChannelManager');
exports.ClientVoiceManager = require('./client/voice/ClientVoiceManager');
exports.DataManager = require('./managers/DataManager');
exports.DMMessageManager = require('./managers/DMMessageManager');
exports.GuildApplicationCommandManager = require('./managers/GuildApplicationCommandManager');
exports.GuildBanManager = require('./managers/GuildBanManager');
exports.GuildChannelManager = require('./managers/GuildChannelManager');
Expand All @@ -65,6 +66,7 @@ exports.GuildInviteManager = require('./managers/GuildInviteManager');
exports.GuildManager = require('./managers/GuildManager');
exports.GuildMemberManager = require('./managers/GuildMemberManager');
exports.GuildMemberRoleManager = require('./managers/GuildMemberRoleManager');
exports.GuildMessageManager = require('./managers/GuildMessageManager');
exports.GuildScheduledEventManager = require('./managers/GuildScheduledEventManager');
exports.GuildStickerManager = require('./managers/GuildStickerManager');
exports.GuildTextThreadManager = require('./managers/GuildTextThreadManager');
Expand Down
17 changes: 17 additions & 0 deletions packages/discord.js/src/managers/DMMessageManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

const MessageManager = require('./MessageManager');

/**
* Manages API methods for messages in direct message channels and holds their cache.
* @extends {MessageManager}
*/
class DMMessageManager extends MessageManager {
/**
* The channel that the messages belong to
* @name DMMessageManager#channel
* @type {DMChannel}
*/
}

module.exports = DMMessageManager;
17 changes: 17 additions & 0 deletions packages/discord.js/src/managers/GuildMessageManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

const MessageManager = require('./MessageManager');

/**
* Manages API methods for messages in a guild and holds their cache.
* @extends {MessageManager}
*/
class GuildMessageManager extends MessageManager {
/**
* The channel that the messages belong to
* @name GuildMessageManager#channel
* @type {GuildTextBasedChannel}
*/
}

module.exports = GuildMessageManager;
1 change: 1 addition & 0 deletions packages/discord.js/src/managers/MessageManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const { resolvePartialEmoji } = require('../util/Util');
/**
* Manages API methods for Messages and holds their cache.
* @extends {CachedManager}
* @abstract
*/
class MessageManager extends CachedManager {
constructor(channel, iterable) {
Expand Down
6 changes: 3 additions & 3 deletions packages/discord.js/src/structures/BaseGuildTextChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

const GuildChannel = require('./GuildChannel');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const GuildMessageManager = require('../managers/GuildMessageManager');
const GuildTextThreadManager = require('../managers/GuildTextThreadManager');
const MessageManager = require('../managers/MessageManager');

/**
* Represents a text-based guild channel on Discord.
Expand All @@ -16,9 +16,9 @@ class BaseGuildTextChannel extends GuildChannel {

/**
* A manager of the messages sent to this channel
* @type {MessageManager}
* @type {GuildMessageManager}
*/
this.messages = new MessageManager(this);
this.messages = new GuildMessageManager(this);

/**
* A manager of the threads belonging to this channel
Expand Down
6 changes: 3 additions & 3 deletions packages/discord.js/src/structures/BaseGuildVoiceChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { Collection } = require('@discordjs/collection');
const { PermissionFlagsBits } = require('discord-api-types/v10');
const GuildChannel = require('./GuildChannel');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const MessageManager = require('../managers/MessageManager');
const GuildMessageManager = require('../managers/GuildMessageManager');

/**
* Represents a voice-based guild channel on Discord.
Expand All @@ -16,9 +16,9 @@ class BaseGuildVoiceChannel extends GuildChannel {
super(guild, data, client, false);
/**
* A manager of the messages sent to this channel
* @type {MessageManager}
* @type {GuildMessageManager}
*/
this.messages = new MessageManager(this);
this.messages = new GuildMessageManager(this);

/**
* If the guild considers this channel NSFW
Expand Down
6 changes: 3 additions & 3 deletions packages/discord.js/src/structures/DMChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { userMention } = require('@discordjs/builders');
const { ChannelType } = require('discord-api-types/v10');
const { BaseChannel } = require('./BaseChannel');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const MessageManager = require('../managers/MessageManager');
const DMMessageManager = require('../managers/DMMessageManager');
const Partials = require('../util/Partials');

/**
Expand All @@ -21,9 +21,9 @@ class DMChannel extends BaseChannel {

/**
* A manager of the messages belonging to this channel
* @type {MessageManager}
* @type {DMMessageManager}
*/
this.messages = new MessageManager(this);
this.messages = new DMMessageManager(this);
}

_patch(data) {
Expand Down
6 changes: 3 additions & 3 deletions packages/discord.js/src/structures/ThreadChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { ChannelType, PermissionFlagsBits, Routes, ChannelFlags } = require('disc
const { BaseChannel } = require('./BaseChannel');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const { DiscordjsRangeError, ErrorCodes } = require('../errors');
const MessageManager = require('../managers/MessageManager');
const GuildMessageManager = require('../managers/GuildMessageManager');
const ThreadMemberManager = require('../managers/ThreadMemberManager');
const ChannelFlagsBitField = require('../util/ChannelFlagsBitField');

Expand All @@ -31,9 +31,9 @@ class ThreadChannel extends BaseChannel {

/**
* A manager of the messages sent to this thread
* @type {MessageManager}
* @type {GuildMessageManager}
*/
this.messages = new MessageManager(this);
this.messages = new GuildMessageManager(this);

/**
* A manager of the members that are part of this thread
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class TextBasedChannel {
constructor() {
/**
* A manager of the messages sent to this channel
* @type {MessageManager}
* @type {GuildMessageManager}
*/
this.messages = new MessageManager(this);
this.messages = new GuildMessageManager(this);

/**
* The channel's last message id, if one was sent
Expand Down Expand Up @@ -410,4 +410,4 @@ module.exports = TextBasedChannel;

// Fixes Circular
// eslint-disable-next-line import/order
const MessageManager = require('../../managers/MessageManager');
const GuildMessageManager = require('../../managers/GuildMessageManager');
18 changes: 13 additions & 5 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4005,14 +4005,13 @@ export class GuildMemberRoleManager extends DataManager<Snowflake, Role, RoleRes
): Promise<GuildMember>;
}

export class MessageManager<InGuild extends boolean = boolean> extends CachedManager<
export abstract class MessageManager<InGuild extends boolean = boolean> extends CachedManager<
Snowflake,
Message<InGuild>,
MessageResolvable
> {
private constructor(channel: TextBasedChannel, iterable?: Iterable<RawMessageData>);
public channel: If<InGuild, GuildTextBasedChannel, TextBasedChannel>;
public crosspost(message: MessageResolvable): Promise<Message<InGuild>>;
protected constructor(channel: TextBasedChannel, iterable?: Iterable<RawMessageData>);
public channel: TextBasedChannel;
public delete(message: MessageResolvable): Promise<void>;
public edit(
message: MessageResolvable,
Expand All @@ -4026,6 +4025,15 @@ export class MessageManager<InGuild extends boolean = boolean> extends CachedMan
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
}

export class DMMessageManager extends MessageManager {
public channel: DMChannel;
}

export class GuildMessageManager extends MessageManager<true> {
public channel: GuildTextBasedChannel;
public crosspost(message: MessageResolvable): Promise<Message<true>>;
}

export class PermissionOverwriteManager extends CachedManager<
Snowflake,
PermissionOverwrites,
Expand Down Expand Up @@ -4192,7 +4200,7 @@ export interface TextBasedChannelFields<InGuild extends boolean = boolean>
get lastMessage(): Message | null;
lastPinTimestamp: number | null;
get lastPinAt(): Date | null;
messages: MessageManager<InGuild>;
messages: If<InGuild, GuildMessageManager, DMMessageManager>;
awaitMessageComponent<T extends MessageComponentType>(
options?: AwaitMessageCollectorOptionsParams<T, true>,
): Promise<MappedInteractionTypes[T]>;
Expand Down
47 changes: 34 additions & 13 deletions packages/discord.js/typings/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ import {
ThreadManager,
FetchedThreads,
FetchedThreadsMore,
DMMessageManager,
GuildMessageManager,
ApplicationCommandChannelOptionData,
ApplicationCommandChannelOption,
ApplicationCommandChoicesOption,
Expand Down Expand Up @@ -349,6 +351,19 @@ declare const assertIsMessage: (m: Promise<Message>) => void;
client.on('messageCreate', async message => {
const { client, channel } = message;

// https://github.com/discordjs/discord.js/issues/8545
{
// These should not throw any errors when comparing messages from any source.
channel.messages.cache.filter(m => m);
(await channel.messages.fetch()).filter(m => m.author.id === message.author.id);

if (channel.isDMBased()) {
expectType<DMMessageManager>(channel.messages.channel.messages);
} else {
expectType<GuildMessageManager>(channel.messages.channel.messages);
}
}

if (!message.inGuild() && message.partial) {
expectNotType<never>(message);
}
Expand Down Expand Up @@ -1519,7 +1534,7 @@ declare const guildChannelManager: GuildChannelManager;
if (channel.isTextBased()) {
const { messages } = channel;
const message = await messages.fetch('123');
expectType<MessageManager<true>>(messages);
expectType<GuildMessageManager>(messages);
expectType<Promise<Message<true>>>(messages.crosspost('1234567890'));
expectType<Promise<Message<true>>>(messages.edit('1234567890', 'text'));
expectType<Promise<Message<true>>>(messages.fetch('1234567890'));
Expand All @@ -1533,18 +1548,24 @@ declare const guildChannelManager: GuildChannelManager;
{
const { messages } = dmChannel;
const message = await messages.fetch('123');
expectType<MessageManager<false>>(messages);
expectType<Promise<Message<false>>>(messages.crosspost('1234567890')); // This shouldn't even exist!
expectType<Promise<Message<false>>>(messages.edit('1234567890', 'text'));
expectType<Promise<Message<false>>>(messages.fetch('1234567890'));
expectType<Promise<Collection<Snowflake, Message<false>>>>(messages.fetchPinned());
expectType<null>(message.guild);
expectType<null>(message.guildId);
expectType<TextBasedChannel>(message.channel.messages.channel);

expectType<MessageMentions<false>>(message.mentions);
expectType<null>(message.mentions.guild);
expectType<null>(message.mentions.members);
expectType<DMMessageManager>(messages);
expectType<Promise<Message>>(messages.edit('1234567890', 'text'));
expectType<Promise<Message>>(messages.fetch('1234567890'));
expectType<Promise<Collection<Snowflake, Message>>>(messages.fetchPinned());
expectType<Guild | null>(message.guild);
expectType<Snowflake | null>(message.guildId);
expectType<DMChannel | GuildTextBasedChannel>(message.channel.messages.channel);
expectType<MessageMentions>(message.mentions);
expectType<Guild | null>(message.mentions.guild);
expectType<Collection<Snowflake, GuildMember> | null>(message.mentions.members);

if (messages.channel.isDMBased()) {
expectType<DMChannel>(messages.channel);
expectType<DMChannel>(messages.channel.messages.channel);
}

// @ts-expect-error Crossposting is not possible in direct messages.
messages.crosspost('1234567890');
}

declare const threadManager: ThreadManager;
Expand Down

0 comments on commit a48d0ef

Please sign in to comment.