modmail/structure/Util.js

158 lines
4.4 KiB
JavaScript

const moment = require('moment');
const path = require('path');
const fs = require('fs');
const fetch = require('node-fetch');
const { Util: DiscordUtil } = require('discord.js');
class Util {
constructor () {
throw new Error("Class may not be instantiated.");
}
static paginate (items, page = 1, pageLength = 10) {
const maxPage = Math.ceil(items.length / pageLength);
if (page < 1) page = 1;
if (page > maxPage) page = maxPage;
const startIndex = (page - 1) * pageLength;
return {
items: items.length > pageLength ? items.slice(startIndex, startIndex + pageLength) : items,
page,
maxPage,
pageLength
};
}
static arrayIncludesAny (target, compareTo = []) {
if (!(compareTo instanceof Array)) compareTo = [ compareTo ];
for (const elem of compareTo) {
if (target.includes(elem)) return true;
}
return false;
}
static downloadAsBuffer (source) {
return new Promise((resolve, reject) => {
fetch(source).then((res) => {
if (res.ok) resolve(res.buffer());
else reject(res.statusText);
});
});
}
static readdirRecursive (directory) {
const result = [];
// eslint-disable-next-line no-shadow
(function read (directory) {
const files = fs.readdirSync(directory);
for (const file of files) {
const filePath = path.join(directory, file);
if (fs.statSync(filePath).isDirectory()) {
read(filePath);
} else {
result.push(filePath);
}
}
}(directory));
return result;
}
static wait (ms) {
return this.delayFor(ms);
}
static delayFor (ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
static escapeMarkdown (text, options) {
if (typeof text !== 'string') return text;
return DiscordUtil.escapeMarkdown(text, options);
}
static get formattingPatterns () {
return [
[ '\\*{1,3}([^*]*)\\*{1,3}', '$1' ],
[ '_{1,3}([^_]*)_{1,3}', '$1' ],
[ '`{1,3}([^`]*)`{1,3}', '$1' ],
[ '~~([^~])~~', '$1' ]
];
}
static removeMarkdown (content) {
if (!content) throw new Error('Missing content');
this.formattingPatterns.forEach(([ pattern, replacer ]) => {
content = content.replace(new RegExp(pattern, 'gu'), replacer);
});
return content.trim();
}
/**
* Sanitise user given regex; escapes unauthorised characters
*
* @static
* @param {string} input
* @param {string[]} [allowed=['?', '\\', '(', ')', '|']]
* @return {string} The sanitised expression
* @memberof Util
*/
static sanitiseRegex (input, allowed = [ '?', '\\', '(', ')', '|' ]) {
if (!input) throw new Error('Missing input');
const reg = new RegExp(`[${this.regChars.filter((char) => !allowed.includes(char)).join('')}]`, 'gu');
return input.replace(reg, '\\$&');
}
static get regChars () {
return [ '.', '+', '*', '?', '\\[', '\\]', '^', '$', '(', ')', '{', '}', '|', '\\\\', '-' ];
}
static escapeRegex (string) {
if (typeof string !== 'string') {
throw new Error("Invalid type sent to escapeRegex.");
}
return string
.replace(/[|\\{}()[\]^$+*?.]/gu, '\\$&')
.replace(/-/gu, '\\x2d');
}
static duration (seconds) {
const { plural } = this;
let s = 0,
m = 0,
h = 0,
d = 0,
w = 0;
s = Math.floor(seconds);
m = Math.floor(s / 60);
s %= 60;
h = Math.floor(m / 60);
m %= 60;
d = Math.floor(h / 24);
h %= 24;
w = Math.floor(d / 7);
d %= 7;
return `${w ? `${w} ${plural(w, 'week')} ` : ''}${d ? `${d} ${plural(d, 'day')} ` : ''}${h ? `${h} ${plural(h, 'hour')} ` : ''}${m ? `${m} ${plural(m, 'minute')} ` : ''}${s ? `${s} ${plural(s, 'second')} ` : ''}`.trim();
}
static plural (amt, word) {
if (amt === 1) return word;
return `${word}s`;
}
static get date () {
return moment().format("YYYY-MM-DD HH:mm:ss");
}
}
module.exports = Util;