1import JsonFile from '@expo/json-file'; 2import { existsSync } from 'fs'; 3 4import { AppJSONConfig, ConfigContext, ExpoConfig } from './Config.types'; 5import { ConfigError } from './Errors'; 6import { DynamicConfigResults, evalConfig } from './evalConfig'; 7 8// We cannot use async config resolution right now because Next.js doesn't support async configs. 9// If they don't add support for async Webpack configs then we may need to pull support for Next.js. 10function readConfigFile(configFile: string, context: ConfigContext): null | DynamicConfigResults { 11 // If the file doesn't exist then we should skip it and continue searching. 12 if (!existsSync(configFile)) { 13 return null; 14 } 15 try { 16 return evalConfig(configFile, context); 17 } catch (error: any) { 18 // @ts-ignore 19 error.isConfigError = true; 20 error.message = `Error reading Expo config at ${configFile}:\n\n${error.message}`; 21 throw error; 22 } 23} 24 25export function getDynamicConfig(configPath: string, request: ConfigContext): DynamicConfigResults { 26 const config = readConfigFile(configPath, request); 27 if (config) { 28 // The config must be serialized and evaluated ahead of time so the spawned process can send it over. 29 return config; 30 } 31 // TODO: It seems this is only thrown if the file cannot be found (which may never happen). 32 // If so we should throw a more helpful error. 33 throw new ConfigError(`Failed to read config at: ${configPath}`, 'INVALID_CONFIG'); 34} 35 36export function getStaticConfig(configPath: string): AppJSONConfig | ExpoConfig { 37 const config = JsonFile.read(configPath, { json5: true }); 38 if (config) { 39 return config as any; 40 } 41 throw new ConfigError(`Failed to read config at: ${configPath}`, 'INVALID_CONFIG'); 42} 43