bot
This commit is contained in:
38
node_modules/discord.js/src/util/ActivityFlags.js
generated
vendored
Normal file
38
node_modules/discord.js/src/util/ActivityFlags.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with an {@link Activity#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class ActivityFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name ActivityFlags
|
||||
* @kind constructor
|
||||
* @memberof ActivityFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric activity flags. All available properties:
|
||||
* * `INSTANCE`
|
||||
* * `JOIN`
|
||||
* * `SPECTATE`
|
||||
* * `JOIN_REQUEST`
|
||||
* * `SYNC`
|
||||
* * `PLAY`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags}
|
||||
*/
|
||||
ActivityFlags.FLAGS = {
|
||||
INSTANCE: 1 << 0,
|
||||
JOIN: 1 << 1,
|
||||
SPECTATE: 1 << 2,
|
||||
JOIN_REQUEST: 1 << 3,
|
||||
SYNC: 1 << 4,
|
||||
PLAY: 1 << 5,
|
||||
};
|
||||
|
||||
module.exports = ActivityFlags;
|
||||
164
node_modules/discord.js/src/util/BitField.js
generated
vendored
Normal file
164
node_modules/discord.js/src/util/BitField.js
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
'use strict';
|
||||
|
||||
const { RangeError } = require('../errors');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a bitfield.
|
||||
*/
|
||||
class BitField {
|
||||
/**
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
constructor(bits) {
|
||||
/**
|
||||
* Bitfield of the packed bits
|
||||
* @type {number}
|
||||
*/
|
||||
this.bitfield = this.constructor.resolve(bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a bit, or any of multiple bits.
|
||||
* @param {BitFieldResolvable} bit Bit(s) to check for
|
||||
* @returns {boolean}
|
||||
*/
|
||||
any(bit) {
|
||||
return (this.bitfield & this.constructor.resolve(bit)) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this bitfield equals another
|
||||
* @param {BitFieldResolvable} bit Bit(s) to check for
|
||||
* @returns {boolean}
|
||||
*/
|
||||
equals(bit) {
|
||||
return this.bitfield === this.constructor.resolve(bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a bit, or multiple bits.
|
||||
* @param {BitFieldResolvable} bit Bit(s) to check for
|
||||
* @returns {boolean}
|
||||
*/
|
||||
has(bit) {
|
||||
if (Array.isArray(bit)) return bit.every(p => this.has(p));
|
||||
bit = this.constructor.resolve(bit);
|
||||
return (this.bitfield & bit) === bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all given bits that are missing from the bitfield.
|
||||
* @param {BitFieldResolvable} bits Bit(s) to check for
|
||||
* @param {...*} hasParams Additional parameters for the has method, if any
|
||||
* @returns {string[]}
|
||||
*/
|
||||
missing(bits, ...hasParams) {
|
||||
if (!Array.isArray(bits)) bits = new this.constructor(bits).toArray(false);
|
||||
return bits.filter(p => !this.has(p, ...hasParams));
|
||||
}
|
||||
|
||||
/**
|
||||
* Freezes these bits, making them immutable.
|
||||
* @returns {Readonly<BitField>} These bits
|
||||
*/
|
||||
freeze() {
|
||||
return Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds bits to these ones.
|
||||
* @param {...BitFieldResolvable} [bits] Bits to add
|
||||
* @returns {BitField} These bits or new BitField if the instance is frozen.
|
||||
*/
|
||||
add(...bits) {
|
||||
let total = 0;
|
||||
for (const bit of bits) {
|
||||
total |= this.constructor.resolve(bit);
|
||||
}
|
||||
if (Object.isFrozen(this)) return new this.constructor(this.bitfield | total);
|
||||
this.bitfield |= total;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes bits from these.
|
||||
* @param {...BitFieldResolvable} [bits] Bits to remove
|
||||
* @returns {BitField} These bits or new BitField if the instance is frozen.
|
||||
*/
|
||||
remove(...bits) {
|
||||
let total = 0;
|
||||
for (const bit of bits) {
|
||||
total |= this.constructor.resolve(bit);
|
||||
}
|
||||
if (Object.isFrozen(this)) return new this.constructor(this.bitfield & ~total);
|
||||
this.bitfield &= ~total;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an object mapping field names to a {@link boolean} indicating whether the
|
||||
* bit is available.
|
||||
* @param {...*} hasParams Additional parameters for the has method, if any
|
||||
* @returns {Object}
|
||||
*/
|
||||
serialize(...hasParams) {
|
||||
const serialized = {};
|
||||
for (const [flag, bit] of Object.entries(this.constructor.FLAGS)) serialized[flag] = this.has(bit, ...hasParams);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an {@link Array} of bitfield names based on the bits available.
|
||||
* @param {...*} hasParams Additional parameters for the has method, if any
|
||||
* @returns {string[]}
|
||||
*/
|
||||
toArray(...hasParams) {
|
||||
return Object.keys(this.constructor.FLAGS).filter(bit => this.has(bit, ...hasParams));
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return this.bitfield;
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
return this.bitfield;
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
yield* this.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a bitfield. This can be:
|
||||
* * A string (see {@link BitField.FLAGS})
|
||||
* * A bit number
|
||||
* * An instance of BitField
|
||||
* * An Array of BitFieldResolvable
|
||||
* @typedef {string|number|BitField|BitFieldResolvable[]} BitFieldResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves bitfields to their numeric form.
|
||||
* @param {BitFieldResolvable} [bit=0] - bit(s) to resolve
|
||||
* @returns {number}
|
||||
*/
|
||||
static resolve(bit = 0) {
|
||||
if (typeof bit === 'number' && bit >= 0) return bit;
|
||||
if (bit instanceof BitField) return bit.bitfield;
|
||||
if (Array.isArray(bit)) return bit.map(p => this.resolve(p)).reduce((prev, p) => prev | p, 0);
|
||||
if (typeof bit === 'string' && typeof this.FLAGS[bit] !== 'undefined') return this.FLAGS[bit];
|
||||
const error = new RangeError('BITFIELD_INVALID');
|
||||
error.bit = bit;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Numeric bitfield flags.
|
||||
* <info>Defined in extension classes</info>
|
||||
* @type {Object}
|
||||
* @abstract
|
||||
*/
|
||||
BitField.FLAGS = {};
|
||||
|
||||
module.exports = BitField;
|
||||
17
node_modules/discord.js/src/util/Collection.js
generated
vendored
Normal file
17
node_modules/discord.js/src/util/Collection.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
const BaseCollection = require('@discordjs/collection');
|
||||
const Util = require('./Util');
|
||||
|
||||
class Collection extends BaseCollection {
|
||||
toJSON() {
|
||||
return this.map(e => (typeof e.toJSON === 'function' ? e.toJSON() : Util.flatten(e)));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Collection;
|
||||
|
||||
/**
|
||||
* @external Collection
|
||||
* @see {@link https://discord.js.org/#/docs/collection/master/class/Collection}
|
||||
*/
|
||||
678
node_modules/discord.js/src/util/Constants.js
generated
vendored
Normal file
678
node_modules/discord.js/src/util/Constants.js
generated
vendored
Normal file
@@ -0,0 +1,678 @@
|
||||
'use strict';
|
||||
|
||||
const Package = (exports.Package = require('../../package.json'));
|
||||
const { Error, RangeError } = require('../errors');
|
||||
const browser = (exports.browser = typeof window !== 'undefined');
|
||||
|
||||
/**
|
||||
* Options for a client.
|
||||
* @typedef {Object} ClientOptions
|
||||
* @property {number|number[]|string} [shards] ID of the shard to run, or an array of shard IDs. If not specified,
|
||||
* the client will spawn {@link ClientOptions#shardCount} shards. If set to `auto`, it will fetch the
|
||||
* recommended amount of shards from Discord and spawn that amount
|
||||
* @property {number} [shardCount=1] The total amount of shards used by all processes of this bot
|
||||
* (e.g. recommended shard count, shard count of the ShardingManager)
|
||||
* @property {number} [messageCacheMaxSize=200] Maximum number of messages to cache per channel
|
||||
* (-1 or Infinity for unlimited - don't do this without message sweeping, otherwise memory usage will climb
|
||||
* indefinitely)
|
||||
* @property {number} [messageCacheLifetime=0] How long a message should stay in the cache until it is considered
|
||||
* sweepable (in seconds, 0 for forever)
|
||||
* @property {number} [messageSweepInterval=0] How frequently to remove messages from the cache that are older than
|
||||
* the message cache lifetime (in seconds, 0 for never)
|
||||
* @property {number} [messageEditHistoryMaxSize=-1] Maximum number of previous versions to hold for an edited message
|
||||
* (-1 or Infinity for unlimited - don't do this without sweeping, otherwise memory usage may climb indefinitely.)
|
||||
* @property {boolean} [fetchAllMembers=false] Whether to cache all guild members and users upon startup, as well as
|
||||
* upon joining a guild (should be avoided whenever possible)
|
||||
* @property {DisableMentionType} [disableMentions='none'] Default value for {@link MessageOptions#disableMentions}
|
||||
* @property {MessageMentionOptions} [allowedMentions] Default value for {@link MessageOptions#allowedMentions}
|
||||
* @property {PartialType[]} [partials] Structures allowed to be partial. This means events can be emitted even when
|
||||
* they're missing all the data for a particular structure. See the "Partials" topic listed in the sidebar for some
|
||||
* important usage information, as partials require you to put checks in place when handling data.
|
||||
* @property {number} [restWsBridgeTimeout=5000] Maximum time permitted between REST responses and their
|
||||
* corresponding websocket events
|
||||
* @property {number} [restTimeOffset=500] Extra time in milliseconds to wait before continuing to make REST
|
||||
* requests (higher values will reduce rate-limiting errors on bad connections)
|
||||
* @property {number} [restRequestTimeout=15000] Time to wait before cancelling a REST request, in milliseconds
|
||||
* @property {number} [restSweepInterval=60] How frequently to delete inactive request buckets, in seconds
|
||||
* (or 0 for never)
|
||||
* @property {number} [retryLimit=1] How many times to retry on 5XX errors (Infinity for indefinite amount of retries)
|
||||
* @property {PresenceData} [presence] Presence data to use upon login
|
||||
* @property {WebsocketOptions} [ws] Options for the WebSocket
|
||||
* @property {HTTPOptions} [http] HTTP options
|
||||
*/
|
||||
exports.DefaultOptions = {
|
||||
shardCount: 1,
|
||||
messageCacheMaxSize: 200,
|
||||
messageCacheLifetime: 0,
|
||||
messageSweepInterval: 0,
|
||||
messageEditHistoryMaxSize: -1,
|
||||
fetchAllMembers: false,
|
||||
disableMentions: 'none',
|
||||
partials: [],
|
||||
restWsBridgeTimeout: 5000,
|
||||
restRequestTimeout: 15000,
|
||||
retryLimit: 1,
|
||||
restTimeOffset: 500,
|
||||
restSweepInterval: 60,
|
||||
presence: {},
|
||||
|
||||
/**
|
||||
* WebSocket options (these are left as snake_case to match the API)
|
||||
* @typedef {Object} WebsocketOptions
|
||||
* @property {number} [large_threshold=50] Number of members in a guild after which offline users will no longer be
|
||||
* sent in the initial guild member list, must be between 50 and 250
|
||||
* @property {IntentsResolvable} [intents] Intents to enable for this connection
|
||||
*/
|
||||
ws: {
|
||||
large_threshold: 50,
|
||||
compress: false,
|
||||
properties: {
|
||||
$os: browser ? 'browser' : process.platform,
|
||||
$browser: 'discord.js',
|
||||
$device: 'discord.js',
|
||||
},
|
||||
version: 6,
|
||||
},
|
||||
|
||||
/**
|
||||
* HTTP options
|
||||
* @typedef {Object} HTTPOptions
|
||||
* @property {number} [version=7] API version to use
|
||||
* @property {string} [api='https://discord.com/api'] Base url of the API
|
||||
* @property {string} [cdn='https://cdn.discordapp.com'] Base url of the CDN
|
||||
* @property {string} [invite='https://discord.gg'] Base url of invites
|
||||
* @property {string} [template='https://discord.new'] Base url of templates
|
||||
*/
|
||||
http: {
|
||||
version: 7,
|
||||
api: 'https://discord.com/api',
|
||||
cdn: 'https://cdn.discordapp.com',
|
||||
invite: 'https://discord.gg',
|
||||
template: 'https://discord.new',
|
||||
},
|
||||
};
|
||||
|
||||
exports.UserAgent = browser
|
||||
? null
|
||||
: `DiscordBot (${Package.homepage.split('#')[0]}, ${Package.version}) Node.js/${process.version}`;
|
||||
|
||||
exports.WSCodes = {
|
||||
1000: 'WS_CLOSE_REQUESTED',
|
||||
4004: 'TOKEN_INVALID',
|
||||
4010: 'SHARDING_INVALID',
|
||||
4011: 'SHARDING_REQUIRED',
|
||||
4013: 'INVALID_INTENTS',
|
||||
4014: 'DISALLOWED_INTENTS',
|
||||
};
|
||||
|
||||
const AllowedImageFormats = ['webp', 'png', 'jpg', 'jpeg', 'gif'];
|
||||
|
||||
const AllowedImageSizes = Array.from({ length: 9 }, (e, i) => 2 ** (i + 4));
|
||||
|
||||
function makeImageUrl(root, { format = 'webp', size } = {}) {
|
||||
if (format && !AllowedImageFormats.includes(format)) throw new Error('IMAGE_FORMAT', format);
|
||||
if (size && !AllowedImageSizes.includes(size)) throw new RangeError('IMAGE_SIZE', size);
|
||||
return `${root}.${format}${size ? `?size=${size}` : ''}`;
|
||||
}
|
||||
/**
|
||||
* Options for Image URLs.
|
||||
* @typedef {Object} ImageURLOptions
|
||||
* @property {string} [format] One of `webp`, `png`, `jpg`, `jpeg`, `gif`. If no format is provided,
|
||||
* defaults to `webp`.
|
||||
* @property {boolean} [dynamic] If true, the format will dynamically change to `gif` for
|
||||
* animated avatars; the default is false.
|
||||
* @property {number} [size] One of `16`, `32`, `64`, `128`, `256`, `512`, `1024`, `2048`, `4096`
|
||||
*/
|
||||
|
||||
exports.Endpoints = {
|
||||
CDN(root) {
|
||||
return {
|
||||
Emoji: (emojiID, format = 'png') => `${root}/emojis/${emojiID}.${format}`,
|
||||
Asset: name => `${root}/assets/${name}`,
|
||||
DefaultAvatar: discriminator => `${root}/embed/avatars/${discriminator}.png`,
|
||||
Avatar: (userID, hash, format = 'webp', size, dynamic = false) => {
|
||||
if (dynamic) format = hash.startsWith('a_') ? 'gif' : format;
|
||||
return makeImageUrl(`${root}/avatars/${userID}/${hash}`, { format, size });
|
||||
},
|
||||
Banner: (guildID, hash, format = 'webp', size) =>
|
||||
makeImageUrl(`${root}/banners/${guildID}/${hash}`, { format, size }),
|
||||
Icon: (guildID, hash, format = 'webp', size, dynamic = false) => {
|
||||
if (dynamic) format = hash.startsWith('a_') ? 'gif' : format;
|
||||
return makeImageUrl(`${root}/icons/${guildID}/${hash}`, { format, size });
|
||||
},
|
||||
AppIcon: (clientID, hash, { format = 'webp', size } = {}) =>
|
||||
makeImageUrl(`${root}/app-icons/${clientID}/${hash}`, { size, format }),
|
||||
AppAsset: (clientID, hash, { format = 'webp', size } = {}) =>
|
||||
makeImageUrl(`${root}/app-assets/${clientID}/${hash}`, { size, format }),
|
||||
GDMIcon: (channelID, hash, format = 'webp', size) =>
|
||||
makeImageUrl(`${root}/channel-icons/${channelID}/${hash}`, { size, format }),
|
||||
Splash: (guildID, hash, format = 'webp', size) =>
|
||||
makeImageUrl(`${root}/splashes/${guildID}/${hash}`, { size, format }),
|
||||
DiscoverySplash: (guildID, hash, format = 'webp', size) =>
|
||||
makeImageUrl(`${root}/discovery-splashes/${guildID}/${hash}`, { size, format }),
|
||||
TeamIcon: (teamID, hash, { format = 'webp', size } = {}) =>
|
||||
makeImageUrl(`${root}/team-icons/${teamID}/${hash}`, { size, format }),
|
||||
};
|
||||
},
|
||||
invite: (root, code) => `${root}/${code}`,
|
||||
botGateway: '/gateway/bot',
|
||||
};
|
||||
|
||||
/**
|
||||
* The current status of the client. Here are the available statuses:
|
||||
* * READY: 0
|
||||
* * CONNECTING: 1
|
||||
* * RECONNECTING: 2
|
||||
* * IDLE: 3
|
||||
* * NEARLY: 4
|
||||
* * DISCONNECTED: 5
|
||||
* * WAITING_FOR_GUILDS: 6
|
||||
* * IDENTIFYING: 7
|
||||
* * RESUMING: 8
|
||||
* @typedef {number} Status
|
||||
*/
|
||||
exports.Status = {
|
||||
READY: 0,
|
||||
CONNECTING: 1,
|
||||
RECONNECTING: 2,
|
||||
IDLE: 3,
|
||||
NEARLY: 4,
|
||||
DISCONNECTED: 5,
|
||||
WAITING_FOR_GUILDS: 6,
|
||||
IDENTIFYING: 7,
|
||||
RESUMING: 8,
|
||||
};
|
||||
|
||||
/**
|
||||
* The current status of a voice connection. Here are the available statuses:
|
||||
* * CONNECTED: 0
|
||||
* * CONNECTING: 1
|
||||
* * AUTHENTICATING: 2
|
||||
* * RECONNECTING: 3
|
||||
* * DISCONNECTED: 4
|
||||
* @typedef {number} VoiceStatus
|
||||
*/
|
||||
exports.VoiceStatus = {
|
||||
CONNECTED: 0,
|
||||
CONNECTING: 1,
|
||||
AUTHENTICATING: 2,
|
||||
RECONNECTING: 3,
|
||||
DISCONNECTED: 4,
|
||||
};
|
||||
|
||||
exports.OPCodes = {
|
||||
DISPATCH: 0,
|
||||
HEARTBEAT: 1,
|
||||
IDENTIFY: 2,
|
||||
STATUS_UPDATE: 3,
|
||||
VOICE_STATE_UPDATE: 4,
|
||||
VOICE_GUILD_PING: 5,
|
||||
RESUME: 6,
|
||||
RECONNECT: 7,
|
||||
REQUEST_GUILD_MEMBERS: 8,
|
||||
INVALID_SESSION: 9,
|
||||
HELLO: 10,
|
||||
HEARTBEAT_ACK: 11,
|
||||
};
|
||||
|
||||
exports.VoiceOPCodes = {
|
||||
IDENTIFY: 0,
|
||||
SELECT_PROTOCOL: 1,
|
||||
READY: 2,
|
||||
HEARTBEAT: 3,
|
||||
SESSION_DESCRIPTION: 4,
|
||||
SPEAKING: 5,
|
||||
HELLO: 8,
|
||||
CLIENT_CONNECT: 12,
|
||||
CLIENT_DISCONNECT: 13,
|
||||
};
|
||||
|
||||
exports.Events = {
|
||||
RATE_LIMIT: 'rateLimit',
|
||||
CLIENT_READY: 'ready',
|
||||
GUILD_CREATE: 'guildCreate',
|
||||
GUILD_DELETE: 'guildDelete',
|
||||
GUILD_UPDATE: 'guildUpdate',
|
||||
GUILD_UNAVAILABLE: 'guildUnavailable',
|
||||
GUILD_AVAILABLE: 'guildAvailable',
|
||||
GUILD_MEMBER_ADD: 'guildMemberAdd',
|
||||
GUILD_MEMBER_REMOVE: 'guildMemberRemove',
|
||||
GUILD_MEMBER_UPDATE: 'guildMemberUpdate',
|
||||
GUILD_MEMBER_AVAILABLE: 'guildMemberAvailable',
|
||||
GUILD_MEMBER_SPEAKING: 'guildMemberSpeaking',
|
||||
GUILD_MEMBERS_CHUNK: 'guildMembersChunk',
|
||||
GUILD_INTEGRATIONS_UPDATE: 'guildIntegrationsUpdate',
|
||||
GUILD_ROLE_CREATE: 'roleCreate',
|
||||
GUILD_ROLE_DELETE: 'roleDelete',
|
||||
INVITE_CREATE: 'inviteCreate',
|
||||
INVITE_DELETE: 'inviteDelete',
|
||||
GUILD_ROLE_UPDATE: 'roleUpdate',
|
||||
GUILD_EMOJI_CREATE: 'emojiCreate',
|
||||
GUILD_EMOJI_DELETE: 'emojiDelete',
|
||||
GUILD_EMOJI_UPDATE: 'emojiUpdate',
|
||||
GUILD_BAN_ADD: 'guildBanAdd',
|
||||
GUILD_BAN_REMOVE: 'guildBanRemove',
|
||||
CHANNEL_CREATE: 'channelCreate',
|
||||
CHANNEL_DELETE: 'channelDelete',
|
||||
CHANNEL_UPDATE: 'channelUpdate',
|
||||
CHANNEL_PINS_UPDATE: 'channelPinsUpdate',
|
||||
MESSAGE_CREATE: 'message',
|
||||
MESSAGE_DELETE: 'messageDelete',
|
||||
MESSAGE_UPDATE: 'messageUpdate',
|
||||
MESSAGE_BULK_DELETE: 'messageDeleteBulk',
|
||||
MESSAGE_REACTION_ADD: 'messageReactionAdd',
|
||||
MESSAGE_REACTION_REMOVE: 'messageReactionRemove',
|
||||
MESSAGE_REACTION_REMOVE_ALL: 'messageReactionRemoveAll',
|
||||
MESSAGE_REACTION_REMOVE_EMOJI: 'messageReactionRemoveEmoji',
|
||||
USER_UPDATE: 'userUpdate',
|
||||
PRESENCE_UPDATE: 'presenceUpdate',
|
||||
VOICE_SERVER_UPDATE: 'voiceServerUpdate',
|
||||
VOICE_STATE_UPDATE: 'voiceStateUpdate',
|
||||
VOICE_BROADCAST_SUBSCRIBE: 'subscribe',
|
||||
VOICE_BROADCAST_UNSUBSCRIBE: 'unsubscribe',
|
||||
TYPING_START: 'typingStart',
|
||||
TYPING_STOP: 'typingStop',
|
||||
WEBHOOKS_UPDATE: 'webhookUpdate',
|
||||
ERROR: 'error',
|
||||
WARN: 'warn',
|
||||
DEBUG: 'debug',
|
||||
SHARD_DISCONNECT: 'shardDisconnect',
|
||||
SHARD_ERROR: 'shardError',
|
||||
SHARD_RECONNECTING: 'shardReconnecting',
|
||||
SHARD_READY: 'shardReady',
|
||||
SHARD_RESUME: 'shardResume',
|
||||
INVALIDATED: 'invalidated',
|
||||
RAW: 'raw',
|
||||
};
|
||||
|
||||
exports.ShardEvents = {
|
||||
CLOSE: 'close',
|
||||
DESTROYED: 'destroyed',
|
||||
INVALID_SESSION: 'invalidSession',
|
||||
READY: 'ready',
|
||||
RESUMED: 'resumed',
|
||||
ALL_READY: 'allReady',
|
||||
};
|
||||
|
||||
/**
|
||||
* The type of Structure allowed to be a partial:
|
||||
* * USER
|
||||
* * CHANNEL (only affects DMChannels)
|
||||
* * GUILD_MEMBER
|
||||
* * MESSAGE
|
||||
* * REACTION
|
||||
* <warn>Partials require you to put checks in place when handling data, read the Partials topic listed in the
|
||||
* sidebar for more information.</warn>
|
||||
* @typedef {string} PartialType
|
||||
*/
|
||||
exports.PartialTypes = keyMirror(['USER', 'CHANNEL', 'GUILD_MEMBER', 'MESSAGE', 'REACTION']);
|
||||
|
||||
/**
|
||||
* The type of a websocket message event, e.g. `MESSAGE_CREATE`. Here are the available events:
|
||||
* * READY
|
||||
* * RESUMED
|
||||
* * GUILD_CREATE
|
||||
* * GUILD_DELETE
|
||||
* * GUILD_UPDATE
|
||||
* * INVITE_CREATE
|
||||
* * INVITE_DELETE
|
||||
* * GUILD_MEMBER_ADD
|
||||
* * GUILD_MEMBER_REMOVE
|
||||
* * GUILD_MEMBER_UPDATE
|
||||
* * GUILD_MEMBERS_CHUNK
|
||||
* * GUILD_INTEGRATIONS_UPDATE
|
||||
* * GUILD_ROLE_CREATE
|
||||
* * GUILD_ROLE_DELETE
|
||||
* * GUILD_ROLE_UPDATE
|
||||
* * GUILD_BAN_ADD
|
||||
* * GUILD_BAN_REMOVE
|
||||
* * GUILD_EMOJIS_UPDATE
|
||||
* * CHANNEL_CREATE
|
||||
* * CHANNEL_DELETE
|
||||
* * CHANNEL_UPDATE
|
||||
* * CHANNEL_PINS_UPDATE
|
||||
* * MESSAGE_CREATE
|
||||
* * MESSAGE_DELETE
|
||||
* * MESSAGE_UPDATE
|
||||
* * MESSAGE_DELETE_BULK
|
||||
* * MESSAGE_REACTION_ADD
|
||||
* * MESSAGE_REACTION_REMOVE
|
||||
* * MESSAGE_REACTION_REMOVE_ALL
|
||||
* * MESSAGE_REACTION_REMOVE_EMOJI
|
||||
* * USER_UPDATE
|
||||
* * PRESENCE_UPDATE
|
||||
* * TYPING_START
|
||||
* * VOICE_STATE_UPDATE
|
||||
* * VOICE_SERVER_UPDATE
|
||||
* * WEBHOOKS_UPDATE
|
||||
* @typedef {string} WSEventType
|
||||
*/
|
||||
exports.WSEvents = keyMirror([
|
||||
'READY',
|
||||
'RESUMED',
|
||||
'GUILD_CREATE',
|
||||
'GUILD_DELETE',
|
||||
'GUILD_UPDATE',
|
||||
'INVITE_CREATE',
|
||||
'INVITE_DELETE',
|
||||
'GUILD_MEMBER_ADD',
|
||||
'GUILD_MEMBER_REMOVE',
|
||||
'GUILD_MEMBER_UPDATE',
|
||||
'GUILD_MEMBERS_CHUNK',
|
||||
'GUILD_INTEGRATIONS_UPDATE',
|
||||
'GUILD_ROLE_CREATE',
|
||||
'GUILD_ROLE_DELETE',
|
||||
'GUILD_ROLE_UPDATE',
|
||||
'GUILD_BAN_ADD',
|
||||
'GUILD_BAN_REMOVE',
|
||||
'GUILD_EMOJIS_UPDATE',
|
||||
'CHANNEL_CREATE',
|
||||
'CHANNEL_DELETE',
|
||||
'CHANNEL_UPDATE',
|
||||
'CHANNEL_PINS_UPDATE',
|
||||
'MESSAGE_CREATE',
|
||||
'MESSAGE_DELETE',
|
||||
'MESSAGE_UPDATE',
|
||||
'MESSAGE_DELETE_BULK',
|
||||
'MESSAGE_REACTION_ADD',
|
||||
'MESSAGE_REACTION_REMOVE',
|
||||
'MESSAGE_REACTION_REMOVE_ALL',
|
||||
'MESSAGE_REACTION_REMOVE_EMOJI',
|
||||
'USER_UPDATE',
|
||||
'PRESENCE_UPDATE',
|
||||
'TYPING_START',
|
||||
'VOICE_STATE_UPDATE',
|
||||
'VOICE_SERVER_UPDATE',
|
||||
'WEBHOOKS_UPDATE',
|
||||
]);
|
||||
|
||||
/**
|
||||
* The type of a message, e.g. `DEFAULT`. Here are the available types:
|
||||
* * DEFAULT
|
||||
* * RECIPIENT_ADD
|
||||
* * RECIPIENT_REMOVE
|
||||
* * CALL
|
||||
* * CHANNEL_NAME_CHANGE
|
||||
* * CHANNEL_ICON_CHANGE
|
||||
* * PINS_ADD
|
||||
* * GUILD_MEMBER_JOIN
|
||||
* * USER_PREMIUM_GUILD_SUBSCRIPTION
|
||||
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1
|
||||
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2
|
||||
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3
|
||||
* * CHANNEL_FOLLOW_ADD
|
||||
* * GUILD_DISCOVERY_DISQUALIFIED
|
||||
* * GUILD_DISCOVERY_REQUALIFIED
|
||||
* @typedef {string} MessageType
|
||||
*/
|
||||
exports.MessageTypes = [
|
||||
'DEFAULT',
|
||||
'RECIPIENT_ADD',
|
||||
'RECIPIENT_REMOVE',
|
||||
'CALL',
|
||||
'CHANNEL_NAME_CHANGE',
|
||||
'CHANNEL_ICON_CHANGE',
|
||||
'PINS_ADD',
|
||||
'GUILD_MEMBER_JOIN',
|
||||
'USER_PREMIUM_GUILD_SUBSCRIPTION',
|
||||
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1',
|
||||
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2',
|
||||
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3',
|
||||
'CHANNEL_FOLLOW_ADD',
|
||||
null,
|
||||
'GUILD_DISCOVERY_DISQUALIFIED',
|
||||
'GUILD_DISCOVERY_REQUALIFIED',
|
||||
];
|
||||
|
||||
/**
|
||||
* <info>Bots cannot set a `CUSTOM_STATUS`, it is only for custom statuses received from users</info>
|
||||
* The type of an activity of a users presence, e.g. `PLAYING`. Here are the available types:
|
||||
* * PLAYING
|
||||
* * STREAMING
|
||||
* * LISTENING
|
||||
* * WATCHING
|
||||
* * CUSTOM_STATUS
|
||||
* * COMPETING
|
||||
* @typedef {string} ActivityType
|
||||
*/
|
||||
exports.ActivityTypes = ['PLAYING', 'STREAMING', 'LISTENING', 'WATCHING', 'CUSTOM_STATUS', 'COMPETING'];
|
||||
|
||||
exports.ChannelTypes = {
|
||||
TEXT: 0,
|
||||
DM: 1,
|
||||
VOICE: 2,
|
||||
GROUP: 3,
|
||||
CATEGORY: 4,
|
||||
NEWS: 5,
|
||||
STORE: 6,
|
||||
};
|
||||
|
||||
exports.ClientApplicationAssetTypes = {
|
||||
SMALL: 1,
|
||||
BIG: 2,
|
||||
};
|
||||
|
||||
exports.Colors = {
|
||||
DEFAULT: 0x000000,
|
||||
WHITE: 0xffffff,
|
||||
AQUA: 0x1abc9c,
|
||||
GREEN: 0x2ecc71,
|
||||
BLUE: 0x3498db,
|
||||
YELLOW: 0xffff00,
|
||||
PURPLE: 0x9b59b6,
|
||||
LUMINOUS_VIVID_PINK: 0xe91e63,
|
||||
GOLD: 0xf1c40f,
|
||||
ORANGE: 0xe67e22,
|
||||
RED: 0xe74c3c,
|
||||
GREY: 0x95a5a6,
|
||||
NAVY: 0x34495e,
|
||||
DARK_AQUA: 0x11806a,
|
||||
DARK_GREEN: 0x1f8b4c,
|
||||
DARK_BLUE: 0x206694,
|
||||
DARK_PURPLE: 0x71368a,
|
||||
DARK_VIVID_PINK: 0xad1457,
|
||||
DARK_GOLD: 0xc27c0e,
|
||||
DARK_ORANGE: 0xa84300,
|
||||
DARK_RED: 0x992d22,
|
||||
DARK_GREY: 0x979c9f,
|
||||
DARKER_GREY: 0x7f8c8d,
|
||||
LIGHT_GREY: 0xbcc0c0,
|
||||
DARK_NAVY: 0x2c3e50,
|
||||
BLURPLE: 0x7289da,
|
||||
GREYPLE: 0x99aab5,
|
||||
DARK_BUT_NOT_BLACK: 0x2c2f33,
|
||||
NOT_QUITE_BLACK: 0x23272a,
|
||||
};
|
||||
|
||||
/**
|
||||
* The value set for the explicit content filter levels for a guild:
|
||||
* * DISABLED
|
||||
* * MEMBERS_WITHOUT_ROLES
|
||||
* * ALL_MEMBERS
|
||||
* @typedef {string} ExplicitContentFilterLevel
|
||||
*/
|
||||
exports.ExplicitContentFilterLevels = ['DISABLED', 'MEMBERS_WITHOUT_ROLES', 'ALL_MEMBERS'];
|
||||
|
||||
/**
|
||||
* The value set for the verification levels for a guild:
|
||||
* * NONE
|
||||
* * LOW
|
||||
* * MEDIUM
|
||||
* * HIGH
|
||||
* * VERY_HIGH
|
||||
* @typedef {string} VerificationLevel
|
||||
*/
|
||||
exports.VerificationLevels = ['NONE', 'LOW', 'MEDIUM', 'HIGH', 'VERY_HIGH'];
|
||||
|
||||
/**
|
||||
* An error encountered while performing an API request. Here are the potential errors:
|
||||
* * UNKNOWN_ACCOUNT
|
||||
* * UNKNOWN_APPLICATION
|
||||
* * UNKNOWN_CHANNEL
|
||||
* * UNKNOWN_GUILD
|
||||
* * UNKNOWN_INTEGRATION
|
||||
* * UNKNOWN_INVITE
|
||||
* * UNKNOWN_MEMBER
|
||||
* * UNKNOWN_MESSAGE
|
||||
* * UNKNOWN_OVERWRITE
|
||||
* * UNKNOWN_PROVIDER
|
||||
* * UNKNOWN_ROLE
|
||||
* * UNKNOWN_TOKEN
|
||||
* * UNKNOWN_USER
|
||||
* * UNKNOWN_EMOJI
|
||||
* * UNKNOWN_WEBHOOK
|
||||
* * UNKNOWN_BAN
|
||||
* * UNKNOWN_GUILD_TEMPLATE
|
||||
* * BOT_PROHIBITED_ENDPOINT
|
||||
* * BOT_ONLY_ENDPOINT
|
||||
* * CHANNEL_HIT_WRITE_RATELIMIT
|
||||
* * MAXIMUM_GUILDS
|
||||
* * MAXIMUM_FRIENDS
|
||||
* * MAXIMUM_PINS
|
||||
* * MAXIMUM_ROLES
|
||||
* * MAXIMUM_WEBHOOKS
|
||||
* * MAXIMUM_REACTIONS
|
||||
* * MAXIMUM_CHANNELS
|
||||
* * MAXIMUM_ATTACHMENTS
|
||||
* * MAXIMUM_INVITES
|
||||
* * GUILD_ALREADY_HAS_TEMPLATE
|
||||
* * UNAUTHORIZED
|
||||
* * ACCOUNT_VERIFICATION_REQUIRED
|
||||
* * REQUEST_ENTITY_TOO_LARGE
|
||||
* * FEATURE_TEMPORARILY_DISABLED
|
||||
* * USER_BANNED
|
||||
* * ALREADY_CROSSPOSTED
|
||||
* * MISSING_ACCESS
|
||||
* * INVALID_ACCOUNT_TYPE
|
||||
* * CANNOT_EXECUTE_ON_DM
|
||||
* * EMBED_DISABLED
|
||||
* * CANNOT_EDIT_MESSAGE_BY_OTHER
|
||||
* * CANNOT_SEND_EMPTY_MESSAGE
|
||||
* * CANNOT_MESSAGE_USER
|
||||
* * CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL
|
||||
* * CHANNEL_VERIFICATION_LEVEL_TOO_HIGH
|
||||
* * OAUTH2_APPLICATION_BOT_ABSENT
|
||||
* * MAXIMUM_OAUTH2_APPLICATIONS
|
||||
* * INVALID_OAUTH_STATE
|
||||
* * MISSING_PERMISSIONS
|
||||
* * INVALID_AUTHENTICATION_TOKEN
|
||||
* * NOTE_TOO_LONG
|
||||
* * INVALID_BULK_DELETE_QUANTITY
|
||||
* * CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL
|
||||
* * INVALID_OR_TAKEN_INVITE_CODE
|
||||
* * CANNOT_EXECUTE_ON_SYSTEM_MESSAGE
|
||||
* * INVALID_OAUTH_TOKEN
|
||||
* * BULK_DELETE_MESSAGE_TOO_OLD
|
||||
* * INVALID_FORM_BODY
|
||||
* * INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT
|
||||
* * INVALID_API_VERSION
|
||||
* * CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL
|
||||
* * REACTION_BLOCKED
|
||||
* * RESOURCE_OVERLOADED
|
||||
* @typedef {string} APIError
|
||||
*/
|
||||
exports.APIErrors = {
|
||||
UNKNOWN_ACCOUNT: 10001,
|
||||
UNKNOWN_APPLICATION: 10002,
|
||||
UNKNOWN_CHANNEL: 10003,
|
||||
UNKNOWN_GUILD: 10004,
|
||||
UNKNOWN_INTEGRATION: 10005,
|
||||
UNKNOWN_INVITE: 10006,
|
||||
UNKNOWN_MEMBER: 10007,
|
||||
UNKNOWN_MESSAGE: 10008,
|
||||
UNKNOWN_OVERWRITE: 10009,
|
||||
UNKNOWN_PROVIDER: 10010,
|
||||
UNKNOWN_ROLE: 10011,
|
||||
UNKNOWN_TOKEN: 10012,
|
||||
UNKNOWN_USER: 10013,
|
||||
UNKNOWN_EMOJI: 10014,
|
||||
UNKNOWN_WEBHOOK: 10015,
|
||||
UNKNOWN_BAN: 10026,
|
||||
UNKNOWN_GUILD_TEMPLATE: 10057,
|
||||
BOT_PROHIBITED_ENDPOINT: 20001,
|
||||
BOT_ONLY_ENDPOINT: 20002,
|
||||
CHANNEL_HIT_WRITE_RATELIMIT: 20028,
|
||||
MAXIMUM_GUILDS: 30001,
|
||||
MAXIMUM_FRIENDS: 30002,
|
||||
MAXIMUM_PINS: 30003,
|
||||
MAXIMUM_ROLES: 30005,
|
||||
MAXIMUM_WEBHOOKS: 30007,
|
||||
MAXIMUM_REACTIONS: 30010,
|
||||
MAXIMUM_CHANNELS: 30013,
|
||||
MAXIMUM_ATTACHMENTS: 30015,
|
||||
MAXIMUM_INVITES: 30016,
|
||||
GUILD_ALREADY_HAS_TEMPLATE: 30031,
|
||||
UNAUTHORIZED: 40001,
|
||||
ACCOUNT_VERIFICATION_REQUIRED: 40002,
|
||||
REQUEST_ENTITY_TOO_LARGE: 40005,
|
||||
FEATURE_TEMPORARILY_DISABLED: 40006,
|
||||
USER_BANNED: 40007,
|
||||
ALREADY_CROSSPOSTED: 40033,
|
||||
MISSING_ACCESS: 50001,
|
||||
INVALID_ACCOUNT_TYPE: 50002,
|
||||
CANNOT_EXECUTE_ON_DM: 50003,
|
||||
EMBED_DISABLED: 50004,
|
||||
CANNOT_EDIT_MESSAGE_BY_OTHER: 50005,
|
||||
CANNOT_SEND_EMPTY_MESSAGE: 50006,
|
||||
CANNOT_MESSAGE_USER: 50007,
|
||||
CANNOT_SEND_MESSAGES_IN_VOICE_CHANNEL: 50008,
|
||||
CHANNEL_VERIFICATION_LEVEL_TOO_HIGH: 50009,
|
||||
OAUTH2_APPLICATION_BOT_ABSENT: 50010,
|
||||
MAXIMUM_OAUTH2_APPLICATIONS: 50011,
|
||||
INVALID_OAUTH_STATE: 50012,
|
||||
MISSING_PERMISSIONS: 50013,
|
||||
INVALID_AUTHENTICATION_TOKEN: 50014,
|
||||
NOTE_TOO_LONG: 50015,
|
||||
INVALID_BULK_DELETE_QUANTITY: 50016,
|
||||
CANNOT_PIN_MESSAGE_IN_OTHER_CHANNEL: 50019,
|
||||
INVALID_OR_TAKEN_INVITE_CODE: 50020,
|
||||
CANNOT_EXECUTE_ON_SYSTEM_MESSAGE: 50021,
|
||||
INVALID_OAUTH_TOKEN: 50025,
|
||||
BULK_DELETE_MESSAGE_TOO_OLD: 50034,
|
||||
INVALID_FORM_BODY: 50035,
|
||||
INVITE_ACCEPTED_TO_GUILD_NOT_CONTAINING_BOT: 50036,
|
||||
INVALID_API_VERSION: 50041,
|
||||
CANNOT_DELETE_COMMUNITY_REQUIRED_CHANNEL: 50074,
|
||||
REACTION_BLOCKED: 90001,
|
||||
RESOURCE_OVERLOADED: 130000,
|
||||
};
|
||||
|
||||
/**
|
||||
* The value set for a guild's default message notifications, e.g. `ALL`. Here are the available types:
|
||||
* * ALL
|
||||
* * MENTIONS
|
||||
* @typedef {string} DefaultMessageNotifications
|
||||
*/
|
||||
exports.DefaultMessageNotifications = ['ALL', 'MENTIONS'];
|
||||
|
||||
/**
|
||||
* The value set for a team members's membership state:
|
||||
* * INVITED
|
||||
* * ACCEPTED
|
||||
* @typedef {string} MembershipStates
|
||||
*/
|
||||
exports.MembershipStates = [
|
||||
// They start at 1
|
||||
null,
|
||||
'INVITED',
|
||||
'ACCEPTED',
|
||||
];
|
||||
|
||||
/**
|
||||
* The value set for a webhook's type:
|
||||
* * Incoming
|
||||
* * Channel Follower
|
||||
* @typedef {string} WebhookTypes
|
||||
*/
|
||||
exports.WebhookTypes = [
|
||||
// They start at 1
|
||||
null,
|
||||
'Incoming',
|
||||
'Channel Follower',
|
||||
];
|
||||
|
||||
function keyMirror(arr) {
|
||||
let tmp = Object.create(null);
|
||||
for (const value of arr) tmp[value] = value;
|
||||
return tmp;
|
||||
}
|
||||
153
node_modules/discord.js/src/util/DataResolver.js
generated
vendored
Normal file
153
node_modules/discord.js/src/util/DataResolver.js
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const stream = require('stream');
|
||||
const fetch = require('node-fetch');
|
||||
const { Error: DiscordError, TypeError } = require('../errors');
|
||||
const { browser } = require('../util/Constants');
|
||||
const Util = require('../util/Util');
|
||||
|
||||
/**
|
||||
* The DataResolver identifies different objects and tries to resolve a specific piece of information from them.
|
||||
* @private
|
||||
*/
|
||||
class DataResolver {
|
||||
constructor() {
|
||||
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give an invite code. This can be:
|
||||
* * An invite code
|
||||
* * An invite URL
|
||||
* @typedef {string} InviteResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give an template code. This can be:
|
||||
* * A template code
|
||||
* * A template URL
|
||||
* @typedef {string} GuildTemplateResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves the string to a code based on the passed regex.
|
||||
* @param {string} data The string to resolve
|
||||
* @param {RegExp} regex The RegExp used to extract the code
|
||||
* @returns {string}
|
||||
*/
|
||||
static resolveCode(data, regex) {
|
||||
const match = regex.exec(data);
|
||||
return match ? match[1] || data : data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves InviteResolvable to an invite code.
|
||||
* @param {InviteResolvable} data The invite resolvable to resolve
|
||||
* @returns {string}
|
||||
*/
|
||||
static resolveInviteCode(data) {
|
||||
return this.resolveCode(data, /discord(?:(?:app)?\.com\/invite|\.gg(?:\/invite)?)\/([\w-]{2,255})/i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves GuildTemplateResolvable to a template code.
|
||||
* @param {GuildTemplateResolvable} data The template resolvable to resolve
|
||||
* @returns {string}
|
||||
*/
|
||||
static resolveGuildTemplateCode(data) {
|
||||
return this.resolveCode(data, /discord(?:app)?\.(?:com\/template|new)\/([\w-]{2,255})/i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a Base64Resolvable, a string, or a BufferResolvable to a Base 64 image.
|
||||
* @param {BufferResolvable|Base64Resolvable} image The image to be resolved
|
||||
* @returns {Promise<?string>}
|
||||
*/
|
||||
static async resolveImage(image) {
|
||||
if (!image) return null;
|
||||
if (typeof image === 'string' && image.startsWith('data:')) {
|
||||
return image;
|
||||
}
|
||||
const file = await this.resolveFileAsBuffer(image);
|
||||
return DataResolver.resolveBase64(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data that resolves to give a Base64 string, typically for image uploading. This can be:
|
||||
* * A Buffer
|
||||
* * A base64 string
|
||||
* @typedef {Buffer|string} Base64Resolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves a Base64Resolvable to a Base 64 image.
|
||||
* @param {Base64Resolvable} data The base 64 resolvable you want to resolve
|
||||
* @returns {?string}
|
||||
*/
|
||||
static resolveBase64(data) {
|
||||
if (Buffer.isBuffer(data)) return `data:image/jpg;base64,${data.toString('base64')}`;
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a Buffer. This can be:
|
||||
* * A Buffer
|
||||
* * The path to a local file
|
||||
* * A URL
|
||||
* @typedef {string|Buffer} BufferResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external Stream
|
||||
* @see {@link https://nodejs.org/api/stream.html}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves a BufferResolvable to a Buffer or a Stream.
|
||||
* @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve
|
||||
* @returns {Promise<Buffer|Stream>}
|
||||
*/
|
||||
static async resolveFile(resource) {
|
||||
if (!browser && Buffer.isBuffer(resource)) return resource;
|
||||
if (browser && resource instanceof ArrayBuffer) return Util.convertToBuffer(resource);
|
||||
// eslint-disable-next-line no-undef
|
||||
if (browser && resource instanceof Blob) return resource;
|
||||
if (resource instanceof stream.Readable) return resource;
|
||||
|
||||
if (typeof resource === 'string') {
|
||||
if (/^https?:\/\//.test(resource)) {
|
||||
const res = await fetch(resource);
|
||||
return browser ? res.blob() : res.body;
|
||||
} else if (!browser) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const file = path.resolve(resource);
|
||||
fs.stat(file, (err, stats) => {
|
||||
if (err) return reject(err);
|
||||
if (!stats.isFile()) return reject(new DiscordError('FILE_NOT_FOUND', file));
|
||||
return resolve(fs.createReadStream(file));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
throw new TypeError('REQ_RESOURCE_TYPE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a BufferResolvable to a Buffer.
|
||||
* @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
static async resolveFileAsBuffer(resource) {
|
||||
const file = await this.resolveFile(resource);
|
||||
if (Buffer.isBuffer(file)) return file;
|
||||
|
||||
const buffers = [];
|
||||
for await (const data of file) buffers.push(data);
|
||||
return Buffer.concat(buffers);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DataResolver;
|
||||
83
node_modules/discord.js/src/util/Intents.js
generated
vendored
Normal file
83
node_modules/discord.js/src/util/Intents.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to calculate intents.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class Intents extends BitField {}
|
||||
|
||||
/**
|
||||
* @name Intents
|
||||
* @kind constructor
|
||||
* @memberof Intents
|
||||
* @param {IntentsResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a permission number. This can be:
|
||||
* * A string (see {@link Intents.FLAGS})
|
||||
* * An intents flag
|
||||
* * An instance of Intents
|
||||
* * An array of IntentsResolvable
|
||||
* @typedef {string|number|Intents|IntentsResolvable[]} IntentsResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric websocket intents. All available properties:
|
||||
* * `GUILDS`
|
||||
* * `GUILD_MEMBERS`
|
||||
* * `GUILD_BANS`
|
||||
* * `GUILD_EMOJIS`
|
||||
* * `GUILD_INTEGRATIONS`
|
||||
* * `GUILD_WEBHOOKS`
|
||||
* * `GUILD_INVITES`
|
||||
* * `GUILD_VOICE_STATES`
|
||||
* * `GUILD_PRESENCES`
|
||||
* * `GUILD_MESSAGES`
|
||||
* * `GUILD_MESSAGE_REACTIONS`
|
||||
* * `GUILD_MESSAGE_TYPING`
|
||||
* * `DIRECT_MESSAGES`
|
||||
* * `DIRECT_MESSAGE_REACTIONS`
|
||||
* * `DIRECT_MESSAGE_TYPING`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/topics/gateway#list-of-intents}
|
||||
*/
|
||||
Intents.FLAGS = {
|
||||
GUILDS: 1 << 0,
|
||||
GUILD_MEMBERS: 1 << 1,
|
||||
GUILD_BANS: 1 << 2,
|
||||
GUILD_EMOJIS: 1 << 3,
|
||||
GUILD_INTEGRATIONS: 1 << 4,
|
||||
GUILD_WEBHOOKS: 1 << 5,
|
||||
GUILD_INVITES: 1 << 6,
|
||||
GUILD_VOICE_STATES: 1 << 7,
|
||||
GUILD_PRESENCES: 1 << 8,
|
||||
GUILD_MESSAGES: 1 << 9,
|
||||
GUILD_MESSAGE_REACTIONS: 1 << 10,
|
||||
GUILD_MESSAGE_TYPING: 1 << 11,
|
||||
DIRECT_MESSAGES: 1 << 12,
|
||||
DIRECT_MESSAGE_REACTIONS: 1 << 13,
|
||||
DIRECT_MESSAGE_TYPING: 1 << 14,
|
||||
};
|
||||
|
||||
/**
|
||||
* Bitfield representing all privileged intents
|
||||
* @type {number}
|
||||
* @see {@link https://discord.com/developers/docs/topics/gateway#privileged-intents}
|
||||
*/
|
||||
Intents.PRIVILEGED = Intents.FLAGS.GUILD_MEMBERS | Intents.FLAGS.GUILD_PRESENCES;
|
||||
|
||||
/**
|
||||
* Bitfield representing all intents combined
|
||||
* @type {number}
|
||||
*/
|
||||
Intents.ALL = Object.values(Intents.FLAGS).reduce((acc, p) => acc | p, 0);
|
||||
|
||||
/**
|
||||
* Bitfield representing all non-privileged intents
|
||||
* @type {number}
|
||||
*/
|
||||
Intents.NON_PRIVILEGED = Intents.ALL & ~Intents.PRIVILEGED;
|
||||
|
||||
module.exports = Intents;
|
||||
34
node_modules/discord.js/src/util/LimitedCollection.js
generated
vendored
Normal file
34
node_modules/discord.js/src/util/LimitedCollection.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
const Collection = require('./Collection.js');
|
||||
|
||||
/**
|
||||
* A Collection which holds a max amount of entries. The first key is deleted if the Collection has
|
||||
* reached max size.
|
||||
* @extends {Collection}
|
||||
* @param {number} [maxSize=0] The maximum size of the Collection
|
||||
* @param {Iterable} [iterable=null] Optional entries passed to the Map constructor.
|
||||
* @private
|
||||
*/
|
||||
class LimitedCollection extends Collection {
|
||||
constructor(maxSize = 0, iterable = null) {
|
||||
super(iterable);
|
||||
/**
|
||||
* The max size of the Collection.
|
||||
* @type {number}
|
||||
*/
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
if (this.maxSize === 0) return this;
|
||||
if (this.size >= this.maxSize && !this.has(key)) this.delete(this.firstKey());
|
||||
return super.set(key, value);
|
||||
}
|
||||
|
||||
static get [Symbol.species]() {
|
||||
return Collection;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LimitedCollection;
|
||||
36
node_modules/discord.js/src/util/MessageFlags.js
generated
vendored
Normal file
36
node_modules/discord.js/src/util/MessageFlags.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with an {@link Message#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class MessageFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name MessageFlags
|
||||
* @kind constructor
|
||||
* @memberof MessageFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric message flags. All available properties:
|
||||
* * `CROSSPOSTED`
|
||||
* * `IS_CROSSPOST`
|
||||
* * `SUPPRESS_EMBEDS`
|
||||
* * `SOURCE_MESSAGE_DELETED`
|
||||
* * `URGENT`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/resources/channel#message-object-message-flags}
|
||||
*/
|
||||
MessageFlags.FLAGS = {
|
||||
CROSSPOSTED: 1 << 0,
|
||||
IS_CROSSPOST: 1 << 1,
|
||||
SUPPRESS_EMBEDS: 1 << 2,
|
||||
SOURCE_MESSAGE_DELETED: 1 << 3,
|
||||
URGENT: 1 << 4,
|
||||
};
|
||||
|
||||
module.exports = MessageFlags;
|
||||
131
node_modules/discord.js/src/util/Permissions.js
generated
vendored
Normal file
131
node_modules/discord.js/src/util/Permissions.js
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a permission bitfield. All {@link GuildMember}s have a set of
|
||||
* permissions in their guild, and each channel in the guild may also have {@link PermissionOverwrites} for the member
|
||||
* that override their default permissions.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class Permissions extends BitField {
|
||||
/**
|
||||
* @name Permissions
|
||||
* @kind constructor
|
||||
* @memberof Permissions
|
||||
* @param {PermissionResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a permission number. This can be:
|
||||
* * A string (see {@link Permissions.FLAGS})
|
||||
* * A permission number
|
||||
* * An instance of Permissions
|
||||
* * An Array of PermissionResolvable
|
||||
* @typedef {string|number|Permissions|PermissionResolvable[]} PermissionResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a permission, or any of multiple permissions.
|
||||
* @param {PermissionResolvable} permission Permission(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {boolean}
|
||||
*/
|
||||
any(permission, checkAdmin = true) {
|
||||
return (checkAdmin && super.has(this.constructor.FLAGS.ADMINISTRATOR)) || super.any(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the bitfield has a permission, or multiple permissions.
|
||||
* @param {PermissionResolvable} permission Permission(s) to check for
|
||||
* @param {boolean} [checkAdmin=true] Whether to allow the administrator permission to override
|
||||
* @returns {boolean}
|
||||
*/
|
||||
has(permission, checkAdmin = true) {
|
||||
return (checkAdmin && super.has(this.constructor.FLAGS.ADMINISTRATOR)) || super.has(permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Numeric permission flags. All available properties:
|
||||
* * `ADMINISTRATOR` (implicitly has *all* permissions, and bypasses all channel overwrites)
|
||||
* * `CREATE_INSTANT_INVITE` (create invitations to the guild)
|
||||
* * `KICK_MEMBERS`
|
||||
* * `BAN_MEMBERS`
|
||||
* * `MANAGE_CHANNELS` (edit and reorder channels)
|
||||
* * `MANAGE_GUILD` (edit the guild information, region, etc.)
|
||||
* * `ADD_REACTIONS` (add new reactions to messages)
|
||||
* * `VIEW_AUDIT_LOG`
|
||||
* * `PRIORITY_SPEAKER`
|
||||
* * `STREAM`
|
||||
* * `VIEW_CHANNEL`
|
||||
* * `SEND_MESSAGES`
|
||||
* * `SEND_TTS_MESSAGES`
|
||||
* * `MANAGE_MESSAGES` (delete messages and reactions)
|
||||
* * `EMBED_LINKS` (links posted will have a preview embedded)
|
||||
* * `ATTACH_FILES`
|
||||
* * `READ_MESSAGE_HISTORY` (view messages that were posted prior to opening Discord)
|
||||
* * `MENTION_EVERYONE`
|
||||
* * `USE_EXTERNAL_EMOJIS` (use emojis from different guilds)
|
||||
* * `VIEW_GUILD_INSIGHTS`
|
||||
* * `CONNECT` (connect to a voice channel)
|
||||
* * `SPEAK` (speak in a voice channel)
|
||||
* * `MUTE_MEMBERS` (mute members across all voice channels)
|
||||
* * `DEAFEN_MEMBERS` (deafen members across all voice channels)
|
||||
* * `MOVE_MEMBERS` (move members between voice channels)
|
||||
* * `USE_VAD` (use voice activity detection)
|
||||
* * `CHANGE_NICKNAME`
|
||||
* * `MANAGE_NICKNAMES` (change other members' nicknames)
|
||||
* * `MANAGE_ROLES`
|
||||
* * `MANAGE_WEBHOOKS`
|
||||
* * `MANAGE_EMOJIS`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/topics/permissions}
|
||||
*/
|
||||
Permissions.FLAGS = {
|
||||
CREATE_INSTANT_INVITE: 1 << 0,
|
||||
KICK_MEMBERS: 1 << 1,
|
||||
BAN_MEMBERS: 1 << 2,
|
||||
ADMINISTRATOR: 1 << 3,
|
||||
MANAGE_CHANNELS: 1 << 4,
|
||||
MANAGE_GUILD: 1 << 5,
|
||||
ADD_REACTIONS: 1 << 6,
|
||||
VIEW_AUDIT_LOG: 1 << 7,
|
||||
PRIORITY_SPEAKER: 1 << 8,
|
||||
STREAM: 1 << 9,
|
||||
VIEW_CHANNEL: 1 << 10,
|
||||
SEND_MESSAGES: 1 << 11,
|
||||
SEND_TTS_MESSAGES: 1 << 12,
|
||||
MANAGE_MESSAGES: 1 << 13,
|
||||
EMBED_LINKS: 1 << 14,
|
||||
ATTACH_FILES: 1 << 15,
|
||||
READ_MESSAGE_HISTORY: 1 << 16,
|
||||
MENTION_EVERYONE: 1 << 17,
|
||||
USE_EXTERNAL_EMOJIS: 1 << 18,
|
||||
VIEW_GUILD_INSIGHTS: 1 << 19,
|
||||
CONNECT: 1 << 20,
|
||||
SPEAK: 1 << 21,
|
||||
MUTE_MEMBERS: 1 << 22,
|
||||
DEAFEN_MEMBERS: 1 << 23,
|
||||
MOVE_MEMBERS: 1 << 24,
|
||||
USE_VAD: 1 << 25,
|
||||
CHANGE_NICKNAME: 1 << 26,
|
||||
MANAGE_NICKNAMES: 1 << 27,
|
||||
MANAGE_ROLES: 1 << 28,
|
||||
MANAGE_WEBHOOKS: 1 << 29,
|
||||
MANAGE_EMOJIS: 1 << 30,
|
||||
};
|
||||
|
||||
/**
|
||||
* Bitfield representing every permission combined
|
||||
* @type {number}
|
||||
*/
|
||||
Permissions.ALL = Object.values(Permissions.FLAGS).reduce((all, p) => all | p, 0);
|
||||
|
||||
/**
|
||||
* Bitfield representing the default permissions for users
|
||||
* @type {number}
|
||||
*/
|
||||
Permissions.DEFAULT = 104324673;
|
||||
|
||||
module.exports = Permissions;
|
||||
93
node_modules/discord.js/src/util/Snowflake.js
generated
vendored
Normal file
93
node_modules/discord.js/src/util/Snowflake.js
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
'use strict';
|
||||
|
||||
const Util = require('../util/Util');
|
||||
|
||||
// Discord epoch (2015-01-01T00:00:00.000Z)
|
||||
const EPOCH = 1420070400000;
|
||||
let INCREMENT = 0;
|
||||
|
||||
/**
|
||||
* A container for useful snowflake-related methods.
|
||||
*/
|
||||
class SnowflakeUtil {
|
||||
constructor() {
|
||||
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Twitter snowflake, except the epoch is 2015-01-01T00:00:00.000Z
|
||||
* ```
|
||||
* If we have a snowflake '266241948824764416' we can represent it as binary:
|
||||
*
|
||||
* 64 22 17 12 0
|
||||
* 000000111011000111100001101001000101000000 00001 00000 000000000000
|
||||
* number of ms since Discord epoch worker pid increment
|
||||
* ```
|
||||
* @typedef {string} Snowflake
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generates a Discord snowflake.
|
||||
* <info>This hardcodes the worker ID as 1 and the process ID as 0.</info>
|
||||
* @param {number|Date} [timestamp=Date.now()] Timestamp or date of the snowflake to generate
|
||||
* @returns {Snowflake} The generated snowflake
|
||||
*/
|
||||
static generate(timestamp = Date.now()) {
|
||||
if (timestamp instanceof Date) timestamp = timestamp.getTime();
|
||||
if (typeof timestamp !== 'number' || isNaN(timestamp)) {
|
||||
throw new TypeError(
|
||||
`"timestamp" argument must be a number (received ${isNaN(timestamp) ? 'NaN' : typeof timestamp})`,
|
||||
);
|
||||
}
|
||||
if (INCREMENT >= 4095) INCREMENT = 0;
|
||||
const BINARY = `${(timestamp - EPOCH).toString(2).padStart(42, '0')}0000100000${(INCREMENT++)
|
||||
.toString(2)
|
||||
.padStart(12, '0')}`;
|
||||
return Util.binaryToID(BINARY);
|
||||
}
|
||||
|
||||
/**
|
||||
* A deconstructed snowflake.
|
||||
* @typedef {Object} DeconstructedSnowflake
|
||||
* @property {number} timestamp Timestamp the snowflake was created
|
||||
* @property {Date} date Date the snowflake was created
|
||||
* @property {number} workerID Worker ID in the snowflake
|
||||
* @property {number} processID Process ID in the snowflake
|
||||
* @property {number} increment Increment in the snowflake
|
||||
* @property {string} binary Binary representation of the snowflake
|
||||
*/
|
||||
|
||||
/**
|
||||
* Deconstructs a Discord snowflake.
|
||||
* @param {Snowflake} snowflake Snowflake to deconstruct
|
||||
* @returns {DeconstructedSnowflake} Deconstructed snowflake
|
||||
*/
|
||||
static deconstruct(snowflake) {
|
||||
const BINARY = Util.idToBinary(snowflake).toString(2).padStart(64, '0');
|
||||
const res = {
|
||||
timestamp: parseInt(BINARY.substring(0, 42), 2) + EPOCH,
|
||||
workerID: parseInt(BINARY.substring(42, 47), 2),
|
||||
processID: parseInt(BINARY.substring(47, 52), 2),
|
||||
increment: parseInt(BINARY.substring(52, 64), 2),
|
||||
binary: BINARY,
|
||||
};
|
||||
Object.defineProperty(res, 'date', {
|
||||
get: function get() {
|
||||
return new Date(this.timestamp);
|
||||
},
|
||||
enumerable: true,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discord's epoch value (2015-01-01T00:00:00.000Z).
|
||||
* @type {number}
|
||||
* @readonly
|
||||
*/
|
||||
static get EPOCH() {
|
||||
return EPOCH;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SnowflakeUtil;
|
||||
33
node_modules/discord.js/src/util/Speaking.js
generated
vendored
Normal file
33
node_modules/discord.js/src/util/Speaking.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link VoiceConnection#speaking}
|
||||
* and {@link guildMemberSpeaking} event bitfields.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class Speaking extends BitField {}
|
||||
|
||||
/**
|
||||
* @name Speaking
|
||||
* @kind constructor
|
||||
* @memberof Speaking
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric speaking flags. All available properties:
|
||||
* * `SPEAKING`
|
||||
* * `SOUNDSHARE`
|
||||
* * `PRIORITY_SPEAKING`
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/topics/voice-connections#speaking}
|
||||
*/
|
||||
Speaking.FLAGS = {
|
||||
SPEAKING: 1 << 0,
|
||||
SOUNDSHARE: 1 << 1,
|
||||
PRIORITY_SPEAKING: 1 << 2,
|
||||
};
|
||||
|
||||
module.exports = Speaking;
|
||||
112
node_modules/discord.js/src/util/Structures.js
generated
vendored
Normal file
112
node_modules/discord.js/src/util/Structures.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* An extendable structure:
|
||||
* * **`GuildEmoji`**
|
||||
* * **`DMChannel`**
|
||||
* * **`TextChannel`**
|
||||
* * **`VoiceChannel`**
|
||||
* * **`CategoryChannel`**
|
||||
* * **`NewsChannel`**
|
||||
* * **`StoreChannel`**
|
||||
* * **`GuildMember`**
|
||||
* * **`Guild`**
|
||||
* * **`Message`**
|
||||
* * **`MessageReaction`**
|
||||
* * **`Presence`**
|
||||
* * **`ClientPresence`**
|
||||
* * **`VoiceState`**
|
||||
* * **`Role`**
|
||||
* * **`User`**
|
||||
* @typedef {string} ExtendableStructure
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allows for the extension of built-in Discord.js structures that are instantiated by {@link BaseManager Managers}.
|
||||
*/
|
||||
class Structures {
|
||||
constructor() {
|
||||
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a structure class.
|
||||
* @param {string} structure Name of the structure to retrieve
|
||||
* @returns {Function}
|
||||
*/
|
||||
static get(structure) {
|
||||
if (typeof structure === 'string') return structures[structure];
|
||||
throw new TypeError(`"structure" argument must be a string (received ${typeof structure})`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends a structure.
|
||||
* <warn> Make sure to extend all structures before instantiating your client.
|
||||
* Extending after doing so may not work as expected. </warn>
|
||||
* @param {ExtendableStructure} structure Name of the structure class to extend
|
||||
* @param {Function} extender Function that takes the base class to extend as its only parameter and returns the
|
||||
* extended class/prototype
|
||||
* @returns {Function} Extended class/prototype returned from the extender
|
||||
* @example
|
||||
* const { Structures } = require('discord.js');
|
||||
*
|
||||
* Structures.extend('Guild', Guild => {
|
||||
* class CoolGuild extends Guild {
|
||||
* constructor(client, data) {
|
||||
* super(client, data);
|
||||
* this.cool = true;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* return CoolGuild;
|
||||
* });
|
||||
*/
|
||||
static extend(structure, extender) {
|
||||
if (!structures[structure]) throw new RangeError(`"${structure}" is not a valid extensible structure.`);
|
||||
if (typeof extender !== 'function') {
|
||||
const received = `(received ${typeof extender})`;
|
||||
throw new TypeError(
|
||||
`"extender" argument must be a function that returns the extended structure class/prototype ${received}.`,
|
||||
);
|
||||
}
|
||||
|
||||
const extended = extender(structures[structure]);
|
||||
if (typeof extended !== 'function') {
|
||||
const received = `(received ${typeof extended})`;
|
||||
throw new TypeError(`The extender function must return the extended structure class/prototype ${received}.`);
|
||||
}
|
||||
|
||||
if (!(extended.prototype instanceof structures[structure])) {
|
||||
const prototype = Object.getPrototypeOf(extended);
|
||||
const received = `${extended.name || 'unnamed'}${prototype.name ? ` extends ${prototype.name}` : ''}`;
|
||||
throw new Error(
|
||||
'The class/prototype returned from the extender function must extend the existing structure class/prototype' +
|
||||
` (received function ${received}; expected extension of ${structures[structure].name}).`,
|
||||
);
|
||||
}
|
||||
|
||||
structures[structure] = extended;
|
||||
return extended;
|
||||
}
|
||||
}
|
||||
|
||||
const structures = {
|
||||
GuildEmoji: require('../structures/GuildEmoji'),
|
||||
DMChannel: require('../structures/DMChannel'),
|
||||
TextChannel: require('../structures/TextChannel'),
|
||||
VoiceChannel: require('../structures/VoiceChannel'),
|
||||
CategoryChannel: require('../structures/CategoryChannel'),
|
||||
NewsChannel: require('../structures/NewsChannel'),
|
||||
StoreChannel: require('../structures/StoreChannel'),
|
||||
GuildMember: require('../structures/GuildMember'),
|
||||
Guild: require('../structures/Guild'),
|
||||
Message: require('../structures/Message'),
|
||||
MessageReaction: require('../structures/MessageReaction'),
|
||||
Presence: require('../structures/Presence').Presence,
|
||||
ClientPresence: require('../structures/ClientPresence'),
|
||||
VoiceState: require('../structures/VoiceState'),
|
||||
Role: require('../structures/Role'),
|
||||
User: require('../structures/User'),
|
||||
};
|
||||
|
||||
module.exports = Structures;
|
||||
40
node_modules/discord.js/src/util/SystemChannelFlags.js
generated
vendored
Normal file
40
node_modules/discord.js/src/util/SystemChannelFlags.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link Guild#systemChannelFlags} bitfield.
|
||||
* <info>Note that all event message types are enabled by default,
|
||||
* and by setting their corresponding flags you are disabling them</info>
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class SystemChannelFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name SystemChannelFlags
|
||||
* @kind constructor
|
||||
* @memberof SystemChannelFlags
|
||||
* @param {SystemChannelFlagsResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a sytem channel flag bitfield. This can be:
|
||||
* * A string (see {@link SystemChannelFlags.FLAGS})
|
||||
* * A sytem channel flag
|
||||
* * An instance of SystemChannelFlags
|
||||
* * An Array of SystemChannelFlagsResolvable
|
||||
* @typedef {string|number|SystemChannelFlags|SystemChannelFlagsResolvable[]} SystemChannelFlagsResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric system channel flags. All available properties:
|
||||
* * `WELCOME_MESSAGE_DISABLED`
|
||||
* * `BOOST_MESSAGE_DISABLED`
|
||||
* @type {Object}
|
||||
*/
|
||||
SystemChannelFlags.FLAGS = {
|
||||
WELCOME_MESSAGE_DISABLED: 1 << 0,
|
||||
BOOST_MESSAGE_DISABLED: 1 << 1,
|
||||
};
|
||||
|
||||
module.exports = SystemChannelFlags;
|
||||
55
node_modules/discord.js/src/util/UserFlags.js
generated
vendored
Normal file
55
node_modules/discord.js/src/util/UserFlags.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
const BitField = require('./BitField');
|
||||
|
||||
/**
|
||||
* Data structure that makes it easy to interact with a {@link User#flags} bitfield.
|
||||
* @extends {BitField}
|
||||
*/
|
||||
class UserFlags extends BitField {}
|
||||
|
||||
/**
|
||||
* @name UserFlags
|
||||
* @kind constructor
|
||||
* @memberof UserFlags
|
||||
* @param {BitFieldResolvable} [bits=0] Bit(s) to read from
|
||||
*/
|
||||
|
||||
/**
|
||||
* Numeric user flags. All available properties:
|
||||
* * `DISCORD_EMPLOYEE`
|
||||
* * `PARTNERED_SERVER_OWNER`
|
||||
* * `DISCORD_PARTNER` **(deprecated)**
|
||||
* * `HYPESQUAD_EVENTS`
|
||||
* * `BUGHUNTER_LEVEL_1`
|
||||
* * `HOUSE_BRAVERY`
|
||||
* * `HOUSE_BRILLIANCE`
|
||||
* * `HOUSE_BALANCE`
|
||||
* * `EARLY_SUPPORTER`
|
||||
* * `TEAM_USER`
|
||||
* * `SYSTEM`
|
||||
* * `BUGHUNTER_LEVEL_2`
|
||||
* * `VERIFIED_BOT`
|
||||
* * `EARLY_VERIFIED_BOT_DEVELOPER`
|
||||
* * `VERIFIED_DEVELOPER` **(deprecated)**
|
||||
* @type {Object}
|
||||
* @see {@link https://discord.com/developers/docs/resources/user#user-object-user-flags}
|
||||
*/
|
||||
UserFlags.FLAGS = {
|
||||
DISCORD_EMPLOYEE: 1 << 0,
|
||||
PARTNERED_SERVER_OWNER: 1 << 1,
|
||||
DISCORD_PARTNER: 1 << 1,
|
||||
HYPESQUAD_EVENTS: 1 << 2,
|
||||
BUGHUNTER_LEVEL_1: 1 << 3,
|
||||
HOUSE_BRAVERY: 1 << 6,
|
||||
HOUSE_BRILLIANCE: 1 << 7,
|
||||
HOUSE_BALANCE: 1 << 8,
|
||||
EARLY_SUPPORTER: 1 << 9,
|
||||
TEAM_USER: 1 << 10,
|
||||
SYSTEM: 1 << 12,
|
||||
BUGHUNTER_LEVEL_2: 1 << 14,
|
||||
VERIFIED_BOT: 1 << 16,
|
||||
EARLY_VERIFIED_DEVELOPER: 1 << 17,
|
||||
VERIFIED_DEVELOPER: 1 << 17,
|
||||
};
|
||||
|
||||
module.exports = UserFlags;
|
||||
625
node_modules/discord.js/src/util/Util.js
generated
vendored
Normal file
625
node_modules/discord.js/src/util/Util.js
generated
vendored
Normal file
@@ -0,0 +1,625 @@
|
||||
'use strict';
|
||||
|
||||
const { parse } = require('path');
|
||||
const fetch = require('node-fetch');
|
||||
const { Colors, DefaultOptions, Endpoints } = require('./Constants');
|
||||
const { Error: DiscordError, RangeError, TypeError } = require('../errors');
|
||||
const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
|
||||
const isObject = d => typeof d === 'object' && d !== null;
|
||||
|
||||
/**
|
||||
* Contains various general-purpose utility methods. These functions are also available on the base `Discord` object.
|
||||
*/
|
||||
class Util {
|
||||
constructor() {
|
||||
throw new Error(`The ${this.constructor.name} class may not be instantiated.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten an object. Any properties that are collections will get converted to an array of keys.
|
||||
* @param {Object} obj The object to flatten.
|
||||
* @param {...Object<string, boolean|string>} [props] Specific properties to include/exclude.
|
||||
* @returns {Object}
|
||||
*/
|
||||
static flatten(obj, ...props) {
|
||||
if (!isObject(obj)) return obj;
|
||||
|
||||
const objProps = Object.keys(obj)
|
||||
.filter(k => !k.startsWith('_'))
|
||||
.map(k => ({ [k]: true }));
|
||||
|
||||
props = objProps.length ? Object.assign(...objProps, ...props) : Object.assign({}, ...props);
|
||||
|
||||
const out = {};
|
||||
|
||||
for (let [prop, newProp] of Object.entries(props)) {
|
||||
if (!newProp) continue;
|
||||
newProp = newProp === true ? prop : newProp;
|
||||
|
||||
const element = obj[prop];
|
||||
const elemIsObj = isObject(element);
|
||||
const valueOf = elemIsObj && typeof element.valueOf === 'function' ? element.valueOf() : null;
|
||||
|
||||
// If it's a Collection, make the array of keys
|
||||
if (element instanceof require('./Collection')) out[newProp] = Array.from(element.keys());
|
||||
// If the valueOf is a Collection, use its array of keys
|
||||
else if (valueOf instanceof require('./Collection')) out[newProp] = Array.from(valueOf.keys());
|
||||
// If it's an array, flatten each element
|
||||
else if (Array.isArray(element)) out[newProp] = element.map(e => Util.flatten(e));
|
||||
// If it's an object with a primitive `valueOf`, use that value
|
||||
else if (typeof valueOf !== 'object') out[newProp] = valueOf;
|
||||
// If it's a primitive
|
||||
else if (!elemIsObj) out[newProp] = element;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a string into multiple chunks at a designated character that do not exceed a specific length.
|
||||
* @param {StringResolvable} text Content to split
|
||||
* @param {SplitOptions} [options] Options controlling the behavior of the split
|
||||
* @returns {string[]}
|
||||
*/
|
||||
static splitMessage(text, { maxLength = 2000, char = '\n', prepend = '', append = '' } = {}) {
|
||||
text = Util.resolveString(text);
|
||||
if (text.length <= maxLength) return [text];
|
||||
const splitText = text.split(char);
|
||||
if (splitText.some(chunk => chunk.length > maxLength)) throw new RangeError('SPLIT_MAX_LEN');
|
||||
const messages = [];
|
||||
let msg = '';
|
||||
for (const chunk of splitText) {
|
||||
if (msg && (msg + char + chunk + append).length > maxLength) {
|
||||
messages.push(msg + append);
|
||||
msg = prepend;
|
||||
}
|
||||
msg += (msg && msg !== prepend ? char : '') + chunk;
|
||||
}
|
||||
return messages.concat(msg).filter(m => m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes any Discord-flavour markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @param {Object} [options={}] What types of markdown to escape
|
||||
* @param {boolean} [options.codeBlock=true] Whether to escape code blocks or not
|
||||
* @param {boolean} [options.inlineCode=true] Whether to escape inline code or not
|
||||
* @param {boolean} [options.bold=true] Whether to escape bolds or not
|
||||
* @param {boolean} [options.italic=true] Whether to escape italics or not
|
||||
* @param {boolean} [options.underline=true] Whether to escape underlines or not
|
||||
* @param {boolean} [options.strikethrough=true] Whether to escape strikethroughs or not
|
||||
* @param {boolean} [options.spoiler=true] Whether to escape spoilers or not
|
||||
* @param {boolean} [options.codeBlockContent=true] Whether to escape text inside code blocks or not
|
||||
* @param {boolean} [options.inlineCodeContent=true] Whether to escape text inside inline code or not
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeMarkdown(
|
||||
text,
|
||||
{
|
||||
codeBlock = true,
|
||||
inlineCode = true,
|
||||
bold = true,
|
||||
italic = true,
|
||||
underline = true,
|
||||
strikethrough = true,
|
||||
spoiler = true,
|
||||
codeBlockContent = true,
|
||||
inlineCodeContent = true,
|
||||
} = {},
|
||||
) {
|
||||
if (!codeBlockContent) {
|
||||
return text
|
||||
.split('```')
|
||||
.map((subString, index, array) => {
|
||||
if (index % 2 && index !== array.length - 1) return subString;
|
||||
return Util.escapeMarkdown(subString, {
|
||||
inlineCode,
|
||||
bold,
|
||||
italic,
|
||||
underline,
|
||||
strikethrough,
|
||||
spoiler,
|
||||
inlineCodeContent,
|
||||
});
|
||||
})
|
||||
.join(codeBlock ? '\\`\\`\\`' : '```');
|
||||
}
|
||||
if (!inlineCodeContent) {
|
||||
return text
|
||||
.split(/(?<=^|[^`])`(?=[^`]|$)/g)
|
||||
.map((subString, index, array) => {
|
||||
if (index % 2 && index !== array.length - 1) return subString;
|
||||
return Util.escapeMarkdown(subString, {
|
||||
codeBlock,
|
||||
bold,
|
||||
italic,
|
||||
underline,
|
||||
strikethrough,
|
||||
spoiler,
|
||||
});
|
||||
})
|
||||
.join(inlineCode ? '\\`' : '`');
|
||||
}
|
||||
if (inlineCode) text = Util.escapeInlineCode(text);
|
||||
if (codeBlock) text = Util.escapeCodeBlock(text);
|
||||
if (italic) text = Util.escapeItalic(text);
|
||||
if (bold) text = Util.escapeBold(text);
|
||||
if (underline) text = Util.escapeUnderline(text);
|
||||
if (strikethrough) text = Util.escapeStrikethrough(text);
|
||||
if (spoiler) text = Util.escapeSpoiler(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes code block markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeCodeBlock(text) {
|
||||
return text.replace(/```/g, '\\`\\`\\`');
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes inline code markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeInlineCode(text) {
|
||||
return text.replace(/(?<=^|[^`])`(?=[^`]|$)/g, '\\`');
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes italic markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeItalic(text) {
|
||||
let i = 0;
|
||||
text = text.replace(/(?<=^|[^*])\*([^*]|\*\*|$)/g, (_, match) => {
|
||||
if (match === '**') return ++i % 2 ? `\\*${match}` : `${match}\\*`;
|
||||
return `\\*${match}`;
|
||||
});
|
||||
i = 0;
|
||||
return text.replace(/(?<=^|[^_])_([^_]|__|$)/g, (_, match) => {
|
||||
if (match === '__') return ++i % 2 ? `\\_${match}` : `${match}\\_`;
|
||||
return `\\_${match}`;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes bold markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeBold(text) {
|
||||
let i = 0;
|
||||
return text.replace(/\*\*(\*)?/g, (_, match) => {
|
||||
if (match) return ++i % 2 ? `${match}\\*\\*` : `\\*\\*${match}`;
|
||||
return '\\*\\*';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes underline markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeUnderline(text) {
|
||||
let i = 0;
|
||||
return text.replace(/__(_)?/g, (_, match) => {
|
||||
if (match) return ++i % 2 ? `${match}\\_\\_` : `\\_\\_${match}`;
|
||||
return '\\_\\_';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes strikethrough markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeStrikethrough(text) {
|
||||
return text.replace(/~~/g, '\\~\\~');
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes spoiler markdown in a string.
|
||||
* @param {string} text Content to escape
|
||||
* @returns {string}
|
||||
*/
|
||||
static escapeSpoiler(text) {
|
||||
return text.replace(/\|\|/g, '\\|\\|');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recommended shard count from Discord.
|
||||
* @param {string} token Discord auth token
|
||||
* @param {number} [guildsPerShard=1000] Number of guilds per shard
|
||||
* @returns {Promise<number>} The recommended number of shards
|
||||
*/
|
||||
static fetchRecommendedShards(token, guildsPerShard = 1000) {
|
||||
if (!token) throw new DiscordError('TOKEN_MISSING');
|
||||
return fetch(`${DefaultOptions.http.api}/v${DefaultOptions.http.version}${Endpoints.botGateway}`, {
|
||||
method: 'GET',
|
||||
headers: { Authorization: `Bot ${token.replace(/^Bot\s*/i, '')}` },
|
||||
})
|
||||
.then(res => {
|
||||
if (res.ok) return res.json();
|
||||
if (res.status === 401) throw new DiscordError('TOKEN_INVALID');
|
||||
throw res;
|
||||
})
|
||||
.then(data => data.shards * (1000 / guildsPerShard));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses emoji info out of a string. The string must be one of:
|
||||
* * A UTF-8 emoji (no ID)
|
||||
* * A URL-encoded UTF-8 emoji (no ID)
|
||||
* * A Discord custom emoji (`<:name:id>` or `<a:name:id>`)
|
||||
* @param {string} text Emoji string to parse
|
||||
* @returns {Object} Object with `animated`, `name`, and `id` properties
|
||||
* @private
|
||||
*/
|
||||
static parseEmoji(text) {
|
||||
if (text.includes('%')) text = decodeURIComponent(text);
|
||||
if (!text.includes(':')) return { animated: false, name: text, id: null };
|
||||
const m = text.match(/<?(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
|
||||
if (!m) return null;
|
||||
return { animated: Boolean(m[1]), name: m[2], id: m[3] || null };
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow-copies an object with its class/prototype intact.
|
||||
* @param {Object} obj Object to clone
|
||||
* @returns {Object}
|
||||
* @private
|
||||
*/
|
||||
static cloneObject(obj) {
|
||||
return Object.assign(Object.create(obj), obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default properties on an object that aren't already specified.
|
||||
* @param {Object} def Default properties
|
||||
* @param {Object} given Object to assign defaults to
|
||||
* @returns {Object}
|
||||
* @private
|
||||
*/
|
||||
static mergeDefault(def, given) {
|
||||
if (!given) return def;
|
||||
for (const key in def) {
|
||||
if (!has(given, key) || given[key] === undefined) {
|
||||
given[key] = def[key];
|
||||
} else if (given[key] === Object(given[key])) {
|
||||
given[key] = Util.mergeDefault(def[key], given[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return given;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an ArrayBuffer or string to a Buffer.
|
||||
* @param {ArrayBuffer|string} ab ArrayBuffer to convert
|
||||
* @returns {Buffer}
|
||||
* @private
|
||||
*/
|
||||
static convertToBuffer(ab) {
|
||||
if (typeof ab === 'string') ab = Util.str2ab(ab);
|
||||
return Buffer.from(ab);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to an ArrayBuffer.
|
||||
* @param {string} str String to convert
|
||||
* @returns {ArrayBuffer}
|
||||
* @private
|
||||
*/
|
||||
static str2ab(str) {
|
||||
const buffer = new ArrayBuffer(str.length * 2);
|
||||
const view = new Uint16Array(buffer);
|
||||
for (var i = 0, strLen = str.length; i < strLen; i++) view[i] = str.charCodeAt(i);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes an Error from a plain info object.
|
||||
* @param {Object} obj Error info
|
||||
* @param {string} obj.name Error type
|
||||
* @param {string} obj.message Message for the error
|
||||
* @param {string} obj.stack Stack for the error
|
||||
* @returns {Error}
|
||||
* @private
|
||||
*/
|
||||
static makeError(obj) {
|
||||
const err = new Error(obj.message);
|
||||
err.name = obj.name;
|
||||
err.stack = obj.stack;
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a plain error info object from an Error.
|
||||
* @param {Error} err Error to get info from
|
||||
* @returns {Object}
|
||||
* @private
|
||||
*/
|
||||
static makePlainError(err) {
|
||||
return {
|
||||
name: err.name,
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an element in an array *in place*.
|
||||
* @param {Array<*>} array Array to modify
|
||||
* @param {*} element Element to move
|
||||
* @param {number} newIndex Index or offset to move the element to
|
||||
* @param {boolean} [offset=false] Move the element by an offset amount rather than to a set index
|
||||
* @returns {number}
|
||||
* @private
|
||||
*/
|
||||
static moveElementInArray(array, element, newIndex, offset = false) {
|
||||
const index = array.indexOf(element);
|
||||
newIndex = (offset ? index : 0) + newIndex;
|
||||
if (newIndex > -1 && newIndex < array.length) {
|
||||
const removedElement = array.splice(index, 1)[0];
|
||||
array.splice(newIndex, 0, removedElement);
|
||||
}
|
||||
return array.indexOf(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a string. This can be:
|
||||
* * A string
|
||||
* * An array (joined with a new line delimiter to give a string)
|
||||
* * Any value
|
||||
* @typedef {string|Array|*} StringResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves a StringResolvable to a string.
|
||||
* @param {StringResolvable} data The string resolvable to resolve
|
||||
* @returns {string}
|
||||
*/
|
||||
static resolveString(data) {
|
||||
if (typeof data === 'string') return data;
|
||||
if (Array.isArray(data)) return data.join('\n');
|
||||
return String(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be a number, hex string, an RGB array like:
|
||||
* ```js
|
||||
* [255, 0, 255] // purple
|
||||
* ```
|
||||
* or one of the following strings:
|
||||
* - `DEFAULT`
|
||||
* - `WHITE`
|
||||
* - `AQUA`
|
||||
* - `GREEN`
|
||||
* - `BLUE`
|
||||
* - `YELLOW`
|
||||
* - `PURPLE`
|
||||
* - `LUMINOUS_VIVID_PINK`
|
||||
* - `GOLD`
|
||||
* - `ORANGE`
|
||||
* - `RED`
|
||||
* - `GREY`
|
||||
* - `DARKER_GREY`
|
||||
* - `NAVY`
|
||||
* - `DARK_AQUA`
|
||||
* - `DARK_GREEN`
|
||||
* - `DARK_BLUE`
|
||||
* - `DARK_PURPLE`
|
||||
* - `DARK_VIVID_PINK`
|
||||
* - `DARK_GOLD`
|
||||
* - `DARK_ORANGE`
|
||||
* - `DARK_RED`
|
||||
* - `DARK_GREY`
|
||||
* - `LIGHT_GREY`
|
||||
* - `DARK_NAVY`
|
||||
* - `BLURPLE`
|
||||
* - `GREYPLE`
|
||||
* - `DARK_BUT_NOT_BLACK`
|
||||
* - `NOT_QUITE_BLACK`
|
||||
* - `RANDOM`
|
||||
* @typedef {string|number|number[]} ColorResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves a ColorResolvable into a color number.
|
||||
* @param {ColorResolvable} color Color to resolve
|
||||
* @returns {number} A color
|
||||
*/
|
||||
static resolveColor(color) {
|
||||
if (typeof color === 'string') {
|
||||
if (color === 'RANDOM') return Math.floor(Math.random() * (0xffffff + 1));
|
||||
if (color === 'DEFAULT') return 0;
|
||||
color = Colors[color] || parseInt(color.replace('#', ''), 16);
|
||||
} else if (Array.isArray(color)) {
|
||||
color = (color[0] << 16) + (color[1] << 8) + color[2];
|
||||
}
|
||||
|
||||
if (color < 0 || color > 0xffffff) throw new RangeError('COLOR_RANGE');
|
||||
else if (color && isNaN(color)) throw new TypeError('COLOR_CONVERT');
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts by Discord's position and ID.
|
||||
* @param {Collection} collection Collection of objects to sort
|
||||
* @returns {Collection}
|
||||
*/
|
||||
static discordSort(collection) {
|
||||
return collection.sorted(
|
||||
(a, b) =>
|
||||
a.rawPosition - b.rawPosition ||
|
||||
parseInt(b.id.slice(0, -10)) - parseInt(a.id.slice(0, -10)) ||
|
||||
parseInt(b.id.slice(10)) - parseInt(a.id.slice(10)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of a Channel or Role.
|
||||
* @param {Channel|Role} item Object to set the position of
|
||||
* @param {number} position New position for the object
|
||||
* @param {boolean} relative Whether `position` is relative to its current position
|
||||
* @param {Collection<string, Channel|Role>} sorted A collection of the objects sorted properly
|
||||
* @param {APIRouter} route Route to call PATCH on
|
||||
* @param {string} [reason] Reason for the change
|
||||
* @returns {Promise<Object[]>} Updated item list, with `id` and `position` properties
|
||||
* @private
|
||||
*/
|
||||
static setPosition(item, position, relative, sorted, route, reason) {
|
||||
let updatedItems = sorted.array();
|
||||
Util.moveElementInArray(updatedItems, item, position, relative);
|
||||
updatedItems = updatedItems.map((r, i) => ({ id: r.id, position: i }));
|
||||
return route.patch({ data: updatedItems, reason }).then(() => updatedItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternative to Node's `path.basename`, removing query string after the extension if it exists.
|
||||
* @param {string} path Path to get the basename of
|
||||
* @param {string} [ext] File extension to remove
|
||||
* @returns {string} Basename of the path
|
||||
* @private
|
||||
*/
|
||||
static basename(path, ext) {
|
||||
let res = parse(path);
|
||||
return ext && res.ext.startsWith(ext) ? res.name : res.base.split('?')[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a snowflake from a decimal string to a bit string.
|
||||
* @param {Snowflake} num Snowflake to be transformed
|
||||
* @returns {string}
|
||||
* @private
|
||||
*/
|
||||
static idToBinary(num) {
|
||||
let bin = '';
|
||||
let high = parseInt(num.slice(0, -10)) || 0;
|
||||
let low = parseInt(num.slice(-10));
|
||||
while (low > 0 || high > 0) {
|
||||
bin = String(low & 1) + bin;
|
||||
low = Math.floor(low / 2);
|
||||
if (high > 0) {
|
||||
low += 5000000000 * (high % 2);
|
||||
high = Math.floor(high / 2);
|
||||
}
|
||||
}
|
||||
return bin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a snowflake from a bit string to a decimal string.
|
||||
* @param {string} num Bit string to be transformed
|
||||
* @returns {Snowflake}
|
||||
* @private
|
||||
*/
|
||||
static binaryToID(num) {
|
||||
let dec = '';
|
||||
|
||||
while (num.length > 50) {
|
||||
const high = parseInt(num.slice(0, -32), 2);
|
||||
const low = parseInt((high % 10).toString(2) + num.slice(-32), 2);
|
||||
|
||||
dec = (low % 10).toString() + dec;
|
||||
num =
|
||||
Math.floor(high / 10).toString(2) +
|
||||
Math.floor(low / 10)
|
||||
.toString(2)
|
||||
.padStart(32, '0');
|
||||
}
|
||||
|
||||
num = parseInt(num, 2);
|
||||
while (num > 0) {
|
||||
dec = (num % 10).toString() + dec;
|
||||
num = Math.floor(num / 10);
|
||||
}
|
||||
|
||||
return dec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Breaks user, role and everyone/here mentions by adding a zero width space after every @ character
|
||||
* @param {string} str The string to sanitize
|
||||
* @returns {string}
|
||||
*/
|
||||
static removeMentions(str) {
|
||||
return str.replace(/@/g, '@\u200b');
|
||||
}
|
||||
|
||||
/**
|
||||
* The content to have all mentions replaced by the equivalent text.
|
||||
* @param {string} str The string to be converted
|
||||
* @param {Message} message The message object to reference
|
||||
* @returns {string}
|
||||
*/
|
||||
static cleanContent(str, message) {
|
||||
str = str
|
||||
.replace(/<@!?[0-9]+>/g, input => {
|
||||
const id = input.replace(/<|!|>|@/g, '');
|
||||
if (message.channel.type === 'dm') {
|
||||
const user = message.client.users.cache.get(id);
|
||||
return user ? Util.removeMentions(`@${user.username}`) : input;
|
||||
}
|
||||
|
||||
const member = message.channel.guild.members.cache.get(id);
|
||||
if (member) {
|
||||
return Util.removeMentions(`@${member.displayName}`);
|
||||
} else {
|
||||
const user = message.client.users.cache.get(id);
|
||||
return user ? Util.removeMentions(`@${user.username}`) : input;
|
||||
}
|
||||
})
|
||||
.replace(/<#[0-9]+>/g, input => {
|
||||
const channel = message.client.channels.cache.get(input.replace(/<|#|>/g, ''));
|
||||
return channel ? `#${channel.name}` : input;
|
||||
})
|
||||
.replace(/<@&[0-9]+>/g, input => {
|
||||
if (message.channel.type === 'dm') return input;
|
||||
const role = message.guild.roles.cache.get(input.replace(/<|@|>|&/g, ''));
|
||||
return role ? `@${role.name}` : input;
|
||||
});
|
||||
if (message.client.options.disableMentions === 'everyone') {
|
||||
str = str.replace(/@([^<>@ ]*)/gmsu, (match, target) => {
|
||||
if (target.match(/^[&!]?\d+$/)) {
|
||||
return `@${target}`;
|
||||
} else {
|
||||
return `@\u200b${target}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (message.client.options.disableMentions === 'all') {
|
||||
return Util.removeMentions(str);
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The content to put in a codeblock with all codeblock fences replaced by the equivalent backticks.
|
||||
* @param {string} text The string to be converted
|
||||
* @returns {string}
|
||||
*/
|
||||
static cleanCodeBlockContent(text) {
|
||||
return text.replace(/```/g, '`\u200b``');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Promise that resolves after a specified duration.
|
||||
* @param {number} ms How long to wait before resolving (in milliseconds)
|
||||
* @returns {Promise<void>}
|
||||
* @private
|
||||
*/
|
||||
static delayFor(ms) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Util;
|
||||
Reference in New Issue
Block a user