1import chalk from 'chalk'; 2 3import { AbortCommandError } from '../../../utils/errors'; 4import { createSelectionFilter, promptAsync } from '../../../utils/prompts'; 5import { Device, logUnauthorized } from './adb'; 6 7function nameStyleForDevice(device: Device): (name: string) => string { 8 const isActive = device.isBooted; 9 if (!isActive) { 10 // Use no style changes for a disconnected device that is available to be opened. 11 return (text: string) => text; 12 } 13 // A device that is connected and ready to be used should be bolded to match iOS. 14 if (device.isAuthorized) { 15 return chalk.bold; 16 } 17 // Devices that are unauthorized and connected cannot be used, but they are connected so gray them out. 18 return (text: string) => chalk.bold(chalk.gray(text)); 19} 20 21export async function promptForDeviceAsync(devices: Device[]): Promise<Device> { 22 // TODO: provide an option to add or download more simulators 23 24 const { value } = await promptAsync({ 25 type: 'autocomplete', 26 name: 'value', 27 limit: 11, 28 message: 'Select a device/emulator', 29 choices: devices.map((item) => { 30 const format = nameStyleForDevice(item); 31 const type = item.isAuthorized ? item.type : 'unauthorized'; 32 return { 33 title: `${format(item.name)} ${chalk.dim(`(${type})`)}`, 34 value: item.name, 35 }; 36 }), 37 suggest: createSelectionFilter(), 38 }); 39 40 const device = devices.find(({ name }) => name === value); 41 42 if (device?.isAuthorized === false) { 43 logUnauthorized(device); 44 throw new AbortCommandError(); 45 } 46 47 return device!; 48} 49