UNPKG

rashi-discord-bot-lib

Version:

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

185 lines • 8.12 kB
"use strict"; // src/core/BotStarter.ts 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 MusicManager_1 = require("../music/MusicManager"); const music_1 = require("../utils/music"); 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; musicManager; async start(client, options) { try { 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); 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); 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); if (options.Music?.enable) { try { this.musicManager = new MusicManager_1.MusicManager(client, options.Music, this.logger); await this.musicManager.init?.(); (0, music_1.setMusic)(this.musicManager); } catch (e) { this.logger.error('Failed to init MusicManager:', e); } } await (0, update_1.checkUpdate)('rashi-discord-bot-lib', localVersion, options.bot.logs?.updates?.webhookURL, options.bot.logs?.updates?.mentionId ?? options.bot.BotInfo?.ownerId ?? ''); 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); if (this.musicManager) this.updateMusicStats(); await this.displayComprehensiveStats(client, options.bot, versedb); return { client, versedb, mongodb, slashSize, prefixSize, eventSize, getDb: mongodb ? () => mongodb : undefined, db: versedb, statistics: this.statistics, music: this.musicManager, }; } catch (error) { this.statistics.trackError(); this.logger.error('Failed to start bot:', error); throw error; } } 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); } updateMusicStats() { if (!this.musicManager) return; this.statistics.setMusicStats?.({ enabled: true }); } 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...'); if (this.musicManager) { try { await this.musicManager.destroy?.(); } catch { } (0, music_1.setMusic)(null); } (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