import { ExpoConfig } from '@expo/config-types'; import { JSONObject } from '@expo/json-file'; import { XcodeProject } from 'xcode'; import { Properties } from './android'; import { AndroidManifest } from './android/Manifest'; import * as AndroidPaths from './android/Paths'; import { ResourceXML } from './android/Resources'; import { ExpoPlist, InfoPlist } from './ios/IosConfig.types'; import { AppDelegateProjectFile } from './ios/Paths'; type OptionalPromise = Promise | T; type Plist = JSONObject; export interface ModProps { /** * Project root directory for the universal app. */ readonly projectRoot: string; /** * Project root for the specific platform. */ readonly platformProjectRoot: string; /** * Name of the mod. */ readonly modName: string; /** * Name of the platform used in the mods config. */ readonly platform: ModPlatform; /** * If the mod is being evaluated in introspection mode. * No file system modifications should be made when introspect is `true`. */ readonly introspect: boolean; /** * [iOS]: The path component used for querying project files. * * @example projectRoot/ios/[projectName]/ */ readonly projectName?: string; /** * Ignore any of the user's local native files and solely rely on the generated files. * This makes prebuild data, like entitlements, more aligned to what users expects. * When enabling this, users must be informed and have a way to disable this exclusion. */ readonly ignoreExistingNativeFiles?: boolean; nextMod?: Mod; } // TODO: Migrate ProjectConfig to using expo instead if exp export interface ExportedConfig extends ExpoConfig { mods?: ModConfig | null; } export interface ExportedConfigWithProps extends ExportedConfig { /** * The Object representation of a complex file type. */ modResults: Data; modRequest: ModProps; /** * A frozen representation of the original file contents, * this can be used as a reference into the user's original intent. * * For example, you could infer that the user defined a certain * value explicitly and disable any automatic changes. */ readonly modRawConfig: ExpoConfig; } /** * A helper type to get the properties of a plugin. */ export type PluginParameters> = T extends ( config: any, props: infer P ) => any ? P : never; export type ConfigPlugin = (config: ExpoConfig, props: Props) => ExpoConfig; export type StaticPlugin = [string | ConfigPlugin, T]; export type Mod = (( config: ExportedConfigWithProps ) => OptionalPromise>) & { /** * Indicates that the mod provides data upstream to other mods. * This mod should always be the last one added. */ isProvider?: boolean; /** * If the mod supports introspection, and avoids making any filesystem modifications during compilation. * By enabling, this mod, and all of its descendants will be run in introspection mode. * This should only be used for static files like JSON or XML, and not for application files that require regexes, * or complex static files that require other files to be generated like Xcode `.pbxproj`. */ isIntrospective?: boolean; }; export interface ModConfig { android?: { /** * Dangerously make a modification before any other android mods have been run. */ dangerous?: Mod; /** * Modify the `android/app/src/main/AndroidManifest.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)). */ manifest?: Mod; /** * Modify the `android/app/src/main/res/values/strings.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)). */ strings?: Mod; /** * Modify the `android/app/src/main/res/values/colors.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)). */ colors?: Mod; /** * Modify the `android/app/src/main/res/values-night/colors.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)). */ colorsNight?: Mod; /** * Modify the `android/app/src/main/res/values/styles.xml` as JSON (parsed with [`xml2js`](https://www.npmjs.com/package/xml2js)). */ styles?: Mod; /** * Modify the `android/app/src/main//MainActivity.java` as a string. */ mainActivity?: Mod; /** * Modify the `android/app/src/main//MainApplication.java` as a string. */ mainApplication?: Mod; /** * Modify the `android/app/build.gradle` as a string. */ appBuildGradle?: Mod; /** * Modify the `android/build.gradle` as a string. */ projectBuildGradle?: Mod; /** * Modify the `android/settings.gradle` as a string. */ settingsGradle?: Mod; /** * Modify the `android/gradle.properties` as a `Properties.PropertiesItem[]`. */ gradleProperties?: Mod; }; ios?: { /** * Dangerously make a modification before any other android mods have been run. */ dangerous?: Mod; /** * Modify the `ios//Info.plist` as JSON (parsed with [`@expo/plist`](https://www.npmjs.com/package/@expo/plist)). */ infoPlist?: Mod; /** * Modify the `ios//.entitlements` as JSON (parsed with [`@expo/plist`](https://www.npmjs.com/package/@expo/plist)). */ entitlements?: Mod; /** * Modify the `ios//Expo.plist` as JSON (Expo updates config for iOS) (parsed with [`@expo/plist`](https://www.npmjs.com/package/@expo/plist)). */ expoPlist?: Mod; /** * Modify the `ios/.xcodeproj` as an `XcodeProject` (parsed with [`xcode`](https://www.npmjs.com/package/xcode)) */ xcodeproj?: Mod; /** * Modify the `ios//AppDelegate.m` as a string (dangerous) */ appDelegate?: Mod; /** * Modify the `ios/Podfile.properties.json` as key-value pairs */ podfileProperties?: Mod>; }; } export type ModPlatform = keyof ModConfig; export { XcodeProject, InfoPlist, ExpoPlist, AndroidManifest };