Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: GuildBanManager #5276

Merged
merged 44 commits into from May 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
24918a3
feat(GuildBanManager): add GuildBanManager
MBR-0001 Jan 4, 2021
6e2986c
fix(GuildBanManager): _fetchMany cache option
MBR-0001 Jan 31, 2021
09b8752
fix(GuildBanAdd): don't create unnecessary variable
MBR-0001 Feb 1, 2021
d25a9e5
fix(GuildBan): use typeof instead of ===
MBR-0001 Feb 1, 2021
4e04ed5
style(GuildBanRemove): let -> const and variable name
MBR-0001 Feb 1, 2021
11a7b2e
style(GuildBanManager): remove unnecessary ()
MBR-0001 Feb 1, 2021
ff49f2c
fix(GuildBanAdd): pass user instead of creating it
MBR-0001 Feb 1, 2021
b7aad42
revert(Guild): remove nameAcronym fix
MBR-0001 Feb 1, 2021
28505d7
fix(GuildBanManager): remove default value for cache in add method
MBR-0001 Feb 1, 2021
a129943
fix(GuildBanManager): add ability to fetch all bans without caching
MBR-0001 Feb 1, 2021
b76e2b5
fix(GuildBanRemove): create GuildBan in case its not cached + jsdoc
MBR-0001 Feb 2, 2021
b6bb51d
refactor(GuildBanManager): make methods async
MBR-0001 Feb 2, 2021
92ce509
fix(GuildBanManager): use reject instead of throw
MBR-0001 Feb 2, 2021
a73f6ff
fix(GuildBan): remove reason & user from constructor & if data check
MBR-0001 Feb 6, 2021
bb141f4
docs(GuildBan): remove readonly from guild, user & reason
MBR-0001 Feb 6, 2021
3f60821
fix(GuildBan): add back jsdoc for user & reason fields
MBR-0001 Feb 6, 2021
a7927ae
fix(GuildBanRemove): pass data directly
MBR-0001 Feb 6, 2021
2acb058
Merge branch 'banmanager' of https://github.com/MBR-0001/discord.js i…
MBR-0001 Feb 6, 2021
1e834c2
fix(GuildBanAdd): pass data directly
MBR-0001 Feb 6, 2021
94d778e
fix(GuildBan): remove if user in data check since it will always be
MBR-0001 Feb 6, 2021
26ebfde
style(GuildBan): replace `typeof` with `in this`
MBR-0001 Feb 6, 2021
c90bd15
fix(GuildBan): revert the value of reason in this
MBR-0001 Feb 6, 2021
1f7a901
docs(GuildBanManager): fix fetch options
MBR-0001 Feb 7, 2021
3bfcb33
style(GuildBanManager): clean up resolve method
MBR-0001 Feb 9, 2021
45ec354
style(GuildBanManager): use reduce to create the ban collection
MBR-0001 Feb 9, 2021
e508b06
fix(GuildBanManager): resolve to member not GuildBan
MBR-0001 Feb 9, 2021
ec24099
style(GuildBanManager): Use ( instead of [
MBR-0001 Feb 9, 2021
c50c1d7
fix(GuildBanManager): remove options mutating
MBR-0001 Feb 9, 2021
a013e4c
style(GuildBanManager): use ( instead of [
MBR-0001 Feb 9, 2021
f3fca29
docs(GuildBanManager): document fetching all members without caching
MBR-0001 Feb 9, 2021
8badd2d
docs(FetchBansOptions): make cache not optional
MBR-0001 Feb 9, 2021
714c322
refactor(GuildBanManager): rename ban methods& add them to MemberManager
MBR-0001 Feb 9, 2021
3fd7df9
types(GuildBanManager): rename ban methods & add them to MemberManager
MBR-0001 Feb 9, 2021
598ba38
feat(*): merge v8
MBR-0001 Feb 11, 2021
71a2de1
Revert "feat(*): merge v8"
MBR-0001 Feb 11, 2021
0f5052e
Merge branch 'master' of https://github.com/discordjs/discord.js into…
MBR-0001 Feb 11, 2021
2db2d77
Merge branch 'discordjs-master' into banmanager
MBR-0001 Feb 11, 2021
e29963f
fix(typings): remove FetchIntegrationsOptions
MBR-0001 Mar 17, 2021
1994727
docs(GuildBanManager): minor change
MBR-0001 Mar 26, 2021
6ac5ae9
types(Guild): remove fetchBan(s) methods
MBR-0001 Mar 27, 2021
2122e6d
typings(GuildBan): extend Base class
MBR-0001 Mar 27, 2021
21b8d7c
docs(GuildBanManager): add inclusive to days
MBR-0001 Mar 28, 2021
449e92e
Merge branch 'master' into banmanager
MBR-0001 Apr 15, 2021
ae078a1
Merge branch 'master' into banmanager
MBR-0001 May 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions esm/discord.mjs
Expand Up @@ -32,6 +32,7 @@ export const {
BaseGuildEmojiManager,
ChannelManager,
GuildApplicationCommandManager,
GuildBanManager,
GuildChannelManager,
GuildEmojiManager,
GuildEmojiRoleManager,
Expand Down Expand Up @@ -67,6 +68,7 @@ export const {
Emoji,
Guild,
GuildAuditLogs,
GuildBan,
GuildChannel,
GuildEmoji,
GuildMember,
Expand Down
1 change: 1 addition & 0 deletions src/client/actions/ActionsManager.js
Expand Up @@ -21,6 +21,7 @@ class ActionsManager {
this.register(require('./InviteDelete'));
this.register(require('./GuildMemberRemove'));
this.register(require('./GuildMemberUpdate'));
this.register(require('./GuildBanAdd'));
this.register(require('./GuildBanRemove'));
this.register(require('./GuildRoleCreate'));
this.register(require('./GuildRoleDelete'));
Expand Down
20 changes: 20 additions & 0 deletions src/client/actions/GuildBanAdd.js
@@ -0,0 +1,20 @@
'use strict';

const Action = require('./Action');
const { Events } = require('../../util/Constants');

class GuildBanAdd extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.cache.get(data.guild_id);

/**
* Emitted whenever a member is banned from a guild.
* @event Client#guildBanAdd
* @param {GuildBan} ban The ban that occurred
*/
if (guild) client.emit(Events.GUILD_BAN_ADD, guild.bans.add(data));
}
}

module.exports = GuildBanAdd;
12 changes: 8 additions & 4 deletions src/client/actions/GuildBanRemove.js
@@ -1,20 +1,24 @@
'use strict';

const Action = require('./Action');
const GuildBan = require('../../structures/GuildBan');
const { Events } = require('../../util/Constants');

class GuildBanRemove extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.cache.get(data.guild_id);
const user = client.users.add(data.user);

/**
* Emitted whenever a member is unbanned from a guild.
* @event Client#guildBanRemove
* @param {Guild} guild The guild that the unban occurred in
* @param {User} user The user that was unbanned
* @param {GuildBan} ban The ban that was removed
*/
if (guild && user) client.emit(Events.GUILD_BAN_REMOVE, guild, user);
if (guild) {
const ban = guild.bans.cache.get(data.user.id) ?? new GuildBan(client, data, guild);
guild.bans.cache.delete(ban.user.id);
client.emit(Events.GUILD_BAN_REMOVE, ban);
}
}
}

Expand Down
15 changes: 2 additions & 13 deletions src/client/websocket/handlers/GUILD_BAN_ADD.js
@@ -1,16 +1,5 @@
'use strict';

const { Events } = require('../../../util/Constants');

module.exports = (client, { d: data }) => {
const guild = client.guilds.cache.get(data.guild_id);
const user = client.users.add(data.user);

/**
* Emitted whenever a member is banned from a guild.
* @event Client#guildBanAdd
* @param {Guild} guild The guild that the ban occurred in
* @param {User} user The user that was banned
*/
if (guild && user) client.emit(Events.GUILD_BAN_ADD, guild, user);
module.exports = (client, packet) => {
client.actions.GuildBanAdd.handle(packet.d);
};
2 changes: 2 additions & 0 deletions src/index.js
Expand Up @@ -37,6 +37,7 @@ module.exports = {
BaseGuildEmojiManager: require('./managers/BaseGuildEmojiManager'),
ChannelManager: require('./managers/ChannelManager'),
GuildApplicationCommandManager: require('./managers/GuildApplicationCommandManager'),
GuildBanManager: require('./managers/GuildBanManager'),
GuildChannelManager: require('./managers/GuildChannelManager'),
GuildEmojiManager: require('./managers/GuildEmojiManager'),
GuildEmojiRoleManager: require('./managers/GuildEmojiRoleManager'),
Expand Down Expand Up @@ -79,6 +80,7 @@ module.exports = {
Emoji: require('./structures/Emoji'),
Guild: require('./structures/Guild'),
GuildAuditLogs: require('./structures/GuildAuditLogs'),
GuildBan: require('./structures/GuildBan'),
GuildChannel: require('./structures/GuildChannel'),
GuildEmoji: require('./structures/GuildEmoji'),
GuildMember: require('./structures/GuildMember'),
Expand Down
177 changes: 177 additions & 0 deletions src/managers/GuildBanManager.js
@@ -0,0 +1,177 @@
'use strict';

const BaseManager = require('./BaseManager');
const GuildBan = require('../structures/GuildBan');
const GuildMember = require('../structures/GuildMember');
const Collection = require('../util/Collection');

/**
* Manages API methods for GuildBans and stores their cache.
* @extends {BaseManager}
*/
class GuildBanManager extends BaseManager {
constructor(guild, iterable) {
super(guild.client, iterable, GuildBan);

/**
* The guild this Manager belongs to
* @type {Guild}
*/
this.guild = guild;
}

/**
* The cache of this Manager
* @type {Collection<Snowflake, GuildBan>}
* @name GuildBanManager#cache
*/

add(data, cache) {
return super.add(data, cache, { id: data.user.id, extras: [this.guild] });
}

/**
* Data that resolves to give a GuildBan object. This can be:
* * A GuildBan object
* * A User resolvable
* @typedef {GuildBan|UserResolvable} GuildBanResolvable
*/

/**
* Resolves a GuildBanResolvable to a GuildBan object.
* @param {GuildBanResolvable} ban The ban that is in the guild
* @returns {?GuildBan}
*/
resolve(ban) {
return super.resolve(ban) ?? super.resolve(this.client.users.resolveID(ban));
}

/**
* Options used to fetch a single ban from a guild.
* @typedef {Object} FetchBanOptions
* @property {UserResolvable} user The ban to fetch
* @property {boolean} [cache=true] Whether or not to cache the fetched ban
* @property {boolean} [force=false] Whether to skip the cache check and request the API
*/

/**
* Options used to fetch all bans from a guild.
* @typedef {Object} FetchBansOptions
* @property {boolean} cache Whether or not to cache the fetched bans
*/

/**
* Fetches ban(s) from Discord.
* @param {UserResolvable|FetchBanOptions|FetchBansOptions} [options] Options for fetching guild ban(s)
* @returns {Promise<GuildBan>|Promise<Collection<Snowflake, GuildBan>>}
* @example
* // Fetch all bans from a guild
* guild.bans.fetch()
* .then(console.log)
* .catch(console.error);
* @example
* // Fetch all bans from a guild without caching
* guild.bans.fetch({ cache: false })
* .then(console.log)
* .catch(console.error);
* @example
* // Fetch a single ban
* guild.bans.fetch('351871113346809860')
* .then(console.log)
* .catch(console.error);
* @example
* // Fetch a single ban without checking cache
* guild.bans.fetch({ user, force: true })
* .then(console.log)
* .catch(console.error)
* @example
* // Fetch a single ban without caching
* guild.bans.fetch({ user, cache: false })
* .then(console.log)
* .catch(console.error);
*/
fetch(options) {
if (!options) return this._fetchMany();
const user = this.client.users.resolveID(options);
if (user) return this._fetchSingle({ user, cache: true });
if (options.user) {
options.user = this.client.users.resolveID(options.user);
}
if (!options.user) {
if ('cache' in options) return this._fetchMany(options.cache);
return Promise.reject(new Error('FETCH_BAN_RESOLVE_ID'));
}
return this._fetchSingle(options);
}

async _fetchSingle({ user, cache, force = false }) {
if (!force) {
const existing = this.cache.get(user);
if (existing && !existing.partial) return existing;
}

const data = await this.client.api.guilds(this.guild.id).bans(user).get();
return this.add(data, cache);
}

async _fetchMany(cache) {
const data = await this.client.api.guilds(this.guild.id).bans.get();
return data.reduce((col, ban) => col.set(ban.user.id, this.add(ban, cache)), new Collection());
}

/**
* Bans a user from the guild.
* @param {UserResolvable} user The user to ban
* @param {Object} [options] Options for the ban
* @param {number} [options.days=0] Number of days of messages to delete, must be between 0 and 7, inclusive
* @param {string} [options.reason] Reason for banning
* @returns {Promise<GuildMember|User|Snowflake>} Result object will be resolved as specifically as possible.
* If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
* be resolved, the user ID will be the result.
* @example
* // Ban a user by ID (or with a user/guild member object)
* guild.bans.create('84484653687267328')
* .then(user => console.log(`Banned ${user.username ?? user.id ?? user} from ${guild.name}`))
* .catch(console.error);
*/
async create(user, options = { days: 0 }) {
if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
const id = this.client.users.resolveID(user);
if (!id) throw new Error('BAN_RESOLVE_ID', true);
await this.client.api
.guilds(this.guild.id)
.bans(id)
.put({
data: {
reason: options.reason,
delete_message_days: options.days,
},
});
if (user instanceof GuildMember) return user;
const _user = this.client.users.resolve(id);
if (_user) {
return this.guild.members.resolve(_user) ?? _user;
}
return id;
}

/**
* Unbans a user from the guild.
* @param {UserResolvable} user The user to unban
* @param {string} [reason] Reason for unbanning user
* @returns {Promise<User>}
* @example
* // Unban a user by ID (or with a user/guild member object)
* guild.bans.remove('84484653687267328')
* .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`))
* .catch(console.error);
*/
async remove(user, reason) {
const id = this.client.users.resolveID(user);
if (!id) throw new Error('BAN_RESOLVE_ID');
await this.client.api.guilds(this.guild.id).bans(id).delete({ reason });
return this.client.users.resolve(user);
}
}

module.exports = GuildBanManager;
28 changes: 5 additions & 23 deletions src/managers/GuildMemberManager.js
Expand Up @@ -216,49 +216,31 @@ class GuildMemberManager extends BaseManager {
* @returns {Promise<GuildMember|User|Snowflake>} Result object will be resolved as specifically as possible.
* If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
* be resolved, the user ID will be the result.
* Internally calls the GuildBanManager#create method.
* @example
* // Ban a user by ID (or with a user/guild member object)
* guild.members.ban('84484653687267328')
* .then(user => console.log(`Banned ${user.username || user.id || user} from ${guild.name}`))
* .then(user => console.log(`Banned ${user.username ?? user.id ?? user} from ${guild.name}`))
* .catch(console.error);
*/
ban(user, options = { days: 0 }) {
if (typeof options !== 'object') return Promise.reject(new TypeError('INVALID_TYPE', 'options', 'object', true));
if (options.days) options.delete_message_days = options.days;
const id = this.client.users.resolveID(user);
if (!id) return Promise.reject(new Error('BAN_RESOLVE_ID', true));
return this.client.api
.guilds(this.guild.id)
.bans[id].put({ data: options })
.then(() => {
if (user instanceof GuildMember) return user;
const _user = this.client.users.resolve(id);
if (_user) {
const member = this.resolve(_user);
return member || _user;
}
return id;
});
return this.guild.bans.create(user, options);
}

/**
* Unbans a user from the guild.
* @param {UserResolvable} user The user to unban
* @param {string} [reason] Reason for unbanning user
* @returns {Promise<User>}
* Internally calls the GuildBanManager#remove method.
* @example
* // Unban a user by ID (or with a user/guild member object)
* guild.members.unban('84484653687267328')
* .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`))
* .catch(console.error);
*/
unban(user, reason) {
const id = this.client.users.resolveID(user);
if (!id) return Promise.reject(new Error('BAN_RESOLVE_ID'));
return this.client.api
.guilds(this.guild.id)
.bans[id].delete({ reason })
.then(() => this.client.users.resolve(user));
return this.guild.bans.remove(user, reason);
}

_fetchSingle({ user, cache, force = false }) {
Expand Down