1import { getConfig } from '@expo/config'; 2import * as PackageManager from '@expo/package-manager'; 3import chalk from 'chalk'; 4 5import * as Log from '../log'; 6import { 7 getVersionedDependenciesAsync, 8 logIncorrectDependencies, 9} from '../start/doctor/dependencies/validateDependenciesVersions'; 10import { isInteractive } from '../utils/interactive'; 11import { confirmAsync } from '../utils/prompts'; 12import { fixPackagesAsync } from './installAsync'; 13import { Options } from './resolveOptions'; 14 15const debug = require('debug')('expo:install:check') as typeof console.log; 16 17// Exposed for testing. 18export async function checkPackagesAsync( 19 projectRoot: string, 20 { 21 packages, 22 packageManager, 23 options: { fix }, 24 packageManagerArguments, 25 }: { 26 /** 27 * List of packages to version 28 * @example ['uuid', 'react-native-reanimated@latest'] 29 */ 30 packages: string[]; 31 /** Package manager to use when installing the versioned packages. */ 32 packageManager: PackageManager.NodePackageManager; 33 34 /** How the check should resolve */ 35 options: Pick<Options, 'fix'>; 36 /** 37 * Extra parameters to pass to the `packageManager` when installing versioned packages. 38 * @example ['--no-save'] 39 */ 40 packageManagerArguments: string[]; 41 } 42) { 43 // Read the project Expo config without plugins. 44 const { exp, pkg } = getConfig(projectRoot, { 45 // Sometimes users will add a plugin to the config before installing the library, 46 // this wouldn't work unless we dangerously disable plugin serialization. 47 skipPlugins: true, 48 }); 49 50 const dependencies = await getVersionedDependenciesAsync(projectRoot, exp, pkg, packages); 51 52 if (!dependencies.length) { 53 Log.exit(chalk.greenBright('Dependencies are up to date'), 0); 54 } 55 56 logIncorrectDependencies(dependencies); 57 58 const value = 59 // If `--fix` then always fix. 60 fix || 61 // Otherwise prompt to fix when not running in CI. 62 (isInteractive() && (await confirmAsync({ message: 'Fix dependencies?' }).catch(() => false))); 63 64 if (value) { 65 debug('Installing fixed dependencies:', dependencies); 66 // Install the corrected dependencies. 67 return fixPackagesAsync(projectRoot, { 68 packageManager, 69 packages: dependencies, 70 packageManagerArguments, 71 sdkVersion: exp.sdkVersion!, 72 }); 73 } 74 // Exit with non-zero exit code if any of the dependencies are out of date. 75 Log.exit(chalk.red('Found outdated dependencies'), 1); 76} 77