Datastore cleanup (#1892)

* Start Store cleanup

* wip store cleanup

* fix iterables initiating datastores

* handle the possibility of a datastore with no holds and no its own 'create' method

* more cleanup (instances that need more than just client/data)

* missed RoleStore extras

* not sure how eslint didn't catch that tab...

* avoid re-getting the channel we already have...

* cleanup resolvers and refactor them into DataStores

* ^

* and remove

* fix some bugs

* fix lint

* fix documentation maybe?

* formatting

* fix presences

* really fix presences this time

* bad fix was bad... let;s see how bad this one is..

* forgot to save a file

* make presence resolving take userresolveables too

* fix tabs in jsdocs

* fix bad fix from last night that caused issues, with better fix...

* oops
This commit is contained in:
bdistin
2017-09-08 16:06:10 -05:00
committed by Crawl
parent 0607720ec8
commit dd085ceaee
34 changed files with 560 additions and 435 deletions

View File

@@ -1,5 +1,6 @@
const Snowflake = require('../util/Snowflake');
const Constants = require('../util/Constants');
const DataResolver = require('../util/DataResolver');
const Base = require('./Base');
/**
@@ -165,7 +166,7 @@ class ClientApplication extends Base {
* @returns {Promise}
*/
createAsset(name, data, type) {
return this.client.resolveBase64(data).then(b64 =>
return DataResolver.resolveBase64(data).then(b64 =>
this.client.api.applications(this.id).assets.post({ data: {
name,
data: b64,

View File

@@ -4,6 +4,7 @@ const ClientUserSettings = require('./ClientUserSettings');
const ClientUserGuildSettings = require('./ClientUserGuildSettings');
const Constants = require('../util/Constants');
const Util = require('../util/Util');
const DataResolver = require('../util/DataResolver');
const Guild = require('./Guild');
/**
@@ -177,7 +178,7 @@ class ClientUser extends User {
* .catch(console.error);
*/
async setAvatar(avatar) {
return this.edit({ avatar: await this.client.resolver.resolveImage(avatar) });
return this.edit({ avatar: await DataResolver.resolveImage(avatar, this.client.browser) });
}
/**
@@ -293,7 +294,7 @@ class ClientUser extends User {
);
}
return this.client.resolver.resolveImage(icon)
return DataResolver.resolveImage(icon, this.client.browser)
.then(data => this.createGuild(name, { region, icon: data || null }));
}
@@ -320,7 +321,7 @@ class ClientUser extends User {
if (r.nick) o[r.user ? r.user.id : r.id] = r.nick;
return o;
}, {}),
} : { recipients: recipients.map(u => this.client.resolver.resolveUserID(u.user || u.id)) };
} : { recipients: recipients.map(u => this.client.users.resolveID(u.user || u.id)) };
return this.client.api.users('@me').channels.post({ data })
.then(res => this.client.channels.create(res));
}

View File

@@ -8,8 +8,8 @@ const { TypeError } = require('../errors');
* @extends {Base}
*/
class Emoji extends Base {
constructor(guild, data) {
super(guild.client);
constructor(client, data, guild) {
super(client);
/**
* The guild this emoji is part of
@@ -152,7 +152,7 @@ class Emoji extends Base {
addRestrictedRoles(roles) {
const newRoles = new Collection(this.roles);
for (let role of roles instanceof Collection ? roles.values() : roles) {
role = this.client.resolver.resolveRole(this.guild, role);
role = this.guild.roles.resolve(role);
if (!role) {
return Promise.reject(new TypeError('INVALID_TYPE', 'roles',
'Array or Collection of Roles or Snowflakes', true));
@@ -179,7 +179,7 @@ class Emoji extends Base {
removeRestrictedRoles(roles) {
const newRoles = new Collection(this.roles);
for (let role of roles instanceof Collection ? roles.values() : roles) {
role = this.client.resolver.resolveRole(this.guild, role);
role = this.guild.roles.resolve(role);
if (!role) {
return Promise.reject(new TypeError('INVALID_TYPE', 'roles',
'Array or Collection of Roles or Snowflakes', true));

View File

@@ -1,6 +1,7 @@
const Channel = require('./Channel');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const Collection = require('../util/Collection');
const DataResolver = require('../util/DataResolver');
const MessageStore = require('../stores/MessageStore');
/*
@@ -160,7 +161,7 @@ class GroupDMChannel extends Channel {
* @returns {Promise<GroupDMChannel>}
*/
async setIcon(icon) {
return this.edit({ icon: await this.client.resolver.resolveImage(icon) });
return this.edit({ icon: await DataResolver.resolveImage(icon, this.client.browser) });
}
/**
@@ -182,7 +183,7 @@ class GroupDMChannel extends Channel {
* @returns {Promise<GroupDMChannel>}
*/
addUser({ user, accessToken, nick }) {
const id = this.client.resolver.resolveUserID(user);
const id = this.client.users.resolveID(user);
const data = this.client.user.bot ?
{ nick, access_token: accessToken } :
{ recipient: id };
@@ -196,7 +197,7 @@ class GroupDMChannel extends Channel {
* @returns {Promise<GroupDMChannel>}
*/
removeUser(user) {
const id = this.client.resolver.resolveUserID(user);
const id = this.client.users.resolveID(user);
return this.client.api.channels[this.id].recipients[id].delete()
.then(() => this);
}

View File

@@ -9,6 +9,7 @@ const VoiceRegion = require('./VoiceRegion');
const Constants = require('../util/Constants');
const Collection = require('../util/Collection');
const Util = require('../util/Util');
const DataResolver = require('../util/DataResolver');
const Snowflake = require('../util/Snowflake');
const Permissions = require('../util/Permissions');
const Shared = require('./shared');
@@ -431,7 +432,7 @@ class Guild extends Base {
* const member = guild.member(message.author);
*/
member(user) {
return this.client.resolver.resolveGuildMember(this, user);
return this.members.resolve(user);
}
/**
@@ -511,7 +512,7 @@ class Guild extends Base {
before: options.before,
after: options.after,
limit: options.limit,
user_id: this.client.resolver.resolveUserID(options.user),
user_id: this.client.users.resolveID(options.user),
action_type: options.type,
} })
.then(data => GuildAuditLogs.build(this, data));
@@ -536,7 +537,7 @@ class Guild extends Base {
if (options.roles) {
const roles = [];
for (let role of options.roles instanceof Collection ? options.roles.values() : options.roles) {
role = this.client.resolver.resolveRole(this, role);
role = this.roles.resolve(role);
if (!role) {
return Promise.reject(new TypeError('INVALID_TYPE', 'options.roles',
'Array or Collection of Roles or Snowflakes', true));
@@ -601,14 +602,14 @@ class Guild extends Base {
if (data.region) _data.region = data.region;
if (typeof data.verificationLevel !== 'undefined') _data.verification_level = Number(data.verificationLevel);
if (typeof data.afkChannel !== 'undefined') {
_data.afk_channel_id = this.client.resolver.resolveChannelID(data.afkChannel);
_data.afk_channel_id = this.client.channels.resolveID(data.afkChannel);
}
if (typeof data.systemChannel !== 'undefined') {
_data.system_channel_id = this.client.resolver.resolveChannelID(data.systemChannel);
_data.system_channel_id = this.client.channels.resolveID(data.systemChannel);
}
if (data.afkTimeout) _data.afk_timeout = Number(data.afkTimeout);
if (typeof data.icon !== 'undefined') _data.icon = data.icon;
if (data.owner) _data.owner_id = this.client.resolver.resolveUser(data.owner).id;
if (data.owner) _data.owner_id = this.client.users.resolve(data.owner).id;
if (data.splash) _data.splash = data.splash;
if (typeof data.explicitContentFilter !== 'undefined') {
_data.explicit_content_filter = Number(data.explicitContentFilter);
@@ -724,7 +725,7 @@ class Guild extends Base {
* .catch(console.error);
*/
async setIcon(icon, reason) {
return this.edit({ icon: await this.client.resolver.resolveImage(icon), reason });
return this.edit({ icon: await DataResolver.resolveImage(icon, this.client.browser), reason });
}
/**
@@ -754,7 +755,7 @@ class Guild extends Base {
* .catch(console.error);
*/
async setSplash(splash, reason) {
return this.edit({ splash: await this.client.resolver.resolveImage(splash), reason });
return this.edit({ splash: await DataResolver.resolveImage(splash, this.client.browser), reason });
}
/**
@@ -815,14 +816,14 @@ class Guild extends Base {
*/
ban(user, options = { days: 0 }) {
if (options.days) options['delete-message-days'] = options.days;
const id = this.client.resolver.resolveUserID(user);
const id = this.client.users.resolveID(user);
if (!id) return Promise.reject(new Error('BAN_RESOLVE_ID', true));
return this.client.api.guilds(this.id).bans[id].put({ query: options })
.then(() => {
if (user instanceof GuildMember) return user;
const _user = this.client.resolver.resolveUser(id);
const _user = this.client.users.resolve(id);
if (_user) {
const member = this.client.resolver.resolveGuildMember(this, _user);
const member = this.members.resolve(_user);
return member || _user;
}
return id;
@@ -841,7 +842,7 @@ class Guild extends Base {
* .catch(console.error);
*/
unban(user, reason) {
const id = this.client.resolver.resolveUserID(user);
const id = this.client.users.resolverID(user);
if (!id) throw new Error('BAN_RESOLVE_ID');
return this.client.api.guilds(this.id).bans[id].delete({ reason })
.then(() => user);
@@ -910,12 +911,12 @@ class Guild extends Base {
if (allow instanceof Array) allow = Permissions.resolve(allow);
if (deny instanceof Array) deny = Permissions.resolve(deny);
const role = this.client.resolver.resolveRole(this, overwrite.id);
const role = this.roles.resolve(overwrite.id);
if (role) {
overwrite.id = role.id;
overwrite.type = 'role';
} else {
overwrite.id = this.client.resolver.resolveUserID(overwrite.id);
overwrite.id = this.client.users.resolveID(overwrite.id);
overwrite.type = 'member';
}
@@ -988,7 +989,7 @@ class Guild extends Base {
*/
setChannelPositions(channelPositions) {
const updatedChannels = channelPositions.map(r => ({
id: this.client.resolver.resolveChannelID(r.channel),
id: this.client.channels.resolveID(r.channel),
position: r.position,
}));
@@ -1063,7 +1064,7 @@ class Guild extends Base {
if (roles) {
data.roles = [];
for (let role of roles instanceof Collection ? roles.values() : roles) {
role = this.client.resolver.resolveRole(this, role);
role = this.roles.resolve(role);
if (!role) {
return Promise.reject(new TypeError('INVALID_TYPE', 'options.roles',
'Array or Collection of Roles or Snowflakes', true));
@@ -1076,7 +1077,7 @@ class Guild extends Base {
.then(emoji => this.client.actions.GuildEmojiCreate.handle(this, emoji).emoji);
}
return this.client.resolver.resolveImage(attachment)
return DataResolver.resolveImage(attachment, this.client.browser)
.then(image => this.createEmoji(image, name, { roles, reason }));
}

View File

@@ -66,7 +66,7 @@ class GuildChannel extends Channel {
* @returns {?Permissions}
*/
permissionsFor(member) {
member = this.client.resolver.resolveGuildMember(this.guild, member);
member = this.guild.members.resolve(member);
if (!member) return null;
if (member.id === this.guild.ownerID) return new Permissions(Permissions.ALL);
@@ -101,7 +101,7 @@ class GuildChannel extends Channel {
}
overwritesFor(member, verified = false, roles = null) {
if (!verified) member = this.client.resolver.resolveGuildMember(this.guild, member);
if (!verified) member = this.guild.members.resolve(member);
if (!member) return [];
roles = roles || member.roles;
@@ -158,13 +158,13 @@ class GuildChannel extends Channel {
deny: 0,
};
if (userOrRole instanceof Role) {
payload.type = 'role';
} else if (this.guild.roles.has(userOrRole)) {
userOrRole = this.guild.roles.get(userOrRole);
const role = this.guild.roles.get(userOrRole);
if (role || userOrRole instanceof Role) {
userOrRole = role || userOrRole;
payload.type = 'role';
} else {
userOrRole = this.client.resolver.resolveUser(userOrRole);
userOrRole = this.client.users.resolve(userOrRole);
payload.type = 'member';
if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role', true));
}

View File

@@ -12,8 +12,8 @@ const { Error, TypeError } = require('../errors');
* @extends {Base}
*/
class GuildMember extends Base {
constructor(guild, data) {
super(guild.client);
constructor(client, data, guild) {
super(client);
/**
* The guild that this member is part of
@@ -291,7 +291,7 @@ class GuildMember extends Base {
* @returns {?Permissions}
*/
permissionsIn(channel) {
channel = this.client.resolver.resolveChannel(channel);
channel = this.client.channels.resolve(channel);
if (!channel || !channel.guild) throw new Error('GUILD_CHANNEL_RESOLVE');
return channel.permissionsFor(this);
}
@@ -342,7 +342,7 @@ class GuildMember extends Base {
*/
edit(data, reason) {
if (data.channel) {
data.channel_id = this.client.resolver.resolveChannel(data.channel).id;
data.channel_id = this.client.channels.resolve(data.channel).id;
data.channel = null;
}
if (data.roles) data.roles = data.roles.map(role => role instanceof Role ? role.id : role);
@@ -412,7 +412,7 @@ class GuildMember extends Base {
* @returns {Promise<GuildMember>}
*/
addRole(role, reason) {
role = this.client.resolver.resolveRole(this.guild, role);
role = this.guild.roles.resolve(role);
if (!role) return Promise.reject(new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake'));
if (this._roles.includes(role.id)) return Promise.resolve(this);
return this.client.api.guilds(this.guild.id).members(this.user.id).roles(role.id)
@@ -433,7 +433,7 @@ class GuildMember extends Base {
addRoles(roles, reason) {
let allRoles = this._roles.slice();
for (let role of roles instanceof Collection ? roles.values() : roles) {
role = this.client.resolver.resolveRole(this.guild, role);
role = this.guild.roles.resolve(role);
if (!role) {
return Promise.reject(new TypeError('INVALID_TYPE', 'roles',
'Array or Collection of Roles or Snowflakes', true));
@@ -450,7 +450,7 @@ class GuildMember extends Base {
* @returns {Promise<GuildMember>}
*/
removeRole(role, reason) {
role = this.client.resolver.resolveRole(this.guild, role);
role = this.guild.roles.resolve(role);
if (!role) return Promise.reject(new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake'));
if (!this._roles.includes(role.id)) return Promise.resolve(this);
return this.client.api.guilds(this.guild.id).members(this.user.id).roles(role.id)
@@ -472,7 +472,7 @@ class GuildMember extends Base {
removeRoles(roles, reason) {
const allRoles = this._roles.slice();
for (let role of roles instanceof Collection ? roles.values() : roles) {
role = this.client.resolver.resolveRole(this.guild, role);
role = this.guild.roles.resolve(role);
if (!role) {
return Promise.reject(new TypeError('INVALID_TYPE', 'roles',
'Array or Collection of Roles or Snowflakes', true));

View File

@@ -17,7 +17,7 @@ let GuildMember;
* @extends {Base}
*/
class Message extends Base {
constructor(channel, data, client) {
constructor(client, data, channel) {
super(client);
/**
@@ -393,7 +393,7 @@ class Message extends Base {
// Add the reply prefix
if (reply && this.channel.type !== 'dm') {
const id = this.client.resolver.resolveUserID(reply);
const id = this.client.users.resolveID(reply);
const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
content = `${mention}${content ? `, ${content}` : ''}`;
}
@@ -427,11 +427,11 @@ class Message extends Base {
/**
* Add a reaction to the message.
* @param {string|Emoji|ReactionEmoji} emoji The emoji to react with
* @param {EmojiIdentifierResolveable} emoji The emoji to react with
* @returns {Promise<MessageReaction>}
*/
react(emoji) {
emoji = this.client.resolver.resolveEmojiIdentifier(emoji);
emoji = this.client.emojis.resolveIdentifier(emoji);
if (!emoji) throw new TypeError('EMOJI_TYPE');
return this.client.api.channels(this.channel.id).messages(this.id).reactions(emoji, '@me')

View File

@@ -7,7 +7,7 @@ const { Error } = require('../errors');
* Represents a reaction to a message.
*/
class MessageReaction {
constructor(message, emoji, count, me) {
constructor(client, data, message) {
/**
* The message that this reaction refers to
* @type {Message}
@@ -18,13 +18,13 @@ class MessageReaction {
* Whether the client has given this reaction
* @type {boolean}
*/
this.me = me;
this.me = data.me;
/**
* The number of people that have given the same reaction
* @type {number}
*/
this.count = count || 0;
this.count = data.count || 0;
/**
* The users that have given this reaction, mapped by their ID
@@ -32,7 +32,7 @@ class MessageReaction {
*/
this.users = new Collection();
this._emoji = new ReactionEmoji(this, emoji.name, emoji.id);
this._emoji = new ReactionEmoji(this, data.emoji.name, data.emoji.id);
}
/**
@@ -62,7 +62,7 @@ class MessageReaction {
* @returns {Promise<MessageReaction>}
*/
remove(user = this.message.client.user) {
const userID = this.message.client.resolver.resolveUserID(user);
const userID = this.message.client.users.resolveID(user);
if (!userID) return Promise.reject(new Error('REACTION_RESOLVE_USER'));
return this.message.client.api.channels[this.message.channel.id].messages[this.message.id]
.reactions[this.emoji.identifier][userID === this.message.client.user.id ? '@me' : userID]

View File

@@ -26,6 +26,8 @@ class Presence {
* @type {?Activity}
*/
this.activity = activity ? new Activity(this, activity) : null;
return this;
}
_clone() {

View File

@@ -9,8 +9,8 @@ const { TypeError } = require('../errors');
* @extends {Base}
*/
class Role extends Base {
constructor(guild, data) {
super(guild.client);
constructor(client, data, guild) {
super(client);
/**
* The guild that the role belongs to
@@ -171,7 +171,7 @@ class Role extends Base {
* positive number if the this one is higher (other's is lower), 0 if equal
*/
comparePositionTo(role) {
role = this.client.resolver.resolveRole(this.guild, role);
role = this.guild.roles.resolve(role);
if (!role) return Promise.reject(new TypeError('INVALID_TYPE', 'role', 'Role nor a Snowflake'));
return this.constructor.comparePositions(this, role);
}

View File

@@ -2,6 +2,7 @@ const GuildChannel = require('./GuildChannel');
const Webhook = require('./Webhook');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const Collection = require('../util/Collection');
const DataResolver = require('../util/DataResolver');
const MessageStore = require('../stores/MessageStore');
/**
@@ -63,7 +64,7 @@ class TextChannel extends GuildChannel {
*/
async createWebhook(name, { avatar, reason } = {}) {
if (typeof avatar === 'string' && !avatar.startsWith('data:')) {
avatar = await this.client.resolver.resolveImage(avatar);
avatar = await DataResolver.resolveImage(avatar, this.client.browser);
}
return this.client.api.channels[this.id].webhooks.post({ data: {
name, avatar,

View File

@@ -158,7 +158,7 @@ class User extends Base {
* @returns {boolean}
*/
typingIn(channel) {
channel = this.client.resolver.resolveChannel(channel);
channel = this.client.channels.resolve(channel);
return channel._typing.has(this.id);
}
@@ -168,7 +168,7 @@ class User extends Base {
* @returns {?Date}
*/
typingSinceIn(channel) {
channel = this.client.resolver.resolveChannel(channel);
channel = this.client.channels.resolve(channel);
return channel._typing.has(this.id) ? new Date(channel._typing.get(this.id).since) : null;
}
@@ -178,7 +178,7 @@ class User extends Base {
* @returns {number}
*/
typingDurationIn(channel) {
channel = this.client.resolver.resolveChannel(channel);
channel = this.client.channels.resolve(channel);
return channel._typing.has(this.id) ? channel._typing.get(this.id).elapsedTime : -1;
}

View File

@@ -1,5 +1,6 @@
const path = require('path');
const Util = require('../util/Util');
const DataResolver = require('../util/DataResolver');
const Embed = require('./MessageEmbed');
const MessageAttachment = require('./MessageAttachment');
const MessageEmbed = require('./MessageEmbed');
@@ -168,7 +169,7 @@ class Webhook {
}
return Promise.all(options.files.map(file =>
this.client.resolver.resolveFile(file.attachment).then(resource => {
DataResolver.resolveFile(file.attachment, this.client.browser).then(resource => {
file.file = resource;
return file;
})
@@ -248,7 +249,7 @@ class Webhook {
*/
edit({ name = this.name, avatar }, reason) {
if (avatar && (typeof avatar === 'string' && !avatar.startsWith('data:'))) {
return this.client.resolver.resolveImage(avatar).then(image =>
return DataResolver.resolveImage(avatar, this.client.browser).then(image =>
this.edit({ name, avatar: image }, reason)
);
}

View File

@@ -1,9 +1,9 @@
const path = require('path');
const MessageCollector = require('../MessageCollector');
const Shared = require('../shared');
const MessageStore = require('../../stores/MessageStore');
const Snowflake = require('../../util/Snowflake');
const Collection = require('../../util/Collection');
const DataResolver = require('../../util/DataResolver');
const MessageAttachment = require('../../structures/MessageAttachment');
const MessageEmbed = require('../../structures/MessageEmbed');
const { RangeError, TypeError } = require('../../errors');
@@ -124,7 +124,7 @@ class TextBasedChannel {
}
return Promise.all(options.files.map(file =>
this.client.resolver.resolveFile(file.attachment).then(resource => {
DataResolver.resolveFile(file.attachment, this.client.browser).then(resource => {
file.file = resource;
return file;
})
@@ -341,3 +341,6 @@ class TextBasedChannel {
}
module.exports = TextBasedChannel;
// Fixes Circular
const MessageStore = require('../../stores/MessageStore');

View File

@@ -52,9 +52,9 @@ module.exports = function search(target, options) {
options.minID = long.fromNumber(t).shiftLeft(22).toString();
options.maxID = long.fromNumber(t + 864e5).shiftLeft(22).toString();
}
if (options.channel) options.channel = target.client.resolver.resolveChannelID(options.channel);
if (options.author) options.author = target.client.resolver.resolveUserID(options.author);
if (options.mentions) options.mentions = target.client.resolver.resolveUserID(options.options.mentions);
if (options.channel) options.channel = target.client.channels.resolveID(options.channel);
if (options.author) options.author = target.client.users.resolveID(options.author);
if (options.mentions) options.mentions = target.client.users.resolveID(options.options.mentions);
if (options.sortOrder) {
options.sortOrder = { ascending: 'asc', descending: 'desc' }[options.sortOrder] || options.sortOrder;
}

View File

@@ -17,7 +17,7 @@ module.exports = function sendMessage(channel, options) { // eslint-disable-line
// Add the reply prefix
if (reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') {
const id = channel.client.resolver.resolveUserID(reply);
const id = channel.client.users.resolveID(reply);
const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
if (split) split.prepend = `${mention}, ${split.prepend || ''}`;
content = `${mention}${typeof content !== 'undefined' ? `, ${content}` : ''}`;