mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 19:13:31 +01:00
fix(ThreadManager): add members and conditionally include hasMore (#9164)
* fix(ThreadManager): conditionally include `hasMore` * types: fix tests --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -451,7 +451,14 @@ class GuildChannelManager extends CachedManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains all active thread channels in the guild from Discord
|
* Data returned from fetching threads.
|
||||||
|
* @typedef {Object} FetchedThreads
|
||||||
|
* @property {Collection<Snowflake, ThreadChannel>} threads The threads that were fetched
|
||||||
|
* @property {Collection<Snowflake, ThreadMember>} members The thread members in the received threads
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains all active thread channels in the guild.
|
||||||
* @param {boolean} [cache=true] Whether to cache the fetched data
|
* @param {boolean} [cache=true] Whether to cache the fetched data
|
||||||
* @returns {Promise<FetchedThreads>}
|
* @returns {Promise<FetchedThreads>}
|
||||||
* @example
|
* @example
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ class ThreadManager extends CachedManager {
|
|||||||
* ThreadChannelResolvable then the specified thread will be fetched. Fetches all active threads if `undefined`
|
* ThreadChannelResolvable then the specified thread will be fetched. Fetches all active threads if `undefined`
|
||||||
* @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch. <warn>The `force` field gets ignored
|
* @param {BaseFetchOptions} [cacheOptions] Additional options for this fetch. <warn>The `force` field gets ignored
|
||||||
* if `options` is not a {@link ThreadChannelResolvable}</warn>
|
* if `options` is not a {@link ThreadChannelResolvable}</warn>
|
||||||
* @returns {Promise<?(ThreadChannel|FetchedThreads)>}
|
* @returns {Promise<?(ThreadChannel|FetchedThreads|FetchedThreadsMore)>}
|
||||||
|
* {@link FetchedThreads} if active & {@link FetchedThreadsMore} if archived.
|
||||||
* @example
|
* @example
|
||||||
* // Fetch a thread by its id
|
* // Fetch a thread by its id
|
||||||
* channel.threads.fetch('831955138126104859')
|
* channel.threads.fetch('831955138126104859')
|
||||||
@@ -124,9 +125,8 @@ class ThreadManager extends CachedManager {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data returned from a thread fetch that returns multiple threads.
|
* Data returned from fetching multiple threads.
|
||||||
* @typedef {Object} FetchedThreads
|
* @typedef {FetchedThreads} FetchedThreadsMore
|
||||||
* @property {Collection<Snowflake, ThreadChannel>} threads The threads that were fetched, with any members returned
|
|
||||||
* @property {?boolean} hasMore Whether there are potentially additional threads that require a subsequent call
|
* @property {?boolean} hasMore Whether there are potentially additional threads that require a subsequent call
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ class ThreadManager extends CachedManager {
|
|||||||
* in the parent channel.</info>
|
* in the parent channel.</info>
|
||||||
* @param {FetchArchivedThreadOptions} [options] The options to fetch archived threads
|
* @param {FetchArchivedThreadOptions} [options] The options to fetch archived threads
|
||||||
* @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
|
* @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
|
||||||
* @returns {Promise<FetchedThreads>}
|
* @returns {Promise<FetchedThreadsMore>}
|
||||||
*/
|
*/
|
||||||
async fetchArchived({ type = 'public', fetchAll = false, before, limit } = {}, cache = true) {
|
async fetchArchived({ type = 'public', fetchAll = false, before, limit } = {}, cache = true) {
|
||||||
let path = Routes.channelThreads(this.channel.id, type);
|
let path = Routes.channelThreads(this.channel.id, type);
|
||||||
@@ -171,15 +171,13 @@ class ThreadManager extends CachedManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the accessible active threads from Discord.
|
* Obtains all active thread channels in the guild.
|
||||||
* <info>This method requires the {@link PermissionFlagsBits.ReadMessageHistory} permission
|
* This internally calls {@link GuildChannelManager#fetchActiveThreads}.
|
||||||
* in the parent channel.</info>
|
* @param {boolean} [cache=true] Whether to cache the fetched data
|
||||||
* @param {boolean} [cache=true] Whether to cache the new thread objects if they aren't already
|
|
||||||
* @returns {Promise<FetchedThreads>}
|
* @returns {Promise<FetchedThreads>}
|
||||||
*/
|
*/
|
||||||
async fetchActive(cache = true) {
|
fetchActive(cache = true) {
|
||||||
const raw = await this.client.rest.get(Routes.guildActiveThreads(this.channel.guild.id));
|
return this.channel.guild.channels.fetchActiveThreads(cache);
|
||||||
return this.constructor._mapThreads(raw, this.client, { parent: this.channel, cache });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static _mapThreads(rawThreads, client, { parent, guild, cache }) {
|
static _mapThreads(rawThreads, client, { parent, guild, cache }) {
|
||||||
@@ -188,12 +186,18 @@ class ThreadManager extends CachedManager {
|
|||||||
if (parent && thread.parentId !== parent.id) return coll;
|
if (parent && thread.parentId !== parent.id) return coll;
|
||||||
return coll.set(thread.id, thread);
|
return coll.set(thread.id, thread);
|
||||||
}, new Collection());
|
}, new Collection());
|
||||||
|
|
||||||
// Discord sends the thread id as id in this object
|
// Discord sends the thread id as id in this object
|
||||||
for (const rawMember of rawThreads.members) client.channels.cache.get(rawMember.id)?.members._add(rawMember);
|
const threadMembers = rawThreads.members.reduce(
|
||||||
return {
|
(coll, raw) => coll.set(raw.user_id, threads.get(raw.id).members._add(raw)),
|
||||||
threads,
|
new Collection(),
|
||||||
hasMore: rawThreads.has_more ?? false,
|
);
|
||||||
};
|
|
||||||
|
const response = { threads, members: threadMembers };
|
||||||
|
|
||||||
|
// The GET `/guilds/{guild.id}/threads/active` route does not return `has_more`.
|
||||||
|
if ('has_more' in rawThreads) response.hasMore = rawThreads.has_more;
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
packages/discord.js/typings/index.d.ts
vendored
12
packages/discord.js/typings/index.d.ts
vendored
@@ -4109,8 +4109,12 @@ export class ThreadManager<Forum extends boolean = boolean> extends CachedManage
|
|||||||
protected constructor(channel: TextChannel | NewsChannel | ForumChannel, iterable?: Iterable<RawThreadChannelData>);
|
protected constructor(channel: TextChannel | NewsChannel | ForumChannel, iterable?: Iterable<RawThreadChannelData>);
|
||||||
public channel: If<Forum, ForumChannel, TextChannel | NewsChannel>;
|
public channel: If<Forum, ForumChannel, TextChannel | NewsChannel>;
|
||||||
public fetch(options: ThreadChannelResolvable, cacheOptions?: BaseFetchOptions): Promise<AnyThreadChannel | null>;
|
public fetch(options: ThreadChannelResolvable, cacheOptions?: BaseFetchOptions): Promise<AnyThreadChannel | null>;
|
||||||
|
public fetch(
|
||||||
|
options: FetchThreadsOptions & { archived: FetchArchivedThreadOptions },
|
||||||
|
cacheOptions?: { cache?: boolean },
|
||||||
|
): Promise<FetchedThreadsMore>;
|
||||||
public fetch(options?: FetchThreadsOptions, cacheOptions?: { cache?: boolean }): Promise<FetchedThreads>;
|
public fetch(options?: FetchThreadsOptions, cacheOptions?: { cache?: boolean }): Promise<FetchedThreads>;
|
||||||
public fetchArchived(options?: FetchArchivedThreadOptions, cache?: boolean): Promise<FetchedThreads>;
|
public fetchArchived(options?: FetchArchivedThreadOptions, cache?: boolean): Promise<FetchedThreadsMore>;
|
||||||
public fetchActive(cache?: boolean): Promise<FetchedThreads>;
|
public fetchActive(cache?: boolean): Promise<FetchedThreads>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5148,7 +5152,11 @@ export interface FetchChannelOptions extends BaseFetchOptions {
|
|||||||
|
|
||||||
export interface FetchedThreads {
|
export interface FetchedThreads {
|
||||||
threads: Collection<Snowflake, AnyThreadChannel>;
|
threads: Collection<Snowflake, AnyThreadChannel>;
|
||||||
hasMore?: boolean;
|
members: Collection<Snowflake, ThreadMember>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FetchedThreadsMore extends FetchedThreads {
|
||||||
|
hasMore: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FetchGuildOptions extends BaseFetchOptions {
|
export interface FetchGuildOptions extends BaseFetchOptions {
|
||||||
|
|||||||
@@ -160,6 +160,9 @@ import {
|
|||||||
PublicThreadChannel,
|
PublicThreadChannel,
|
||||||
GuildMemberManager,
|
GuildMemberManager,
|
||||||
GuildMemberFlagsBitField,
|
GuildMemberFlagsBitField,
|
||||||
|
ThreadManager,
|
||||||
|
FetchedThreads,
|
||||||
|
FetchedThreadsMore,
|
||||||
} from '.';
|
} from '.';
|
||||||
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
|
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
|
||||||
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
||||||
@@ -1479,6 +1482,18 @@ declare const guildChannelManager: GuildChannelManager;
|
|||||||
expectType<null>(message.mentions.members);
|
expectType<null>(message.mentions.members);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare const threadManager: ThreadManager;
|
||||||
|
{
|
||||||
|
expectType<Promise<AnyThreadChannel | null>>(threadManager.fetch('12345678901234567'));
|
||||||
|
expectType<Promise<AnyThreadChannel | null>>(threadManager.fetch('12345678901234567', { cache: true, force: false }));
|
||||||
|
expectType<Promise<FetchedThreads>>(threadManager.fetch());
|
||||||
|
expectType<Promise<FetchedThreads>>(threadManager.fetch({}));
|
||||||
|
expectType<Promise<FetchedThreadsMore>>(threadManager.fetch({ archived: { limit: 4 } }));
|
||||||
|
|
||||||
|
// @ts-expect-error The force option has no effect here.
|
||||||
|
threadManager.fetch({ archived: {} }, { force: true });
|
||||||
|
}
|
||||||
|
|
||||||
declare const guildForumThreadManager: GuildForumThreadManager;
|
declare const guildForumThreadManager: GuildForumThreadManager;
|
||||||
expectType<ForumChannel>(guildForumThreadManager.channel);
|
expectType<ForumChannel>(guildForumThreadManager.channel);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user