UNPKG

@botport/core

Version:

Unified framework for Discord bot products, published by BotPort.

98 lines (83 loc) 2.95 kB
import path from 'path'; import * as fs from 'fs'; import {pathToFileURL} from 'url'; import logger from '../logger/logger.js'; import {parseInfoFile} from '../utils/fileUtils.js'; import {loadAddons, isDebug, getProjectDirectory} from '../config/environment.js'; export async function loadAddonsIfEnabled(client) { if (!loadAddons) { logger.debug('Addon loading is disabled (ADDONS=false)'); return; } logger.info('🔄 Loading addons...'); const projectDir = getProjectDirectory(); const addonsRoot = path.join(projectDir, '..', '..', '..', 'src', 'addons'); if (!fs.existsSync(addonsRoot)) { return; } const addonDirs = fs .readdirSync(addonsRoot, {withFileTypes: true}) .filter(d => d.isDirectory()) .map(d => d.name); if (addonDirs.length === 0) { logger.info('No addon directories found in src/addons folder'); return; } let addonsLoaded = 0; for (const dirName of addonDirs) { const success = await loadSingleAddon(client, addonsRoot, dirName); if (success) { addonsLoaded++; } } if (addonsLoaded > 0) { logger.success(`🎉 Successfully loaded ${addonsLoaded} addon(s)`); } else { logger.info('No addons were loaded'); } } async function loadSingleAddon(client, addonsRoot, dirName) { const dirPath = path.join(addonsRoot, dirName); const infoPath = path.join(dirPath, 'addon.info'); if (!fs.existsSync(infoPath)) { logger.debug(`Skipping ${dirName}: no addon.info file found`); return false; } const info = parseInfoFile(infoPath); if (!info) { logger.error(`Failed to parse addon.info for ${dirName}`); return false; } if (info.type && info.type.toLowerCase() !== 'addon') { logger.debug(`Skipping ${dirName}: type is '${info.type}', not 'addon'`); return false; } if (!info.mainfile) { logger.error(`Addon "${dirName}" is missing 'mainfile' field in addon.info`); return false; } const addonFilePath = path.join(dirPath, info.mainfile); if (!fs.existsSync(addonFilePath)) { logger.error(`Main file for addon "${dirName}" not found at ${info.mainfile}`); return false; } logger.debug(`Loading addon: ${info.name || dirName} v${info.version || '1.0'}`); try { const addon = await import(pathToFileURL(addonFilePath).href); if (addon.default && typeof addon.default.execute === 'function') { await addon.default.execute(client); logger.success(`Loaded addon: ${info.name || dirName} v${info.version || '1.0'}`); return true; } else { logger.error(`⛔ Failed to initialize addon ${dirName}: missing default export or execute function`); return false; } } catch (err) { const error = err instanceof Error ? err : new Error(String(err)); logger.error(`❌ Error loading addon ${dirName}:`, error.message); if (isDebug) { logger.debug(`Full error details: ${error.stack}`); } return false; } }