1import JsonFile from '@expo/json-file'; 2import chalk from 'chalk'; 3import fs from 'fs'; 4 5import * as Log from '../../../log'; 6 7export const baseTSConfigName = 'expo/tsconfig.base'; 8 9export async function updateTSConfigAsync({ 10 tsConfigPath, 11}: { 12 tsConfigPath: string; 13}): Promise<void> { 14 const shouldGenerate = !fs.existsSync(tsConfigPath) || fs.statSync(tsConfigPath).size === 0; 15 if (shouldGenerate) { 16 await JsonFile.writeAsync(tsConfigPath, { compilerOptions: {} }); 17 } 18 19 const projectTSConfig = JsonFile.read(tsConfigPath, { 20 // Some tsconfig.json files have a generated comment in the file. 21 json5: true, 22 }); 23 24 projectTSConfig.compilerOptions ??= {}; 25 26 const modifications: [string, string][] = []; 27 28 // If the extends field isn't defined, set it to the expo default 29 if (!projectTSConfig.extends) { 30 // if (projectTSConfig.extends !== baseTSConfigName) { 31 projectTSConfig.extends = baseTSConfigName; 32 modifications.push(['extends', baseTSConfigName]); 33 } 34 35 // If no changes, then quietly bail out 36 if (!modifications.length) { 37 return; 38 } 39 40 // Write changes and log out a summary of what changed 41 await JsonFile.writeAsync(tsConfigPath, projectTSConfig); 42 43 // If no changes, then quietly bail out 44 if (modifications.length === 0) { 45 return; 46 } 47 48 Log.log(); 49 50 if (shouldGenerate) { 51 Log.log(chalk`{bold TypeScript}: A {cyan tsconfig.json} has been auto-generated`); 52 } else { 53 Log.log( 54 chalk`{bold TypeScript}: The {cyan tsconfig.json} has been updated {dim (Use EXPO_NO_TYPESCRIPT_SETUP to skip)}` 55 ); 56 logModifications(modifications); 57 } 58 Log.log(); 59} 60 61function logModifications(modifications: string[][]) { 62 Log.log(); 63 64 Log.log(chalk`\u203A {bold Required} modifications made to the {cyan tsconfig.json}:`); 65 66 Log.log(); 67 68 // Sort the items based on key name length 69 printTable(modifications.sort((a, b) => a[0].length - b[0].length)); 70 71 Log.log(); 72} 73 74function printTable(items: string[][]) { 75 const tableFormat = (name: string, msg: string) => 76 ` ${chalk.bold`${name}`} is now ${chalk.cyan(msg)}`; 77 for (const [key, value] of items) { 78 Log.log(tableFormat(key, value)); 79 } 80} 81