diff --git a/.eslintrc.js b/.eslintrc.js index 3f1e804..24e5620 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,24 +1,30 @@ module.exports = { - 'env': { - 'commonjs': true, - 'es2021': true, - 'node': true + "env": { + "es6": true, + "node": true }, - 'extends': 'eslint:recommended', - 'parserOptions': { - 'ecmaVersion': 12 + "extends": "eslint:recommended", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" }, - 'rules': { + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module" + }, + "rules": { "accessor-pairs": "warn", "array-callback-return": "warn", - "arrow-parens": "warn", + "array-bracket-newline": [ "warn", "consistent" ], + "array-bracket-spacing": [ "warn", "always", { "objectsInArrays": false, "arraysInArrays": false }], + // "arrow-parens": "warn", "arrow-spacing": "warn", "block-scoped-var": "warn", - "block-spacing": "warn", - "brace-style": "warn", + "block-spacing": [ "warn", "always" ], + "brace-style": [ "warn", "1tbs" ], "callback-return": "warn", "camelcase": "warn", - "comma-dangle": "warn", + "comma-dangle": [ "warn", "only-multiline" ], "comma-spacing": [ "warn", { @@ -38,6 +44,10 @@ module.exports = { "allowKeywords": true } ], + "dot-location": [ + "error", + "property" + ], "eol-last": [ "warn", "never" @@ -55,18 +65,13 @@ module.exports = { "id-blacklist": "warn", "id-match": "warn", "implicit-arrow-linebreak": "warn", - "indent": [ - "warn", - 4, - { - "SwitchCase": 1 - } - ], + "indent": "warn", "init-declarations": "warn", - "jsx-quotes": "warn", - "key-spacing": "warn", + "jsx-quotes": [ "warn", "prefer-single" ], + "key-spacing": [ "warn", { "beforeColon": false, "afterColon": true }], + "keyword-spacing": [ "warn", { "after": true, "before": true }], "linebreak-style": [ - "warn", + "error", "windows" ], "lines-around-comment": "warn", @@ -98,13 +103,14 @@ module.exports = { "no-floating-decimal": "warn", "no-implicit-coercion": "warn", "no-implicit-globals": "warn", - "no-implied-eval": "warn", + "no-implied-eval": "error", "no-import-assign": "warn", "no-invalid-this": "warn", "no-iterator": "warn", "no-label-var": "warn", // "no-labels": "warn", "no-lone-blocks": "warn", + "no-lonely-if": "warn", "no-loop-func": "warn", "no-mixed-requires": "warn", "no-multi-assign": "warn", @@ -113,6 +119,7 @@ module.exports = { "no-multiple-empty-lines": "warn", "no-native-reassign": "warn", "no-negated-in-lhs": "warn", + "no-negated-condition": "error", "no-nested-ternary": "warn", "no-new": "warn", "no-new-func": "warn", @@ -135,14 +142,16 @@ module.exports = { "no-sequences": "warn", "no-setter-return": "warn", "no-spaced-func": "warn", + "no-shadow": "error", "no-tabs": "warn", - "no-template-curly-in-string": "warn", + "no-template-curly-in-string": "error", "no-throw-literal": "warn", - "no-undef-init": "warn", + "no-undef-init": "error", + "no-undefined": "error", "no-unmodified-loop-condition": "warn", - "no-unneeded-ternary": "warn", + "no-unneeded-ternary": "error", "no-unused-expressions": "warn", - "no-use-before-define": "warn", + "no-use-before-define": "error", "no-useless-call": "warn", "no-useless-computed-key": "warn", "no-useless-concat": "warn", @@ -151,22 +160,25 @@ module.exports = { "no-useless-return": "warn", "no-var": "warn", "no-void": "warn", - "no-whitespace-before-property": "warn", + "no-whitespace-before-property": "error", "nonblock-statement-body-position": "warn", "object-curly-spacing": [ "warn", "always" ], + "object-property-newline": [ "warn", { "allowAllPropertiesOnSameLine": true }], "object-shorthand": "warn", "one-var-declaration-per-line": "warn", "operator-assignment": "warn", + "operator-linebreak": [ "warn", "before" ], "padding-line-between-statements": "warn", + "padded-blocks": [ "warn", { "switches": "never" }, { "allowSingleLineBlocks": true }], "prefer-arrow-callback": "warn", "prefer-const": "warn", "prefer-destructuring": "warn", "prefer-exponentiation-operator": "warn", "prefer-numeric-literals": "warn", - "prefer-object-spread": "warn", + "prefer-object-spread": "error", "prefer-promise-reject-errors": "warn", "prefer-regex-literals": "warn", "prefer-rest-params": "warn", @@ -174,17 +186,20 @@ module.exports = { "require-jsdoc": "warn", "require-unicode-regexp": "warn", "rest-spread-spacing": "warn", - "semi": "warn", + "semi": "error", "semi-spacing": "warn", "semi-style": [ "warn", "last" ], "space-before-blocks": "warn", + "space-before-function-paren": [ "error", "always" ], "space-in-parens": [ "warn", "never" ], + "spaced-comment": [ "warn", "always" ], + "strict": "warn", "switch-colon-spacing": "warn", "symbol-description": "warn", "template-curly-spacing": [ @@ -198,7 +213,7 @@ module.exports = { ], "vars-on-top": "warn", "wrap-iife": "warn", - "wrap-regex": "warn", + "wrap-regex": "error", "yield-star-spacing": "warn", "yoda": [ "warn", diff --git a/.gitignore b/.gitignore index 5346749..b3fedb6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ modmail_cache persistent_cache.json canned_replies.json config - server.js +old.eslintrc.js diff --git a/structure/Cache.js b/structure/Cache.js index ac2f994..178a14c 100644 --- a/structure/Cache.js +++ b/structure/Cache.js @@ -1,11 +1,13 @@ const fs = require('fs'); +const CacheHandler = require('./abstractions/CacheHandler'); -class Cache { +class JsonCache extends CacheHandler { - constructor(client) { + constructor (client) { + + super(client); const opts = client._options; - this.client = client; this.logger = client.logger; this.saveInterval = opts.saveInterval; @@ -23,7 +25,7 @@ class Cache { } - load() { + load () { if (this._ready) return; @@ -31,27 +33,27 @@ class Cache { this.logger.info('Loading cache'); const raw = JSON.parse(fs.readFileSync('./persistent_cache.json', { encoding: 'utf-8' })); const entries = Object.entries(raw); - for (const [key, val] of entries) this[key] = val; + for (const [ key, val ] of entries) this[key] = val; } else { this.logger.info('Cache file missing, creating...'); - this.save(); + this.savePersistentCache(); } - this.cacheSaveInterval = setInterval(this.save.bind(this), 10 * 60 * 1000); + this.cacheSaveInterval = setInterval(this.savePersistentCache.bind(this), 10 * 60 * 1000); this.modmailSaveInterval = setInterval(this.saveModmailHistory.bind(this), this.saveInterval * 60 * 1000, this.client.modmail); this._ready = true; } - save() { + savePersistentCache () { this.logger.debug('Saving cache'); fs.writeFileSync('./persistent_cache.json', JSON.stringify(this.json)); } - saveModmailHistory() { + saveModmailHistory () { if (!this.updatedThreads.length) return; - const toSave = [...this.updatedThreads]; + const toSave = [ ...this.updatedThreads ]; this.updatedThreads = []; this.client.logger.debug(`Saving modmail data`); if (!fs.existsSync('./modmail_cache')) fs.mkdirSync('./modmail_cache'); @@ -67,7 +69,7 @@ class Cache { } - loadModmailHistory(userId) { + loadModmailHistory (userId) { return new Promise((resolve, reject) => { @@ -90,7 +92,7 @@ class Cache { } - get json() { + get json () { return { queue: this.queue, channels: this.channels, @@ -101,4 +103,4 @@ class Cache { } -module.exports = Cache; \ No newline at end of file +module.exports = JsonCache; \ No newline at end of file diff --git a/structure/ChannelHandler.js b/structure/ChannelHandler.js index e076de5..2771f3a 100644 --- a/structure/ChannelHandler.js +++ b/structure/ChannelHandler.js @@ -1,6 +1,6 @@ class ChannelHandler { - constructor(modmail, opts) { + constructor (modmail, opts) { this.modmail = modmail; this.client = modmail.client; @@ -19,7 +19,7 @@ class ChannelHandler { } - init() { + init () { this.mainServer = this.modmail.mainServer; this.bansServer = this.modmail.bansServer; @@ -41,7 +41,7 @@ class ChannelHandler { } - async send(target, embed, newEntry) { + async send (target, embed, newEntry) { // Load & update the users past modmails const history = await this.cache.loadModmailHistory(target.id) @@ -71,7 +71,7 @@ class ChannelHandler { } - async setReadState(target, channel, staff, state) { + async setReadState (target, channel, staff, state) { const history = await this.cache.loadModmailHistory(target) .catch((err) => { @@ -106,7 +106,7 @@ class ChannelHandler { * @return {TextChannel} * @memberof ChannelHandler */ - load(target, history) { + load (target, history) { if (this.awaitingChannel[target.id]) return this.awaitingChannel[target.id]; // eslint-disable-next-line no-async-promise-executor @@ -135,8 +135,8 @@ class ChannelHandler { fields: [ { name: '__User Data__', - value: `**User:** <@${user.id}>\n` + - `**Account created:** ${user.createdAt.toDateString()}\n`, + value: `**User:** <@${user.id}>\n` + + `**Account created:** ${user.createdAt.toDateString()}\n`, inline: false } ], @@ -151,9 +151,9 @@ class ChannelHandler { } else embed.description = `**__USER IS IN APPEAL SERVER__**`; } else if (member) embed.fields.push({ name: '__Member Data__', - value: `**Nickname:** ${member.nickname || 'N/A'}\n` + - `**Server join date:** ${member.joinedAt.toDateString()}\n` + - `**Roles:** ${member.roles.cache.filter((r) => r.id !== guild.roles.everyone.id).map((r) => `<@&${r.id}>`).join(' ')}`, + value: `**Nickname:** ${member.nickname || 'N/A'}\n` + + `**Server join date:** ${member.joinedAt.toDateString()}\n` + + `**Roles:** ${member.roles.cache.filter((r) => r.id !== guild.roles.everyone.id).map((r) => `<@&${r.id}>`).join(' ')}`, inline: false }); @@ -166,10 +166,12 @@ class ChannelHandler { if (!entry) continue; if ([ 'read', 'unread' ].includes(entry.readState)) continue; + // eslint-disable-next-line no-shadow const user = await this.client.resolveUser(entry.author).catch(this.client.logger.error.bind(this.client.logger)); const mem = await this.modmail.getMember(user.id).catch(this.client.logger.error.bind(this.client.logger)); if (!user) return reject(new Error(`Failed to find user`)); + // eslint-disable-next-line no-shadow const embed = { footer: { text: user.id @@ -201,7 +203,7 @@ class ChannelHandler { } // Ensure the right category - //if (channel.parentID !== this.newMail.id) + // if (channel.parentID !== this.newMail.id) await channel.edit({ parentID: this.newMail.id, lockPermissions: true }).catch((err) => { this.client.logger.error(`Error during channel transition:\n${err.stack}`); }); @@ -221,7 +223,7 @@ class ChannelHandler { * @param {object} { age, count, force } age: how long the channel has to be without activity to be deleted, count: how many channels to act on, force: whether to ignore answered status * @memberof Modmail */ - async sweepChannels({ age, count, force = false } = {}) { + async sweepChannels ({ age, count, force = false } = {}) { this.client.logger.info(`Sweeping graveyard`); const now = Date.now(); @@ -240,11 +242,11 @@ class ChannelHandler { if (!lastMessage || now - lastMessage.createdTimestamp > age || count && channelCount <= count) { await channel.delete().then((ch) => { const chCache = this.cache.channels; - const _cached = Object.entries(chCache).find(([, val]) => { + const _cached = Object.entries(chCache).find(([ , val ]) => { return val === ch.id; }); if (_cached) { - const [userId] = _cached; + const [ userId ] = _cached; delete this.modmail.cache.channels[userId]; } }).catch((err) => { @@ -279,7 +281,7 @@ class ChannelHandler { } - async overflow() { // Overflows new modmail category into read + async overflow () { // Overflows new modmail category into read const channels = this.newMail.children.sort((a, b) => { if (!a.lastMessage) return -1; if (!b.lastMessage) return 1; diff --git a/structure/Client.js b/structure/Client.js index 10b4bef..813ad1e 100644 --- a/structure/Client.js +++ b/structure/Client.js @@ -10,7 +10,7 @@ const Cache = require('./Cache'); class ModmailClient extends Client { - constructor(options) { + constructor (options) { super(options.clientOptions); @@ -31,7 +31,7 @@ class ModmailClient extends Client { } - async init() { + async init () { this.registry.loadCommands(); @@ -51,13 +51,13 @@ class ModmailClient extends Client { process.on('exit', () => { this.logger.warn('process exiting'); - this.cache.save(); + this.cache.savePersistentCache(); this.cache.saveModmailHistory(this.modmail); }); process.on('SIGINT', () => { this.logger.warn('received sigint'); - //this.cache.save(); - //this.cache.saveModmailHistory(this.modmail); + // this.cache.save(); + // this.cache.saveModmailHistory(this.modmail); // eslint-disable-next-line no-process-exit process.exit(); }); @@ -66,7 +66,7 @@ class ModmailClient extends Client { } - ready() { + ready () { return new Promise((resolve) => { if (this._ready) resolve(); @@ -75,7 +75,7 @@ class ModmailClient extends Client { } - async handleMessage(message) { + async handleMessage (message) { if (!this._ready) return; if (message.author.bot) return; @@ -90,13 +90,13 @@ class ModmailClient extends Client { const { prefix } = this; const { channel, guild, content, member } = message; - if (![this.mainServer.id, this.bansServer?.id || '0'].includes(guild.id)) return; + if (![ this.mainServer.id, this.bansServer?.id || '0' ].includes(guild.id)) return; if (!content || !content.startsWith(prefix)) return; const roles = member.roles.cache.map((r) => r.id); - if(!roles.some((r) => this._options.staffRoles.includes(r)) && !member.hasPermission('ADMINISTRATOR')) return; + if (!roles.some((r) => this._options.staffRoles.includes(r)) && !member.hasPermission('ADMINISTRATOR')) return; - const [rawCommand, ...args] = content.split(' '); + const [ rawCommand, ...args ] = content.split(' '); const commandName = rawCommand.substring(prefix.length); const command = this.registry.find(commandName); if (!command) return; @@ -127,32 +127,32 @@ class ModmailClient extends Client { } - resolveUser(...args) { + resolveUser (...args) { return this.resolver.resolveUser(...args); } - resolveUsers(...args) { + resolveUsers (...args) { return this.resolver.resolveUsers(...args); } - resolveChannels(...args) { + resolveChannels (...args) { return this.resolver.resolveChannels(...args); } - resolveChannel(...args) { + resolveChannel (...args) { return this.resolver.resolveChannel(...args); } - async prompt(str, { author, channel, time }) { + async prompt (str, { author, channel, time }) { if (!channel && author) channel = await author.createDM(); if (!channel) throw new Error(`Missing channel for prompt, must pass at least author.`); await channel.send(str); - return channel.awaitMessages((m) => m.author.id === author.id, { max: 1, time: time || 30000, errors: ['time'] }) + return channel.awaitMessages((m) => m.author.id === author.id, { max: 1, time: time || 30000, errors: [ 'time' ] }) .then((collected) => { return collected.first(); }) - .catch((error) => { //eslint-disable-line no-unused-vars, handle-callback-err + .catch((error) => { // eslint-disable-line no-unused-vars, handle-callback-err return null; }); diff --git a/structure/Command.js b/structure/Command.js index 8c64fb2..ec2f07a 100644 --- a/structure/Command.js +++ b/structure/Command.js @@ -1,8 +1,8 @@ class Command { - constructor(client, options) { + constructor (client, options) { - Object.entries(options).forEach(([key, val]) => { + Object.entries(options).forEach(([ key, val ]) => { this[key] = val; }); @@ -12,7 +12,7 @@ class Command { } - async execute() { + async execute () { throw new Error(`Missing execute in ${this.name}`); } diff --git a/structure/Modmail.js b/structure/Modmail.js index c6c233b..5a760d1 100644 --- a/structure/Modmail.js +++ b/structure/Modmail.js @@ -6,7 +6,7 @@ class Modmail { // A lot of this can probably be simplified but I wrote all of this in 2 days and I cba to fix this atm // TODO: Fix everything - constructor(client) { + constructor (client) { this.client = client; this.cache = client.cache; @@ -35,7 +35,7 @@ class Modmail { } - async init() { + async init () { this.mainServer = this.client.mainServer; if (!this.mainServer) throw new Error(`Missing main server`); @@ -62,7 +62,7 @@ class Modmail { let logStr = `Started modmail handler for ${this.mainServer.name}`; if (this.bansServer) logStr += ` with ${this.bansServer.name} for ban appeals`; this.client.logger.info(logStr); - //this.client.logger.info(`Fetching messages from discord for modmail`); + // this.client.logger.info(`Fetching messages from discord for modmail`); // TODO: Fetch messages from discord in modmail channels this.channels.init(); @@ -70,16 +70,16 @@ class Modmail { } - async getMember(user) { + async getMember (user) { let result = this.mainServer.members.cache.get(user); - if(!result) result = await this.mainServer.members.fetch(user).catch(() => { + if (!result) result = await this.mainServer.members.fetch(user).catch(() => { return null; }); if (!result && this.bansServer) { result = this.bansServer.members.cache.get(user); - if(!result) result = await this.bansServer.members.fetch(user).catch(() => { + if (!result) result = await this.bansServer.members.fetch(user).catch(() => { return null; }); if (result) result.inAppealServer = true; @@ -89,7 +89,7 @@ class Modmail { } - async getUser(user) { + async getUser (user) { let result = this.client.users.cache.get(user); if (!result) result = await this.client.users.fetch(user).catch(() => { @@ -99,7 +99,7 @@ class Modmail { } - async handleUser(message) { + async handleUser (message) { const { author, content } = message; const member = await this.getMember(author.id); @@ -107,7 +107,7 @@ class Modmail { const now = Math.floor(Date.now() / 1000); const lastActivity = this.client.cache.lastActivity[author.id]; - //console.log(now - lastActivity, lastActivity, now) + // console.log(now - lastActivity, lastActivity, now) if (!lastActivity || now - lastActivity > 30 * 60) { await author.send(`Thank you for your message, we'll get back to you soon!`); } @@ -117,22 +117,18 @@ class Modmail { // Anti spam if (!this.spammers[author.id]) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; - else { - if (this.spammers[author.id].timeout) { - if (now - this.spammers[author.id].start > 5 * 60) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; - else return; - } else if (this.spammers[author.id].count > 5 && now - this.spammers[author.id].start < 15) { - this.spammers[author.id].timeout = true; - if (!this.spammers[author.id].warned) { - this.spammers[author.id].warned = true; - await author.send(`I've blocked you for spamming, please try again in 5 minutes`); - if (cache._channels[author.id]) await cache._channels[author.id].send(`I've blocked ${author.tag} from DMing me as they were spamming.`); - } - } else { - if (now - this.spammers[author.id].start > 15) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; - else this.spammers[author.id].count++; + else if (this.spammers[author.id].timeout) { + if (now - this.spammers[author.id].start > 5 * 60) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; + else return; + } else if (this.spammers[author.id].count > 5 && now - this.spammers[author.id].start < 15) { + this.spammers[author.id].timeout = true; + if (!this.spammers[author.id].warned) { + this.spammers[author.id].warned = true; + await author.send(`I've blocked you for spamming, please try again in 5 minutes`); + if (cache._channels[author.id]) await cache._channels[author.id].send(`I've blocked ${author.tag} from DMing me as they were spamming.`); } - } + } else if (now - this.spammers[author.id].start > 15) this.spammers[author.id] = { start: now, count: 1, timeout: false, warned: false }; + else this.spammers[author.id].count++; const pastModmail = await this.cache.loadModmailHistory(author.id) .catch((err) => { @@ -187,7 +183,7 @@ class Modmail { } - async sendCannedResponse({ message, responseName, anon }) { + async sendCannedResponse ({ message, responseName, anon }) { const content = this.getCanned(responseName); if (!content) return { @@ -200,7 +196,7 @@ class Modmail { } // Send reply from channel - async sendResponse({ message, content, anon }) { + async sendResponse ({ message, content, anon }) { const { channel, member, author } = message; if (!this.categories.includes(channel.parentID)) return { @@ -210,7 +206,7 @@ class Modmail { // Resolve target user from cache const chCache = this.cache.channels; - const result = Object.entries(chCache).find(([, val]) => { + const result = Object.entries(chCache).find(([ , val ]) => { return val === channel.id; }); @@ -220,7 +216,7 @@ class Modmail { }; // Ensure target exists, this should never run into issues - const [userId] = result; + const [ userId ] = result; const targetMember = await this.getMember(userId); if (!targetMember) return { error: true, @@ -234,7 +230,7 @@ class Modmail { } // Send modmail with the modmail command - async sendModmail({ message, content, anon, target }) { + async sendModmail ({ message, content, anon, target }) { const targetMember = await this.getMember(target.id); if (!targetMember) return { @@ -254,7 +250,7 @@ class Modmail { } - async send({ target, staff, anon, content }) { + async send ({ target, staff, anon, content }) { const embed = { author: { @@ -286,7 +282,7 @@ class Modmail { } - async changeReadState(message, args, state = 'read') { + async changeReadState (message, args, state = 'read') { const { author } = message; @@ -301,14 +297,14 @@ class Modmail { if (args.length) { // Eventually support marking several threads read at the same time - const [id] = args; + const [ id ] = args; user = await this.client.resolveUser(id, true); let channel = await this.client.resolveChannel(id); if (channel) { const chCache = this.cache.channels; - const result = Object.entries(chCache).find(([, val]) => { + const result = Object.entries(chCache).find(([ , val ]) => { return val === channel.id; }); @@ -334,7 +330,7 @@ class Modmail { if (!response) { const { channel } = message; const chCache = this.cache.channels; - const result = Object.entries(chCache).find(([, val]) => { + const result = Object.entries(chCache).find(([ , val ]) => { return val === channel.id; }); @@ -343,7 +339,7 @@ class Modmail { msg: `This doesn't seem to be a valid modmail channel. Cache might be out of sync. **[MISSING TARGET]**` }; - const [userId] = result; + const [ userId ] = result; user = await this.getUser(userId); response = await this.channels.setReadState(userId, channel, author, state); } @@ -355,7 +351,7 @@ class Modmail { } - async sendReminder() { + async sendReminder () { const channel = this.reminderChannel; const amount = this.queue.length; @@ -379,7 +375,7 @@ class Modmail { } - async log({ author, content, action, target }) { + async log ({ author, content, action, target }) { const embed = { author: { @@ -400,11 +396,11 @@ class Modmail { } - getCanned(name) { + getCanned (name) { return this.replies[name.toLowerCase()]; } - loadReplies() { + loadReplies () { this.client.logger.info('Loading canned replies'); if (!fs.existsSync('./canned_replies.json')) return {}; @@ -412,7 +408,7 @@ class Modmail { } - saveReplies() { + saveReplies () { this.client.logger.info('Saving canned replies'); fs.writeFileSync('./canned_replies.json', JSON.stringify(this.replies)); diff --git a/structure/Registry.js b/structure/Registry.js index 438eddf..1e49758 100644 --- a/structure/Registry.js +++ b/structure/Registry.js @@ -4,7 +4,7 @@ const fs = require('fs'); class Registry { - constructor(client) { + constructor (client) { this.client = client; @@ -12,13 +12,13 @@ class Registry { } - find(name) { + find (name) { return this.commands.find((c) => c.name === name.toLowerCase() || c.aliases?.includes(name.toLowerCase())); } - loadCommands() { + loadCommands () { const commandsDir = path.join(process.cwd(), 'structure', 'commands'); const files = fs.readdirSync(commandsDir); diff --git a/structure/Resolver.js b/structure/Resolver.js index 694461a..a8c8b8c 100644 --- a/structure/Resolver.js +++ b/structure/Resolver.js @@ -1,6 +1,6 @@ class Resolver { - constructor(client) { + constructor (client) { this.client = client; } @@ -12,9 +12,9 @@ class Resolver { * @returns {Promise> || boolean} Array of resolved users or false if none were resolved * @memberof Resolver */ - async resolveUsers(resolveables = [], strict = false) { + async resolveUsers (resolveables = [], strict = false) { - if (typeof resolveables === 'string') resolveables = [resolveables]; + if (typeof resolveables === 'string') resolveables = [ resolveables ]; if (resolveables.length === 0) return false; const { users } = this.client; const resolved = []; @@ -23,7 +23,7 @@ class Resolver { if ((/<@!?([0-9]{17,21})>/u).test(resolveable)) { - const [, id] = resolveable.match(/<@!?([0-9]{17,21})>/u); + const [ , id ] = resolveable.match(/<@!?([0-9]{17,21})>/u); const user = await users.fetch(id).catch((err) => { if (err.code === 10013) return false; // this.client.logger.warn(err); return false; @@ -33,7 +33,7 @@ class Resolver { } else if ((/(id:)?([0-9]{17,21})/u).test(resolveable)) { - const [, , id] = resolveable.match(/(id:)?([0-9]{17,21})/u); + const [ , , id ] = resolveable.match(/(id:)?([0-9]{17,21})/u); const user = await users.fetch(id).catch((err) => { if (err.code === 10013) return false; // this.client.logger.warn(err); return false; @@ -63,11 +63,11 @@ class Resolver { } - async resolveUser(resolveable, strict) { + async resolveUser (resolveable, strict) { if (!resolveable) return false; if (resolveable instanceof Array) throw new Error('Resolveable cannot be of type Array, use resolveUsers for resolving arrays of users'); - const result = await this.resolveUsers([resolveable], strict); + const result = await this.resolveUsers([ resolveable ], strict); return result ? result[0] : false; } @@ -82,9 +82,9 @@ class Resolver { * @returns {Promise> || Promise} an array of guild channels or false if none were resolved * @memberof Resolver */ - async resolveChannels(resolveables = [], strict = false, guild = null, filter = () => true) { + async resolveChannels (resolveables = [], strict = false, guild = null, filter = () => true) { - if (typeof resolveables === 'string') resolveables = [resolveables]; + if (typeof resolveables === 'string') resolveables = [ resolveables ]; if (resolveables.length === 0) return false; if (!guild) guild = this.client.mainServer; const CM = guild.channels; @@ -102,9 +102,10 @@ class Resolver { if (id.test(resolveable)) { const match = resolveable.match(id); - const [, ch] = match; + const [ , ch ] = match; - const channel = await this.client.channels.fetch(ch).catch((e) => { }); //eslint-disable-line no-empty, no-empty-function, no-unused-vars + // eslint-disable-next-line no-shadow + const channel = await this.client.channels.fetch(ch).catch((e) => { }); // eslint-disable-line no-empty, no-empty-function, no-unused-vars if (channel && filter(channel)) resolved.push(channel); @@ -112,6 +113,7 @@ class Resolver { const match = resolveable.match(name); const ch = match[1].toLowerCase(); + // eslint-disable-next-line no-shadow const channel = CM.cache.sort((a, b) => a.name.length - b.name.length).filter(filter).filter((c) => { if (!strict) return c.name.toLowerCase().includes(ch); return c.name.toLowerCase() === ch; @@ -127,11 +129,11 @@ class Resolver { } - async resolveChannel(resolveable, strict, guild, filter) { + async resolveChannel (resolveable, strict, guild, filter) { if (!resolveable) return false; if (resolveable instanceof Array) throw new Error('Resolveable cannot be of type Array, use resolveChannels for resolving arrays of channels'); - const result = await this.resolveChannels([resolveable], strict, guild, filter); + const result = await this.resolveChannels([ resolveable ], strict, guild, filter); return result ? result[0] : false; } diff --git a/structure/commands/CannedReply.js b/structure/commands/CannedReply.js index bc3f8db..bf6a9fe 100644 --- a/structure/commands/CannedReply.js +++ b/structure/commands/CannedReply.js @@ -2,18 +2,18 @@ const Command = require('../Command'); class CannedReply extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'cannedreply', - aliases: ['cr', 'canned'], + aliases: [ 'cr', 'canned' ], showUsage: true, usage: `` }); } - async execute(message, { args }) { + async execute (message, { args }) { - const [first] = args.map((a) => a); + const [ first ] = args.map((a) => a); // eslint-disable-next-line prefer-const let { channel, content, _caller } = message, anon = false; @@ -22,13 +22,14 @@ class CannedReply extends Command { if (op === 'anon') { anon = true; content = content.replace(first, ''); - } else if (['create', 'delete'].includes(op)) { + } else if ([ 'create', 'delete' ].includes(op)) { return this.createCanned(op, args, message); - } else if (['list'].includes(first.toLowerCase(op))) { + } else if ([ 'list' ].includes(first.toLowerCase(op))) { const list = Object.entries(this.client.modmail.replies); let str = ''; - for (const [name, content] of list) { + // eslint-disable-next-line no-shadow + for (const [ name, content ] of list) { if (str.length + content.length > 2000) { await channel.send(str).catch(this.client.logger.error.bind(this.client.logger)); str = ''; @@ -42,13 +43,13 @@ class CannedReply extends Command { } - async createCanned(op, args, { channel, author }) { + async createCanned (op, args, { channel, author }) { if (args.length < 1) return { error: true, msg: 'Missing reply name' }; - const [_name, ...rest] = args; + const [ _name, ...rest ] = args; const name = _name.toLowerCase(); const canned = this.client.modmail.replies; @@ -63,7 +64,7 @@ class CannedReply extends Command { if (canned[name]) { confirmation = await this.client.prompt(`A canned reply by the name ${name} already exists, would you like to overwrite it?`, { channel, author }); if (!confirmation) return 'Timed out.'; - confirmation = ['y', 'yes', 'ok'].includes(confirmation.content.toLowerCase()); + confirmation = [ 'y', 'yes', 'ok' ].includes(confirmation.content.toLowerCase()); if (!confirmation) return 'Cancelled'; } diff --git a/structure/commands/Eval.js b/structure/commands/Eval.js index ba29b46..9a906db 100644 --- a/structure/commands/Eval.js +++ b/structure/commands/Eval.js @@ -5,20 +5,20 @@ const Command = require('../Command'); class Eval extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'eval', - aliases: ['e'] + aliases: [ 'e' ] }); } - async execute(message, { clean }) { + async execute (message, { clean }) { if (!this.client._options.evalAccess.includes(message.author.id)) return; - const { guild, author, member, client, channel } = message; //eslint-disable-line no-unused-vars + const { guild, author, member, client, channel } = message; // eslint-disable-line no-unused-vars try { - let evaled = eval(clean); //eslint-disable-line no-eval + let evaled = eval(clean); // eslint-disable-line no-eval if (evaled instanceof Promise) await evaled; if (typeof evaled !== 'string') evaled = inspect(evaled); @@ -26,7 +26,7 @@ class Eval extends Command { .replace(new RegExp(this.client.token, 'gu'), '') .replace(new RegExp(username, 'gu'), ''); - //if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Success: ${evaled}`); + // if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Success: ${evaled}`); if (evaled.length > 1850) { evaled = `${evaled.substring(0, 1850)}...`; @@ -41,7 +41,7 @@ class Eval extends Command { let msg = `${error}${error.stack ? `\n${error.stack}` : ''}`; - //if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Fail: ${msg}`); + // if (args.log) guild._debugLog(`[${message.author.tag}] Evaluation Fail: ${msg}`); if (msg.length > 2000) msg = `${msg.substring(0, 1900)}...`; await channel.send( `Evaluation failed.\`\`\`js\n${msg}\`\`\``, diff --git a/structure/commands/Id.js b/structure/commands/Id.js index 5f29efd..e21bce6 100644 --- a/structure/commands/Id.js +++ b/structure/commands/Id.js @@ -2,25 +2,25 @@ const Command = require('../Command'); class ModmailID extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'id', - aliases: ['mmid'] + aliases: [ 'mmid' ] }); } - async execute(message, { args }) { + async execute (message, { args }) { let channel = null; if (args?.length) { - const [ch] = args; + const [ ch ] = args; channel = await this.client.resolveChannel(ch); } else { ({ channel } = message); } const chCache = this.client.cache.channels; - const result = Object.entries(chCache).find(([, val]) => { + const result = Object.entries(chCache).find(([ , val ]) => { return val === channel.id; }); @@ -29,7 +29,7 @@ class ModmailID extends Command { msg: `This doesn't seem to be a valid modmail channel. Cache might be out of sync. **[MISSING TARGET]**` }; - const [userId] = result; + const [ userId ] = result; return userId; } diff --git a/structure/commands/Logs.js b/structure/commands/Logs.js index 0d5260b..9d1cf84 100644 --- a/structure/commands/Logs.js +++ b/structure/commands/Logs.js @@ -2,16 +2,16 @@ const Command = require('../Command'); class Logs extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'logs', - aliases: ['mmlogs', 'mmhistory', 'mmlog'], + aliases: [ 'mmlogs', 'mmhistory', 'mmlog' ], showUsage: true, usage: ' [page]' }); } - async execute(message, { args }) { + async execute (message, { args }) { const user = await this.client.resolveUser(args[0]); let pageNr = 1; @@ -27,7 +27,7 @@ class Logs extends Command { const { member, channel } = message; const history = await this.client.cache.loadModmailHistory(user.id); if (!history.length) return 'Not found in modmail DB'; - const page = this.paginate([...history].filter((e) => !('readState' in e)).reverse(), pageNr, 10); + const page = this.paginate([ ...history ].filter((e) => !('readState' in e)).reverse(), pageNr, 10); const embed = { author: { @@ -43,6 +43,7 @@ class Logs extends Command { }; for (const entry of page.items) { + // eslint-disable-next-line no-shadow const user = await this.client.resolveUser(entry.author); embed.fields.push({ name: `${user.tag}${entry.anon ? ' (ANON)' : ''} @ ${new Date(entry.timestamp).toUTCString()}`, @@ -54,7 +55,7 @@ class Logs extends Command { } - paginate(items, page = 1, pageLength = 10) { + paginate (items, page = 1, pageLength = 10) { const maxPage = Math.ceil(items.length / pageLength); if (page < 1) page = 1; if (page > maxPage) page = maxPage; diff --git a/structure/commands/Markread.js b/structure/commands/Markread.js index 59b4cc0..6821ab1 100644 --- a/structure/commands/Markread.js +++ b/structure/commands/Markread.js @@ -2,13 +2,13 @@ const Command = require('../Command'); class Markread extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'markread' }); } - async execute(message, { args }) { + async execute (message, { args }) { return this.client.modmail.changeReadState(message, args); diff --git a/structure/commands/Markunread.js b/structure/commands/Markunread.js index 7ec8b88..1772525 100644 --- a/structure/commands/Markunread.js +++ b/structure/commands/Markunread.js @@ -2,13 +2,13 @@ const Command = require('../Command'); class Markunread extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'markunread' }); } - async execute(message, { args }) { + async execute (message, { args }) { return this.client.modmail.changeReadState(message, args, 'unread'); diff --git a/structure/commands/Modmail.js b/structure/commands/Modmail.js index 920a449..0ea8f9f 100644 --- a/structure/commands/Modmail.js +++ b/structure/commands/Modmail.js @@ -2,19 +2,19 @@ const Command = require('../Command'); class Modmail extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'modmail', - aliases: ['mm'], + aliases: [ 'mm' ], showUsage: true, usage: ` ` }); } - async execute(message, { args }) { + async execute (message, { args }) { // eslint-disable-next-line prefer-const - let [first, second] = args.map((a) => a); + let [ first, second ] = args.map((a) => a); // eslint-disable-next-line prefer-const let { content, _caller } = message, anon = false; diff --git a/structure/commands/Ping.js b/structure/commands/Ping.js index 2bebd86..c737bd9 100644 --- a/structure/commands/Ping.js +++ b/structure/commands/Ping.js @@ -2,13 +2,13 @@ const Command = require('../Command'); class Ping extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'ping' }); } - async execute() { + async execute () { return `PONG!`; } diff --git a/structure/commands/Queue.js b/structure/commands/Queue.js index 3654121..2f58859 100644 --- a/structure/commands/Queue.js +++ b/structure/commands/Queue.js @@ -2,14 +2,14 @@ const Command = require('../Command'); class Queue extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'queue', - aliases: ['mmq', 'mmqueue', 'q'] + aliases: [ 'mmq', 'mmqueue', 'q' ] }); } - async execute(message) { + async execute (message) { const { queue } = this.client.modmail; if (!queue.length) return 'Queue is empty!'; diff --git a/structure/commands/Reply.js b/structure/commands/Reply.js index 26d65db..737169d 100644 --- a/structure/commands/Reply.js +++ b/structure/commands/Reply.js @@ -2,18 +2,18 @@ const Command = require('../Command'); class Reply extends Command { - constructor(client) { + constructor (client) { super(client, { name: 'reply', - aliases: ['r'], + aliases: [ 'r' ], showUsage: true, usage: `` }); } - async execute(message, { args }) { + async execute (message, { args }) { - const [first] = args.map((a) => a); + const [ first ] = args.map((a) => a); // eslint-disable-next-line prefer-const let { content, _caller } = message, anon = false;