UNPKG

rashi-discord-bot-lib

Version:

🚀 Powerful Discord bot framework with built-in database, event handling, and utilities

161 lines • 6.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BotStarter = void 0; const update_1 = require("../utils/update"); const EventLoader_1 = require("./EventLoader"); const CommandLoader_1 = require("./CommandLoader"); const DatabaseManager_1 = require("./DatabaseManager"); const Logger_1 = require("../utils/Logger"); const FileWatcher_1 = require("../utils/FileWatcher"); const mongo_1 = require("../utils/mongo"); const BotStatistics_1 = require("../utils/BotStatistics"); const commandGuards_1 = require("../utils/commandGuards"); const MongoCooldownManager_1 = require("../utils/MongoCooldownManager"); const i18n_1 = require("../i18n"); const verse_1 = require("../utils/verse"); const { version: localVersion } = require("../../package.json"); class BotStarter { logger = new Logger_1.Logger(); eventLoader = new EventLoader_1.EventLoader(this.logger); commandLoader = new CommandLoader_1.CommandLoader(this.logger); databaseManager = new DatabaseManager_1.DatabaseManager(this.logger); statistics = new BotStatistics_1.BotStatistics(this.logger); fileWatcher; async start(client, options) { this.validateOptions(options); await (0, i18n_1.initializeI18n)(); if (options.bot.logs?.terminal) this.logger.enableTerminalLogs(); if (options.bot.logs?.devLogs?.enable) await this.setupDevLogs(options.bot.logs.devLogs); const { versedb, mongodb } = await this.databaseManager.initialize(options.bot.Database); if (versedb) (0, verse_1.setVerseDb)(versedb); if (mongodb) (0, mongo_1.setDb)(mongodb); // --- Cooldowns --- let cooldowns; if (mongodb) { const mongoManager = new MongoCooldownManager_1.MongoCooldownManager("cooldowns"); await mongoManager.connect(); cooldowns = mongoManager; } else if (versedb) { cooldowns = new commandGuards_1.CooldownManager({ type: "verse", instance: versedb }); } else { throw new Error("No valid cooldown backend found (VerseDB or MongoDB required)."); } if ("connect" in cooldowns && typeof cooldowns.connect === "function") { await cooldowns.connect(); } this.commandLoader.setCooldowns(cooldowns); // --- Load Events & Commands --- const eventSize = await this.eventLoader.loadEvents(client, options.events.path, options.events.recursive || false, options.events.eventBlacklist || []); const { slashSize, prefixSize } = await this.commandLoader.loadCommands(client, options.commands); this.statistics.setLoadedEvents(eventSize); this.statistics.setLoadedCommands(slashSize, prefixSize); this.statistics.initialize(client); this.commandLoader.setStatistics(this.statistics); if (options.anticrash?.enable) this.setupAntiCrash(options.anticrash); await this.loginBot(client, options.bot.token); if (options.bot.BotInfo) await this.setupBotInfo(client, options.bot.BotInfo); await (0, update_1.checkUpdate)("rashi-discord-bot-lib", localVersion, options.bot.logs?.updates?.webhookURL, options.bot.logs?.updates?.mentionId ?? options.bot.BotInfo?.ownerId ?? ""); // --- Database stats --- const stores = []; let singleDbStats; if (versedb) { const stats = await versedb.getStats().catch(() => null); if (stats) { singleDbStats = { adapter: stats.adapter, keys: stats.keys, size: stats.size, }; stores.push({ name: "VerseDB", status: "connected", ...stats }); } } if (mongodb) { let info; try { const cols = await mongodb.listCollections().toArray(); info = `collections: ${cols.length}`; } catch { } stores.push({ name: "MongoDB", adapter: "mongo", status: "connected", info, }); if (!singleDbStats) singleDbStats = { adapter: "mongo", keys: 0 }; } if (singleDbStats) this.statistics.setDatabaseStats(singleDbStats); this.statistics.setDatabaseStores(stores); await this.displayComprehensiveStats(client, options.bot, versedb); return { client, versedb, mongodb, slashSize, prefixSize, eventSize, getDb: mongodb ? () => mongodb : undefined, db: versedb, statistics: this.statistics, }; } validateOptions(options) { if (!options.bot?.token) throw new Error("Bot token is required"); if (!options.events?.path) throw new Error("Events path is required"); if (!options.bot.Database) throw new Error("Database configuration is required"); } async setupDevLogs(devLogs) { if (!devLogs.pathToWatch || !devLogs.webhookURL) throw new Error("Development logs require pathToWatch and webhookURL"); this.fileWatcher = new FileWatcher_1.FileWatcher(devLogs.pathToWatch, devLogs.webhookURL, devLogs.mention, this.logger); await this.fileWatcher.start(); } async loginBot(client, token) { await client.login(token); } async displayComprehensiveStats(client, botOptions, versedb) { const statsOptions = { BotInfo: botOptions.BotInfo }; await this.statistics.loadDatabaseStatsFrom(versedb); await this.statistics.generateTableStats(client, statsOptions); } async setupBotInfo(client, info) { this.logger.info(`Bot info setup: ${info?.ownerId ?? "Brak właściciela"}`); } setupAntiCrash(anticrash) { process.on("unhandledRejection", async (reason, promise) => { this.statistics.trackError(); this.logger.error("Unhandled Rejection at:", { promise, reason }); }); process.on("uncaughtException", async (error) => { this.statistics.trackError(); this.logger.error("Uncaught Exception:", error); }); this.logger.info("Anti-crash protection enabled"); } async shutdown() { this.logger.info("Gracefully shutting down..."); (0, mongo_1.setDb)(null); if (this.fileWatcher) await this.fileWatcher.stop(); await this.databaseManager.disconnect(); this.logger.info("Shutdown complete"); } getStatistics() { return this.statistics; } } exports.BotStarter = BotStarter; //# sourceMappingURL=BotStarter.js.map