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, LocalStorage, Queue, Util, ServerManagement, Event } from '.'; import { Customer, CustomerInterface, CustomerPortal, CustomerPortalInterface, File, FileInterface, Inquiry, InquiryInterface, Member, MemberInterface, Merchant, MerchantInterface, Moderation, ModerationInterface, NNTrainingData, NNTrainingDataInterface, Note, NoteInterface, PagerNumber, PagerNumberInterface, Promo, PromoInterface, Rank, RankInterface, Redirect, RedirectInterface, Score, ScoreInterface, ScoreHistorical, ScoreHistoricalInterface, Staff, StaffInterface, Stat, StatInterface, } from '../models'; import { Config } from '../../types'; // eslint-disable-line pluris(eris); export default class Client extends eris.Client { public config: Config; public commands: Collection; public events: Collection; public intervals: Collection; public util: Util; public serverManagement: ServerManagement; public queue: Queue; public stripe: Stripe; public db: { Customer: mongoose.Model, CustomerPortal: mongoose.Model, File: mongoose.Model, Inquiry: mongoose.Model, Member: mongoose.Model, Merchant: mongoose.Model, Moderation: mongoose.Model, NNTrainingData: mongoose.Model, Note: mongoose.Model, PagerNumber: mongoose.Model, Promo: mongoose.Model, Rank: mongoose.Model, Redirect: 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.events = new Collection(); this.intervals = new Collection(); this.queue = new Queue(this); this.db = { Customer, CustomerPortal, File, Inquiry, Member, Merchant, Moderation, NNTrainingData, Note, PagerNumber, Promo, Rank, Redirect, Score, ScoreHistorical, Staff, Stat, local: { muted: new LocalStorage('muted') } }; } get report() { return this.util.report; } get pbx() { return this.util.pbx; } public async loadDatabase() { await mongoose.connect(this.config.mongoDB, { useNewUrlParser: true, useUnifiedTopology: true, poolSize: 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; 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}`); } } }