xref: /expo/packages/@expo/cli/src/api/getVersions.ts (revision d566f199)
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