Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(MessageEmbed): Skip validation of field when inside a message #3894

Merged
merged 10 commits into from
Mar 8, 2020
4 changes: 2 additions & 2 deletions src/structures/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class Message extends Base {
* A list of embeds in the message - e.g. YouTube Player
* @type {MessageEmbed[]}
*/
this.embeds = (data.embeds || []).map(e => new Embed(e));
this.embeds = (data.embeds || []).map(e => new Embed(e, true));

/**
* A collection of attachments in the message - e.g. Pictures - mapped by their ID
Expand Down Expand Up @@ -225,7 +225,7 @@ class Message extends Base {
if ('content' in data) this.content = data.content;
if ('pinned' in data) this.pinned = data.pinned;
if ('tts' in data) this.tts = data.tts;
if ('embeds' in data) this.embeds = data.embeds.map(e => new Embed(e));
if ('embeds' in data) this.embeds = data.embeds.map(e => new Embed(e, true));
else this.embeds = this.embeds.slice();

if ('attachments' in data) {
Expand Down
46 changes: 36 additions & 10 deletions src/structures/MessageEmbed.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ const Util = require('../util/Util');
* Represents an embed in a message (image/video preview, rich embed, etc.)
*/
class MessageEmbed {
constructor(data = {}) {
this.setup(data);
/**
* @param {Object} [data={}] The data to build the embed from
* @param {boolean} [skipValidation=false] A flag to skip field validations
MattIPv4 marked this conversation as resolved.
Show resolved Hide resolved
*/
constructor(data = {}, skipValidation = false) {
this.setup(data, skipValidation);
}

setup(data) {
/**
* @param {Object} data The data to build the embed from
* @param {boolean} skipValidation A flag to skip field validations
*/
setup(data, skipValidation) {
MattIPv4 marked this conversation as resolved.
Show resolved Hide resolved
/**
* The type of this embed, either:
* * `rich` - a rich embed
Expand Down Expand Up @@ -65,7 +73,7 @@ class MessageEmbed {
* The fields of this embed
* @type {EmbedField[]}
*/
this.fields = data.fields ? this.constructor.normalizeFields(data.fields) : [];
this.fields = data.fields ? this.constructor._normalizeFields(this.skipValidation, data.fields) : [];
MattIPv4 marked this conversation as resolved.
Show resolved Hide resolved

/**
* @typedef {Object} MessageEmbedThumbnail
Expand Down Expand Up @@ -193,6 +201,12 @@ class MessageEmbed {
* @type {Array<FileOptions|string|MessageAttachment>}
*/
this.files = data.files || [];

/**
* If this embed should skip validation of its data
* @type {boolean}
*/
this.skipValidation = skipValidation;
}

/**
Expand Down Expand Up @@ -246,7 +260,7 @@ class MessageEmbed {
* @returns {MessageEmbed}
*/
addFields(...fields) {
this.fields.push(...this.constructor.normalizeFields(fields));
this.fields.push(...this.constructor._normalizeFields(this.skipValidation, fields));
return this;
}

Expand All @@ -258,7 +272,7 @@ class MessageEmbed {
* @returns {MessageEmbed}
*/
spliceFields(index, deleteCount, ...fields) {
this.fields.splice(index, deleteCount, ...this.constructor.normalizeFields(...fields));
this.fields.splice(index, deleteCount, ...this.constructor._normalizeFields(this.skipValidation, ...fields));
return this;
}

Expand Down Expand Up @@ -406,13 +420,14 @@ class MessageEmbed {
* @param {StringResolvable} name The name of the field
* @param {StringResolvable} value The value of the field
* @param {boolean} [inline=false] Set the field to display inline
* @param {boolean} [skipValidation=false] Skips the validation of the name and value
* @returns {EmbedField}
*/
static normalizeField(name, value, inline = false) {
static normalizeField(name, value, inline = false, skipValidation = false) {
name = Util.resolveString(name);
if (!name) throw new RangeError('EMBED_FIELD_NAME');
if (!skipValidation && !name) throw new RangeError('EMBED_FIELD_NAME');
value = Util.resolveString(value);
if (!value) throw new RangeError('EMBED_FIELD_VALUE');
if (!skipValidation && !value) throw new RangeError('EMBED_FIELD_VALUE');
return { name, value, inline };
}

Expand All @@ -425,20 +440,31 @@ class MessageEmbed {

/**
* Normalizes field input and resolves strings.
* @param {boolean} skipValidation Skips the validation of the name and value in fields
* @param {...EmbedFieldData|EmbedFieldData[]} fields Fields to normalize
* @returns {EmbedField[]}
*/
static normalizeFields(...fields) {
static _normalizeFields(skipValidation, ...fields) {
return fields
.flat(2)
.map(field =>
this.normalizeField(
field && field.name,
field && field.value,
field && typeof field.inline === 'boolean' ? field.inline : false,
skipValidation,
),
);
}

/**
* Normalizes field input and resolves strings.
* @param {...EmbedFieldData|EmbedFieldData[]} fields Fields to normalize
* @returns {EmbedField[]}
*/
static normalizeFields(...fields) {
return this._normalizeFields(false, ...fields);
}
}

module.exports = MessageEmbed;
13 changes: 9 additions & 4 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ declare module 'discord.js' {
}

export class MessageEmbed {
constructor(data?: MessageEmbed | MessageEmbedOptions);
constructor(data?: MessageEmbed | MessageEmbedOptions, skipValidation?: boolean);
public author: MessageEmbedAuthor | null;
public color?: number;
public readonly createdAt: Date | null;
Expand Down Expand Up @@ -1154,10 +1154,15 @@ declare module 'discord.js' {
public toJSON(): object;

public static normalizeField(
name: StringResolvable,
value: StringResolvable,
inline?: boolean,
name: StringResolvable,
value: StringResolvable,
inline?: boolean,
skipValidation?: boolean
): Required<EmbedFieldData>;
public static _normalizeFields(
skipValidation: boolean,
...fields: EmbedFieldData[] | EmbedFieldData[][]
): Required<EmbedFieldData>[];
public static normalizeFields(...fields: EmbedFieldData[] | EmbedFieldData[][]): Required<EmbedFieldData>[];
}

Expand Down