import { Platform } from '@expo/eas-build-job' ; import { MissingParentProfileError , MissingProfileError } from '../errors' ; import { EasJson } from '../types' ; import { BuildProfileSchema } from './schema' ; import { BuildProfile , EasJsonBuildProfile } from './types' ; type EasJsonBuildProfileResolved = Omit < EasJsonBuildProfile , 'extends' > ; export function resolveBuildProfile < T extends Platform > ( { easJson , platform , profileName , } ) { const easJsonProfile = resolveProfile ( { easJson , profileName , } ) ; const { android , ios , ... base } = easJsonProfile ; const withoutDefaults = mergeProfiles ( base , easJsonProfile [ platform ] ?? { } ) ; return mergeProfiles ( getDefaultProfile ( platform ) , withoutDefaults ) as BuildProfile < T > ; } function resolveProfile ( { easJson , profileName , depth = 0 , } ) { if ( depth >= 2 ) { throw new Error ( 'Too long chain of profile extensions, make sure "extends" keys do not make a cycle' ) ; } const profile = easJson . build ?. [ profileName ] ; if ( ! profile ) { if ( depth === 0 ) { throw new MissingProfileError ( `Missing build profile in eas.json: ${ profileName }` ) ; } else { throw new MissingParentProfileError ( `Extending non-existent build profile in eas.json: ${ profileName }` ) ; } } const { extends : baseProfileName , ... rest } = profile ; if ( baseProfileName ) { const baseProfile = resolveProfile ( { easJson , profileName : baseProfileName , depth : depth + 1 , } ) ; return mergeProfiles ( baseProfile , rest ) ; } else { return rest ; } } function mergeProfiles ( base , update ) { const result = { ... base , ... update , } ; if ( base . env && update . env ) { result . env = { ... base . env , ... update . env , } ; } if ( base . android && update . android ) { result . android = mergeProfiles ( base . android , update . android ) ; } if ( base . ios && update . ios ) { result . ios = mergeProfiles ( base . ios , update . ios ) ; } return result ; } function getDefaultProfile < T extends Platform > ( platform ) { const defaultProfile = BuildProfileSchema . validate ( { } , { allowUnknown : false , abortEarly : false , convert : true } ) . value ; const { android , ios , ... base } = defaultProfile ; return mergeProfiles ( base , defaultProfile [ platform ] ) ; }