( name: string, choices: SelectDefChoice<T>[], options?: SelectDefOptions<T>, )
| 40 | * @param options See definition of `SelectDefOptions` for more details. |
| 41 | */ |
| 42 | export function selectDef<T>( |
| 43 | name: string, |
| 44 | choices: SelectDefChoice<T>[], |
| 45 | options?: SelectDefOptions<T>, |
| 46 | ): InputDefinition<T> { |
| 47 | const nameOfChoice = (choice: SelectDefChoice<T>): string => |
| 48 | typeof choice === 'object' ? choice.name : choice.toString() |
| 49 | const valueOfChoice = (choice: SelectDefChoice<T>): T => |
| 50 | (typeof choice === 'number' || typeof choice === 'string' ? choice : choice.value) as T |
| 51 | |
| 52 | const namesByValue = new Map(choices.map(choice => [valueOfChoice(choice), nameOfChoice(choice)])) |
| 53 | |
| 54 | const editValue = async (defaultSelection: T | undefined): Promise<T | CancelAction> => { |
| 55 | const inquirerChoices: (Choice<T | CancelAction | HelpAction>)[] = choices.map(choice => ({ |
| 56 | name: nameOfChoice(choice), |
| 57 | value: valueOfChoice(choice), |
| 58 | })) |
| 59 | |
| 60 | inquirerChoices.push(new Separator()) |
| 61 | if (options?.helpText) { |
| 62 | inquirerChoices.push(helpOption) |
| 63 | } |
| 64 | inquirerChoices.push(cancelOption) |
| 65 | |
| 66 | // eslint-disable-next-line no-constant-condition |
| 67 | while (true) { |
| 68 | const selection = await select({ |
| 69 | message: `Select ${name}.`, |
| 70 | choices: inquirerChoices, |
| 71 | default: defaultSelection ?? 0, |
| 72 | pageSize: inquirerPageSize, |
| 73 | }) |
| 74 | |
| 75 | if (selection === helpAction) { |
| 76 | console.log(`\n${options?.helpText}\n`) |
| 77 | } else { |
| 78 | return selection |
| 79 | } |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | const buildFromUserInput = (): Promise<T | CancelAction> => editValue(options?.default) |
| 84 | |
| 85 | const summarizeForEdit = options?.summarizeForEdit |
| 86 | ?? ((value: T) => clipToMaximum((namesByValue.get(value)) ?? stringFromUnknown(value), maxItemValueLength)) |
| 87 | |
| 88 | const updateFromUserInput = (original: T): Promise<T | CancelAction> => editValue(original) |
| 89 | |
| 90 | return { name, buildFromUserInput, summarizeForEdit, updateFromUserInput } |
| 91 | } |
no test coverage detected