@shadow-dev/core
Version:
A modular core framework for Discord bot development, providing commands, buttons, menus, middleware, and more.
73 lines (60 loc) • 2.13 kB
text/typescript
import fs from "fs";
import path from "path";
import { glob } from "glob";
import { importFile } from "../util";
import { Bot } from "../bot";
import { Plugin, metadata } from "./plugin";
export class PluginLoader {
private baseDir: string;
private pluginDir: string;
private ext: "ts" | "js";
private debug: boolean;
private bot: Bot;
constructor(bot: Bot) {
this.bot = bot;
this.baseDir = process.cwd();
this.debug = bot.debug;
const isDev = fs.existsSync(path.join(this.baseDir, "src/plugins"));
this.pluginDir = isDev ? "src/plugins" : "dist/plugins";
this.ext = isDev ? "ts" : "js";
if (this.debug) {
console.log("🟢 PluginLoader initialized.");
console.log("🗂 Plugin directory:", this.pluginDir);
}
}
public async registerPlugins() {
if (this.debug) console.log("🔍 Scanning for plugins...");
const pluginFiles = await glob(`*/index.${this.ext}`, {
cwd: path.join(this.baseDir, this.pluginDir),
absolute: true,
});
for (const filePath of pluginFiles) {
const pluginDirPath = path.dirname(filePath);
const pluginJsonPath = path.join(pluginDirPath, "plugin.json");
let meta: metadata = {} as metadata;
if (fs.existsSync(pluginJsonPath)) {
try {
const raw = fs.readFileSync(pluginJsonPath, "utf-8");
meta = JSON.parse(raw);
} catch (err) {
console.warn(`⚠️ Failed to parse plugin.json in ${pluginDirPath}`, err);
}
}
try {
const pluginModule: Plugin = await importFile(filePath);
if (pluginModule?.register) {
pluginModule.metadata = meta;
pluginModule.register(this.bot.client);
if (this.debug) {
console.log(`✅ Loaded plugin: ${meta.name ?? filePath}`);
}
} else {
console.warn(`⚠️ Skipped plugin at ${filePath} — no register() found`);
}
} catch (err) {
console.error(`❌ Error loading plugin at ${filePath}:`, err);
}
}
if (this.debug) console.log("✅ Plugin registration complete.");
}
}