mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 08:33:30 +01:00
Merge branch 'master' into indev-prism
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
const User = require('./User');
|
||||
const OAuth2Application = require('./OAuth2Application');
|
||||
|
||||
/**
|
||||
* Represents the client's OAuth2 Application
|
||||
* @extends {OAuth2Application}
|
||||
*/
|
||||
class ClientOAuth2Application extends OAuth2Application {
|
||||
setup(data) {
|
||||
super.setup(data);
|
||||
|
||||
/**
|
||||
* The app's flags
|
||||
* @type {number}
|
||||
*/
|
||||
this.flags = data.flags;
|
||||
|
||||
/**
|
||||
* The app's owner
|
||||
* @type {User}
|
||||
*/
|
||||
this.owner = new User(this.client, data.owner);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientOAuth2Application;
|
||||
@@ -5,9 +5,7 @@ const Presence = require('./Presence').Presence;
|
||||
const GuildMember = require('./GuildMember');
|
||||
const Constants = require('../util/Constants');
|
||||
const Collection = require('../util/Collection');
|
||||
const cloneObject = require('../util/CloneObject');
|
||||
const arraysEqual = require('../util/ArraysEqual');
|
||||
const moveElementInArray = require('../util/MoveElementInArray');
|
||||
const Util = require('../util/Util');
|
||||
|
||||
/**
|
||||
* Represents a guild (or a server) on Discord.
|
||||
@@ -331,6 +329,24 @@ class Guild {
|
||||
return this.client.rest.methods.fetchVoiceRegions(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a user to the guild using OAuth2. Requires the `CREATE_INSTANT_INVITE` permission.
|
||||
* @param {UserResolvable} user User to add to the guild
|
||||
* @param {Object} options Options for the addition
|
||||
* @param {string} options.accessToken An OAuth2 access token for the user with the `guilds.join` scope granted to the
|
||||
* bot's application
|
||||
* @param {string} [options.nick] Nickname to give the member (requires `MANAGE_NICKNAMES`)
|
||||
* @param {Collection<Snowflake, Role>|Role[]|Snowflake[]} [options.roles] Roles to add to the member
|
||||
* (requires `MANAGE_ROLES`)
|
||||
* @param {boolean} [options.mute] Whether the member should be muted (requires `MUTE_MEMBERS`)
|
||||
* @param {boolean} [options.deaf] Whether the member should be deafened (requires `DEAFEN_MEMBERS`)
|
||||
* @returns {Promise<GuildMember>}
|
||||
*/
|
||||
addMember(user, options) {
|
||||
if (this.members.has(user.id)) return Promise.resolve(this.members.get(user.id));
|
||||
return this.client.rest.methods.putGuildMember(this, user, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a single guild member from a user.
|
||||
* @param {UserResolvable} user The user to fetch the member for
|
||||
@@ -552,8 +568,10 @@ class Guild {
|
||||
* If the GuildMember cannot be resolved, the User will instead be attempted to be resolved. If that also cannot
|
||||
* be resolved, the user ID will be the result.
|
||||
* @example
|
||||
* // ban a user
|
||||
* guild.ban('123123123123');
|
||||
* // ban a user by ID (or with a user/guild member object)
|
||||
* guild.ban('some user ID')
|
||||
* .then(user => console.log(`Banned ${user.username || user.id || user} from ${guild.name}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
ban(user, deleteDays = 0) {
|
||||
return this.client.rest.methods.banGuildMember(this, user, deleteDays);
|
||||
@@ -564,10 +582,10 @@ class Guild {
|
||||
* @param {UserResolvable} user The user to unban
|
||||
* @returns {Promise<User>}
|
||||
* @example
|
||||
* // unban a user
|
||||
* guild.unban('123123123123')
|
||||
* // unban a user by ID (or with a user/guild member object)
|
||||
* guild.unban('some user ID')
|
||||
* .then(user => console.log(`Unbanned ${user.username} from ${guild.name}`))
|
||||
* .catch(reject);
|
||||
* .catch(console.error);
|
||||
*/
|
||||
unban(user) {
|
||||
return this.client.rest.methods.unbanGuildMember(this, user);
|
||||
@@ -659,7 +677,7 @@ class Guild {
|
||||
let updatedRoles = Object.assign([], this.roles.array()
|
||||
.sort((r1, r2) => r1.position !== r2.position ? r1.position - r2.position : r1.id - r2.id));
|
||||
|
||||
moveElementInArray(updatedRoles, role, position, relative);
|
||||
Util.moveElementInArray(updatedRoles, role, position, relative);
|
||||
|
||||
updatedRoles = updatedRoles.map((r, i) => ({ id: r.id, position: i }));
|
||||
return this.client.rest.methods.setRolePositions(this.id, updatedRoles);
|
||||
@@ -687,9 +705,10 @@ class Guild {
|
||||
if (typeof attachment === 'string' && attachment.startsWith('data:')) {
|
||||
resolve(this.client.rest.methods.createEmoji(this, attachment, name, roles));
|
||||
} else {
|
||||
this.client.resolver.resolveBuffer(attachment).then(data =>
|
||||
resolve(this.client.rest.methods.createEmoji(this, data, name, roles))
|
||||
);
|
||||
this.client.resolver.resolveBuffer(attachment).then(data => {
|
||||
const dataURI = this.client.resolver.resolveBase64(data);
|
||||
resolve(this.client.rest.methods.createEmoji(this, dataURI, name, roles));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -748,7 +767,7 @@ class Guild {
|
||||
this.memberCount === guild.member_count &&
|
||||
this.large === guild.large &&
|
||||
this.icon === guild.icon &&
|
||||
arraysEqual(this.features, guild.features) &&
|
||||
Util.arraysEqual(this.features, guild.features) &&
|
||||
this.ownerID === guild.owner_id &&
|
||||
this.verificationLevel === guild.verification_level &&
|
||||
this.embedEnabled === guild.embed_enabled;
|
||||
@@ -814,12 +833,12 @@ class Guild {
|
||||
}
|
||||
|
||||
_updateMember(member, data) {
|
||||
const oldMember = cloneObject(member);
|
||||
const oldMember = Util.cloneObject(member);
|
||||
|
||||
if (data.roles) member._roles = data.roles;
|
||||
if (typeof data.nick !== 'undefined') member.nickname = data.nick;
|
||||
|
||||
const notSame = member.nickname !== oldMember.nickname || !arraysEqual(member._roles, oldMember._roles);
|
||||
const notSame = member.nickname !== oldMember.nickname || !Util.arraysEqual(member._roles, oldMember._roles);
|
||||
|
||||
if (this.client.ws.status === Constants.Status.READY && notSame) {
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const Attachment = require('./MessageAttachment');
|
||||
const Embed = require('./MessageEmbed');
|
||||
const MessageReaction = require('./MessageReaction');
|
||||
const Util = require('../util/Util');
|
||||
const Collection = require('../util/Collection');
|
||||
const Constants = require('../util/Constants');
|
||||
const escapeMarkdown = require('../util/EscapeMarkdown');
|
||||
let GuildMember;
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ class Message {
|
||||
/**
|
||||
* Represents the author of the message as a guild member. Only available if the message comes from a guild
|
||||
* where the author is still a member.
|
||||
* @type {GuildMember}
|
||||
* @type {?GuildMember}
|
||||
*/
|
||||
this.member = this.guild ? this.guild.member(this.author) || null : null;
|
||||
|
||||
@@ -409,7 +409,7 @@ class Message {
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
editCode(lang, content) {
|
||||
content = escapeMarkdown(this.client.resolver.resolveString(content), true);
|
||||
content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true);
|
||||
return this.edit(`\`\`\`${lang || ''}\n${content}\n\`\`\``);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,51 @@ class OAuth2Application {
|
||||
|
||||
/**
|
||||
* The app's RPC origins
|
||||
* @type {Array<string>}
|
||||
* @type {?string[]}
|
||||
*/
|
||||
this.rpcOrigins = data.rpc_origins;
|
||||
|
||||
/**
|
||||
* The app's redirect URIs
|
||||
* @type {string[]}
|
||||
*/
|
||||
this.redirectURIs = data.redirect_uris;
|
||||
|
||||
/**
|
||||
* If this app's bot requires a code grant when using the oauth2 flow
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.botRequireCodeGrant = data.bot_require_code_grant;
|
||||
|
||||
/**
|
||||
* If this app's bot is public
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.botPublic = data.bot_public;
|
||||
|
||||
/**
|
||||
* If this app can use rpc
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.rpcApplicationState = data.rpc_application_state;
|
||||
|
||||
/**
|
||||
* Object containing basic info about this app's bot
|
||||
* @type {Object}
|
||||
*/
|
||||
this.bot = data.bot;
|
||||
|
||||
/**
|
||||
* Flags for the app
|
||||
* @type {number}
|
||||
*/
|
||||
this.flags = data.flags;
|
||||
|
||||
/**
|
||||
* oauth2 secret for the app
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.secret = data.secret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +112,14 @@ class OAuth2Application {
|
||||
return new Date(this.createdTimestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the app's secret and bot token
|
||||
* @returns {OAuth2Application}
|
||||
*/
|
||||
reset() {
|
||||
return this.client.rest.methods.resetApplication(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* When concatenated with a string, this automatically concatenates the app name rather than the app object.
|
||||
* @returns {string}
|
||||
|
||||
@@ -37,7 +37,7 @@ class PartialGuildChannel {
|
||||
* The type of this guild channel - `text` or `voice`
|
||||
* @type {string}
|
||||
*/
|
||||
this.type = Constants.ChannelTypes.text === data.type ? 'text' : 'voice';
|
||||
this.type = Constants.ChannelTypes.TEXT === data.type ? 'text' : 'voice';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,12 @@ class RichEmbed {
|
||||
* @type {Object}
|
||||
*/
|
||||
this.footer = data.footer;
|
||||
|
||||
/**
|
||||
* File to upload alongside this Embed
|
||||
* @type {string}
|
||||
*/
|
||||
this.file = data.file;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,6 +156,15 @@ class RichEmbed {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function for `<RichEmbed>.addField('\u200B', '\u200B', inline)`.
|
||||
* @param {boolean} [inline=false] Set the field to display inline
|
||||
* @returns {RichEmbed} This embed
|
||||
*/
|
||||
addBlankField(inline = false) {
|
||||
return this.addField('\u200B', '\u200B', inline);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thumbnail of this embed
|
||||
* @param {string} url The URL of the thumbnail
|
||||
@@ -162,7 +177,7 @@ class RichEmbed {
|
||||
|
||||
/**
|
||||
* Set the image of this embed
|
||||
* @param {string} url The URL of the thumbnail
|
||||
* @param {string} url The URL of the image
|
||||
* @returns {RichEmbed} This embed
|
||||
*/
|
||||
setImage(url) {
|
||||
@@ -182,6 +197,18 @@ class RichEmbed {
|
||||
this.footer = { text, icon_url: icon };
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file to upload alongside the embed. This file can be accessed via `attachment://fileName.extension` when
|
||||
* setting an embed image or author/footer icons. Only one file may be attached.
|
||||
* @param {FileOptions|string} file Local path or URL to the file to attach, or valid FileOptions for a file to attach
|
||||
* @returns {RichEmbed} This embed
|
||||
*/
|
||||
attachFile(file) {
|
||||
if (this.file) throw new RangeError('You may not upload more than one file at once.');
|
||||
this.file = file;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RichEmbed;
|
||||
|
||||
@@ -140,11 +140,7 @@ class Role {
|
||||
* console.log(role.serialize());
|
||||
*/
|
||||
serialize() {
|
||||
const serializedPermissions = {};
|
||||
for (const permissionName in Constants.PermissionFlags) {
|
||||
serializedPermissions[permissionName] = this.hasPermission(permissionName);
|
||||
}
|
||||
return serializedPermissions;
|
||||
return this.client.resolver.serializePermissions(this.permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,10 +156,8 @@ class Role {
|
||||
* console.log('This role can\'t ban members');
|
||||
* }
|
||||
*/
|
||||
hasPermission(permission, explicit = false) {
|
||||
permission = this.client.resolver.resolvePermission(permission);
|
||||
if (!explicit && (this.permissions & Constants.PermissionFlags.ADMINISTRATOR) > 0) return true;
|
||||
return (this.permissions & permission) > 0;
|
||||
hasPermission(permission, explicit) {
|
||||
return this.client.resolver.hasPermission(this.permissions, permission, explicit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -78,6 +78,8 @@ class TextBasedChannel {
|
||||
options = {};
|
||||
}
|
||||
|
||||
if (options.embed && options.embed.file) options.file = options.embed.file;
|
||||
|
||||
if (options.file) {
|
||||
if (typeof options.file === 'string') options.file = { attachment: options.file };
|
||||
if (!options.file.name) {
|
||||
@@ -223,6 +225,33 @@ class TextBasedChannel {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} MessageSearchOptions
|
||||
* @property {string} [content] Message content
|
||||
* @property {string} [maxID] Maximum ID for the filter
|
||||
* @property {string} [minID] Minimum ID for the filter
|
||||
* @property {string} [has] One of `link`, `embed`, `file`, `video`, `image`, or `sound`,
|
||||
* or add `-` to negate (e.g. `-file`)
|
||||
* @property {ChannelResolvable} [channel] Channel to limit search to (only for guild search endpoint)
|
||||
* @property {UserResolvable} [author] Author to limit search
|
||||
* @property {string} [authorType] One of `user`, `bot`, `webhook`, or add `-` to negate (e.g. `-webhook`)
|
||||
* @property {string} [sortBy='recent'] `recent` or `relevant`
|
||||
* @property {string} [sortOrder='desc'] `asc` or `desc`
|
||||
* @property {number} [contextSize=2] How many messages to get around the matched message (0 to 2)
|
||||
* @property {number} [limit=25] Maximum number of results to get (1 to 25)
|
||||
* @property {number} [offset=0] Offset the "pages" of results (since you can only see 25 at a time)
|
||||
* @property {UserResolvable} [mentions] Mentioned user filter
|
||||
* @property {boolean} [mentionsEveryone] If everyone is mentioned
|
||||
* @property {string} [linkHostname] Filter links by hostname
|
||||
* @property {string} [embedProvider] The name of an embed provider
|
||||
* @property {string} [embedType] one of `image`, `video`, `url`, `rich`
|
||||
* @property {string} [attachmentFilename] The name of an attachment
|
||||
* @property {string} [attachmentExtension] The extension of an attachment
|
||||
* @property {Date} [before] Date to find messages before
|
||||
* @property {Date} [after] Date to find messages before
|
||||
* @property {Date} [during] Date to find messages during (range of date to date + 24 hours)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Performs a search within the channel.
|
||||
* @param {MessageSearchOptions} [options={}] Options to pass to the search
|
||||
|
||||
Reference in New Issue
Block a user