1import { getConfig } from '@expo/config'; 2import fs from 'fs/promises'; 3import { Server } from 'metro'; 4import path from 'path'; 5 6import { removeExpoEnvDTS, writeExpoEnvDTS } from './expo-env'; 7import { setupTypedRoutes } from './routes'; 8import { forceRemovalTSConfig, forceUpdateTSConfig } from './tsconfig'; 9import { removeFromGitIgnore, upsertGitIgnoreContents } from '../../../utils/mergeGitIgnorePaths'; 10import { ensureDotExpoProjectDirectoryInitialized } from '../../project/dotExpo'; 11import { ServerLike } from '../BundlerDevServer'; 12import { getRouterDirectoryWithManifest } from '../metro/router'; 13 14export interface TypeScriptTypeGenerationOptions { 15 server?: ServerLike; 16 metro?: Server | null; 17 projectRoot: string; 18} 19 20const debug = require('debug')('expo:typed-routes') as typeof console.log; 21 22/** Setup all requisite features for statically typed routes in Expo Router v2 / SDK +49. */ 23export async function startTypescriptTypeGenerationAsync({ 24 metro, 25 projectRoot, 26 server, 27}: TypeScriptTypeGenerationOptions) { 28 const { exp } = getConfig(projectRoot); 29 30 // If typed routes are disabled, remove any files that were added. 31 if (!exp.experiments?.typedRoutes) { 32 debug('Removing typed routes side-effects (experiments.typedRoutes: false)'); 33 const gitIgnorePath = path.join(projectRoot, '.gitignore'); 34 await Promise.all([ 35 forceRemovalTSConfig(projectRoot), 36 removeExpoEnvDTS(projectRoot), 37 removeFromGitIgnore(gitIgnorePath, 'expo-env.d.ts'), 38 ]); 39 } else { 40 const dotExpoDir = ensureDotExpoProjectDirectoryInitialized(projectRoot); 41 const typesDirectory = path.resolve(dotExpoDir, './types'); 42 debug( 43 'Ensuring typed routes side-effects are setup (experiments.typedRoutes: true, typesDirectory: %s)', 44 typesDirectory 45 ); 46 47 // Ensure the types directory exists. 48 await fs.mkdir(typesDirectory, { recursive: true }); 49 50 await Promise.all([ 51 upsertGitIgnoreContents(path.join(projectRoot, '.gitignore'), 'expo-env.d.ts'), 52 writeExpoEnvDTS(projectRoot), 53 forceUpdateTSConfig(projectRoot), 54 setupTypedRoutes({ 55 metro, 56 server, 57 typesDirectory, 58 projectRoot, 59 routerDirectory: getRouterDirectoryWithManifest(projectRoot, exp), 60 }), 61 ]); 62 } 63} 64