makecord-create
Version:
Create advanced Discord Bots with Makecord - Now with TypeScript support
116 lines (95 loc) • 3.83 kB
JavaScript
import chokidar from 'chokidar';
import { fileURLToPath } from 'url';
import path from 'path';
import fs from 'fs';
import chalk from 'chalk';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export class CommandWatcher {
constructor(client) {
this.client = client;
this.commandsPath = path.join(__dirname, '..', 'commands');
this.watcher = null;
}
start() {
console.log(chalk.yellow('Starting command hot-reload watcher...'));
this.watcher = chokidar.watch(this.commandsPath, {
ignored: /(^|[\/\\])\../, // ignore dotfiles
persistent: true
});
// Add event listeners
this.watcher
.on('add', path => this.handleCommandAdd(path))
.on('change', path => this.handleCommandChange(path))
.on('unlink', path => this.handleCommandRemove(path));
console.log(chalk.green('Hot-reload watcher started successfully!'));
}
async handleCommandAdd(filePath) {
if (!filePath.endsWith('.js')) return;
try {
const command = await this.importCommand(filePath);
if (!command) return;
await this.registerCommand(command);
console.log(chalk.green(`Command added: ${path.basename(filePath, '.js')}`));
} catch (error) {
console.error(chalk.red(`Error adding command ${filePath}:`, error));
}
}
async handleCommandChange(filePath) {
if (!filePath.endsWith('.js')) return;
try {
// Clear require cache
const resolvedPath = path.resolve(filePath);
delete require.cache[resolvedPath];
const command = await this.importCommand(filePath);
if (!command) return;
// Remove old command
this.client.commands.delete(command.data.name);
// Add new command
await this.registerCommand(command);
console.log(chalk.yellow(`Command reloaded: ${path.basename(filePath, '.js')}`));
} catch (error) {
console.error(chalk.red(`Error reloading command ${filePath}:`, error));
}
}
handleCommandRemove(filePath) {
if (!filePath.endsWith('.js')) return;
try {
const commandName = path.basename(filePath, '.js');
this.client.commands.delete(commandName);
console.log(chalk.red(`Command removed: ${commandName}`));
} catch (error) {
console.error(chalk.red(`Error removing command ${filePath}:`, error));
}
}
async importCommand(filePath) {
try {
const command = await import(`file://${filePath}`);
return command.default;
} catch (error) {
console.error(chalk.red(`Error importing command ${filePath}:`, error));
return null;
}
}
async registerCommand(command) {
if (!command.data || !command.execute) {
console.error(chalk.red('Invalid command format'));
return;
}
this.client.commands.set(command.data.name, command);
// Register with Discord API if in development mode
if (process.env.NODE_ENV === 'development') {
try {
await this.client.application.commands.create(command.data.toJSON());
} catch (error) {
console.error(chalk.red('Error registering command with Discord:', error));
}
}
}
stop() {
if (this.watcher) {
this.watcher.close();
console.log(chalk.yellow('Hot-reload watcher stopped'));
}
}
}