UNPKG

@api-buddy/plugin-utils

Version:

Shared utilities for API Buddy plugins

116 lines (99 loc) 2.95 kB
import { Command } from 'commander'; // Define a basic Logger interface if @api-buddy/types is not available interface Logger { info: (message: string) => void; warn: (message: string) => void; error: (message: string) => void; debug: (message: string) => void; } import { BaseCommand, CommandContext } from './commands/base-command.js'; import * as utils from './utils/index.js'; export interface PluginCLIOptions { name: string; version: string; description?: string; logger?: Logger; cwd?: string; } export class PluginCLI { private program: Command; private commandClasses: Map<string, new (context: CommandContext) => BaseCommand> = new Map(); private context: CommandContext; constructor(options: PluginCLIOptions) { this.program = new Command(); this.program .name(options.name) .version(options.version) .description(options.description || ''); // Add common options this.program .option('--verbose', 'Enable verbose logging', false) .option('--dry-run', 'Perform a dry run without making changes', false); this.context = { cwd: options.cwd || process.cwd(), logger: { info: console.log, warn: console.warn, error: console.error, debug: options.logger?.debug || (() => {}), }, config: {}, data: new Map(), utils: { registerHook: () => {}, unregisterHook: () => {}, callHook: async () => undefined, }, }; } /** * Register a command */ registerCommand(commandClass: typeof BaseCommand): this { const command = new commandClass(this.context); const meta = command.getMetadata(); const cmd = this.program .command(meta.name) .description(meta.description || ''); // Register command-specific arguments meta.arguments?.forEach((arg) => { cmd.argument( arg.required ? `<${arg.name}>` : `[${arg.name}]`, arg.description || '' ); }); // Register command-specific options meta.options?.forEach((opt: { flags: string; description?: string; defaultValue?: string | boolean }) => { cmd.option( opt.flags, opt.description || '', opt.defaultValue ); }); // Add action to execute the command cmd.action(async (...args: any[]) => { try { const commandInstance = new commandClass(this.context); await commandInstance.run(process.argv); } catch (error) { console.error('Error executing command:', error); process.exit(1); } }); return this; } /** * Parse and execute the CLI */ async run(argv: string[] = process.argv): Promise<void> { await this.program.parseAsync(argv); } } // Export everything export * from './commands/base-command'; export * from './utils'; // Export a default instance for convenience export default { PluginCLI, ...utils, };