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 | null> {
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 = value ? devices.find(({ name }) => name === value)! : null;
44
45  if (device?.isAuthorized === false) {
46    logUnauthorized(device);
47    throw new AbortCommandError();
48  }
49
50  return device;
51}
52