1import { CommandError } from '../utils/errors'; 2import { createCachedFetch } from './rest/client'; 3 4interface NativeModule { 5 npmPackage: string; 6 versionRange: string; 7} 8type BundledNativeModuleList = NativeModule[]; 9 10export type BundledNativeModules = Record<string, string>; 11 12/** 13 * The endpoint returns the list of bundled native modules for a given SDK version. 14 * The data is populated by the `et sync-bundled-native-modules` script from expo/expo repo. 15 * See the code for more details: 16 * https://github.com/expo/expo/blob/main/tools/src/commands/SyncBundledNativeModules.ts 17 * 18 * Example result: 19 * [ 20 * { 21 * id: "79285187-e5c4-47f7-b6a9-664f5d16f0db", 22 * sdkVersion: "41.0.0", 23 * npmPackage: "expo-analytics-amplitude", 24 * versionRange: "~10.1.0", 25 * createdAt: "2021-04-29T09:34:32.825Z", 26 * updatedAt: "2021-04-29T09:34:32.825Z" 27 * }, 28 * ... 29 * ] 30 */ 31export async function getNativeModuleVersionsAsync( 32 sdkVersion: string 33): Promise<BundledNativeModules> { 34 const fetchAsync = createCachedFetch({ 35 cacheDirectory: 'native-modules-cache', 36 // 1 minute cache 37 ttl: 1000 * 60 * 1, 38 }); 39 const results = await fetchAsync(`sdks/${sdkVersion}/native-modules`); 40 if (!results.ok) { 41 throw new CommandError( 42 'API', 43 `Unexpected response when fetching version info from Expo servers: ${results.statusText}.` 44 ); 45 } 46 const { data } = await results.json(); 47 if (!data.length) { 48 throw new CommandError('VERSIONS', 'The bundled native module list from the Expo API is empty'); 49 } 50 return fromBundledNativeModuleList(data); 51} 52 53function fromBundledNativeModuleList(list: BundledNativeModuleList): BundledNativeModules { 54 return list.reduce((acc, i) => { 55 acc[i.npmPackage] = i.versionRange; 56 return acc; 57 }, {} as BundledNativeModules); 58} 59