import * as plugins from './smartcli.plugins.js'; // interfaces export interface ICommandObservableObject { commandName: string; subject: plugins.smartrx.rxjs.Subject; } const logger = new plugins.smartlog.ConsoleLog(); /** * class to create a new instance of Smartcli. Handles parsing of command line arguments. */ export class Smartcli { /** * this Deferred contains the parsed result in the end */ public parseCompleted = plugins.smartpromise.defer(); public version: string; /** * map of all Trigger/Observable objects to keep track */ private commandObservableMap = new plugins.lik.ObjectMap(); /** * maps alias */ public aliasObject: { [key: string]: string[] } = {}; /** * The constructor of Smartcli */ constructor() {} /** * adds an alias, meaning one equals the other in terms of command execution. */ public addCommandAlias(originalArg: string, aliasArg: string): void { this.aliasObject[originalArg] = this.aliasObject[originalArg] || []; this.aliasObject[originalArg].push(aliasArg); } /** * adds a Command by returning a Promise that reacts to the specific commandString given. * Note: in e.g. "npm install something" the "install" is considered the command. */ public addCommand(commandNameArg: string): plugins.smartrx.rxjs.Subject { let commandSubject: plugins.smartrx.rxjs.Subject; const existingCommandSubject = this.getCommandSubject(commandNameArg); commandSubject = existingCommandSubject || new plugins.smartrx.rxjs.Subject(); this.commandObservableMap.add({ commandName: commandNameArg, subject: commandSubject, }); return commandSubject; } /** * execute trigger by name * @param commandNameArg - the name of the command to trigger */ public triggerCommand(commandNameArg: string, argvObject: any) { const triggerSubject = this.getCommandSubject(commandNameArg); triggerSubject.next(argvObject); return triggerSubject; } public getCommandSubject(commandNameArg: string) { const triggerObservableObject = this.commandObservableMap.findSync( (triggerObservableObjectArg) => { return triggerObservableObjectArg.commandName === commandNameArg; } ); if (triggerObservableObject) { return triggerObservableObject.subject; } else { return null; } } /** * allows to specify help text to be printed above the rest of the help text */ public addHelp(optionsArg: { helpText: string }) { this.addCommand('help').subscribe((argvArg) => { logger.log('info', optionsArg.helpText); }); } /** * specify version to be printed for -v --version */ public addVersion(versionArg: string) { this.version = versionArg; } /** * adds a trigger that is called when no command is specified */ public standardCommand(): plugins.smartrx.rxjs.Subject { const standardSubject = this.addCommand('standardCommand'); return standardSubject; } /** * start the process of evaluating commands */ public startParse(): void { const parsedYArgs = plugins.yargsParser(process.argv); // lets handle commands let counter = 0; let foundCommand = false; parsedYArgs._ = parsedYArgs._.filter((commandPartArg) => { counter++; if (typeof commandPartArg === 'number') { return true; } if (counter <= 2 && !foundCommand) { const isPath = commandPartArg.startsWith('/'); foundCommand = !isPath; return foundCommand; } else { return true; } }); const wantedCommand = parsedYArgs._[0]; // lets handle some standards if (!wantedCommand && (parsedYArgs.v || parsedYArgs.version)) { console.log(this.version || 'unknown version'); return; } console.log(`Wanted command: ${wantedCommand}`); for (const command of this.commandObservableMap.getArray()) { if (!wantedCommand) { const standardCommand = this.commandObservableMap.findSync((commandArg) => { return commandArg.commandName === 'standardCommand'; }); if (standardCommand) { standardCommand.subject.next(parsedYArgs); } else { console.log('no smartcli standard task was created or assigned.'); } break; } if (command.commandName === parsedYArgs._[0]) { command.subject.next(parsedYArgs); break; } if (this.aliasObject[parsedYArgs[0]]) { } } this.parseCompleted.resolve(parsedYArgs); return; } }