18d307f52SEvan Baconimport chalk from 'chalk'; 28d307f52SEvan Bacon 38d307f52SEvan Baconimport { getBestSimulatorAsync } from './getBestSimulator'; 48d307f52SEvan Baconimport { Device } from './simctl'; 5*8a424bebSJames Ideimport { createSelectionFilter, promptAsync } from '../../../utils/prompts'; 68d307f52SEvan Bacon 78d307f52SEvan Bacon/** 88d307f52SEvan Bacon * Sort the devices so the last simulator that was opened (user's default) is the first suggested. 98d307f52SEvan Bacon * 108d307f52SEvan Bacon * @param devices list of devices to sort. 118d307f52SEvan Bacon * @param osType optional sort by operating system. 128d307f52SEvan Bacon */ 138d307f52SEvan Baconexport async function sortDefaultDeviceToBeginningAsync( 148d307f52SEvan Bacon devices: Device[], 158d307f52SEvan Bacon osType?: Device['osType'] 168d307f52SEvan Bacon): Promise<Device[]> { 178d307f52SEvan Bacon const defaultId = await getBestSimulatorAsync({ osType }); 188d307f52SEvan Bacon if (defaultId) { 198d307f52SEvan Bacon let iterations = 0; 208d307f52SEvan Bacon while (devices[0].udid !== defaultId && iterations < devices.length) { 218d307f52SEvan Bacon devices.push(devices.shift()!); 228d307f52SEvan Bacon iterations++; 238d307f52SEvan Bacon } 248d307f52SEvan Bacon } 258d307f52SEvan Bacon return devices; 268d307f52SEvan Bacon} 278d307f52SEvan Bacon 288d307f52SEvan Bacon/** Prompt the user to select an Apple device, sorting the most likely option to the beginning. */ 298d307f52SEvan Baconexport async function promptAppleDeviceAsync( 308d307f52SEvan Bacon devices: Device[], 318d307f52SEvan Bacon osType?: Device['osType'] 328d307f52SEvan Bacon): Promise<Device> { 338d307f52SEvan Bacon devices = await sortDefaultDeviceToBeginningAsync(devices, osType); 348d307f52SEvan Bacon const results = await promptAppleDeviceInternalAsync(devices); 358d307f52SEvan Bacon return devices.find(({ udid }) => results === udid)!; 368d307f52SEvan Bacon} 378d307f52SEvan Bacon 388d307f52SEvan Baconasync function promptAppleDeviceInternalAsync(devices: Device[]): Promise<string> { 398d307f52SEvan Bacon // TODO: provide an option to add or download more simulators 408d307f52SEvan Bacon // TODO: Add support for physical devices too. 418d307f52SEvan Bacon 428d307f52SEvan Bacon const { value } = await promptAsync({ 438d307f52SEvan Bacon type: 'autocomplete', 448d307f52SEvan Bacon name: 'value', 458d307f52SEvan Bacon limit: 11, 468d307f52SEvan Bacon message: 'Select a simulator', 478d307f52SEvan Bacon choices: devices.map((item) => { 488d307f52SEvan Bacon const isActive = item.state === 'Booted'; 498d307f52SEvan Bacon const format = isActive ? chalk.bold : (text: string) => text; 508d307f52SEvan Bacon return { 518d307f52SEvan Bacon title: `${format(item.name)} ${chalk.dim(`(${item.osVersion})`)}`, 528d307f52SEvan Bacon value: item.udid, 538d307f52SEvan Bacon }; 548d307f52SEvan Bacon }), 5586ab6f9aSEvan Bacon suggest: createSelectionFilter(), 568d307f52SEvan Bacon }); 578d307f52SEvan Bacon 588d307f52SEvan Bacon return value; 598d307f52SEvan Bacon} 60