xref: /expo/packages/@expo/config/src/getConfig.ts (revision bb5069cd)
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