1082815dcSEvan Baconimport type { ExpoConfig } from '@expo/config-types';
2082815dcSEvan Bacon
3082815dcSEvan Baconimport type { ConfigPlugin } from '../Plugin.types';
4082815dcSEvan Baconimport { withPodfileProperties } from '../plugins/ios-plugins';
5082815dcSEvan Baconimport { BuildPropertiesConfig, ConfigToPropertyRuleType } from '../utils/BuildProperties.types';
6082815dcSEvan Bacon
7082815dcSEvan Bacon/**
8082815dcSEvan Bacon * Creates a `withPodfileProperties` config-plugin based on given config to property mapping rules.
9082815dcSEvan Bacon *
10082815dcSEvan Bacon * The factory supports two modes from generic type inference
11082815dcSEvan Bacon * ```ts
12082815dcSEvan Bacon * // config-plugin without `props`, it will implicitly use the expo config as source config.
13082815dcSEvan Bacon * createBuildPodfilePropsConfigPlugin<ExpoConfig>(): ConfigPlugin<void>;
14082815dcSEvan Bacon *
15082815dcSEvan Bacon * // config-plugin with a parameter `props: CustomType`, it will use the `props` as source config.
16082815dcSEvan Bacon * createBuildPodfilePropsConfigPlugin<CustomType>(): ConfigPlugin<CustomType>;
17082815dcSEvan Bacon * ```
18082815dcSEvan Bacon *
19082815dcSEvan Bacon * @param configToPropertyRules config to property mapping rules
20082815dcSEvan Bacon * @param name the config plugin name
21082815dcSEvan Bacon */
22082815dcSEvan Baconexport function createBuildPodfilePropsConfigPlugin<SourceConfigType extends BuildPropertiesConfig>(
23082815dcSEvan Bacon  configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[],
24082815dcSEvan Bacon  name?: string
25082815dcSEvan Bacon) {
26082815dcSEvan Bacon  const withUnknown: ConfigPlugin<SourceConfigType extends ExpoConfig ? void : SourceConfigType> = (
27082815dcSEvan Bacon    config,
28082815dcSEvan Bacon    sourceConfig
29082815dcSEvan Bacon  ) =>
30082815dcSEvan Bacon    withPodfileProperties(config, (config) => {
31082815dcSEvan Bacon      config.modResults = updateIosBuildPropertiesFromConfig(
32082815dcSEvan Bacon        (sourceConfig ?? config) as SourceConfigType,
33082815dcSEvan Bacon        config.modResults,
34082815dcSEvan Bacon        configToPropertyRules
35082815dcSEvan Bacon      );
36082815dcSEvan Bacon      return config;
37082815dcSEvan Bacon    });
38082815dcSEvan Bacon  if (name) {
39082815dcSEvan Bacon    Object.defineProperty(withUnknown, 'name', {
40082815dcSEvan Bacon      value: name,
41082815dcSEvan Bacon    });
42082815dcSEvan Bacon  }
43082815dcSEvan Bacon  return withUnknown;
44082815dcSEvan Bacon}
45082815dcSEvan Bacon
46082815dcSEvan Bacon/**
47082815dcSEvan Bacon * A config-plugin to update `ios/Podfile.properties.json` from the `jsEngine` in expo config
48082815dcSEvan Bacon */
49082815dcSEvan Baconexport const withJsEnginePodfileProps = createBuildPodfilePropsConfigPlugin<ExpoConfig>(
50082815dcSEvan Bacon  [
51082815dcSEvan Bacon    {
52082815dcSEvan Bacon      propName: 'expo.jsEngine',
53*ba115a22SGabriel Donadel Dall'Agnol      propValueGetter: (config) => config.ios?.jsEngine ?? config.jsEngine ?? 'hermes',
54082815dcSEvan Bacon    },
55082815dcSEvan Bacon  ],
56082815dcSEvan Bacon  'withJsEnginePodfileProps'
57082815dcSEvan Bacon);
58082815dcSEvan Bacon
59082815dcSEvan Baconexport function updateIosBuildPropertiesFromConfig<SourceConfigType extends BuildPropertiesConfig>(
60082815dcSEvan Bacon  config: SourceConfigType,
61082815dcSEvan Bacon  podfileProperties: Record<string, string>,
62082815dcSEvan Bacon  configToPropertyRules: ConfigToPropertyRuleType<SourceConfigType>[]
63082815dcSEvan Bacon) {
64082815dcSEvan Bacon  for (const configToProperty of configToPropertyRules) {
65082815dcSEvan Bacon    const value = configToProperty.propValueGetter(config);
66082815dcSEvan Bacon    updateIosBuildProperty(podfileProperties, configToProperty.propName, value);
67082815dcSEvan Bacon  }
68082815dcSEvan Bacon  return podfileProperties;
69082815dcSEvan Bacon}
70082815dcSEvan Bacon
71082815dcSEvan Baconexport function updateIosBuildProperty(
72082815dcSEvan Bacon  podfileProperties: Record<string, string>,
73082815dcSEvan Bacon  name: string,
74082815dcSEvan Bacon  value: string | null | undefined,
75082815dcSEvan Bacon  options?: { removePropWhenValueIsNull?: boolean }
76082815dcSEvan Bacon) {
77082815dcSEvan Bacon  if (value) {
78082815dcSEvan Bacon    podfileProperties[name] = value;
79082815dcSEvan Bacon  } else if (options?.removePropWhenValueIsNull) {
80082815dcSEvan Bacon    delete podfileProperties[name];
81082815dcSEvan Bacon  }
82082815dcSEvan Bacon  return podfileProperties;
83082815dcSEvan Bacon}
84