1import { createRunOncePlugin, Mod, withDangerousMod } from '@expo/config-plugins'; 2import { ExpoConfig } from '@expo/config-types'; 3// @ts-expect-error missing types 4import withDevLauncher from 'expo-dev-launcher/app.plugin'; 5// @ts-expect-error missing types 6import withDevMenu from 'expo-dev-menu/app.plugin'; 7import fs from 'fs'; 8import path from 'path'; 9 10import withGeneratedAndroidScheme from './withGeneratedAndroidScheme'; 11import withGeneratedIosScheme from './withGeneratedIosScheme'; 12 13const pkg = require('expo-dev-client/package.json'); 14 15const REACT_NATIVE_CONFIG_JS = `// File created by expo-dev-client/app.plugin.js 16 17module.exports = { 18 dependencies: { 19 ...require('expo-dev-client/dependencies'), 20 }, 21}; 22`; 23 24function withReactNativeConfigJs(config: ExpoConfig): ExpoConfig { 25 config = withDangerousMod(config, ['android', addReactNativeConfigAsync]); 26 config = withDangerousMod(config, ['ios', addReactNativeConfigAsync]); 27 return config; 28} 29 30const addReactNativeConfigAsync: Mod = async config => { 31 const filename = path.join(config.modRequest.projectRoot, 'react-native.config.js'); 32 try { 33 const config = fs.readFileSync(filename, 'utf8'); 34 if (!config.includes('expo-dev-client/dependencies')) { 35 throw new Error( 36 `Could not add expo-dev-client dependencies to existing file ${filename}. See expo-dev-client installation instructions to add them manually.` 37 ); 38 } 39 } catch (error) { 40 if (error.code === 'ENOENT') { 41 // The file doesn't exist, so we create it. 42 fs.writeFileSync(filename, REACT_NATIVE_CONFIG_JS); 43 } else { 44 throw error; 45 } 46 } 47 return config; 48}; 49 50function withDevClient(config: ExpoConfig) { 51 config = withDevMenu(config); 52 config = withDevLauncher(config); 53 config = withReactNativeConfigJs(config); 54 config = withGeneratedAndroidScheme(config); 55 config = withGeneratedIosScheme(config); 56 return config; 57} 58 59export default createRunOncePlugin(withDevClient, pkg.name, pkg.version); 60