UNPKG

detritus-client

Version:

A Typescript NodeJS library to interact with Discord's API, both Rest and Gateway.

524 lines (523 loc) 17.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Member = void 0; const detritus_client_rest_1 = require("detritus-client-rest"); const basecollection_1 = require("../collections/basecollection"); const baseset_1 = require("../collections/baseset"); const constants_1 = require("../constants"); const utils_1 = require("../utils"); const channel_1 = require("./channel"); const role_1 = require("./role"); const user_1 = require("./user"); const keysMember = new baseset_1.BaseSet([ constants_1.DiscordKeys.AVATAR, constants_1.DiscordKeys.DEAF, constants_1.DiscordKeys.GUILD_ID, constants_1.DiscordKeys.HOISTED_ROLE, constants_1.DiscordKeys.IS_PENDING, constants_1.DiscordKeys.JOINED_AT, constants_1.DiscordKeys.MUTE, constants_1.DiscordKeys.NICK, constants_1.DiscordKeys.PENDING, constants_1.DiscordKeys.PERMISSIONS, constants_1.DiscordKeys.PREMIUM_SINCE, constants_1.DiscordKeys.ROLES, constants_1.DiscordKeys.USER, ]); const keysMergeMember = new baseset_1.BaseSet([ constants_1.DiscordKeys.GUILD_ID, constants_1.DiscordKeys.ROLES, constants_1.DiscordKeys.HOISTED_ROLE, ]); const keysSkipDifferenceMember = new baseset_1.BaseSet([ constants_1.DiscordKeys.GUILD_ID, constants_1.DiscordKeys.PERMISSIONS, ]); /** * Guild Member Structure * @category Structure */ class Member extends user_1.UserMixin { constructor(client, data, isClone) { super(client, undefined, isClone); this._keys = keysMember; this._keysMerge = keysMergeMember; this._keysSkipDifference = keysSkipDifferenceMember; this._avatar = null; this._permissions = 0n; this.deaf = false; this.guildId = ''; this.hoistedRoleId = null; this.isPending = false; this.joinedAtUnix = 0; this.left = false; this.mute = false; this.nick = null; this.pending = false; this.premiumSinceUnix = 0; this.merge(data); Object.defineProperty(this, '_roles', { enumerable: false, writable: true }); } get avatar() { return this._avatar; } get canAdministrator() { return this.can([constants_1.Permissions.ADMINISTRATOR]); } get canBanMembers() { return this.can([constants_1.Permissions.BAN_MEMBERS]); } get canChangeNickname() { return this.can([constants_1.Permissions.CHANGE_NICKNAME]); } get canChangeNicknames() { return this.can([constants_1.Permissions.CHANGE_NICKNAMES]); } get canCreateInstantInvite() { return this.can([constants_1.Permissions.CREATE_INSTANT_INVITE]); } get canKickMembers() { return this.can([constants_1.Permissions.KICK_MEMBERS]); } get canManageChannels() { return this.can([constants_1.Permissions.MANAGE_CHANNELS]); } get canManageEmojis() { return this.can([constants_1.Permissions.MANAGE_EMOJIS]); } get canManageGuild() { return this.can([constants_1.Permissions.MANAGE_GUILD]); } get canManageMessages() { return this.can([constants_1.Permissions.MANAGE_MESSAGES]); } get canManageRoles() { return this.can([constants_1.Permissions.MANAGE_ROLES]); } get canManageThreads() { return this.can([constants_1.Permissions.MANAGE_THREADS]); } get canManageWebhooks() { return this.can([constants_1.Permissions.MANAGE_WEBHOOKS]); } get canRequestToSpeak() { return this.can([constants_1.Permissions.REQUEST_TO_SPEAK]); } get canUseApplicationCommands() { return this.can([constants_1.Permissions.USE_APPLICATION_COMMANDS]); } get canUsePrivateThreads() { return this.can([constants_1.Permissions.USE_PRIVATE_THREADS]); } get canUsePublicThreads() { return this.can([constants_1.Permissions.USE_PUBLIC_THREADS]); } get canViewAuditLogs() { return this.can([constants_1.Permissions.VIEW_AUDIT_LOG]); } get color() { const role = this.colorRole; return (role) ? role.color : 0; } get colorRole() { let highestRole = null; for (let [roleId, role] of this.roles) { if (role && role.color) { if (highestRole) { if (highestRole.position < role.position) { highestRole = role; } } else { highestRole = role; } } } return highestRole; } get guild() { return this.client.guilds.get(this.guildId) || null; } get hasGuildAvatar() { return !!this._avatar; } get highestRole() { let highestRole = null; for (let [roleId, role] of this.roles) { if (role) { if (highestRole) { if (highestRole.position < role.position) { highestRole = role; } } else { highestRole = role; } } } return highestRole; } get hoistedRole() { if (this.hoistedRoleId) { return this.roles.get(this.hoistedRoleId) || null; } return null; } get isBoosting() { return !!this.premiumSinceUnix; } get isOffline() { const presence = this.presence; if (presence) { return presence.isOffline; } return true; } get isOwner() { const guild = this.guild; if (guild) { return guild.isOwner(this.id); } return false; } get isPartial() { return !!this.joinedAtUnix; } get joinedAt() { if (this.joinedAtUnix) { return new Date(this.joinedAtUnix); } return null; } get mention() { return (this.nick) ? `<@!${this.id}>` : this.user.mention; } get name() { return this.nick || this.username; } get names() { if (this.nick) { return [this.nick, this.username]; } return [this.username]; } get permissions() { if (this._permissions) { return this._permissions; } if (this.isOwner) { return constants_1.PERMISSIONS_ALL; } return this.roles.reduce((total, role) => { if (role) { return total | role.permissions; } return total; }, constants_1.Permissions.NONE); } get premiumSince() { if (this.premiumSinceUnix) { return new Date(this.premiumSinceUnix); } return null; } get roles() { const collection = new basecollection_1.BaseCollection(); const guild = this.guild; collection.set(this.guildId, (guild) ? guild.defaultRole : null); if (this._roles) { for (let roleId of this._roles) { if (guild) { collection.set(roleId, guild.roles.get(roleId) || null); } else { collection.set(roleId, null); } } } return collection; } get voiceChannel() { const voiceState = this.voiceState; if (voiceState) { return voiceState.channel; } return null; } get voiceState() { return this.client.voiceStates.get(this.guildId, this.id) || null; } avatarUrlFormat(format, query) { if (!this.avatar) { return this.user.avatarUrlFormat(format, query); } const hash = this.avatar; format = utils_1.getFormatFromHash(hash, format, this.client.imageFormat); return utils_1.addQuery(detritus_client_rest_1.Endpoints.CDN.URL + detritus_client_rest_1.Endpoints.CDN.GUILD_USER_AVATAR(this.guildId, this.id, hash, format), query); } can(permissions, options = {}) { const guild = this.guild; if (guild) { return guild.can(permissions, this, options); } return utils_1.PermissionTools.checkPermissions(this.permissions, permissions); } /* just checks who has the higher role, doesn't check permissions */ canEdit(member) { if (this.isOwner) { return true; } if (member.isOwner) { return false; } if (this.id === member.id) { return true; } const us = this.highestRole; const them = member.highestRole; if (us && them) { return them.position < us.position; } return false; } /* doesnt do any permission checks */ canEditRole(roleId) { let role; if (roleId instanceof role_1.Role) { role = roleId; } else { if (this.client.roles.has(this.guildId, roleId)) { role = this.client.roles.get(this.guildId, roleId); } else { return false; } } const us = this.highestRole; if (us) { return role.position < us.position; } return false; } permissionsIn(channelId) { let channel; if (channelId instanceof channel_1.ChannelBase) { channel = channelId; } else { if (this.client.channels.has(channelId)) { channel = this.client.channels.get(channelId); } else { return constants_1.Permissions.NONE; } } const guildId = channel.guildId || ''; let total = this.permissions; if (channel.permissionOverwrites.has(guildId)) { const overwrite = channel.permissionOverwrites.get(guildId); total = (total & ~overwrite.deny) | overwrite.allow; } let allow = constants_1.Permissions.NONE, deny = constants_1.Permissions.NONE; for (let [roleId, role] of this.roles) { if (roleId === this.guildId) { continue; } if (channel.permissionOverwrites.has(roleId)) { const overwrite = channel.permissionOverwrites.get(roleId); allow |= overwrite.allow; deny |= overwrite.deny; } } total = (total & ~deny) | allow; if (channel.permissionOverwrites.has(this.id)) { const overwrite = channel.permissionOverwrites.get(this.id); total = (total & ~overwrite.deny) | overwrite.allow; } return total; } addRole(roleId, options = {}) { return this.client.rest.addGuildMemberRole(this.guildId, this.id, roleId, options); } ban(options = {}) { return this.client.rest.createGuildBan(this.guildId, this.id, options); } edit(options = {}) { return this.client.rest.editGuildMember(this.guildId, this.id, options); } editNick(nick, options = {}) { if (this.isMe) { return this.client.rest.editGuildNick(this.guildId, nick, options); } return this.edit({ ...options, nick }); } editVoiceState(options) { const userId = (this.isMe) ? '@me' : this.id; return this.client.rest.editGuildVoiceState(this.guildId, userId, options); } move(channelId, options = {}) { return this.edit({ ...options, channelId }); } remove(options = {}) { return this.client.rest.removeGuildMember(this.guildId, this.id, options); } removeBan(options = {}) { return this.client.rest.removeGuildBan(this.guildId, this.id, options); } removeRole(roleId, options = {}) { return this.client.rest.removeGuildMemberRole(this.guildId, this.id, roleId, options); } setDeaf(deaf, options = {}) { return this.edit({ ...options, deaf }); } setMute(mute, options = {}) { return this.edit({ ...options, mute }); } difference(key, value) { let differences; switch (key) { case constants_1.DiscordKeys.HOISTED_ROLE: { if (this.hasDifference(key, value)) { differences = this.hoistedRoleId; } } ; break; case constants_1.DiscordKeys.ROLES: { if (this.hasDifference(key, value)) { differences = this._roles || []; } } ; break; default: { return super.difference(key, value); } ; } if (differences !== undefined) { return [true, differences]; } return [false, null]; } hasDifference(key, value) { switch (key) { case constants_1.DiscordKeys.HOISTED_ROLE: { return (this.hoistedRoleId !== value); } ; case constants_1.DiscordKeys.ROLES: { const old = this._roles; if (old) { return (old.length !== value.length) || !value.every((roleId) => old.includes(roleId)); } else { return value.length !== 0; } } ; } return super.hasDifference(key, value); } mergeValue(key, value) { if (value === undefined) { switch (key) { case constants_1.DiscordKeys.HOISTED_ROLE: { // find the hoisted role since we got the member from rest or an interaction (which wont give us a hoisted role value) const hoistedRole = this.roles.filter((x) => !!x).sort((x, y) => y.position - x.position).find((x) => x.hoist); if (hoistedRole) { this.hoistedRoleId = hoistedRole.id; } } ; return; } } else { switch (key) { case constants_1.DiscordKeys.AVATAR: { this._avatar = value; } ; return; case constants_1.DiscordKeys.HOISTED_ROLE: { this.hoistedRoleId = value; } ; return; case constants_1.DiscordKeys.JOINED_AT: { this.joinedAtUnix = (value) ? (new Date(value).getTime()) : 0; } ; return; case constants_1.DiscordKeys.PERMISSIONS: { this._permissions = BigInt(value); } ; return; case constants_1.DiscordKeys.PREMIUM_SINCE: { this.premiumSinceUnix = (value) ? (new Date(value).getTime()) : 0; } ; return; case constants_1.DiscordKeys.ROLES: { if (value.length) { this._roles = value; } else { this._roles = undefined; } } ; return; case constants_1.DiscordKeys.USER: { let user; if (this.isClone) { user = new user_1.User(this.client, value, this.isClone); } else { if (this.client.users.has(value.id)) { user = this.client.users.get(value.id); user.merge(value); } else { user = new user_1.User(this.client, value); this.client.users.insert(user); } } value = user; } ; break; } return super.mergeValue(key, value); } } toJSON(withRoles) { const data = super.toJSON(); if (!withRoles) { if (constants_1.DiscordKeys.HOISTED_ROLE in data) { data[constants_1.DiscordKeys.HOISTED_ROLE] = this.hoistedRoleId; } if (constants_1.DiscordKeys.ROLES in data) { data[constants_1.DiscordKeys.ROLES] = Array.from(this.roles.keys()); } } return data; } } exports.Member = Member;