mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 16:43:31 +01:00
feat(*): enforce strings (#4880)
BREAKING CHANGE: Removes all Resolvables for only string inputs Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
This commit is contained in:
@@ -37,6 +37,13 @@ const Messages = {
|
||||
COLOR_RANGE: 'Color must be within the range 0 - 16777215 (0xFFFFFF).',
|
||||
COLOR_CONVERT: 'Unable to convert color to a number.',
|
||||
|
||||
EMBED_TITLE: 'MessageEmbed title must be a string.',
|
||||
EMBED_FIELD_NAME: 'MessageEmbed field names must be non-empty strings.',
|
||||
EMBED_FIELD_VALUE: 'MessageEmbed field values must be non-empty strings.',
|
||||
EMBED_FOOTER_TEXT: 'MessageEmbed footer text must be a string.',
|
||||
EMBED_DESCRIPTION: 'MessageEmbed description must be a string.',
|
||||
EMBED_AUTHOR_NAME: 'MessageEmbed author name must be a string.',
|
||||
|
||||
FILE_NOT_FOUND: file => `File could not be found: ${file}`,
|
||||
|
||||
USER_NO_DMCHANNEL: 'No DM Channel exists!',
|
||||
@@ -72,6 +79,7 @@ const Messages = {
|
||||
|
||||
MESSAGE_BULK_DELETE_TYPE: 'The messages must be an Array, Collection, or number.',
|
||||
MESSAGE_NONCE_TYPE: 'Message nonce must be an integer or a string.',
|
||||
MESSAGE_CONTENT_TYPE: 'Message content must be a non-empty string.',
|
||||
|
||||
TYPING_COUNT: 'Count must be at least 1',
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ module.exports = {
|
||||
escapeMarkdown: Util.escapeMarkdown,
|
||||
fetchRecommendedShards: Util.fetchRecommendedShards,
|
||||
resolveColor: Util.resolveColor,
|
||||
resolveString: Util.resolveString,
|
||||
verifyString: Util.verifyString,
|
||||
splitMessage: Util.splitMessage,
|
||||
|
||||
// Structures
|
||||
|
||||
@@ -92,7 +92,7 @@ class APIMessage {
|
||||
if (this.options.content === null) {
|
||||
content = '';
|
||||
} else if (typeof this.options.content !== 'undefined') {
|
||||
content = Util.resolveString(this.options.content);
|
||||
content = Util.verifyString(this.options.content, RangeError, 'MESSAGE_CONTENT_TYPE', false);
|
||||
}
|
||||
|
||||
if (typeof content !== 'string') return content;
|
||||
@@ -322,7 +322,7 @@ class APIMessage {
|
||||
/**
|
||||
* Transforms the user-level arguments into a final options object. Passing a transformed options object alone into
|
||||
* this method will keep it the same, allowing for the reuse of the final options object.
|
||||
* @param {StringResolvable} [content] Content to send
|
||||
* @param {string} [content] Content to send
|
||||
* @param {MessageOptions|WebhookMessageOptions|MessageAdditions} [options={}] Options to use
|
||||
* @param {MessageOptions|WebhookMessageOptions} [extra={}] Extra options to add onto transformed options
|
||||
* @param {boolean} [isWebhook=false] Whether or not to use WebhookMessageOptions as the result
|
||||
@@ -358,7 +358,7 @@ class APIMessage {
|
||||
/**
|
||||
* Creates an `APIMessage` from user-level arguments.
|
||||
* @param {MessageTarget} target Target to send to
|
||||
* @param {StringResolvable} [content] Content to send
|
||||
* @param {string} [content] Content to send
|
||||
* @param {MessageOptions|WebhookMessageOptions|MessageAdditions} [options={}] Options to use
|
||||
* @param {MessageOptions|WebhookMessageOptions} [extra={}] - Extra options to add onto transformed options
|
||||
* @returns {MessageOptions|WebhookMessageOptions}
|
||||
|
||||
@@ -486,7 +486,7 @@ class Message extends Base {
|
||||
|
||||
/**
|
||||
* Edits the content of the message.
|
||||
* @param {StringResolvable|APIMessage} [content] The new content for the message
|
||||
* @param {string|APIMessage} [content] The new content for the message
|
||||
* @param {MessageEditOptions|MessageEmbed} [options] The options to provide
|
||||
* @returns {Promise<Message>}
|
||||
* @example
|
||||
|
||||
@@ -265,8 +265,8 @@ class MessageEmbed {
|
||||
|
||||
/**
|
||||
* Adds a field to the embed (max 25).
|
||||
* @param {StringResolvable} name The name of this field
|
||||
* @param {StringResolvable} value The value of this field
|
||||
* @param {string} name The name of this field
|
||||
* @param {string} value The value of this field
|
||||
* @param {boolean} [inline=false] If this field will be displayed inline
|
||||
* @returns {MessageEmbed}
|
||||
*/
|
||||
@@ -309,13 +309,13 @@ class MessageEmbed {
|
||||
|
||||
/**
|
||||
* Sets the author of this embed.
|
||||
* @param {StringResolvable} name The name of the author
|
||||
* @param {string} name The name of the author
|
||||
* @param {string} [iconURL] The icon URL of the author
|
||||
* @param {string} [url] The URL of the author
|
||||
* @returns {MessageEmbed}
|
||||
*/
|
||||
setAuthor(name, iconURL, url) {
|
||||
this.author = { name: Util.resolveString(name), iconURL, url };
|
||||
this.author = { name: Util.verifyString(name, RangeError, 'EMBED_AUTHOR_NAME'), iconURL, url };
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -331,24 +331,22 @@ class MessageEmbed {
|
||||
|
||||
/**
|
||||
* Sets the description of this embed.
|
||||
* @param {StringResolvable} description The description
|
||||
* @param {string} description The description
|
||||
* @returns {MessageEmbed}
|
||||
*/
|
||||
setDescription(description) {
|
||||
description = Util.resolveString(description);
|
||||
this.description = description;
|
||||
this.description = Util.verifyString(description, RangeError, 'EMBED_DESCRIPTION');
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the footer of this embed.
|
||||
* @param {StringResolvable} text The text of the footer
|
||||
* @param {string} text The text of the footer
|
||||
* @param {string} [iconURL] The icon URL of the footer
|
||||
* @returns {MessageEmbed}
|
||||
*/
|
||||
setFooter(text, iconURL) {
|
||||
text = Util.resolveString(text);
|
||||
this.footer = { text, iconURL };
|
||||
this.footer = { text: Util.verifyString(text, RangeError, 'EMBED_FOOTER_TEXT'), iconURL };
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -385,12 +383,11 @@ class MessageEmbed {
|
||||
|
||||
/**
|
||||
* Sets the title of this embed.
|
||||
* @param {StringResolvable} title The title
|
||||
* @param {string} title The title
|
||||
* @returns {MessageEmbed}
|
||||
*/
|
||||
setTitle(title) {
|
||||
title = Util.resolveString(title);
|
||||
this.title = title;
|
||||
this.title = Util.verifyString(title, RangeError, 'EMBED_TITLE');
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -437,21 +434,23 @@ class MessageEmbed {
|
||||
|
||||
/**
|
||||
* Normalizes field input and resolves strings.
|
||||
* @param {StringResolvable} name The name of the field
|
||||
* @param {StringResolvable} value The value of the field
|
||||
* @param {string} name The name of the field
|
||||
* @param {string} value The value of the field
|
||||
* @param {boolean} [inline=false] Set the field to display inline
|
||||
* @returns {EmbedField}
|
||||
*/
|
||||
static normalizeField(name, value, inline = false) {
|
||||
name = Util.resolveString(name);
|
||||
value = Util.resolveString(value);
|
||||
return { name, value, inline };
|
||||
return {
|
||||
name: Util.verifyString(name, RangeError, 'EMBED_FIELD_NAME', false),
|
||||
value: Util.verifyString(value, RangeError, 'EMBED_FIELD_VALUE', false),
|
||||
inline,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbedFieldData
|
||||
* @property {StringResolvable} name The name of this field
|
||||
* @property {StringResolvable} value The value of this field
|
||||
* @property {string} name The name of this field
|
||||
* @property {string} value The value of this field
|
||||
* @property {boolean} [inline] If this field will be displayed inline
|
||||
*/
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ class Webhook {
|
||||
|
||||
/**
|
||||
* Sends a message with this webhook.
|
||||
* @param {StringResolvable|APIMessage} [content=''] The content to send
|
||||
* @param {string|APIMessage} [content=''] The content to send
|
||||
* @param {WebhookMessageOptions|MessageAdditions} [options={}] The options to provide
|
||||
* @returns {Promise<Message|Object>}
|
||||
* @example
|
||||
|
||||
@@ -114,7 +114,7 @@ class TextBasedChannel {
|
||||
|
||||
/**
|
||||
* Sends a message to this channel.
|
||||
* @param {StringResolvable|APIMessage} [content=''] The content to send
|
||||
* @param {string|APIMessage} [content=''] The content to send
|
||||
* @param {MessageOptions|MessageAdditions} [options={}] The options to provide
|
||||
* @returns {Promise<Message|Message[]>}
|
||||
* @example
|
||||
|
||||
@@ -57,12 +57,12 @@ class Util {
|
||||
|
||||
/**
|
||||
* Splits a string into multiple chunks at a designated character that do not exceed a specific length.
|
||||
* @param {StringResolvable} text Content to split
|
||||
* @param {string} text Content to split
|
||||
* @param {SplitOptions} [options] Options controlling the behavior of the split
|
||||
* @returns {string[]}
|
||||
*/
|
||||
static splitMessage(text, { maxLength = 2000, char = '\n', prepend = '', append = '' } = {}) {
|
||||
text = Util.resolveString(text);
|
||||
text = Util.verifyString(text, RangeError, 'MESSAGE_CONTENT_TYPE', false);
|
||||
if (text.length <= maxLength) return [text];
|
||||
const splitText = text.split(char);
|
||||
if (splitText.some(chunk => chunk.length > maxLength)) throw new RangeError('SPLIT_MAX_LEN');
|
||||
@@ -347,22 +347,22 @@ class Util {
|
||||
}
|
||||
|
||||
/**
|
||||
* Data that can be resolved to give a string. This can be:
|
||||
* * A string
|
||||
* * An array (joined with a new line delimiter to give a string)
|
||||
* * Any value
|
||||
* @typedef {string|Array|*} StringResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves a StringResolvable to a string.
|
||||
* @param {StringResolvable} data The string resolvable to resolve
|
||||
* Verifies the provided data is a string, otherwise throws provided error.
|
||||
* @param {string} data The string resolvable to resolve
|
||||
* @param {Function} [error] The Error constructor to instantiate. Defaults to Error
|
||||
* @param {string} [errorMessage] The error message to throw with. Defaults to "Expected string, got <data> instead."
|
||||
* @param {boolean} [allowEmpty=true] Whether an empty string should be allowed
|
||||
* @returns {string}
|
||||
*/
|
||||
static resolveString(data) {
|
||||
if (typeof data === 'string') return data;
|
||||
if (Array.isArray(data)) return data.join('\n');
|
||||
return String(data);
|
||||
static verifyString(
|
||||
data,
|
||||
error = Error,
|
||||
errorMessage = `Expected a string, got ${data} instead.`,
|
||||
allowEmpty = true,
|
||||
) {
|
||||
if (typeof data !== 'string') throw new error(errorMessage);
|
||||
if (!allowEmpty && data.length === 0) throw new error(errorMessage);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user