18d307f52SEvan Baconimport { ExpoConfig, getConfig, ProjectConfig } from '@expo/config'; 28d307f52SEvan Baconimport assert from 'assert'; 38d307f52SEvan Baconimport util from 'util'; 48d307f52SEvan Bacon 58d307f52SEvan Baconimport * as Log from '../log'; 68d307f52SEvan Baconimport { CommandError } from '../utils/errors'; 72dd43328SEvan Baconimport { setNodeEnv } from '../utils/nodeEnv'; 88d307f52SEvan Baconimport { profile } from '../utils/profile'; 98d307f52SEvan Bacon 108d307f52SEvan Bacontype Options = { 118d307f52SEvan Bacon type?: string; 1229975bfdSEvan Bacon full?: boolean; 138d307f52SEvan Bacon json?: boolean; 148d307f52SEvan Bacon}; 158d307f52SEvan Bacon 168d307f52SEvan Baconexport function logConfig(config: ExpoConfig | ProjectConfig) { 178d307f52SEvan Bacon const isObjStr = (str: string): boolean => /^\w+: {/g.test(str); 188d307f52SEvan Bacon Log.log( 198d307f52SEvan Bacon util.inspect(config, { 208d307f52SEvan Bacon colors: true, 218d307f52SEvan Bacon compact: false, 228d307f52SEvan Bacon // Sort objects to the end so that smaller values aren't hidden between large objects. 238d307f52SEvan Bacon sorted(a: string, b: string) { 248d307f52SEvan Bacon if (isObjStr(a)) return 1; 258d307f52SEvan Bacon if (isObjStr(b)) return -1; 268d307f52SEvan Bacon return 0; 278d307f52SEvan Bacon }, 288d307f52SEvan Bacon showHidden: false, 298d307f52SEvan Bacon depth: null, 308d307f52SEvan Bacon }) 318d307f52SEvan Bacon ); 328d307f52SEvan Bacon} 338d307f52SEvan Bacon 348d307f52SEvan Baconexport async function configAsync(projectRoot: string, options: Options) { 35aaa8033fSEvan Bacon const loggingFunctions = { 36aaa8033fSEvan Bacon log: console.log, 37aaa8033fSEvan Bacon warn: console.warn, 38aaa8033fSEvan Bacon error: console.error, 39aaa8033fSEvan Bacon }; 40aaa8033fSEvan Bacon // Disable logging for this command if the user wants to get JSON output. 41aaa8033fSEvan Bacon // This will ensure that only the JSON is printed to stdout. 42aaa8033fSEvan Bacon if (options.json) { 43aaa8033fSEvan Bacon console.log = function () {}; 44aaa8033fSEvan Bacon console.warn = function () {}; 45aaa8033fSEvan Bacon console.error = function () {}; 46aaa8033fSEvan Bacon } 472dd43328SEvan Bacon setNodeEnv('development'); 486a750d06SEvan Bacon require('@expo/env').load(projectRoot); 492dd43328SEvan Bacon 508d307f52SEvan Bacon if (options.type) { 518d307f52SEvan Bacon assert.match(options.type, /^(public|prebuild|introspect)$/); 528d307f52SEvan Bacon } 538d307f52SEvan Bacon 548d307f52SEvan Bacon let config: ProjectConfig; 558d307f52SEvan Bacon 568d307f52SEvan Bacon if (options.type === 'prebuild') { 578d307f52SEvan Bacon const { getPrebuildConfigAsync } = await import('@expo/prebuild-config'); 588d307f52SEvan Bacon 598d307f52SEvan Bacon config = await profile(getPrebuildConfigAsync)(projectRoot, { 608d307f52SEvan Bacon platforms: ['ios', 'android'], 618d307f52SEvan Bacon }); 628d307f52SEvan Bacon } else if (options.type === 'introspect') { 638d307f52SEvan Bacon const { getPrebuildConfigAsync } = await import('@expo/prebuild-config'); 64*1a3a1db5SEvan Bacon const { compileModsAsync } = await import('@expo/config-plugins/build/plugins/mod-compiler.js'); 658d307f52SEvan Bacon 668d307f52SEvan Bacon config = await profile(getPrebuildConfigAsync)(projectRoot, { 678d307f52SEvan Bacon platforms: ['ios', 'android'], 688d307f52SEvan Bacon }); 698d307f52SEvan Bacon 708d307f52SEvan Bacon await compileModsAsync(config.exp, { 718d307f52SEvan Bacon projectRoot, 728d307f52SEvan Bacon introspect: true, 738d307f52SEvan Bacon platforms: ['ios', 'android'], 748d307f52SEvan Bacon assertMissingModProviders: false, 758d307f52SEvan Bacon }); 768d307f52SEvan Bacon // @ts-ignore 778d307f52SEvan Bacon delete config.modRequest; 788d307f52SEvan Bacon // @ts-ignore 798d307f52SEvan Bacon delete config.modResults; 808d307f52SEvan Bacon } else if (options.type === 'public') { 818d307f52SEvan Bacon config = profile(getConfig)(projectRoot, { 828d307f52SEvan Bacon skipSDKVersionRequirement: true, 838d307f52SEvan Bacon isPublicConfig: true, 848d307f52SEvan Bacon }); 858d307f52SEvan Bacon } else if (options.type) { 868d307f52SEvan Bacon throw new CommandError( 878d307f52SEvan Bacon `Invalid option: --type ${options.type}. Valid options are: public, prebuild` 888d307f52SEvan Bacon ); 898d307f52SEvan Bacon } else { 908d307f52SEvan Bacon config = profile(getConfig)(projectRoot, { 918d307f52SEvan Bacon skipSDKVersionRequirement: true, 928d307f52SEvan Bacon }); 938d307f52SEvan Bacon } 948d307f52SEvan Bacon 958d307f52SEvan Bacon const configOutput = options.full ? config : config.exp; 968d307f52SEvan Bacon 978d307f52SEvan Bacon if (!options.json) { 988d307f52SEvan Bacon Log.log(); 998d307f52SEvan Bacon logConfig(configOutput); 1008d307f52SEvan Bacon Log.log(); 1018d307f52SEvan Bacon } else { 102aaa8033fSEvan Bacon process.stdout.write(JSON.stringify(configOutput)); 103aaa8033fSEvan Bacon 104aaa8033fSEvan Bacon // Re-enable logging functions for testing. 105aaa8033fSEvan Bacon console.log = loggingFunctions.log; 106aaa8033fSEvan Bacon console.warn = loggingFunctions.warn; 107aaa8033fSEvan Bacon console.error = loggingFunctions.error; 1088d307f52SEvan Bacon } 1098d307f52SEvan Bacon} 110