1082815dcSEvan Baconimport { ExpoConfig } from '@expo/config-types'; 2082815dcSEvan Baconimport plist from '@expo/plist'; 3082815dcSEvan Baconimport assert from 'assert'; 4082815dcSEvan Baconimport fs from 'fs'; 5082815dcSEvan Baconimport path from 'path'; 6082815dcSEvan Baconimport { XcodeProject } from 'xcode'; 7082815dcSEvan Bacon 8082815dcSEvan Baconimport { InfoPlist } from './IosConfig.types'; 9082815dcSEvan Baconimport { getSourceRoot } from './Paths'; 10082815dcSEvan Baconimport { appendScheme } from './Scheme'; 11082815dcSEvan Baconimport { addResourceFileToGroup, getProjectName } from './utils/Xcodeproj'; 12*8a424bebSJames Ideimport { ConfigPlugin, ModProps } from '../Plugin.types'; 13*8a424bebSJames Ideimport { withInfoPlist, withXcodeProject } from '../plugins/ios-plugins'; 14082815dcSEvan Bacon 15082815dcSEvan Baconexport const withGoogle: ConfigPlugin = (config) => { 16082815dcSEvan Bacon return withInfoPlist(config, (config) => { 17082815dcSEvan Bacon config.modResults = setGoogleConfig(config, config.modResults, config.modRequest); 18082815dcSEvan Bacon return config; 19082815dcSEvan Bacon }); 20082815dcSEvan Bacon}; 21082815dcSEvan Bacon 22082815dcSEvan Baconexport const withGoogleServicesFile: ConfigPlugin = (config) => { 23082815dcSEvan Bacon return withXcodeProject(config, (config) => { 24082815dcSEvan Bacon config.modResults = setGoogleServicesFile(config, { 25082815dcSEvan Bacon projectRoot: config.modRequest.projectRoot, 26082815dcSEvan Bacon project: config.modResults, 27082815dcSEvan Bacon }); 28082815dcSEvan Bacon return config; 29082815dcSEvan Bacon }); 30082815dcSEvan Bacon}; 31082815dcSEvan Bacon 32082815dcSEvan Baconfunction readGoogleServicesInfoPlist( 33082815dcSEvan Bacon relativePath: string, 34082815dcSEvan Bacon { projectRoot }: { projectRoot: string } 35082815dcSEvan Bacon) { 36082815dcSEvan Bacon const googleServiceFilePath = path.resolve(projectRoot, relativePath); 37082815dcSEvan Bacon const contents = fs.readFileSync(googleServiceFilePath, 'utf8'); 38082815dcSEvan Bacon assert(contents, 'GoogleService-Info.plist is empty'); 39082815dcSEvan Bacon return plist.parse(contents); 40082815dcSEvan Bacon} 41082815dcSEvan Bacon 425f51f606SEvan Baconexport function getGoogleSignInReversedClientId( 43082815dcSEvan Bacon config: Pick<ExpoConfig, 'ios'>, 44082815dcSEvan Bacon modRequest: Pick<ModProps<InfoPlist>, 'projectRoot'> 45082815dcSEvan Bacon): string | null { 46082815dcSEvan Bacon const googleServicesFileRelativePath = getGoogleServicesFile(config); 47082815dcSEvan Bacon if (googleServicesFileRelativePath === null) { 48082815dcSEvan Bacon return null; 49082815dcSEvan Bacon } 50082815dcSEvan Bacon 51082815dcSEvan Bacon const infoPlist = readGoogleServicesInfoPlist(googleServicesFileRelativePath, modRequest); 52082815dcSEvan Bacon 53082815dcSEvan Bacon return infoPlist.REVERSED_CLIENT_ID ?? null; 54082815dcSEvan Bacon} 55082815dcSEvan Bacon 56082815dcSEvan Baconexport function getGoogleServicesFile(config: Pick<ExpoConfig, 'ios'>) { 57082815dcSEvan Bacon return config.ios?.googleServicesFile ?? null; 58082815dcSEvan Bacon} 59082815dcSEvan Bacon 605f51f606SEvan Baconexport function setGoogleSignInReversedClientId( 61082815dcSEvan Bacon config: Pick<ExpoConfig, 'ios'>, 62082815dcSEvan Bacon infoPlist: InfoPlist, 63082815dcSEvan Bacon modRequest: Pick<ModProps<InfoPlist>, 'projectRoot'> 64082815dcSEvan Bacon): InfoPlist { 655f51f606SEvan Bacon const reversedClientId = getGoogleSignInReversedClientId(config, modRequest); 66082815dcSEvan Bacon 675f51f606SEvan Bacon if (reversedClientId === null) { 68082815dcSEvan Bacon return infoPlist; 69082815dcSEvan Bacon } 70082815dcSEvan Bacon 715f51f606SEvan Bacon return appendScheme(reversedClientId, infoPlist); 72082815dcSEvan Bacon} 73082815dcSEvan Bacon 74082815dcSEvan Baconexport function setGoogleConfig( 75082815dcSEvan Bacon config: Pick<ExpoConfig, 'ios'>, 76082815dcSEvan Bacon infoPlist: InfoPlist, 77082815dcSEvan Bacon modRequest: ModProps<InfoPlist> 78082815dcSEvan Bacon): InfoPlist { 795f51f606SEvan Bacon infoPlist = setGoogleSignInReversedClientId(config, infoPlist, modRequest); 80082815dcSEvan Bacon return infoPlist; 81082815dcSEvan Bacon} 82082815dcSEvan Bacon 83082815dcSEvan Baconexport function setGoogleServicesFile( 84082815dcSEvan Bacon config: Pick<ExpoConfig, 'ios'>, 85082815dcSEvan Bacon { projectRoot, project }: { project: XcodeProject; projectRoot: string } 86082815dcSEvan Bacon): XcodeProject { 87082815dcSEvan Bacon const googleServicesFileRelativePath = getGoogleServicesFile(config); 88082815dcSEvan Bacon if (googleServicesFileRelativePath === null) { 89082815dcSEvan Bacon return project; 90082815dcSEvan Bacon } 91082815dcSEvan Bacon 92082815dcSEvan Bacon const googleServiceFilePath = path.resolve(projectRoot, googleServicesFileRelativePath); 93082815dcSEvan Bacon fs.copyFileSync( 94082815dcSEvan Bacon googleServiceFilePath, 95082815dcSEvan Bacon path.join(getSourceRoot(projectRoot), 'GoogleService-Info.plist') 96082815dcSEvan Bacon ); 97082815dcSEvan Bacon 98082815dcSEvan Bacon const projectName = getProjectName(projectRoot); 99082815dcSEvan Bacon const plistFilePath = `${projectName}/GoogleService-Info.plist`; 100082815dcSEvan Bacon if (!project.hasFile(plistFilePath)) { 101082815dcSEvan Bacon project = addResourceFileToGroup({ 102082815dcSEvan Bacon filepath: plistFilePath, 103082815dcSEvan Bacon groupName: projectName, 104082815dcSEvan Bacon project, 105082815dcSEvan Bacon isBuildFile: true, 106082815dcSEvan Bacon verbose: true, 107082815dcSEvan Bacon }); 108082815dcSEvan Bacon } 109082815dcSEvan Bacon return project; 110082815dcSEvan Bacon} 111