Structures.js (3933B)
1 'use strict'; 2 3 /** 4 * An extendable structure: 5 * * **`GuildEmoji`** 6 * * **`DMChannel`** 7 * * **`TextChannel`** 8 * * **`VoiceChannel`** 9 * * **`CategoryChannel`** 10 * * **`NewsChannel`** 11 * * **`StoreChannel`** 12 * * **`GuildMember`** 13 * * **`Guild`** 14 * * **`Message`** 15 * * **`MessageReaction`** 16 * * **`Presence`** 17 * * **`ClientPresence`** 18 * * **`VoiceState`** 19 * * **`Role`** 20 * * **`User`** 21 * @typedef {string} ExtendableStructure 22 */ 23 24 /** 25 * Allows for the extension of built-in Discord.js structures that are instantiated by {@link BaseManager Managers}. 26 */ 27 class Structures { 28 constructor() { 29 throw new Error(`The ${this.constructor.name} class may not be instantiated.`); 30 } 31 32 /** 33 * Retrieves a structure class. 34 * @param {string} structure Name of the structure to retrieve 35 * @returns {Function} 36 */ 37 static get(structure) { 38 if (typeof structure === 'string') return structures[structure]; 39 throw new TypeError(`"structure" argument must be a string (received ${typeof structure})`); 40 } 41 42 /** 43 * Extends a structure. 44 * <warn> Make sure to extend all structures before instantiating your client. 45 * Extending after doing so may not work as expected. </warn> 46 * @param {ExtendableStructure} structure Name of the structure class to extend 47 * @param {Function} extender Function that takes the base class to extend as its only parameter and returns the 48 * extended class/prototype 49 * @returns {Function} Extended class/prototype returned from the extender 50 * @example 51 * const { Structures } = require('discord.js'); 52 * 53 * Structures.extend('Guild', Guild => { 54 * class CoolGuild extends Guild { 55 * constructor(client, data) { 56 * super(client, data); 57 * this.cool = true; 58 * } 59 * } 60 * 61 * return CoolGuild; 62 * }); 63 */ 64 static extend(structure, extender) { 65 if (!structures[structure]) throw new RangeError(`"${structure}" is not a valid extensible structure.`); 66 if (typeof extender !== 'function') { 67 const received = `(received ${typeof extender})`; 68 throw new TypeError( 69 `"extender" argument must be a function that returns the extended structure class/prototype ${received}.`, 70 ); 71 } 72 73 const extended = extender(structures[structure]); 74 if (typeof extended !== 'function') { 75 const received = `(received ${typeof extended})`; 76 throw new TypeError(`The extender function must return the extended structure class/prototype ${received}.`); 77 } 78 79 if (!(extended.prototype instanceof structures[structure])) { 80 const prototype = Object.getPrototypeOf(extended); 81 const received = `${extended.name || 'unnamed'}${prototype.name ? ` extends ${prototype.name}` : ''}`; 82 throw new Error( 83 'The class/prototype returned from the extender function must extend the existing structure class/prototype' + 84 ` (received function ${received}; expected extension of ${structures[structure].name}).`, 85 ); 86 } 87 88 structures[structure] = extended; 89 return extended; 90 } 91 } 92 93 const structures = { 94 GuildEmoji: require('../structures/GuildEmoji'), 95 DMChannel: require('../structures/DMChannel'), 96 TextChannel: require('../structures/TextChannel'), 97 VoiceChannel: require('../structures/VoiceChannel'), 98 CategoryChannel: require('../structures/CategoryChannel'), 99 NewsChannel: require('../structures/NewsChannel'), 100 StoreChannel: require('../structures/StoreChannel'), 101 GuildMember: require('../structures/GuildMember'), 102 Guild: require('../structures/Guild'), 103 Message: require('../structures/Message'), 104 MessageReaction: require('../structures/MessageReaction'), 105 Presence: require('../structures/Presence').Presence, 106 ClientPresence: require('../structures/ClientPresence'), 107 VoiceState: require('../structures/VoiceState'), 108 Role: require('../structures/Role'), 109 User: require('../structures/User'), 110 }; 111 112 module.exports = Structures;