refactor(*): use async functions (#6210)

This commit is contained in:
Sugden
2021-08-02 00:47:43 +01:00
committed by GitHub
parent 626ff85ae7
commit e2e4f6518b
29 changed files with 298 additions and 399 deletions

View File

@@ -236,7 +236,7 @@ class Client extends BaseClient {
); );
if (this.options.presence) { if (this.options.presence) {
this.options.ws.presence = await this.presence._parse(this.options.presence); this.options.ws.presence = this.presence._parse(this.options.presence);
} }
this.emit(Events.DEBUG, 'Preparing to connect to the gateway...'); this.emit(Events.DEBUG, 'Preparing to connect to the gateway...');
@@ -284,12 +284,10 @@ class Client extends BaseClient {
* .then(invite => console.log(`Obtained invite with code: ${invite.code}`)) * .then(invite => console.log(`Obtained invite with code: ${invite.code}`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchInvite(invite) { async fetchInvite(invite) {
const code = DataResolver.resolveInviteCode(invite); const code = DataResolver.resolveInviteCode(invite);
return this.api const data = await this.api.invites(code).get({ query: { with_counts: true, with_expiration: true } });
.invites(code) return new Invite(this, data);
.get({ query: { with_counts: true, with_expiration: true } })
.then(data => new Invite(this, data));
} }
/** /**
@@ -301,12 +299,10 @@ class Client extends BaseClient {
* .then(template => console.log(`Obtained template with code: ${template.code}`)) * .then(template => console.log(`Obtained template with code: ${template.code}`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchGuildTemplate(template) { async fetchGuildTemplate(template) {
const code = DataResolver.resolveGuildTemplateCode(template); const code = DataResolver.resolveGuildTemplateCode(template);
return this.api.guilds const data = await this.api.guilds.templates(code).get();
.templates(code) return new GuildTemplate(this, data);
.get()
.then(data => new GuildTemplate(this, data));
} }
/** /**
@@ -319,11 +315,9 @@ class Client extends BaseClient {
* .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`)) * .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchWebhook(id, token) { async fetchWebhook(id, token) {
return this.api const data = await this.api.webhooks(id, token).get();
.webhooks(id, token) return new Webhook(this, { token, ...data });
.get()
.then(data => new Webhook(this, { token, ...data }));
} }
/** /**
@@ -334,12 +328,11 @@ class Client extends BaseClient {
* .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`)) * .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchVoiceRegions() { async fetchVoiceRegions() {
return this.api.voice.regions.get().then(res => { const apiRegions = await this.api.voice.regions.get();
const regions = new Collection(); const regions = new Collection();
for (const region of res) regions.set(region.id, new VoiceRegion(region)); for (const region of apiRegions) regions.set(region.id, new VoiceRegion(region));
return regions; return regions;
});
} }
/** /**
@@ -433,13 +426,11 @@ class Client extends BaseClient {
* @param {GuildResolvable} guild The guild to fetch the preview for * @param {GuildResolvable} guild The guild to fetch the preview for
* @returns {Promise<GuildPreview>} * @returns {Promise<GuildPreview>}
*/ */
fetchGuildPreview(guild) { async fetchGuildPreview(guild) {
const id = this.guilds.resolveId(guild); const id = this.guilds.resolveId(guild);
if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable'); if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
return this.api const data = await this.api.guilds(id).preview.get();
.guilds(id) return new GuildPreview(this, data);
.preview.get()
.then(data => new GuildPreview(this, data));
} }
/** /**

View File

@@ -65,10 +65,8 @@ class GuildEmojiManager extends BaseGuildEmojiManager {
} }
} }
return this.client.api const emoji = await this.client.api.guilds(this.guild.id).emojis.post({ data, reason });
.guilds(this.guild.id) return this.client.actions.GuildEmojiCreate.handle(this.guild, emoji).emoji;
.emojis.post({ data, reason })
.then(emoji => this.client.actions.GuildEmojiCreate.handle(this.guild, emoji).emoji);
} }
/** /**

View File

@@ -195,45 +195,42 @@ class GuildManager extends CachedManager {
} }
if (systemChannelFlags) systemChannelFlags = SystemChannelFlags.resolve(systemChannelFlags); if (systemChannelFlags) systemChannelFlags = SystemChannelFlags.resolve(systemChannelFlags);
return new Promise((resolve, reject) => const data = await this.client.api.guilds.post({
this.client.api.guilds data: {
.post({ name,
data: { icon,
name, verification_level: verificationLevel,
icon, default_message_notifications: defaultMessageNotifications,
verification_level: verificationLevel, explicit_content_filter: explicitContentFilter,
default_message_notifications: defaultMessageNotifications, roles,
explicit_content_filter: explicitContentFilter, channels,
roles, afk_channel_id: afkChannelId,
channels, afk_timeout: afkTimeout,
afk_channel_id: afkChannelId, system_channel_id: systemChannelId,
afk_timeout: afkTimeout, system_channel_flags: systemChannelFlags,
system_channel_id: systemChannelId, },
system_channel_flags: systemChannelFlags, });
},
})
.then(data => {
if (this.client.guilds.cache.has(data.id)) return resolve(this.client.guilds.cache.get(data.id));
const handleGuild = guild => { if (this.client.guilds.cache.has(data.id)) return this.client.guilds.cache.get(data.id);
if (guild.id === data.id) {
clearTimeout(timeout);
this.client.removeListener(Events.GUILD_CREATE, handleGuild);
this.client.decrementMaxListeners();
resolve(guild);
}
};
this.client.incrementMaxListeners();
this.client.on(Events.GUILD_CREATE, handleGuild);
const timeout = setTimeout(() => { return new Promise(resolve => {
this.client.removeListener(Events.GUILD_CREATE, handleGuild); const handleGuild = guild => {
this.client.decrementMaxListeners(); if (guild.id === data.id) {
resolve(this.client.guilds._add(data)); clearTimeout(timeout);
}, 10000).unref(); this.client.removeListener(Events.GUILD_CREATE, handleGuild);
return undefined; this.client.decrementMaxListeners();
}, reject), resolve(guild);
); }
};
this.client.incrementMaxListeners();
this.client.on(Events.GUILD_CREATE, handleGuild);
const timeout = setTimeout(() => {
this.client.removeListener(Events.GUILD_CREATE, handleGuild);
this.client.decrementMaxListeners();
resolve(this.client.guilds._add(data));
}, 10000).unref();
});
} }
/** /**

View File

@@ -277,8 +277,8 @@ class GuildMemberManager extends CachedManager {
* .then(pruned => console.log(`I just pruned ${pruned} people!`)) * .then(pruned => console.log(`I just pruned ${pruned} people!`))
* .catch(console.error); * .catch(console.error);
*/ */
prune({ days = 7, dry = false, count: compute_prune_count = true, roles = [], reason } = {}) { async prune({ days = 7, dry = false, count: compute_prune_count = true, roles = [], reason } = {}) {
if (typeof days !== 'number') return Promise.reject(new TypeError('PRUNE_DAYS_TYPE')); if (typeof days !== 'number') throw new TypeError('PRUNE_DAYS_TYPE');
const query = { days }; const query = { days };
const resolvedRoles = []; const resolvedRoles = [];
@@ -286,7 +286,7 @@ class GuildMemberManager extends CachedManager {
for (const role of roles) { for (const role of roles) {
const resolvedRole = this.guild.roles.resolveId(role); const resolvedRole = this.guild.roles.resolveId(role);
if (!resolvedRole) { if (!resolvedRole) {
return Promise.reject(new TypeError('INVALID_ELEMENT', 'Array', 'options.roles', role)); throw new TypeError('INVALID_ELEMENT', 'Array', 'options.roles', role);
} }
resolvedRoles.push(resolvedRole); resolvedRoles.push(resolvedRole);
} }
@@ -297,16 +297,11 @@ class GuildMemberManager extends CachedManager {
const endpoint = this.client.api.guilds(this.guild.id).prune; const endpoint = this.client.api.guilds(this.guild.id).prune;
if (dry) { const { pruned } = await (dry
return endpoint.get({ query, reason }).then(data => data.pruned); ? endpoint.get({ query, reason })
} : endpoint.post({ data: { ...query, compute_prune_count }, reason }));
return endpoint return pruned;
.post({
data: { ...query, compute_prune_count },
reason,
})
.then(data => data.pruned);
} }
/** /**
@@ -366,17 +361,14 @@ class GuildMemberManager extends CachedManager {
return this.guild.bans.remove(user, reason); return this.guild.bans.remove(user, reason);
} }
_fetchSingle({ user, cache, force = false }) { async _fetchSingle({ user, cache, force = false }) {
if (!force) { if (!force) {
const existing = this.cache.get(user); const existing = this.cache.get(user);
if (existing && !existing.partial) return Promise.resolve(existing); if (existing && !existing.partial) return existing;
} }
return this.client.api const data = await this.client.api.guilds(this.guild.id).members(user).get();
.guilds(this.guild.id) return this._add(data, cache);
.members(user)
.get()
.then(data => this._add(data, cache));
} }
_fetchMany({ _fetchMany({

View File

@@ -57,10 +57,10 @@ class GuildStickerManager extends CachedManager {
const data = { name, tags, description: description ?? '' }; const data = { name, tags, description: description ?? '' };
return this.client.api const sticker = await this.client.api
.guilds(this.guild.id) .guilds(this.guild.id)
.stickers.post({ data, files: [file], reason, dontUsePayloadJSON: true }) .stickers.post({ data, files: [file], reason, dontUsePayloadJSON: true });
.then(sticker => this.client.actions.GuildStickerCreate.handle(this.guild, sticker).sticker); return this.client.actions.GuildStickerCreate.handle(this.guild, sticker).sticker;
} }
/** /**

View File

@@ -80,12 +80,11 @@ class MessageManager extends CachedManager {
* .then(messages => console.log(`Received ${messages.size} messages`)) * .then(messages => console.log(`Received ${messages.size} messages`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchPinned(cache = true) { async fetchPinned(cache = true) {
return this.client.api.channels[this.channel.id].pins.get().then(data => { const data = await this.client.api.channels[this.channel.id].pins.get();
const messages = new Collection(); const messages = new Collection();
for (const message of data) messages.set(message.id, this._add(message, cache)); for (const message of data) messages.set(message.id, this._add(message, cache));
return messages; return messages;
});
} }
/** /**

View File

@@ -54,7 +54,9 @@ class PermissionOverwriteManager extends CachedManager {
*/ */
set(overwrites, reason) { set(overwrites, reason) {
if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) { if (!Array.isArray(overwrites) && !(overwrites instanceof Collection)) {
throw new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true); return Promise.reject(
new TypeError('INVALID_TYPE', 'overwrites', 'Array or Collection of Permission Overwrites', true),
);
} }
return this.channel.edit({ permissionOverwrites: overwrites, reason }); return this.channel.edit({ permissionOverwrites: overwrites, reason });
} }
@@ -81,7 +83,7 @@ class PermissionOverwriteManager extends CachedManager {
let { type, reason } = overwriteOptions; let { type, reason } = overwriteOptions;
if (typeof type !== 'number') { if (typeof type !== 'number') {
userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole); userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
if (!userOrRole) return Promise.reject(new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role')); if (!userOrRole) throw new TypeError('INVALID_TYPE', 'parameter', 'User nor a Role');
type = userOrRole instanceof Role ? OverwriteTypes.role : OverwriteTypes.member; type = userOrRole instanceof Role ? OverwriteTypes.role : OverwriteTypes.member;
} }

View File

@@ -57,12 +57,9 @@ class ReactionManager extends CachedManager {
* Removes all reactions from a message. * Removes all reactions from a message.
* @returns {Promise<Message>} * @returns {Promise<Message>}
*/ */
removeAll() { async removeAll() {
return this.client.api await this.client.api.channels(this.message.channel.id).messages(this.message.id).reactions.delete();
.channels(this.message.channel.id) return this.message;
.messages(this.message.id)
.reactions.delete()
.then(() => this.message);
} }
} }

View File

@@ -57,15 +57,14 @@ class ReactionUserManager extends CachedManager {
* @param {UserResolvable} [user=this.client.user] The user to remove the reaction of * @param {UserResolvable} [user=this.client.user] The user to remove the reaction of
* @returns {Promise<MessageReaction>} * @returns {Promise<MessageReaction>}
*/ */
remove(user = this.client.user) { async remove(user = this.client.user) {
const userId = this.client.users.resolveId(user); const userId = this.client.users.resolveId(user);
if (!userId) return Promise.reject(new Error('REACTION_RESOLVE_USER')); if (!userId) throw new Error('REACTION_RESOLVE_USER');
const message = this.reaction.message; const message = this.reaction.message;
return this.client.api.channels[message.channel.id].messages[message.id].reactions[this.reaction.emoji.identifier][ await this.client.api.channels[message.channel.id].messages[message.id].reactions[this.reaction.emoji.identifier][
userId === this.client.user.id ? '@me' : userId userId === this.client.user.id ? '@me' : userId
] ].delete();
.delete() return this.reaction;
.then(() => this.reaction);
} }
} }

View File

@@ -118,31 +118,27 @@ class RoleManager extends CachedManager {
* .then(console.log) * .then(console.log)
* .catch(console.error); * .catch(console.error);
*/ */
create(options = {}) { async create(options = {}) {
let { name, color, hoist, permissions, position, mentionable, reason } = options; let { name, color, hoist, permissions, position, mentionable, reason } = options;
if (color) color = resolveColor(color); if (color) color = resolveColor(color);
if (typeof permissions !== 'undefined') permissions = new Permissions(permissions); if (typeof permissions !== 'undefined') permissions = new Permissions(permissions);
return this.client.api const data = await this.client.api.guilds(this.guild.id).roles.post({
.guilds(this.guild.id) data: {
.roles.post({ name,
data: { color,
name, hoist,
color, permissions,
hoist, mentionable,
permissions, },
mentionable, reason,
}, });
reason, const { role } = this.client.actions.GuildRoleCreate.handle({
}) guild_id: this.guild.id,
.then(r => { role: data,
const { role } = this.client.actions.GuildRoleCreate.handle({ });
guild_id: this.guild.id, if (position) return role.setPosition(position, reason);
role: r, return role;
});
if (position) return role.setPosition(position, reason);
return role;
});
} }
/** /**

View File

@@ -74,13 +74,11 @@ class ThreadMemberManager extends CachedManager {
* @param {string} [reason] The reason for adding this member * @param {string} [reason] The reason for adding this member
* @returns {Promise<Snowflake>} * @returns {Promise<Snowflake>}
*/ */
add(member, reason) { async add(member, reason) {
const id = member === '@me' ? member : this.client.users.resolveId(member); const id = member === '@me' ? member : this.client.users.resolveId(member);
if (!id) return Promise.reject(new TypeError('INVALID_TYPE', 'member', 'UserResolvable')); if (!id) throw new TypeError('INVALID_TYPE', 'member', 'UserResolvable');
return this.client.api await this.client.api.channels(this.thread.id, 'thread-members', id).put({ reason });
.channels(this.thread.id, 'thread-members', id) return id;
.put({ reason })
.then(() => id);
} }
/** /**
@@ -89,11 +87,9 @@ class ThreadMemberManager extends CachedManager {
* @param {string} [reason] The reason for removing this member from the thread * @param {string} [reason] The reason for removing this member from the thread
* @returns {Promise<Snowflake>} * @returns {Promise<Snowflake>}
*/ */
remove(id, reason) { async remove(id, reason) {
return this.client.api await this.client.api.channels(this.thread.id, 'thread-members', id).delete({ reason });
.channels(this.thread.id, 'thread-members', id) return id;
.delete({ reason })
.then(() => id);
} }
/** /**

View File

@@ -106,7 +106,7 @@ class Shard extends EventEmitter {
* before resolving (`-1` or `Infinity` for no wait) * before resolving (`-1` or `Infinity` for no wait)
* @returns {Promise<ChildProcess>} * @returns {Promise<ChildProcess>}
*/ */
async spawn(timeout = 30000) { spawn(timeout = 30000) {
if (this.process) throw new Error('SHARDING_PROCESS_EXISTS', this.id); if (this.process) throw new Error('SHARDING_PROCESS_EXISTS', this.id);
if (this.worker) throw new Error('SHARDING_WORKER_EXISTS', this.id); if (this.worker) throw new Error('SHARDING_WORKER_EXISTS', this.id);
@@ -137,7 +137,7 @@ class Shard extends EventEmitter {
this.emit('spawn', child); this.emit('spawn', child);
if (timeout === -1 || timeout === Infinity) return child; if (timeout === -1 || timeout === Infinity) return child;
await new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const cleanup = () => { const cleanup = () => {
clearTimeout(spawnTimeoutTimer); clearTimeout(spawnTimeoutTimer);
this.off('ready', onReady); this.off('ready', onReady);
@@ -147,7 +147,7 @@ class Shard extends EventEmitter {
const onReady = () => { const onReady = () => {
cleanup(); cleanup();
resolve(); resolve(child);
}; };
const onDisconnect = () => { const onDisconnect = () => {
@@ -170,7 +170,6 @@ class Shard extends EventEmitter {
this.once('disconnect', onDisconnect); this.once('disconnect', onDisconnect);
this.once('death', onDeath); this.once('death', onDeath);
}); });
return child;
} }
/** /**

View File

@@ -556,13 +556,9 @@ class Guild extends AnonymousGuild {
* Resolves with a collection mapping templates by their codes. * Resolves with a collection mapping templates by their codes.
* @returns {Promise<Collection<string, GuildTemplate>>} * @returns {Promise<Collection<string, GuildTemplate>>}
*/ */
fetchTemplates() { async fetchTemplates() {
return this.client.api const templates = await this.client.api.guilds(this.id).templates.get();
.guilds(this.id) return templates.reduce((col, data) => col.set(data.code, new GuildTemplate(this.client, data)), new Collection());
.templates.get()
.then(templates =>
templates.reduce((col, data) => col.set(data.code, new GuildTemplate(this.client, data)), new Collection()),
);
} }
/** /**
@@ -580,22 +576,18 @@ class Guild extends AnonymousGuild {
* @param {string} [description] The description for the template * @param {string} [description] The description for the template
* @returns {Promise<GuildTemplate>} * @returns {Promise<GuildTemplate>}
*/ */
createTemplate(name, description) { async createTemplate(name, description) {
return this.client.api const data = await this.client.api.guilds(this.id).templates.post({ data: { name, description } });
.guilds(this.id) return new GuildTemplate(this.client, data);
.templates.post({ data: { name, description } })
.then(data => new GuildTemplate(this.client, data));
} }
/** /**
* Obtains a guild preview for this guild from Discord. * Obtains a guild preview for this guild from Discord.
* @returns {Promise<GuildPreview>} * @returns {Promise<GuildPreview>}
*/ */
fetchPreview() { async fetchPreview() {
return this.client.api const data = await this.client.api.guilds(this.id).preview.get();
.guilds(this.id) return new GuildPreview(this.client, data);
.preview.get()
.then(data => new GuildPreview(this.client, data));
} }
/** /**
@@ -637,15 +629,11 @@ class Guild extends AnonymousGuild {
* .then(webhooks => console.log(`Fetched ${webhooks.size} webhooks`)) * .then(webhooks => console.log(`Fetched ${webhooks.size} webhooks`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchWebhooks() { async fetchWebhooks() {
return this.client.api const apiHooks = await this.client.api.guilds(this.id).webhooks.get();
.guilds(this.id) const hooks = new Collection();
.webhooks.get() for (const hook of apiHooks) hooks.set(hook.id, new Webhook(this.client, hook));
.then(data => { return hooks;
const hooks = new Collection();
for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook));
return hooks;
});
} }
/** /**
@@ -713,21 +701,19 @@ class Guild extends AnonymousGuild {
* .then(audit => console.log(audit.entries.first())) * .then(audit => console.log(audit.entries.first()))
* .catch(console.error); * .catch(console.error);
*/ */
fetchAuditLogs(options = {}) { async fetchAuditLogs(options = {}) {
if (options.before && options.before instanceof GuildAuditLogs.Entry) options.before = options.before.id; if (options.before && options.before instanceof GuildAuditLogs.Entry) options.before = options.before.id;
if (typeof options.type === 'string') options.type = GuildAuditLogs.Actions[options.type]; if (typeof options.type === 'string') options.type = GuildAuditLogs.Actions[options.type];
return this.client.api const data = await this.client.api.guilds(this.id)['audit-logs'].get({
.guilds(this.id) query: {
['audit-logs'].get({ before: options.before,
query: { limit: options.limit,
before: options.before, user_id: this.client.users.resolveId(options.user),
limit: options.limit, action_type: options.type,
user_id: this.client.users.resolveId(options.user), },
action_type: options.type, });
}, return GuildAuditLogs.build(this, data);
})
.then(data => GuildAuditLogs.build(this, data));
} }
/** /**
@@ -781,7 +767,7 @@ class Guild extends AnonymousGuild {
* .then(updated => console.log(`New guild name ${updated}`)) * .then(updated => console.log(`New guild name ${updated}`))
* .catch(console.error); * .catch(console.error);
*/ */
edit(data, reason) { async edit(data, reason) {
const _data = {}; const _data = {};
if (data.name) _data.name = data.name; if (data.name) _data.name = data.name;
if (typeof data.verificationLevel !== 'undefined') { if (typeof data.verificationLevel !== 'undefined') {
@@ -830,10 +816,8 @@ class Guild extends AnonymousGuild {
_data.description = data.description; _data.description = data.description;
} }
if (data.preferredLocale) _data.preferred_locale = data.preferredLocale; if (data.preferredLocale) _data.preferred_locale = data.preferredLocale;
return this.client.api const newData = await this.client.api.guilds(this.id).patch({ data: _data, reason });
.guilds(this.id) return this.client.actions.GuildUpdate.handle(newData).updated;
.patch({ data: _data, reason })
.then(newData => this.client.actions.GuildUpdate.handle(newData).updated);
} }
/** /**
@@ -1158,7 +1142,7 @@ class Guild extends AnonymousGuild {
* .then(guild => console.log(`Updated channel positions for ${guild}`)) * .then(guild => console.log(`Updated channel positions for ${guild}`))
* .catch(console.error); * .catch(console.error);
*/ */
setChannelPositions(channelPositions) { async setChannelPositions(channelPositions) {
const updatedChannels = channelPositions.map(r => ({ const updatedChannels = channelPositions.map(r => ({
id: this.client.channels.resolveId(r.channel), id: this.client.channels.resolveId(r.channel),
position: r.position, position: r.position,
@@ -1166,16 +1150,11 @@ class Guild extends AnonymousGuild {
parent_id: typeof r.parent !== 'undefined' ? this.channels.resolveId(r.parent) : undefined, parent_id: typeof r.parent !== 'undefined' ? this.channels.resolveId(r.parent) : undefined,
})); }));
return this.client.api await this.client.api.guilds(this.id).channels.patch({ data: updatedChannels });
.guilds(this.id) return this.client.actions.GuildChannelsPositionUpdate.handle({
.channels.patch({ data: updatedChannels }) guild_id: this.id,
.then( channels: updatedChannels,
() => }).guild;
this.client.actions.GuildChannelsPositionUpdate.handle({
guild_id: this.id,
channels: updatedChannels,
}).guild,
);
} }
/** /**
@@ -1194,7 +1173,7 @@ class Guild extends AnonymousGuild {
* .then(guild => console.log(`Role positions updated for ${guild}`)) * .then(guild => console.log(`Role positions updated for ${guild}`))
* .catch(console.error); * .catch(console.error);
*/ */
setRolePositions(rolePositions) { async setRolePositions(rolePositions) {
// Make sure rolePositions are prepared for API // Make sure rolePositions are prepared for API
rolePositions = rolePositions.map(o => ({ rolePositions = rolePositions.map(o => ({
id: this.roles.resolveId(o.role), id: this.roles.resolveId(o.role),
@@ -1202,18 +1181,13 @@ class Guild extends AnonymousGuild {
})); }));
// Call the API to update role positions // Call the API to update role positions
return this.client.api await this.client.api.guilds(this.id).roles.patch({
.guilds(this.id) data: rolePositions,
.roles.patch({ });
data: rolePositions, return this.client.actions.GuildRolesPositionUpdate.handle({
}) guild_id: this.id,
.then( roles: rolePositions,
() => }).guild;
this.client.actions.GuildRolesPositionUpdate.handle({
guild_id: this.id,
roles: rolePositions,
}).guild,
);
} }
/** /**
@@ -1222,17 +1196,15 @@ class Guild extends AnonymousGuild {
* @param {string} [reason] Reason for changing the guild's widget settings * @param {string} [reason] Reason for changing the guild's widget settings
* @returns {Promise<Guild>} * @returns {Promise<Guild>}
*/ */
setWidgetSettings(settings, reason) { async setWidgetSettings(settings, reason) {
return this.client.api await this.client.api.guilds(this.id).widget.patch({
.guilds(this.id) data: {
.widget.patch({ enabled: settings.enabled,
data: { channel_id: this.channels.resolveId(settings.channel),
enabled: settings.enabled, },
channel_id: this.channels.resolveId(settings.channel), reason,
}, });
reason, return this;
})
.then(() => this);
} }
/** /**
@@ -1244,13 +1216,10 @@ class Guild extends AnonymousGuild {
* .then(g => console.log(`Left the guild ${g}`)) * .then(g => console.log(`Left the guild ${g}`))
* .catch(console.error); * .catch(console.error);
*/ */
leave() { async leave() {
if (this.ownerId === this.client.user.id) return Promise.reject(new Error('GUILD_OWNED')); if (this.ownerId === this.client.user.id) throw new Error('GUILD_OWNED');
return this.client.api await this.client.api.users('@me').guilds(this.id).delete();
.users('@me') return this.client.actions.GuildDelete.handle({ id: this.id }).guild;
.guilds(this.id)
.delete()
.then(() => this.client.actions.GuildDelete.handle({ id: this.id }).guild);
} }
/** /**
@@ -1262,11 +1231,9 @@ class Guild extends AnonymousGuild {
* .then(g => console.log(`Deleted the guild ${g}`)) * .then(g => console.log(`Deleted the guild ${g}`))
* .catch(console.error); * .catch(console.error);
*/ */
delete() { async delete() {
return this.client.api await this.client.api.guilds(this.id).delete();
.guilds(this.id) return this.client.actions.GuildDelete.handle({ id: this.id }).guild;
.delete()
.then(() => this.client.actions.GuildDelete.handle({ id: this.id }).guild);
} }
/** /**

View File

@@ -198,9 +198,10 @@ class GuildAuditLogs {
* Handles possible promises for entry targets. * Handles possible promises for entry targets.
* @returns {Promise<GuildAuditLogs>} * @returns {Promise<GuildAuditLogs>}
*/ */
static build(...args) { static async build(...args) {
const logs = new GuildAuditLogs(...args); const logs = new GuildAuditLogs(...args);
return Promise.all(logs.entries.map(e => e.target)).then(() => logs); await Promise.all(logs.entries.map(e => e.target));
return logs;
} }
/** /**
@@ -500,19 +501,17 @@ class GuildAuditLogsEntry {
), ),
); );
} else if (targetType === Targets.INVITE) { } else if (targetType === Targets.INVITE) {
this.target = guild.members.fetch(guild.client.user.id).then(me => { this.target = guild.members.fetch(guild.client.user.id).then(async me => {
if (me.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { if (me.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) {
let change = this.changes.find(c => c.key === 'code'); let change = this.changes.find(c => c.key === 'code');
change = change.new ?? change.old; change = change.new ?? change.old;
return guild.invites.fetch().then(invites => { const invites = await guild.invites.fetch();
this.target = invites.find(i => i.code === change) ?? null; this.target = invites.find(i => i.code === change) ?? null;
});
} else { } else {
this.target = this.changes.reduce((o, c) => { this.target = this.changes.reduce((o, c) => {
o[c.key] = c.new ?? c.old; o[c.key] = c.new ?? c.old;
return o; return o;
}, {}); }, {});
return this.target;
} }
}); });
} else if (targetType === Targets.MESSAGE) { } else if (targetType === Targets.MESSAGE) {

View File

@@ -296,18 +296,17 @@ class GuildChannel extends Channel {
if (data.parent) data.parent = this.client.channels.resolveId(data.parent); if (data.parent) data.parent = this.client.channels.resolveId(data.parent);
if (typeof data.position !== 'undefined') { if (typeof data.position !== 'undefined') {
await Util.setPosition( const updatedChannels = await Util.setPosition(
this, this,
data.position, data.position,
false, false,
this.guild._sortedChannels(this), this.guild._sortedChannels(this),
this.client.api.guilds(this.guild.id).channels, this.client.api.guilds(this.guild.id).channels,
reason, reason,
).then(updatedChannels => { );
this.client.actions.GuildChannelsPositionUpdate.handle({ this.client.actions.GuildChannelsPositionUpdate.handle({
guild_id: this.guild.id, guild_id: this.guild.id,
channels: updatedChannels, channels: updatedChannels,
});
}); });
} }
@@ -389,8 +388,7 @@ class GuildChannel extends Channel {
setParent(channel, { lockPermissions = true, reason } = {}) { setParent(channel, { lockPermissions = true, reason } = {}) {
return this.edit( return this.edit(
{ {
// eslint-disable-next-line no-prototype-builtins parentId: channel?.id ?? channel ?? null,
parent: channel ?? null,
lockPermissions, lockPermissions,
}, },
reason, reason,
@@ -430,21 +428,20 @@ class GuildChannel extends Channel {
* .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`)) * .then(newChannel => console.log(`Channel's new position is ${newChannel.position}`))
* .catch(console.error); * .catch(console.error);
*/ */
setPosition(position, { relative, reason } = {}) { async setPosition(position, { relative, reason } = {}) {
return Util.setPosition( const updatedChannels = await Util.setPosition(
this, this,
position, position,
relative, relative,
this.guild._sortedChannels(this), this.guild._sortedChannels(this),
this.client.api.guilds(this.guild.id).channels, this.client.api.guilds(this.guild.id).channels,
reason, reason,
).then(updatedChannels => { );
this.client.actions.GuildChannelsPositionUpdate.handle({ this.client.actions.GuildChannelsPositionUpdate.handle({
guild_id: this.guild.id, guild_id: this.guild.id,
channels: updatedChannels, channels: updatedChannels,
});
return this;
}); });
return this;
} }
/** /**
@@ -600,11 +597,9 @@ class GuildChannel extends Channel {
* .then(console.log) * .then(console.log)
* .catch(console.error); * .catch(console.error);
*/ */
delete(reason) { async delete(reason) {
return this.client.api await this.client.api.channels(this.id).delete({ reason });
.channels(this.id) return this;
.delete({ reason })
.then(() => this);
} }
} }

View File

@@ -107,9 +107,9 @@ class GuildEmoji extends BaseGuildEmoji {
* .then(e => console.log(`Edited emoji ${e}`)) * .then(e => console.log(`Edited emoji ${e}`))
* .catch(console.error); * .catch(console.error);
*/ */
edit(data, reason) { async edit(data, reason) {
const roles = data.roles?.map(r => r.id ?? r); const roles = data.roles?.map(r => r.id ?? r);
return this.client.api const newData = await this.client.api
.guilds(this.guild.id) .guilds(this.guild.id)
.emojis(this.id) .emojis(this.id)
.patch({ .patch({
@@ -118,12 +118,10 @@ class GuildEmoji extends BaseGuildEmoji {
roles, roles,
}, },
reason, reason,
})
.then(newData => {
const clone = this._clone();
clone._patch(newData);
return clone;
}); });
const clone = this._clone();
clone._patch(newData);
return clone;
} }
/** /**
@@ -141,12 +139,9 @@ class GuildEmoji extends BaseGuildEmoji {
* @param {string} [reason] Reason for deleting the emoji * @param {string} [reason] Reason for deleting the emoji
* @returns {Promise<GuildEmoji>} * @returns {Promise<GuildEmoji>}
*/ */
delete(reason) { async delete(reason) {
return this.client.api await this.client.api.guilds(this.guild.id).emojis(this.id).delete({ reason });
.guilds(this.guild.id) return this;
.emojis(this.id)
.delete({ reason })
.then(() => this);
} }
/** /**

View File

@@ -140,14 +140,10 @@ class GuildPreview extends Base {
* Fetches this guild. * Fetches this guild.
* @returns {Promise<GuildPreview>} * @returns {Promise<GuildPreview>}
*/ */
fetch() { async fetch() {
return this.client.api const data = await this.client.api.guilds(this.id).preview.get();
.guilds(this.id) this._patch(data);
.preview.get() return this;
.then(data => {
this._patch(data);
return this;
});
} }
/** /**

View File

@@ -109,11 +109,10 @@ class GuildTemplate extends Base {
icon: await DataResolver.resolveImage(icon), icon: await DataResolver.resolveImage(icon),
}, },
}); });
// eslint-disable-next-line consistent-return
return new Promise(resolve => {
const createdGuild = client.guilds.cache.get(data.id);
if (createdGuild) return resolve(createdGuild);
if (client.guilds.cache.has(data.id)) return client.guilds.cache.get(data.id);
return new Promise(resolve => {
const resolveGuild = guild => { const resolveGuild = guild => {
client.off(Events.GUILD_CREATE, handleGuild); client.off(Events.GUILD_CREATE, handleGuild);
client.decrementMaxListeners(); client.decrementMaxListeners();
@@ -146,36 +145,27 @@ class GuildTemplate extends Base {
* @param {EditGuildTemplateOptions} [options] Options for editing the template * @param {EditGuildTemplateOptions} [options] Options for editing the template
* @returns {Promise<GuildTemplate>} * @returns {Promise<GuildTemplate>}
*/ */
edit({ name, description } = {}) { async edit({ name, description } = {}) {
return this.client.api const data = await this.client.api.guilds(this.guildId).templates(this.code).patch({ data: { name, description } });
.guilds(this.guildId) return this._patch(data);
.templates(this.code)
.patch({ data: { name, description } })
.then(data => this._patch(data));
} }
/** /**
* Deletes this template. * Deletes this template.
* @returns {Promise<GuildTemplate>} * @returns {Promise<GuildTemplate>}
*/ */
delete() { async delete() {
return this.client.api await this.client.api.guilds(this.guildId).templates(this.code).delete();
.guilds(this.guildId) return this;
.templates(this.code)
.delete()
.then(() => this);
} }
/** /**
* Syncs this template to the current state of the guild. * Syncs this template to the current state of the guild.
* @returns {Promise<GuildTemplate>} * @returns {Promise<GuildTemplate>}
*/ */
sync() { async sync() {
return this.client.api const data = await this.client.api.guilds(this.guildId).templates(this.code).put();
.guilds(this.guildId) return this._patch(data);
.templates(this.code)
.put()
.then(data => this._patch(data));
} }
/** /**

View File

@@ -126,12 +126,9 @@ class Integration extends Base {
* @returns {Promise<Integration>} * @returns {Promise<Integration>}
* @param {string} [reason] Reason for deleting this integration * @param {string} [reason] Reason for deleting this integration
*/ */
delete(reason) { async delete(reason) {
return this.client.api await this.client.api.guilds(this.guild.id).integrations(this.id).delete({ reason });
.guilds(this.guild.id) return this;
.integrations(this.id)
.delete({ reason })
.then(() => this);
} }
toJSON() { toJSON() {

View File

@@ -189,8 +189,9 @@ class Invite extends Base {
* @param {string} [reason] Reason for deleting this invite * @param {string} [reason] Reason for deleting this invite
* @returns {Promise<Invite>} * @returns {Promise<Invite>}
*/ */
delete(reason) { async delete(reason) {
return this.client.api.invites[this.code].delete({ reason }).then(() => this); await this.client.api.invites[this.code].delete({ reason });
return this;
} }
/** /**

View File

@@ -637,8 +637,9 @@ class Message extends Base {
* .then(console.log) * .then(console.log)
* .catch(console.error) * .catch(console.error)
*/ */
pin() { async pin() {
return this.channel.messages.pin(this.id).then(() => this); await this.channel.messages.pin(this.id);
return this;
} }
/** /**
@@ -650,8 +651,9 @@ class Message extends Base {
* .then(console.log) * .then(console.log)
* .catch(console.error) * .catch(console.error)
*/ */
unpin() { async unpin() {
return this.channel.messages.unpin(this.id).then(() => this); await this.channel.messages.unpin(this.id);
return this;
} }
/** /**

View File

@@ -310,21 +310,20 @@ class Role extends Base {
* .then(updated => console.log(`Role position: ${updated.position}`)) * .then(updated => console.log(`Role position: ${updated.position}`))
* .catch(console.error); * .catch(console.error);
*/ */
setPosition(position, { relative, reason } = {}) { async setPosition(position, { relative, reason } = {}) {
return Util.setPosition( const updatedRoles = await Util.setPosition(
this, this,
position, position,
relative, relative,
this.guild._sortedRoles(), this.guild._sortedRoles(),
this.client.api.guilds(this.guild.id).roles, this.client.api.guilds(this.guild.id).roles,
reason, reason,
).then(updatedRoles => { );
this.client.actions.GuildRolesPositionUpdate.handle({ this.client.actions.GuildRolesPositionUpdate.handle({
guild_id: this.guild.id, guild_id: this.guild.id,
roles: updatedRoles, roles: updatedRoles,
});
return this;
}); });
return this;
} }
/** /**
@@ -337,11 +336,10 @@ class Role extends Base {
* .then(deleted => console.log(`Deleted role ${deleted.name}`)) * .then(deleted => console.log(`Deleted role ${deleted.name}`))
* .catch(console.error); * .catch(console.error);
*/ */
delete(reason) { async delete(reason) {
return this.client.api.guilds[this.guild.id].roles[this.id].delete({ reason }).then(() => { await this.client.api.guilds[this.guild.id].roles[this.id].delete({ reason });
this.client.actions.GuildRoleDelete.handle({ guild_id: this.guild.id, role_id: this.id }); this.client.actions.GuildRoleDelete.handle({ guild_id: this.guild.id, role_id: this.id });
return this; return this;
});
} }
/** /**

View File

@@ -143,12 +143,11 @@ class TextChannel extends GuildChannel {
* .then(hooks => console.log(`This channel has ${hooks.size} hooks`)) * .then(hooks => console.log(`This channel has ${hooks.size} hooks`))
* .catch(console.error); * .catch(console.error);
*/ */
fetchWebhooks() { async fetchWebhooks() {
return this.client.api.channels[this.id].webhooks.get().then(data => { const data = await this.client.api.channels[this.id].webhooks.get();
const hooks = new Collection(); const hooks = new Collection();
for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook)); for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook));
return hooks; return hooks;
});
} }
/** /**
@@ -176,15 +175,14 @@ class TextChannel extends GuildChannel {
if (typeof avatar === 'string' && !avatar.startsWith('data:')) { if (typeof avatar === 'string' && !avatar.startsWith('data:')) {
avatar = await DataResolver.resolveImage(avatar); avatar = await DataResolver.resolveImage(avatar);
} }
return this.client.api.channels[this.id].webhooks const data = await this.client.api.channels[this.id].webhooks.post({
.post({ data: {
data: { name,
name, avatar,
avatar, },
}, reason,
reason, });
}) return new Webhook(this.client, data);
.then(data => new Webhook(this.client, data));
} }
// These are here only for documentation purposes - they are implemented by TextBasedChannel // These are here only for documentation purposes - they are implemented by TextBasedChannel

View File

@@ -212,16 +212,18 @@ class ThreadChannel extends Channel {
* Makes the client user join the thread. * Makes the client user join the thread.
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
*/ */
join() { async join() {
return this.members.add('@me').then(() => this); await this.members.add('@me');
return this;
} }
/** /**
* Makes the client user leave the thread. * Makes the client user leave the thread.
* @returns {Promise<ThreadChannel>} * @returns {Promise<ThreadChannel>}
*/ */
leave() { async leave() {
return this.members.remove('@me').then(() => this); await this.members.remove('@me');
return this;
} }
/** /**
@@ -444,11 +446,9 @@ class ThreadChannel extends Channel {
* .then(deletedThread => console.log(deletedThread)) * .then(deletedThread => console.log(deletedThread))
* .catch(console.error); * .catch(console.error);
*/ */
delete(reason) { async delete(reason) {
return this.client.api await this.client.api.channels(this.id).delete({ reason });
.channels(this.id) return this;
.delete({ reason })
.then(() => this);
} }
// These are here only for documentation purposes - they are implemented by TextBasedChannel // These are here only for documentation purposes - they are implemented by TextBasedChannel

View File

@@ -87,8 +87,9 @@ class ThreadMember extends Base {
* @param {string} [reason] Reason for removing the member * @param {string} [reason] Reason for removing the member
* @returns {ThreadMember} * @returns {ThreadMember}
*/ */
remove(reason) { async remove(reason) {
return this.thread.members.remove(this.id, reason).then(() => this); await this.thread.members.remove(this.id, reason);
return this;
} }
} }

View File

@@ -166,15 +166,13 @@ class Webhook {
} }
const { data, files } = await messagePayload.resolveFiles(); const { data, files } = await messagePayload.resolveFiles();
return this.client.api const d = await this.client.api.webhooks(this.id, this.token).post({
.webhooks(this.id, this.token) data,
.post({ files,
data, query: { thread_id: messagePayload.options.threadId, wait: true },
files, auth: false,
query: { thread_id: messagePayload.options.threadId, wait: true }, });
auth: false, return this.client.channels?.cache.get(d.channel_id)?.messages._add(d, false) ?? d;
})
.then(d => this.client.channels?.cache.get(d.channel_id)?.messages._add(d, false) ?? d);
} }
/** /**
@@ -195,17 +193,15 @@ class Webhook {
* }).catch(console.error); * }).catch(console.error);
* @see {@link https://api.slack.com/messaging/webhooks} * @see {@link https://api.slack.com/messaging/webhooks}
*/ */
sendSlackMessage(body) { async sendSlackMessage(body) {
if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE'); if (!this.token) throw new Error('WEBHOOK_TOKEN_UNAVAILABLE');
return this.client.api const data = await this.client.api.webhooks(this.id, this.token).slack.post({
.webhooks(this.id, this.token) query: { wait: true },
.slack.post({ auth: false,
query: { wait: true }, data: body,
auth: false, });
data: body, return data.toString() === 'ok';
})
.then(data => data.toString() === 'ok');
} }
/** /**

View File

@@ -92,17 +92,13 @@ class Application extends Base {
* Gets the application's rich presence assets. * Gets the application's rich presence assets.
* @returns {Promise<Array<ApplicationAsset>>} * @returns {Promise<Array<ApplicationAsset>>}
*/ */
fetchAssets() { async fetchAssets() {
return this.client.api.oauth2 const assets = await this.client.api.oauth2.applications(this.id).assets.get();
.applications(this.id) return assets.map(a => ({
.assets.get() id: a.id,
.then(assets => name: a.name,
assets.map(a => ({ type: AssetTypes[a.type - 1],
id: a.id, }));
name: a.name,
type: AssetTypes[a.type - 1],
})),
);
} }
/** /**

View File

@@ -155,7 +155,8 @@ class TextBasedChannel {
const GuildMember = require('../GuildMember'); const GuildMember = require('../GuildMember');
if (this instanceof User || this instanceof GuildMember) { if (this instanceof User || this instanceof GuildMember) {
return this.createDM().then(dm => dm.send(options)); const dm = await this.createDM();
return dm.send(options);
} }
let messagePayload; let messagePayload;

View File

@@ -267,19 +267,19 @@ class Util extends null {
* @param {FetchRecommendedShardsOptions} [options] Options for fetching the recommended shard count * @param {FetchRecommendedShardsOptions} [options] Options for fetching the recommended shard count
* @returns {Promise<number>} The recommended number of shards * @returns {Promise<number>} The recommended number of shards
*/ */
static fetchRecommendedShards(token, { guildsPerShard = 1000, multipleOf = 1 } = {}) { static async fetchRecommendedShards(token, { guildsPerShard = 1000, multipleOf = 1 } = {}) {
if (!token) throw new DiscordError('TOKEN_MISSING'); if (!token) throw new DiscordError('TOKEN_MISSING');
const defaults = Options.createDefault(); const defaults = Options.createDefault();
return fetch(`${defaults.http.api}/v${defaults.http.version}${Endpoints.botGateway}`, { const response = await fetch(`${defaults.http.api}/v${defaults.http.version}${Endpoints.botGateway}`, {
method: 'GET', method: 'GET',
headers: { Authorization: `Bot ${token.replace(/^Bot\s*/i, '')}` }, headers: { Authorization: `Bot ${token.replace(/^Bot\s*/i, '')}` },
}) });
.then(res => { if (!response.ok) {
if (res.ok) return res.json(); if (response.status === 401) throw new DiscordError('TOKEN_INVALID');
if (res.status === 401) throw new DiscordError('TOKEN_INVALID'); throw response;
throw res; }
}) const { shards } = await response.json();
.then(data => Math.ceil((data.shards * (1000 / guildsPerShard)) / multipleOf) * multipleOf); return Math.ceil((shards * (1000 / guildsPerShard)) / multipleOf) * multipleOf;
} }
/** /**
@@ -500,11 +500,12 @@ class Util extends null {
* @returns {Promise<Channel[]|Role[]>} Updated item list, with `id` and `position` properties * @returns {Promise<Channel[]|Role[]>} Updated item list, with `id` and `position` properties
* @private * @private
*/ */
static setPosition(item, position, relative, sorted, route, reason) { static async setPosition(item, position, relative, sorted, route, reason) {
let updatedItems = [...sorted.values()]; let updatedItems = [...sorted.values()];
Util.moveElementInArray(updatedItems, item, position, relative); Util.moveElementInArray(updatedItems, item, position, relative);
updatedItems = updatedItems.map((r, i) => ({ id: r.id, position: i })); updatedItems = updatedItems.map((r, i) => ({ id: r.id, position: i }));
return route.patch({ data: updatedItems, reason }).then(() => updatedItems); await route.patch({ data: updatedItems, reason });
return updatedItems;
} }
/** /**