From c4325911130f30072246dd1b2e381c91293b3e6a Mon Sep 17 00:00:00 2001 From: Kyra Date: Sat, 9 Feb 2019 16:07:31 +0100 Subject: [PATCH] feat(RoleStore, ChannelStore): `fetch()` method (#3071) * feat({Role,Channel}Store): fetch method * docs: Add usage examples to the new methods * misc: Add note of why we are fetching all roles even for a single one --- src/stores/ChannelStore.js | 18 ++++++++++++++++++ src/stores/RoleStore.js | 28 ++++++++++++++++++++++++++++ typings/index.d.ts | 3 +++ 3 files changed, 49 insertions(+) diff --git a/src/stores/ChannelStore.js b/src/stores/ChannelStore.js index 8d491c837..9ce6465cf 100644 --- a/src/stores/ChannelStore.js +++ b/src/stores/ChannelStore.js @@ -74,6 +74,24 @@ class ChannelStore extends DataStore { super.remove(id); } + /** + * Obtains a channel from Discord, or the channel cache if it's already available. + * @param {Snowflake} id ID of the channel + * @param {boolean} [cache=true] Whether to cache the new channel object if it isn't already + * @returns {Promise} + * @example + * // Fetch a channel by its id + * client.channels.fetch('222109930545610754') + * .then(channel => console.log(channel.name)) + * .catch(console.error); + */ + fetch(id, cache = true) { + const existing = this.get(id); + if (existing) return Promise.resolve(existing); + + return this.client.api.channels(id).get().then(data => this.add(data, null, cache)); + } + /** * Data that can be resolved to give a Channel object. This can be: * * A Channel object diff --git a/src/stores/RoleStore.js b/src/stores/RoleStore.js index 14956c309..6f97d2770 100644 --- a/src/stores/RoleStore.js +++ b/src/stores/RoleStore.js @@ -19,6 +19,34 @@ class RoleStore extends DataStore { return super.add(data, cache, { extras: [this.guild] }); } + /** + * Obtains one or more roles from Discord, or the role cache if they're already available. + * @param {Snowflake} [id] ID or IDs of the role(s) + * @param {boolean} [cache=true] Whether to cache the new roles objects if it weren't already + * @returns {Promise} + * @example + * // Fetch all roles from the guild + * message.guild.roles.fetch() + * .then(roles => console.log(`There are ${roles.size} roles.`)) + * .catch(console.error); + * @example + * // Fetch a single role + * message.guild.roles.fetch('222078108977594368') + * .then(role => console.log(`The role color is: ${role.color}`)) + * .catch(console.error); + */ + async fetch(id, cache = true) { + if (id) { + const existing = this.get(id); + if (existing) return existing; + } + + // We cannot fetch a single role, as of this commit's date, Discord API throws with 405 + const roles = await this.client.api.guilds(this.guild.id).roles.get(); + for (const role of roles) this.add(role, cache); + return id ? this.get(id) || null : this; + } + /** * Data that can be resolved to a Role object. This can be: * * A Role diff --git a/typings/index.d.ts b/typings/index.d.ts index 56f941075..60a19f3db 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1320,6 +1320,7 @@ declare module 'discord.js' { export class ChannelStore extends DataStore { constructor(client: Client, iterable: Iterable, options?: { lru: boolean }); constructor(client: Client, options?: { lru: boolean }); + public fetch(id: Snowflake, cache?: boolean): Promise; } export class DataStore, R = any> extends Collection { @@ -1410,6 +1411,8 @@ declare module 'discord.js' { public readonly highest: Role; public create(options?: { data?: RoleData, reason?: string }): Promise; + public fetch(id?: Snowflake, cache?: boolean): Promise; + public fetch(id: Snowflake, cache?: boolean): Promise; } export class UserStore extends DataStore {