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