Skip to content

Commit

Permalink
Merge branch 'custom-structures'
Browse files Browse the repository at this point in the history
  • Loading branch information
Gawdl3y committed Nov 30, 2017
2 parents efd1c4c + be02875 commit 77fc046
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 15 deletions.
3 changes: 2 additions & 1 deletion src/client/websocket/packets/handlers/Ready.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const AbstractHandler = require('./AbstractHandler');
const { Events } = require('../../../../util/Constants');
const ClientUser = require('../../../../structures/ClientUser');
let ClientUser;

class ReadyHandler extends AbstractHandler {
handle(packet) {
Expand All @@ -12,6 +12,7 @@ class ReadyHandler extends AbstractHandler {
data.user.user_settings = data.user_settings;
data.user.user_guild_settings = data.user_guild_settings;

if (!ClientUser) ClientUser = require('../../../../structures/ClientUser');
const clientUser = new ClientUser(client, data.user);
client.user = clientUser;
client.readyAt = new Date();
Expand Down
6 changes: 5 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
Permissions: require('./util/Permissions'),
Snowflake: require('./util/Snowflake'),
SnowflakeUtil: require('./util/Snowflake'),
Structures: require('./util/Structures'),
Util: Util,
util: Util,
version: require('../package.json').version,
Expand Down Expand Up @@ -46,7 +47,10 @@ module.exports = {
CategoryChannel: require('./structures/CategoryChannel'),
Channel: require('./structures/Channel'),
ClientApplication: require('./structures/ClientApplication'),
ClientUser: require('./structures/ClientUser'),
get ClientUser() {
// This is a getter so that it properly extends any custom User class
return require('./structures/ClientUser');
},
ClientUserChannelOverride: require('./structures/ClientUserChannelOverride'),
ClientUserGuildSettings: require('./structures/ClientUserGuildSettings'),
ClientUserSettings: require('./structures/ClientUserSettings'),
Expand Down
4 changes: 3 additions & 1 deletion src/stores/DataStore.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const Collection = require('../util/Collection');
let Structures;

/**
* Manages the creation, retrieval and deletion of a specific data model.
Expand All @@ -7,8 +8,9 @@ const Collection = require('../util/Collection');
class DataStore extends Collection {
constructor(client, iterable, holds) {
super();
if (!Structures) Structures = require('../util/Structures');
Object.defineProperty(this, 'client', { value: client });
Object.defineProperty(this, 'holds', { value: holds });
Object.defineProperty(this, 'holds', { value: Structures.get(holds.name) });
if (iterable) for (const item of iterable) this.create(item);
}

Expand Down
25 changes: 15 additions & 10 deletions src/structures/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,32 +66,37 @@ class Channel extends Base {
}

static create(client, data, guild) {
const DMChannel = require('./DMChannel');
const GroupDMChannel = require('./GroupDMChannel');
const TextChannel = require('./TextChannel');
const VoiceChannel = require('./VoiceChannel');
const CategoryChannel = require('./CategoryChannel');
const GuildChannel = require('./GuildChannel');
const Structures = require('../util/Structures');
let channel;
if (data.type === ChannelTypes.DM) {
const DMChannel = Structures.get('DMChannel');
channel = new DMChannel(client, data);
} else if (data.type === ChannelTypes.GROUP) {
const GroupDMChannel = Structures.get('GroupDMChannel');
channel = new GroupDMChannel(client, data);
} else {
guild = guild || client.guilds.get(data.guild_id);
if (guild) {
switch (data.type) {
case ChannelTypes.TEXT:
case ChannelTypes.TEXT: {
const TextChannel = Structures.get('TextChannel');
channel = new TextChannel(guild, data);
break;
case ChannelTypes.VOICE:
}
case ChannelTypes.VOICE: {
const VoiceChannel = Structures.get('VoiceChannel');
channel = new VoiceChannel(guild, data);
break;
case ChannelTypes.CATEGORY:
}
case ChannelTypes.CATEGORY: {
const CategoryChannel = Structures.get('CategoryChannel');
channel = new CategoryChannel(guild, data);
break;
default:
}
default: {
const GuildChannel = Structures.get('GuildChannel');
channel = new GuildChannel(guild, data);
}
}
guild.channels.set(channel.id, channel);
}
Expand Down
4 changes: 2 additions & 2 deletions src/structures/ClientUser.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const User = require('./User');
const Structures = require('../util/Structures');
const Collection = require('../util/Collection');
const ClientUserSettings = require('./ClientUserSettings');
const ClientUserGuildSettings = require('./ClientUserGuildSettings');
Expand All @@ -11,7 +11,7 @@ const Guild = require('./Guild');
* Represents the logged in client's Discord user.
* @extends {User}
*/
class ClientUser extends User {
class ClientUser extends Structures.get('User') {
_patch(data) {
super._patch(data);

Expand Down
80 changes: 80 additions & 0 deletions src/util/Structures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Allows for the extension of built-in Discord.js structures that are instantiated by {@link DataStore DataStores}.
*/
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.
* @param {string} 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') {
throw new TypeError('The extender function must return the extended structure class/prototype.');
}
if (Object.getPrototypeOf(extended) !== structures[structure]) {
throw new Error(
'The class/prototype returned from the extender function must extend the existing structure class/prototype.'
);
}

structures[structure] = extended;
return extended;
}
}

const structures = {
Emoji: require('../structures/Emoji'),
DMChannel: require('../structures/DMChannel'),
GroupDMChannel: require('../structures/GroupDMChannel'),
TextChannel: require('../structures/TextChannel'),
VoiceChannel: require('../structures/VoiceChannel'),
CategoryChannel: require('../structures/CategoryChannel'),
GuildChannel: require('../structures/GuildChannel'),
GuildMember: require('../structures/GuildMember'),
Guild: require('../structures/Guild'),
Message: require('../structures/Message'),
MessageReaction: require('../structures/MessageReaction'),
Presence: require('../structures/Presence').Presence,
Role: require('../structures/Role'),
User: require('../structures/User'),
};

module.exports = Structures;

0 comments on commit 77fc046

Please sign in to comment.