import { ConfirmQuestion, InputQuestion, ListQuestion, Question } from 'inquirer'; // tslint:disable-next-line: no-duplicate-imports import * as inquirer from 'inquirer'; import * as prettyjson from 'prettyjson'; import { getCommandDefinitionParameterValue, validateCommandDefinitionParameterValue } from '../parameters'; import { CliCommandDefinitionParameter, ParsedCliCommand } from '../types'; import { CliPromptResult } from './types'; /** * Build valid inquirer Question object from CliCommandDefinitionParameter (arg or option) * @param param CommandDefinition Parameter * @param isRequred Indicates whether Parameter is required (applies only to arg parameters) */ const buildParameterPromptQuestion = ( param: CliCommandDefinitionParameter, isRequred: boolean = false ): InputQuestion | ConfirmQuestion | ListQuestion | undefined => { const prompt = param.prompt || {}; const messageBase = prompt && prompt.message ? prompt.message : param.name; const message = `${messageBase}${isRequred ? ' (required)' : ''}:`; const validate = input => { if (isRequred && (!input || (input.length && input.length === 0))) { return `Value is required`; } const val = getCommandDefinitionParameterValue(input, param); const isValid = validateCommandDefinitionParameterValue(val, param); if (isValid !== true) { if (typeof isValid === 'string') { return isValid; } else { return 'Invalid Value'; } } return true; }; const defaultTransformer = (input: string): string => { return (getCommandDefinitionParameterValue(input, param) as string) || ''; }; const transformer = prompt.transformer || defaultTransformer; let type = prompt.type || 'input'; let promptDefault; if (param.valueType === 'boolean') { type = 'confirm'; promptDefault = typeof param.default === 'boolean' ? param.default : false; } return { ...(prompt || {}), type, name: param.name, message, validate, transformer, default: promptDefault, }; }; const buildArgQuestions = (parsed: ParsedCliCommand): Question[] => { return Object.keys(parsed.parsedArguments).reduce((questions, argName) => { const arg = parsed.parsedArguments[argName]; if (!arg.wasPassed) { const q = buildParameterPromptQuestion(arg, !!!arg.isOptional); if (q) { questions.push(q); } } return questions; }, []); }; const buildOptionsQuestions = (parsed: ParsedCliCommand): Question[] => { return (parsed.command.options || []).reduce((questions, option) => { const parsedOption = parsed.parsedOptions[option.name]; if (!parsedOption.wasPassed) { const q = buildParameterPromptQuestion(parsedOption); if (q) { questions.push(q); } } return questions; }, []); }; export const promptHandler = async (parsed: ParsedCliCommand): Promise => { const argAnswers = await inquirer.prompt(buildArgQuestions(parsed)); const optAnswers = await inquirer.prompt(buildOptionsQuestions(parsed)); const argAnswersKeys = Object.keys(argAnswers); const args = Object.keys(parsed.arguments).reduce((prev, curr) => { prev[curr] = argAnswersKeys.indexOf(curr) >= 0 ? argAnswers[curr] : parsed.arguments[curr]; return prev; }, {}); const optAnswersKeys = Object.keys(optAnswers); const opts = Object.keys(parsed.options).reduce((prev, curr) => { prev[curr] = optAnswersKeys.indexOf(curr) >= 0 ? optAnswers[curr] : parsed.options[curr]; return prev; }, {}); const result = { arguments: args, options: opts, }; // console.log(prettyjson.render(result)); return result; };