1import { getExpoHomeDirectory } from '@expo/config/build/getUserState'; 2import path from 'path'; 3 4import { getReleasedVersionsAsync, SDKVersion } from '../api/getVersions'; 5import * as Log from '../log'; 6import { downloadAppAsync } from './downloadAppAsync'; 7import { CommandError } from './errors'; 8import { profile } from './profile'; 9import { createProgressBar } from './progress'; 10 11const platformSettings: Record< 12 string, 13 { 14 shouldExtractResults: boolean; 15 versionsKey: keyof SDKVersion; 16 getFilePath: (filename: string) => string; 17 } 18> = { 19 ios: { 20 versionsKey: 'iosClientUrl', 21 getFilePath: (filename) => 22 path.join(getExpoHomeDirectory(), 'ios-simulator-app-cache', `${filename}.app`), 23 shouldExtractResults: true, 24 }, 25 android: { 26 versionsKey: 'androidClientUrl', 27 getFilePath: (filename) => 28 path.join(getExpoHomeDirectory(), 'android-apk-cache', `${filename}.apk`), 29 shouldExtractResults: false, 30 }, 31}; 32 33/** Download the Expo Go app from the Expo servers (if only it was this easy for every app). */ 34export async function downloadExpoGoAsync( 35 platform: keyof typeof platformSettings, 36 { 37 url, 38 sdkVersion, 39 }: { 40 url?: string; 41 sdkVersion?: string; 42 } 43): Promise<string> { 44 const { getFilePath, versionsKey, shouldExtractResults } = platformSettings[platform]; 45 46 const bar = createProgressBar('Downloading the Expo Go app [:bar] :percent :etas', { 47 width: 64, 48 total: 100, 49 clear: true, 50 complete: '=', 51 incomplete: ' ', 52 }); 53 54 if (!url) { 55 if (!sdkVersion) { 56 throw new CommandError( 57 `Unable to determine which Expo Go version to install (platform: ${platform})` 58 ); 59 } 60 const versions = await getReleasedVersionsAsync(); 61 const version = versions[sdkVersion]; 62 Log.debug(`Installing Expo Go version for SDK ${sdkVersion} at URL: ${version[versionsKey]}`); 63 url = version[versionsKey] as string; 64 } 65 66 const filename = path.parse(url).name; 67 68 try { 69 const outputPath = getFilePath(filename); 70 Log.debug(`Downloading Expo Go from "${url}" to "${outputPath}".`); 71 Log.debug( 72 `The requested copy of Expo Go might already be cached in: "${getExpoHomeDirectory()}". You can disable the cache with EXPO_NO_CACHE=1` 73 ); 74 await profile(downloadAppAsync)({ 75 url, 76 // Save all encrypted cache data to `~/.expo/expo-go` 77 cacheDirectory: 'expo-go', 78 outputPath, 79 extract: shouldExtractResults, 80 onProgress({ progress }) { 81 if (bar) { 82 bar.tick(1, progress); 83 } 84 }, 85 }); 86 return outputPath; 87 } finally { 88 bar?.terminate(); 89 } 90} 91