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 37 if (options.type) { 38 assert.match(options.type, /^(public|prebuild|introspect)$/); 39 } 40 41 let config: ProjectConfig; 42 43 if (options.type === 'prebuild') { 44 const { getPrebuildConfigAsync } = await import('@expo/prebuild-config'); 45 46 config = await profile(getPrebuildConfigAsync)(projectRoot, { 47 platforms: ['ios', 'android'], 48 }); 49 } else if (options.type === 'introspect') { 50 const { getPrebuildConfigAsync } = await import('@expo/prebuild-config'); 51 const { compileModsAsync } = await import('@expo/config-plugins/build/plugins/mod-compiler'); 52 53 config = await profile(getPrebuildConfigAsync)(projectRoot, { 54 platforms: ['ios', 'android'], 55 }); 56 57 await compileModsAsync(config.exp, { 58 projectRoot, 59 introspect: true, 60 platforms: ['ios', 'android'], 61 assertMissingModProviders: false, 62 }); 63 // @ts-ignore 64 delete config.modRequest; 65 // @ts-ignore 66 delete config.modResults; 67 } else if (options.type === 'public') { 68 config = profile(getConfig)(projectRoot, { 69 skipSDKVersionRequirement: true, 70 isPublicConfig: true, 71 }); 72 } else if (options.type) { 73 throw new CommandError( 74 `Invalid option: --type ${options.type}. Valid options are: public, prebuild` 75 ); 76 } else { 77 config = profile(getConfig)(projectRoot, { 78 skipSDKVersionRequirement: true, 79 }); 80 } 81 82 const configOutput = options.full ? config : config.exp; 83 84 if (!options.json) { 85 Log.log(); 86 logConfig(configOutput); 87 Log.log(); 88 } else { 89 Log.log(JSON.stringify(configOutput)); 90 } 91} 92