import Stripe from 'stripe'; import eris from 'eris'; import pluris from 'pluris'; import mongoose from 'mongoose'; import { promises as fs } from 'fs'; import { Collection, Command, InteractionCommand, LocalStorage, Queue, Util, ServerManagement, Event } from '.'; import { Customer, CustomerInterface, CustomerPortal, CustomerPortalInterface, ExecutiveOrder, ExecutiveOrderInterface, File, FileInterface, Inquiry, InquiryInterface, Judgement, JudgementInterface, Member, MemberInterface, Merchant, MerchantInterface, Moderation, ModerationInterface, Motion, MotionInterface, Note, NoteInterface, PagerNumber, PagerNumberInterface, Proclamation, ProclamationInterface, Promo, PromoInterface, Rank, RankInterface, Redirect, RedirectInterface, Resolution, ResolutionInterface, SAA, SAAInterface, Score, ScoreInterface, ScoreHistorical, ScoreHistoricalInterface, Staff, StaffInterface, Stat, StatInterface, } from '../models'; import { Config } from '../../types'; // eslint-disable-line pluris(eris, { endpoints: false }); export default class Client extends eris.Client { public config: Config; public commands: Collection; public interactions: Collection; public events: Collection; // eslint-disable-next-line no-undef public intervals: Collection; public util: Util; public serverManagement: ServerManagement; public queue: Queue; public stripe: Stripe; public db: { Customer: mongoose.Model, CustomerPortal: mongoose.Model, ExecutiveOrder: mongoose.Model, File: mongoose.Model, Inquiry: mongoose.Model, Judgement: mongoose.Model, Member: mongoose.Model, Merchant: mongoose.Model, Moderation: mongoose.Model, Motion: mongoose.Model, Note: mongoose.Model, PagerNumber: mongoose.Model, Proclamation: mongoose.Model, Promo: mongoose.Model, Rank: mongoose.Model, Redirect: mongoose.Model, Resolution: mongoose.Model, SAA: mongoose.Model, Score: mongoose.Model, ScoreHistorical: mongoose.Model, Staff: mongoose.Model, Stat: mongoose.Model, local: { muted: LocalStorage } }; constructor(token: string, options?: eris.ClientOptions) { super(token, options); this.commands = new Collection(); this.interactions = new Collection(); this.events = new Collection(); // eslint-disable-next-line no-undef this.intervals = new Collection(); this.queue = new Queue(this); this.db = { Customer, CustomerPortal, ExecutiveOrder, File, Inquiry, Judgement, Member, Merchant, Moderation, Motion, Note, PagerNumber, Promo, Proclamation, Rank, Redirect, Resolution, SAA, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') }, }; } get report() { return this.util.report; } get pbx() { return this.util.pbx; } public async loadDatabase() { mongoose.connect(this.config.mongoDB, { minPoolSize: 50, }); const statMessages = await this.db.Stat.findOne({ name: 'messages' }); const statCommands = await this.db.Stat.findOne({ name: 'commands' }); const statPages = await this.db.Stat.findOne({ name: 'pages' }); const statRequests = await this.db.Stat.findOne({ name: 'requests' }); if (!statMessages) { await (new this.db.Stat({ name: 'messages', value: 0 }).save()); } if (!statCommands) { await (new this.db.Stat({ name: 'commands', value: 0 }).save()); } if (!statPages) { await (new this.db.Stat({ name: 'pages', value: 0 }).save()); } if (!statRequests) { await (new this.db.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) { const evtFiles = Object.entries(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) { const cmdFiles = Object.values(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) { const intFiles = Object.values(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.application_id, interaction); this.util.signale.success(`Successfully loaded interaction: ${interaction.name}`); } } }