Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types(MessageManager): Allow comparison of messages again #9612

Merged
merged 10 commits into from
Jul 7, 2023
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