1import chalk from 'chalk'; 2 3import { AbortCommandError } from '../../../utils/errors'; 4import { 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: (input: any, choices: any) => { 38 const regex = new RegExp(input, 'i'); 39 return choices.filter((choice: any) => regex.test(choice.title)); 40 }, 41 }); 42 43 const device = devices.find(({ name }) => name === value); 44 45 if (device?.isAuthorized === false) { 46 logUnauthorized(device); 47 throw new AbortCommandError(); 48 } 49 50 return device!; 51} 52