From d35e0862e6b60fe3c4f823371627359f3ce3e68b Mon Sep 17 00:00:00 2001 From: Alee14 Date: Fri, 28 Jul 2017 16:20:27 -0400 Subject: Removing node modules (go get them yourself :P) --- node_modules/discord.js/src/structures/Channel.js | 67 -- .../src/structures/ClientOAuth2Application.js | 26 - .../discord.js/src/structures/ClientUser.js | 274 ------- .../discord.js/src/structures/DMChannel.js | 60 -- node_modules/discord.js/src/structures/Emoji.js | 140 ---- .../src/structures/EvaluatedPermissions.js | 67 -- .../discord.js/src/structures/GroupDMChannel.js | 144 ---- node_modules/discord.js/src/structures/Guild.js | 851 --------------------- .../discord.js/src/structures/GuildChannel.js | 299 -------- .../discord.js/src/structures/GuildMember.js | 442 ----------- node_modules/discord.js/src/structures/Invite.js | 159 ---- node_modules/discord.js/src/structures/Message.js | 568 -------------- .../discord.js/src/structures/MessageAttachment.js | 68 -- .../discord.js/src/structures/MessageCollector.js | 151 ---- .../discord.js/src/structures/MessageEmbed.js | 293 ------- .../discord.js/src/structures/MessageReaction.js | 92 --- .../discord.js/src/structures/OAuth2Application.js | 82 -- .../discord.js/src/structures/PartialGuild.js | 51 -- .../src/structures/PartialGuildChannel.js | 44 -- .../src/structures/PermissionOverwrites.js | 43 -- node_modules/discord.js/src/structures/Presence.js | 92 --- .../discord.js/src/structures/ReactionEmoji.js | 49 -- .../discord.js/src/structures/RichEmbed.js | 204 ----- node_modules/discord.js/src/structures/Role.js | 341 --------- .../discord.js/src/structures/TextChannel.js | 96 --- node_modules/discord.js/src/structures/User.js | 277 ------- .../discord.js/src/structures/UserConnection.js | 48 -- .../discord.js/src/structures/UserProfile.js | 56 -- .../discord.js/src/structures/VoiceChannel.js | 120 --- node_modules/discord.js/src/structures/Webhook.js | 200 ----- .../src/structures/interface/TextBasedChannel.js | 377 --------- 31 files changed, 5781 deletions(-) delete mode 100644 node_modules/discord.js/src/structures/Channel.js delete mode 100644 node_modules/discord.js/src/structures/ClientOAuth2Application.js delete mode 100644 node_modules/discord.js/src/structures/ClientUser.js delete mode 100644 node_modules/discord.js/src/structures/DMChannel.js delete mode 100644 node_modules/discord.js/src/structures/Emoji.js delete mode 100644 node_modules/discord.js/src/structures/EvaluatedPermissions.js delete mode 100644 node_modules/discord.js/src/structures/GroupDMChannel.js delete mode 100644 node_modules/discord.js/src/structures/Guild.js delete mode 100644 node_modules/discord.js/src/structures/GuildChannel.js delete mode 100644 node_modules/discord.js/src/structures/GuildMember.js delete mode 100644 node_modules/discord.js/src/structures/Invite.js delete mode 100644 node_modules/discord.js/src/structures/Message.js delete mode 100644 node_modules/discord.js/src/structures/MessageAttachment.js delete mode 100644 node_modules/discord.js/src/structures/MessageCollector.js delete mode 100644 node_modules/discord.js/src/structures/MessageEmbed.js delete mode 100644 node_modules/discord.js/src/structures/MessageReaction.js delete mode 100644 node_modules/discord.js/src/structures/OAuth2Application.js delete mode 100644 node_modules/discord.js/src/structures/PartialGuild.js delete mode 100644 node_modules/discord.js/src/structures/PartialGuildChannel.js delete mode 100644 node_modules/discord.js/src/structures/PermissionOverwrites.js delete mode 100644 node_modules/discord.js/src/structures/Presence.js delete mode 100644 node_modules/discord.js/src/structures/ReactionEmoji.js delete mode 100644 node_modules/discord.js/src/structures/RichEmbed.js delete mode 100644 node_modules/discord.js/src/structures/Role.js delete mode 100644 node_modules/discord.js/src/structures/TextChannel.js delete mode 100644 node_modules/discord.js/src/structures/User.js delete mode 100644 node_modules/discord.js/src/structures/UserConnection.js delete mode 100644 node_modules/discord.js/src/structures/UserProfile.js delete mode 100644 node_modules/discord.js/src/structures/VoiceChannel.js delete mode 100644 node_modules/discord.js/src/structures/Webhook.js delete mode 100644 node_modules/discord.js/src/structures/interface/TextBasedChannel.js (limited to 'node_modules/discord.js/src/structures') diff --git a/node_modules/discord.js/src/structures/Channel.js b/node_modules/discord.js/src/structures/Channel.js deleted file mode 100644 index b37b14b..0000000 --- a/node_modules/discord.js/src/structures/Channel.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Represents any channel on Discord - */ -class Channel { - constructor(client, data) { - /** - * The client that instantiated the Channel - * @name Channel#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * The type of the channel, either: - * * `dm` - a DM channel - * * `group` - a Group DM channel - * * `text` - a guild text channel - * * `voice` - a guild voice channel - * @type {string} - */ - this.type = null; - - if (data) this.setup(data); - } - - setup(data) { - /** - * The unique ID of the channel - * @type {string} - */ - this.id = data.id; - } - - /** - * The timestamp the channel was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the channel was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * Deletes the channel - * @returns {Promise} - * @example - * // delete the channel - * channel.delete() - * .then() // success - * .catch(console.error); // log error - */ - delete() { - return this.client.rest.methods.deleteChannel(this); - } -} - -module.exports = Channel; diff --git a/node_modules/discord.js/src/structures/ClientOAuth2Application.js b/node_modules/discord.js/src/structures/ClientOAuth2Application.js deleted file mode 100644 index 46e1250..0000000 --- a/node_modules/discord.js/src/structures/ClientOAuth2Application.js +++ /dev/null @@ -1,26 +0,0 @@ -const User = require('./User'); -const OAuth2Application = require('./OAuth2Application'); - -/** - * Represents the client's OAuth2 Application - * @extends {OAuth2Application} - */ -class ClientOAuth2Application extends OAuth2Application { - setup(data) { - super.setup(data); - - /** - * The app's flags - * @type {number} - */ - this.flags = data.flags; - - /** - * The app's owner - * @type {User} - */ - this.owner = new User(this.client, data.owner); - } -} - -module.exports = ClientOAuth2Application; diff --git a/node_modules/discord.js/src/structures/ClientUser.js b/node_modules/discord.js/src/structures/ClientUser.js deleted file mode 100644 index d526af6..0000000 --- a/node_modules/discord.js/src/structures/ClientUser.js +++ /dev/null @@ -1,274 +0,0 @@ -const User = require('./User'); -const Collection = require('../util/Collection'); - -/** - * Represents the logged in client's Discord user - * @extends {User} - */ -class ClientUser extends User { - setup(data) { - super.setup(data); - - /** - * Whether or not this account has been verified - * @type {boolean} - */ - this.verified = data.verified; - - /** - * The email of this account - * @type {string} - */ - this.email = data.email; - this.localPresence = {}; - this._typing = new Map(); - - /** - * A Collection of friends for the logged in user. - * This is only filled when using a user account. - * @type {Collection} - */ - this.friends = new Collection(); - - /** - * A Collection of blocked users for the logged in user. - * This is only filled when using a user account. - * @type {Collection} - */ - this.blocked = new Collection(); - - /** - * A Collection of notes for the logged in user. - * This is only filled when using a user account. - * @type {Collection} - */ - this.notes = new Collection(); - } - - edit(data) { - return this.client.rest.methods.updateCurrentUser(data); - } - - /** - * Set the username of the logged in Client. - * Changing usernames in Discord is heavily rate limited, with only 2 requests - * every hour. Use this sparingly! - * @param {string} username The new username - * @param {string} [password] Current password (only for user accounts) - * @returns {Promise} - * @example - * // set username - * client.user.setUsername('discordjs') - * .then(user => console.log(`My new username is ${user.username}`)) - * .catch(console.error); - */ - setUsername(username, password) { - return this.client.rest.methods.updateCurrentUser({ username }, password); - } - - /** - * Changes the email for the client user's account. - * This is only available when using a user account. - * @param {string} email New email to change to - * @param {string} password Current password - * @returns {Promise} - * @example - * // set email - * client.user.setEmail('bob@gmail.com', 'some amazing password 123') - * .then(user => console.log(`My new email is ${user.email}`)) - * .catch(console.error); - */ - setEmail(email, password) { - return this.client.rest.methods.updateCurrentUser({ email }, password); - } - - /** - * Changes the password for the client user's account. - * This is only available when using a user account. - * @param {string} newPassword New password to change to - * @param {string} oldPassword Current password - * @returns {Promise} - * @example - * // set password - * client.user.setPassword('some new amazing password 456', 'some amazing password 123') - * .then(user => console.log('New password set!')) - * .catch(console.error); - */ - setPassword(newPassword, oldPassword) { - return this.client.rest.methods.updateCurrentUser({ password: newPassword }, oldPassword); - } - - /** - * Set the avatar of the logged in Client. - * @param {BufferResolvable|Base64Resolvable} avatar The new avatar - * @returns {Promise} - * @example - * // set avatar - * client.user.setAvatar('./avatar.png') - * .then(user => console.log(`New avatar set!`)) - * .catch(console.error); - */ - setAvatar(avatar) { - if (avatar.startsWith('data:')) { - return this.client.rest.methods.updateCurrentUser({ avatar }); - } else { - return this.client.resolver.resolveBuffer(avatar).then(data => - this.client.rest.methods.updateCurrentUser({ avatar: data }) - ); - } - } - - /** - * Data resembling a raw Discord presence - * @typedef {Object} PresenceData - * @property {PresenceStatus} [status] Status of the user - * @property {boolean} [afk] Whether the user is AFK - * @property {Object} [game] Game the user is playing - * @property {string} [game.name] Name of the game - * @property {string} [game.url] Twitch stream URL - */ - - /** - * Sets the full presence of the client user. - * @param {PresenceData} data Data for the presence - * @returns {Promise} - */ - setPresence(data) { - // {"op":3,"d":{"status":"dnd","since":0,"game":null,"afk":false}} - return new Promise(resolve => { - let status = this.localPresence.status || this.presence.status; - let game = this.localPresence.game; - let afk = this.localPresence.afk || this.presence.afk; - - if (!game && this.presence.game) { - game = { - name: this.presence.game.name, - type: this.presence.game.type, - url: this.presence.game.url, - }; - } - - if (data.status) { - if (typeof data.status !== 'string') throw new TypeError('Status must be a string'); - status = data.status; - } - - if (data.game) { - game = data.game; - if (game.url) game.type = 1; - } - - if (typeof data.afk !== 'undefined') afk = data.afk; - afk = Boolean(afk); - - this.localPresence = { status, game, afk }; - this.localPresence.since = 0; - this.localPresence.game = this.localPresence.game || null; - - this.client.ws.send({ - op: 3, - d: this.localPresence, - }); - - this.client._setPresence(this.id, this.localPresence); - - resolve(this); - }); - } - - /** - * A user's status. Must be one of: - * - `online` - * - `idle` - * - `invisible` - * - `dnd` (do not disturb) - * @typedef {string} PresenceStatus - */ - - /** - * Sets the status of the client user. - * @param {PresenceStatus} status Status to change to - * @returns {Promise} - */ - setStatus(status) { - return this.setPresence({ status }); - } - - /** - * Sets the game the client user is playing. - * @param {string} game Game being played - * @param {string} [streamingURL] Twitch stream URL - * @returns {Promise} - */ - setGame(game, streamingURL) { - return this.setPresence({ game: { - name: game, - url: streamingURL, - } }); - } - - /** - * Sets/removes the AFK flag for the client user. - * @param {boolean} afk Whether or not the user is AFK - * @returns {Promise} - */ - setAFK(afk) { - return this.setPresence({ afk }); - } - - /** - * Fetches messages that mentioned the client's user - * @param {Object} [options] Options for the fetch - * @param {number} [options.limit=25] Maximum number of mentions to retrieve - * @param {boolean} [options.roles=true] Whether to include role mentions - * @param {boolean} [options.everyone=true] Whether to include everyone/here mentions - * @param {Guild|string} [options.guild] Limit the search to a specific guild - * @returns {Promise} - */ - fetchMentions(options = { limit: 25, roles: true, everyone: true, guild: null }) { - return this.client.rest.methods.fetchMentions(options); - } - - /** - * Send a friend request - * This is only available when using a user account. - * @param {UserResolvable} user The user to send the friend request to. - * @returns {Promise} The user the friend request was sent to. - */ - addFriend(user) { - user = this.client.resolver.resolveUser(user); - return this.client.rest.methods.addFriend(user); - } - - /** - * Remove a friend - * This is only available when using a user account. - * @param {UserResolvable} user The user to remove from your friends - * @returns {Promise} The user that was removed - */ - removeFriend(user) { - user = this.client.resolver.resolveUser(user); - return this.client.rest.methods.removeFriend(user); - } - - /** - * Creates a guild - * This is only available when using a user account. - * @param {string} name The name of the guild - * @param {string} region The region for the server - * @param {BufferResolvable|Base64Resolvable} [icon=null] The icon for the guild - * @returns {Promise} The guild that was created - */ - createGuild(name, region, icon = null) { - if (!icon) return this.client.rest.methods.createGuild({ name, icon, region }); - if (icon.startsWith('data:')) { - return this.client.rest.methods.createGuild({ name, icon, region }); - } else { - return this.client.resolver.resolveBuffer(icon).then(data => - this.client.rest.methods.createGuild({ name, icon: data, region }) - ); - } - } -} - -module.exports = ClientUser; diff --git a/node_modules/discord.js/src/structures/DMChannel.js b/node_modules/discord.js/src/structures/DMChannel.js deleted file mode 100644 index de49c8b..0000000 --- a/node_modules/discord.js/src/structures/DMChannel.js +++ /dev/null @@ -1,60 +0,0 @@ -const Channel = require('./Channel'); -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Collection = require('../util/Collection'); - -/** - * Represents a direct message channel between two users. - * @extends {Channel} - * @implements {TextBasedChannel} - */ -class DMChannel extends Channel { - constructor(client, data) { - super(client, data); - this.type = 'dm'; - this.messages = new Collection(); - this._typing = new Map(); - } - - setup(data) { - super.setup(data); - - /** - * The recipient on the other end of the DM - * @type {User} - */ - this.recipient = this.client.dataManager.newUser(data.recipients[0]); - - this.lastMessageID = data.last_message_id; - } - - /** - * When concatenated with a string, this automatically concatenates the recipient's mention instead of the - * DM channel object. - * @returns {string} - */ - toString() { - return this.recipient.toString(); - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } - fetchMessage() { return; } - fetchMessages() { return; } - fetchPinnedMessages() { return; } - startTyping() { return; } - stopTyping() { return; } - get typing() { return; } - get typingCount() { return; } - createCollector() { return; } - awaitMessages() { return; } - bulkDelete() { return; } - _cacheMessage() { return; } -} - -TextBasedChannel.applyToClass(DMChannel, true); - -module.exports = DMChannel; diff --git a/node_modules/discord.js/src/structures/Emoji.js b/node_modules/discord.js/src/structures/Emoji.js deleted file mode 100644 index d8a62e1..0000000 --- a/node_modules/discord.js/src/structures/Emoji.js +++ /dev/null @@ -1,140 +0,0 @@ -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); - -/** - * Represents a custom emoji - */ -class Emoji { - constructor(guild, data) { - /** - * The Client that instantiated this object - * @name Emoji#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: guild.client }); - - /** - * The guild this emoji is part of - * @type {Guild} - */ - this.guild = guild; - - this.setup(data); - } - - setup(data) { - /** - * The ID of the emoji - * @type {string} - */ - this.id = data.id; - - /** - * The name of the emoji - * @type {string} - */ - this.name = data.name; - - /** - * Whether or not this emoji requires colons surrounding it - * @type {boolean} - */ - this.requiresColons = data.require_colons; - - /** - * Whether this emoji is managed by an external service - * @type {boolean} - */ - this.managed = data.managed; - - this._roles = data.roles; - } - - /** - * The timestamp the emoji was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the emoji was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * A collection of roles this emoji is active for (empty if all), mapped by role ID. - * @type {Collection} - * @readonly - */ - get roles() { - const roles = new Collection(); - for (const role of this._roles) { - if (this.guild.roles.has(role)) roles.set(role, this.guild.roles.get(role)); - } - return roles; - } - - /** - * The URL to the emoji file - * @type {string} - * @readonly - */ - get url() { - return Constants.Endpoints.emoji(this.id); - } - - /** - * When concatenated with a string, this automatically returns the emoji mention rather than the object. - * @returns {string} - * @example - * // send an emoji: - * const emoji = guild.emojis.first(); - * msg.reply(`Hello! ${emoji}`); - */ - toString() { - return this.requiresColons ? `<:${this.name}:${this.id}>` : this.name; - } - - /** - * Whether this emoji is the same as another one - * @param {Emoji|Object} other the emoji to compare it to - * @returns {boolean} whether the emoji is equal to the given emoji or not - */ - equals(other) { - if (other instanceof Emoji) { - return ( - other.id === this.id && - other.name === this.name && - other.managed === this.managed && - other.requiresColons === this.requiresColons - ); - } else { - return ( - other.id === this.id && - other.name === this.name - ); - } - } - - /** - * The identifier of this emoji, used for message reactions - * @readonly - * @type {string} - */ - get identifier() { - if (this.id) { - return `${this.name}:${this.id}`; - } - return encodeURIComponent(this.name); - } -} - -module.exports = Emoji; diff --git a/node_modules/discord.js/src/structures/EvaluatedPermissions.js b/node_modules/discord.js/src/structures/EvaluatedPermissions.js deleted file mode 100644 index ae8a643..0000000 --- a/node_modules/discord.js/src/structures/EvaluatedPermissions.js +++ /dev/null @@ -1,67 +0,0 @@ -const Constants = require('../util/Constants'); - -/** - * The final evaluated permissions for a member in a channel - */ -class EvaluatedPermissions { - constructor(member, raw) { - /** - * The member this permissions refer to - * @type {GuildMember} - */ - this.member = member; - - /** - * A number representing the packed permissions - * @type {number} - */ - this.raw = raw; - } - - /** - * Get an object mapping permission name, e.g. `READ_MESSAGES` to a boolean - whether the user - * can perform this or not. - * @returns {Object} - */ - serialize() { - const serializedPermissions = {}; - for (const permissionName in Constants.PermissionFlags) { - serializedPermissions[permissionName] = this.hasPermission(permissionName); - } - return serializedPermissions; - } - - /** - * Checks whether the user has a certain permission, e.g. `READ_MESSAGES`. - * @param {PermissionResolvable} permission The permission to check for - * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permission - * @returns {boolean} - */ - hasPermission(permission, explicit = false) { - permission = this.member.client.resolver.resolvePermission(permission); - if (!explicit && (this.raw & Constants.PermissionFlags.ADMINISTRATOR) > 0) return true; - return (this.raw & permission) > 0; - } - - /** - * Checks whether the user has all specified permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permissions - * @returns {boolean} - */ - hasPermissions(permissions, explicit = false) { - return permissions.every(p => this.hasPermission(p, explicit)); - } - - /** - * Checks whether the user has all specified permissions, and lists any missing permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the user to explicitly have the exact permissions - * @returns {PermissionResolvable[]} - */ - missingPermissions(permissions, explicit = false) { - return permissions.filter(p => !this.hasPermission(p, explicit)); - } -} - -module.exports = EvaluatedPermissions; diff --git a/node_modules/discord.js/src/structures/GroupDMChannel.js b/node_modules/discord.js/src/structures/GroupDMChannel.js deleted file mode 100644 index 84fe4f9..0000000 --- a/node_modules/discord.js/src/structures/GroupDMChannel.js +++ /dev/null @@ -1,144 +0,0 @@ -const Channel = require('./Channel'); -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Collection = require('../util/Collection'); - -/* -{ type: 3, - recipients: - [ { username: 'Charlie', - id: '123', - discriminator: '6631', - avatar: '123' }, - { username: 'Ben', - id: '123', - discriminator: '2055', - avatar: '123' }, - { username: 'Adam', - id: '123', - discriminator: '2406', - avatar: '123' } ], - owner_id: '123', - name: null, - last_message_id: '123', - id: '123', - icon: null } -*/ - -/** - * Represents a Group DM on Discord - * @extends {Channel} - * @implements {TextBasedChannel} - */ -class GroupDMChannel extends Channel { - constructor(client, data) { - super(client, data); - this.type = 'group'; - this.messages = new Collection(); - this._typing = new Map(); - } - - setup(data) { - super.setup(data); - - /** - * The name of this Group DM, can be null if one isn't set. - * @type {string} - */ - this.name = data.name; - - /** - * A hash of the Group DM icon. - * @type {string} - */ - this.icon = data.icon; - - /** - * The user ID of this Group DM's owner. - * @type {string} - */ - this.ownerID = data.owner_id; - - if (!this.recipients) { - /** - * A collection of the recipients of this DM, mapped by their ID. - * @type {Collection} - */ - this.recipients = new Collection(); - } - - if (data.recipients) { - for (const recipient of data.recipients) { - const user = this.client.dataManager.newUser(recipient); - this.recipients.set(user.id, user); - } - } - - this.lastMessageID = data.last_message_id; - } - - /** - * The owner of this Group DM. - * @type {User} - * @readonly - */ - get owner() { - return this.client.users.get(this.ownerID); - } - - /** - * Whether this channel equals another channel. It compares all properties, so for most operations - * it is advisable to just compare `channel.id === channel2.id` as it is much faster and is often - * what most users need. - * @param {GroupDMChannel} channel Channel to compare with - * @returns {boolean} - */ - equals(channel) { - const equal = channel && - this.id === channel.id && - this.name === channel.name && - this.icon === channel.icon && - this.ownerID === channel.ownerID; - - if (equal) { - return this.recipients.equals(channel.recipients); - } - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the channel's name instead of the Channel object. - * @returns {string} - * @example - * // logs: Hello from My Group DM! - * console.log(`Hello from ${channel}!`); - * @example - * // logs: Hello from My Group DM! - * console.log(`Hello from ' + channel + '!'); - */ - toString() { - return this.name; - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } - fetchMessage() { return; } - fetchMessages() { return; } - fetchPinnedMessages() { return; } - startTyping() { return; } - stopTyping() { return; } - get typing() { return; } - get typingCount() { return; } - createCollector() { return; } - awaitMessages() { return; } - bulkDelete() { return; } - _cacheMessage() { return; } -} - -TextBasedChannel.applyToClass(GroupDMChannel, true); - -module.exports = GroupDMChannel; diff --git a/node_modules/discord.js/src/structures/Guild.js b/node_modules/discord.js/src/structures/Guild.js deleted file mode 100644 index acd5b6f..0000000 --- a/node_modules/discord.js/src/structures/Guild.js +++ /dev/null @@ -1,851 +0,0 @@ -const User = require('./User'); -const Role = require('./Role'); -const Emoji = require('./Emoji'); -const Presence = require('./Presence').Presence; -const GuildMember = require('./GuildMember'); -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); -const cloneObject = require('../util/CloneObject'); -const arraysEqual = require('../util/ArraysEqual'); - -/** - * Represents a guild (or a server) on Discord. - * It's recommended to see if a guild is available before performing operations or reading data from it. You can - * check this with `guild.available`. - */ -class Guild { - constructor(client, data) { - /** - * The Client that created the instance of the the Guild. - * @name Guild#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * A collection of members that are in this guild. The key is the member's ID, the value is the member. - * @type {Collection} - */ - this.members = new Collection(); - - /** - * A collection of channels that are in this guild. The key is the channel's ID, the value is the channel. - * @type {Collection} - */ - this.channels = new Collection(); - - /** - * A collection of roles that are in this guild. The key is the role's ID, the value is the role. - * @type {Collection} - */ - this.roles = new Collection(); - - /** - * A collection of presences in this guild - * @type {Collection} - */ - this.presences = new Collection(); - - if (!data) return; - if (data.unavailable) { - /** - * Whether the guild is available to access. If it is not available, it indicates a server outage. - * @type {boolean} - */ - this.available = false; - - /** - * The Unique ID of the Guild, useful for comparisons. - * @type {string} - */ - this.id = data.id; - } else { - this.available = true; - this.setup(data); - } - } - - /** - * Sets up the Guild - * @param {*} data The raw data of the guild - * @private - */ - setup(data) { - /** - * The name of the guild - * @type {string} - */ - this.name = data.name; - - /** - * The hash of the guild icon, or null if there is no icon. - * @type {?string} - */ - this.icon = data.icon; - - /** - * The hash of the guild splash image, or null if no splash (VIP only) - * @type {?string} - */ - this.splash = data.splash; - - /** - * The region the guild is located in - * @type {string} - */ - this.region = data.region; - - /** - * The full amount of members in this guild as of `READY` - * @type {number} - */ - this.memberCount = data.member_count || this.memberCount; - - /** - * Whether the guild is "large" (has more than 250 members) - * @type {boolean} - */ - this.large = data.large || this.large; - - /** - * An array of guild features. - * @type {Object[]} - */ - this.features = data.features; - - /** - * The ID of the application that created this guild (if applicable) - * @type {?string} - */ - this.applicationID = data.application_id; - - /** - * A collection of emojis that are in this guild. The key is the emoji's ID, the value is the emoji. - * @type {Collection} - */ - this.emojis = new Collection(); - for (const emoji of data.emojis) this.emojis.set(emoji.id, new Emoji(this, emoji)); - - /** - * The time in seconds before a user is counted as "away from keyboard". - * @type {?number} - */ - this.afkTimeout = data.afk_timeout; - - /** - * The ID of the voice channel where AFK members are moved. - * @type {?string} - */ - this.afkChannelID = data.afk_channel_id; - - /** - * Whether embedded images are enabled on this guild. - * @type {boolean} - */ - this.embedEnabled = data.embed_enabled; - - /** - * The verification level of the guild. - * @type {number} - */ - this.verificationLevel = data.verification_level; - - /** - * The timestamp the client user joined the guild at - * @type {number} - */ - this.joinedTimestamp = data.joined_at ? new Date(data.joined_at).getTime() : this.joinedTimestamp; - - this.id = data.id; - this.available = !data.unavailable; - this.features = data.features || this.features || []; - - if (data.members) { - this.members.clear(); - for (const guildUser of data.members) this._addMember(guildUser, false); - } - - if (data.owner_id) { - /** - * The user ID of this guild's owner. - * @type {string} - */ - this.ownerID = data.owner_id; - } - - if (data.channels) { - this.channels.clear(); - for (const channel of data.channels) this.client.dataManager.newChannel(channel, this); - } - - if (data.roles) { - this.roles.clear(); - for (const role of data.roles) { - const newRole = new Role(this, role); - this.roles.set(newRole.id, newRole); - } - } - - if (data.presences) { - for (const presence of data.presences) { - this._setPresence(presence.user.id, presence); - } - } - - this._rawVoiceStates = new Collection(); - if (data.voice_states) { - for (const voiceState of data.voice_states) { - this._rawVoiceStates.set(voiceState.user_id, voiceState); - const member = this.members.get(voiceState.user_id); - if (member) { - member.serverMute = voiceState.mute; - member.serverDeaf = voiceState.deaf; - member.selfMute = voiceState.self_mute; - member.selfDeaf = voiceState.self_deaf; - member.voiceSessionID = voiceState.session_id; - member.voiceChannelID = voiceState.channel_id; - this.channels.get(voiceState.channel_id).members.set(member.user.id, member); - } - } - } - } - - /** - * The timestamp the guild was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the guild was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The time the client user joined the guild - * @type {Date} - * @readonly - */ - get joinedAt() { - return new Date(this.joinedTimestamp); - } - - /** - * Gets the URL to this guild's icon (if it has one, otherwise it returns null) - * @type {?string} - * @readonly - */ - get iconURL() { - if (!this.icon) return null; - return Constants.Endpoints.guildIcon(this.id, this.icon); - } - - /** - * Gets the URL to this guild's splash (if it has one, otherwise it returns null) - * @type {?string} - * @readonly - */ - get splashURL() { - if (!this.splash) return null; - return Constants.Endpoints.guildSplash(this.id, this.splash); - } - - /** - * The owner of the guild - * @type {GuildMember} - * @readonly - */ - get owner() { - return this.members.get(this.ownerID); - } - - /** - * If the client is connected to any voice channel in this guild, this will be the relevant VoiceConnection. - * @type {?VoiceConnection} - * @readonly - */ - get voiceConnection() { - if (this.client.browser) return null; - return this.client.voice.connections.get(this.id) || null; - } - - /** - * The `#general` GuildChannel of the server. - * @type {GuildChannel} - * @readonly - */ - get defaultChannel() { - return this.channels.get(this.id); - } - - /** - * Returns the GuildMember form of a User object, if the user is present in the guild. - * @param {UserResolvable} user The user that you want to obtain the GuildMember of - * @returns {?GuildMember} - * @example - * // get the guild member of a user - * const member = guild.member(message.author); - */ - member(user) { - return this.client.resolver.resolveGuildMember(this, user); - } - - /** - * Fetch a collection of banned users in this guild. - * @returns {Promise>} - */ - fetchBans() { - return this.client.rest.methods.getGuildBans(this); - } - - /** - * Fetch a collection of invites to this guild. Resolves with a collection mapping invites by their codes. - * @returns {Promise>} - */ - fetchInvites() { - return this.client.rest.methods.getGuildInvites(this); - } - - /** - * Fetch all webhooks for the guild. - * @returns {Collection} - */ - fetchWebhooks() { - return this.client.rest.methods.getGuildWebhooks(this); - } - - /** - * Fetch a single guild member from a user. - * @param {UserResolvable} user The user to fetch the member for - * @returns {Promise} - */ - fetchMember(user) { - if (this._fetchWaiter) return Promise.reject(new Error('Already fetching guild members.')); - user = this.client.resolver.resolveUser(user); - if (!user) return Promise.reject(new Error('User is not cached. Use Client.fetchUser first.')); - if (this.members.has(user.id)) return Promise.resolve(this.members.get(user.id)); - return this.client.rest.methods.getGuildMember(this, user); - } - - /** - * Fetches all the members in the guild, even if they are offline. If the guild has less than 250 members, - * this should not be necessary. - * @param {string} [query=''] An optional query to provide when fetching members - * @returns {Promise} - */ - fetchMembers(query = '') { - return new Promise((resolve, reject) => { - if (this._fetchWaiter) throw new Error('Already fetching guild members in ${this.id}.'); - if (this.memberCount === this.members.size) { - resolve(this); - return; - } - this._fetchWaiter = resolve; - this.client.ws.send({ - op: Constants.OPCodes.REQUEST_GUILD_MEMBERS, - d: { - guild_id: this.id, - query, - limit: 0, - }, - }); - this._checkChunks(); - this.client.setTimeout(() => reject(new Error('Members didn\'t arrive in time.')), 120 * 1000); - }); - } - - /** - * The data for editing a guild - * @typedef {Object} GuildEditData - * @property {string} [name] The name of the guild - * @property {string} [region] The region of the guild - * @property {number} [verificationLevel] The verification level of the guild - * @property {ChannelResolvable} [afkChannel] The AFK channel of the guild - * @property {number} [afkTimeout] The AFK timeout of the guild - * @property {Base64Resolvable} [icon] The icon of the guild - * @property {GuildMemberResolvable} [owner] The owner of the guild - * @property {Base64Resolvable} [splash] The splash screen of the guild - */ - - /** - * Updates the Guild with new information - e.g. a new name. - * @param {GuildEditData} data The data to update the guild with - * @returns {Promise} - * @example - * // set the guild name and region - * guild.edit({ - * name: 'Discord Guild', - * region: 'london', - * }) - * .then(updated => console.log(`New guild name ${updated.name} in region ${updated.region}`)) - * .catch(console.error); - */ - edit(data) { - return this.client.rest.methods.updateGuild(this, data); - } - - /** - * Edit the name of the guild. - * @param {string} name The new name of the guild - * @returns {Promise} - * @example - * // edit the guild name - * guild.setName('Discord Guild') - * .then(updated => console.log(`Updated guild name to ${guild.name}`)) - * .catch(console.error); - */ - setName(name) { - return this.edit({ name }); - } - - /** - * Edit the region of the guild. - * @param {string} region The new region of the guild. - * @returns {Promise} - * @example - * // edit the guild region - * guild.setRegion('london') - * .then(updated => console.log(`Updated guild region to ${guild.region}`)) - * .catch(console.error); - */ - setRegion(region) { - return this.edit({ region }); - } - - /** - * Edit the verification level of the guild. - * @param {number} verificationLevel The new verification level of the guild - * @returns {Promise} - * @example - * // edit the guild verification level - * guild.setVerificationLevel(1) - * .then(updated => console.log(`Updated guild verification level to ${guild.verificationLevel}`)) - * .catch(console.error); - */ - setVerificationLevel(verificationLevel) { - return this.edit({ verificationLevel }); - } - - /** - * Edit the AFK channel of the guild. - * @param {ChannelResolvable} afkChannel The new AFK channel - * @returns {Promise} - * @example - * // edit the guild AFK channel - * guild.setAFKChannel(channel) - * .then(updated => console.log(`Updated guild AFK channel to ${guild.afkChannel}`)) - * .catch(console.error); - */ - setAFKChannel(afkChannel) { - return this.edit({ afkChannel }); - } - - /** - * Edit the AFK timeout of the guild. - * @param {number} afkTimeout The time in seconds that a user must be idle to be considered AFK - * @returns {Promise} - * @example - * // edit the guild AFK channel - * guild.setAFKTimeout(60) - * .then(updated => console.log(`Updated guild AFK timeout to ${guild.afkTimeout}`)) - * .catch(console.error); - */ - setAFKTimeout(afkTimeout) { - return this.edit({ afkTimeout }); - } - - /** - * Set a new guild icon. - * @param {Base64Resolvable} icon The new icon of the guild - * @returns {Promise} - * @example - * // edit the guild icon - * guild.setIcon(fs.readFileSync('./icon.png')) - * .then(updated => console.log('Updated the guild icon')) - * .catch(console.error); - */ - setIcon(icon) { - return this.edit({ icon }); - } - - /** - * Sets a new owner of the guild. - * @param {GuildMemberResolvable} owner The new owner of the guild - * @returns {Promise} - * @example - * // edit the guild owner - * guild.setOwner(guilds.members[0]) - * .then(updated => console.log(`Updated the guild owner to ${updated.owner.username}`)) - * .catch(console.error); - */ - setOwner(owner) { - return this.edit({ owner }); - } - - /** - * Set a new guild splash screen. - * @param {Base64Resolvable} splash The new splash screen of the guild - * @returns {Promise} - * @example - * // edit the guild splash - * guild.setIcon(fs.readFileSync('./splash.png')) - * .then(updated => console.log('Updated the guild splash')) - * .catch(console.error); - */ - setSplash(splash) { - return this.edit({ splash }); - } - - /** - * Bans a user from the guild. - * @param {UserResolvable} user The user to ban - * @param {number} [deleteDays=0] The amount of days worth of messages from this user that should - * also be deleted. Between `0` and `7`. - * @returns {Promise} 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 - * guild.ban('123123123123'); - */ - ban(user, deleteDays = 0) { - return this.client.rest.methods.banGuildMember(this, user, deleteDays); - } - - /** - * Unbans a user from the guild. - * @param {UserResolvable} user The user to unban - * @returns {Promise} - * @example - * // unban a user - * guild.unban('123123123123') - * .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`)) - * .catch(reject); - */ - unban(user) { - return this.client.rest.methods.unbanGuildMember(this, user); - } - - /** - * Prunes members from the guild based on how long they have been inactive. - * @param {number} days Number of days of inactivity required to kick - * @param {boolean} [dry=false] If true, will return number of users that will be kicked, without actually doing it - * @returns {Promise} The number of members that were/will be kicked - * @example - * // see how many members will be pruned - * guild.pruneMembers(12, true) - * .then(pruned => console.log(`This will prune ${pruned} people!`); - * .catch(console.error); - * @example - * // actually prune the members - * guild.pruneMembers(12) - * .then(pruned => console.log(`I just pruned ${pruned} people!`); - * .catch(console.error); - */ - pruneMembers(days, dry = false) { - if (typeof days !== 'number') throw new TypeError('Days must be a number.'); - return this.client.rest.methods.pruneGuildMembers(this, days, dry); - } - - /** - * Syncs this guild (already done automatically every 30 seconds). - * This is only available when using a user account. - */ - sync() { - if (!this.client.user.bot) this.client.syncGuilds([this]); - } - - /** - * Creates a new channel in the guild. - * @param {string} name The name of the new channel - * @param {string} type The type of the new channel, either `text` or `voice` - * @param {Array} overwrites Permission overwrites to apply to the new channel - * @returns {Promise} - * @example - * // create a new text channel - * guild.createChannel('new-general', 'text') - * .then(channel => console.log(`Created new channel ${channel}`)) - * .catch(console.error); - */ - createChannel(name, type, overwrites) { - return this.client.rest.methods.createChannel(this, name, type, overwrites); - } - - /** - * Creates a new role in the guild, and optionally updates it with the given information. - * @param {RoleData} [data] The data to update the role with - * @returns {Promise} - * @example - * // create a new role - * guild.createRole() - * .then(role => console.log(`Created role ${role}`)) - * .catch(console.error); - * @example - * // create a new role with data - * guild.createRole({ name: 'Super Cool People' }) - * .then(role => console.log(`Created role ${role}`)) - * .catch(console.error) - */ - createRole(data) { - const create = this.client.rest.methods.createGuildRole(this); - if (!data) return create; - return create.then(role => role.edit(data)); - } - - /** - * Creates a new custom emoji in the guild. - * @param {BufferResolvable} attachment The image for the emoji. - * @param {string} name The name for the emoji. - * @returns {Promise} The created emoji. - * @example - * // create a new emoji from a url - * guild.createEmoji('https://i.imgur.com/w3duR07.png', 'rip') - * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`)) - * .catch(console.error); - * @example - * // create a new emoji from a file on your computer - * guild.createEmoji('./memes/banana.png', 'banana') - * .then(emoji => console.log(`Created new emoji with name ${emoji.name}!`)) - * .catch(console.error); - */ - createEmoji(attachment, name) { - return new Promise(resolve => { - if (attachment.startsWith('data:')) { - resolve(this.client.rest.methods.createEmoji(this, attachment, name)); - } else { - this.client.resolver.resolveBuffer(attachment).then(data => - resolve(this.client.rest.methods.createEmoji(this, data, name)) - ); - } - }); - } - - /** - * Delete an emoji. - * @param {Emoji|string} emoji The emoji to delete. - * @returns {Promise} - */ - deleteEmoji(emoji) { - if (!(emoji instanceof Emoji)) emoji = this.emojis.get(emoji); - return this.client.rest.methods.deleteEmoji(emoji); - } - - /** - * Causes the Client to leave the guild. - * @returns {Promise} - * @example - * // leave a guild - * guild.leave() - * .then(g => console.log(`Left the guild ${g}`)) - * .catch(console.error); - */ - leave() { - return this.client.rest.methods.leaveGuild(this); - } - - /** - * Causes the Client to delete the guild. - * @returns {Promise} - * @example - * // delete a guild - * guild.delete() - * .then(g => console.log(`Deleted the guild ${g}`)) - * .catch(console.error); - */ - delete() { - return this.client.rest.methods.deleteGuild(this); - } - - /** - * Set the position of a role in this guild - * @param {string|Role} role the role to edit, can be a role object or a role ID. - * @param {number} position the new position of the role - * @returns {Promise} - */ - setRolePosition(role, position) { - if (typeof role === 'string') { - role = this.roles.get(role); - if (!role) return Promise.reject(new Error('Supplied role is not a role or string.')); - } - - position = Number(position); - if (isNaN(position)) return Promise.reject(new Error('Supplied position is not a number.')); - - const lowestAffected = Math.min(role.position, position); - const highestAffected = Math.max(role.position, position); - - const rolesToUpdate = this.roles.filter(r => r.position >= lowestAffected && r.position <= highestAffected); - - // stop role positions getting stupidly inflated - if (position > role.position) { - position = rolesToUpdate.first().position; - } else { - position = rolesToUpdate.last().position; - } - - const updatedRoles = []; - - for (const uRole of rolesToUpdate.values()) { - updatedRoles.push({ - id: uRole.id, - position: uRole.id === role.id ? position : uRole.position + (position < role.position ? 1 : -1), - }); - } - - return this.client.rest.methods.setRolePositions(this.id, updatedRoles); - } - - /** - * Whether this Guild equals another Guild. It compares all properties, so for most operations - * it is advisable to just compare `guild.id === guild2.id` as it is much faster and is often - * what most users need. - * @param {Guild} guild Guild to compare with - * @returns {boolean} - */ - equals(guild) { - let equal = - guild && - this.id === guild.id && - this.available === !guild.unavailable && - this.splash === guild.splash && - this.region === guild.region && - this.name === guild.name && - this.memberCount === guild.member_count && - this.large === guild.large && - this.icon === guild.icon && - arraysEqual(this.features, guild.features) && - this.ownerID === guild.owner_id && - this.verificationLevel === guild.verification_level && - this.embedEnabled === guild.embed_enabled; - - if (equal) { - if (this.embedChannel) { - if (this.embedChannel.id !== guild.embed_channel_id) equal = false; - } else if (guild.embed_channel_id) { - equal = false; - } - } - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the guild's name instead of the Guild object. - * @returns {string} - * @example - * // logs: Hello from My Guild! - * console.log(`Hello from ${guild}!`); - * @example - * // logs: Hello from My Guild! - * console.log(`Hello from ' + guild + '!'); - */ - toString() { - return this.name; - } - - _addMember(guildUser, emitEvent = true) { - const existing = this.members.has(guildUser.user.id); - if (!(guildUser.user instanceof User)) guildUser.user = this.client.dataManager.newUser(guildUser.user); - - guildUser.joined_at = guildUser.joined_at || 0; - const member = new GuildMember(this, guildUser); - this.members.set(member.id, member); - - if (this._rawVoiceStates && this._rawVoiceStates.has(member.user.id)) { - const voiceState = this._rawVoiceStates.get(member.user.id); - member.serverMute = voiceState.mute; - member.serverDeaf = voiceState.deaf; - member.selfMute = voiceState.self_mute; - member.selfDeaf = voiceState.self_deaf; - member.voiceSessionID = voiceState.session_id; - member.voiceChannelID = voiceState.channel_id; - if (this.client.channels.has(voiceState.channel_id)) { - this.client.channels.get(voiceState.channel_id).members.set(member.user.id, member); - } else { - this.client.emit('warn', `Member ${member.id} added in guild ${this.id} with an uncached voice channel`); - } - } - - /** - * Emitted whenever a user joins a guild. - * @event Client#guildMemberAdd - * @param {GuildMember} member The member that has joined a guild - */ - if (this.client.ws.status === Constants.Status.READY && emitEvent && !existing) { - this.client.emit(Constants.Events.GUILD_MEMBER_ADD, member); - } - - this._checkChunks(); - return member; - } - - _updateMember(member, data) { - const oldMember = cloneObject(member); - - if (data.roles) member._roles = data.roles; - if (typeof data.nick !== 'undefined') member.nickname = data.nick; - - const notSame = member.nickname !== oldMember.nickname || !arraysEqual(member._roles, oldMember._roles); - - if (this.client.ws.status === Constants.Status.READY && notSame) { - /** - * Emitted whenever a guild member changes - i.e. new role, removed role, nickname - * @event Client#guildMemberUpdate - * @param {GuildMember} oldMember The member before the update - * @param {GuildMember} newMember The member after the update - */ - this.client.emit(Constants.Events.GUILD_MEMBER_UPDATE, oldMember, member); - } - - return { - old: oldMember, - mem: member, - }; - } - - _removeMember(guildMember) { - this.members.delete(guildMember.id); - this._checkChunks(); - } - - _memberSpeakUpdate(user, speaking) { - const member = this.members.get(user); - if (member && member.speaking !== speaking) { - member.speaking = speaking; - /** - * Emitted once a guild member starts/stops speaking - * @event Client#guildMemberSpeaking - * @param {GuildMember} member The member that started/stopped speaking - * @param {boolean} speaking Whether or not the member is speaking - */ - this.client.emit(Constants.Events.GUILD_MEMBER_SPEAKING, member, speaking); - } - } - - _setPresence(id, presence) { - if (this.presences.get(id)) { - this.presences.get(id).update(presence); - return; - } - this.presences.set(id, new Presence(presence)); - } - - _checkChunks() { - if (this._fetchWaiter) { - if (this.members.size === this.memberCount) { - this._fetchWaiter(this); - this._fetchWaiter = null; - } - } - } -} - -module.exports = Guild; diff --git a/node_modules/discord.js/src/structures/GuildChannel.js b/node_modules/discord.js/src/structures/GuildChannel.js deleted file mode 100644 index a930789..0000000 --- a/node_modules/discord.js/src/structures/GuildChannel.js +++ /dev/null @@ -1,299 +0,0 @@ -const Channel = require('./Channel'); -const Role = require('./Role'); -const PermissionOverwrites = require('./PermissionOverwrites'); -const EvaluatedPermissions = require('./EvaluatedPermissions'); -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); - -/** - * Represents a guild channel (i.e. text channels and voice channels) - * @extends {Channel} - */ -class GuildChannel extends Channel { - constructor(guild, data) { - super(guild.client, data); - - /** - * The guild the channel is in - * @type {Guild} - */ - this.guild = guild; - } - - setup(data) { - super.setup(data); - - /** - * The name of the guild channel - * @type {string} - */ - this.name = data.name; - - /** - * The position of the channel in the list. - * @type {number} - */ - this.position = data.position; - - /** - * A map of permission overwrites in this channel for roles and users. - * @type {Collection} - */ - this.permissionOverwrites = new Collection(); - if (data.permission_overwrites) { - for (const overwrite of data.permission_overwrites) { - this.permissionOverwrites.set(overwrite.id, new PermissionOverwrites(this, overwrite)); - } - } - } - - /** - * Gets the overall set of permissions for a user in this channel, taking into account roles and permission - * overwrites. - * @param {GuildMemberResolvable} member The user that you want to obtain the overall permissions for - * @returns {?EvaluatedPermissions} - */ - permissionsFor(member) { - member = this.client.resolver.resolveGuildMember(this.guild, member); - if (!member) return null; - if (member.id === this.guild.ownerID) return new EvaluatedPermissions(member, Constants.ALL_PERMISSIONS); - - let permissions = 0; - - const roles = member.roles; - for (const role of roles.values()) permissions |= role.permissions; - - const overwrites = this.overwritesFor(member, true, roles); - for (const overwrite of overwrites.role.concat(overwrites.member)) { - permissions &= ~overwrite.deny; - permissions |= overwrite.allow; - } - - const admin = Boolean(permissions & Constants.PermissionFlags.ADMINISTRATOR); - if (admin) permissions = Constants.ALL_PERMISSIONS; - - return new EvaluatedPermissions(member, permissions); - } - - overwritesFor(member, verified = false, roles = null) { - if (!verified) member = this.client.resolver.resolveGuildMember(this.guild, member); - if (!member) return []; - - roles = roles || member.roles; - const roleOverwrites = []; - const memberOverwrites = []; - - for (const overwrite of this.permissionOverwrites.values()) { - if (overwrite.id === member.id) { - memberOverwrites.push(overwrite); - } else if (roles.has(overwrite.id)) { - roleOverwrites.push(overwrite); - } - } - - return { - role: roleOverwrites, - member: memberOverwrites, - }; - } - - /** - * An object mapping permission flags to `true` (enabled) or `false` (disabled) - * ```js - * { - * 'SEND_MESSAGES': true, - * 'ATTACH_FILES': false, - * } - * ``` - * @typedef {Object} PermissionOverwriteOptions - */ - - /** - * Overwrites the permissions for a user or role in this channel. - * @param {RoleResolvable|UserResolvable} userOrRole The user or role to update - * @param {PermissionOverwriteOptions} options The configuration for the update - * @returns {Promise} - * @example - * // overwrite permissions for a message author - * message.channel.overwritePermissions(message.author, { - * SEND_MESSAGES: false - * }) - * .then(() => console.log('Done!')) - * .catch(console.error); - */ - overwritePermissions(userOrRole, options) { - const payload = { - allow: 0, - deny: 0, - }; - - if (userOrRole instanceof Role) { - payload.type = 'role'; - } else if (this.guild.roles.has(userOrRole)) { - userOrRole = this.guild.roles.get(userOrRole); - payload.type = 'role'; - } else { - userOrRole = this.client.resolver.resolveUser(userOrRole); - payload.type = 'member'; - if (!userOrRole) return Promise.reject(new TypeError('Supplied parameter was neither a User nor a Role.')); - } - - payload.id = userOrRole.id; - - const prevOverwrite = this.permissionOverwrites.get(userOrRole.id); - - if (prevOverwrite) { - payload.allow = prevOverwrite.allow; - payload.deny = prevOverwrite.deny; - } - - for (const perm in options) { - if (options[perm] === true) { - payload.allow |= Constants.PermissionFlags[perm] || 0; - payload.deny &= ~(Constants.PermissionFlags[perm] || 0); - } else if (options[perm] === false) { - payload.allow &= ~(Constants.PermissionFlags[perm] || 0); - payload.deny |= Constants.PermissionFlags[perm] || 0; - } else if (options[perm] === null) { - payload.allow &= ~(Constants.PermissionFlags[perm] || 0); - payload.deny &= ~(Constants.PermissionFlags[perm] || 0); - } - } - - return this.client.rest.methods.setChannelOverwrite(this, payload); - } - - /** - * The data for a guild channel - * @typedef {Object} ChannelData - * @property {string} [name] The name of the channel - * @property {number} [position] The position of the channel - * @property {string} [topic] The topic of the text channel - * @property {number} [bitrate] The bitrate of the voice channel - * @property {number} [userLimit] The user limit of the channel - */ - - /** - * Edits the channel - * @param {ChannelData} data The new data for the channel - * @returns {Promise} - * @example - * // edit a channel - * channel.edit({name: 'new-channel'}) - * .then(c => console.log(`Edited channel ${c}`)) - * .catch(console.error); - */ - edit(data) { - return this.client.rest.methods.updateChannel(this, data); - } - - /** - * Set a new name for the guild channel - * @param {string} name The new name for the guild channel - * @returns {Promise} - * @example - * // set a new channel name - * channel.setName('not_general') - * .then(newChannel => console.log(`Channel's new name is ${newChannel.name}`)) - * .catch(console.error); - */ - setName(name) { - return this.edit({ name }); - } - - /** - * Set a new position for the guild channel - * @param {number} position The new position for the guild channel - * @returns {Promise} - * @example - * // set a new channel position - * channel.setPosition(2) - * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) - * .catch(console.error); - */ - setPosition(position) { - return this.client.rest.methods.updateChannel(this, { position }); - } - - /** - * Set a new topic for the guild channel - * @param {string} topic The new topic for the guild channel - * @returns {Promise} - * @example - * // set a new channel topic - * channel.setTopic('needs more rate limiting') - * .then(newChannel => console.log(`Channel's new topic is ${newChannel.topic}`)) - * .catch(console.error); - */ - setTopic(topic) { - return this.client.rest.methods.updateChannel(this, { topic }); - } - - /** - * Options given when creating a guild channel invite - * @typedef {Object} InviteOptions - * @property {boolean} [temporary=false] Whether the invite should kick users after 24hrs if they are not given a role - * @property {number} [maxAge=0] Time in seconds the invite expires in - * @property {number} [maxUses=0] Maximum amount of uses for this invite - */ - - /** - * Create an invite to this guild channel - * @param {InviteOptions} [options={}] The options for the invite - * @returns {Promise} - */ - createInvite(options = {}) { - return this.client.rest.methods.createChannelInvite(this, options); - } - - /** - * Clone this channel - * @param {string} [name=this.name] Optional name for the new channel, otherwise it has the name of this channel - * @param {boolean} [withPermissions=true] Whether to clone the channel with this channel's permission overwrites - * @returns {Promise} - */ - clone(name = this.name, withPermissions = true) { - return this.guild.createChannel(name, this.type, withPermissions ? this.permissionOverwrites : []); - } - - /** - * Checks if this channel has the same type, topic, position, name, overwrites and ID as another channel. - * In most cases, a simple `channel.id === channel2.id` will do, and is much faster too. - * @param {GuildChannel} channel Channel to compare with - * @returns {boolean} - */ - equals(channel) { - let equal = channel && - this.id === channel.id && - this.type === channel.type && - this.topic === channel.topic && - this.position === channel.position && - this.name === channel.name; - - if (equal) { - if (this.permissionOverwrites && channel.permissionOverwrites) { - equal = this.permissionOverwrites.equals(channel.permissionOverwrites); - } else { - equal = !this.permissionOverwrites && !channel.permissionOverwrites; - } - } - - return equal; - } - - /** - * When concatenated with a string, this automatically returns the channel's mention instead of the Channel object. - * @returns {string} - * @example - * // Outputs: Hello from #general - * console.log(`Hello from ${channel}`); - * @example - * // Outputs: Hello from #general - * console.log('Hello from ' + channel); - */ - toString() { - return `<#${this.id}>`; - } -} - -module.exports = GuildChannel; diff --git a/node_modules/discord.js/src/structures/GuildMember.js b/node_modules/discord.js/src/structures/GuildMember.js deleted file mode 100644 index 60a498a..0000000 --- a/node_modules/discord.js/src/structures/GuildMember.js +++ /dev/null @@ -1,442 +0,0 @@ -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Role = require('./Role'); -const EvaluatedPermissions = require('./EvaluatedPermissions'); -const Constants = require('../util/Constants'); -const Collection = require('../util/Collection'); -const Presence = require('./Presence').Presence; - -/** - * Represents a member of a guild on Discord - * @implements {TextBasedChannel} - */ -class GuildMember { - constructor(guild, data) { - /** - * The Client that instantiated this GuildMember - * @name GuildMember#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: guild.client }); - - /** - * The guild that this member is part of - * @type {Guild} - */ - this.guild = guild; - - /** - * The user that this guild member instance Represents - * @type {User} - */ - this.user = {}; - - this._roles = []; - if (data) this.setup(data); - - /** - * The ID of the last message sent by the member in their guild, if one was sent. - * @type {?string} - */ - this.lastMessageID = null; - } - - setup(data) { - /** - * Whether this member is deafened server-wide - * @type {boolean} - */ - this.serverDeaf = data.deaf; - - /** - * Whether this member is muted server-wide - * @type {boolean} - */ - this.serverMute = data.mute; - - /** - * Whether this member is self-muted - * @type {boolean} - */ - this.selfMute = data.self_mute; - - /** - * Whether this member is self-deafened - * @type {boolean} - */ - this.selfDeaf = data.self_deaf; - - /** - * The voice session ID of this member, if any - * @type {?string} - */ - this.voiceSessionID = data.session_id; - - /** - * The voice channel ID of this member, if any - * @type {?string} - */ - this.voiceChannelID = data.channel_id; - - /** - * Whether this member is speaking - * @type {boolean} - */ - this.speaking = false; - - /** - * The nickname of this guild member, if they have one - * @type {?string} - */ - this.nickname = data.nick || null; - - /** - * The timestamp the member joined the guild at - * @type {number} - */ - this.joinedTimestamp = new Date(data.joined_at).getTime(); - - this.user = data.user; - this._roles = data.roles; - } - - /** - * The time the member joined the guild - * @type {Date} - * @readonly - */ - get joinedAt() { - return new Date(this.joinedTimestamp); - } - - /** - * The presence of this guild member - * @type {Presence} - * @readonly - */ - get presence() { - return this.frozenPresence || this.guild.presences.get(this.id) || new Presence(); - } - - /** - * A list of roles that are applied to this GuildMember, mapped by the role ID. - * @type {Collection} - * @readonly - */ - get roles() { - const list = new Collection(); - const everyoneRole = this.guild.roles.get(this.guild.id); - - if (everyoneRole) list.set(everyoneRole.id, everyoneRole); - - for (const roleID of this._roles) { - const role = this.guild.roles.get(roleID); - if (role) list.set(role.id, role); - } - - return list; - } - - /** - * The role of the member with the highest position. - * @type {Role} - * @readonly - */ - get highestRole() { - return this.roles.reduce((prev, role) => !prev || role.comparePositionTo(prev) > 0 ? role : prev); - } - - /** - * Whether this member is muted in any way - * @type {boolean} - * @readonly - */ - get mute() { - return this.selfMute || this.serverMute; - } - - /** - * Whether this member is deafened in any way - * @type {boolean} - * @readonly - */ - get deaf() { - return this.selfDeaf || this.serverDeaf; - } - - /** - * The voice channel this member is in, if any - * @type {?VoiceChannel} - * @readonly - */ - get voiceChannel() { - return this.guild.channels.get(this.voiceChannelID); - } - - /** - * The ID of this user - * @type {string} - * @readonly - */ - get id() { - return this.user.id; - } - - /** - * The nickname of the 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 the guild member, taking only roles into account - * @type {EvaluatedPermissions} - * @readonly - */ - get permissions() { - if (this.user.id === this.guild.ownerID) return new EvaluatedPermissions(this, Constants.ALL_PERMISSIONS); - - let permissions = 0; - const roles = this.roles; - for (const role of roles.values()) permissions |= role.permissions; - - const admin = Boolean(permissions & Constants.PermissionFlags.ADMINISTRATOR); - if (admin) permissions = Constants.ALL_PERMISSIONS; - - return new EvaluatedPermissions(this, permissions); - } - - /** - * Whether the member is kickable by the client user. - * @type {boolean} - * @readonly - */ - get kickable() { - if (this.user.id === this.guild.ownerID) return false; - if (this.user.id === this.client.user.id) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.hasPermission(Constants.PermissionFlags.KICK_MEMBERS)) return false; - return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; - } - - /** - * Whether the member is bannable by the client user. - * @type {boolean} - * @readonly - */ - get bannable() { - if (this.user.id === this.guild.ownerID) return false; - if (this.user.id === this.client.user.id) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.hasPermission(Constants.PermissionFlags.BAN_MEMBERS)) return false; - return clientMember.highestRole.comparePositionTo(this.highestRole) > 0; - } - - /** - * Returns `channel.permissionsFor(guildMember)`. Returns evaluated permissions for a member in a guild channel. - * @param {ChannelResolvable} channel Guild channel to use as context - * @returns {?EvaluatedPermissions} - */ - permissionsIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - if (!channel || !channel.guild) throw new Error('Could not resolve channel to a guild channel.'); - return channel.permissionsFor(this); - } - - /** - * Checks if any of the member's roles have a permission. - * @param {PermissionResolvable} permission The permission to check for - * @param {boolean} [explicit=false] Whether to require the roles to explicitly have the exact permission - * @returns {boolean} - */ - hasPermission(permission, explicit = false) { - if (!explicit && this.user.id === this.guild.ownerID) return true; - return this.roles.some(r => r.hasPermission(permission, explicit)); - } - - /** - * Checks whether the roles of the member allows them to perform specific actions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions - * @returns {boolean} - */ - hasPermissions(permissions, explicit = false) { - if (!explicit && this.user.id === this.guild.ownerID) return true; - return permissions.every(p => this.hasPermission(p, explicit)); - } - - /** - * Checks whether the roles of the member allows them to perform specific actions, and lists any missing permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the member to explicitly have the exact permissions - * @returns {PermissionResolvable[]} - */ - missingPermissions(permissions, explicit = false) { - return permissions.filter(p => !this.hasPermission(p, explicit)); - } - - /** - * Edit a guild member - * @param {GuildmemberEditData} data The data to edit the member with - * @returns {Promise} - */ - edit(data) { - return this.client.rest.methods.updateGuildMember(this, data); - } - - /** - * Mute/unmute a user - * @param {boolean} mute Whether or not the member should be muted - * @returns {Promise} - */ - setMute(mute) { - return this.edit({ mute }); - } - - /** - * Deafen/undeafen a user - * @param {boolean} deaf Whether or not the member should be deafened - * @returns {Promise} - */ - setDeaf(deaf) { - return this.edit({ deaf }); - } - - /** - * Moves the guild member to the given channel. - * @param {ChannelResolvable} channel The channel to move the member to - * @returns {Promise} - */ - setVoiceChannel(channel) { - return this.edit({ channel }); - } - - /** - * Sets the roles applied to the member. - * @param {Collection|Role[]|string[]} roles The roles or role IDs to apply - * @returns {Promise} - */ - setRoles(roles) { - return this.edit({ roles }); - } - - /** - * Adds a single role to the member. - * @param {Role|string} role The role or ID of the role to add - * @returns {Promise} - */ - addRole(role) { - if (!(role instanceof Role)) role = this.guild.roles.get(role); - return this.client.rest.methods.addMemberRole(this, role); - } - - /** - * Adds multiple roles to the member. - * @param {Collection|Role[]|string[]} roles The roles or role IDs to add - * @returns {Promise} - */ - addRoles(roles) { - let allRoles; - if (roles instanceof Collection) { - allRoles = this._roles.slice(); - for (const role of roles.values()) allRoles.push(role.id); - } else { - allRoles = this._roles.concat(roles); - } - return this.edit({ roles: allRoles }); - } - - /** - * Removes a single role from the member. - * @param {Role|string} role The role or ID of the role to remove - * @returns {Promise} - */ - removeRole(role) { - if (!(role instanceof Role)) role = this.guild.roles.get(role); - return this.client.rest.methods.removeMemberRole(this, role); - } - - /** - * Removes multiple roles from the member. - * @param {Collection|Role[]|string[]} roles The roles or role IDs to remove - * @returns {Promise} - */ - removeRoles(roles) { - const allRoles = this._roles.slice(); - if (roles instanceof Collection) { - for (const role of roles.values()) { - const index = allRoles.indexOf(role.id); - if (index >= 0) allRoles.splice(index, 1); - } - } else { - for (const role of roles) { - const index = allRoles.indexOf(role instanceof Role ? role.id : role); - if (index >= 0) allRoles.splice(index, 1); - } - } - return this.edit({ roles: allRoles }); - } - - /** - * Set the nickname for the guild member - * @param {string} nick The nickname for the guild member - * @returns {Promise} - */ - setNickname(nick) { - return this.edit({ nick }); - } - - /** - * Deletes any DMs with this guild member - * @returns {Promise} - */ - deleteDM() { - return this.client.rest.methods.deleteChannel(this); - } - - /** - * Kick this member from the guild - * @returns {Promise} - */ - kick() { - return this.client.rest.methods.kickGuildMember(this.guild, this); - } - - /** - * Ban this guild member - * @param {number} [deleteDays=0] The amount of days worth of messages from this member that should - * also be deleted. Between `0` and `7`. - * @returns {Promise} - * @example - * // ban a guild member - * guildMember.ban(7); - */ - ban(deleteDays = 0) { - return this.client.rest.methods.banGuildMember(this.guild, this, deleteDays); - } - - /** - * When concatenated with a string, this automatically concatenates the user's mention instead of the Member object. - * @returns {string} - * @example - * // logs: Hello from <@123456789>! - * console.log(`Hello from ${member}!`); - */ - toString() { - return `<@${this.nickname ? '!' : ''}${this.user.id}>`; - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } -} - -TextBasedChannel.applyToClass(GuildMember); - -module.exports = GuildMember; diff --git a/node_modules/discord.js/src/structures/Invite.js b/node_modules/discord.js/src/structures/Invite.js deleted file mode 100644 index b4b34da..0000000 --- a/node_modules/discord.js/src/structures/Invite.js +++ /dev/null @@ -1,159 +0,0 @@ -const PartialGuild = require('./PartialGuild'); -const PartialGuildChannel = require('./PartialGuildChannel'); -const Constants = require('../util/Constants'); - -/* -{ max_age: 86400, - code: 'CG9A5', - guild: - { splash: null, - id: '123123123', - icon: '123123123', - name: 'name' }, - created_at: '2016-08-28T19:07:04.763368+00:00', - temporary: false, - uses: 0, - max_uses: 0, - inviter: - { username: '123', - discriminator: '4204', - bot: true, - id: '123123123', - avatar: '123123123' }, - channel: { type: 0, id: '123123', name: 'heavy-testing' } } -*/ - -/** - * Represents an invitation to a guild channel. - * The only guaranteed properties are `code`, `guild` and `channel`. Other properties can be missing. - */ -class Invite { - constructor(client, data) { - /** - * The client that instantiated the invite - * @name Invite#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The guild the invite is for. If this guild is already known, this will be a Guild object. If the guild is - * unknown, this will be a PartialGuild object. - * @type {Guild|PartialGuild} - */ - this.guild = this.client.guilds.get(data.guild.id) || new PartialGuild(this.client, data.guild); - - /** - * The code for this invite - * @type {string} - */ - this.code = data.code; - - /** - * Whether or not this invite is temporary - * @type {boolean} - */ - this.temporary = data.temporary; - - /** - * The maximum age of the invite, in seconds - * @type {?number} - */ - this.maxAge = data.max_age; - - /** - * How many times this invite has been used - * @type {number} - */ - this.uses = data.uses; - - /** - * The maximum uses of this invite - * @type {number} - */ - this.maxUses = data.max_uses; - - if (data.inviter) { - /** - * The user who created this invite - * @type {User} - */ - this.inviter = this.client.dataManager.newUser(data.inviter); - } - - /** - * The channel the invite is for. If this channel is already known, this will be a GuildChannel object. - * If the channel is unknown, this will be a PartialGuildChannel object. - * @type {GuildChannel|PartialGuildChannel} - */ - this.channel = this.client.channels.get(data.channel.id) || new PartialGuildChannel(this.client, data.channel); - - /** - * The timestamp the invite was created at - * @type {number} - */ - this.createdTimestamp = new Date(data.created_at).getTime(); - } - - /** - * The time the invite was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The timestamp the invite will expire at - * @type {number} - * @readonly - */ - get expiresTimestamp() { - return this.createdTimestamp + (this.maxAge * 1000); - } - - /** - * The time the invite will expire - * @type {Date} - * @readonly - */ - get expiresAt() { - return new Date(this.expiresTimestamp); - } - - /** - * The URL to the invite - * @type {string} - * @readonly - */ - get url() { - return Constants.Endpoints.inviteLink(this.code); - } - - /** - * Deletes this invite - * @returns {Promise} - */ - delete() { - return this.client.rest.methods.deleteInvite(this); - } - - /** - * When concatenated with a string, this automatically concatenates the invite's URL instead of the object. - * @returns {string} - * @example - * // logs: Invite: https://discord.gg/A1b2C3 - * console.log(`Invite: ${invite}`); - */ - toString() { - return this.url; - } -} - -module.exports = Invite; diff --git a/node_modules/discord.js/src/structures/Message.js b/node_modules/discord.js/src/structures/Message.js deleted file mode 100644 index 7fcc5b4..0000000 --- a/node_modules/discord.js/src/structures/Message.js +++ /dev/null @@ -1,568 +0,0 @@ -const Attachment = require('./MessageAttachment'); -const Embed = require('./MessageEmbed'); -const MessageReaction = require('./MessageReaction'); -const Collection = require('../util/Collection'); -const Constants = require('../util/Constants'); -const escapeMarkdown = require('../util/EscapeMarkdown'); - -// Done purely for GuildMember, which would cause a bad circular dependency -const Discord = require('..'); - -/** - * Represents a message on Discord - */ -class Message { - constructor(channel, data, client) { - /** - * The Client that instantiated the Message - * @name Message#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - /** - * The channel that the message was sent in - * @type {TextChannel|DMChannel|GroupDMChannel} - */ - this.channel = channel; - - if (data) this.setup(data); - } - - setup(data) { // eslint-disable-line complexity - /** - * The ID of the message (unique in the channel it was sent) - * @type {string} - */ - this.id = data.id; - - /** - * The type of the message - * @type {string} - */ - this.type = Constants.MessageTypes[data.type]; - - /** - * The content of the message - * @type {string} - */ - this.content = data.content; - - /** - * The author of the message - * @type {User} - */ - this.author = this.client.dataManager.newUser(data.author); - - /** - * Represents the author of the message as a guild member. Only available if the message comes from a guild - * where the author is still a member. - * @type {GuildMember} - */ - this.member = this.guild ? this.guild.member(this.author) || null : null; - - /** - * Whether or not this message is pinned - * @type {boolean} - */ - this.pinned = data.pinned; - - /** - * Whether or not the message was Text-To-Speech - * @type {boolean} - */ - this.tts = data.tts; - - /** - * A random number used for checking message delivery - * @type {string} - */ - this.nonce = data.nonce; - - /** - * Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications) - * @type {boolean} - */ - this.system = data.type === 6; - - /** - * A list of embeds in the message - e.g. YouTube Player - * @type {MessageEmbed[]} - */ - this.embeds = data.embeds.map(e => new Embed(this, e)); - - /** - * A collection of attachments in the message - e.g. Pictures - mapped by their ID. - * @type {Collection} - */ - this.attachments = new Collection(); - for (const attachment of data.attachments) this.attachments.set(attachment.id, new Attachment(this, attachment)); - - /** - * The timestamp the message was sent at - * @type {number} - */ - this.createdTimestamp = new Date(data.timestamp).getTime(); - - /** - * The timestamp the message was last edited at (if applicable) - * @type {?number} - */ - this.editedTimestamp = data.edited_timestamp ? new Date(data.edited_timestamp).getTime() : null; - - /** - * An object containing a further users, roles or channels collections - * @type {Object} - * @property {Collection} mentions.users Mentioned users, maps their ID to the user object. - * @property {Collection} mentions.roles Mentioned roles, maps their ID to the role object. - * @property {Collection} mentions.channels Mentioned channels, - * maps their ID to the channel object. - * @property {boolean} mentions.everyone Whether or not @everyone was mentioned. - */ - this.mentions = { - users: new Collection(), - roles: new Collection(), - channels: new Collection(), - everyone: data.mention_everyone, - }; - - for (const mention of data.mentions) { - let user = this.client.users.get(mention.id); - if (user) { - this.mentions.users.set(user.id, user); - } else { - user = this.client.dataManager.newUser(mention); - this.mentions.users.set(user.id, user); - } - } - - if (data.mention_roles) { - for (const mention of data.mention_roles) { - const role = this.channel.guild.roles.get(mention); - if (role) this.mentions.roles.set(role.id, role); - } - } - - if (this.channel.guild) { - const channMentionsRaw = data.content.match(/<#([0-9]{14,20})>/g) || []; - for (const raw of channMentionsRaw) { - const chan = this.channel.guild.channels.get(raw.match(/([0-9]{14,20})/g)[0]); - if (chan) this.mentions.channels.set(chan.id, chan); - } - } - - this._edits = []; - - /** - * A collection of reactions to this message, mapped by the reaction "id". - * @type {Collection} - */ - this.reactions = new Collection(); - - if (data.reactions && data.reactions.length > 0) { - for (const reaction of data.reactions) { - const id = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name; - this.reactions.set(id, new MessageReaction(this, reaction.emoji, reaction.count, reaction.me)); - } - } - - /** - * ID of the webhook that sent the message, if applicable - * @type {?string} - */ - this.webhookID = data.webhook_id || null; - } - - patch(data) { // eslint-disable-line complexity - if (data.author) { - this.author = this.client.users.get(data.author.id); - if (this.guild) this.member = this.guild.member(this.author); - } - if (data.content) this.content = data.content; - if (data.timestamp) this.createdTimestamp = new Date(data.timestamp).getTime(); - if (data.edited_timestamp) { - this.editedTimestamp = data.edited_timestamp ? new Date(data.edited_timestamp).getTime() : null; - } - if ('tts' in data) this.tts = data.tts; - if ('mention_everyone' in data) this.mentions.everyone = data.mention_everyone; - if (data.nonce) this.nonce = data.nonce; - if (data.embeds) this.embeds = data.embeds.map(e => new Embed(this, e)); - if (data.type > -1) { - this.system = false; - if (data.type === 6) this.system = true; - } - if (data.attachments) { - this.attachments = new Collection(); - for (const attachment of data.attachments) { - this.attachments.set(attachment.id, new Attachment(this, attachment)); - } - } - if (data.mentions) { - for (const mention of data.mentions) { - let user = this.client.users.get(mention.id); - if (user) { - this.mentions.users.set(user.id, user); - } else { - user = this.client.dataManager.newUser(mention); - this.mentions.users.set(user.id, user); - } - } - } - if (data.mention_roles) { - for (const mention of data.mention_roles) { - const role = this.channel.guild.roles.get(mention); - if (role) this.mentions.roles.set(role.id, role); - } - } - if (data.id) this.id = data.id; - if (this.channel.guild && data.content) { - const channMentionsRaw = data.content.match(/<#([0-9]{14,20})>/g) || []; - for (const raw of channMentionsRaw) { - const chan = this.channel.guild.channels.get(raw.match(/([0-9]{14,20})/g)[0]); - if (chan) this.mentions.channels.set(chan.id, chan); - } - } - if (data.reactions) { - this.reactions = new Collection(); - if (data.reactions.length > 0) { - for (const reaction of data.reactions) { - const id = reaction.emoji.id ? `${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name; - this.reactions.set(id, new MessageReaction(this, data.emoji, data.count, data.me)); - } - } - } - } - - /** - * The time the message was sent - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The time the message was last edited at (if applicable) - * @type {?Date} - * @readonly - */ - get editedAt() { - return this.editedTimestamp ? new Date(this.editedTimestamp) : null; - } - - /** - * The guild the message was sent in (if in a guild channel) - * @type {?Guild} - * @readonly - */ - get guild() { - return this.channel.guild || null; - } - - /** - * The message contents with all mentions replaced by the equivalent text. If mentions cannot be resolved to a name, - * the relevant mention in the message content will not be converted. - * @type {string} - * @readonly - */ - get cleanContent() { - return this.content - .replace(/@(everyone|here)/g, '@\u200b$1') - .replace(/<@!?[0-9]+>/g, (input) => { - const id = input.replace(/<|!|>|@/g, ''); - if (this.channel.type === 'dm' || this.channel.type === 'group') { - return this.client.users.has(id) ? `@${this.client.users.get(id).username}` : input; - } - - const member = this.channel.guild.members.get(id); - if (member) { - if (member.nickname) return `@${member.nickname}`; - return `@${member.user.username}`; - } else { - const user = this.client.users.get(id); - if (user) return `@${user.username}`; - return input; - } - }) - .replace(/<#[0-9]+>/g, (input) => { - const channel = this.client.channels.get(input.replace(/<|#|>/g, '')); - if (channel) return `#${channel.name}`; - return input; - }) - .replace(/<@&[0-9]+>/g, (input) => { - if (this.channel.type === 'dm' || this.channel.type === 'group') return input; - const role = this.guild.roles.get(input.replace(/<|@|>|&/g, '')); - if (role) return `@${role.name}`; - return input; - }); - } - - /** - * An array of cached versions of the message, including the current version. - * Sorted from latest (first) to oldest (last). - * @type {Message[]} - * @readonly - */ - get edits() { - const copy = this._edits.slice(); - copy.unshift(this); - return copy; - } - - /** - * Whether the message is editable by the client user. - * @type {boolean} - * @readonly - */ - get editable() { - return this.author.id === this.client.user.id; - } - - /** - * Whether the message is deletable by the client user. - * @type {boolean} - * @readonly - */ - get deletable() { - return this.author.id === this.client.user.id || (this.guild && - this.channel.permissionsFor(this.client.user).hasPermission(Constants.PermissionFlags.MANAGE_MESSAGES) - ); - } - - /** - * Whether the message is pinnable by the client user. - * @type {boolean} - * @readonly - */ - get pinnable() { - return !this.guild || - this.channel.permissionsFor(this.client.user).hasPermission(Constants.PermissionFlags.MANAGE_MESSAGES); - } - - /** - * Whether or not a user, channel or role is mentioned in this message. - * @param {GuildChannel|User|Role|string} data either a guild channel, user or a role object, or a string representing - * the ID of any of these. - * @returns {boolean} - */ - isMentioned(data) { - data = data && data.id ? data.id : data; - return this.mentions.users.has(data) || this.mentions.channels.has(data) || this.mentions.roles.has(data); - } - - /** - * Whether or not a guild member is mentioned in this message. Takes into account - * user mentions, role mentions, and @everyone/@here mentions. - * @param {GuildMember|User} member Member/user to check for a mention of - * @returns {boolean} - */ - isMemberMentioned(member) { - if (this.mentions.everyone) return true; - if (this.mentions.users.has(member.id)) return true; - if (member instanceof Discord.GuildMember && member.roles.some(r => this.mentions.roles.has(r.id))) return true; - return false; - } - - /** - * Options that can be passed into editMessage - * @typedef {Object} MessageEditOptions - * @property {Object} [embed] An embed to be added/edited - * @property {string|boolean} [code] Language for optional codeblock formatting to apply - */ - - /** - * Edit the content of the message - * @param {StringResolvable} [content] The new content for the message - * @param {MessageEditOptions} [options] The options to provide - * @returns {Promise} - * @example - * // update the content of a message - * message.edit('This is my new content!') - * .then(msg => console.log(`Updated the content of a message from ${msg.author}`)) - * .catch(console.error); - */ - edit(content, options) { - if (!options && typeof content === 'object') { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - return this.client.rest.methods.updateMessage(this, content, options); - } - - /** - * Edit the content of the message, with a code block - * @param {string} lang Language for the code block - * @param {StringResolvable} content The new content for the message - * @returns {Promise} - */ - editCode(lang, content) { - content = escapeMarkdown(this.client.resolver.resolveString(content), true); - return this.edit(`\`\`\`${lang || ''}\n${content}\n\`\`\``); - } - - /** - * Pins this message to the channel's pinned messages - * @returns {Promise} - */ - pin() { - return this.client.rest.methods.pinMessage(this); - } - - /** - * Unpins this message from the channel's pinned messages - * @returns {Promise} - */ - unpin() { - return this.client.rest.methods.unpinMessage(this); - } - - /** - * Add a reaction to the message - * @param {string|Emoji|ReactionEmoji} emoji Emoji to react with - * @returns {Promise} - */ - react(emoji) { - emoji = this.client.resolver.resolveEmojiIdentifier(emoji); - if (!emoji) throw new TypeError('Emoji must be a string or Emoji/ReactionEmoji'); - - return this.client.rest.methods.addMessageReaction(this, emoji); - } - - /** - * Remove all reactions from a message - * @returns {Promise} - */ - clearReactions() { - return this.client.rest.methods.removeMessageReactions(this); - } - - /** - * Deletes the message - * @param {number} [timeout=0] How long to wait to delete the message in milliseconds - * @returns {Promise} - * @example - * // delete a message - * message.delete() - * .then(msg => console.log(`Deleted message from ${msg.author}`)) - * .catch(console.error); - */ - delete(timeout = 0) { - if (timeout <= 0) { - return this.client.rest.methods.deleteMessage(this); - } else { - return new Promise(resolve => { - this.client.setTimeout(() => { - resolve(this.delete()); - }, timeout); - }); - } - } - - /** - * Reply to the message - * @param {StringResolvable} content The content for the message - * @param {MessageOptions} [options = {}] The options to provide - * @returns {Promise} - * @example - * // reply to a message - * message.reply('Hey, I\'m a reply!') - * .then(msg => console.log(`Sent a reply to ${msg.author}`)) - * .catch(console.error); - */ - reply(content, options = {}) { - content = `${this.guild || this.channel.type === 'group' ? `${this.author}, ` : ''}${content}`; - return this.channel.send(content, options); - } - - /** - * Fetches the webhook used to create this message. - * @returns {Promise} - */ - fetchWebhook() { - if (!this.webhookID) return Promise.reject(new Error('The message was not sent by a webhook.')); - return this.client.fetchWebhook(this.webhookID); - } - - /** - * Used mainly internally. Whether two messages are identical in properties. If you want to compare messages - * without checking all the properties, use `message.id === message2.id`, which is much more efficient. This - * method allows you to see if there are differences in content, embeds, attachments, nonce and tts properties. - * @param {Message} message The message to compare it to - * @param {Object} rawData Raw data passed through the WebSocket about this message - * @returns {boolean} - */ - equals(message, rawData) { - if (!message) return false; - const embedUpdate = !message.author && !message.attachments; - if (embedUpdate) return this.id === message.id && this.embeds.length === message.embeds.length; - - let equal = this.id === message.id && - this.author.id === message.author.id && - this.content === message.content && - this.tts === message.tts && - this.nonce === message.nonce && - this.embeds.length === message.embeds.length && - this.attachments.length === message.attachments.length; - - if (equal && rawData) { - equal = this.mentions.everyone === message.mentions.everyone && - this.createdTimestamp === new Date(rawData.timestamp).getTime() && - this.editedTimestamp === new Date(rawData.edited_timestamp).getTime(); - } - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the message's content instead of the object. - * @returns {string} - * @example - * // logs: Message: This is a message! - * console.log(`Message: ${message}`); - */ - toString() { - return this.content; - } - - _addReaction(emoji, user) { - const emojiID = emoji.id ? `${emoji.name}:${emoji.id}` : emoji.name; - let reaction; - if (this.reactions.has(emojiID)) { - reaction = this.reactions.get(emojiID); - if (!reaction.me) reaction.me = user.id === this.client.user.id; - } else { - reaction = new MessageReaction(this, emoji, 0, user.id === this.client.user.id); - this.reactions.set(emojiID, reaction); - } - if (!reaction.users.has(user.id)) { - reaction.users.set(user.id, user); - reaction.count++; - return reaction; - } - return null; - } - - _removeReaction(emoji, user) { - const emojiID = emoji.id || emoji; - if (this.reactions.has(emojiID)) { - const reaction = this.reactions.get(emojiID); - if (reaction.users.has(user.id)) { - reaction.users.delete(user.id); - reaction.count--; - if (user.id === this.client.user.id) reaction.me = false; - return reaction; - } - } - return null; - } - - _clearReactions() { - this.reactions.clear(); - } -} - -module.exports = Message; diff --git a/node_modules/discord.js/src/structures/MessageAttachment.js b/node_modules/discord.js/src/structures/MessageAttachment.js deleted file mode 100644 index 29dfb52..0000000 --- a/node_modules/discord.js/src/structures/MessageAttachment.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Represents an attachment in a message - */ -class MessageAttachment { - constructor(message, data) { - /** - * The Client that instantiated this MessageAttachment. - * @name MessageAttachment#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: message.client }); - - /** - * The message this attachment is part of. - * @type {Message} - */ - this.message = message; - - this.setup(data); - } - - setup(data) { - /** - * The ID of this attachment - * @type {string} - */ - this.id = data.id; - - /** - * The file name of this attachment - * @type {string} - */ - this.filename = data.filename; - - /** - * The size of this attachment in bytes - * @type {number} - */ - this.filesize = data.size; - - /** - * The URL to this attachment - * @type {string} - */ - this.url = data.url; - - /** - * The Proxy URL to this attachment - * @type {string} - */ - this.proxyURL = data.proxy_url; - - /** - * The height of this attachment (if an image) - * @type {?number} - */ - this.height = data.height; - - /** - * The width of this attachment (if an image) - * @type {?number} - */ - this.width = data.width; - } -} - -module.exports = MessageAttachment; diff --git a/node_modules/discord.js/src/structures/MessageCollector.js b/node_modules/discord.js/src/structures/MessageCollector.js deleted file mode 100644 index f84ecbd..0000000 --- a/node_modules/discord.js/src/structures/MessageCollector.js +++ /dev/null @@ -1,151 +0,0 @@ -const EventEmitter = require('events').EventEmitter; -const Collection = require('../util/Collection'); - -/** - * Collects messages based on a specified filter, then emits them. - * @extends {EventEmitter} - */ -class MessageCollector extends EventEmitter { - /** - * A function that takes a Message object and a MessageCollector and returns a boolean. - * ```js - * function(message, collector) { - * if (message.content.includes('discord')) { - * return true; // passed the filter test - * } - * return false; // failed the filter test - * } - * ``` - * @typedef {Function} CollectorFilterFunction - */ - - /** - * An object containing options used to configure a MessageCollector. All properties are optional. - * @typedef {Object} CollectorOptions - * @property {number} [time] Duration for the collector in milliseconds - * @property {number} [max] Maximum number of messages to handle - * @property {number} [maxMatches] Maximum number of successfully filtered messages to obtain - */ - - /** - * @param {Channel} channel The channel to collect messages in - * @param {CollectorFilterFunction} filter The filter function - * @param {CollectorOptions} [options] Options for the collector - */ - constructor(channel, filter, options = {}) { - super(); - - /** - * The channel this collector is operating on - * @type {Channel} - */ - this.channel = channel; - - /** - * A function used to filter messages that the collector collects. - * @type {CollectorFilterFunction} - */ - this.filter = filter; - - /** - * Options for the collecor. - * @type {CollectorOptions} - */ - this.options = options; - - /** - * Whether this collector has stopped collecting messages. - * @type {boolean} - */ - this.ended = false; - - /** - * A collection of collected messages, mapped by message ID. - * @type {Collection} - */ - this.collected = new Collection(); - - this.listener = message => this.verify(message); - this.channel.client.on('message', this.listener); - if (options.time) this.channel.client.setTimeout(() => this.stop('time'), options.time); - } - - /** - * Verifies a message against the filter and options - * @private - * @param {Message} message The message - * @returns {boolean} - */ - verify(message) { - if (this.channel ? this.channel.id !== message.channel.id : false) return false; - if (this.filter(message, this)) { - this.collected.set(message.id, message); - /** - * Emitted whenever the collector receives a message that passes the filter test. - * @param {Message} message The received message - * @param {MessageCollector} collector The collector the message passed through - * @event MessageCollector#message - */ - this.emit('message', message, this); - if (this.collected.size >= this.options.maxMatches) this.stop('matchesLimit'); - else if (this.options.max && this.collected.size === this.options.max) this.stop('limit'); - return true; - } - return false; - } - - /** - * Returns a promise that resolves when a valid message is sent. Rejects - * with collected messages if the Collector ends before receiving a message. - * @type {Promise} - * @readonly - */ - get next() { - return new Promise((resolve, reject) => { - if (this.ended) { - reject(this.collected); - return; - } - - const cleanup = () => { - this.removeListener('message', onMessage); - this.removeListener('end', onEnd); - }; - - const onMessage = (...args) => { - cleanup(); - resolve(...args); - }; - - const onEnd = (...args) => { - cleanup(); - reject(...args); - }; - - this.once('message', onMessage); - this.once('end', onEnd); - }); - } - - /** - * Stops the collector and emits `end`. - * @param {string} [reason='user'] An optional reason for stopping the collector - */ - stop(reason = 'user') { - if (this.ended) return; - this.ended = true; - this.channel.client.removeListener('message', this.listener); - /** - * Emitted when the Collector stops collecting. - * @param {Collection} collection A collection of messages collected - * during the lifetime of the collector, mapped by the ID of the messages. - * @param {string} reason The reason for the end of the collector. If it ended because it reached the specified time - * limit, this would be `time`. If you invoke `.stop()` without specifying a reason, this would be `user`. If it - * ended because it reached its message limit, it will be `limit`. - * @event MessageCollector#end - */ - this.emit('end', this.collected, reason); - } -} - -module.exports = MessageCollector; diff --git a/node_modules/discord.js/src/structures/MessageEmbed.js b/node_modules/discord.js/src/structures/MessageEmbed.js deleted file mode 100644 index 1249c42..0000000 --- a/node_modules/discord.js/src/structures/MessageEmbed.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * Represents an embed in a message (image/video preview, rich embed, etc.) - */ -class MessageEmbed { - constructor(message, data) { - /** - * The client that instantiated this embed - * @name MessageEmbed#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: message.client }); - - /** - * The message this embed is part of - * @type {Message} - */ - this.message = message; - - this.setup(data); - } - - setup(data) { - /** - * The type of this embed - * @type {string} - */ - this.type = data.type; - - /** - * The title of this embed, if there is one - * @type {?string} - */ - this.title = data.title; - - /** - * The description of this embed, if there is one - * @type {?string} - */ - this.description = data.description; - - /** - * The URL of this embed - * @type {string} - */ - this.url = data.url; - - /** - * The color of the embed - * @type {number} - */ - this.color = data.color; - - /** - * The fields of this embed - * @type {MessageEmbedField[]} - */ - this.fields = []; - if (data.fields) for (const field of data.fields) this.fields.push(new MessageEmbedField(this, field)); - - /** - * The timestamp of this embed - * @type {number} - */ - this.createdTimestamp = data.timestamp; - - /** - * The thumbnail of this embed, if there is one - * @type {MessageEmbedThumbnail} - */ - this.thumbnail = data.thumbnail ? new MessageEmbedThumbnail(this, data.thumbnail) : null; - - /** - * The author of this embed, if there is one - * @type {MessageEmbedAuthor} - */ - this.author = data.author ? new MessageEmbedAuthor(this, data.author) : null; - - /** - * The provider of this embed, if there is one - * @type {MessageEmbedProvider} - */ - this.provider = data.provider ? new MessageEmbedProvider(this, data.provider) : null; - - /** - * The footer of this embed - * @type {MessageEmbedFooter} - */ - this.footer = data.footer ? new MessageEmbedFooter(this, data.footer) : null; - } - - /** - * The date this embed was created - * @type {Date} - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The hexadecimal version of the embed color, with a leading hash. - * @type {string} - * @readonly - */ - get hexColor() { - let col = this.color.toString(16); - while (col.length < 6) col = `0${col}`; - return `#${col}`; - } -} - -/** - * Represents a thumbnail for a message embed - */ -class MessageEmbedThumbnail { - constructor(embed, data) { - /** - * The embed this thumbnail is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The URL for this thumbnail - * @type {string} - */ - this.url = data.url; - - /** - * The Proxy URL for this thumbnail - * @type {string} - */ - this.proxyURL = data.proxy_url; - - /** - * The height of the thumbnail - * @type {number} - */ - this.height = data.height; - - /** - * The width of the thumbnail - * @type {number} - */ - this.width = data.width; - } -} - -/** - * Represents a provider for a message embed - */ -class MessageEmbedProvider { - constructor(embed, data) { - /** - * The embed this provider is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The name of this provider - * @type {string} - */ - this.name = data.name; - - /** - * The URL of this provider - * @type {string} - */ - this.url = data.url; - } -} - -/** - * Represents an author for a message embed - */ -class MessageEmbedAuthor { - constructor(embed, data) { - /** - * The embed this author is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The name of this author - * @type {string} - */ - this.name = data.name; - - /** - * The URL of this author - * @type {string} - */ - this.url = data.url; - - /** - * The icon URL of this author - * @type {string} - */ - this.iconURL = data.icon_url; - } -} - -/** - * Represents a field for a message embed - */ -class MessageEmbedField { - constructor(embed, data) { - /** - * The embed this footer is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The name of this field - * @type {string} - */ - this.name = data.name; - - /** - * The value of this field - * @type {string} - */ - this.value = data.value; - - /** - * If this field is displayed inline - * @type {boolean} - */ - this.inline = data.inline; - } -} - -/** - * Represents the footer of a message embed - */ -class MessageEmbedFooter { - constructor(embed, data) { - /** - * The embed this footer is part of - * @type {MessageEmbed} - */ - this.embed = embed; - - this.setup(data); - } - - setup(data) { - /** - * The text in this footer - * @type {string} - */ - this.text = data.text; - - /** - * The icon URL of this footer - * @type {string} - */ - this.iconURL = data.icon_url; - - /** - * The proxy icon URL of this footer - * @type {string} - */ - this.proxyIconUrl = data.proxy_icon_url; - } -} - -MessageEmbed.Thumbnail = MessageEmbedThumbnail; -MessageEmbed.Provider = MessageEmbedProvider; -MessageEmbed.Author = MessageEmbedAuthor; -MessageEmbed.Field = MessageEmbedField; -MessageEmbed.Footer = MessageEmbedFooter; - -module.exports = MessageEmbed; diff --git a/node_modules/discord.js/src/structures/MessageReaction.js b/node_modules/discord.js/src/structures/MessageReaction.js deleted file mode 100644 index 30c555f..0000000 --- a/node_modules/discord.js/src/structures/MessageReaction.js +++ /dev/null @@ -1,92 +0,0 @@ -const Collection = require('../util/Collection'); -const Emoji = require('./Emoji'); -const ReactionEmoji = require('./ReactionEmoji'); - -/** - * Represents a reaction to a message - */ -class MessageReaction { - constructor(message, emoji, count, me) { - /** - * The message that this reaction refers to - * @type {Message} - */ - this.message = message; - - /** - * Whether the client has given this reaction - * @type {boolean} - */ - this.me = me; - - /** - * The number of people that have given the same reaction. - * @type {number} - */ - this.count = count || 0; - - /** - * The users that have given this reaction, mapped by their ID. - * @type {Collection} - */ - this.users = new Collection(); - - this._emoji = new ReactionEmoji(this, emoji.name, emoji.id); - } - - /** - * The emoji of this reaction, either an Emoji object for known custom emojis, or a ReactionEmoji - * object which has fewer properties. Whatever the prototype of the emoji, it will still have - * `name`, `id`, `identifier` and `toString()` - * @type {Emoji|ReactionEmoji} - */ - get emoji() { - if (this._emoji instanceof Emoji) return this._emoji; - // check to see if the emoji has become known to the client - if (this._emoji.id) { - const emojis = this.message.client.emojis; - if (emojis.has(this._emoji.id)) { - const emoji = emojis.get(this._emoji.id); - this._emoji = emoji; - return emoji; - } - } - return this._emoji; - } - - /** - * Removes a user from this reaction. - * @param {UserResolvable} [user=this.message.client.user] User to remove the reaction of - * @returns {Promise} - */ - remove(user = this.message.client.user) { - const message = this.message; - user = this.message.client.resolver.resolveUserID(user); - if (!user) return Promise.reject('Couldn\'t resolve the user ID to remove from the reaction.'); - return message.client.rest.methods.removeMessageReaction( - message, this.emoji.identifier, user - ); - } - - /** - * Fetch all the users that gave this reaction. Resolves with a collection of users, mapped by their IDs. - * @param {number} [limit=100] the maximum amount of users to fetch, defaults to 100 - * @returns {Promise>} - */ - fetchUsers(limit = 100) { - const message = this.message; - return message.client.rest.methods.getMessageReactionUsers( - message, this.emoji.identifier, limit - ).then(users => { - this.users = new Collection(); - for (const rawUser of users) { - const user = this.message.client.dataManager.newUser(rawUser); - this.users.set(user.id, user); - } - this.count = this.users.size; - return users; - }); - } -} - -module.exports = MessageReaction; diff --git a/node_modules/discord.js/src/structures/OAuth2Application.js b/node_modules/discord.js/src/structures/OAuth2Application.js deleted file mode 100644 index b7c7285..0000000 --- a/node_modules/discord.js/src/structures/OAuth2Application.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Represents an OAuth2 Application - */ -class OAuth2Application { - constructor(client, data) { - /** - * The client that instantiated the application - * @name OAuth2Application#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The ID of the app - * @type {string} - */ - this.id = data.id; - - /** - * The name of the app - * @type {string} - */ - this.name = data.name; - - /** - * The app's description - * @type {string} - */ - this.description = data.description; - - /** - * The app's icon hash - * @type {string} - */ - this.icon = data.icon; - - /** - * The app's icon URL - * @type {string} - */ - this.iconURL = `https://cdn.discordapp.com/app-icons/${this.id}/${this.icon}.jpg`; - - /** - * The app's RPC origins - * @type {Array} - */ - this.rpcOrigins = data.rpc_origins; - } - - /** - * The timestamp the app was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the app was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * When concatenated with a string, this automatically concatenates the app name rather than the app object. - * @returns {string} - */ - toString() { - return this.name; - } -} - -module.exports = OAuth2Application; diff --git a/node_modules/discord.js/src/structures/PartialGuild.js b/node_modules/discord.js/src/structures/PartialGuild.js deleted file mode 100644 index 407212e..0000000 --- a/node_modules/discord.js/src/structures/PartialGuild.js +++ /dev/null @@ -1,51 +0,0 @@ -/* -{ splash: null, - id: '123123123', - icon: '123123123', - name: 'name' } -*/ - -/** - * Represents a guild that the client only has limited information for - e.g. from invites. - */ -class PartialGuild { - constructor(client, data) { - /** - * The Client that instantiated this PartialGuild - * @name PartialGuild#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The ID of this guild - * @type {string} - */ - this.id = data.id; - - /** - * The name of this guild - * @type {string} - */ - this.name = data.name; - - /** - * The hash of this guild's icon, or null if there is none. - * @type {?string} - */ - this.icon = data.icon; - - /** - * The hash of the guild splash image, or null if no splash (VIP only) - * @type {?string} - */ - this.splash = data.splash; - } -} - -module.exports = PartialGuild; diff --git a/node_modules/discord.js/src/structures/PartialGuildChannel.js b/node_modules/discord.js/src/structures/PartialGuildChannel.js deleted file mode 100644 index e58a6bb..0000000 --- a/node_modules/discord.js/src/structures/PartialGuildChannel.js +++ /dev/null @@ -1,44 +0,0 @@ -const Constants = require('../util/Constants'); - -/* -{ type: 0, id: '123123', name: 'heavy-testing' } } -*/ - -/** - * Represents a guild channel that the client only has limited information for - e.g. from invites. - */ -class PartialGuildChannel { - constructor(client, data) { - /** - * The Client that instantiated this PartialGuildChannel - * @name PartialGuildChannel#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - this.setup(data); - } - - setup(data) { - /** - * The ID of this guild channel - * @type {string} - */ - this.id = data.id; - - /** - * The name of this guild channel - * @type {string} - */ - this.name = data.name; - - /** - * The type of this guild channel - `text` or `voice` - * @type {string} - */ - this.type = Constants.ChannelTypes.text === data.type ? 'text' : 'voice'; - } -} - -module.exports = PartialGuildChannel; diff --git a/node_modules/discord.js/src/structures/PermissionOverwrites.js b/node_modules/discord.js/src/structures/PermissionOverwrites.js deleted file mode 100644 index 9b2f536..0000000 --- a/node_modules/discord.js/src/structures/PermissionOverwrites.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Represents a permission overwrite for a role or member in a guild channel. - */ -class PermissionOverwrites { - constructor(guildChannel, data) { - /** - * The GuildChannel this overwrite is for - * @name PermissionOverwrites#channel - * @type {GuildChannel} - * @readonly - */ - Object.defineProperty(this, 'channel', { value: guildChannel }); - - if (data) this.setup(data); - } - - setup(data) { - /** - * The ID of this overwrite, either a user ID or a role ID - * @type {string} - */ - this.id = data.id; - - /** - * The type of this overwrite - * @type {string} - */ - this.type = data.type; - - this.deny = data.deny; - this.allow = data.allow; - } - - /** - * Delete this Permission Overwrite. - * @returns {Promise} - */ - delete() { - return this.channel.client.rest.methods.deletePermissionOverwrites(this); - } -} - -module.exports = PermissionOverwrites; diff --git a/node_modules/discord.js/src/structures/Presence.js b/node_modules/discord.js/src/structures/Presence.js deleted file mode 100644 index ddca5fb..0000000 --- a/node_modules/discord.js/src/structures/Presence.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Represents a user's presence - */ -class Presence { - constructor(data = {}) { - /** - * The status of the presence: - * - * * **`online`** - user is online - * * **`offline`** - user is offline or invisible - * * **`idle`** - user is AFK - * * **`dnd`** - user is in Do not Disturb - * @type {string} - */ - this.status = data.status || 'offline'; - - /** - * The game that the user is playing, `null` if they aren't playing a game. - * @type {?Game} - */ - this.game = data.game ? new Game(data.game) : null; - } - - update(data) { - this.status = data.status || this.status; - this.game = data.game ? new Game(data.game) : null; - } - - /** - * Whether this presence is equal to another - * @param {Presence} presence Presence to compare with - * @returns {boolean} - */ - equals(presence) { - return this === presence || ( - presence && - this.status === presence.status && - this.game ? this.game.equals(presence.game) : !presence.game - ); - } -} - -/** - * Represents a game that is part of a user's presence. - */ -class Game { - constructor(data) { - /** - * The name of the game being played - * @type {string} - */ - this.name = data.name; - - /** - * The type of the game status - * @type {number} - */ - this.type = data.type; - - /** - * If the game is being streamed, a link to the stream - * @type {?string} - */ - this.url = data.url || null; - } - - /** - * Whether or not the game is being streamed - * @type {boolean} - * @readonly - */ - get streaming() { - return this.type === 1; - } - - /** - * Whether this game is equal to another game - * @param {Game} game Game to compare with - * @returns {boolean} - */ - equals(game) { - return this === game || ( - game && - this.name === game.name && - this.type === game.type && - this.url === game.url - ); - } -} - -exports.Presence = Presence; -exports.Game = Game; diff --git a/node_modules/discord.js/src/structures/ReactionEmoji.js b/node_modules/discord.js/src/structures/ReactionEmoji.js deleted file mode 100644 index b6d2cdb..0000000 --- a/node_modules/discord.js/src/structures/ReactionEmoji.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Represents a limited emoji set used for both custom and unicode emojis. Custom emojis - * will use this class opposed to the Emoji class when the client doesn't know enough - * information about them. - */ -class ReactionEmoji { - constructor(reaction, name, id) { - /** - * The message reaction this emoji refers to - * @type {MessageReaction} - */ - this.reaction = reaction; - - /** - * The name of this reaction emoji. - * @type {string} - */ - this.name = name; - - /** - * The ID of this reaction emoji. - * @type {string} - */ - this.id = id; - } - - /** - * The identifier of this emoji, used for message reactions - * @readonly - * @type {string} - */ - get identifier() { - if (this.id) return `${this.name}:${this.id}`; - return encodeURIComponent(this.name); - } - - /** - * Creates the text required to form a graphical emoji on Discord. - * @example - * // send the emoji used in a reaction to the channel the reaction is part of - * reaction.message.channel.sendMessage(`The emoji used is ${reaction.emoji}`); - * @returns {string} - */ - toString() { - return this.id ? `<:${this.name}:${this.id}>` : this.name; - } -} - -module.exports = ReactionEmoji; diff --git a/node_modules/discord.js/src/structures/RichEmbed.js b/node_modules/discord.js/src/structures/RichEmbed.js deleted file mode 100644 index fbd9383..0000000 --- a/node_modules/discord.js/src/structures/RichEmbed.js +++ /dev/null @@ -1,204 +0,0 @@ -/** - * A rich embed to be sent with a message - * @param {Object} [data] Data to set in the rich embed - */ -class RichEmbed { - constructor(data = {}) { - /** - * Title for this Embed - * @type {string} - */ - this.title = data.title; - - /** - * Description for this Embed - * @type {string} - */ - this.description = data.description; - - /** - * URL for this Embed - * @type {string} - */ - this.url = data.url; - - /** - * Color for this Embed - * @type {number} - */ - this.color = data.color; - - /** - * Author for this Embed - * @type {Object} - */ - this.author = data.author; - - /** - * Timestamp for this Embed - * @type {Date} - */ - this.timestamp = data.timestamp; - - /** - * Fields for this Embed - * @type {Object[]} - */ - this.fields = data.fields || []; - - /** - * Thumbnail for this Embed - * @type {Object} - */ - this.thumbnail = data.thumbnail; - - /** - * Image for this Embed - * @type {Object} - */ - this.image = data.image; - - /** - * Footer for this Embed - * @type {Object} - */ - this.footer = data.footer; - } - - /** - * Sets the title of this embed - * @param {StringResolvable} title The title - * @returns {RichEmbed} This embed - */ - setTitle(title) { - title = resolveString(title); - if (title.length > 256) throw new RangeError('RichEmbed titles may not exceed 256 characters.'); - this.title = title; - return this; - } - - /** - * Sets the description of this embed - * @param {StringResolvable} description The description - * @returns {RichEmbed} This embed - */ - setDescription(description) { - description = resolveString(description); - if (description.length > 2048) throw new RangeError('RichEmbed descriptions may not exceed 2048 characters.'); - this.description = description; - return this; - } - - /** - * Sets the URL of this embed - * @param {string} url The URL - * @returns {RichEmbed} This embed - */ - setURL(url) { - this.url = url; - return this; - } - - /** - * Sets the color of this embed - * @param {string|number|number[]} color The color to set - * @returns {RichEmbed} This embed - */ - setColor(color) { - let radix = 10; - if (color instanceof Array) { - color = (color[0] << 16) + (color[1] << 8) + color[2]; - } else if (typeof color === 'string' && color.startsWith('#')) { - radix = 16; - color = color.replace('#', ''); - } - color = parseInt(color, radix); - if (color < 0 || color > 0xFFFFFF) { - throw new RangeError('RichEmbed color must be within the range 0 - 16777215 (0xFFFFFF).'); - } else if (color && isNaN(color)) { - throw new TypeError('Unable to convert RichEmbed color to a number.'); - } - this.color = color; - return this; - } - - /** - * Sets the author of this embed - * @param {StringResolvable} name The name of the author - * @param {string} [icon] The icon URL of the author - * @param {string} [url] The URL of the author - * @returns {RichEmbed} This embed - */ - setAuthor(name, icon, url) { - this.author = { name: resolveString(name), icon_url: icon, url }; - return this; - } - - /** - * Sets the timestamp of this embed - * @param {Date} [timestamp=current date] The timestamp - * @returns {RichEmbed} This embed - */ - setTimestamp(timestamp = new Date()) { - this.timestamp = timestamp; - return this; - } - - /** - * Adds a field to the embed (max 25) - * @param {StringResolvable} name The name of the field - * @param {StringResolvable} value The value of the field - * @param {boolean} [inline=false] Set the field to display inline - * @returns {RichEmbed} This embed - */ - addField(name, value, inline = false) { - if (this.fields.length >= 25) throw new RangeError('RichEmbeds may not exceed 25 fields.'); - name = resolveString(name); - if (name.length > 256) throw new RangeError('RichEmbed field names may not exceed 256 characters.'); - value = resolveString(value); - if (value.length > 1024) throw new RangeError('RichEmbed field values may not exceed 1024 characters.'); - this.fields.push({ name: String(name), value: value, inline }); - return this; - } - - /** - * Set the thumbnail of this embed - * @param {string} url The URL of the thumbnail - * @returns {RichEmbed} This embed - */ - setThumbnail(url) { - this.thumbnail = { url }; - return this; - } - - /** - * Set the image of this embed - * @param {string} url The URL of the thumbnail - * @returns {RichEmbed} This embed - */ - setImage(url) { - this.image = { url }; - return this; - } - - /** - * Sets the footer of this embed - * @param {StringResolvable} text The text of the footer - * @param {string} [icon] The icon URL of the footer - * @returns {RichEmbed} This embed - */ - setFooter(text, icon) { - text = resolveString(text); - if (text.length > 2048) throw new RangeError('RichEmbed footer text may not exceed 2048 characters.'); - this.footer = { text, icon_url: icon }; - return this; - } -} - -module.exports = RichEmbed; - -function resolveString(data) { - if (typeof data === 'string') return data; - if (data instanceof Array) return data.join('\n'); - return String(data); -} diff --git a/node_modules/discord.js/src/structures/Role.js b/node_modules/discord.js/src/structures/Role.js deleted file mode 100644 index c15ff4b..0000000 --- a/node_modules/discord.js/src/structures/Role.js +++ /dev/null @@ -1,341 +0,0 @@ -const Constants = require('../util/Constants'); - -/** - * Represents a role on Discord - */ -class Role { - constructor(guild, data) { - /** - * The client that instantiated the role - * @name Role#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: guild.client }); - - /** - * The guild that the role belongs to - * @type {Guild} - */ - this.guild = guild; - - if (data) this.setup(data); - } - - setup(data) { - /** - * The ID of the role (unique to the guild it is part of) - * @type {string} - */ - this.id = data.id; - - /** - * The name of the role - * @type {string} - */ - this.name = data.name; - - /** - * The base 10 color of the role - * @type {number} - */ - this.color = data.color; - - /** - * If true, users that are part of this role will appear in a separate category in the users list - * @type {boolean} - */ - this.hoist = data.hoist; - - /** - * The position of the role in the role manager - * @type {number} - */ - this.position = data.position; - - /** - * The evaluated permissions number - * @type {number} - */ - this.permissions = data.permissions; - - /** - * Whether or not the role is managed by an external service - * @type {boolean} - */ - this.managed = data.managed; - - /** - * Whether or not the role can be mentioned by anyone - * @type {boolean} - */ - this.mentionable = data.mentionable; - } - - /** - * The timestamp the role was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the role was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The hexadecimal version of the role color, with a leading hashtag. - * @type {string} - * @readonly - */ - get hexColor() { - let col = this.color.toString(16); - while (col.length < 6) col = `0${col}`; - return `#${col}`; - } - - /** - * The cached guild members that have this role. - * @type {Collection} - * @readonly - */ - get members() { - return this.guild.members.filter(m => m.roles.has(this.id)); - } - - /** - * Whether the role is editable by the client user. - * @type {boolean} - * @readonly - */ - get editable() { - if (this.managed) return false; - const clientMember = this.guild.member(this.client.user); - if (!clientMember.hasPermission(Constants.PermissionFlags.MANAGE_ROLES_OR_PERMISSIONS)) return false; - return clientMember.highestRole.comparePositionTo(this) > 0; - } - - /** - * Get an object mapping permission names to whether or not the role enables that permission - * @returns {Object} - * @example - * // print the serialized role - * console.log(role.serialize()); - */ - serialize() { - const serializedPermissions = {}; - for (const permissionName in Constants.PermissionFlags) { - serializedPermissions[permissionName] = this.hasPermission(permissionName); - } - return serializedPermissions; - } - - /** - * Checks if the role has a permission. - * @param {PermissionResolvable} permission The permission to check for - * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permission - * @returns {boolean} - * @example - * // see if a role can ban a member - * if (role.hasPermission('BAN_MEMBERS')) { - * console.log('This role can ban members'); - * } else { - * console.log('This role can\'t ban members'); - * } - */ - hasPermission(permission, explicit = false) { - permission = this.client.resolver.resolvePermission(permission); - if (!explicit && (this.permissions & Constants.PermissionFlags.ADMINISTRATOR) > 0) return true; - return (this.permissions & permission) > 0; - } - - /** - * Checks if the role has all specified permissions. - * @param {PermissionResolvable[]} permissions The permissions to check for - * @param {boolean} [explicit=false] Whether to require the role to explicitly have the exact permissions - * @returns {boolean} - */ - hasPermissions(permissions, explicit = false) { - return permissions.every(p => this.hasPermission(p, explicit)); - } - - /** - * Compares this role's position to another role's. - * @param {Role} role Role to compare to this one - * @returns {number} Negative number if the this role's position is lower (other role's is higher), - * positive number if the this one is higher (other's is lower), 0 if equal - */ - comparePositionTo(role) { - return this.constructor.comparePositions(this, role); - } - - /** - * The data for a role - * @typedef {Object} RoleData - * @property {string} [name] The name of the role - * @property {number|string} [color] The color of the role, either a hex string or a base 10 number - * @property {boolean} [hoist] Whether or not the role should be hoisted - * @property {number} [position] The position of the role - * @property {string[]} [permissions] The permissions of the role - * @property {boolean} [mentionable] Whether or not the role should be mentionable - */ - - /** - * Edits the role - * @param {RoleData} data The new data for the role - * @returns {Promise} - * @example - * // edit a role - * role.edit({name: 'new role'}) - * .then(r => console.log(`Edited role ${r}`)) - * .catch(console.error); - */ - edit(data) { - return this.client.rest.methods.updateGuildRole(this, data); - } - - /** - * Set a new name for the role - * @param {string} name The new name of the role - * @returns {Promise} - * @example - * // set the name of the role - * role.setName('new role') - * .then(r => console.log(`Edited name of role ${r}`)) - * .catch(console.error); - */ - setName(name) { - return this.edit({ name }); - } - - /** - * Set a new color for the role - * @param {number|string} color The new color for the role, either a hex string or a base 10 number - * @returns {Promise} - * @example - * // set the color of a role - * role.setColor('#FF0000') - * .then(r => console.log(`Set color of role ${r}`)) - * .catch(console.error); - */ - setColor(color) { - return this.edit({ color }); - } - - /** - * Set whether or not the role should be hoisted - * @param {boolean} hoist Whether or not to hoist the role - * @returns {Promise} - * @example - * // set the hoist of the role - * role.setHoist(true) - * .then(r => console.log(`Role hoisted: ${r.hoist}`)) - * .catch(console.error); - */ - setHoist(hoist) { - return this.edit({ hoist }); - } - - /** - * Set the position of the role - * @param {number} position The position of the role - * @returns {Promise} - * @example - * // set the position of the role - * role.setPosition(1) - * .then(r => console.log(`Role position: ${r.position}`)) - * .catch(console.error); - */ - setPosition(position) { - return this.guild.setRolePosition(this, position).then(() => this); - } - - /** - * Set the permissions of the role - * @param {string[]} permissions The permissions of the role - * @returns {Promise} - * @example - * // set the permissions of the role - * role.setPermissions(['KICK_MEMBERS', 'BAN_MEMBERS']) - * .then(r => console.log(`Role updated ${r}`)) - * .catch(console.error); - */ - setPermissions(permissions) { - return this.edit({ permissions }); - } - - /** - * Set whether this role is mentionable - * @param {boolean} mentionable Whether this role should be mentionable - * @returns {Promise} - * @example - * // make the role mentionable - * role.setMentionable(true) - * .then(r => console.log(`Role updated ${r}`)) - * .catch(console.error); - */ - setMentionable(mentionable) { - return this.edit({ mentionable }); - } - - /** - * Deletes the role - * @returns {Promise} - * @example - * // delete a role - * role.delete() - * .then(r => console.log(`Deleted role ${r}`)) - * .catch(console.error); - */ - delete() { - return this.client.rest.methods.deleteGuildRole(this); - } - - /** - * Whether this role equals another role. It compares all properties, so for most operations - * it is advisable to just compare `role.id === role2.id` as it is much faster and is often - * what most users need. - * @param {Role} role Role to compare with - * @returns {boolean} - */ - equals(role) { - return role && - this.id === role.id && - this.name === role.name && - this.color === role.color && - this.hoist === role.hoist && - this.position === role.position && - this.permissions === role.permissions && - this.managed === role.managed; - } - - /** - * When concatenated with a string, this automatically concatenates the role mention rather than the Role object. - * @returns {string} - */ - toString() { - if (this.id === this.guild.id) return '@everyone'; - return `<@&${this.id}>`; - } - - /** - * Compares the positions of two roles. - * @param {Role} role1 First role to compare - * @param {Role} role2 Second role to compare - * @returns {number} Negative number if the first role's position is lower (second role's is higher), - * positive number if the first's is higher (second's is lower), 0 if equal - */ - static comparePositions(role1, role2) { - if (role1.position === role2.position) return role2.id - role1.id; - return role1.position - role2.position; - } -} - -module.exports = Role; diff --git a/node_modules/discord.js/src/structures/TextChannel.js b/node_modules/discord.js/src/structures/TextChannel.js deleted file mode 100644 index 9697abd..0000000 --- a/node_modules/discord.js/src/structures/TextChannel.js +++ /dev/null @@ -1,96 +0,0 @@ -const GuildChannel = require('./GuildChannel'); -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Collection = require('../util/Collection'); - -/** - * Represents a guild text channel on Discord. - * @extends {GuildChannel} - * @implements {TextBasedChannel} - */ -class TextChannel extends GuildChannel { - constructor(guild, data) { - super(guild, data); - this.type = 'text'; - this.messages = new Collection(); - this._typing = new Map(); - } - - setup(data) { - super.setup(data); - - /** - * The topic of the text channel, if there is one. - * @type {?string} - */ - this.topic = data.topic; - - this.lastMessageID = data.last_message_id; - } - - /** - * A collection of members that can see this channel, mapped by their ID. - * @type {Collection} - * @readonly - */ - get members() { - const members = new Collection(); - for (const member of this.guild.members.values()) { - if (this.permissionsFor(member).hasPermission('READ_MESSAGES')) { - members.set(member.id, member); - } - } - return members; - } - - /** - * Fetch all webhooks for the channel. - * @returns {Promise>} - */ - fetchWebhooks() { - return this.client.rest.methods.getChannelWebhooks(this); - } - - /** - * Create a webhook for the channel. - * @param {string} name The name of the webhook. - * @param {BufferResolvable} avatar The avatar for the webhook. - * @returns {Promise} webhook The created webhook. - * @example - * channel.createWebhook('Snek', 'http://snek.s3.amazonaws.com/topSnek.png') - * .then(webhook => console.log(`Created Webhook ${webhook}`)) - * .catch(console.error) - */ - createWebhook(name, avatar) { - return new Promise(resolve => { - if (avatar.startsWith('data:')) { - resolve(this.client.rest.methods.createWebhook(this, name, avatar)); - } else { - this.client.resolver.resolveBuffer(avatar).then(data => - resolve(this.client.rest.methods.createWebhook(this, name, data)) - ); - } - }); - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } - fetchMessage() { return; } - fetchMessages() { return; } - fetchPinnedMessages() { return; } - startTyping() { return; } - stopTyping() { return; } - get typing() { return; } - get typingCount() { return; } - createCollector() { return; } - awaitMessages() { return; } - bulkDelete() { return; } - _cacheMessage() { return; } -} - -TextBasedChannel.applyToClass(TextChannel, true); - -module.exports = TextChannel; diff --git a/node_modules/discord.js/src/structures/User.js b/node_modules/discord.js/src/structures/User.js deleted file mode 100644 index f714828..0000000 --- a/node_modules/discord.js/src/structures/User.js +++ /dev/null @@ -1,277 +0,0 @@ -const TextBasedChannel = require('./interface/TextBasedChannel'); -const Constants = require('../util/Constants'); -const Presence = require('./Presence').Presence; - -/** - * Represents a user on Discord. - * @implements {TextBasedChannel} - */ -class User { - constructor(client, data) { - /** - * The Client that created the instance of the the User. - * @name User#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - - if (data) this.setup(data); - } - - setup(data) { - /** - * The ID of the user - * @type {string} - */ - this.id = data.id; - - /** - * The username of the user - * @type {string} - */ - this.username = data.username; - - /** - * A discriminator based on username for the user - * @type {string} - */ - this.discriminator = data.discriminator; - - /** - * The ID of the user's avatar - * @type {string} - */ - this.avatar = data.avatar; - - /** - * Whether or not the user is a bot. - * @type {boolean} - */ - this.bot = Boolean(data.bot); - - /** - * The ID of the last message sent by the user, if one was sent. - * @type {?string} - */ - this.lastMessageID = null; - } - - patch(data) { - for (const prop of ['id', 'username', 'discriminator', 'avatar', 'bot']) { - if (typeof data[prop] !== 'undefined') this[prop] = data[prop]; - } - if (data.token) this.client.token = data.token; - } - - /** - * The timestamp the user was created at - * @type {number} - * @readonly - */ - get createdTimestamp() { - return (this.id / 4194304) + 1420070400000; - } - - /** - * The time the user was created - * @type {Date} - * @readonly - */ - get createdAt() { - return new Date(this.createdTimestamp); - } - - /** - * The presence of this user - * @type {Presence} - * @readonly - */ - get presence() { - if (this.client.presences.has(this.id)) return this.client.presences.get(this.id); - for (const guild of this.client.guilds.values()) { - if (guild.presences.has(this.id)) return guild.presences.get(this.id); - } - return new Presence(); - } - - /** - * A link to the user's avatar (if they have one, otherwise null) - * @type {?string} - * @readonly - */ - get avatarURL() { - if (!this.avatar) return null; - return Constants.Endpoints.avatar(this.id, this.avatar); - } - - /** - * A link to the user's default avatar - * @type {string} - * @readonly - */ - get defaultAvatarURL() { - let defaultAvatars = Object.values(Constants.DefaultAvatars); - let defaultAvatar = this.discriminator % defaultAvatars.length; - return Constants.Endpoints.assets(`${defaultAvatars[defaultAvatar]}.png`); - } - - /** - * A link to the user's avatar if they have one. Otherwise a link to their default avatar will be returned - * @type {string} - * @readonly - */ - get displayAvatarURL() { - return this.avatarURL || this.defaultAvatarURL; - } - - /** - * The note that is set for the user - * This is only available when using a user account. - * @type {?string} - * @readonly - */ - get note() { - return this.client.user.notes.get(this.id) || null; - } - - /** - * Check whether the user is typing in a channel. - * @param {ChannelResolvable} channel The channel to check in - * @returns {boolean} - */ - typingIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - return channel._typing.has(this.id); - } - - /** - * Get the time that the user started typing. - * @param {ChannelResolvable} channel The channel to get the time in - * @returns {?Date} - */ - typingSinceIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - return channel._typing.has(this.id) ? new Date(channel._typing.get(this.id).since) : null; - } - - /** - * Get the amount of time the user has been typing in a channel for (in milliseconds), or -1 if they're not typing. - * @param {ChannelResolvable} channel The channel to get the time in - * @returns {number} - */ - typingDurationIn(channel) { - channel = this.client.resolver.resolveChannel(channel); - return channel._typing.has(this.id) ? channel._typing.get(this.id).elapsedTime : -1; - } - - /** - * The DM between the client's user and this user - * @type {?DMChannel} - */ - get dmChannel() { - return this.client.channels.filter(c => c.type === 'dm').find(c => c.recipient.id === this.id); - } - - /** - * Deletes a DM channel (if one exists) between the client and the user. Resolves with the channel if successful. - * @returns {Promise} - */ - deleteDM() { - return this.client.rest.methods.deleteChannel(this); - } - - /** - * Sends a friend request to the user - * This is only available when using a user account. - * @returns {Promise} - */ - addFriend() { - return this.client.rest.methods.addFriend(this); - } - - /** - * Removes the user from your friends - * This is only available when using a user account. - * @returns {Promise} - */ - removeFriend() { - return this.client.rest.methods.removeFriend(this); - } - - /** - * Blocks the user - * This is only available when using a user account. - * @returns {Promise} - */ - block() { - return this.client.rest.methods.blockUser(this); - } - - /** - * Unblocks the user - * This is only available when using a user account. - * @returns {Promise} - */ - unblock() { - return this.client.rest.methods.unblockUser(this); - } - - /** - * Get the profile of the user - * This is only available when using a user account. - * @returns {Promise} - */ - fetchProfile() { - return this.client.rest.methods.fetchUserProfile(this); - } - - /** - * Sets a note for the user - * This is only available when using a user account. - * @param {string} note The note to set for the user - * @returns {Promise} - */ - setNote(note) { - return this.client.rest.methods.setNote(this, note); - } - - /** - * Checks if the user is equal to another. It compares ID, username, discriminator, avatar, and bot flags. - * It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties. - * @param {User} user User to compare with - * @returns {boolean} - */ - equals(user) { - let equal = user && - this.id === user.id && - this.username === user.username && - this.discriminator === user.discriminator && - this.avatar === user.avatar && - this.bot === Boolean(user.bot); - - return equal; - } - - /** - * When concatenated with a string, this automatically concatenates the user's mention instead of the User object. - * @returns {string} - * @example - * // logs: Hello from <@123456789>! - * console.log(`Hello from ${user}!`); - */ - toString() { - return `<@${this.id}>`; - } - - // These are here only for documentation purposes - they are implemented by TextBasedChannel - send() { return; } - sendMessage() { return; } - sendEmbed() { return; } - sendFile() { return; } - sendCode() { return; } -} - -TextBasedChannel.applyToClass(User); - -module.exports = User; diff --git a/node_modules/discord.js/src/structures/UserConnection.js b/node_modules/discord.js/src/structures/UserConnection.js deleted file mode 100644 index 6ee9fc5..0000000 --- a/node_modules/discord.js/src/structures/UserConnection.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Represents a user connection (or "platform identity") - */ -class UserConnection { - constructor(user, data) { - /** - * The user that owns the Connection - * @type {User} - */ - this.user = user; - - this.setup(data); - } - - setup(data) { - /** - * The type of the Connection - * @type {string} - */ - this.type = data.type; - - /** - * The username of the connection account - * @type {string} - */ - this.name = data.name; - - /** - * The id of the connection account - * @type {string} - */ - this.id = data.id; - - /** - * Whether the connection is revoked - * @type {boolean} - */ - this.revoked = data.revoked; - - /** - * an array of partial server integrations (not yet implemented in this lib) - * @type {Object[]} - */ - this.integrations = data.integrations; - } -} - -module.exports = UserConnection; diff --git a/node_modules/discord.js/src/structures/UserProfile.js b/node_modules/discord.js/src/structures/UserProfile.js deleted file mode 100644 index 77f097c..0000000 --- a/node_modules/discord.js/src/structures/UserProfile.js +++ /dev/null @@ -1,56 +0,0 @@ -const Collection = require('../util/Collection'); -const UserConnection = require('./UserConnection'); - -/** - * Represents a user's profile on Discord. - */ -class UserProfile { - constructor(user, data) { - /** - * The owner of the profile - * @type {User} - */ - this.user = user; - - /** - * The Client that created the instance of the the UserProfile. - * @name UserProfile#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: user.client }); - - /** - * Guilds that the client user and the user share - * @type {Collection} - */ - this.mutualGuilds = new Collection(); - - /** - * The user's connections - * @type {Collection} - */ - this.connections = new Collection(); - - this.setup(data); - } - - setup(data) { - /** - * If the user has Discord Premium - * @type {boolean} - */ - this.premium = data.premium; - - for (const guild of data.mutual_guilds) { - if (this.client.guilds.has(guild.id)) { - this.mutualGuilds.set(guild.id, this.client.guilds.get(guild.id)); - } - } - for (const connection of data.connected_accounts) { - this.connections.set(connection.id, new UserConnection(this.user, connection)); - } - } -} - -module.exports = UserProfile; diff --git a/node_modules/discord.js/src/structures/VoiceChannel.js b/node_modules/discord.js/src/structures/VoiceChannel.js deleted file mode 100644 index 848a6d5..0000000 --- a/node_modules/discord.js/src/structures/VoiceChannel.js +++ /dev/null @@ -1,120 +0,0 @@ -const GuildChannel = require('./GuildChannel'); -const Collection = require('../util/Collection'); - -/** - * Represents a guild voice channel on Discord. - * @extends {GuildChannel} - */ -class VoiceChannel extends GuildChannel { - constructor(guild, data) { - super(guild, data); - - /** - * The members in this voice channel. - * @type {Collection} - */ - this.members = new Collection(); - - this.type = 'voice'; - } - - setup(data) { - super.setup(data); - - /** - * The bitrate of this voice channel - * @type {number} - */ - this.bitrate = data.bitrate; - - /** - * The maximum amount of users allowed in this channel - 0 means unlimited. - * @type {number} - */ - this.userLimit = data.user_limit; - } - - /** - * The voice connection for this voice channel, if the client is connected - * @type {?VoiceConnection} - * @readonly - */ - get connection() { - const connection = this.guild.voiceConnection; - if (connection && connection.channel.id === this.id) return connection; - return null; - } - - /** - * Checks if the client has permission join the voice channel - * @type {boolean} - */ - get joinable() { - if (this.client.browser) return false; - return this.permissionsFor(this.client.user).hasPermission('CONNECT'); - } - - /** - * Checks if the client has permission to send audio to the voice channel - * @type {boolean} - */ - get speakable() { - return this.permissionsFor(this.client.user).hasPermission('SPEAK'); - } - - /** - * Sets the bitrate of the channel - * @param {number} bitrate The new bitrate - * @returns {Promise} - * @example - * // set the bitrate of a voice channel - * voiceChannel.setBitrate(48000) - * .then(vc => console.log(`Set bitrate to ${vc.bitrate} for ${vc.name}`)) - * .catch(console.error); - */ - setBitrate(bitrate) { - return this.edit({ bitrate }); - } - - /** - * Sets the user limit of the channel - * @param {number} userLimit The new user limit - * @returns {Promise} - * @example - * // set the user limit of a voice channel - * voiceChannel.setUserLimit(42) - * .then(vc => console.log(`Set user limit to ${vc.userLimit} for ${vc.name}`)) - * .catch(console.error); - */ - setUserLimit(userLimit) { - return this.edit({ userLimit }); - } - - /** - * Attempts to join this voice channel - * @returns {Promise} - * @example - * // join a voice channel - * voiceChannel.join() - * .then(connection => console.log('Connected!')) - * .catch(console.error); - */ - join() { - if (this.client.browser) return Promise.reject(new Error('Voice connections are not available in browsers.')); - return this.client.voice.joinChannel(this); - } - - /** - * Leaves this voice channel - * @example - * // leave a voice channel - * voiceChannel.leave(); - */ - leave() { - if (this.client.browser) return; - const connection = this.client.voice.connections.get(this.guild.id); - if (connection && connection.channel.id === this.id) connection.disconnect(); - } -} - -module.exports = VoiceChannel; diff --git a/node_modules/discord.js/src/structures/Webhook.js b/node_modules/discord.js/src/structures/Webhook.js deleted file mode 100644 index 96984ff..0000000 --- a/node_modules/discord.js/src/structures/Webhook.js +++ /dev/null @@ -1,200 +0,0 @@ -const path = require('path'); -const escapeMarkdown = require('../util/EscapeMarkdown'); - -/** - * Represents a webhook - */ -class Webhook { - constructor(client, dataOrID, token) { - if (client) { - /** - * The Client that instantiated the Webhook - * @name Webhook#client - * @type {Client} - * @readonly - */ - Object.defineProperty(this, 'client', { value: client }); - if (dataOrID) this.setup(dataOrID); - } else { - this.id = dataOrID; - this.token = token; - Object.defineProperty(this, 'client', { value: this }); - } - } - - setup(data) { - /** - * The name of the webhook - * @type {string} - */ - this.name = data.name; - - /** - * The token for the webhook - * @type {string} - */ - this.token = data.token; - - /** - * The avatar for the webhook - * @type {string} - */ - this.avatar = data.avatar; - - /** - * The ID of the webhook - * @type {string} - */ - this.id = data.id; - - /** - * The guild the webhook belongs to - * @type {string} - */ - this.guildID = data.guild_id; - - /** - * The channel the webhook belongs to - * @type {string} - */ - this.channelID = data.channel_id; - - /** - * The owner of the webhook - * @type {User} - */ - if (data.user) this.owner = data.user; - } - - /** - * Options that can be passed into sendMessage, sendTTSMessage, sendFile, sendCode - * @typedef {Object} WebhookMessageOptions - * @property {boolean} [tts=false] Whether or not the message should be spoken aloud - * @property {boolean} [disableEveryone=this.options.disableEveryone] Whether or not @everyone and @here - * should be replaced with plain-text - */ - - /** - * Send a message with this webhook - * @param {StringResolvable} content The content to send. - * @param {WebhookMessageOptions} [options={}] The options to provide. - * @returns {Promise} - * @example - * // send a message - * webhook.sendMessage('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - sendMessage(content, options = {}) { - return this.client.rest.methods.sendWebhookMessage(this, content, options); - } - - /** - * Send a raw slack message with this webhook - * @param {Object} body The raw body to send. - * @returns {Promise} - * @example - * // send a slack message - * webhook.sendSlackMessage({ - * 'username': 'Wumpus', - * 'attachments': [{ - * 'pretext': 'this looks pretty cool', - * 'color': '#F0F', - * 'footer_icon': 'http://snek.s3.amazonaws.com/topSnek.png', - * 'footer': 'Powered by sneks', - * 'ts': Date.now() / 1000 - * }] - * }).catch(console.error); - */ - sendSlackMessage(body) { - return this.client.rest.methods.sendSlackWebhookMessage(this, body); - } - - /** - * Send a text-to-speech message with this webhook - * @param {StringResolvable} content The content to send - * @param {WebhookMessageOptions} [options={}] The options to provide - * @returns {Promise} - * @example - * // send a TTS message - * webhook.sendTTSMessage('hello!') - * .then(message => console.log(`Sent tts message: ${message.content}`)) - * .catch(console.error); - */ - sendTTSMessage(content, options = {}) { - Object.assign(options, { tts: true }); - return this.client.rest.methods.sendWebhookMessage(this, content, options); - } - - /** - * Send a file with this webhook - * @param {BufferResolvable} attachment The file to send - * @param {string} [fileName="file.jpg"] The name and extension of the file - * @param {StringResolvable} [content] Text message to send with the attachment - * @param {WebhookMessageOptions} [options] The options to provide - * @returns {Promise} - */ - sendFile(attachment, fileName, content, options = {}) { - if (!fileName) { - if (typeof attachment === 'string') { - fileName = path.basename(attachment); - } else if (attachment && attachment.path) { - fileName = path.basename(attachment.path); - } else { - fileName = 'file.jpg'; - } - } - return this.client.resolver.resolveBuffer(attachment).then(file => - this.client.rest.methods.sendWebhookMessage(this, content, options, { - file, - name: fileName, - }) - ); - } - - /** - * Send a code block with this webhook - * @param {string} lang Language for the code block - * @param {StringResolvable} content Content of the code block - * @param {WebhookMessageOptions} options The options to provide - * @returns {Promise} - */ - sendCode(lang, content, options = {}) { - if (options.split) { - if (typeof options.split !== 'object') options.split = {}; - if (!options.split.prepend) options.split.prepend = `\`\`\`${lang || ''}\n`; - if (!options.split.append) options.split.append = '\n```'; - } - content = escapeMarkdown(this.client.resolver.resolveString(content), true); - return this.sendMessage(`\`\`\`${lang || ''}\n${content}\n\`\`\``, options); - } - - /** - * Edit the webhook. - * @param {string} name The new name for the Webhook - * @param {BufferResolvable} avatar The new avatar for the Webhook. - * @returns {Promise} - */ - edit(name = this.name, avatar) { - if (avatar) { - return this.client.resolver.resolveBuffer(avatar).then(file => { - const dataURI = this.client.resolver.resolveBase64(file); - return this.client.rest.methods.editWebhook(this, name, dataURI); - }); - } - return this.client.rest.methods.editWebhook(this, name).then(data => { - this.setup(data); - return this; - }); - } - - /** - * Delete the webhook - * @returns {Promise} - */ - delete() { - return this.client.rest.methods.deleteWebhook(this); - } -} - -module.exports = Webhook; diff --git a/node_modules/discord.js/src/structures/interface/TextBasedChannel.js b/node_modules/discord.js/src/structures/interface/TextBasedChannel.js deleted file mode 100644 index 353c0a9..0000000 --- a/node_modules/discord.js/src/structures/interface/TextBasedChannel.js +++ /dev/null @@ -1,377 +0,0 @@ -const path = require('path'); -const Message = require('../Message'); -const MessageCollector = require('../MessageCollector'); -const Collection = require('../../util/Collection'); - - -/** - * Interface for classes that have text-channel-like features - * @interface - */ -class TextBasedChannel { - constructor() { - /** - * A collection containing the messages sent to this channel. - * @type {Collection} - */ - this.messages = new Collection(); - - /** - * The ID of the last message in the channel, if one was sent. - * @type {?string} - */ - this.lastMessageID = null; - } - - /** - * Options that can be passed into send, sendMessage, sendFile, sendEmbed, sendCode, and Message#reply - * @typedef {Object} MessageOptions - * @property {boolean} [tts=false] Whether or not the message should be spoken aloud - * @property {string} [nonce=''] The nonce for the message - * @property {Object} [embed] An embed for the message - * (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details) - * @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here - * should be replaced with plain-text - * @property {FileOptions|string} [file] A file to send with the message - * @property {string|boolean} [code] Language for optional codeblock formatting to apply - * @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if - * it exceeds the character limit. If an object is provided, these are the options for splitting the message. - */ - - /** - * @typedef {Object} FileOptions - * @property {BufferResolvable} attachment - * @property {string} [name='file.jpg'] - */ - - /** - * Options for splitting a message - * @typedef {Object} SplitOptions - * @property {number} [maxLength=1950] Maximum character length per message piece - * @property {string} [char='\n'] Character to split the message with - * @property {string} [prepend=''] Text to prepend to every piece except the first - * @property {string} [append=''] Text to append to every piece except the last - */ - - /** - * Send a message to this channel - * @param {StringResolvable} [content] Text for the message - * @param {MessageOptions} [options={}] Options for the message - * @returns {Promise} - * @example - * // send a message - * channel.send('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - send(content, options) { - if (!options && typeof content === 'object' && !(content instanceof Array)) { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - if (options.file) { - if (typeof options.file === 'string') options.file = { attachment: options.file }; - if (!options.file.name) { - if (typeof options.file.attachment === 'string') { - options.file.name = path.basename(options.file.attachment); - } else if (options.file.attachment && options.file.attachment.path) { - options.file.name = path.basename(options.file.attachment.path); - } else { - options.file.name = 'file.jpg'; - } - } - return this.client.resolver.resolveBuffer(options.file.attachment).then(file => - this.client.rest.methods.sendMessage(this, content, options, { - file, - name: options.file.name, - }) - ); - } - return this.client.rest.methods.sendMessage(this, content, options); - } - - /** - * Send a message to this channel - * @param {StringResolvable} content Text for the message - * @param {MessageOptions} [options={}] Options for the message - * @returns {Promise} - * @example - * // send a message - * channel.sendMessage('hello!') - * .then(message => console.log(`Sent message: ${message.content}`)) - * .catch(console.error); - */ - sendMessage(content, options) { - return this.send(content, options); - } - - /** - * Send an embed to this channel - * @param {RichEmbed|Object} embed Embed for the message - * @param {string} [content] Text for the message - * @param {MessageOptions} [options] Options for the message - * @returns {Promise} - */ - sendEmbed(embed, content, options) { - if (!options && typeof content === 'object') { - options = content; - content = ''; - } else if (!options) { - options = {}; - } - return this.send(content, Object.assign(options, { embed })); - } - - /** - * Send a file to this channel - * @param {BufferResolvable} attachment File to send - * @param {string} [name='file.jpg'] Name and extension of the file - * @param {StringResolvable} [content] Text for the message - * @param {MessageOptions} [options] Options for the message - * @returns {Promise} - */ - sendFile(attachment, name, content, options = {}) { - return this.send(content, Object.assign(options, { file: { attachment, name } })); - } - - /** - * Send a code block to this channel - * @param {string} lang Language for the code block - * @param {StringResolvable} content Content of the code block - * @param {MessageOptions} [options] Options for the message - * @returns {Promise} - */ - sendCode(lang, content, options = {}) { - return this.send(content, Object.assign(options, { code: lang })); - } - - /** - * Gets a single message from this channel, regardless of it being cached or not. - * This is only available when using a bot account. - * @param {string} messageID ID of the message to get - * @returns {Promise} - * @example - * // get message - * channel.fetchMessage('99539446449315840') - * .then(message => console.log(message.content)) - * .catch(console.error); - */ - fetchMessage(messageID) { - return this.client.rest.methods.getChannelMessage(this, messageID).then(data => { - const msg = data instanceof Message ? data : new Message(this, data, this.client); - this._cacheMessage(msg); - return msg; - }); - } - - /** - * The parameters to pass in when requesting previous messages from a channel. `around`, `before` and - * `after` are mutually exclusive. All the parameters are optional. - * @typedef {Object} ChannelLogsQueryOptions - * @property {number} [limit=50] Number of messages to acquire - * @property {string} [before] ID of a message to get the messages that were posted before it - * @property {string} [after] ID of a message to get the messages that were posted after it - * @property {string} [around] ID of a message to get the messages that were posted around it - */ - - /** - * Gets the past messages sent in this channel. Resolves with a collection mapping message ID's to Message objects. - * @param {ChannelLogsQueryOptions} [options={}] Query parameters to pass in - * @returns {Promise>} - * @example - * // get messages - * channel.fetchMessages({limit: 10}) - * .then(messages => console.log(`Received ${messages.size} messages`)) - * .catch(console.error); - */ - fetchMessages(options = {}) { - return this.client.rest.methods.getChannelMessages(this, options).then(data => { - const messages = new Collection(); - for (const message of data) { - const msg = new Message(this, message, this.client); - messages.set(message.id, msg); - this._cacheMessage(msg); - } - return messages; - }); - } - - /** - * Fetches the pinned messages of this channel and returns a collection of them. - * @returns {Promise>} - */ - fetchPinnedMessages() { - return this.client.rest.methods.getChannelPinnedMessages(this).then(data => { - const messages = new Collection(); - for (const message of data) { - const msg = new Message(this, message, this.client); - messages.set(message.id, msg); - this._cacheMessage(msg); - } - return messages; - }); - } - - /** - * Starts a typing indicator in the channel. - * @param {number} [count] The number of times startTyping should be considered to have been called - * @example - * // start typing in a channel - * channel.startTyping(); - */ - startTyping(count) { - if (typeof count !== 'undefined' && count < 1) throw new RangeError('Count must be at least 1.'); - if (!this.client.user._typing.has(this.id)) { - this.client.user._typing.set(this.id, { - count: count || 1, - interval: this.client.setInterval(() => { - this.client.rest.methods.sendTyping(this.id); - }, 4000), - }); - this.client.rest.methods.sendTyping(this.id); - } else { - const entry = this.client.user._typing.get(this.id); - entry.count = count || entry.count + 1; - } - } - - /** - * Stops the typing indicator in the channel. - * The indicator will only stop if this is called as many times as startTyping(). - * It can take a few seconds for the client user to stop typing. - * @param {boolean} [force=false] Whether or not to reset the call count and force the indicator to stop - * @example - * // stop typing in a channel - * channel.stopTyping(); - * @example - * // force typing to fully stop in a channel - * channel.stopTyping(true); - */ - stopTyping(force = false) { - if (this.client.user._typing.has(this.id)) { - const entry = this.client.user._typing.get(this.id); - entry.count--; - if (entry.count <= 0 || force) { - this.client.clearInterval(entry.interval); - this.client.user._typing.delete(this.id); - } - } - } - - /** - * Whether or not the typing indicator is being shown in the channel. - * @type {boolean} - * @readonly - */ - get typing() { - return this.client.user._typing.has(this.id); - } - - /** - * Number of times `startTyping` has been called. - * @type {number} - * @readonly - */ - get typingCount() { - if (this.client.user._typing.has(this.id)) return this.client.user._typing.get(this.id).count; - return 0; - } - - /** - * Creates a Message Collector - * @param {CollectorFilterFunction} filter The filter to create the collector with - * @param {CollectorOptions} [options={}] The options to pass to the collector - * @returns {MessageCollector} - * @example - * // create a message collector - * const collector = channel.createCollector( - * m => m.content.includes('discord'), - * { time: 15000 } - * ); - * collector.on('message', m => console.log(`Collected ${m.content}`)); - * collector.on('end', collected => console.log(`Collected ${collected.size} items`)); - */ - createCollector(filter, options = {}) { - return new MessageCollector(this, filter, options); - } - - /** - * An object containing the same properties as CollectorOptions, but a few more: - * @typedef {CollectorOptions} AwaitMessagesOptions - * @property {string[]} [errors] Stop/end reasons that cause the promise to reject - */ - - /** - * Similar to createCollector but in promise form. Resolves with a collection of messages that pass the specified - * filter. - * @param {CollectorFilterFunction} filter The filter function to use - * @param {AwaitMessagesOptions} [options={}] Optional options to pass to the internal collector - * @returns {Promise>} - * @example - * // await !vote messages - * const filter = m => m.content.startsWith('!vote'); - * // errors: ['time'] treats ending because of the time limit as an error - * channel.awaitMessages(filter, { max: 4, time: 60000, errors: ['time'] }) - * .then(collected => console.log(collected.size)) - * .catch(collected => console.log(`After a minute, only ${collected.size} out of 4 voted.`)); - */ - awaitMessages(filter, options = {}) { - return new Promise((resolve, reject) => { - const collector = this.createCollector(filter, options); - collector.on('end', (collection, reason) => { - if (options.errors && options.errors.includes(reason)) { - reject(collection); - } else { - resolve(collection); - } - }); - }); - } - - /** - * Bulk delete given messages. - * This is only available when using a bot account. - * @param {Collection|Message[]|number} messages Messages to delete, or number of messages to delete - * @returns {Promise>} Deleted messages - */ - bulkDelete(messages) { - if (!isNaN(messages)) return this.fetchMessages({ limit: messages }).then(msgs => this.bulkDelete(msgs)); - if (messages instanceof Array || messages instanceof Collection) { - const messageIDs = messages instanceof Collection ? messages.keyArray() : messages.map(m => m.id); - return this.client.rest.methods.bulkDeleteMessages(this, messageIDs); - } - throw new TypeError('The messages must be an Array, Collection, or number.'); - } - - _cacheMessage(message) { - const maxSize = this.client.options.messageCacheMaxSize; - if (maxSize === 0) return null; - if (this.messages.size >= maxSize && maxSize > 0) this.messages.delete(this.messages.firstKey()); - this.messages.set(message.id, message); - return message; - } -} - -exports.applyToClass = (structure, full = false) => { - const props = ['send', 'sendMessage', 'sendEmbed', 'sendFile', 'sendCode']; - if (full) { - props.push( - '_cacheMessage', - 'fetchMessages', - 'fetchMessage', - 'bulkDelete', - 'startTyping', - 'stopTyping', - 'typing', - 'typingCount', - 'fetchPinnedMessages', - 'createCollector', - 'awaitMessages' - ); - } - for (const prop of props) { - Object.defineProperty(structure.prototype, prop, Object.getOwnPropertyDescriptor(TextBasedChannel.prototype, prop)); - } -}; -- cgit v1.2.3