1import { ExpoConfig, getConfig, ProjectConfig } from '@expo/config'; 2import assert from 'assert'; 3import util from 'util'; 4 5import * as Log from '../log'; 6import { CommandError } from '../utils/errors'; 7import { setNodeEnv } from '../utils/nodeEnv'; 8import { profile } from '../utils/profile'; 9 10type Options = { 11 type?: string; 12 full?: boolean; 13 json?: boolean; 14}; 15 16export function logConfig(config: ExpoConfig | ProjectConfig) { 17 const isObjStr = (str: string): boolean => /^\w+: {/g.test(str); 18 Log.log( 19 util.inspect(config, { 20 colors: true, 21 compact: false, 22 // Sort objects to the end so that smaller values aren't hidden between large objects. 23 sorted(a: string, b: string) { 24 if (isObjStr(a)) return 1; 25 if (isObjStr(b)) return -1; 26 return 0; 27 }, 28 showHidden: false, 29 depth: null, 30 }) 31 ); 32} 33 34export async function configAsync(projectRoot: string, options: Options) { 35 setNodeEnv('development'); 36 require('@expo/env').load(projectRoot); 37 38 if (options.type) { 39 assert.match(options.type, /^(public|prebuild|introspect)$/); 40 } 41 42 let config: ProjectConfig; 43 44 if (options.type === 'prebuild') { 45 const { getPrebuildConfigAsync } = await import('@expo/prebuild-config'); 46 47 config = await profile(getPrebuildConfigAsync)(projectRoot, { 48 platforms: ['ios', 'android'], 49 }); 50 } else if (options.type === 'introspect') { 51 const { getPrebuildConfigAsync } = await import('@expo/prebuild-config'); 52 const { compileModsAsync } = await import('@expo/config-plugins/build/plugins/mod-compiler'); 53 54 config = await profile(getPrebuildConfigAsync)(projectRoot, { 55 platforms: ['ios', 'android'], 56 }); 57 58 await compileModsAsync(config.exp, { 59 projectRoot, 60 introspect: true, 61 platforms: ['ios', 'android'], 62 assertMissingModProviders: false, 63 }); 64 // @ts-ignore 65 delete config.modRequest; 66 // @ts-ignore 67 delete config.modResults; 68 } else if (options.type === 'public') { 69 config = profile(getConfig)(projectRoot, { 70 skipSDKVersionRequirement: true, 71 isPublicConfig: true, 72 }); 73 } else if (options.type) { 74 throw new CommandError( 75 `Invalid option: --type ${options.type}. Valid options are: public, prebuild` 76 ); 77 } else { 78 config = profile(getConfig)(projectRoot, { 79 skipSDKVersionRequirement: true, 80 }); 81 } 82 83 const configOutput = options.full ? config : config.exp; 84 85 if (!options.json) { 86 Log.log(); 87 logConfig(configOutput); 88 Log.log(); 89 } else { 90 Log.log(JSON.stringify(configOutput)); 91 } 92} 93