refactor: implement command class structure for better organization and error handling; update existing commands to extend from the new base class

This commit is contained in:
2025-03-25 11:17:26 -04:00
parent 69dc616668
commit 5bc0d98334
9 changed files with 351 additions and 244 deletions
+30 -10
View File
@@ -1,6 +1,19 @@
import { readdirSync } from 'node:fs';
import { join } from 'node:path';
/**
* Asynchronously loads all command modules from a directory
* @async
* @param {string} commandsPath - Path to the commands directory
* @param {Logger} logger - Logger instance for logging loading progress
* @returns {Promise<Array<Object>>} Array of command objects with:
* @property {SlashCommandBuilder} data - Command definition
* @property {Function} execute - Command execution function
* @throws {TypeError} If commandsPath is not a string
* @example
* // Load all commands from './commands'
* const commands = await loadCommands('./commands', logger);
*/
export async function loadCommands(commandsPath, logger) {
const commands = [];
const commandFiles = readdirSync(commandsPath).filter(file => file.endsWith('.js'));
@@ -10,21 +23,28 @@ export async function loadCommands(commandsPath, logger) {
try {
const filePath = join(commandsPath, file);
const commandModule = await import(filePath);
const command = commandModule.default;
const Command = commandModule.default;
if (!command?.data || !command?.execute) {
logger.warn(
`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`
);
const CommandBase = (await import('./Command.js')).default;
if (Command.prototype instanceof CommandBase) {
// New style - class extending Command
const commandInstance = new Command();
// Wrap run() in execute() for backward compatibility
commandInstance.execute = commandInstance.run.bind(commandInstance);
commands.push(commandInstance);
logger.log(`Loaded command: ${commandInstance.data.name}`);
} else if (Command?.data && Command?.execute) {
// Old style - plain object (maintain backward compatibility)
commands.push(Command);
logger.log(`Loaded command: ${Command.data.name}`);
} else {
logger.warn(`[WARNING] The command at ${filePath} is missing required properties.`);
return;
}
commands.push(command);
logger.log(`Loaded command: ${command.data.name}`);
} catch (error) {
logger.error(`Error loading command from ${file}:`, error);
logger.error(`Error loading command from ${file}: ${error.stack}`);
}
})
}),
);
return commands;