import { ExpoConfig } from '@expo/config-types' ; import { JSONObject } from '@expo/json-file' ; import fs from 'fs-extra' ; import path from 'path' ; import slash from 'slash' ; import { createEntitlementsPlugin } from '../plugins/ios-plugins' ; import * as Paths from './Paths' ; import { getPbxproj , getProductName , getProjectName , isBuildConfig , isNotComment , isNotTestHost , } from './utils/Xcodeproj' ; export const withAssociatedDomains = createEntitlementsPlugin ( setAssociatedDomains , 'withAssociatedDomains' ) ; export function setAssociatedDomains ( config , { 'com.apple.developer.associated-domains' : _ , ... entitlementsPlist } ) { if ( config . ios ?. associatedDomains ) { return { ... entitlementsPlist , 'com.apple.developer.associated-domains' : config . ios . associatedDomains } ; } return entitlementsPlist ; } export function getEntitlementsPath ( projectRoot ) { const paths = Paths . getAllEntitlementsPaths ( projectRoot ) ; let targetPath = null ; /**
     * Add file to pbxproj under CODE_SIGN_ENTITLEMENTS
     */ const project = getPbxproj ( projectRoot ) ; const projectName = getProjectName ( projectRoot ) ; const productName = getProductName ( project ) ; const entitlementsRelativePath = slash ( path . join ( projectName , `${ productName }.entitlements` ) ) ; const entitlementsPath = slash ( path . normalize ( path . join ( projectRoot , 'ios' , entitlementsRelativePath ) ) ) ; const pathsToDelete = [ ] ; while ( paths . length ) { const last = slash ( path . normalize ( paths . pop ( ) ! ) ) ; if ( last !== entitlementsPath ) { pathsToDelete . push ( last ) ; } else { targetPath = last ; } } if ( ! targetPath ) { targetPath = entitlementsPath ; let template = ENTITLEMENTS_TEMPLATE ; if ( pathsToDelete . length ) { const last = pathsToDelete [ pathsToDelete . length - 1 ] ! ; template = fs . readFileSync ( last , 'utf8' ) ; } fs . ensureDirSync ( path . dirname ( entitlementsPath ) ) ; fs . writeFileSync ( entitlementsPath , template ) ; Object . entries ( project . pbxXCBuildConfigurationSection ( ) ) . filter ( isNotComment ) . filter ( isBuildConfig ) . filter ( isNotTestHost ) . forEach ( ( { 1 : { buildSettings } } ) => { buildSettings . CODE_SIGN_ENTITLEMENTS = `"${ entitlementsRelativePath }"` ; } ) ; fs . writeFileSync ( project . filepath , project . writeSync ( ) ) ; } deleteEntitlementsFiles ( pathsToDelete ) ; return entitlementsPath ; } function deleteEntitlementsFiles ( entitlementsPaths ) { for ( const path of entitlementsPaths ) { fs . removeSync ( path ) ; } } const ENTITLEMENTS_TEMPLATE = `
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
</dict>
</plist>
` ;