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