forked from noxious/server
58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
import * as fs from 'fs'
|
|
import * as path from 'path'
|
|
import { pathToFileURL } from 'url'
|
|
|
|
import Logger, { LoggerType } from '#application/logger'
|
|
import Storage from '#application/storage'
|
|
import { Command } from '#application/types'
|
|
|
|
export class CommandRegistry {
|
|
private readonly commands: Map<string, Command> = new Map()
|
|
private readonly logger = Logger.type(LoggerType.COMMAND)
|
|
|
|
public getCommand(name: string): Command | undefined {
|
|
return this.commands.get(name)
|
|
}
|
|
|
|
public async loadCommands(): Promise<void> {
|
|
const directory = Storage.getAppPath('commands')
|
|
this.logger.info(`Loading commands from: ${directory}`)
|
|
|
|
try {
|
|
const files = await fs.promises.readdir(directory, { withFileTypes: true })
|
|
await Promise.all(files.filter((file) => this.isValidCommandFile(file)).map((file) => this.loadCommandFile(file)))
|
|
} catch (error) {
|
|
this.logger.error(`Failed to read commands directory: ${error instanceof Error ? error.message : String(error)}`)
|
|
}
|
|
}
|
|
|
|
private isValidCommandFile(file: fs.Dirent): boolean {
|
|
return file.isFile() && (file.name.endsWith('.ts') || file.name.endsWith('.js'))
|
|
}
|
|
|
|
private async loadCommandFile(file: fs.Dirent): Promise<void> {
|
|
try {
|
|
const filePath = Storage.getAppPath('commands', file.name)
|
|
const commandName = path.basename(file.name, path.extname(file.name))
|
|
|
|
const module = await import(pathToFileURL(filePath).href)
|
|
if (typeof module.default !== 'function') {
|
|
this.logger.warn(`Unrecognized export in ${file.name}`)
|
|
return
|
|
}
|
|
|
|
this.registerCommand(commandName, module.default)
|
|
} catch (error) {
|
|
this.logger.error(`Error loading command ${file.name}: ${error instanceof Error ? error.message : String(error)}`)
|
|
}
|
|
}
|
|
|
|
private registerCommand(name: string, CommandClass: Command): void {
|
|
if (this.commands.has(name)) {
|
|
this.logger.warn(`Command '${name}' is already registered. Overwriting...`)
|
|
}
|
|
this.commands.set(name, CommandClass)
|
|
this.logger.info(`Registered command: ${name}`)
|
|
}
|
|
}
|