Remove as many error overrides as possible

merge-requests/12/head
Bsian 2020-05-16 20:03:21 +01:00
parent 817328a49d
commit 830f81b8f6
No known key found for this signature in database
GPG Key ID: 097FB9A291026091
30 changed files with 109 additions and 84 deletions

View File

@ -39,6 +39,7 @@
"import/prefer-default-export": "off",
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": 2,
"import/extensions": "off"
"import/extensions": "off",
"no-param-reassign": "off"
}
}

5
src/api/index.ts Normal file
View File

@ -0,0 +1,5 @@
import locsh from './loc.sh/main';
export default {
'loc.sh': locsh,
};

View File

@ -1,6 +1,6 @@
import { Server, ServerManagement } from '../../class';
export default function (management: ServerManagement) {
export default (management: ServerManagement) => {
const server = new Server(management, 3890, `${__dirname}/routes`);
return server;
}
};

View File

@ -0,0 +1 @@
export { default as root } from './root';

View File

@ -1,16 +1,18 @@
import { Route, Server } from '../../../class';
import { RedirectInterface } from '../../../models';
import { RedirectRaw } from '../../../models';
export default class Root extends Route {
constructor(server: Server) {
super(server, { path: '/' });
super(server);
this.conf = {
path: '/',
};
}
public bind() {
this.router.get('/:key', async (req, res) => {
try {
// @ts-ignore
const link: RedirectInterface = await this.server.client.db.redirect.findOne({ key: req.params.key }).lean().exec();
const link: RedirectRaw = await this.server.client.db.Redirect.findOne({ key: req.params.key }).lean().exec();
if (!link) return res.status(404).json({ code: this.constants.codes.NOT_FOUND, message: this.constants.messages.NOT_FOUND });
return res.redirect(link.to);
} catch (err) {

View File

@ -1 +0,0 @@

View File

@ -1,15 +1,17 @@
import eris from 'eris';
import mongoose from 'mongoose';
import { promises as fs } from 'fs';
import { Collection, Command, Util, ServerManagement } from '.';
import { Collection, Command, Util, ServerManagement, Event } from '.';
import { Member, MemberInterface, Moderation, ModerationInterface, Redirect, RedirectInterface } from '../models';
import * as eventFiles from '../events';
import * as commandFiles from '../commands';
export default class Client extends eris.Client {
public config: { token: string, prefix: string, guildID: string, mongoDB: string };
public commands: Collection<Command>;
public events: Collection<Function>;
public events: Collection<Event>;
public intervals: Collection<NodeJS.Timeout>;
@ -17,15 +19,14 @@ export default class Client extends eris.Client {
public serverManagement: ServerManagement;
public db: { member: mongoose.Model<MemberInterface>, moderation: mongoose.Model<ModerationInterface>, redirect: mongoose.Model<RedirectInterface> };
public db: { Member: mongoose.Model<MemberInterface>, Moderation: mongoose.Model<ModerationInterface>, Redirect: mongoose.Model<RedirectInterface> };
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(token: string, options?: eris.ClientOptions) {
super(token, options);
this.commands = new Collection<Command>();
this.events = new Collection<Function>();
this.events = new Collection<Event>();
this.intervals = new Collection<NodeJS.Timeout>();
this.db = { member: Member, moderation: Moderation, redirect: Redirect };
this.db = { Member, Moderation, Redirect };
}
public async loadDatabase() {
@ -49,26 +50,22 @@ export default class Client extends eris.Client {
}
public async loadEvents() {
const evtFiles = await fs.readdir(`${__dirname}/../events`);
evtFiles.forEach((file) => {
const eventName = file.split('.')[0];
if (file === 'index.js') return;
// eslint-disable-next-line
const event = new (require(`${__dirname}/../events/${file}`).default)(this);
this.events.add(eventName, event);
this.on(eventName, (...args) => event.run(...args));
this.util.signale.success(`Successfully loaded event: ${eventName}`);
delete require.cache[require.resolve(`${__dirname}/../events/${file}`)];
});
const evtFiles = Object.entries<new(client: Client) => Event>(eventFiles);
for (const [name, Ev] of evtFiles) {
const event = new Ev(this);
this.events.add(event.event, event);
this.on(event.event, event.run);
this.util.signale.success(`Successfully loaded event: ${name}`);
delete require.cache[require.resolve(`${__dirname}/../events/${name}`)];
}
}
public async loadCommands() {
const commandFiles = await fs.readdir(`${__dirname}/../commands`);
commandFiles.forEach((file) => {
// eslint-disable-next-line new-cap
const command: Command = new (require(`${__dirname}/../commands/${file}`).default)(this);
const cmdFiles = Object.values<new(client: Client) => Command>(commandFiles);
for (const Cmd of cmdFiles) {
const command = new Cmd(this);
this.commands.add(command.name, command);
this.util.signale.success(`Successfully loaded command: ${command.name}`);
});
}
}
}

14
src/class/Event.ts Normal file
View File

@ -0,0 +1,14 @@
import { Client } from '.';
export default class Event {
public client: Client
public event: string;
constructor(client: Client) {
this.client = client;
this.event = '';
}
public async run(...args: any[]): Promise<void> { return Promise.resolve(); }
}

View File

@ -124,8 +124,7 @@ export default class RichEmbed implements EmbedData {
* Sets the timestamp of this embed.
*/
setTimestamp(timestamp = new Date()) {
// eslint-disable-next-line no-restricted-globals
if (isNaN(timestamp.getTime())) throw new TypeError('Expecting ISO8601 (Date constructor)');
if (Number.isNaN(timestamp.getTime())) throw new TypeError('Expecting ISO8601 (Date constructor)');
this.timestamp = timestamp;
return this;
}

View File

@ -9,9 +9,9 @@ export default class Route {
public router: Router;
constructor(server: Server, options: { path: string, deprecated?: boolean, maintenance?: boolean }) {
constructor(server: Server) {
this.server = server;
this.conf = options;
this.conf = { path: '' };
this.router = Router();
}

View File

@ -31,10 +31,9 @@ export default class Server {
}
public async loadRoutes() {
const routes = await fs.readdir(`${this.root}`);
for (const routeFile of routes) {
// eslint-disable-next-line new-cap
const route: Route = new (require(`${this.root}/${routeFile}`).default)(this);
const routes = Object.values<typeof Route>(require(this.root));
for (const RouteFile of routes) {
const route = new RouteFile(this);
if (route.conf.deprecated) {
route.deprecated();
} else if (route.conf.maintenance) {

View File

@ -1,7 +1,5 @@
import express from 'express';
import { promises as fs } from 'fs';
import { Client, Collection, Server } from '.';
// import serverSetup from '../api/server';
import serverSetup from '../api';
export default class ServerManagement {
public client: Client;
@ -15,12 +13,9 @@ export default class ServerManagement {
}
public async loadServers() {
const apiRoot = await fs.readdir(`${__dirname}/../api`);
for (const api of apiRoot) {
// eslint-disable-next-line no-continue
if (api === 'server.js') continue;
const server: Server = require(`${__dirname}/../api/${api}/main.js`).default(this);
this.servers.add(api, server);
const apiRoot = Object.entries<(management: ServerManagement) => Server>(serverSetup);
for (const [api, server] of apiRoot) {
this.servers.add(api, server(this));
this.client.util.signale.success(`Successfully loaded server '${api}'.`);
}
}

View File

@ -37,8 +37,6 @@ export default class Util {
*/
public resolveCommand(query: string | string[]): Promise<{cmd: Command, args: string[] }> {
try {
// let resolvedCommand: Command;
// eslint-disable-next-line no-param-reassign
if (typeof query === 'string') query = query.split(' ');
const commands = this.client.commands.toArray();
const resolvedCommand = commands.find((c) => c.name === query[0].toLowerCase() || c.aliases.includes(query[0].toLowerCase()));
@ -91,7 +89,6 @@ export default class Util {
}
await this.client.createMessage('595788220764127272', info);
const msg = message ? message.content.slice(this.client.config.prefix.length).trim().split(/ +/g) : [];
// eslint-disable-next-line no-param-reassign
if (command && disable) this.resolveCommand(msg).then((c) => { c.cmd.enabled = false; });
if (message) message.channel.createMessage(`***${this.emojis.ERROR} An unexpected error has occured - please contact a Staff member.${command && disable ? ' This command has been disabled.' : ''}***`);
} catch (err) {
@ -101,7 +98,6 @@ export default class Util {
public splitString(string: string, length: number): string[] {
if (!string) return [];
// eslint-disable-next-line no-param-reassign
if (Array.isArray(string)) string = string.join('\n');
if (string.length <= length) return [string];
const arrayString: string[] = [];
@ -111,7 +107,6 @@ export default class Util {
pos = string.length > length ? string.lastIndexOf('\n', length) : string.length;
if (pos > length) pos = length;
str = string.substr(0, pos);
// eslint-disable-next-line no-param-reassign
string = string.substr(pos);
arrayString.push(str);
}

View File

@ -1,6 +1,7 @@
export { default as Client } from './Client';
export { default as Collection } from './Collection';
export { default as Command } from './Command';
export { default as Event } from './Event';
export { default as Moderation } from './Moderation';
export { default as RichEmbed } from './RichEmbed';
export { default as Route } from './Route';

View File

@ -23,10 +23,9 @@ export default class AddItem extends Command {
return message.channel.createMessage({ embed });
}
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
const account = await this.client.db.member.findOne({ userID: message.member.id });
const account = await this.client.db.Member.findOne({ userID: message.member.id });
if (!account) {
// eslint-disable-next-line new-cap
const newAccount = new this.client.db.member({
const newAccount = new this.client.db.Member({
userID: message.member.id,
additional: {
operatingSystems: [args[0].split('-')[1]],
@ -39,10 +38,9 @@ export default class AddItem extends Command {
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added OS code ${args[0]} to profile.***`);
}
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
const account = await this.client.db.member.findOne({ userID: message.member.id });
const account = await this.client.db.Member.findOne({ userID: message.member.id });
if (!account) {
// eslint-disable-next-line new-cap
const newAccount = new this.client.db.member({
const newAccount = new this.client.db.Member({
userID: message.member.id,
additional: {
langs: [args[0].split('-')[1]],

View File

@ -15,7 +15,7 @@ export default class AddRedirect extends Command {
public async run(message: Message, args: string[]) {
try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const check = await this.client.db.redirect.findOne({ key: args[1].toLowerCase() });
const check = await this.client.db.Redirect.findOne({ key: args[1].toLowerCase() });
if (check) return this.error(message.channel, `Redirect key ${args[1].toLowerCase()} already exists. Linked to: ${check.to}`);
try {
const test = new URL(args[0]);
@ -24,8 +24,7 @@ export default class AddRedirect extends Command {
return this.error(message.channel, 'This doesn\'t appear to be a valid URL.');
}
if ((/^[a-zA-Z0-9]+$/gi.test(args[1].toLowerCase().replace('-', '').trim()) === false) || args[1].toLowerCase().length > 15) return this.error(message.channel, 'Invalid key. The key must be alphanumeric and less than 16 characters.');
// eslint-disable-next-line new-cap
const redirect = new this.client.db.redirect({
const redirect = new this.client.db.Redirect({
key: args[1].toLowerCase(),
to: args[0],
});

View File

@ -23,7 +23,7 @@ export default class DelItem extends Command {
return message.channel.createMessage({ embed });
}
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
const account = await this.client.db.member.findOne({ userID: message.member.id });
const account = await this.client.db.Member.findOne({ userID: message.member.id });
if (!account || !account?.additional.operatingSystems || account?.additional.operatingSystems.length < 1) {
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any operating systems to remove.***`);
}
@ -31,7 +31,7 @@ export default class DelItem extends Command {
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed OS code ${args[0]} from profile.***`);
}
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
const account = await this.client.db.member.findOne({ userID: message.member.id });
const account = await this.client.db.Member.findOne({ userID: message.member.id });
if (!account || !account?.additional.langs || account?.additional.langs.length < 1) {
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any languages to remove.***`);
}

View File

@ -15,9 +15,9 @@ export default class DelRedirect extends Command {
public async run(message: Message, args: string[]) {
try {
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
const check = await this.client.db.redirect.findOne({ key: args[0].toLowerCase() });
const check = await this.client.db.Redirect.findOne({ key: args[0].toLowerCase() });
if (!check) return this.error(message.channel, `Redirect key ${args[0].toLowerCase()} doesn't exist.`);
await this.client.db.redirect.deleteOne({ key: args[0].toLowerCase() });
await this.client.db.Redirect.deleteOne({ key: args[0].toLowerCase() });
return this.success(message.channel, `Deleted redirect https://loc.sh/${args[0].toLowerCase()}.`);
} catch (err) {
return this.client.util.handleError(err, message, this);

View File

@ -47,13 +47,9 @@ export default class Game extends Command {
embed.setColor('#1ed760');
embed.addField('Song', mainStatus.details, true);
embed.addField('Artist', mainStatus.state, true);
// @ts-ignore
embed.addField('Album', mainStatus.assets.large_text);
// @ts-ignore
embed.addField('Start', `${new Date(mainStatus.timestamps.start).toLocaleTimeString('en-us')} ET`, true);
// @ts-ignore
embed.addField('End', `${new Date(mainStatus.timestamps.end).toLocaleTimeString('en-us')} ET`, true);
// @ts-ignore
embed.setThumbnail(`https://i.scdn.co/image/${mainStatus.assets.large_image.split(':')[1]}`);
embed.setFooter(`Listening to Spotify | ${this.client.user.username}`, 'https://media.discordapp.net/attachments/358674161566220288/496894273304920064/2000px-Spotify_logo_without_text.png');
embed.setTimestamp();

View File

@ -12,7 +12,6 @@ export default class Help extends Command {
this.enabled = true;
}
// eslint-disable-next-line consistent-return
public async run(message: Message, args: string[]) {
try {
if (args.length > 0) {
@ -110,7 +109,7 @@ export default class Help extends Command {
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
return createPaginationEmbed(message, cmdPages);
} catch (err) {
this.client.util.handleError(err, message, this, false);
return this.client.util.handleError(err, message, this, false);
}
}
}

17
src/commands/index.ts Normal file
View File

@ -0,0 +1,17 @@
export { default as additem } from './additem';
export { default as addredirect } from './addredirect';
export { default as ban } from './ban';
export { default as delitem } from './delitem';
export { default as delredirect } from './delredirect';
export { default as djs } from './djs';
export { default as eval } from './eval';
export { default as game } from './game';
export { default as help } from './help';
export { default as info } from './info';
export { default as kick } from './kick';
export { default as listredirects } from './listredirects';
export { default as npm } from './npm';
export { default as ping } from './ping';
export { default as roleinfo } from './roleinfo';
export { default as unban } from './unban';
export { default as whois } from './whois';

View File

@ -16,7 +16,7 @@ export default class DelRedirect extends Command {
public async run(message: Message, args: string[]) {
try {
if (args[0]) {
const redirects = await this.client.db.redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] });
const redirects = await this.client.db.Redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] });
if (redirects.length <= 0) return this.error(message.channel, 'Could not find an entry matching that query.');
const embed = new RichEmbed();
embed.setTitle('Redirect Information');
@ -27,7 +27,7 @@ export default class DelRedirect extends Command {
embed.setTimestamp();
return message.channel.createMessage({ embed });
}
const redirects = await this.client.db.redirect.find();
const redirects = await this.client.db.Redirect.find();
if (!redirects) return this.error(message.channel, 'No redirect links found.');
const redirectArray: [{ name: string, value: string }?] = [];
for (const redirect of redirects) {

View File

@ -34,8 +34,7 @@ export default class NPM extends Command {
license = data.license;
}
let dependencies: string = 'None';
// eslint-disable-next-line no-prototype-builtins
if (version !== 'Unknown' && data.versions[version].hasOwnProperty('dependencies') && Object.keys(data.versions[version].dependencies).length > 0) {
if (version !== 'Unknown' && data.versions[version].dependencies !== undefined && Object.keys(data.versions[version].dependencies).length > 0) {
dependencies = Object.keys(data.versions[version].dependencies).join(', ');
}
const name: string = data.name || 'None';

View File

@ -95,7 +95,7 @@ export default class Whois extends Command {
if ((bit | 1073741824) === bit) permissions.push('Manage Emojis');
if ((bit | 4) === bit) permissions.push('Ban Members');
if ((bit | 2) === bit) permissions.push('Kick Members');
const account = await this.client.db.member.findOne({ userID: member.id });
const account = await this.client.db.Member.findOne({ userID: member.id });
if (account?.additional?.langs.length > 0) {
const langs: string[] = [];
for (const lang of account.additional.langs.sort((a, b) => a.localeCompare(b))) {

View File

@ -1,12 +1,13 @@
/* eslint-disable no-useless-return */
import { Message, TextChannel, NewsChannel } from 'eris';
import { Client } from '../class';
import { Client, Event } from '../class';
export default class {
export default class CommandHandler extends Event {
public client: Client;
constructor(client: Client) {
this.client = client;
super(client);
this.event = 'messageCreate';
}
public async run(message: Message) {

2
src/events/index.ts Normal file
View File

@ -0,0 +1,2 @@
export { default as CommandHandler } from './CommandHandler';
export { default as ready } from './ready';

View File

@ -1,10 +1,11 @@
import { Client } from '../class';
import { Client, Event } from '../class';
export default class {
export default class Ready extends Event {
public client: Client;
constructor(client: Client) {
this.client = client;
super(client);
this.event = 'ready';
}
public async run() {

View File

@ -5,7 +5,7 @@ let interval: NodeJS.Timeout;
export default function checkLock(client: Client): NodeJS.Timeout {
interval = setInterval(async () => {
try {
const moderations = await client.db.moderation.find();
const moderations = await client.db.Moderation.find();
moderations.forEach(async (moderation) => {
if (!moderation.expiration) return;
if (moderation.expiration.processed) return;

View File

@ -5,6 +5,11 @@ export interface RedirectInterface extends Document {
to: string,
}
export interface RedirectRaw {
key: string,
to: string,
}
const Redirect: Schema = new Schema({
key: String,
to: String,

View File

@ -1,3 +1,3 @@
export { default as Member, MemberInterface } from './Member';
export { default as Moderation, ModerationInterface } from './Moderation';
export { default as Redirect, RedirectInterface } from './Redirect';
export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect';