diff --git a/.github/workflows/publish-dev.yml b/.github/workflows/publish-dev.yml index 30b2d34bd481..47f4bd1b7ccb 100644 --- a/.github/workflows/publish-dev.yml +++ b/.github/workflows/publish-dev.yml @@ -17,7 +17,7 @@ jobs: node-version: 16 registry-url: https://registry.npmjs.org/ cache: npm - + - name: pre-release id: pre-release run: | diff --git a/package-lock.json b/package-lock.json index 84b70b45c35c..2e6744f2292d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "discord.js", "version": "13.3.0-dev", "license": "Apache-2.0", "dependencies": { @@ -991,6 +992,14 @@ "npm": ">=7.0.0" } }, + "node_modules/@discordjs/builders/node_modules/discord-api-types": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.24.0.tgz", + "integrity": "sha512-X0uA2a92cRjowUEXpLZIHWl4jiX1NsUpDhcEOpa1/hpO1vkaokgZ8kkPtPih9hHth5UVQ3mHBu/PpB4qjyfJ4A==", + "engines": { + "node": ">=12" + } + }, "node_modules/@discordjs/builders/node_modules/tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -12916,6 +12925,11 @@ "tslib": "^2.3.1" }, "dependencies": { + "discord-api-types": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.24.0.tgz", + "integrity": "sha512-X0uA2a92cRjowUEXpLZIHWl4jiX1NsUpDhcEOpa1/hpO1vkaokgZ8kkPtPih9hHth5UVQ3mHBu/PpB4qjyfJ4A==" + }, "tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", diff --git a/src/managers/ThreadMemberManager.js b/src/managers/ThreadMemberManager.js index deff230d7974..ce6988e5cb2a 100644 --- a/src/managers/ThreadMemberManager.js +++ b/src/managers/ThreadMemberManager.js @@ -92,17 +92,32 @@ class ThreadMemberManager extends CachedManager { return id; } + async _fetchOne(memberId, cache, force) { + if (!force) { + const existing = this.cache.get(memberId); + if (existing) return existing; + } + + const data = await this.client.api.channels(this.thread.id, 'thread-members', memberId).get(); + return this._add(data, cache); + } + + async _fetchMany(cache) { + const raw = await this.client.api.channels(this.thread.id, 'thread-members').get(); + return raw.reduce((col, member) => col.set(member.user_id, this._add(member, cache)), new Collection()); + } + /** * Fetches member(s) for the thread from Discord, requires access to the `GUILD_MEMBERS` gateway intent. - * @param {boolean} [cache=true] Whether or not to cache the fetched members - * @returns {Promise>} + * @param {UserResolvable|boolean} [member] The member to fetch. If `undefined`, all members + * in the thread are fetched, and will be cached based on `options.cache`. If boolean, this serves + * the purpose of `options.cache`. + * @param {BaseFetchOptions} [options] Additional options for this fetch + * @returns {Promise>} */ - async fetch(cache = true) { - const raw = await this.client.api.channels(this.thread.id, 'thread-members').get(); - return raw.reduce((col, rawMember) => { - const member = this._add(rawMember, cache); - return col.set(member.id, member); - }, new Collection()); + fetch(member, { cache = true, force = false } = {}) { + const id = this.resolveId(member); + return id ? this._fetchOne(id, cache, force) : this._fetchMany(member ?? cache); } } diff --git a/typings/index.d.ts b/typings/index.d.ts index 373a55ca0182..a6abbef01477 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -2946,6 +2946,8 @@ export class ThreadMemberManager extends CachedManager); public thread: ThreadChannel; public add(member: UserResolvable | '@me', reason?: string): Promise; + public fetch(member?: UserResolvable, options?: BaseFetchOptions): Promise; + /** @deprecated Use `fetch(member, options)` instead. */ public fetch(cache?: boolean): Promise>; public remove(id: Snowflake | '@me', reason?: string): Promise; } diff --git a/typings/tests.ts b/typings/tests.ts index 2ce3fa4c092b..fe494f5d6708 100644 --- a/typings/tests.ts +++ b/typings/tests.ts @@ -75,6 +75,7 @@ import { TextBasedChannels, TextChannel, ThreadChannel, + ThreadMember, Typing, User, VoiceChannel, @@ -446,10 +447,17 @@ client.on('ready', async () => { // This is to check that stuff is the right type declare const assertIsPromiseMember: (m: Promise) => void; -client.on('guildCreate', g => { +client.on('guildCreate', async g => { const channel = g.channels.cache.random(); if (!channel) return; + if (channel.isThread()) { + const fetchedMember = await channel.members.fetch('12345678'); + assertType(fetchedMember); + const fetchedMemberCol = await channel.members.fetch(true); + assertType>(fetchedMemberCol); + } + channel.setName('foo').then(updatedChannel => { console.log(`New channel name: ${updatedChannel.name}`); });