16d6b81f9SEvan Baconimport { getConfig, Platform } from '@expo/config'; 2dc51e206SEvan Bacon 36d6b81f9SEvan Baconimport { getPlatformBundlers, PlatformBundlers } from '../start/server/platformBundlers'; 46d6b81f9SEvan Baconimport { CommandError } from '../utils/errors'; 5dc51e206SEvan Bacon 6dc51e206SEvan Baconexport type Options = { 7dc51e206SEvan Bacon outputDir: string; 86d6b81f9SEvan Bacon platforms: Platform[]; 9dc51e206SEvan Bacon maxWorkers?: number; 10dc51e206SEvan Bacon dev: boolean; 11dc51e206SEvan Bacon clear: boolean; 121a3d836eSEvan Bacon minify: boolean; 13dc51e206SEvan Bacon dumpAssetmap: boolean; 14dc51e206SEvan Bacon dumpSourcemap: boolean; 15dc51e206SEvan Bacon}; 16dc51e206SEvan Bacon 176d6b81f9SEvan Bacon/** Returns an array of platforms based on the input platform identifier and runtime constraints. */ 186d6b81f9SEvan Baconexport function resolvePlatformOption( 196d6b81f9SEvan Bacon platformBundlers: PlatformBundlers, 20*8eba27a6SCedric van Putten platform: string[] = ['all'] 216d6b81f9SEvan Bacon): Platform[] { 22*8eba27a6SCedric van Putten const platformsAvailable: Partial<PlatformBundlers> = Object.fromEntries( 236d6b81f9SEvan Bacon Object.entries(platformBundlers).filter(([, bundler]) => bundler === 'metro') 246d6b81f9SEvan Bacon ); 256d6b81f9SEvan Bacon 26*8eba27a6SCedric van Putten if (!Object.keys(platformsAvailable).length) { 276d6b81f9SEvan Bacon throw new CommandError( 286d6b81f9SEvan Bacon `No platforms are configured to use the Metro bundler in the project Expo config.` 296d6b81f9SEvan Bacon ); 306d6b81f9SEvan Bacon } 316d6b81f9SEvan Bacon 32*8eba27a6SCedric van Putten const assertPlatformBundler = (platform: Platform): Platform => { 33*8eba27a6SCedric van Putten if (!platformsAvailable[platform]) { 346d6b81f9SEvan Bacon throw new CommandError( 356d6b81f9SEvan Bacon 'BAD_ARGS', 366d6b81f9SEvan Bacon `Platform "${platform}" is not configured to use the Metro bundler in the project Expo config.` 376d6b81f9SEvan Bacon ); 386d6b81f9SEvan Bacon } 39*8eba27a6SCedric van Putten 40*8eba27a6SCedric van Putten return platform; 416d6b81f9SEvan Bacon }; 426d6b81f9SEvan Bacon 43*8eba27a6SCedric van Putten const knownPlatforms = ['android', 'ios', 'web'] as Platform[]; 44*8eba27a6SCedric van Putten const assertPlatformIsKnown = (platform: string): Platform => { 45*8eba27a6SCedric van Putten if (!knownPlatforms.includes(platform as Platform)) { 466d6b81f9SEvan Bacon throw new CommandError( 47*8eba27a6SCedric van Putten `Unsupported platform "${platform}". Options are: ${knownPlatforms.join(',')},all` 486d6b81f9SEvan Bacon ); 496d6b81f9SEvan Bacon } 50*8eba27a6SCedric van Putten 51*8eba27a6SCedric van Putten return platform as Platform; 52*8eba27a6SCedric van Putten }; 53*8eba27a6SCedric van Putten 54*8eba27a6SCedric van Putten return ( 55*8eba27a6SCedric van Putten platform 56*8eba27a6SCedric van Putten // Expand `all` to all available platforms. 57*8eba27a6SCedric van Putten .map((platform) => (platform === 'all' ? Object.keys(platformsAvailable) : platform)) 58*8eba27a6SCedric van Putten .flat() 59*8eba27a6SCedric van Putten // Remove duplicated platforms 60*8eba27a6SCedric van Putten .filter((platform, index, list) => list.indexOf(platform) === index) 61*8eba27a6SCedric van Putten // Assert platforms are valid 62*8eba27a6SCedric van Putten .map((platform) => assertPlatformIsKnown(platform)) 63*8eba27a6SCedric van Putten .map((platform) => assertPlatformBundler(platform)) 64*8eba27a6SCedric van Putten ); 656d6b81f9SEvan Bacon} 666d6b81f9SEvan Bacon 676d6b81f9SEvan Baconexport async function resolveOptionsAsync(projectRoot: string, args: any): Promise<Options> { 686d6b81f9SEvan Bacon const { exp } = getConfig(projectRoot, { skipPlugins: true, skipSDKVersionRequirement: true }); 696d6b81f9SEvan Bacon const platformBundlers = getPlatformBundlers(exp); 70dc51e206SEvan Bacon 71dc51e206SEvan Bacon return { 72*8eba27a6SCedric van Putten platforms: resolvePlatformOption(platformBundlers, args['--platform']), 73dc51e206SEvan Bacon outputDir: args['--output-dir'] ?? 'dist', 741a3d836eSEvan Bacon minify: !args['--no-minify'], 75dc51e206SEvan Bacon clear: !!args['--clear'], 76dc51e206SEvan Bacon dev: !!args['--dev'], 77dc51e206SEvan Bacon maxWorkers: args['--max-workers'], 78dc51e206SEvan Bacon dumpAssetmap: !!args['--dump-assetmap'], 79dc51e206SEvan Bacon dumpSourcemap: !!args['--dump-sourcemap'], 80dc51e206SEvan Bacon }; 81dc51e206SEvan Bacon} 82