1import { ExpoConfig, modifyConfigAsync } from '@expo/config';
2import chalk from 'chalk';
3
4import * as Log from '../log';
5import { SilentError } from './errors';
6
7/** Wraps `[@expo/config] modifyConfigAsync()` and adds additional logging. */
8export async function attemptModification(
9  projectRoot: string,
10  edits: Partial<ExpoConfig>,
11  exactEdits: Partial<ExpoConfig>
12): Promise<void> {
13  const modification = await modifyConfigAsync(projectRoot, edits, {
14    skipSDKVersionRequirement: true,
15  });
16  if (modification.type === 'success') {
17    Log.log();
18  } else {
19    warnAboutConfigAndThrow(modification.type, modification.message!, exactEdits);
20  }
21}
22
23function logNoConfig() {
24  Log.log(
25    chalk.yellow(
26      `No Expo config was found. Please create an Expo config (${chalk.bold`app.json`} or ${chalk.bold`app.config.js`}) in your project root.`
27    )
28  );
29}
30
31export function warnAboutConfigAndThrow(type: string, message: string, edits: Partial<ExpoConfig>) {
32  Log.log();
33  if (type === 'warn') {
34    // The project is using a dynamic config, give the user a helpful log and bail out.
35    Log.log(chalk.yellow(message));
36  } else {
37    logNoConfig();
38  }
39
40  notifyAboutManualConfigEdits(edits);
41  throw new SilentError();
42}
43
44function notifyAboutManualConfigEdits(edits: Partial<ExpoConfig>) {
45  Log.log(chalk.cyan(`Please add the following to your Expo config`));
46  Log.log();
47  Log.log(JSON.stringify(edits, null, 2));
48  Log.log();
49}
50