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:
+30
-10
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user