From ed777ff265c8abc06f097a09b1b47c0b48041f0b Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 20 Jun 2021 16:35:20 +0200 Subject: [PATCH 01/34] =?UTF-8?q?feat(Managers):=20=E2=9C=A8=20Add=20Guild?= =?UTF-8?q?InviteManager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The InviteManager was missing, this new Manager comes with some extra features - Invites generation from Guild based on the first accessible channel - Invite deletion outside of an Invite instance - Fetch a single invite with cache filling to avoid unnecessary future requests (force option is available) --- src/client/actions/InviteCreate.js | 4 +- src/client/actions/InviteDelete.js | 1 + src/errors/Messages.js | 6 + src/managers/GuildInviteManager.js | 179 +++++++++++++++++++++++++++++ typings/index.d.ts | 19 +++ 5 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 src/managers/GuildInviteManager.js diff --git a/src/client/actions/InviteCreate.js b/src/client/actions/InviteCreate.js index 34cfa8455072..6aee0b95db6d 100644 --- a/src/client/actions/InviteCreate.js +++ b/src/client/actions/InviteCreate.js @@ -1,7 +1,6 @@ 'use strict'; const Action = require('./Action'); -const Invite = require('../../structures/Invite'); const { Events } = require('../../util/Constants'); class InviteCreateAction extends Action { @@ -12,7 +11,8 @@ class InviteCreateAction extends Action { if (!channel) return false; const inviteData = Object.assign(data, { channel, guild }); - const invite = new Invite(client, inviteData); + const invite = guild.invites.add(inviteData); + /** * Emitted when an invite is created. * This event only triggers if the client has `MANAGE_GUILD` permissions for the guild, diff --git a/src/client/actions/InviteDelete.js b/src/client/actions/InviteDelete.js index 96e22aa03275..c6c039ca36f3 100644 --- a/src/client/actions/InviteDelete.js +++ b/src/client/actions/InviteDelete.js @@ -13,6 +13,7 @@ class InviteDeleteAction extends Action { const inviteData = Object.assign(data, { channel, guild }); const invite = new Invite(client, inviteData); + guild.invites.cache.delete(invite.code); /** * Emitted when an invite is deleted. diff --git a/src/errors/Messages.js b/src/errors/Messages.js index c9d7983fea8a..279c87dfc6ac 100644 --- a/src/errors/Messages.js +++ b/src/errors/Messages.js @@ -81,6 +81,8 @@ const Messages = { PRUNE_DAYS_TYPE: 'Days must be a number', + GUILD_CHANNEL_INVITE: 'Could not find a available channel to create a invite.', + GUILD_CHANNEL_RESOLVE: 'Could not resolve channel to a guild channel.', GUILD_VOICE_CHANNEL_RESOLVE: 'Could not resolve channel to a guild voice channel.', GUILD_CHANNEL_ORPHAN: 'Could not find a parent to this guild channel.', @@ -105,6 +107,10 @@ const Messages = { VANITY_URL: 'This guild does not have the VANITY_URL feature enabled.', + INVITE_RESOLVE_CODE: `Couldn't resolve the code to fetch the invite.`, + + UNKNOWN_INVITE: `Unknown invite.`, + DELETE_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot delete them", FETCH_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot fetch them", diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js new file mode 100644 index 000000000000..dfe9ebd9f155 --- /dev/null +++ b/src/managers/GuildInviteManager.js @@ -0,0 +1,179 @@ +'use strict'; + +const BaseManager = require('./BaseManager'); +const { Error } = require('../errors'); +const GuildChannel = require('../structures/GuildChannel'); +const Invite = require('../structures/Invite'); +const Collection = require('../util/Collection'); +const DataResolver = require('../util/DataResolver'); + +/** + * Manages API methods for GuildInvites and stores their cache. + * @extends {BaseManager} + */ +class GuildInviteManager extends BaseManager { + constructor(guild, iterable) { + super(guild.client, iterable, Invite); + + /** + * The guild this Manager belongs to + * @type {Guild} + */ + this.guild = guild; + } + + /** + * The cache of this Manager + * @type {Collection} + * @name GuildInviteManager#cache + */ + + add(data, cache) { + return super.add(data, cache, { id: data.code, extras: [this.guild] }); + } + + /** + * Data that resolves to give a Invite object. This can be: + * * An invite code + * * An invite URL + * @typedef {string} InviteResolvable + */ + + /** + * Resolves a InviteResolvable to a Invite object. + * @method resolve + * @memberof GuildInviteManager + * @instance + * @param {InviteResolvable} invite The invite resolvable to resolve + * @returns {?Invite} + */ + + /** + * Resolves a InviteResolvable to a invite code string. + * @method resolveID + * @memberof GuildInviteManager + * @instance + * @param {InviteResolvable} invite The invite resolvable to resolve + * @returns {?string} + */ + + /** + * Options used to fetch a single invite from a guild. + * @typedef {Object} FetchInviteOptions + * @property {InviteResolvable} code The invite to fetch + * @property {boolean} [cache=true] Whether or not to cache the fetched invite + * @property {boolean} [force=false] Whether to skip the cache check and request the API + */ + + /** + * Options used to fetch all invites from a guild. + * @typedef {Object} FetchInvitesOptions + * @property {boolean} cache Whether or not to cache the fetched invites + */ + + /** + * Fetches invite(s) from Discord. + * @param {InviteResolvable|FetchInviteOptions|FetchInvitesOptions} [options] Options for fetching guild invite(s) + * @returns {Promise|Promise>} + * @example + * // Fetch all invites from a guild + * guild.invites.fetch() + * .then(console.log) + * .catch(console.error); + * @example + * // Fetch all invites from a guild without caching + * guild.invites.fetch({ cache: false }) + * .then(console.log) + * .catch(console.error); + * @example + * // Fetch a single invite + * guild.invites.fetch('DrzKVU3') + * .then(console.log) + * .catch(console.error); + * @example + * // Fetch a single invite without checking cache + * guild.invites.fetch({ code: 'DrzKVU3', force: true }) + * .then(console.log) + * .catch(console.error) + * @example + * // Fetch a single invite without caching + * guild.invites.fetch({ code: 'DrzKVU3', cache: false }) + * .then(console.log) + * .catch(console.error); + */ + fetch(options) { + if (!options) return this._fetchMany(); + const code = DataResolver.resolveInviteCode(options); + if (code) return this._fetchSingle({ code, cache: true }); + if (options.code) { + options.code = DataResolver.resolveInviteCode(options); + } + if (!options.code) { + if ('cache' in options) return this._fetchMany(options.cache); + return Promise.reject(new Error('INVITE_RESOLVE_CODE')); + } + return this._fetchSingle(options); + } + + async _fetchSingle({ code, cache, force = false }) { + if (!force) { + const existing = this.cache.get(code); + if (existing) return existing; + } + + const invites = await this._fetchMany(cache); + const invite = invites.get(code); + if (!invite) throw new Error('UNKNOWN_INVITE'); + return invite; + } + + async _fetchMany(cache) { + const data = await this.client.api.guilds(this.guild.id).invites.get(); + return data.reduce((col, invite) => col.set(invite.code, this.add(invite, cache)), new Collection()); + } + + /** + * Create a invite to the guild from a random channel. + * @param {CreateInviteOptions|ChannelResolvable} [options=null] The options for creating the invite + * @param {ChannelResolvable} [channel=null] The options for creating the invite + * @returns {Promise} + * @example + * // Create an invite to a random allowed channel + * guild.invites.create() + * .then(invite => console.log(`Created an invite with a code of ${invite.code} from ${invite.channel}`)) + * .catch(console.error); + * @example + * // Create an invite to a selected channel + * guild.invites.create('599942732013764608') + * .then(console.log) + * .catch(console.error); + */ + create(options = null, channel = null) { + if (!channel && (options instanceof GuildChannel || typeof options === 'string')) { + channel = options; + options = null; + } + if (!channel) { + channel = this.guild.channels.cache.find(c => c.permissionsFor(this.guild.me).has('CREATE_INSTANT_INVITE')); + if (!channel) throw new Error('GUILD_CHANNEL_INVITE'); + } + + channel = this.guild.channels.resolve(channel); + if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE'); + + return channel.createInvite(options); + } + + /** + * Deletes a invite. + * @param {InviteResolvable} invite The invite to delete + * @param {string} [reason] Reason for deleting the invite + * @returns {Promise} + */ + delete(invite, reason) { + const code = DataResolver.resolveInviteCode(invite); + return this.client.api.invites[code].delete({ reason }).then(() => this); + } +} + +module.exports = GuildInviteManager; diff --git a/typings/index.d.ts b/typings/index.d.ts index a7bfef6c343c..969fab800105 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -795,6 +795,7 @@ declare module 'discord.js' { public approximatePresenceCount: number | null; public available: boolean; public bans: GuildBanManager; + public invites: GuildInvitesManager; public channels: GuildChannelManager; public commands: GuildApplicationCommandManager; public defaultMessageNotifications: DefaultMessageNotificationLevel | number; @@ -2340,6 +2341,16 @@ declare module 'discord.js' { public remove(user: UserResolvable, reason?: string): Promise; } + export class GuildInvitesManager extends BaseManager { + constructor(guild: Guild, iterable?: Iterable); + public guild: Guild; + public create(options?: InviteOptions, channel?: ChannelResolvable): Promise; + public create(channel?: ChannelResolvable): Promise; + public fetch(options: InviteResolvable | FetchInviteOptions): Promise; + public fetch(options?: FetchInvitesOptions): Promise>; + public delete(invite: InviteResolvable, reason?: string): Promise; + } + export class GuildMemberRoleManager { constructor(member: GuildMember); public readonly cache: Collection; @@ -3015,6 +3026,14 @@ declare module 'discord.js' { cache: boolean; } + interface FetchInviteOptions extends BaseFetchOptions { + code: string; + } + + interface FetchInvitesOptions { + cache: boolean; + } + interface FetchGuildOptions extends BaseFetchOptions { guild: GuildResolvable; } From 9f6f82ea9edcf2deb2e4d3325b937cf233f2161e Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 20 Jun 2021 16:45:46 +0200 Subject: [PATCH 02/34] types(GuildInviteManager) Fix pluralization of class name in typings Co-authored-by: iShibi --- typings/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index 969fab800105..6f2c6581438e 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -795,7 +795,7 @@ declare module 'discord.js' { public approximatePresenceCount: number | null; public available: boolean; public bans: GuildBanManager; - public invites: GuildInvitesManager; + public invites: GuildInviteManager; public channels: GuildChannelManager; public commands: GuildApplicationCommandManager; public defaultMessageNotifications: DefaultMessageNotificationLevel | number; @@ -2341,7 +2341,7 @@ declare module 'discord.js' { public remove(user: UserResolvable, reason?: string): Promise; } - export class GuildInvitesManager extends BaseManager { + export class GuildInviteManager extends BaseManager { constructor(guild: Guild, iterable?: Iterable); public guild: Guild; public create(options?: InviteOptions, channel?: ChannelResolvable): Promise; From c576e4baaafad9024010ad35c78f39580025dd65 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 20 Jun 2021 18:03:28 +0200 Subject: [PATCH 03/34] =?UTF-8?q?refactor:=20=F0=9F=92=AC=20Adds=20literar?= =?UTF-8?q?y=20corrections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correction of docs and errors messages Co-authored-by: Vlad Frangu --- src/errors/Messages.js | 2 +- src/managers/GuildInviteManager.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/errors/Messages.js b/src/errors/Messages.js index 279c87dfc6ac..ca6b422398cb 100644 --- a/src/errors/Messages.js +++ b/src/errors/Messages.js @@ -81,7 +81,7 @@ const Messages = { PRUNE_DAYS_TYPE: 'Days must be a number', - GUILD_CHANNEL_INVITE: 'Could not find a available channel to create a invite.', + GUILD_CHANNEL_INVITE: 'Could not find an available channel to create an invite.', GUILD_CHANNEL_RESOLVE: 'Could not resolve channel to a guild channel.', GUILD_VOICE_CHANNEL_RESOLVE: 'Could not resolve channel to a guild voice channel.', diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index dfe9ebd9f155..b7eb1565628b 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -133,7 +133,7 @@ class GuildInviteManager extends BaseManager { } /** - * Create a invite to the guild from a random channel. + * Create a invite to the guild from the first available channel. * @param {CreateInviteOptions|ChannelResolvable} [options=null] The options for creating the invite * @param {ChannelResolvable} [channel=null] The options for creating the invite * @returns {Promise} From f97bcc5d49676f7dbc9bbf1760edf6cdd5a74ef4 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 20 Jun 2021 18:15:46 +0200 Subject: [PATCH 04/34] =?UTF-8?q?refactor:=20=F0=9F=A5=85=20Transform=20sy?= =?UTF-8?q?nc=20errors=20to=20Promise=20rejections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vlad Frangu --- src/managers/GuildInviteManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index b7eb1565628b..ee195ed1d59e 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -155,11 +155,11 @@ class GuildInviteManager extends BaseManager { } if (!channel) { channel = this.guild.channels.cache.find(c => c.permissionsFor(this.guild.me).has('CREATE_INSTANT_INVITE')); - if (!channel) throw new Error('GUILD_CHANNEL_INVITE'); + if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_INVITE')); } channel = this.guild.channels.resolve(channel); - if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE'); + if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); return channel.createInvite(options); } From 921c81faa88ce62b4a12d5d62c748c5c2d51673c Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 20 Jun 2021 18:19:36 +0200 Subject: [PATCH 05/34] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Remove=20mutating?= =?UTF-8?q?=20in=20case=20of=20options=20is=20a=20frozen=20object?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vlad Frangu --- src/managers/GuildInviteManager.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index ee195ed1d59e..ed205b299257 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -105,14 +105,14 @@ class GuildInviteManager extends BaseManager { if (!options) return this._fetchMany(); const code = DataResolver.resolveInviteCode(options); if (code) return this._fetchSingle({ code, cache: true }); - if (options.code) { - options.code = DataResolver.resolveInviteCode(options); - } if (!options.code) { if ('cache' in options) return this._fetchMany(options.cache); return Promise.reject(new Error('INVITE_RESOLVE_CODE')); } - return this._fetchSingle(options); + return this._fetchSingle({ + ...options, + code: DataResolver.resolveInviteCode(options.code), + }); } async _fetchSingle({ code, cache, force = false }) { From 8bfd39a2d22fac33f428c8d326b0897080d856e9 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 20 Jun 2021 18:24:15 +0200 Subject: [PATCH 06/34] =?UTF-8?q?types:=20=F0=9F=8F=B7=EF=B8=8F=20Replace?= =?UTF-8?q?=20InviteOptions=20with=20CreateInviteOptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: iShibi --- typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index 6f2c6581438e..b1edb58bcb49 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -2344,7 +2344,7 @@ declare module 'discord.js' { export class GuildInviteManager extends BaseManager { constructor(guild: Guild, iterable?: Iterable); public guild: Guild; - public create(options?: InviteOptions, channel?: ChannelResolvable): Promise; + public create(options?: CreateInviteOptions, channel?: ChannelResolvable): Promise; public create(channel?: ChannelResolvable): Promise; public fetch(options: InviteResolvable | FetchInviteOptions): Promise; public fetch(options?: FetchInvitesOptions): Promise>; From 3bc3be9a629f629a495cc58f56e278a44d9cbd25 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 20 Jun 2021 18:46:53 +0200 Subject: [PATCH 07/34] =?UTF-8?q?refactor(Errors):=20=F0=9F=A5=85=20Change?= =?UTF-8?q?=20"unknown=20invite"=20error=20to=20avoid=20confusion=20with?= =?UTF-8?q?=20APIErrors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: iShibi --- src/errors/Messages.js | 2 +- src/managers/GuildInviteManager.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/errors/Messages.js b/src/errors/Messages.js index ca6b422398cb..ee71428d8ab4 100644 --- a/src/errors/Messages.js +++ b/src/errors/Messages.js @@ -109,7 +109,7 @@ const Messages = { INVITE_RESOLVE_CODE: `Couldn't resolve the code to fetch the invite.`, - UNKNOWN_INVITE: `Unknown invite.`, + INVITE_NOT_FOUND: `Could not find the requested invite.`, DELETE_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot delete them", FETCH_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot fetch them", diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index ed205b299257..5f1559b1b5f2 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -123,7 +123,7 @@ class GuildInviteManager extends BaseManager { const invites = await this._fetchMany(cache); const invite = invites.get(code); - if (!invite) throw new Error('UNKNOWN_INVITE'); + if (!invite) throw new Error('INVITE_NOT_FOUND'); return invite; } From 1890cd11c99423c72ced3664003f5607b22b64a8 Mon Sep 17 00:00:00 2001 From: DraftMan Date: Mon, 21 Jun 2021 13:25:48 +0200 Subject: [PATCH 08/34] fix(Errors): Update quotes & formulation Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> --- src/errors/Messages.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/errors/Messages.js b/src/errors/Messages.js index ee71428d8ab4..40bb0f69e87f 100644 --- a/src/errors/Messages.js +++ b/src/errors/Messages.js @@ -107,9 +107,9 @@ const Messages = { VANITY_URL: 'This guild does not have the VANITY_URL feature enabled.', - INVITE_RESOLVE_CODE: `Couldn't resolve the code to fetch the invite.`, + INVITE_RESOLVE_CODE: 'Could not resolve the code to fetch the invite.', - INVITE_NOT_FOUND: `Could not find the requested invite.`, + INVITE_NOT_FOUND: 'Could not find the requested invite.', DELETE_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot delete them", FETCH_GROUP_DM_CHANNEL: "Bots don't have access to Group DM Channels and cannot fetch them", From 8b727b8e7a584f2dfc9589042287284f1d1c3512 Mon Sep 17 00:00:00 2001 From: DraftMan Date: Wed, 23 Jun 2021 00:33:22 +0200 Subject: [PATCH 09/34] docs: Provide more details in docs about invite creation Co-authored-by: Vlad Frangu --- src/managers/GuildInviteManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 5f1559b1b5f2..64a3ac1c0761 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -133,7 +133,7 @@ class GuildInviteManager extends BaseManager { } /** - * Create a invite to the guild from the first available channel. + * Create a invite to the guild from the provided or the first available channel. * @param {CreateInviteOptions|ChannelResolvable} [options=null] The options for creating the invite * @param {ChannelResolvable} [channel=null] The options for creating the invite * @returns {Promise} From 186b1524c6351b042b426dd44f319eb10610a0b8 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Wed, 23 Jun 2021 01:07:39 +0200 Subject: [PATCH 10/34] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20Move=20c?= =?UTF-8?q?hannel=20parameter=20to=20options?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/managers/GuildInviteManager.js | 24 +++++++++++++----------- typings/index.d.ts | 4 ++++ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 64a3ac1c0761..6f4486ac74a1 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -2,7 +2,6 @@ const BaseManager = require('./BaseManager'); const { Error } = require('../errors'); -const GuildChannel = require('../structures/GuildChannel'); const Invite = require('../structures/Invite'); const Collection = require('../util/Collection'); const DataResolver = require('../util/DataResolver'); @@ -132,10 +131,15 @@ class GuildInviteManager extends BaseManager { return data.reduce((col, invite) => col.set(invite.code, this.add(invite, cache)), new Collection()); } + /** + * @typedef {Object} CreateChannelInviteOptions + * @property {GuildChannel} [channel] The optional channel to define where to create the invite. + * @extends {CreateInviteOptions} + */ + /** * Create a invite to the guild from the provided or the first available channel. - * @param {CreateInviteOptions|ChannelResolvable} [options=null] The options for creating the invite - * @param {ChannelResolvable} [channel=null] The options for creating the invite + * @param {CreateChannelInviteOptions} [options={}] The options for creating the invite from a optional channel. * @returns {Promise} * @example * // Create an invite to a random allowed channel @@ -144,21 +148,19 @@ class GuildInviteManager extends BaseManager { * .catch(console.error); * @example * // Create an invite to a selected channel - * guild.invites.create('599942732013764608') + * guild.invites.create({ channel: '599942732013764608' }) * .then(console.log) * .catch(console.error); */ - create(options = null, channel = null) { - if (!channel && (options instanceof GuildChannel || typeof options === 'string')) { - channel = options; - options = null; - } - if (!channel) { + create(options = {}) { + let channel; + + if (!options.channel) { channel = this.guild.channels.cache.find(c => c.permissionsFor(this.guild.me).has('CREATE_INSTANT_INVITE')); if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_INVITE')); } - channel = this.guild.channels.resolve(channel); + channel = this.guild.channels.resolve(options.channel); if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); return channel.createInvite(options); diff --git a/typings/index.d.ts b/typings/index.d.ts index b1edb58bcb49..f54114fcc1c4 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3026,6 +3026,10 @@ declare module 'discord.js' { cache: boolean; } + interface CreateChannelInviteOptions extends CreateInviteOptions { + channel: GuildChannel + } + interface FetchInviteOptions extends BaseFetchOptions { code: string; } From ae9916d3b556da5031cbf5b6b72ba19046f7c385 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Wed, 23 Jun 2021 01:33:56 +0200 Subject: [PATCH 11/34] =?UTF-8?q?types(options):=20=F0=9F=8F=B7=EF=B8=8F?= =?UTF-8?q?=20Fix=20options=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- typings/index.d.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index f54114fcc1c4..9cfa213bb0f6 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -2344,8 +2344,7 @@ declare module 'discord.js' { export class GuildInviteManager extends BaseManager { constructor(guild: Guild, iterable?: Iterable); public guild: Guild; - public create(options?: CreateInviteOptions, channel?: ChannelResolvable): Promise; - public create(channel?: ChannelResolvable): Promise; + public create(options?: CreateChannelInviteOptions): Promise; public fetch(options: InviteResolvable | FetchInviteOptions): Promise; public fetch(options?: FetchInvitesOptions): Promise>; public delete(invite: InviteResolvable, reason?: string): Promise; From edced3aaf01d3289c68c5ae0f87cc982873b9824 Mon Sep 17 00:00:00 2001 From: DraftMan Date: Wed, 23 Jun 2021 15:22:35 +0200 Subject: [PATCH 12/34] refactor: Change [] to () Co-authored-by: Vlad Frangu --- src/managers/GuildInviteManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 6f4486ac74a1..6439ad3b4f0a 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -174,7 +174,7 @@ class GuildInviteManager extends BaseManager { */ delete(invite, reason) { const code = DataResolver.resolveInviteCode(invite); - return this.client.api.invites[code].delete({ reason }).then(() => this); + return this.client.api.invites(code).delete({ reason }).then(() => this); } } From 357dd093b84f636a5e54acd9ed6def6dd675d4b1 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Wed, 23 Jun 2021 16:06:31 +0200 Subject: [PATCH 13/34] =?UTF-8?q?style:=20=F0=9F=9A=A8=20Lint=20suggest=20?= =?UTF-8?q?&=20typings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vlad Frangu --- src/managers/GuildInviteManager.js | 5 ++++- typings/index.d.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 6439ad3b4f0a..9f0afbcf4cdb 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -174,7 +174,10 @@ class GuildInviteManager extends BaseManager { */ delete(invite, reason) { const code = DataResolver.resolveInviteCode(invite); - return this.client.api.invites(code).delete({ reason }).then(() => this); + return this.client.api + .invites(code) + .delete({ reason }) + .then(() => this); } } diff --git a/typings/index.d.ts b/typings/index.d.ts index 9cfa213bb0f6..3ad0c2acb10c 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3030,7 +3030,7 @@ declare module 'discord.js' { } interface FetchInviteOptions extends BaseFetchOptions { - code: string; + code: string } interface FetchInvitesOptions { From 8aacbd90e058ac1f6f8102e85114de99c258e316 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Wed, 23 Jun 2021 17:32:26 +0200 Subject: [PATCH 14/34] refactor: Some suggested corrections on typings & typedoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Antonio Román --- src/managers/GuildInviteManager.js | 3 +-- typings/index.d.ts | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 9f0afbcf4cdb..260b3a4de0cc 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -132,9 +132,8 @@ class GuildInviteManager extends BaseManager { } /** - * @typedef {Object} CreateChannelInviteOptions + * @typedef {CreateInviteOptions} CreateChannelInviteOptions * @property {GuildChannel} [channel] The optional channel to define where to create the invite. - * @extends {CreateInviteOptions} */ /** diff --git a/typings/index.d.ts b/typings/index.d.ts index 3ad0c2acb10c..84467fdfd07b 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3026,11 +3026,11 @@ declare module 'discord.js' { } interface CreateChannelInviteOptions extends CreateInviteOptions { - channel: GuildChannel + channel: GuildChannel; } interface FetchInviteOptions extends BaseFetchOptions { - code: string + code: string; } interface FetchInvitesOptions { From 4d1cbf0c7c8b8b7ba91f38a532a76ad89b05191b Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 24 Jun 2021 13:17:36 +0200 Subject: [PATCH 15/34] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20Change?= =?UTF-8?q?=20return=20value=20of=20delete=20method=20to=20void?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vlad Frangu --- src/managers/GuildInviteManager.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 260b3a4de0cc..d1724d9a7a78 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -169,14 +169,12 @@ class GuildInviteManager extends BaseManager { * Deletes a invite. * @param {InviteResolvable} invite The invite to delete * @param {string} [reason] Reason for deleting the invite - * @returns {Promise} + * @returns {Promise} */ - delete(invite, reason) { + async delete(invite, reason) { const code = DataResolver.resolveInviteCode(invite); - return this.client.api - .invites(code) - .delete({ reason }) - .then(() => this); + + await this.client.api.invites(code).delete({ reason }); } } From 0900a51aec387aab9d3b2c8a337f581418eabef0 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 24 Jun 2021 13:20:09 +0200 Subject: [PATCH 16/34] =?UTF-8?q?fix:=20=F0=9F=93=9D=20Remove=20uncertain?= =?UTF-8?q?=20return=20value=20of=20doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vlad Frangu --- src/managers/GuildInviteManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index d1724d9a7a78..77003d3776a2 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -139,7 +139,7 @@ class GuildInviteManager extends BaseManager { /** * Create a invite to the guild from the provided or the first available channel. * @param {CreateChannelInviteOptions} [options={}] The options for creating the invite from a optional channel. - * @returns {Promise} + * @returns {Promise} * @example * // Create an invite to a random allowed channel * guild.invites.create() From dcacf1c461aa442b210b2fb81ae6fe9022ba36c9 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 24 Jun 2021 15:36:22 +0200 Subject: [PATCH 17/34] =?UTF-8?q?fix:=20=F0=9F=90=9B=20If=20"options"=20is?= =?UTF-8?q?=20a=20string,=20it's=20not=20needed=20to=20continue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> --- src/managers/GuildInviteManager.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 77003d3776a2..164a94445291 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -102,8 +102,11 @@ class GuildInviteManager extends BaseManager { */ fetch(options) { if (!options) return this._fetchMany(); - const code = DataResolver.resolveInviteCode(options); - if (code) return this._fetchSingle({ code, cache: true }); + if (typeof options === 'string') { + const code = DataResolver.resolveInviteCode(options); + if (!code) return Promise.reject(new Error('INVITE_RESOLVE_CODE')); + return this._fetchSingle({ code, cache: true }); + } if (!options.code) { if ('cache' in options) return this._fetchMany(options.cache); return Promise.reject(new Error('INVITE_RESOLVE_CODE')); From 92e74ef7532506568a5687d0ed4e4849930e985f Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 24 Jun 2021 15:36:59 +0200 Subject: [PATCH 18/34] =?UTF-8?q?perf:=20=E2=9A=A1=EF=B8=8F=20Remove=20dou?= =?UTF-8?q?ble=20channel=20resolution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> --- src/managers/GuildInviteManager.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 164a94445291..6a7b376b14bb 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -157,14 +157,14 @@ class GuildInviteManager extends BaseManager { create(options = {}) { let channel; - if (!options.channel) { + if (options.channel) { + channel = this.guild.channels.resolve(options.channel); + if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); + } else { channel = this.guild.channels.cache.find(c => c.permissionsFor(this.guild.me).has('CREATE_INSTANT_INVITE')); if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_INVITE')); } - channel = this.guild.channels.resolve(options.channel); - if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); - return channel.createInvite(options); } From ddbb26da5aacbf916e92e5d191c16427a3d5a02f Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 24 Jun 2021 15:37:30 +0200 Subject: [PATCH 19/34] =?UTF-8?q?perf:=20=E2=9A=A1=EF=B8=8F=20Use=20Permis?= =?UTF-8?q?sions=20flags=20instead=20of=20string?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> --- src/managers/GuildInviteManager.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 6a7b376b14bb..ab98a84cb79c 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -5,6 +5,7 @@ const { Error } = require('../errors'); const Invite = require('../structures/Invite'); const Collection = require('../util/Collection'); const DataResolver = require('../util/DataResolver'); +const Permissions = require('../util/Permissions'); /** * Manages API methods for GuildInvites and stores their cache. @@ -161,7 +162,9 @@ class GuildInviteManager extends BaseManager { channel = this.guild.channels.resolve(options.channel); if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); } else { - channel = this.guild.channels.cache.find(c => c.permissionsFor(this.guild.me).has('CREATE_INSTANT_INVITE')); + channel = this.guild.channels.cache.find(c => + c.permissionsFor(this.guild.me).has(Permissions.FLAGS.CREATE_INSTANT_INVITE), + ); if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_INVITE')); } From e2992b67f6690bde11d24d3e492e2cf009333718 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 24 Jun 2021 15:41:52 +0200 Subject: [PATCH 20/34] =?UTF-8?q?types:=20=F0=9F=8F=B7=EF=B8=8F=20Change?= =?UTF-8?q?=20GuildChannel=20to=20GuildChannelResolvable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com> --- src/managers/GuildInviteManager.js | 2 +- typings/index.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index ab98a84cb79c..2b605f4a1dbb 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -137,7 +137,7 @@ class GuildInviteManager extends BaseManager { /** * @typedef {CreateInviteOptions} CreateChannelInviteOptions - * @property {GuildChannel} [channel] The optional channel to define where to create the invite. + * @property {GuildChannelResolvable} [channel] The optional channel to define where to create the invite. */ /** diff --git a/typings/index.d.ts b/typings/index.d.ts index 84467fdfd07b..f7baa70bd162 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3026,7 +3026,7 @@ declare module 'discord.js' { } interface CreateChannelInviteOptions extends CreateInviteOptions { - channel: GuildChannel; + channel: GuildChannelResolvable; } interface FetchInviteOptions extends BaseFetchOptions { From 6baef142cb4c029ba44bc283612dbcd631a43b6f Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Fri, 25 Jun 2021 19:03:08 +0200 Subject: [PATCH 21/34] =?UTF-8?q?docs:=20=F0=9F=93=9D=20Remove=20personnal?= =?UTF-8?q?=20invites=20of=20examples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/managers/GuildInviteManager.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 2b605f4a1dbb..9a94a150d3e4 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -87,17 +87,17 @@ class GuildInviteManager extends BaseManager { * .catch(console.error); * @example * // Fetch a single invite - * guild.invites.fetch('DrzKVU3') + * guild.invites.fetch('bRCvFy9') * .then(console.log) * .catch(console.error); * @example * // Fetch a single invite without checking cache - * guild.invites.fetch({ code: 'DrzKVU3', force: true }) + * guild.invites.fetch({ code: 'bRCvFy9', force: true }) * .then(console.log) * .catch(console.error) * @example * // Fetch a single invite without caching - * guild.invites.fetch({ code: 'DrzKVU3', cache: false }) + * guild.invites.fetch({ code: 'bRCvFy9', cache: false }) * .then(console.log) * .catch(console.error); */ From 546a73c46db81f0f8c577a79f453b24c9e5ae9e7 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Mon, 28 Jun 2021 00:16:51 +0200 Subject: [PATCH 22/34] =?UTF-8?q?refactor(Guild):=20=F0=9F=94=A5=20Remove?= =?UTF-8?q?=20'Guild#fetchInvites'=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: The 'Guild#fetchInvites' method has been removed. Co-authored-by: SpaceEEC --- src/structures/Guild.js | 30 ------------------------------ typings/index.d.ts | 1 - 2 files changed, 31 deletions(-) diff --git a/src/structures/Guild.js b/src/structures/Guild.js index 36f09e7a478f..4476a5d8095e 100644 --- a/src/structures/Guild.js +++ b/src/structures/Guild.js @@ -5,7 +5,6 @@ const GuildAuditLogs = require('./GuildAuditLogs'); const GuildPreview = require('./GuildPreview'); const GuildTemplate = require('./GuildTemplate'); const Integration = require('./Integration'); -const Invite = require('./Invite'); const Webhook = require('./Webhook'); const WelcomeScreen = require('./WelcomeScreen'); const { Error, TypeError } = require('../errors'); @@ -580,35 +579,6 @@ class Guild extends AnonymousGuild { .then(data => new GuildTemplate(this.client, data)); } - /** - * Fetches a collection of invites to this guild. - * Resolves with a collection mapping invites by their codes. - * @returns {Promise>} - * @example - * // Fetch invites - * guild.fetchInvites() - * .then(invites => console.log(`Fetched ${invites.size} invites`)) - * .catch(console.error); - * @example - * // Fetch invite creator by their id - * guild.fetchInvites() - * .then(invites => console.log(invites.find(invite => invite.inviter.id === '84484653687267328'))) - * .catch(console.error); - */ - fetchInvites() { - return this.client.api - .guilds(this.id) - .invites.get() - .then(inviteItems => { - const invites = new Collection(); - for (const inviteItem of inviteItems) { - const invite = new Invite(this.client, inviteItem); - invites.set(invite.code, invite); - } - return invites; - }); - } - /** * Obtains a guild preview for this guild from Discord. * @returns {Promise} diff --git a/typings/index.d.ts b/typings/index.d.ts index f7baa70bd162..bc2d5aa67ad2 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -844,7 +844,6 @@ declare module 'discord.js' { public equals(guild: Guild): boolean; public fetchAuditLogs(options?: GuildAuditLogsFetchOptions): Promise; public fetchIntegrations(): Promise>; - public fetchInvites(): Promise>; public fetchOwner(options?: FetchOwnerOptions): Promise; public fetchPreview(): Promise; public fetchTemplates(): Promise>; From 8173ad0c52ccce576773a15198290765ae11fbef Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 1 Jul 2021 00:45:27 +0200 Subject: [PATCH 23/34] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20Refactor?= =?UTF-8?q?=20of=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Separate channel of options - Move invite creation from channel to manager - Update typings for separated options Co-authored-by: Antonio Román --- src/managers/GuildInviteManager.js | 56 ++++++++++++++---------------- src/structures/GuildChannel.js | 27 ++------------ typings/index.d.ts | 8 ++--- 3 files changed, 31 insertions(+), 60 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 9a94a150d3e4..dd65998a3776 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -1,11 +1,10 @@ 'use strict'; const BaseManager = require('./BaseManager'); -const { Error } = require('../errors'); +const { TypeError, Error } = require('../errors'); const Invite = require('../structures/Invite'); const Collection = require('../util/Collection'); const DataResolver = require('../util/DataResolver'); -const Permissions = require('../util/Permissions'); /** * Manages API methods for GuildInvites and stores their cache. @@ -136,39 +135,38 @@ class GuildInviteManager extends BaseManager { } /** - * @typedef {CreateInviteOptions} CreateChannelInviteOptions - * @property {GuildChannelResolvable} [channel] The optional channel to define where to create the invite. - */ - - /** - * Create a invite to the guild from the provided or the first available channel. - * @param {CreateChannelInviteOptions} [options={}] The options for creating the invite from a optional channel. + * Create a invite to the guild from the provided channel. + * @param {GuildChannelResolvable} channel The options for creating the invite from a channel. + * @param {CreateInviteOptions} [options={}] The options for creating the invite from a channel. * @returns {Promise} * @example - * // Create an invite to a random allowed channel - * guild.invites.create() - * .then(invite => console.log(`Created an invite with a code of ${invite.code} from ${invite.channel}`)) - * .catch(console.error); - * @example * // Create an invite to a selected channel - * guild.invites.create({ channel: '599942732013764608' }) + * guild.invites.create('599942732013764608') * .then(console.log) * .catch(console.error); */ - create(options = {}) { - let channel; - - if (options.channel) { - channel = this.guild.channels.resolve(options.channel); - if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); - } else { - channel = this.guild.channels.cache.find(c => - c.permissionsFor(this.guild.me).has(Permissions.FLAGS.CREATE_INSTANT_INVITE), - ); - if (!channel) return Promise.reject(new Error('GUILD_CHANNEL_INVITE')); - } - - return channel.createInvite(options); + async create( + channel, + { temporary = false, maxAge = 86400, maxUses = 0, unique, targetUser, targetApplication, targetType, reason } = {}, + ) { + if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true); + + const id = this.guild.channels.resolveID(channel); + if (!id) throw new Error('GUILD_CHANNEL_RESOLVE'); + + const invite = await this.client.api.channels(id).invites.post({ + data: { + temporary, + max_age: maxAge, + max_uses: maxUses, + unique, + target_user_id: this.client.users.resolveID(targetUser), + target_application_id: targetApplication?.id ?? targetApplication?.applicationID ?? targetApplication, + target_type: targetType, + }, + reason, + }); + return new Invite(this.client, invite); } /** diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index 92fc087266fc..17144a504eb0 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -564,31 +564,8 @@ class GuildChannel extends Channel { * .then(invite => console.log(`Created an invite with a code of ${invite.code}`)) * .catch(console.error); */ - createInvite({ - temporary = false, - maxAge = 86400, - maxUses = 0, - unique, - targetUser, - targetApplication, - targetType, - reason, - } = {}) { - return this.client.api - .channels(this.id) - .invites.post({ - data: { - temporary, - max_age: maxAge, - max_uses: maxUses, - unique, - target_user_id: this.client.users.resolveID(targetUser), - target_application_id: targetApplication?.id ?? targetApplication?.applicationID ?? targetApplication, - target_type: targetType, - }, - reason, - }) - .then(invite => new Invite(this.client, invite)); + createInvite(options) { + return this.guild.invites.create(this.id, options); } /** diff --git a/typings/index.d.ts b/typings/index.d.ts index bc2d5aa67ad2..33e430a683c4 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -2343,7 +2343,7 @@ declare module 'discord.js' { export class GuildInviteManager extends BaseManager { constructor(guild: Guild, iterable?: Iterable); public guild: Guild; - public create(options?: CreateChannelInviteOptions): Promise; + public create(channel: GuildChannelResolvable, options?: CreateInviteOptions): Promise; public fetch(options: InviteResolvable | FetchInviteOptions): Promise; public fetch(options?: FetchInvitesOptions): Promise>; public delete(invite: InviteResolvable, reason?: string): Promise; @@ -3023,11 +3023,7 @@ declare module 'discord.js' { interface FetchBansOptions { cache: boolean; } - - interface CreateChannelInviteOptions extends CreateInviteOptions { - channel: GuildChannelResolvable; - } - + interface FetchInviteOptions extends BaseFetchOptions { code: string; } From a189ae62628c76703c91ab39d029a03dabec71f6 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Thu, 1 Jul 2021 00:50:26 +0200 Subject: [PATCH 24/34] =?UTF-8?q?fix:=20=F0=9F=8F=B7=EF=B8=8F=20Fix=20tsli?= =?UTF-8?q?nt=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index 33e430a683c4..1a9df90c0685 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3023,7 +3023,7 @@ declare module 'discord.js' { interface FetchBansOptions { cache: boolean; } - + interface FetchInviteOptions extends BaseFetchOptions { code: string; } From d12db152350ba1958e326bfdddf38648061c92b4 Mon Sep 17 00:00:00 2001 From: DraftMan Date: Sat, 3 Jul 2021 16:02:57 +0200 Subject: [PATCH 25/34] refactor(Errors): Remove unused errors Co-authored-by: SpaceEEC --- src/errors/Messages.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/errors/Messages.js b/src/errors/Messages.js index 40bb0f69e87f..c19d9d94c5be 100644 --- a/src/errors/Messages.js +++ b/src/errors/Messages.js @@ -81,8 +81,6 @@ const Messages = { PRUNE_DAYS_TYPE: 'Days must be a number', - GUILD_CHANNEL_INVITE: 'Could not find an available channel to create an invite.', - GUILD_CHANNEL_RESOLVE: 'Could not resolve channel to a guild channel.', GUILD_VOICE_CHANNEL_RESOLVE: 'Could not resolve channel to a guild voice channel.', GUILD_CHANNEL_ORPHAN: 'Could not find a parent to this guild channel.', From d713efbc5398b88a64910b2c562c1ebf2d292861 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sat, 3 Jul 2021 16:15:33 +0200 Subject: [PATCH 26/34] =?UTF-8?q?docs(GuildInviteManager):=20=F0=9F=93=9D?= =?UTF-8?q?=20Correct=20errors=20in=20typedoc=20descriptions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: SpaceEEC --- src/managers/GuildInviteManager.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index dd65998a3776..d9981ed21a99 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -32,14 +32,14 @@ class GuildInviteManager extends BaseManager { } /** - * Data that resolves to give a Invite object. This can be: + * Data that resolves to give an Invite object. This can be: * * An invite code * * An invite URL * @typedef {string} InviteResolvable */ /** - * Resolves a InviteResolvable to a Invite object. + * Resolves an InviteResolvable to an Invite object. * @method resolve * @memberof GuildInviteManager * @instance @@ -48,7 +48,7 @@ class GuildInviteManager extends BaseManager { */ /** - * Resolves a InviteResolvable to a invite code string. + * Resolves an InviteResolvable to an invite code string. * @method resolveID * @memberof GuildInviteManager * @instance @@ -135,7 +135,7 @@ class GuildInviteManager extends BaseManager { } /** - * Create a invite to the guild from the provided channel. + * Create an invite to the guild from the provided channel. * @param {GuildChannelResolvable} channel The options for creating the invite from a channel. * @param {CreateInviteOptions} [options={}] The options for creating the invite from a channel. * @returns {Promise} @@ -170,7 +170,7 @@ class GuildInviteManager extends BaseManager { } /** - * Deletes a invite. + * Deletes an invite. * @param {InviteResolvable} invite The invite to delete * @param {string} [reason] Reason for deleting the invite * @returns {Promise} From 78443370f658af3f6b0a095e88f6503b18601c6a Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sat, 3 Jul 2021 16:21:00 +0200 Subject: [PATCH 27/34] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20Remove?= =?UTF-8?q?=20useless=20type=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Antonio Román --- src/managers/GuildInviteManager.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index d9981ed21a99..0a5bf7754b07 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -1,7 +1,7 @@ 'use strict'; const BaseManager = require('./BaseManager'); -const { TypeError, Error } = require('../errors'); +const { Error } = require('../errors'); const Invite = require('../structures/Invite'); const Collection = require('../util/Collection'); const DataResolver = require('../util/DataResolver'); @@ -149,8 +149,6 @@ class GuildInviteManager extends BaseManager { channel, { temporary = false, maxAge = 86400, maxUses = 0, unique, targetUser, targetApplication, targetType, reason } = {}, ) { - if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true); - const id = this.guild.channels.resolveID(channel); if (!id) throw new Error('GUILD_CHANNEL_RESOLVE'); From c7354614b4157d22c4159af3875aee9189e6e590 Mon Sep 17 00:00:00 2001 From: DraftMan Date: Sat, 3 Jul 2021 17:17:15 +0200 Subject: [PATCH 28/34] docs(GuildInviteManager): Simplification of typedoc return schem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Antonio Román --- src/managers/GuildInviteManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index 0a5bf7754b07..e87eeaf7a586 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -73,7 +73,7 @@ class GuildInviteManager extends BaseManager { /** * Fetches invite(s) from Discord. * @param {InviteResolvable|FetchInviteOptions|FetchInvitesOptions} [options] Options for fetching guild invite(s) - * @returns {Promise|Promise>} + * @returns {Promise>} * @example * // Fetch all invites from a guild * guild.invites.fetch() From bff9de714f498f708228282d08bdb75345eba8dc Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sat, 3 Jul 2021 17:25:49 +0200 Subject: [PATCH 29/34] =?UTF-8?q?refactor:=20=E2=9A=A1=EF=B8=8F=20Improve?= =?UTF-8?q?=20GuildChannel#fetchInvites=20with=20GuildInviteManager=20cach?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/managers/GuildInviteManager.js | 16 ++++++++++++++++ src/structures/GuildChannel.js | 11 ++--------- typings/index.d.ts | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index e87eeaf7a586..e14586686eff 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -85,6 +85,11 @@ class GuildInviteManager extends BaseManager { * .then(console.log) * .catch(console.error); * @example + * // Fetch all invites from a channel + * guild.invites.fetch({ channelID, '222197033908436994' }) + * .then(console.log) + * .catch(console.error); + * @example * // Fetch a single invite * guild.invites.fetch('bRCvFy9') * .then(console.log) @@ -108,6 +113,12 @@ class GuildInviteManager extends BaseManager { return this._fetchSingle({ code, cache: true }); } if (!options.code) { + if (options.channelID) { + const id = this.guild.channels.resolveID(options.channelID); + if (!id) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); + return this._fetchChannelMany(id, options.cache); + } + if ('cache' in options) return this._fetchMany(options.cache); return Promise.reject(new Error('INVITE_RESOLVE_CODE')); } @@ -134,6 +145,11 @@ class GuildInviteManager extends BaseManager { return data.reduce((col, invite) => col.set(invite.code, this.add(invite, cache)), new Collection()); } + async _fetchChannelMany(channelID, cache) { + const data = await this.client.api.channels(channelID).invites.get(); + return data.reduce((col, invite) => col.set(invite.code, this.add(invite, cache)), new Collection()); + } + /** * Create an invite to the guild from the provided channel. * @param {GuildChannelResolvable} channel The options for creating the invite from a channel. diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index 17144a504eb0..fd8dc319513e 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -1,7 +1,6 @@ 'use strict'; const Channel = require('./Channel'); -const Invite = require('./Invite'); const PermissionOverwrites = require('./PermissionOverwrites'); const Role = require('./Role'); const { Error, TypeError } = require('../errors'); @@ -573,14 +572,8 @@ class GuildChannel extends Channel { * Resolves with a collection mapping invites by their codes. * @returns {Promise>} */ - async fetchInvites() { - const inviteItems = await this.client.api.channels(this.id).invites.get(); - const invites = new Collection(); - for (const inviteItem of inviteItems) { - const invite = new Invite(this.client, inviteItem); - invites.set(invite.code, invite); - } - return invites; + fetchInvites() { + return this.guild.invites.fetch({ channelID: this.id }); } /** diff --git a/typings/index.d.ts b/typings/index.d.ts index 1a9df90c0685..af26a0be6978 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3029,6 +3029,7 @@ declare module 'discord.js' { } interface FetchInvitesOptions { + channelID?: Snowflake; cache: boolean; } From 70423b6c5f96d9608ee223418a0d5ff29efef11c Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sat, 3 Jul 2021 17:26:13 +0200 Subject: [PATCH 30/34] =?UTF-8?q?docs(GuildInviteManager):=20=F0=9F=8F=B7?= =?UTF-8?q?=EF=B8=8F=20Fix=20cache=20option=20typing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Antonio Román --- typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index af26a0be6978..fde33140c842 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -3030,7 +3030,7 @@ declare module 'discord.js' { interface FetchInvitesOptions { channelID?: Snowflake; - cache: boolean; + cache?: boolean; } interface FetchGuildOptions extends BaseFetchOptions { From a1d850900d14f0d0c18e4ffbe79ac3a9c81f0f61 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sat, 3 Jul 2021 17:36:32 +0200 Subject: [PATCH 31/34] =?UTF-8?q?fix:=20=F0=9F=9A=91=20Fix=20breaking=20ch?= =?UTF-8?q?anges=20in=20GuildAuditLogs=20initialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/structures/GuildAuditLogs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structures/GuildAuditLogs.js b/src/structures/GuildAuditLogs.js index afcb683165ba..c257e0e84ea6 100644 --- a/src/structures/GuildAuditLogs.js +++ b/src/structures/GuildAuditLogs.js @@ -474,7 +474,7 @@ class GuildAuditLogsEntry { this.target = guild.members.fetch(guild.client.user.id).then(me => { if (me.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { const change = this.changes.find(c => c.key === 'code'); - return guild.fetchInvites().then(invites => { + return guild.invites.fetch().then(invites => { this.target = invites.find(i => i.code === (change.new || change.old)); }); } else { From 5be49e90b511ef3e5858522820ef986e8f17096b Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sat, 3 Jul 2021 23:12:49 +0200 Subject: [PATCH 32/34] =?UTF-8?q?feat(GuildChannel):=20=E2=9C=A8=20Add=20c?= =?UTF-8?q?ache=20option=20to=20GuildChannel#fetchInvites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: SpaceEEC --- src/structures/GuildChannel.js | 5 +++-- typings/index.d.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/structures/GuildChannel.js b/src/structures/GuildChannel.js index 37866074ebc9..8035ed41f706 100644 --- a/src/structures/GuildChannel.js +++ b/src/structures/GuildChannel.js @@ -469,10 +469,11 @@ class GuildChannel extends Channel { /** * Fetches a collection of invites to this guild channel. * Resolves with a collection mapping invites by their codes. + * @param {boolean} [cache=true] Whether or not to cache the fetched invites * @returns {Promise>} */ - fetchInvites() { - return this.guild.invites.fetch({ channelID: this.id }); + fetchInvites(cache = true) { + return this.guild.invites.fetch({ channelID: this.id, cache }); } /** diff --git a/typings/index.d.ts b/typings/index.d.ts index 1a995a7b1dc2..04aebebc6ead 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1032,7 +1032,7 @@ declare module 'discord.js' { public createInvite(options?: CreateInviteOptions): Promise; public edit(data: ChannelData, reason?: string): Promise; public equals(channel: GuildChannel): boolean; - public fetchInvites(): Promise>; + public fetchInvites(cache?: boolean): Promise>; public lockPermissions(): Promise; public permissionsFor(memberOrRole: GuildMember | Role): Readonly; public permissionsFor(memberOrRole: GuildMemberResolvable | RoleResolvable): Readonly | null; From 3135046d55781710930cd2c548ffa0e95cae0bb8 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 4 Jul 2021 21:10:47 +0200 Subject: [PATCH 33/34] =?UTF-8?q?refactor(GuildInviteManager):=20=E2=99=BB?= =?UTF-8?q?=EF=B8=8F=20Add=20changes=20due=20to=20methods=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: iCrawl --- src/managers/GuildInviteManager.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/managers/GuildInviteManager.js b/src/managers/GuildInviteManager.js index e14586686eff..e9b47cdea367 100644 --- a/src/managers/GuildInviteManager.js +++ b/src/managers/GuildInviteManager.js @@ -49,7 +49,7 @@ class GuildInviteManager extends BaseManager { /** * Resolves an InviteResolvable to an invite code string. - * @method resolveID + * @method resolveId * @memberof GuildInviteManager * @instance * @param {InviteResolvable} invite The invite resolvable to resolve @@ -113,8 +113,8 @@ class GuildInviteManager extends BaseManager { return this._fetchSingle({ code, cache: true }); } if (!options.code) { - if (options.channelID) { - const id = this.guild.channels.resolveID(options.channelID); + if (options.channelId) { + const id = this.guild.channels.resolveId(options.channelId); if (!id) return Promise.reject(new Error('GUILD_CHANNEL_RESOLVE')); return this._fetchChannelMany(id, options.cache); } @@ -165,7 +165,7 @@ class GuildInviteManager extends BaseManager { channel, { temporary = false, maxAge = 86400, maxUses = 0, unique, targetUser, targetApplication, targetType, reason } = {}, ) { - const id = this.guild.channels.resolveID(channel); + const id = this.guild.channels.resolveId(channel); if (!id) throw new Error('GUILD_CHANNEL_RESOLVE'); const invite = await this.client.api.channels(id).invites.post({ @@ -174,8 +174,8 @@ class GuildInviteManager extends BaseManager { max_age: maxAge, max_uses: maxUses, unique, - target_user_id: this.client.users.resolveID(targetUser), - target_application_id: targetApplication?.id ?? targetApplication?.applicationID ?? targetApplication, + target_user_id: this.client.users.resolveId(targetUser), + target_application_id: targetApplication?.id ?? targetApplication?.applicationId ?? targetApplication, target_type: targetType, }, reason, From bdcceb0e68b97f0f63d182013c6cd6fa3392cbf4 Mon Sep 17 00:00:00 2001 From: DraftProducts Date: Sun, 4 Jul 2021 21:16:03 +0200 Subject: [PATCH 34/34] =?UTF-8?q?types(GuildInviteManager):=20=F0=9F=8F=B7?= =?UTF-8?q?=EF=B8=8F=20Fix=20typings=20due=20to=20external=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/typings/index.d.ts b/typings/index.d.ts index d7f37b02ce93..1f186af86a68 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -2550,7 +2550,7 @@ declare module 'discord.js' { public remove(user: UserResolvable, reason?: string): Promise; } - export class GuildInviteManager extends BaseManager { + export class GuildInviteManager extends DataManager { constructor(guild: Guild, iterable?: Iterable); public guild: Guild; public create(channel: GuildChannelResolvable, options?: CreateInviteOptions): Promise;