1import { getAccountUsername, getConfig } from '@expo/config';
2import { ModPlatform } from '@expo/config-plugins';
3import { ExpoConfig } from '@expo/config-types';
4
5import { getAutolinkedPackagesAsync } from './getAutolinkedPackages';
6import {
7  withAndroidExpoPlugins,
8  withIosExpoPlugins,
9  withLegacyExpoPlugins,
10  withVersionedExpoSDKPlugins,
11} from './plugins/withDefaultPlugins';
12
13export async function getPrebuildConfigAsync(
14  projectRoot: string,
15  props: {
16    bundleIdentifier?: string;
17    packageName?: string;
18    platforms: ModPlatform[];
19    expoUsername?: string | ((config: ExpoConfig) => string | null);
20  }
21): Promise<ReturnType<typeof getConfig>> {
22  const autolinkedModules = await getAutolinkedPackagesAsync(projectRoot, props.platforms);
23
24  return getPrebuildConfig(projectRoot, {
25    ...props,
26    autolinkedModules,
27  });
28}
29
30function getPrebuildConfig(
31  projectRoot: string,
32  {
33    platforms,
34    bundleIdentifier,
35    packageName,
36    autolinkedModules,
37    expoUsername,
38  }: {
39    bundleIdentifier?: string;
40    packageName?: string;
41    platforms: ModPlatform[];
42    autolinkedModules?: string[];
43    expoUsername?: string | ((config: ExpoConfig) => string | null);
44  }
45) {
46  // let config: ExpoConfig;
47  let { exp: config, ...rest } = getConfig(projectRoot, {
48    skipSDKVersionRequirement: true,
49    isModdedConfig: true,
50  });
51
52  if (autolinkedModules) {
53    if (!config._internal) {
54      config._internal = {};
55    }
56    config._internal.autolinkedModules = autolinkedModules;
57  }
58
59  const resolvedExpoUsername =
60    typeof expoUsername === 'function'
61      ? expoUsername(config)
62      : // If the user didn't pass a username then fallback on the static cached username.
63        expoUsername ?? getAccountUsername(config);
64
65  // Add all built-in plugins first because they should take
66  // priority over the unversioned plugins.
67  config = withVersionedExpoSDKPlugins(config, {
68    expoUsername: resolvedExpoUsername,
69  });
70  config = withLegacyExpoPlugins(config);
71
72  if (platforms.includes('ios')) {
73    if (!config.ios) config.ios = {};
74    config.ios.bundleIdentifier =
75      bundleIdentifier ?? config.ios.bundleIdentifier ?? `com.placeholder.appid`;
76
77    // Add all built-in plugins
78    config = withIosExpoPlugins(config, {
79      bundleIdentifier: config.ios.bundleIdentifier,
80    });
81  }
82
83  if (platforms.includes('android')) {
84    if (!config.android) config.android = {};
85    config.android.package = packageName ?? config.android.package ?? `com.placeholder.appid`;
86
87    // Add all built-in plugins
88    config = withAndroidExpoPlugins(config, {
89      package: config.android.package,
90    });
91  }
92
93  return { exp: config, ...rest };
94}
95