19657025fSTomasz Sapetaimport JsonFile from '@expo/json-file'; 2eeffdb10STomasz Sapetaimport path from 'path'; 3eeffdb10STomasz Sapeta 4*a272999eSBartosz Kaszubowskiimport { EXPO_DIR } from './Constants'; 5eeffdb10STomasz Sapetaimport { Package } from './Packages'; 6eeffdb10STomasz Sapetaimport { spawnAsync, spawnJSONCommandAsync } from './Utils'; 7eeffdb10STomasz Sapeta 8eeffdb10STomasz Sapetaconst NATIVE_APPS_PATHS = [EXPO_DIR, path.join(EXPO_DIR, 'apps/bare-expo')]; 9eeffdb10STomasz Sapeta 10eeffdb10STomasz Sapeta/** 11eeffdb10STomasz Sapeta * Workspace info for the single project. 12eeffdb10STomasz Sapeta */ 13eeffdb10STomasz Sapetaexport type WorkspaceProjectInfo = { 14eeffdb10STomasz Sapeta location: string; 15eeffdb10STomasz Sapeta workspaceDependencies: string[]; 16eeffdb10STomasz Sapeta mismatchedWorkspaceDependencies: string[]; 17eeffdb10STomasz Sapeta}; 18eeffdb10STomasz Sapeta 19eeffdb10STomasz Sapeta/** 20eeffdb10STomasz Sapeta * An object with workspace's projects info. 21eeffdb10STomasz Sapeta */ 22eeffdb10STomasz Sapetaexport type WorkspacesInfo = Record<string, WorkspaceProjectInfo>; 23eeffdb10STomasz Sapeta 24eeffdb10STomasz Sapeta/** 25eeffdb10STomasz Sapeta * Returns an object containing info for all projects in the workspace. 26eeffdb10STomasz Sapeta */ 27eeffdb10STomasz Sapetaexport async function getInfoAsync(): Promise<WorkspacesInfo> { 28eeffdb10STomasz Sapeta const info = await spawnJSONCommandAsync<{ data: string }>('yarn', [ 29eeffdb10STomasz Sapeta '--json', 30eeffdb10STomasz Sapeta 'workspaces', 31eeffdb10STomasz Sapeta 'info', 32eeffdb10STomasz Sapeta ]); 33eeffdb10STomasz Sapeta return JSON.parse(info.data); 34eeffdb10STomasz Sapeta} 35eeffdb10STomasz Sapeta 36eeffdb10STomasz Sapeta/** 37eeffdb10STomasz Sapeta * Runs yarn in the root workspace directory. 38eeffdb10STomasz Sapeta */ 39eeffdb10STomasz Sapetaexport async function installAsync(): Promise<void> { 40eeffdb10STomasz Sapeta await spawnAsync('yarn'); 41eeffdb10STomasz Sapeta} 42eeffdb10STomasz Sapeta 43eeffdb10STomasz Sapeta/** 44eeffdb10STomasz Sapeta * Returns an array of workspace's native apps, like Expo Client or BareExpo. 45eeffdb10STomasz Sapeta */ 46eeffdb10STomasz Sapetaexport function getNativeApps(): Package[] { 47eeffdb10STomasz Sapeta return NATIVE_APPS_PATHS.map((appPath) => new Package(appPath)); 48eeffdb10STomasz Sapeta} 499657025fSTomasz Sapeta 509657025fSTomasz Sapeta/** 519657025fSTomasz Sapeta * Updates the dependency across all workspace projects to given version range. 529657025fSTomasz Sapeta */ 539657025fSTomasz Sapetaexport async function updateDependencyAsync(dependencyName: string, versionRange: string) { 549657025fSTomasz Sapeta const projectLocations = Object.values(await getInfoAsync()).map( 559657025fSTomasz Sapeta (projectInfo) => projectInfo.location 569657025fSTomasz Sapeta ); 579657025fSTomasz Sapeta 589657025fSTomasz Sapeta await Promise.all( 599657025fSTomasz Sapeta projectLocations.map(async (location) => { 609657025fSTomasz Sapeta const jsonFile = new JsonFile(path.join(EXPO_DIR, location, 'package.json')); 619657025fSTomasz Sapeta const packageJson = await jsonFile.readAsync(); 629657025fSTomasz Sapeta 639657025fSTomasz Sapeta for (const dependencyType of ['dependencies', 'devDependencies', 'peerDependencies']) { 649657025fSTomasz Sapeta const dependencies = packageJson[dependencyType]; 659657025fSTomasz Sapeta const currentVersion = dependencies?.[dependencyName]; 669657025fSTomasz Sapeta 679657025fSTomasz Sapeta if (dependencies && currentVersion && currentVersion !== '*') { 689657025fSTomasz Sapeta dependencies[dependencyName] = versionRange; 699657025fSTomasz Sapeta } 709657025fSTomasz Sapeta } 719657025fSTomasz Sapeta await jsonFile.writeAsync(packageJson); 729657025fSTomasz Sapeta }) 739657025fSTomasz Sapeta ); 749657025fSTomasz Sapeta} 75