diff --git a/src/providers/App.ts b/src/providers/App.ts new file mode 100644 index 0000000..81c320c --- /dev/null +++ b/src/providers/App.ts @@ -0,0 +1,27 @@ +import Logger from '../libs/Logger'; + +import Environment from './Environment'; +import Prisma from './Prisma'; +import Discord from './Discord'; + +class App { + + public readonly version = '0.01'; + + public loadENV(): void { + Logger.log('info', 'Loading environment'); + Environment.init(); + } + + public loadPrisma(): void { + Logger.log('info', 'Loading Prisma'); + Prisma.init(); + } + + public loadDiscord(): void { + Logger.log('info', 'Loading Discord Client'); + Discord.init(); + } +} + +export default new App; \ No newline at end of file diff --git a/src/providers/Discord.ts b/src/providers/Discord.ts new file mode 100644 index 0000000..b3a76ba --- /dev/null +++ b/src/providers/Discord.ts @@ -0,0 +1,89 @@ +import {Client, Intents, TextChannel} from "discord.js"; + +import Logger from "../libs/Logger"; +import Environment from "./Environment"; + +import Discord_Core from "../discord/core"; +import Discord_Ping from "../discord/ping"; +import Cache from "./Cache"; + +class Discord { + + public client: Client; + private loaded_module: any; + + constructor () { + this.client = new Client({ + partials: ['MESSAGE', 'CHANNEL', 'REACTION'], + intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] + }); + this.loaded_module = {}; + } + + public init(): void { + Logger.info('Logging in to discord'); + this.client.login(Environment.get().DISCORD_TOKEN); + + this.loaded_module["Core"] = new Discord_Core(); + this.loaded_module["Ping"] = new Discord_Ping(); + + for(const module in this.loaded_module) { + let thisModule = this.loaded_module[module]; + + if (typeof thisModule.init === "function") + thisModule.init(); + } + + this.client.on("ready", () => { + for(const module in this.loaded_module) { + let thisModule = this.loaded_module[module]; + + if (typeof thisModule.ready === "function") + thisModule.ready(); + } + }); + + this.client.on("messageCreate", message => { + for(const module in this.loaded_module) { + let thisModule = this.loaded_module[module]; + + if (typeof thisModule.messageCreate === "function") + thisModule.messageCreate(message); + } + }); + + // Handling commands + this.client.on("messageCreate", async (message) => { + + // TODO: Handle DMs commands soon + if(!(message.channel instanceof TextChannel)) return; + if(message.author.bot) return; + + if(typeof message.guild?.id === 'undefined') return; + + let GuildCache = await Cache.getGuild(message.guild.id); + if(typeof GuildCache === 'undefined' || typeof GuildCache.prefix === 'undefined') return; + + if(!message.content.startsWith(GuildCache.prefix)) return; + + let args = message.content.split(" "); + let command = args[0].replace(GuildCache.prefix, ''); + args.shift(); + args = args.filter(e => e !== ''); + + if(args.length === 0) + args = []; + + for(const module in this.loaded_module) { + let thisModule = this.loaded_module[module]; + + if (typeof thisModule.onCommand === "function") + thisModule.onCommand(command, args, message); + } + }); + + } + +} + +export default new Discord(); diff --git a/src/providers/Environment.ts b/src/providers/Environment.ts new file mode 100644 index 0000000..cc5f039 --- /dev/null +++ b/src/providers/Environment.ts @@ -0,0 +1,60 @@ +import * as path from "path"; +import * as dotenv from "dotenv"; + +import Validator from "validator"; + +import Logger from "../libs/Logger"; + +const requiredENV = [ + 'NODE_ENV', + 'DISCORD_TOKEN' +]; + +class Environment { + + public init(): void { + dotenv.config({ path: path.resolve(__dirname, "../../.env") }); + + for (let param of requiredENV) { + if (this.isUndefinedOrEmpty(process.env[param])) + throw new Error(`.env ${param} is undefined`); + } + + // NODE_ENV Checks + if (this.get().NODE_ENV != "production" && this.get().NODE_ENV != "development") + throw new Error('.env NODE_ENV must be either "production" or "development"'); + + // TODO: Discord token check + + Logger.log('info', `Running in ${process.env.NODE_ENV} environment`); + } + + public get(): any { + + const NODE_ENV = process.env.NODE_ENV; + + const DISCORD_TOKEN = process.env.DISCORD_TOKEN; + + return { + NODE_ENV, + + DISCORD_TOKEN + }; + } + + private isUndefinedOrEmpty(value: String | undefined): boolean { + if(typeof value === 'undefined') + return true; + + if(value === undefined) + return true; + + if(value === '') + return true; + + return false; + } + +} + +export default new Environment(); diff --git a/src/providers/Prisma.ts b/src/providers/Prisma.ts new file mode 100644 index 0000000..5212871 --- /dev/null +++ b/src/providers/Prisma.ts @@ -0,0 +1,21 @@ +import { PrismaClient } from '@prisma/client'; + +class Prisma { + + public client: PrismaClient; + + constructor () { + this.client = new PrismaClient; + } + + public init(): void { + this.client = new PrismaClient(); + } + + public end(): void { + this.client.$disconnect(); + } + +} + +export default new Prisma(); \ No newline at end of file