1import { EXPO_BETA } from '../utils/env'; 2import { CommandError } from '../utils/errors'; 3import { pickBy } from '../utils/obj'; 4import { createCachedFetch } from './rest/client'; 5 6/** Represents version info for a particular SDK. */ 7export type SDKVersion = { 8 /** @example "2.16.1" */ 9 iosVersion?: string; 10 /** @example "https://dpq5q02fu5f55.cloudfront.net/Exponent-2.17.4.tar.gz" */ 11 iosClientUrl?: string; 12 /** @example "https://dev.to/expo/expo-sdk-38-is-now-available-5aa0" */ 13 releaseNoteUrl?: string; 14 /** @example "2.17.4" */ 15 iosClientVersion?: string; 16 /** @example "https://d1ahtucjixef4r.cloudfront.net/Exponent-2.16.1.apk" */ 17 androidClientUrl?: string; 18 /** @example "2.16.1" */ 19 androidClientVersion?: string; 20 /** @example { "typescript": "~3.9.5" } */ 21 relatedPackages?: Record<string, string>; 22 23 facebookReactNativeVersion: string; 24 25 facebookReactVersion?: string; 26 27 beta?: boolean; 28}; 29 30export type SDKVersions = Record<string, SDKVersion>; 31 32export type Versions = { 33 androidUrl: string; 34 androidVersion: string; 35 iosUrl: string; 36 iosVersion: string; 37 sdkVersions: SDKVersions; 38}; 39 40/** Get versions from remote endpoint. */ 41export async function getVersionsAsync({ 42 skipCache, 43}: { skipCache?: boolean } = {}): Promise<Versions> { 44 // Reconstruct the cached fetch since caching could be disabled. 45 const fetchAsync = createCachedFetch({ 46 skipCache, 47 cacheDirectory: 'versions-cache', 48 // We'll use a 1 week cache for versions so older versions get flushed out eventually. 49 ttl: 1000 * 60 * 60 * 24 * 7, 50 }); 51 52 const results = await fetchAsync('versions/latest'); 53 if (!results.ok) { 54 throw new CommandError( 55 'API', 56 `Unexpected response when fetching version info from Expo servers: ${results.statusText}.` 57 ); 58 } 59 const json = await results.json(); 60 return json.data; 61} 62 63/** Get the currently released version while also accounting for if the user is running in `EXPO_BETA` mode. */ 64export async function getReleasedVersionsAsync(): Promise<SDKVersions> { 65 // NOTE(brentvatne): it is possible for an unreleased version to be published to 66 // the versions endpoint, but in some cases we only want to list out released 67 // versions 68 const { sdkVersions } = await getVersionsAsync(); 69 return pickBy( 70 sdkVersions, 71 (data, _sdkVersionString) => !!data.releaseNoteUrl || (EXPO_BETA && data.beta) 72 ); 73} 74