refactor(ThreadMemberManager): Consistent thread member fetching (#8021)

This commit is contained in:
Jiralite
2022-06-09 19:52:56 +01:00
committed by GitHub
parent f57d6768ad
commit da9107c007
4 changed files with 48 additions and 33 deletions

View File

@@ -111,35 +111,43 @@ class ThreadMemberManager extends CachedManager {
return id;
}
async _fetchOne(memberId, cache, force) {
/**
* @typedef {BaseFetchOptions} FetchThreadMemberOptions
* @property {ThreadMemberResolvable} [member] The thread member to fetch
*/
/**
* @typedef {Object} FetchThreadMembersOptions
* @property {boolean} [cache] Whether to cache the fetched thread members
*/
/**
* Fetches thread member(s) from Discord. Requires the `GUILD_MEMBERS` gateway intent.
* @param {ThreadMemberResolvable|FetchThreadMemberOptions|FetchThreadMembersOptions} [options]
* Options for fetching thread member(s)
* @returns {Promise<ThreadMember|Collection<Snowflake, ThreadMember>>}
*/
fetch(options) {
if (!options) return this._fetchMany();
const { member, cache, force } = options;
const resolvedMember = this.resolveId(member ?? options);
if (resolvedMember) return this._fetchSingle({ member: resolvedMember, cache, force });
return this._fetchMany(options);
}
async _fetchSingle({ member, cache, force = false }) {
if (!force) {
const existing = this.cache.get(memberId);
const existing = this.cache.get(member);
if (existing) return existing;
}
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, memberId));
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id, member));
return this._add(data, cache);
}
async _fetchMany(cache) {
const raw = await this.client.rest.get(Routes.threadMembers(this.thread.id));
return raw.reduce((col, member) => col.set(member.user_id, this._add(member, cache)), new Collection());
}
/**
* @typedef {BaseFetchOptions} ThreadMemberFetchOptions
* @property {UserResolvable} [member] The specific user to fetch from the thread
*/
/**
* Fetches member(s) for the thread from Discord, requires access to the `GUILD_MEMBERS` gateway intent.
* @param {ThreadMemberFetchOptions|boolean} [options] Additional options for this fetch, when a `boolean` is provided
* all members are fetched with `options.cache` set to the boolean value
* @returns {Promise<ThreadMember|Collection<Snowflake, ThreadMember>>}
*/
fetch({ member, cache = true, force = false } = {}) {
const id = this.resolveId(member);
return id ? this._fetchOne(id, cache, force) : this._fetchMany(member ?? cache);
async _fetchMany(options = {}) {
const data = await this.client.rest.get(Routes.threadMembers(this.thread.id));
return data.reduce((col, member) => col.set(member.user_id, this._add(member, options.cache)), new Collection());
}
}

View File

@@ -272,7 +272,7 @@ class ThreadChannel extends Channel {
}
// We cannot fetch a single thread member, as of this commit's date, Discord API responds with 405
const members = await this.members.fetch(cache);
const members = await this.members.fetch({ cache });
return members.get(this.ownerId) ?? null;
}

View File

@@ -3404,8 +3404,8 @@ export class ThreadMemberManager extends CachedManager<Snowflake, ThreadMember,
public thread: AnyThreadChannel;
public get me(): ThreadMember | null;
public add(member: UserResolvable | '@me', reason?: string): Promise<Snowflake>;
public fetch(options?: ThreadMemberFetchOptions): Promise<ThreadMember>;
public fetch(cache?: boolean): Promise<Collection<Snowflake, ThreadMember>>;
public fetch(options?: ThreadMemberResolvable | FetchThreadMemberOptions): Promise<ThreadMember>;
public fetch(options?: FetchThreadMembersOptions): Promise<Collection<Snowflake, ThreadMember>>;
public fetchMe(options?: BaseFetchOptions): Promise<ThreadMember>;
public remove(id: Snowflake | '@me', reason?: string): Promise<Snowflake>;
}
@@ -3748,10 +3748,6 @@ export interface BaseFetchOptions {
force?: boolean;
}
export interface ThreadMemberFetchOptions extends BaseFetchOptions {
member?: UserResolvable;
}
export type BitFieldResolvable<T extends string, N extends number | bigint> =
| RecursiveReadonlyArray<T | N | `${bigint}` | Readonly<BitField<T, N>>>
| T
@@ -4313,6 +4309,14 @@ export interface FetchReactionUsersOptions {
after?: Snowflake;
}
export interface FetchThreadMemberOptions extends BaseFetchOptions {
member: ThreadMemberResolvable;
}
export interface FetchThreadMembersOptions {
cache?: boolean;
}
export interface FetchThreadsOptions {
archived?: FetchArchivedThreadOptions;
active?: boolean;

View File

@@ -127,7 +127,7 @@ import {
UserContextMenuCommandInteraction,
AnyThreadChannel,
} from '.';
import { expectAssignable, expectDeprecated, expectNotAssignable, expectNotType, expectType } from 'tsd';
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
import { UnsafeButtonBuilder, UnsafeEmbedBuilder, UnsafeSelectMenuBuilder } from '@discordjs/builders';
// Test type transformation:
@@ -561,11 +561,14 @@ client.on('guildCreate', async g => {
}
if (channel.isThread()) {
const fetchedMember = await channel.members.fetch({ member: '12345678' });
const fetchedMember = await channel.members.fetch('12345678');
const fetchedMember2 = await channel.members.fetch({ member: '12345678', cache: false, force: true });
expectType<ThreadMember>(fetchedMember);
const fetchedMemberCol = await channel.members.fetch(true);
expectDeprecated(await channel.members.fetch(true));
expectType<ThreadMember>(fetchedMember2);
const fetchedMemberCol = await channel.members.fetch({ cache: true });
expectType<Collection<Snowflake, ThreadMember>>(fetchedMemberCol);
// @ts-expect-error The `force` option cannot be used alongside fetching all thread members.
const fetchedMemberCol2 = await channel.members.fetch({ cache: true, force: false });
}
channel.setName('foo').then(updatedChannel => {