buddy

node MVC discord bot
Log | Files | Refs | README

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;