-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: validate arguments correctly (#724)
currently the arguments are not validated correctly (#722) since they are validated against filtered questions. this fixes it to validate against the full list of questions. this also refactors the prompts module to move argument handling to the prompt function.
- Loading branch information
Showing
7 changed files
with
140 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import prompts from 'prompts'; | ||
|
||
type Choice = { | ||
title: string; | ||
value: string; | ||
description?: string; | ||
}; | ||
|
||
export type Question<T extends string> = Omit< | ||
prompts.PromptObject<T>, | ||
'validate' | 'name' | 'choices' | ||
> & { | ||
name: T; | ||
validate?: (value: string) => boolean | string; | ||
choices?: | ||
| Choice[] | ||
| ((prev: unknown, values: Partial<prompts.Answers<T>>) => Choice[]); | ||
}; | ||
|
||
/** | ||
* Wrapper around `prompts` with additional features: | ||
* | ||
* - Improved type-safety | ||
* - Read answers from passed arguments | ||
* - Skip questions with a single choice | ||
* - Exit on canceling the prompt | ||
*/ | ||
export async function prompt<T extends string>( | ||
questions: Question<T>[] | Question<T>, | ||
argv?: Record<T, string>, | ||
options?: prompts.Options | ||
) { | ||
const singleChoiceAnswers = {}; | ||
const promptQuestions = []; | ||
|
||
if (Array.isArray(questions)) { | ||
for (const question of questions) { | ||
// Skip questions which are passed as parameter and pass validation | ||
const argValue = argv?.[question.name]; | ||
|
||
if (argValue && question.validate?.(argValue) !== false) { | ||
continue; | ||
} | ||
|
||
// Don't prompt questions with a single choice | ||
if (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 | ||
singleChoiceAnswers[question.name] = onlyChoice.value; | ||
} | ||
|
||
continue; | ||
} | ||
|
||
const { type, choices } = question; | ||
|
||
// Don't prompt dynamic questions with a single choice | ||
if (type === 'select' && typeof choices === 'function') { | ||
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 | ||
singleChoiceAnswers[question.name] = onlyChoice.value; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
return type; | ||
}; | ||
} | ||
|
||
promptQuestions.push(question); | ||
} | ||
} else { | ||
promptQuestions.push(questions); | ||
} | ||
|
||
const promptAnswers = await prompts(promptQuestions, { | ||
onCancel() { | ||
// Exit the CLI on cancel | ||
process.exit(1); | ||
}, | ||
...options, | ||
}); | ||
|
||
return { | ||
...argv, | ||
...singleChoiceAnswers, | ||
...promptAnswers, | ||
}; | ||
} |
This file was deleted.
Oops, something went wrong.