1import JsonFile from '@expo/json-file'; 2import path from 'path'; 3 4import { EXPO_DIR } from './Constants'; 5import { Package } from './Packages'; 6import { spawnAsync, spawnJSONCommandAsync } from './Utils'; 7 8const NATIVE_APPS_PATHS = [EXPO_DIR, path.join(EXPO_DIR, 'apps/bare-expo')]; 9 10/** 11 * Workspace info for the single project. 12 */ 13export type WorkspaceProjectInfo = { 14 location: string; 15 workspaceDependencies: string[]; 16 mismatchedWorkspaceDependencies: string[]; 17}; 18 19/** 20 * An object with workspace's projects info. 21 */ 22export type WorkspacesInfo = Record<string, WorkspaceProjectInfo>; 23 24/** 25 * Returns an object containing info for all projects in the workspace. 26 */ 27export async function getInfoAsync(): Promise<WorkspacesInfo> { 28 const info = await spawnJSONCommandAsync<{ data: string }>('yarn', [ 29 '--json', 30 'workspaces', 31 'info', 32 ]); 33 return JSON.parse(info.data); 34} 35 36/** 37 * Runs yarn in the root workspace directory. 38 */ 39export async function installAsync(): Promise<void> { 40 await spawnAsync('yarn'); 41} 42 43/** 44 * Returns an array of workspace's native apps, like Expo Client or BareExpo. 45 */ 46export function getNativeApps(): Package[] { 47 return NATIVE_APPS_PATHS.map((appPath) => new Package(appPath)); 48} 49 50/** 51 * Updates the dependency across all workspace projects to given version range. 52 */ 53export async function updateDependencyAsync(dependencyName: string, versionRange: string) { 54 const projectLocations = Object.values(await getInfoAsync()).map( 55 (projectInfo) => projectInfo.location 56 ); 57 58 await Promise.all( 59 projectLocations.map(async (location) => { 60 const jsonFile = new JsonFile(path.join(EXPO_DIR, location, 'package.json')); 61 const packageJson = await jsonFile.readAsync(); 62 63 for (const dependencyType of ['dependencies', 'devDependencies', 'peerDependencies']) { 64 const dependencies = packageJson[dependencyType]; 65 const currentVersion = dependencies?.[dependencyName]; 66 67 if (dependencies && currentVersion && currentVersion !== '*') { 68 dependencies[dependencyName] = versionRange; 69 } 70 } 71 await jsonFile.writeAsync(packageJson); 72 }) 73 ); 74} 75