1{"version":3,"file":"BundleIdentifier.js","names":["withBundleIdentifier","config","bundleIdentifier","withDangerousMod","bundleId","ios","assert","setBundleIdentifierForPbxproj","modRequest","projectRoot","getBundleIdentifier","setBundleIdentifier","infoPlist","CFBundleIdentifier","getBundleIdentifierFromPbxproj","targetName","buildConfiguration","pbxprojPath","getPBXProjectPath","project","xcode","parseSync","xcBuildConfiguration","getXCBuildConfigurationFromPbxproj","getProductBundleIdentifierFromBuildConfiguration","bundleIdentifierRaw","buildSettings","PRODUCT_BUNDLE_IDENTIFIER","trimQuotes","bundleIdentifierParts","split","length","PRODUCT_NAME","replace","join","updateBundleIdentifierForPbxproj","updateProductName","nativeTarget","findFirstNativeTarget","getBuildConfigurationsForListId","buildConfigurationList","forEach","item","productName","pop","includes","fs","writeFileSync","writeSync","pbxprojPaths","getAllPBXProjectPaths","defaultBundleId","resetAllPlistBundleIdentifiers","infoPlistPaths","getAllInfoPlistPaths","plistPath","resetPlistBundleIdentifier","rawPlist","readFileSync","plistObject","plist","parse","format","pretty","indent","xml","build"],"sources":["../../src/ios/BundleIdentifier.ts"],"sourcesContent":["import { ExpoConfig } from '@expo/config-types';\nimport plist, { PlistObject } from '@expo/plist';\nimport assert from 'assert';\nimport fs from 'fs';\nimport xcode, { XCBuildConfiguration } from 'xcode';\n\nimport { ConfigPlugin } from '../Plugin.types';\nimport { withDangerousMod } from '../plugins/withDangerousMod';\nimport { InfoPlist } from './IosConfig.types';\nimport { getAllInfoPlistPaths, getAllPBXProjectPaths, getPBXProjectPath } from './Paths';\nimport { findFirstNativeTarget, getXCBuildConfigurationFromPbxproj } from './Target';\nimport { ConfigurationSectionEntry, getBuildConfigurationsForListId } from './utils/Xcodeproj';\nimport { trimQuotes } from './utils/string';\n\nexport const withBundleIdentifier: ConfigPlugin<{ bundleIdentifier?: string }> = (\n config,\n { bundleIdentifier }\n) => {\n return withDangerousMod(config, [\n 'ios',\n async (config) => {\n const bundleId = bundleIdentifier ?? config.ios?.bundleIdentifier;\n assert(\n bundleId,\n '`bundleIdentifier` must be defined in the app config (`expo.ios.bundleIdentifier`) or passed to the plugin `withBundleIdentifier`.'\n );\n await setBundleIdentifierForPbxproj(config.modRequest.projectRoot, bundleId!);\n return config;\n },\n ]);\n};\n\nfunction getBundleIdentifier(config: Pick<ExpoConfig, 'ios'>): string | null {\n return config.ios?.bundleIdentifier ?? null;\n}\n\n/**\n * In Turtle v1 we set the bundleIdentifier directly on Info.plist rather\n * than in pbxproj\n */\nfunction setBundleIdentifier(config: ExpoConfig, infoPlist: InfoPlist): InfoPlist {\n const bundleIdentifier = getBundleIdentifier(config);\n\n if (!bundleIdentifier) {\n return infoPlist;\n }\n\n return {\n ...infoPlist,\n CFBundleIdentifier: bundleIdentifier,\n };\n}\n\n/**\n * Gets the bundle identifier defined in the Xcode project found in the project directory.\n *\n * A bundle identifier is stored as a value in XCBuildConfiguration entry.\n * Those entries exist for every pair (build target, build configuration).\n * Unless target name is passed, the first target defined in the pbxproj is used\n * (to keep compatibility with the inaccurate legacy implementation of this function).\n * The build configuration is usually 'Release' or 'Debug'. However, it could be any arbitrary string.\n * Defaults to 'Release'.\n *\n * @param {string} projectRoot Path to project root containing the ios directory\n * @param {string} targetName Target name\n * @param {string} buildConfiguration Build configuration. Defaults to 'Release'.\n * @returns {string | null} bundle identifier of the Xcode project or null if the project is not configured\n */\nfunction getBundleIdentifierFromPbxproj(\n projectRoot: string,\n {\n targetName,\n buildConfiguration = 'Release',\n }: { targetName?: string; buildConfiguration?: string } = {}\n): string | null {\n let pbxprojPath: string;\n try {\n pbxprojPath = getPBXProjectPath(projectRoot);\n } catch {\n return null;\n }\n const project = xcode.project(pbxprojPath);\n project.parseSync();\n\n const xcBuildConfiguration = getXCBuildConfigurationFromPbxproj(project, {\n targetName,\n buildConfiguration,\n });\n if (!xcBuildConfiguration) {\n return null;\n }\n return getProductBundleIdentifierFromBuildConfiguration(xcBuildConfiguration);\n}\n\nfunction getProductBundleIdentifierFromBuildConfiguration(\n xcBuildConfiguration: XCBuildConfiguration\n): string | null {\n const bundleIdentifierRaw = xcBuildConfiguration.buildSettings.PRODUCT_BUNDLE_IDENTIFIER;\n if (bundleIdentifierRaw) {\n const bundleIdentifier = trimQuotes(bundleIdentifierRaw);\n // it's possible to use interpolation for the bundle identifier\n // the most common case is when the last part of the id is set to `$(PRODUCT_NAME:rfc1034identifier)`\n // in this case, PRODUCT_NAME should be replaced with its value\n // the `rfc1034identifier` modifier replaces all non-alphanumeric characters with dashes\n const bundleIdentifierParts = bundleIdentifier.split('.');\n if (\n bundleIdentifierParts[bundleIdentifierParts.length - 1] ===\n '$(PRODUCT_NAME:rfc1034identifier)' &&\n xcBuildConfiguration.buildSettings.PRODUCT_NAME\n ) {\n bundleIdentifierParts[bundleIdentifierParts.length - 1] =\n xcBuildConfiguration.buildSettings.PRODUCT_NAME.replace(/[^a-zA-Z0-9]/g, '-');\n }\n return bundleIdentifierParts.join('.');\n } else {\n return null;\n }\n}\n\n/**\n * Updates the bundle identifier for a given pbxproj\n *\n * @param {string} pbxprojPath Path to pbxproj file\n * @param {string} bundleIdentifier Bundle identifier to set in the pbxproj\n * @param {boolean} [updateProductName=true] Whether to update PRODUCT_NAME\n */\nfunction updateBundleIdentifierForPbxproj(\n pbxprojPath: string,\n bundleIdentifier: string,\n updateProductName: boolean = true\n): void {\n const project = xcode.project(pbxprojPath);\n project.parseSync();\n\n const [, nativeTarget] = findFirstNativeTarget(project);\n\n getBuildConfigurationsForListId(project, nativeTarget.buildConfigurationList).forEach(\n ([, item]: ConfigurationSectionEntry) => {\n if (item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER === bundleIdentifier) {\n return;\n }\n\n item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER = `\"${bundleIdentifier}\"`;\n\n if (updateProductName) {\n const productName = bundleIdentifier.split('.').pop();\n if (!productName?.includes('$')) {\n item.buildSettings.PRODUCT_NAME = productName;\n }\n }\n }\n );\n fs.writeFileSync(pbxprojPath, project.writeSync());\n}\n\n/**\n * Updates the bundle identifier for pbx projects inside the ios directory of the given project root\n *\n * @param {string} projectRoot Path to project root containing the ios directory\n * @param {string} bundleIdentifier Desired bundle identifier\n * @param {boolean} [updateProductName=true] Whether to update PRODUCT_NAME\n */\nfunction setBundleIdentifierForPbxproj(\n projectRoot: string,\n bundleIdentifier: string,\n updateProductName: boolean = true\n): void {\n // Get all pbx projects in the ${projectRoot}/ios directory\n let pbxprojPaths: string[] = [];\n try {\n pbxprojPaths = getAllPBXProjectPaths(projectRoot);\n } catch {}\n\n for (const pbxprojPath of pbxprojPaths) {\n updateBundleIdentifierForPbxproj(pbxprojPath, bundleIdentifier, updateProductName);\n }\n}\n\n/**\n * Reset bundle identifier field in Info.plist to use PRODUCT_BUNDLE_IDENTIFIER, as recommended by Apple.\n */\n\nconst defaultBundleId = '$(PRODUCT_BUNDLE_IDENTIFIER)';\n\nfunction resetAllPlistBundleIdentifiers(projectRoot: string): void {\n const infoPlistPaths = getAllInfoPlistPaths(projectRoot);\n\n for (const plistPath of infoPlistPaths) {\n resetPlistBundleIdentifier(plistPath);\n }\n}\n\nfunction resetPlistBundleIdentifier(plistPath: string): void {\n const rawPlist = fs.readFileSync(plistPath, 'utf8');\n const plistObject = plist.parse(rawPlist) as PlistObject;\n\n if (plistObject.CFBundleIdentifier) {\n if (plistObject.CFBundleIdentifier === defaultBundleId) return;\n\n // attempt to match default Info.plist format\n const format = { pretty: true, indent: `\\t` };\n\n const xml = plist.build(\n {\n ...plistObject,\n CFBundleIdentifier: defaultBundleId,\n },\n format\n );\n\n if (xml !== rawPlist) {\n fs.writeFileSync(plistPath, xml);\n }\n }\n}\n\nexport {\n getBundleIdentifier,\n setBundleIdentifier,\n getBundleIdentifierFromPbxproj,\n updateBundleIdentifierForPbxproj,\n setBundleIdentifierForPbxproj,\n resetAllPlistBundleIdentifiers,\n resetPlistBundleIdentifier,\n};\n"],"mappings":";;;;;;;;;;;;;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AAGA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AAEA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;AACA;EAAA;;EAAA;IAAA;EAAA;;EAAA;AAAA;;;;AAEO,MAAMA,oBAAiE,GAAG,CAC/EC,MAD+E,EAE/E;EAAEC;AAAF,CAF+E,KAG5E;EACH,OAAO,IAAAC,oCAAA,EAAiBF,MAAjB,EAAyB,CAC9B,KAD8B,EAE9B,MAAOA,MAAP,IAAkB;IAAA;;IAChB,MAAMG,QAAQ,GAAGF,gBAAH,aAAGA,gBAAH,cAAGA,gBAAH,kBAAuBD,MAAM,CAACI,GAA9B,gDAAuB,YAAYH,gBAAjD;IACA,IAAAI,iBAAA,EACEF,QADF,EAEE,oIAFF;IAIA,MAAMG,6BAA6B,CAACN,MAAM,CAACO,UAAP,CAAkBC,WAAnB,EAAgCL,QAAhC,CAAnC;IACA,OAAOH,MAAP;EACD,CAV6B,CAAzB,CAAP;AAYD,CAhBM;;;;AAkBP,SAASS,mBAAT,CAA6BT,MAA7B,EAA6E;EAAA;;EAC3E,gDAAOA,MAAM,CAACI,GAAd,iDAAO,aAAYH,gBAAnB,yEAAuC,IAAvC;AACD;AAED;AACA;AACA;AACA;;;AACA,SAASS,mBAAT,CAA6BV,MAA7B,EAAiDW,SAAjD,EAAkF;EAChF,MAAMV,gBAAgB,GAAGQ,mBAAmB,CAACT,MAAD,CAA5C;;EAEA,IAAI,CAACC,gBAAL,EAAuB;IACrB,OAAOU,SAAP;EACD;;EAED,OAAO,EACL,GAAGA,SADE;IAELC,kBAAkB,EAAEX;EAFf,CAAP;AAID;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASY,8BAAT,CACEL,WADF,EAEE;EACEM,UADF;EAEEC,kBAAkB,GAAG;AAFvB,IAG0D,EAL5D,EAMiB;EACf,IAAIC,WAAJ;;EACA,IAAI;IACFA,WAAW,GAAG,IAAAC,0BAAA,EAAkBT,WAAlB,CAAd;EACD,CAFD,CAEE,MAAM;IACN,OAAO,IAAP;EACD;;EACD,MAAMU,OAAO,GAAGC,gBAAA,CAAMD,OAAN,CAAcF,WAAd,CAAhB;;EACAE,OAAO,CAACE,SAAR;EAEA,MAAMC,oBAAoB,GAAG,IAAAC,4CAAA,EAAmCJ,OAAnC,EAA4C;IACvEJ,UADuE;IAEvEC;EAFuE,CAA5C,CAA7B;;EAIA,IAAI,CAACM,oBAAL,EAA2B;IACzB,OAAO,IAAP;EACD;;EACD,OAAOE,gDAAgD,CAACF,oBAAD,CAAvD;AACD;;AAED,SAASE,gDAAT,CACEF,oBADF,EAEiB;EACf,MAAMG,mBAAmB,GAAGH,oBAAoB,CAACI,aAArB,CAAmCC,yBAA/D;;EACA,IAAIF,mBAAJ,EAAyB;IACvB,MAAMvB,gBAAgB,GAAG,IAAA0B,oBAAA,EAAWH,mBAAX,CAAzB,CADuB,CAEvB;IACA;IACA;IACA;;IACA,MAAMI,qBAAqB,GAAG3B,gBAAgB,CAAC4B,KAAjB,CAAuB,GAAvB,CAA9B;;IACA,IACED,qBAAqB,CAACA,qBAAqB,CAACE,MAAtB,GAA+B,CAAhC,CAArB,KACE,mCADF,IAEAT,oBAAoB,CAACI,aAArB,CAAmCM,YAHrC,EAIE;MACAH,qBAAqB,CAACA,qBAAqB,CAACE,MAAtB,GAA+B,CAAhC,CAArB,GACET,oBAAoB,CAACI,aAArB,CAAmCM,YAAnC,CAAgDC,OAAhD,CAAwD,eAAxD,EAAyE,GAAzE,CADF;IAED;;IACD,OAAOJ,qBAAqB,CAACK,IAAtB,CAA2B,GAA3B,CAAP;EACD,CAhBD,MAgBO;IACL,OAAO,IAAP;EACD;AACF;AAED;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASC,gCAAT,CACElB,WADF,EAEEf,gBAFF,EAGEkC,iBAA0B,GAAG,IAH/B,EAIQ;EACN,MAAMjB,OAAO,GAAGC,gBAAA,CAAMD,OAAN,CAAcF,WAAd,CAAhB;;EACAE,OAAO,CAACE,SAAR;EAEA,MAAM,GAAGgB,YAAH,IAAmB,IAAAC,+BAAA,EAAsBnB,OAAtB,CAAzB;EAEA,IAAAoB,4CAAA,EAAgCpB,OAAhC,EAAyCkB,YAAY,CAACG,sBAAtD,EAA8EC,OAA9E,CACE,CAAC,GAAGC,IAAH,CAAD,KAAyC;IACvC,IAAIA,IAAI,CAAChB,aAAL,CAAmBC,yBAAnB,KAAiDzB,gBAArD,EAAuE;MACrE;IACD;;IAEDwC,IAAI,CAAChB,aAAL,CAAmBC,yBAAnB,GAAgD,IAAGzB,gBAAiB,GAApE;;IAEA,IAAIkC,iBAAJ,EAAuB;MACrB,MAAMO,WAAW,GAAGzC,gBAAgB,CAAC4B,KAAjB,CAAuB,GAAvB,EAA4Bc,GAA5B,EAApB;;MACA,IAAI,EAACD,WAAD,aAACA,WAAD,eAACA,WAAW,CAAEE,QAAb,CAAsB,GAAtB,CAAD,CAAJ,EAAiC;QAC/BH,IAAI,CAAChB,aAAL,CAAmBM,YAAnB,GAAkCW,WAAlC;MACD;IACF;EACF,CAdH;;EAgBAG,aAAA,CAAGC,aAAH,CAAiB9B,WAAjB,EAA8BE,OAAO,CAAC6B,SAAR,EAA9B;AACD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASzC,6BAAT,CACEE,WADF,EAEEP,gBAFF,EAGEkC,iBAA0B,GAAG,IAH/B,EAIQ;EACN;EACA,IAAIa,YAAsB,GAAG,EAA7B;;EACA,IAAI;IACFA,YAAY,GAAG,IAAAC,8BAAA,EAAsBzC,WAAtB,CAAf;EACD,CAFD,CAEE,MAAM,CAAE;;EAEV,KAAK,MAAMQ,WAAX,IAA0BgC,YAA1B,EAAwC;IACtCd,gCAAgC,CAAClB,WAAD,EAAcf,gBAAd,EAAgCkC,iBAAhC,CAAhC;EACD;AACF;AAED;AACA;AACA;;;AAEA,MAAMe,eAAe,GAAG,8BAAxB;;AAEA,SAASC,8BAAT,CAAwC3C,WAAxC,EAAmE;EACjE,MAAM4C,cAAc,GAAG,IAAAC,6BAAA,EAAqB7C,WAArB,CAAvB;;EAEA,KAAK,MAAM8C,SAAX,IAAwBF,cAAxB,EAAwC;IACtCG,0BAA0B,CAACD,SAAD,CAA1B;EACD;AACF;;AAED,SAASC,0BAAT,CAAoCD,SAApC,EAA6D;EAC3D,MAAME,QAAQ,GAAGX,aAAA,CAAGY,YAAH,CAAgBH,SAAhB,EAA2B,MAA3B,CAAjB;;EACA,MAAMI,WAAW,GAAGC,gBAAA,CAAMC,KAAN,CAAYJ,QAAZ,CAApB;;EAEA,IAAIE,WAAW,CAAC9C,kBAAhB,EAAoC;IAClC,IAAI8C,WAAW,CAAC9C,kBAAZ,KAAmCsC,eAAvC,EAAwD,OADtB,CAGlC;;IACA,MAAMW,MAAM,GAAG;MAAEC,MAAM,EAAE,IAAV;MAAgBC,MAAM,EAAG;IAAzB,CAAf;;IAEA,MAAMC,GAAG,GAAGL,gBAAA,CAAMM,KAAN,CACV,EACE,GAAGP,WADL;MAEE9C,kBAAkB,EAAEsC;IAFtB,CADU,EAKVW,MALU,CAAZ;;IAQA,IAAIG,GAAG,KAAKR,QAAZ,EAAsB;MACpBX,aAAA,CAAGC,aAAH,CAAiBQ,SAAjB,EAA4BU,GAA5B;IACD;EACF;AACF"}