summaryrefslogtreecommitdiff
path: root/node_modules/discord.js/src/structures/GuildMember.js
diff options
context:
space:
mode:
author8cy <[email protected]>2020-04-30 15:46:16 -0700
committer8cy <[email protected]>2020-04-30 15:46:16 -0700
commit3a4deac89054021b56ad5bd8005b2044cc085c98 (patch)
tree3dd6af8503e497e46180b6b5231674f36bdce9f2 /node_modules/discord.js/src/structures/GuildMember.js
downloaduppity-3a4deac89054021b56ad5bd8005b2044cc085c98.tar.xz
uppity-3a4deac89054021b56ad5bd8005b2044cc085c98.zip
Up, up, uppity.
Diffstat (limited to 'node_modules/discord.js/src/structures/GuildMember.js')
-rw-r--r--node_modules/discord.js/src/structures/GuildMember.js410
1 files changed, 410 insertions, 0 deletions
diff --git a/node_modules/discord.js/src/structures/GuildMember.js b/node_modules/discord.js/src/structures/GuildMember.js
new file mode 100644
index 0000000..f949517
--- /dev/null
+++ b/node_modules/discord.js/src/structures/GuildMember.js
@@ -0,0 +1,410 @@
+'use strict';
+
+const Base = require('./Base');
+const { Presence } = require('./Presence');
+const Role = require('./Role');
+const VoiceState = require('./VoiceState');
+const TextBasedChannel = require('./interfaces/TextBasedChannel');
+const { Error } = require('../errors');
+const GuildMemberRoleManager = require('../managers/GuildMemberRoleManager');
+const Permissions = require('../util/Permissions');
+
+/**
+ * Represents a member of a guild on Discord.
+ * @implements {TextBasedChannel}
+ * @extends {Base}
+ */
+class GuildMember extends Base {
+ /**
+ * @param {Client} client The instantiating client
+ * @param {Object} data The data for the guild member
+ * @param {Guild} guild The guild the member is part of
+ */
+ constructor(client, data, guild) {
+ super(client);
+
+ /**
+ * The guild that this member is part of
+ * @type {Guild}
+ */
+ this.guild = guild;
+
+ /**
+ * The user that this guild member instance represents
+ * @type {User}
+ * @name GuildMember#user
+ */
+ if (data.user) this.user = client.users.add(data.user, true);
+
+ /**
+ * The timestamp the member joined the guild at
+ * @type {?number}
+ */
+ this.joinedTimestamp = null;
+
+ /**
+ * The ID of the last message sent by the member in their guild, if one was sent
+ * @type {?Snowflake}
+ */
+ this.lastMessageID = null;
+
+ /**
+ * The ID of the channel for the last message sent by the member in their guild, if one was sent
+ * @type {?Snowflake}
+ */
+ this.lastMessageChannelID = null;
+
+ /**
+ * The timestamp of when the member used their Nitro boost on the guild, if it was used
+ * @type {?number}
+ */
+ this.premiumSinceTimestamp = null;
+
+ /**
+ * Whether the member has been removed from the guild
+ * @type {boolean}
+ */
+ this.deleted = false;
+
+ this._roles = [];
+ if (data) this._patch(data);
+ }
+
+ _patch(data) {
+ /**
+ * The nickname of this member, if they have one
+ * @type {?string}
+ * @name GuildMember#nickname
+ */
+ if (typeof data.nick !== 'undefined') this.nickname = data.nick;
+
+ if (data.joined_at) this.joinedTimestamp = new Date(data.joined_at).getTime();
+ if (data.premium_since) this.premiumSinceTimestamp = new Date(data.premium_since).getTime();
+
+ if (data.user) this.user = this.guild.client.users.add(data.user);
+ if (data.roles) this._roles = data.roles;
+ }
+
+ _clone() {
+ const clone = super._clone();
+ clone._roles = this._roles.slice();
+ return clone;
+ }
+
+ /**
+ * Whether this GuildMember is a partial
+ * @type {boolean}
+ * @readonly
+ */
+ get partial() {
+ return !this.joinedTimestamp;
+ }
+
+ /**
+ * A manager for the roles belonging to this member
+ * @type {GuildMemberRoleManager}
+ * @readonly
+ */
+ get roles() {
+ return new GuildMemberRoleManager(this);
+ }
+
+ /**
+ * The Message object of the last message sent by the member in their guild, if one was sent
+ * @type {?Message}
+ * @readonly
+ */
+ get lastMessage() {
+ const channel = this.guild.channels.cache.get(this.lastMessageChannelID);
+ return (channel && channel.messages.cache.get(this.lastMessageID)) || null;
+ }
+
+ /**
+ * The voice state of this member
+ * @type {VoiceState}
+ * @readonly
+ */
+ get voice() {
+ return this.guild.voiceStates.cache.get(this.id) || new VoiceState(this.guild, { user_id: this.id });
+ }
+
+ /**
+ * The time this member joined the guild
+ * @type {?Date}
+ * @readonly
+ */
+ get joinedAt() {
+ return this.joinedTimestamp ? new Date(this.joinedTimestamp) : null;
+ }
+
+ /**
+ * The time of when the member used their Nitro boost on the guild, if it was used
+ * @type {?Date}
+ * @readonly
+ */
+ get premiumSince() {
+ return this.premiumSinceTimestamp ? new Date(this.premiumSinceTimestamp) : null;
+ }
+
+ /**
+ * The presence of this guild member
+ * @type {Presence}
+ * @readonly
+ */
+ get presence() {
+ return (
+ this.guild.presences.cache.get(this.id) ||
+ new Presence(this.client, {
+ user: {
+ id: this.id,
+ },
+ guild: this.guild,
+ })
+ );
+ }
+
+ /**
+ * The displayed color of this member in base 10
+ * @type {number}
+ * @readonly
+ */
+ get displayColor() {
+ const role = this.roles.color;
+ return (role && role.color) || 0;
+ }
+
+ /**
+ * The displayed color of this member in hexadecimal
+ * @type {string}
+ * @readonly
+ */
+ get displayHexColor() {
+ const role = this.roles.color;
+ return (role && role.hexColor) || '#000000';
+ }
+
+ /**
+ * The ID of this member
+ * @type {Snowflake}
+ * @readonly
+ */
+ get id() {
+ return this.user.id;
+ }
+
+ /**
+ * The nickname of this member, or their username if they don't have one
+ * @type {string}
+ * @readonly
+ */
+ get displayName() {
+ return this.nickname || this.user.username;
+ }
+
+ /**
+ * The overall set of permissions for this member, taking only roles into account
+ * @type {Readonly<Permissions>}
+ * @readonly
+ */
+ get permissions() {
+ if (this.user.id === this.guild.ownerID) return new Permissions(Permissions.ALL).freeze();
+ return new Permissions(this.roles.cache.map(role => role.permissions)).freeze();
+ }
+
+ /**
+ * Whether the client user is above this user in the hierarchy, according to role position and guild ownership.
+ * This is a prerequisite for many moderative actions.
+ * @type {boolean}
+ * @readonly
+ */
+ get manageable() {
+ if (this.user.id === this.guild.ownerID) return false;
+ if (this.user.id === this.client.user.id) return false;
+ if (this.client.user.id === this.guild.ownerID) return true;
+ if (!this.guild.me) throw new Error('GUILD_UNCACHED_ME');
+ return this.guild.me.roles.highest.comparePositionTo(this.roles.highest) > 0;
+ }
+
+ /**
+ * Whether this member is kickable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get kickable() {
+ return this.manageable && this.guild.me.permissions.has(Permissions.FLAGS.KICK_MEMBERS);
+ }
+
+ /**
+ * Whether this member is bannable by the client user
+ * @type {boolean}
+ * @readonly
+ */
+ get bannable() {
+ return this.manageable && this.guild.me.permissions.has(Permissions.FLAGS.BAN_MEMBERS);
+ }
+
+ /**
+ * Returns `channel.permissionsFor(guildMember)`. Returns permissions for a member in a guild channel,
+ * taking into account roles and permission overwrites.
+ * @param {ChannelResolvable} channel The guild channel to use as context
+ * @returns {Readonly<Permissions>}
+ */
+ permissionsIn(channel) {
+ channel = this.guild.channels.resolve(channel);
+ if (!channel) throw new Error('GUILD_CHANNEL_RESOLVE');
+ return channel.memberPermissions(this);
+ }
+
+ /**
+ * Checks if any of this member's roles have a permission.
+ * @param {PermissionResolvable} permission Permission(s) to check for
+ * @param {Object} [options] Options
+ * @param {boolean} [options.checkAdmin=true] Whether to allow the administrator permission to override
+ * @param {boolean} [options.checkOwner=true] Whether to allow being the guild's owner to override
+ * @returns {boolean}
+ */
+ hasPermission(permission, { checkAdmin = true, checkOwner = true } = {}) {
+ if (checkOwner && this.user.id === this.guild.ownerID) return true;
+ return this.roles.cache.some(r => r.permissions.has(permission, checkAdmin));
+ }
+
+ /**
+ * The data for editing a guild member.
+ * @typedef {Object} GuildMemberEditData
+ * @property {string} [nick] The nickname to set for the member
+ * @property {Collection<Snowflake, Role>|RoleResolvable[]} [roles] The roles or role IDs to apply
+ * @property {boolean} [mute] Whether or not the member should be muted
+ * @property {boolean} [deaf] Whether or not the member should be deafened
+ * @property {ChannelResolvable|null} [channel] Channel to move member to (if they are connected to voice), or `null`
+ * if you want to kick them from voice
+ */
+
+ /**
+ * Edits this member.
+ * @param {GuildMemberEditData} data The data to edit the member with
+ * @param {string} [reason] Reason for editing this user
+ * @returns {Promise<GuildMember>}
+ */
+ async edit(data, reason) {
+ if (data.channel) {
+ data.channel = this.guild.channels.resolve(data.channel);
+ if (!data.channel || data.channel.type !== 'voice') {
+ throw new Error('GUILD_VOICE_CHANNEL_RESOLVE');
+ }
+ data.channel_id = data.channel.id;
+ data.channel = undefined;
+ } else if (data.channel === null) {
+ data.channel_id = null;
+ data.channel = undefined;
+ }
+ if (data.roles) data.roles = data.roles.map(role => (role instanceof Role ? role.id : role));
+ let endpoint = this.client.api.guilds(this.guild.id);
+ if (this.user.id === this.client.user.id) {
+ const keys = Object.keys(data);
+ if (keys.length === 1 && keys[0] === 'nick') endpoint = endpoint.members('@me').nick;
+ else endpoint = endpoint.members(this.id);
+ } else {
+ endpoint = endpoint.members(this.id);
+ }
+ await endpoint.patch({ data, reason });
+
+ const clone = this._clone();
+ data.user = this.user;
+ clone._patch(data);
+ return clone;
+ }
+
+ /**
+ * Sets the nickname for this member.
+ * @param {string} nick The nickname for the guild member
+ * @param {string} [reason] Reason for setting the nickname
+ * @returns {Promise<GuildMember>}
+ */
+ setNickname(nick, reason) {
+ return this.edit({ nick }, reason);
+ }
+
+ /**
+ * Creates a DM channel between the client and this member.
+ * @returns {Promise<DMChannel>}
+ */
+ createDM() {
+ return this.user.createDM();
+ }
+
+ /**
+ * Deletes any DMs with this member.
+ * @returns {Promise<DMChannel>}
+ */
+ deleteDM() {
+ return this.user.deleteDM();
+ }
+
+ /**
+ * Kicks this member from the guild.
+ * @param {string} [reason] Reason for kicking user
+ * @returns {Promise<GuildMember>}
+ */
+ kick(reason) {
+ return this.client.api
+ .guilds(this.guild.id)
+ .members(this.user.id)
+ .delete({ reason })
+ .then(() => this);
+ }
+
+ /**
+ * Bans this guild member.
+ * @param {Object} [options] Options for the ban
+ * @param {number} [options.days=0] Number of days of messages to delete
+ * @param {string} [options.reason] Reason for banning
+ * @returns {Promise<GuildMember>}
+ * @example
+ * // ban a guild member
+ * guildMember.ban({ days: 7, reason: 'They deserved it' })
+ * .then(console.log)
+ * .catch(console.error);
+ */
+ ban(options) {
+ return this.guild.members.ban(this, options);
+ }
+
+ /**
+ * Fetches this GuildMember.
+ * @returns {Promise<GuildMember>}
+ */
+ fetch() {
+ return this.guild.members.fetch(this.id, true);
+ }
+
+ /**
+ * When concatenated with a string, this automatically returns the user's mention instead of the GuildMember object.
+ * @returns {string}
+ * @example
+ * // Logs: Hello from <@123456789012345678>!
+ * console.log(`Hello from ${member}!`);
+ */
+ toString() {
+ return `<@${this.nickname ? '!' : ''}${this.user.id}>`;
+ }
+
+ toJSON() {
+ return super.toJSON({
+ guild: 'guildID',
+ user: 'userID',
+ displayName: true,
+ speaking: false,
+ lastMessage: false,
+ lastMessageID: false,
+ roles: true,
+ });
+ }
+
+ // These are here only for documentation purposes - they are implemented by TextBasedChannel
+ /* eslint-disable no-empty-function */
+ send() {}
+}
+
+TextBasedChannel.applyToClass(GuildMember);
+
+module.exports = GuildMember;