18d307f52SEvan Baconimport { ModPlatform } from '@expo/config-plugins'; 28d307f52SEvan Baconimport assert from 'assert'; 38d307f52SEvan Baconimport chalk from 'chalk'; 48d307f52SEvan Baconimport fs from 'fs'; 58d307f52SEvan Baconimport path from 'path'; 68d307f52SEvan Bacon 78d307f52SEvan Baconimport * as Log from '../log'; 88d307f52SEvan Baconimport { CommandError } from '../utils/errors'; 98d307f52SEvan Baconimport { validateUrl } from '../utils/url'; 108d307f52SEvan Bacon 116caf5755SEvan Baconexport function resolvePackageManagerOptions(args: any) { 126caf5755SEvan Bacon const managers: Record<string, boolean> = { 136caf5755SEvan Bacon npm: args['--npm'], 146caf5755SEvan Bacon yarn: args['--yarn'], 156caf5755SEvan Bacon pnpm: args['--pnpm'], 16*9b1b5ec6SEvan Bacon bun: args['--bun'], 176caf5755SEvan Bacon }; 186caf5755SEvan Bacon 196caf5755SEvan Bacon if ( 20*9b1b5ec6SEvan Bacon [managers.npm, managers.pnpm, managers.yarn, managers.bun, !!args['--no-install']].filter( 21*9b1b5ec6SEvan Bacon Boolean 22*9b1b5ec6SEvan Bacon ).length > 1 236caf5755SEvan Bacon ) { 246caf5755SEvan Bacon throw new CommandError( 256caf5755SEvan Bacon 'BAD_ARGS', 26*9b1b5ec6SEvan Bacon 'Specify at most one of: --no-install, --npm, --pnpm, --yarn, --bun' 276caf5755SEvan Bacon ); 286caf5755SEvan Bacon } 296caf5755SEvan Bacon 306caf5755SEvan Bacon return managers; 316caf5755SEvan Bacon} 326caf5755SEvan Bacon 338d307f52SEvan Bacon/** Resolves a template option as a URL or file path pointing to a tar file. */ 348d307f52SEvan Baconexport function resolveTemplateOption(template: string) { 358d307f52SEvan Bacon if (validateUrl(template)) { 368d307f52SEvan Bacon return template; 378d307f52SEvan Bacon } 388d307f52SEvan Bacon const templatePath = path.resolve(template); 398d307f52SEvan Bacon assert(fs.existsSync(templatePath), 'template file does not exist: ' + templatePath); 408d307f52SEvan Bacon assert( 418d307f52SEvan Bacon fs.statSync(templatePath).isFile(), 428d307f52SEvan Bacon 'template must be a tar file created by running `npm pack` in a project: ' + templatePath 438d307f52SEvan Bacon ); 448d307f52SEvan Bacon 458d307f52SEvan Bacon return templatePath; 468d307f52SEvan Bacon} 478d307f52SEvan Bacon 488d307f52SEvan Bacon/** Resolves dependencies to skip from a string joined by `,`. Example: `react-native,expo,lodash` */ 498d307f52SEvan Baconexport function resolveSkipDependencyUpdate(value: any) { 508d307f52SEvan Bacon if (!value || typeof value !== 'string') { 518d307f52SEvan Bacon return []; 528d307f52SEvan Bacon } 538d307f52SEvan Bacon return value.split(','); 548d307f52SEvan Bacon} 558d307f52SEvan Bacon 568d307f52SEvan Bacon/** Returns an array of platforms based on the input platform identifier and runtime constraints. */ 578d307f52SEvan Baconexport function resolvePlatformOption( 588d307f52SEvan Bacon platform: string = 'all', 598d307f52SEvan Bacon { loose }: { loose?: boolean } = {} 608d307f52SEvan Bacon): ModPlatform[] { 618d307f52SEvan Bacon switch (platform) { 628d307f52SEvan Bacon case 'ios': 638d307f52SEvan Bacon return ['ios']; 648d307f52SEvan Bacon case 'android': 658d307f52SEvan Bacon return ['android']; 668d307f52SEvan Bacon case 'all': 675492d26aSCedric van Putten return loose || process.platform !== 'win32' ? ['android', 'ios'] : ['android']; 688d307f52SEvan Bacon default: 695492d26aSCedric van Putten return [platform as ModPlatform]; 708d307f52SEvan Bacon } 718d307f52SEvan Bacon} 728d307f52SEvan Bacon 738d307f52SEvan Bacon/** Warns and filters out unsupported platforms based on the runtime constraints. Essentially this means no iOS on Windows devices. */ 748d307f52SEvan Baconexport function ensureValidPlatforms(platforms: ModPlatform[]): ModPlatform[] { 758d307f52SEvan Bacon // Skip ejecting for iOS on Windows 768d307f52SEvan Bacon if (process.platform === 'win32' && platforms.includes('ios')) { 778d307f52SEvan Bacon Log.warn( 788d307f52SEvan Bacon chalk`⚠️ Skipping generating the iOS native project files. Run {bold expo eject} again from macOS or Linux to generate the iOS project.\n` 798d307f52SEvan Bacon ); 808d307f52SEvan Bacon return platforms.filter((platform) => platform !== 'ios'); 818d307f52SEvan Bacon } 828d307f52SEvan Bacon return platforms; 838d307f52SEvan Bacon} 848d307f52SEvan Bacon 858d307f52SEvan Bacon/** Asserts platform length must be greater than zero. */ 868d307f52SEvan Baconexport function assertPlatforms(platforms: ModPlatform[]) { 878d307f52SEvan Bacon if (!platforms?.length) { 888d307f52SEvan Bacon throw new CommandError('At least one platform must be enabled when syncing'); 898d307f52SEvan Bacon } 908d307f52SEvan Bacon} 91