import chalk from 'chalk'; import * as commandHelper from '../utils/command'; import path from 'path'; import type { CommandModule } from '../command-types'; interface CommandInfo { name: string; description: string; path: string; } function compare(a: CommandInfo, b: CommandInfo): number { if (a.name.indexOf(':') > -1 || b.name.indexOf(':') > -1) { if (a.name.indexOf(':') > -1 && b.name.indexOf(':') === -1) { return 1; } if (a.name.indexOf(':') === -1 && b.name.indexOf(':') > -1) { return -1; } } if (a.name < b.name) { return -1; } if (a.name > b.name) { return 1; } return 0; } const helpContent = ` This command displays a list of the available commands. # Parameters: * -p, --path Displays the absolute filepath to the corresponding file, for easy editing. `; const listCommand: CommandModule<{ path?: boolean }> = { async command(args) { const list: CommandInfo[] = []; const commandPaths = commandHelper.getCommandAbsolutePaths(); for (const item of commandPaths) { const commandName = path.basename(item).replace(/_/g, ':').replace(/\.(js|ts)$/, ''); const moduleName = path.normalize(item).replace(/\.(js|ts)$/, ''); const rawOptions = await import(moduleName); const { commandOptions } = rawOptions.default ? rawOptions.default : rawOptions; list.push({ name: commandName, description: commandOptions.description || 'No help provided.', path: item, }); } list.sort(compare); console.log(chalk.yellow('List of available commands:')); let maxCommandNameLength = 0; list.forEach((element) => { if (maxCommandNameLength < element.name.length) { maxCommandNameLength = element.name.length; } }); maxCommandNameLength += 3; let listOutput = '\n'; let lastNamespace = ''; let namespace = ''; for (let element of list) { let name: string; let optionalName: string | null = null; if (element.name.includes(':')) { // we can only go 3 layers deep with this implementation [namespace, name, optionalName = null] = element.name.split(':'); } else { namespace = ''; name = element.name; } if (lastNamespace !== namespace) { listOutput += chalk.yellow(namespace) + ':\n'; } name = optionalName ? name + ":" + optionalName : name; listOutput += ' ' + chalk.green(name.padEnd(maxCommandNameLength, ' ')) + chalk.white(element.description) + '\n'; if (args.path && args.path === true) { listOutput += ' '.repeat(maxCommandNameLength + 2) + chalk.italic.gray(element.path) + '\n'; } lastNamespace = namespace; } console.log(listOutput); }, commandOptions: { help: helpContent, description: "Lists commands", args: { "--path": Boolean, "-p": "--path" } } }; export default listCommand;