community-relations/src/class/Client.ts

163 lines
5.4 KiB
TypeScript

import Stripe from 'stripe';
import Redis from 'ioredis';
import eris from 'eris';
import pluris from 'pluris';
import mongoose from 'mongoose';
import { promises as fs } from 'fs';
import Database from 'cr-db';
import * as Sentry from '@sentry/node';
import * as Tracing from '@sentry/tracing';
import { Collection, Command, InteractionCommand, LocalStorage, Queue, Util, ServerManagement, Event } from '.';
import { Config } from '../../types'; // eslint-disable-line
// @ts-ignore
pluris(eris, { endpoints: false });
export default class Client extends eris.Client {
public config: Config;
public commands: Collection<Command>;
public interactions: Collection<InteractionCommand>;
public events: Collection<Event>;
// eslint-disable-next-line no-undef
public intervals: Collection<NodeJS.Timeout>;
public util: Util;
public serverManagement: ServerManagement;
public queue: Queue;
public stripe: Stripe;
public db: {
mongo: typeof Database.MongoDBModels,
maria: null,
redis: Redis.Redis,
local: { muted: LocalStorage },
};
constructor(token: string, options?: eris.ClientOptions) {
super(token, options);
this.setupSentry();
this.commands = new Collection<Command>();
this.interactions = new Collection<InteractionCommand>();
this.events = new Collection<Event>();
// eslint-disable-next-line no-undef
this.intervals = new Collection<NodeJS.Timeout>();
this.queue = new Queue(this);
this.db = {
mongo: Database.MongoDBModels,
redis: new Redis(),
local: {
muted: new LocalStorage('muted'),
},
maria: null,
};
}
get report() {
return this.util.report;
}
get pbx() {
return this.util.pbx;
}
public setupSentry() {
Sentry.init({
dsn: 'https://323f6626a7104be7859088750b91abe1@sentry.libraryofcode.org/2',
tracesSampleRate: 0.25,
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
],
});
Tracing.addExtensionMethods();
}
public async loadDatabase() {
mongoose.connect(this.config.mongoDB, {
minPoolSize: 50,
});
const statMessages = await this.db.mongo.Stat.findOne({ name: 'messages' });
const statCommands = await this.db.mongo.Stat.findOne({ name: 'commands' });
const statPages = await this.db.mongo.Stat.findOne({ name: 'pages' });
const statRequests = await this.db.mongo.Stat.findOne({ name: 'requests' });
if (!statMessages) {
await (new this.db.mongo.Stat({ name: 'messages', value: 0 }).save());
}
if (!statCommands) {
await (new this.db.mongo.Stat({ name: 'commands', value: 0 }).save());
}
if (!statPages) {
await (new this.db.mongo.Stat({ name: 'pages', value: 0 }).save());
}
if (!statRequests) {
await (new this.db.mongo.Stat({ name: 'requests', value: 0 }).save());
}
}
public loadPlugins() {
this.util = new Util(this);
this.serverManagement = new ServerManagement(this);
this.stripe = new Stripe(this.config.stripeKey, { apiVersion: null, typescript: true });
}
public async loadIntervals() {
const intervalFiles = await fs.readdir(`${__dirname}/../intervals`);
intervalFiles.forEach((file) => {
const intervalName = file.split('.')[0];
if (file === 'index.js') return;
// eslint-disable-next-line no-undef
const interval: NodeJS.Timeout = (require(`${__dirname}/../intervals/${file}`).default)(this);
this.intervals.add(intervalName, interval);
this.util.signale.success(`Successfully loaded interval: ${intervalName}`);
});
}
public async loadEvents(eventFiles: { [s: string]: typeof Event; } | ArrayLike<typeof Event>) {
const evtFiles = Object.entries<typeof 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(commandFiles: { [s: string]: typeof Command; } | ArrayLike<typeof Command>) {
const cmdFiles = Object.values<typeof Command>(commandFiles);
for (const Cmd of cmdFiles) {
const command = new Cmd(this);
if (command.subcmds.length) {
command.subcmds.forEach((C) => {
const cmd: Command = new C(this);
command.subcommands.add(cmd.name, cmd);
this.util.signale.success(`Successfully loaded subcommand ${cmd.name} under ${command.name}`);
});
}
delete command.subcmds;
this.commands.add(command.name, command);
this.util.signale.success(`Successfully loaded command: ${command.name}`);
}
}
public async loadInteractions(interactionFiles: { [s: string]: typeof InteractionCommand; } | ArrayLike<typeof InteractionCommand>) {
const intFiles = Object.values<typeof InteractionCommand>(interactionFiles);
for (const Int of intFiles) {
const interaction = new Int(this);
// eslint-disable-next-line no-await-in-loop
const c = await this.createGuildCommand(this.config.guildID, interaction.serializeData());
this.interactions.add(c.id, interaction);
this.util.signale.success(`Successfully loaded interaction: ${interaction.name}`);
}
}
}