mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 03:53:29 +01:00
refactor(Util.escapeMarkdown): allow separate escaping and add tests (#3241)
* wip refactor * add escapeMarkdown tests * italics can be done with a single underscore too * more refined * fix test name * unnecessary eslint ignores * use jest * make eslint less annoying in this test file * more testing * fix lib usage * more tests and a small fix
This commit is contained in:
@@ -57,6 +57,7 @@
|
|||||||
"@types/ws": "^6.0.1",
|
"@types/ws": "^6.0.1",
|
||||||
"discord.js-docgen": "discordjs/docgen",
|
"discord.js-docgen": "discordjs/docgen",
|
||||||
"eslint": "^5.13.0",
|
"eslint": "^5.13.0",
|
||||||
|
"jest": "^24.7.1",
|
||||||
"json-filter-loader": "^1.0.0",
|
"json-filter-loader": "^1.0.0",
|
||||||
"terser-webpack-plugin": "^1.2.2",
|
"terser-webpack-plugin": "^1.2.2",
|
||||||
"tslint": "^5.12.1",
|
"tslint": "^5.12.1",
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class APIMessage {
|
|||||||
if (content || mentionPart) {
|
if (content || mentionPart) {
|
||||||
if (isCode) {
|
if (isCode) {
|
||||||
const codeName = typeof this.options.code === 'string' ? this.options.code : '';
|
const codeName = typeof this.options.code === 'string' ? this.options.code : '';
|
||||||
content = `${mentionPart}\`\`\`${codeName}\n${Util.escapeMarkdown(content || '', true)}\n\`\`\``;
|
content = `${mentionPart}\`\`\`${codeName}\n${Util.cleanCodeBlockContent(content || '')}\n\`\`\``;
|
||||||
if (isSplit) {
|
if (isSplit) {
|
||||||
splitOptions.prepend = `${splitOptions.prepend || ''}\`\`\`${codeName}\n`;
|
splitOptions.prepend = `${splitOptions.prepend || ''}\`\`\`${codeName}\n`;
|
||||||
splitOptions.append = `\n\`\`\`${splitOptions.append || ''}`;
|
splitOptions.append = `\n\`\`\`${splitOptions.append || ''}`;
|
||||||
|
|||||||
151
src/util/Util.js
151
src/util/Util.js
@@ -75,14 +75,144 @@ class Util {
|
|||||||
/**
|
/**
|
||||||
* Escapes any Discord-flavour markdown in a string.
|
* Escapes any Discord-flavour markdown in a string.
|
||||||
* @param {string} text Content to escape
|
* @param {string} text Content to escape
|
||||||
* @param {boolean} [onlyCodeBlock=false] Whether to only escape codeblocks (takes priority)
|
* @param {Object} [options={}] What types of markdown to escape
|
||||||
* @param {boolean} [onlyInlineCode=false] Whether to only escape inline code
|
* @param {boolean} [options.codeBlock=true] Whether to escape code blocks or not
|
||||||
|
* @param {boolean} [options.inlineCode=true] Whether to escape inline code or not
|
||||||
|
* @param {boolean} [options.bold=true] Whether to escape bolds or not
|
||||||
|
* @param {boolean} [options.italic=true] Whether to escape italics or not
|
||||||
|
* @param {boolean} [options.underline=true] Whether to escape underlines or not
|
||||||
|
* @param {boolean} [options.strikethrough=true] Whether to escape strikethroughs or not
|
||||||
|
* @param {boolean} [options.spoiler=true] Whether to escape spoilers or not
|
||||||
|
* @param {boolean} [options.codeBlockContent=true] Whether to escape text inside code blocks or not
|
||||||
|
* @param {boolean} [options.inlineCodeContent=true] Whether to escape text inside inline code or not
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
static escapeMarkdown(text, onlyCodeBlock = false, onlyInlineCode = false) {
|
static escapeMarkdown(text, {
|
||||||
if (onlyCodeBlock) return text.replace(/```/g, '`\u200b``');
|
codeBlock = true,
|
||||||
if (onlyInlineCode) return text.replace(/\\(`|\\)/g, '$1').replace(/(`|\\)/g, '\\$1');
|
inlineCode = true,
|
||||||
return text.replace(/\\(\*|_|`|~|\\)/g, '$1').replace(/(\*|_|`|~|\\)/g, '\\$1');
|
bold = true,
|
||||||
|
italic = true,
|
||||||
|
underline = true,
|
||||||
|
strikethrough = true,
|
||||||
|
spoiler = true,
|
||||||
|
codeBlockContent = true,
|
||||||
|
inlineCodeContent = true,
|
||||||
|
} = {}) {
|
||||||
|
if (!codeBlockContent) {
|
||||||
|
return text.split('```').map((subString, index, array) => {
|
||||||
|
if ((index % 2) && index !== array.length - 1) return subString;
|
||||||
|
return Util.escapeMarkdown(subString, {
|
||||||
|
inlineCode,
|
||||||
|
bold,
|
||||||
|
italic,
|
||||||
|
underline,
|
||||||
|
strikethrough,
|
||||||
|
spoiler,
|
||||||
|
inlineCodeContent,
|
||||||
|
});
|
||||||
|
}).join(codeBlock ? '\\`\\`\\`' : '```');
|
||||||
|
}
|
||||||
|
if (!inlineCodeContent) {
|
||||||
|
return text.split(/(?<=^|[^`])`(?=[^`]|$)/g).map((subString, index, array) => {
|
||||||
|
if ((index % 2) && index !== array.length - 1) return subString;
|
||||||
|
return Util.escapeMarkdown(subString, {
|
||||||
|
codeBlock,
|
||||||
|
bold,
|
||||||
|
italic,
|
||||||
|
underline,
|
||||||
|
strikethrough,
|
||||||
|
spoiler,
|
||||||
|
});
|
||||||
|
}).join(inlineCode ? '\\`' : '`');
|
||||||
|
}
|
||||||
|
if (inlineCode) text = Util.escapeInlineCode(text);
|
||||||
|
if (codeBlock) text = Util.escapeCodeBlock(text);
|
||||||
|
if (italic) text = Util.escapeItalic(text);
|
||||||
|
if (bold) text = Util.escapeBold(text);
|
||||||
|
if (underline) text = Util.escapeUnderline(text);
|
||||||
|
if (strikethrough) text = Util.escapeStrikethrough(text);
|
||||||
|
if (spoiler) text = Util.escapeSpoiler(text);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes code block markdown in a string.
|
||||||
|
* @param {string} text Content to escape
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static escapeCodeBlock(text) {
|
||||||
|
return text.replace(/```/g, '\\`\\`\\`');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes inline code markdown in a string.
|
||||||
|
* @param {string} text Content to escape
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static escapeInlineCode(text) {
|
||||||
|
return text.replace(/(?<=^|[^`])`(?=[^`]|$)/g, '\\`');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes italic markdown in a string.
|
||||||
|
* @param {string} text Content to escape
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static escapeItalic(text) {
|
||||||
|
let i = 0;
|
||||||
|
text = text.replace(/(?<=^|[^*])\*([^*]|\*\*|$)/g, (_, match) => {
|
||||||
|
if (match === '**') return ++i % 2 ? `\\*${match}` : `${match}\\*`;
|
||||||
|
return `\\*${match}`;
|
||||||
|
});
|
||||||
|
i = 0;
|
||||||
|
return text.replace(/(?<=^|[^_])_([^_]|__|$)/g, (_, match) => {
|
||||||
|
if (match === '__') return ++i % 2 ? `\\_${match}` : `${match}\\_`;
|
||||||
|
return `\\_${match}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes bold markdown in a string.
|
||||||
|
* @param {string} text Content to escape
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static escapeBold(text) {
|
||||||
|
let i = 0;
|
||||||
|
return text.replace(/\*\*(\*)?/g, (_, match) => {
|
||||||
|
if (match) return ++i % 2 ? `${match}\\*\\*` : `\\*\\*${match}`;
|
||||||
|
return '\\*\\*';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes underline markdown in a string.
|
||||||
|
* @param {string} text Content to escape
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static escapeUnderline(text) {
|
||||||
|
let i = 0;
|
||||||
|
return text.replace(/__(_)?/g, (_, match) => {
|
||||||
|
if (match) return ++i % 2 ? `${match}\\_\\_` : `\\_\\_${match}`;
|
||||||
|
return '\\_\\_';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes strikethrough markdown in a string.
|
||||||
|
* @param {string} text Content to escape
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static escapeStrikethrough(text) {
|
||||||
|
return text.replace(/~~/g, '\\~\\~');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes spoiler markdown in a string.
|
||||||
|
* @param {string} text Content to escape
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static escapeSpoiler(text) {
|
||||||
|
return text.replace(/\|\|/g, '\\|\\|');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -421,6 +551,15 @@ class Util {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The content to put in a codeblock with all codeblock fences replaced by the equivalent backticks.
|
||||||
|
* @param {string} text The string to be converted
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static cleanCodeBlockContent(text) {
|
||||||
|
return text.replace('```', '`\u200b``');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Promise that resolves after a specified duration.
|
* Creates a Promise that resolves after a specified duration.
|
||||||
* @param {number} ms How long to wait before resolving (in milliseconds)
|
* @param {number} ms How long to wait before resolving (in milliseconds)
|
||||||
|
|||||||
184
test/escapeMarkdown.test.js
Normal file
184
test/escapeMarkdown.test.js
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* eslint-disable max-len, no-undef */
|
||||||
|
|
||||||
|
const Util = require('../src/util/Util');
|
||||||
|
const testString = '`_Behold!_`\n||___~~***```js\n`use strict`;\nrequire(\'discord.js\');```***~~___||';
|
||||||
|
|
||||||
|
describe('escapeCodeblock', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeCodeBlock(testString))
|
||||||
|
.toBe('`_Behold!_`\n||___~~***\\`\\`\\`js\n`use strict`;\nrequire(\'discord.js\');\\`\\`\\`***~~___||');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic', () => {
|
||||||
|
expect(Util.escapeCodeBlock('```test```'))
|
||||||
|
.toBe('\\`\\`\\`test\\`\\`\\`');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('escapeInlineCode', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeInlineCode(testString))
|
||||||
|
.toBe('\\`_Behold!_\\`\n||___~~***```js\n\\`use strict\\`;\nrequire(\'discord.js\');```***~~___||');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic', () => {
|
||||||
|
expect(Util.escapeInlineCode('`test`'))
|
||||||
|
.toBe('\\`test\\`');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('escapeBold', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeBold(testString))
|
||||||
|
.toBe('`_Behold!_`\n||___~~*\\*\\*```js\n`use strict`;\nrequire(\'discord.js\');```\\*\\**~~___||');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic', () => {
|
||||||
|
expect(Util.escapeBold('**test**'))
|
||||||
|
.toBe('\\*\\*test\\*\\*');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('escapeItalic', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeItalic(testString))
|
||||||
|
.toBe('`\\_Behold!\\_`\n||\\___~~\\***```js\n`use strict`;\nrequire(\'discord.js\');```**\\*~~__\\_||');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic (_)', () => {
|
||||||
|
expect(Util.escapeItalic('_test_'))
|
||||||
|
.toBe('\\_test\\_');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic (*)', () => {
|
||||||
|
expect(Util.escapeItalic('*test*'))
|
||||||
|
.toBe('\\*test\\*');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('escapeUnderline', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeUnderline(testString))
|
||||||
|
.toBe('`_Behold!_`\n||_\\_\\_~~***```js\n`use strict`;\nrequire(\'discord.js\');```***~~\\_\\__||');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic', () => {
|
||||||
|
expect(Util.escapeUnderline('__test__'))
|
||||||
|
.toBe('\\_\\_test\\_\\_');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('escapeStrikethrough', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeStrikethrough(testString))
|
||||||
|
.toBe('`_Behold!_`\n||___\\~\\~***```js\n`use strict`;\nrequire(\'discord.js\');```***\\~\\~___||');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic', () => {
|
||||||
|
expect(Util.escapeStrikethrough('~~test~~'))
|
||||||
|
.toBe('\\~\\~test\\~\\~');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('escapeSpoiler', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeSpoiler(testString))
|
||||||
|
.toBe('`_Behold!_`\n\\|\\|___~~***```js\n`use strict`;\nrequire(\'discord.js\');```***~~___\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('basic', () => {
|
||||||
|
expect(Util.escapeSpoiler('||test||'))
|
||||||
|
.toBe('\\|\\|test\\|\\|');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('escapeMarkdown', () => {
|
||||||
|
test('shared', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*\\`\\`\\`js\n\\`use strict\\`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no codeBlock', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { codeBlock: false }))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*```js\n\\`use strict\\`;\nrequire(\'discord.js\');```\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no inlineCode', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { inlineCode: false }))
|
||||||
|
.toBe('`\\_Behold!\\_`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*\\`\\`\\`js\n`use strict`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no bold', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { bold: false }))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n\\|\\|\\_\\_\\_\\~\\~\\***\\`\\`\\`js\n\\`use strict\\`;\nrequire(\'discord.js\');\\`\\`\\`**\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no italic', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { italic: false }))
|
||||||
|
.toBe('\\`_Behold!_\\`\n\\|\\|_\\_\\_\\~\\~*\\*\\*\\`\\`\\`js\n\\`use strict\\`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\**\\~\\~\\_\\__\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no underline', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { underline: false }))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n\\|\\|\\___\\~\\~\\*\\*\\*\\`\\`\\`js\n\\`use strict\\`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~__\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no strikethrough', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { strikethrough: false }))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n\\|\\|\\_\\_\\_~~\\*\\*\\*\\`\\`\\`js\n\\`use strict\\`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*~~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no spoiler', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { spoiler: false }))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n||\\_\\_\\_\\~\\~\\*\\*\\*\\`\\`\\`js\n\\`use strict\\`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~\\_\\_\\_||');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('code content', () => {
|
||||||
|
test('no code block content', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { codeBlockContent: false }))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*\\`\\`\\`js\n`use strict`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no inline code content', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { inlineCodeContent: false }))
|
||||||
|
.toBe('\\`_Behold!_\\`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*\\`\\`\\`js\n\\`use strict\\`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('neither inline code or code block content', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { inlineCodeContent: false, codeBlockContent: false }))
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
.toBe('\\`_Behold!_\\`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*\\`\\`\\`js\n`use strict`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('neither code blocks or code block content', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { codeBlock: false, codeBlockContent: false }))
|
||||||
|
.toBe('\\`\\_Behold!\\_\\`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*```js\n`use strict`;\nrequire(\'discord.js\');```\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('neither inline code or inline code content', () => {
|
||||||
|
expect(Util.escapeMarkdown(testString, { inlineCode: false, inlineCodeContent: false }))
|
||||||
|
.toBe('`_Behold!_`\n\\|\\|\\_\\_\\_\\~\\~\\*\\*\\*\\`\\`\\`js\n`use strict`;\nrequire(\'discord.js\');\\`\\`\\`\\*\\*\\*\\~\\~\\_\\_\\_\\|\\|');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('edge-case odd number of fenses with no code block content', () => {
|
||||||
|
expect(Util.escapeMarkdown('**foo** ```**bar**``` **fizz** ``` **buzz**', { codeBlock: false, codeBlockContent: false }))
|
||||||
|
.toBe('\\*\\*foo\\*\\* ```**bar**``` \\*\\*fizz\\*\\* ``` \\*\\*buzz\\*\\*');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('edge-case odd number of backticks with no inline code content', () => {
|
||||||
|
expect(Util.escapeMarkdown('**foo** `**bar**` **fizz** ` **buzz**', { inlineCode: false, inlineCodeContent: false }))
|
||||||
|
.toBe('\\*\\*foo\\*\\* `**bar**` \\*\\*fizz\\*\\* ` \\*\\*buzz\\*\\*');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* eslint-enable max-len, no-undef */
|
||||||
10
typings/index.d.ts
vendored
10
typings/index.d.ts
vendored
@@ -1160,7 +1160,15 @@ declare module 'discord.js' {
|
|||||||
public static convertToBuffer(ab: ArrayBuffer | string): Buffer;
|
public static convertToBuffer(ab: ArrayBuffer | string): Buffer;
|
||||||
public static delayFor(ms: number): Promise<void>;
|
public static delayFor(ms: number): Promise<void>;
|
||||||
public static discordSort<K, V extends { rawPosition: number; id: string; }>(collection: Collection<K, V>): Collection<K, V>;
|
public static discordSort<K, V extends { rawPosition: number; id: string; }>(collection: Collection<K, V>): Collection<K, V>;
|
||||||
public static escapeMarkdown(text: string, onlyCodeBlock?: boolean, onlyInlineCode?: boolean): string;
|
public static escapeMarkdown(text: string, options?: { codeBlock?: boolean, inlineCode?: boolean, bold?: boolean, italic?: boolean, underline?: boolean, strikethrough?: boolean, spoiler?: boolean, inlineCodeContent?: boolean, codeBlockContent?: boolean }): string;
|
||||||
|
public static escapeCodeBlock(text: string): string;
|
||||||
|
public static escapeInlineCode(text: string): string;
|
||||||
|
public static escapeBold(text: string): string;
|
||||||
|
public static escapeItalic(text: string): string;
|
||||||
|
public static escapeUnderline(text: string): string;
|
||||||
|
public static escapeStrikethrough(text: string): string;
|
||||||
|
public static escapeSpoiler(text: string): string;
|
||||||
|
public static cleanCodeBlockContent(text: string): string;
|
||||||
public static fetchRecommendedShards(token: string, guildsPerShard?: number): Promise<number>;
|
public static fetchRecommendedShards(token: string, guildsPerShard?: number): Promise<number>;
|
||||||
public static flatten(obj: object, ...props: { [key: string]: boolean | string }[]): object;
|
public static flatten(obj: object, ...props: { [key: string]: boolean | string }[]): object;
|
||||||
public static idToBinary(num: Snowflake): string;
|
public static idToBinary(num: Snowflake): string;
|
||||||
|
|||||||
Reference in New Issue
Block a user