UNPKG

create-react-native-library

Version:
165 lines (157 loc) 5.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.prompt = prompt; var _kleur = _interopRequireDefault(require("kleur")); var _prompts = _interopRequireDefault(require("prompts")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * Wrapper around `prompts` with additional features: * * - Improved type-safety * - Read answers from passed arguments * - Skip questions with a single choice * - Validate answers * - Exit on canceling the prompt * - Handle non-interactive mode */ async function prompt(questions, argv, options) { const interactive = options?.interactive ?? (process.stdout.isTTY && process.env.TERM !== 'dumb' && !process.env.CI); const onCancel = () => { // Exit the CLI on Ctrl+C process.exit(1); }; const onError = message => { console.log(message); process.exit(1); }; if (argv) { validate(argv, questions, onError); } const defaultAnswers = {}; const promptQuestions = []; if (Array.isArray(questions)) { for (const question of questions) { let promptQuestion = question; // Skip questions which are passed as parameter and pass validation const argValue = argv?.[question.name]; if (argValue && question.validate?.(String(argValue)) !== false) { continue; } const { type, choices } = question; // Track default value from questions if (type && question.default != null) { // @ts-expect-error assume the passed value is correct defaultAnswers[question.name] = question.default; // Don't prompt questions with a default value when not interactive if (!interactive) { continue; } } // Don't prompt questions with a single choice if (type === 'select' && Array.isArray(question.choices) && question.choices.length === 1) { const onlyChoice = question.choices[0]; if (onlyChoice?.value) { // @ts-expect-error assume the passed value is correct defaultAnswers[question.name] = onlyChoice.value; } continue; } // Don't prompt dynamic questions with a single choice if (type === 'select' && typeof choices === 'function') { promptQuestion = { ...question, type: (prev, values) => { const dynamicChoices = choices(prev, { ...argv, ...values }); if (dynamicChoices && dynamicChoices.length === 1) { const onlyChoice = dynamicChoices[0]; if (onlyChoice?.value) { // @ts-expect-error assume the passed value is correct defaultAnswers[question.name] = onlyChoice.value; } return null; } return type; } }; } promptQuestions.push(promptQuestion); } } else { promptQuestions.push(questions); } let promptAnswers; if (interactive) { promptAnswers = await (0, _prompts.default)(promptQuestions, { ...options, onCancel }); } else { const missingQuestions = promptQuestions.reduce((acc, question) => { let type = question.type; if (typeof question.type === 'function') { // @ts-expect-error assume the passed value is correct type = question.type(null, argv, null); } if (type != null) { acc.push(question.name.replace(/([A-Z]+)/g, '-$1').replace(/^-/, '').toLowerCase()); } return acc; }, []); if (missingQuestions.length) { onError(`Missing values for options: ${missingQuestions.map(q => _kleur.default.blue(q)).join(', ')}`); } } const result = { ...argv, ...defaultAnswers, ...promptAnswers }; validate(result, questions, onError); // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion return result; } function validate(argv, questions, onError) { for (const [key, value] of Object.entries(argv)) { if (value == null) { continue; } const question = Array.isArray(questions) ? questions.find(q => q.name === key) : questions.name === key ? questions : null; if (question == null) { continue; } let validation; // We also need to guard against invalid choices // If we don't already have a validation message to provide a better error if ('choices' in question) { const choices = typeof question.choices === 'function' ? question.choices(undefined, argv) : question.choices; if (choices && choices.every(choice => choice.value !== value)) { if (choices.length > 1) { validation = `Must be one of ${choices.map(choice => _kleur.default.green(choice.value)).join(', ')}`; } else if (choices[0]) { validation = `Must be '${_kleur.default.green(choices[0].value)}'`; } else { validation = false; } } } if (validation == null && question.validate) { validation = question.validate(String(value)); } if (validation != null && validation !== true) { let message = `Invalid value ${_kleur.default.red(String(value))} passed for ${_kleur.default.blue(key)}`; if (typeof validation === 'string') { message += `: ${validation}`; } onError(message); } } } //# sourceMappingURL=prompt.js.map