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; private checkForEnvCliCall = true; /** * 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() {} /** * halts any execution of commands if (process.env.CLI_CALL === false) */ disableEnvCliCall() { this.checkForEnvCliCall = false; } /** * 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; this.addCommandAlias('v', 'version'); this.parseCompleted.promise.then((argv) => { if (argv.v) { console.log(this.version); } }); } /** * 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 { // if we check for cli env calls, we might want to abort here. if (!process.env.CLI_CALL && this.checkForEnvCliCall) { console.log( `note: @pushrocks/smartcli: You called .startParse() on a SmartCli instance. However process.env.CLI_CALL being absent prevented parsing.` ); return; } const parsedYArgs = plugins.yargsParser(process.argv); // lets handle commands let counter = 0; let foundCommand = false; parsedYArgs._.map((commandPartArg) => { counter++; if (typeof commandPartArg === 'number') { return true; } if (counter <= 2 && !foundCommand) { const isPath = commandPartArg.startsWith('/'); foundCommand = !isPath; return foundCommand; } else { return true; } }); for (const command of this.commandObservableMap.getArray()) { if (!parsedYArgs._[0]) { 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; } }