Skip to content

Commit da9107c

Browse files
authored
refactor(ThreadMemberManager): Consistent thread member fetching (#8021)
1 parent f57d676 commit da9107c

File tree

4 files changed

+48
-33
lines changed

4 files changed

+48
-33
lines changed

packages/discord.js/src/managers/ThreadMemberManager.js

+30-22
Original file line numberDiff line numberDiff line change
@@ -111,35 +111,43 @@ class ThreadMemberManager extends CachedManager {
111111
return id;
112112
}
113113

114-
async _fetchOne(memberId, cache, force) {
115-
if (!force) {
116-
const existing = this.cache.get(memberId);
117-
if (existing) return existing;
118-
}
119-
120-
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, memberId));
121-
return this._add(data, cache);
122-
}
123-
124-
async _fetchMany(cache) {
125-
const raw = await this.client.rest.get(Routes.threadMembers(this.thread.id));
126-
return raw.reduce((col, member) => col.set(member.user_id, this._add(member, cache)), new Collection());
127-
}
114+
/**
115+
* @typedef {BaseFetchOptions} FetchThreadMemberOptions
116+
* @property {ThreadMemberResolvable} [member] The thread member to fetch
117+
*/
128118

129119
/**
130-
* @typedef {BaseFetchOptions} ThreadMemberFetchOptions
131-
* @property {UserResolvable} [member] The specific user to fetch from the thread
120+
* @typedef {Object} FetchThreadMembersOptions
121+
* @property {boolean} [cache] Whether to cache the fetched thread members
132122
*/
133123

134124
/**
135-
* Fetches member(s) for the thread from Discord, requires access to the `GUILD_MEMBERS` gateway intent.
136-
* @param {ThreadMemberFetchOptions|boolean} [options] Additional options for this fetch, when a `boolean` is provided
137-
* all members are fetched with `options.cache` set to the boolean value
125+
* Fetches thread member(s) from Discord. Requires the `GUILD_MEMBERS` gateway intent.
126+
* @param {ThreadMemberResolvable|FetchThreadMemberOptions|FetchThreadMembersOptions} [options]
127+
* Options for fetching thread member(s)
138128
* @returns {Promise<ThreadMember|Collection<Snowflake, ThreadMember>>}
139129
*/
140-
fetch({ member, cache = true, force = false } = {}) {
141-
const id = this.resolveId(member);
142-
return id ? this._fetchOne(id, cache, force) : this._fetchMany(member ?? cache);
130+
fetch(options) {
131+
if (!options) return this._fetchMany();
132+
const { member, cache, force } = options;
133+
const resolvedMember = this.resolveId(member ?? options);
134+
if (resolvedMember) return this._fetchSingle({ member: resolvedMember, cache, force });
135+
return this._fetchMany(options);
136+
}
137+
138+
async _fetchSingle({ member, cache, force = false }) {
139+
if (!force) {
140+
const existing = this.cache.get(member);
141+
if (existing) return existing;
142+
}
143+
144+
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member));
145+
return this._add(data, cache);
146+
}
147+
148+
async _fetchMany(options = {}) {
149+
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id));
150+
return data.reduce((col, member) => col.set(member.user_id, this._add(member, options.cache)), new Collection());
143151
}
144152
}
145153

packages/discord.js/src/structures/ThreadChannel.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class ThreadChannel extends Channel {
272272
}
273273

274274
// We cannot fetch a single thread member, as of this commit's date, Discord API responds with 405
275-
const members = await this.members.fetch(cache);
275+
const members = await this.members.fetch({ cache });
276276
return members.get(this.ownerId) ?? null;
277277
}
278278

packages/discord.js/typings/index.d.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -3404,8 +3404,8 @@ export class ThreadMemberManager extends CachedManager<Snowflake, ThreadMember,
34043404
public thread: AnyThreadChannel;
34053405
public get me(): ThreadMember | null;
34063406
public add(member: UserResolvable | '@me', reason?: string): Promise<Snowflake>;
3407-
public fetch(options?: ThreadMemberFetchOptions): Promise<ThreadMember>;
3408-
public fetch(cache?: boolean): Promise<Collection<Snowflake, ThreadMember>>;
3407+
public fetch(options?: ThreadMemberResolvable | FetchThreadMemberOptions): Promise<ThreadMember>;
3408+
public fetch(options?: FetchThreadMembersOptions): Promise<Collection<Snowflake, ThreadMember>>;
34093409
public fetchMe(options?: BaseFetchOptions): Promise<ThreadMember>;
34103410
public remove(id: Snowflake | '@me', reason?: string): Promise<Snowflake>;
34113411
}
@@ -3748,10 +3748,6 @@ export interface BaseFetchOptions {
37483748
force?: boolean;
37493749
}
37503750

3751-
export interface ThreadMemberFetchOptions extends BaseFetchOptions {
3752-
member?: UserResolvable;
3753-
}
3754-
37553751
export type BitFieldResolvable<T extends string, N extends number | bigint> =
37563752
| RecursiveReadonlyArray<T | N | `${bigint}` | Readonly<BitField<T, N>>>
37573753
| T
@@ -4313,6 +4309,14 @@ export interface FetchReactionUsersOptions {
43134309
after?: Snowflake;
43144310
}
43154311

4312+
export interface FetchThreadMemberOptions extends BaseFetchOptions {
4313+
member: ThreadMemberResolvable;
4314+
}
4315+
4316+
export interface FetchThreadMembersOptions {
4317+
cache?: boolean;
4318+
}
4319+
43164320
export interface FetchThreadsOptions {
43174321
archived?: FetchArchivedThreadOptions;
43184322
active?: boolean;

packages/discord.js/typings/index.test-d.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ import {
127127
UserContextMenuCommandInteraction,
128128
AnyThreadChannel,
129129
} from '.';
130-
import { expectAssignable, expectDeprecated, expectNotAssignable, expectNotType, expectType } from 'tsd';
130+
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
131131
import { UnsafeButtonBuilder, UnsafeEmbedBuilder, UnsafeSelectMenuBuilder } from '@discordjs/builders';
132132

133133
// Test type transformation:
@@ -561,11 +561,14 @@ client.on('guildCreate', async g => {
561561
}
562562

563563
if (channel.isThread()) {
564-
const fetchedMember = await channel.members.fetch({ member: '12345678' });
564+
const fetchedMember = await channel.members.fetch('12345678');
565+
const fetchedMember2 = await channel.members.fetch({ member: '12345678', cache: false, force: true });
565566
expectType<ThreadMember>(fetchedMember);
566-
const fetchedMemberCol = await channel.members.fetch(true);
567-
expectDeprecated(await channel.members.fetch(true));
567+
expectType<ThreadMember>(fetchedMember2);
568+
const fetchedMemberCol = await channel.members.fetch({ cache: true });
568569
expectType<Collection<Snowflake, ThreadMember>>(fetchedMemberCol);
570+
// @ts-expect-error The `force` option cannot be used alongside fetching all thread members.
571+
const fetchedMemberCol2 = await channel.members.fetch({ cache: true, force: false });
569572
}
570573

571574
channel.setName('foo').then(updatedChannel => {

0 commit comments

Comments
 (0)