customerio-expo-plugin 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/package.json +8 -1
  2. package/plugin/lib/commonjs/android/withAndroidManifestUpdates.js +64 -59
  3. package/plugin/lib/commonjs/android/withAndroidManifestUpdates.js.map +1 -1
  4. package/plugin/lib/commonjs/android/withAppGoogleServices.js +10 -7
  5. package/plugin/lib/commonjs/android/withAppGoogleServices.js.map +1 -1
  6. package/plugin/lib/commonjs/android/withGoogleServicesJSON.js +18 -21
  7. package/plugin/lib/commonjs/android/withGoogleServicesJSON.js.map +1 -1
  8. package/plugin/lib/commonjs/android/withLocationGradleProperties.js +16 -12
  9. package/plugin/lib/commonjs/android/withLocationGradleProperties.js.map +1 -1
  10. package/plugin/lib/commonjs/android/withMainApplicationModifications.js +19 -12
  11. package/plugin/lib/commonjs/android/withMainApplicationModifications.js.map +1 -1
  12. package/plugin/lib/commonjs/android/withNotificationChannelMetadata.js +2 -1
  13. package/plugin/lib/commonjs/android/withNotificationChannelMetadata.js.map +1 -1
  14. package/plugin/lib/commonjs/android/withProjectBuildGradle.js +29 -25
  15. package/plugin/lib/commonjs/android/withProjectBuildGradle.js.map +1 -1
  16. package/plugin/lib/commonjs/android/withProjectGoogleServices.js +9 -5
  17. package/plugin/lib/commonjs/android/withProjectGoogleServices.js.map +1 -1
  18. package/plugin/lib/commonjs/helpers/constants/ios.js +76 -8
  19. package/plugin/lib/commonjs/helpers/constants/ios.js.map +1 -1
  20. package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js +76 -31
  21. package/plugin/lib/commonjs/helpers/utils/injectCIOPodfileCode.js.map +1 -1
  22. package/plugin/lib/commonjs/index.js +7 -0
  23. package/plugin/lib/commonjs/index.js.map +1 -1
  24. package/plugin/lib/commonjs/ios/withAppDelegateModifications.js +47 -33
  25. package/plugin/lib/commonjs/ios/withAppDelegateModifications.js.map +1 -1
  26. package/plugin/lib/commonjs/ios/withCIOIosSwift.js +44 -54
  27. package/plugin/lib/commonjs/ios/withCIOIosSwift.js.map +1 -1
  28. package/plugin/lib/commonjs/ios/withGoogleServicesJsonFile.js +46 -30
  29. package/plugin/lib/commonjs/ios/withGoogleServicesJsonFile.js.map +1 -1
  30. package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js +192 -122
  31. package/plugin/lib/commonjs/ios/withNotificationsXcodeProject.js.map +1 -1
  32. package/plugin/lib/commonjs/postInstallHelper.js +58 -11
  33. package/plugin/lib/commonjs/postInstallHelper.js.map +1 -1
  34. package/plugin/lib/commonjs/utils/resolveRNSDK.js +97 -0
  35. package/plugin/lib/commonjs/utils/resolveRNSDK.js.map +1 -0
  36. package/plugin/lib/commonjs/utils/writeExpoVersion.js +56 -0
  37. package/plugin/lib/commonjs/utils/writeExpoVersion.js.map +1 -0
  38. package/plugin/lib/module/android/withAndroidManifestUpdates.js +61 -58
  39. package/plugin/lib/module/android/withAndroidManifestUpdates.js.map +1 -1
  40. package/plugin/lib/module/android/withAppGoogleServices.js +9 -7
  41. package/plugin/lib/module/android/withAppGoogleServices.js.map +1 -1
  42. package/plugin/lib/module/android/withGoogleServicesJSON.js +17 -21
  43. package/plugin/lib/module/android/withGoogleServicesJSON.js.map +1 -1
  44. package/plugin/lib/module/android/withLocationGradleProperties.js +15 -12
  45. package/plugin/lib/module/android/withLocationGradleProperties.js.map +1 -1
  46. package/plugin/lib/module/android/withMainApplicationModifications.js +18 -12
  47. package/plugin/lib/module/android/withMainApplicationModifications.js.map +1 -1
  48. package/plugin/lib/module/android/withNotificationChannelMetadata.js +1 -1
  49. package/plugin/lib/module/android/withNotificationChannelMetadata.js.map +1 -1
  50. package/plugin/lib/module/android/withProjectBuildGradle.js +28 -25
  51. package/plugin/lib/module/android/withProjectBuildGradle.js.map +1 -1
  52. package/plugin/lib/module/android/withProjectGoogleServices.js +8 -5
  53. package/plugin/lib/module/android/withProjectGoogleServices.js.map +1 -1
  54. package/plugin/lib/module/helpers/constants/ios.js +75 -8
  55. package/plugin/lib/module/helpers/constants/ios.js.map +1 -1
  56. package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js +74 -31
  57. package/plugin/lib/module/helpers/utils/injectCIOPodfileCode.js.map +1 -1
  58. package/plugin/lib/module/index.js +7 -0
  59. package/plugin/lib/module/index.js.map +1 -1
  60. package/plugin/lib/module/ios/withAppDelegateModifications.js +45 -33
  61. package/plugin/lib/module/ios/withAppDelegateModifications.js.map +1 -1
  62. package/plugin/lib/module/ios/withCIOIosSwift.js +42 -54
  63. package/plugin/lib/module/ios/withCIOIosSwift.js.map +1 -1
  64. package/plugin/lib/module/ios/withGoogleServicesJsonFile.js +45 -30
  65. package/plugin/lib/module/ios/withGoogleServicesJsonFile.js.map +1 -1
  66. package/plugin/lib/module/ios/withNotificationsXcodeProject.js +187 -122
  67. package/plugin/lib/module/ios/withNotificationsXcodeProject.js.map +1 -1
  68. package/plugin/lib/module/postInstallHelper.js +58 -11
  69. package/plugin/lib/module/postInstallHelper.js.map +1 -1
  70. package/plugin/lib/module/utils/resolveRNSDK.js +88 -0
  71. package/plugin/lib/module/utils/resolveRNSDK.js.map +1 -0
  72. package/plugin/lib/module/utils/writeExpoVersion.js +48 -0
  73. package/plugin/lib/module/utils/writeExpoVersion.js.map +1 -0
  74. package/plugin/lib/typescript/android/withAndroidManifestUpdates.d.ts +2 -0
  75. package/plugin/lib/typescript/android/withAppGoogleServices.d.ts +1 -0
  76. package/plugin/lib/typescript/android/withGoogleServicesJSON.d.ts +1 -0
  77. package/plugin/lib/typescript/android/withLocationGradleProperties.d.ts +2 -0
  78. package/plugin/lib/typescript/android/withMainApplicationModifications.d.ts +6 -0
  79. package/plugin/lib/typescript/android/withNotificationChannelMetadata.d.ts +5 -0
  80. package/plugin/lib/typescript/android/withProjectBuildGradle.d.ts +9 -0
  81. package/plugin/lib/typescript/android/withProjectGoogleServices.d.ts +1 -0
  82. package/plugin/lib/typescript/helpers/constants/ios.d.ts +18 -0
  83. package/plugin/lib/typescript/helpers/utils/injectCIOPodfileCode.d.ts +25 -1
  84. package/plugin/lib/typescript/ios/withAppDelegateModifications.d.ts +13 -0
  85. package/plugin/lib/typescript/ios/withCIOIosSwift.d.ts +11 -0
  86. package/plugin/lib/typescript/ios/withGoogleServicesJsonFile.d.ts +14 -1
  87. package/plugin/lib/typescript/ios/withNotificationsXcodeProject.d.ts +53 -2
  88. package/plugin/lib/typescript/utils/resolveRNSDK.d.ts +7 -0
  89. package/plugin/lib/typescript/utils/writeExpoVersion.d.ts +3 -0
  90. package/plugin/src/android/withAndroidManifestUpdates.ts +83 -73
  91. package/plugin/src/android/withAppGoogleServices.ts +13 -11
  92. package/plugin/src/android/withGoogleServicesJSON.ts +30 -28
  93. package/plugin/src/android/withLocationGradleProperties.ts +23 -17
  94. package/plugin/src/android/withMainApplicationModifications.ts +25 -15
  95. package/plugin/src/android/withNotificationChannelMetadata.ts +1 -1
  96. package/plugin/src/android/withProjectBuildGradle.ts +37 -27
  97. package/plugin/src/android/withProjectGoogleServices.ts +14 -9
  98. package/plugin/src/helpers/constants/ios.ts +87 -8
  99. package/plugin/src/helpers/utils/injectCIOPodfileCode.ts +97 -50
  100. package/plugin/src/index.ts +7 -0
  101. package/plugin/src/ios/withAppDelegateModifications.ts +61 -48
  102. package/plugin/src/ios/withCIOIosSwift.ts +58 -62
  103. package/plugin/src/ios/withGoogleServicesJsonFile.ts +66 -48
  104. package/plugin/src/ios/withNotificationsXcodeProject.ts +257 -207
  105. package/plugin/src/postInstallHelper.js +75 -17
  106. package/plugin/src/utils/resolveRNSDK.ts +118 -0
  107. package/plugin/src/utils/writeExpoVersion.ts +62 -0
@@ -2,44 +2,59 @@ import { IOSConfig, withXcodeProject } from '@expo/config-plugins';
2
2
  import { logger } from '../utils/logger';
3
3
  import { FileManagement } from './../helpers/utils/fileManagement';
4
4
  import { isFcmPushProvider } from './utils';
5
+ /**
6
+ * Copies the FCM GoogleService-Info.plist into the iOS project (when needed) and registers it
7
+ * in the Xcode project's Resources group. Idempotent — no-ops if a plist is already present
8
+ * at either of the two well-known locations Expo / RN Firebase use.
9
+ */
10
+ export function copyGoogleServicePlistFile({
11
+ iosPath,
12
+ appName,
13
+ googleServicesFile,
14
+ expoIosGoogleServicesFileSet,
15
+ xcodeProject
16
+ }) {
17
+ const destination = `${iosPath}/GoogleService-Info.plist`;
18
+ if (FileManagement.exists(destination)) {
19
+ logger.info(`File already exists: ${destination}. Skipping...`);
20
+ return;
21
+ }
22
+ if (appName && FileManagement.exists(`${iosPath}/${appName}/GoogleService-Info.plist`)) {
23
+ // This is where RN Firebase potentially copies GoogleService-Info.plist
24
+ // Do not copy if it's already done by Firebase to avoid conflict in Resources
25
+ logger.info(`File already exists: ${iosPath}/${appName}/GoogleService-Info.plist. Skipping...`);
26
+ return;
27
+ }
28
+ if (googleServicesFile && FileManagement.exists(googleServicesFile)) {
29
+ if (expoIosGoogleServicesFileSet) {
30
+ logger.warn('Specifying both Expo ios.googleServicesFile and Customer.io ios.pushNotification.googleServicesFile can cause a conflict' + ' duplicating GoogleService-Info.plist in the iOS project resources. Please remove Customer.io ios.pushNotification.googleServicesFile');
31
+ }
32
+ try {
33
+ FileManagement.copyFile(googleServicesFile, destination);
34
+ addFileToXcodeProject(xcodeProject, 'GoogleService-Info.plist');
35
+ } catch {
36
+ logger.error(`There was an error copying your GoogleService-Info.plist file. You can copy it manually into ${destination}`);
37
+ }
38
+ } else {
39
+ logger.error(`The Google Services file provided in ${googleServicesFile} doesn't seem to exist. You can copy it manually into ${destination}`);
40
+ }
41
+ }
5
42
  export const withGoogleServicesJsonFile = (config, cioProps) => {
6
43
  return withXcodeProject(config, async props => {
7
- var _cioProps$pushNotific;
44
+ var _cioProps$pushNotific, _config$ios;
8
45
  const useFcm = isFcmPushProvider(cioProps);
9
46
  if (!useFcm) {
10
47
  // Nothing to do, for providers other than FCM, the Google services JSON file isn't needed
11
48
  return props;
12
49
  }
13
50
  logger.info('Only specify Customer.io ios.pushNotification.googleServicesFile config if you are not already including' + ' GoogleService-Info.plist as part of Firebase integration');
14
-
15
- // googleServicesFile
16
- const iosPath = props.modRequest.platformProjectRoot;
17
- const googleServicesFile = (_cioProps$pushNotific = cioProps.pushNotification) === null || _cioProps$pushNotific === void 0 ? void 0 : _cioProps$pushNotific.googleServicesFile;
18
- const appName = props.modRequest.projectName;
19
- if (FileManagement.exists(`${iosPath}/GoogleService-Info.plist`)) {
20
- logger.info(`File already exists: ${iosPath}/GoogleService-Info.plist. Skipping...`);
21
- return props;
22
- }
23
- if (FileManagement.exists(`${iosPath}/${appName}/GoogleService-Info.plist`)) {
24
- // This is where RN Firebase potentially copies GoogleService-Info.plist
25
- // Do not copy if it's already done by Firebase to avoid conflict in Resources
26
- logger.info(`File already exists: ${iosPath}/${appName}/GoogleService-Info.plist. Skipping...`);
27
- return props;
28
- }
29
- if (googleServicesFile && FileManagement.exists(googleServicesFile)) {
30
- var _config$ios;
31
- if ((_config$ios = config.ios) !== null && _config$ios !== void 0 && _config$ios.googleServicesFile) {
32
- logger.warn('Specifying both Expo ios.googleServicesFile and Customer.io ios.pushNotification.googleServicesFile can cause a conflict' + ' duplicating GoogleService-Info.plist in the iOS project resources. Please remove Customer.io ios.pushNotification.googleServicesFile');
33
- }
34
- try {
35
- FileManagement.copyFile(googleServicesFile, `${iosPath}/GoogleService-Info.plist`);
36
- addFileToXcodeProject(props.modResults, 'GoogleService-Info.plist');
37
- } catch {
38
- logger.error(`There was an error copying your GoogleService-Info.plist file. You can copy it manually into ${iosPath}/GoogleService-Info.plist`);
39
- }
40
- } else {
41
- logger.error(`The Google Services file provided in ${googleServicesFile} doesn't seem to exist. You can copy it manually into ${iosPath}/GoogleService-Info.plist`);
42
- }
51
+ copyGoogleServicePlistFile({
52
+ iosPath: props.modRequest.platformProjectRoot,
53
+ appName: props.modRequest.projectName,
54
+ googleServicesFile: (_cioProps$pushNotific = cioProps.pushNotification) === null || _cioProps$pushNotific === void 0 ? void 0 : _cioProps$pushNotific.googleServicesFile,
55
+ expoIosGoogleServicesFileSet: Boolean((_config$ios = config.ios) === null || _config$ios === void 0 ? void 0 : _config$ios.googleServicesFile),
56
+ xcodeProject: props.modResults
57
+ });
43
58
  return props;
44
59
  });
45
60
  };
@@ -1 +1 @@
1
- {"version":3,"names":["IOSConfig","withXcodeProject","logger","FileManagement","isFcmPushProvider","withGoogleServicesJsonFile","config","cioProps","props","_cioProps$pushNotific","useFcm","info","iosPath","modRequest","platformProjectRoot","googleServicesFile","pushNotification","appName","projectName","exists","_config$ios","ios","warn","copyFile","addFileToXcodeProject","modResults","error","project","fileName","groupName","filepath","XcodeUtils","ensureGroupRecursively","addResourceFileToGroup","isBuildFile"],"sources":["withGoogleServicesJsonFile.ts"],"sourcesContent":["import type { ConfigPlugin, XcodeProject } from '@expo/config-plugins';\nimport { IOSConfig, withXcodeProject } from '@expo/config-plugins';\n\nimport type { CustomerIOPluginOptionsIOS } from '../types/cio-types';\nimport { logger } from '../utils/logger';\nimport { FileManagement } from './../helpers/utils/fileManagement';\nimport { isFcmPushProvider } from './utils';\n\nexport const withGoogleServicesJsonFile: ConfigPlugin<\n CustomerIOPluginOptionsIOS\n> = (config, cioProps) => {\n return withXcodeProject(config, async (props) => {\n const useFcm = isFcmPushProvider(cioProps);\n if (!useFcm) {\n // Nothing to do, for providers other than FCM, the Google services JSON file isn't needed\n return props;\n }\n\n logger.info(\n 'Only specify Customer.io ios.pushNotification.googleServicesFile config if you are not already including' +\n ' GoogleService-Info.plist as part of Firebase integration'\n );\n\n // googleServicesFile\n const iosPath = props.modRequest.platformProjectRoot;\n const googleServicesFile = cioProps.pushNotification?.googleServicesFile;\n const appName = props.modRequest.projectName;\n\n if (FileManagement.exists(`${iosPath}/GoogleService-Info.plist`)) {\n logger.info(\n `File already exists: ${iosPath}/GoogleService-Info.plist. Skipping...`\n );\n return props;\n }\n\n if (\n FileManagement.exists(`${iosPath}/${appName}/GoogleService-Info.plist`)\n ) {\n // This is where RN Firebase potentially copies GoogleService-Info.plist\n // Do not copy if it's already done by Firebase to avoid conflict in Resources\n logger.info(\n `File already exists: ${iosPath}/${appName}/GoogleService-Info.plist. Skipping...`\n );\n return props;\n }\n\n if (googleServicesFile && FileManagement.exists(googleServicesFile)) {\n if (config.ios?.googleServicesFile) {\n logger.warn(\n 'Specifying both Expo ios.googleServicesFile and Customer.io ios.pushNotification.googleServicesFile can cause a conflict' +\n ' duplicating GoogleService-Info.plist in the iOS project resources. Please remove Customer.io ios.pushNotification.googleServicesFile'\n );\n }\n\n try {\n FileManagement.copyFile(\n googleServicesFile,\n `${iosPath}/GoogleService-Info.plist`\n );\n\n addFileToXcodeProject(props.modResults, 'GoogleService-Info.plist');\n } catch {\n logger.error(\n `There was an error copying your GoogleService-Info.plist file. You can copy it manually into ${iosPath}/GoogleService-Info.plist`\n );\n }\n } else {\n logger.error(\n `The Google Services file provided in ${googleServicesFile} doesn't seem to exist. You can copy it manually into ${iosPath}/GoogleService-Info.plist`\n );\n }\n\n return props;\n });\n};\n\nfunction addFileToXcodeProject(project: XcodeProject, fileName: string) {\n const groupName = 'Resources';\n const filepath = fileName;\n\n if (!IOSConfig.XcodeUtils.ensureGroupRecursively(project, groupName)) {\n logger.error(\n `Error copying GoogleService-Info.plist. Failed to find or create '${groupName}' group in Xcode.`\n );\n return;\n }\n\n // Add GoogleService-Info.plist to the Xcode project\n IOSConfig.XcodeUtils.addResourceFileToGroup({\n project,\n filepath,\n groupName,\n isBuildFile: true,\n });\n}\n"],"mappings":"AACA,SAASA,SAAS,EAAEC,gBAAgB,QAAQ,sBAAsB;AAGlE,SAASC,MAAM,QAAQ,iBAAiB;AACxC,SAASC,cAAc,QAAQ,mCAAmC;AAClE,SAASC,iBAAiB,QAAQ,SAAS;AAE3C,OAAO,MAAMC,0BAEZ,GAAGA,CAACC,MAAM,EAAEC,QAAQ,KAAK;EACxB,OAAON,gBAAgB,CAACK,MAAM,EAAE,MAAOE,KAAK,IAAK;IAAA,IAAAC,qBAAA;IAC/C,MAAMC,MAAM,GAAGN,iBAAiB,CAACG,QAAQ,CAAC;IAC1C,IAAI,CAACG,MAAM,EAAE;MACX;MACA,OAAOF,KAAK;IACd;IAEAN,MAAM,CAACS,IAAI,CACT,0GAA0G,GAC1G,2DACF,CAAC;;IAED;IACA,MAAMC,OAAO,GAAGJ,KAAK,CAACK,UAAU,CAACC,mBAAmB;IACpD,MAAMC,kBAAkB,IAAAN,qBAAA,GAAGF,QAAQ,CAACS,gBAAgB,cAAAP,qBAAA,uBAAzBA,qBAAA,CAA2BM,kBAAkB;IACxE,MAAME,OAAO,GAAGT,KAAK,CAACK,UAAU,CAACK,WAAW;IAE5C,IAAIf,cAAc,CAACgB,MAAM,CAAC,GAAGP,OAAO,2BAA2B,CAAC,EAAE;MAChEV,MAAM,CAACS,IAAI,CACT,wBAAwBC,OAAO,wCACjC,CAAC;MACD,OAAOJ,KAAK;IACd;IAEA,IACEL,cAAc,CAACgB,MAAM,CAAC,GAAGP,OAAO,IAAIK,OAAO,2BAA2B,CAAC,EACvE;MACA;MACA;MACAf,MAAM,CAACS,IAAI,CACT,wBAAwBC,OAAO,IAAIK,OAAO,wCAC5C,CAAC;MACD,OAAOT,KAAK;IACd;IAEA,IAAIO,kBAAkB,IAAIZ,cAAc,CAACgB,MAAM,CAACJ,kBAAkB,CAAC,EAAE;MAAA,IAAAK,WAAA;MACnE,KAAAA,WAAA,GAAId,MAAM,CAACe,GAAG,cAAAD,WAAA,eAAVA,WAAA,CAAYL,kBAAkB,EAAE;QAClCb,MAAM,CAACoB,IAAI,CACT,0HAA0H,GAC1H,uIACF,CAAC;MACH;MAEA,IAAI;QACFnB,cAAc,CAACoB,QAAQ,CACrBR,kBAAkB,EAClB,GAAGH,OAAO,2BACZ,CAAC;QAEDY,qBAAqB,CAAChB,KAAK,CAACiB,UAAU,EAAE,0BAA0B,CAAC;MACrE,CAAC,CAAC,MAAM;QACNvB,MAAM,CAACwB,KAAK,CACV,gGAAgGd,OAAO,2BACzG,CAAC;MACH;IACF,CAAC,MAAM;MACLV,MAAM,CAACwB,KAAK,CACV,wCAAwCX,kBAAkB,yDAAyDH,OAAO,2BAC5H,CAAC;IACH;IAEA,OAAOJ,KAAK;EACd,CAAC,CAAC;AACJ,CAAC;AAED,SAASgB,qBAAqBA,CAACG,OAAqB,EAAEC,QAAgB,EAAE;EACtE,MAAMC,SAAS,GAAG,WAAW;EAC7B,MAAMC,QAAQ,GAAGF,QAAQ;EAEzB,IAAI,CAAC5B,SAAS,CAAC+B,UAAU,CAACC,sBAAsB,CAACL,OAAO,EAAEE,SAAS,CAAC,EAAE;IACpE3B,MAAM,CAACwB,KAAK,CACV,qEAAqEG,SAAS,mBAChF,CAAC;IACD;EACF;;EAEA;EACA7B,SAAS,CAAC+B,UAAU,CAACE,sBAAsB,CAAC;IAC1CN,OAAO;IACPG,QAAQ;IACRD,SAAS;IACTK,WAAW,EAAE;EACf,CAAC,CAAC;AACJ","ignoreList":[]}
1
+ {"version":3,"names":["IOSConfig","withXcodeProject","logger","FileManagement","isFcmPushProvider","copyGoogleServicePlistFile","iosPath","appName","googleServicesFile","expoIosGoogleServicesFileSet","xcodeProject","destination","exists","info","warn","copyFile","addFileToXcodeProject","error","withGoogleServicesJsonFile","config","cioProps","props","_cioProps$pushNotific","_config$ios","useFcm","modRequest","platformProjectRoot","projectName","pushNotification","Boolean","ios","modResults","project","fileName","groupName","filepath","XcodeUtils","ensureGroupRecursively","addResourceFileToGroup","isBuildFile"],"sources":["withGoogleServicesJsonFile.ts"],"sourcesContent":["import type { ConfigPlugin, XcodeProject } from '@expo/config-plugins';\nimport { IOSConfig, withXcodeProject } from '@expo/config-plugins';\n\nimport type { CustomerIOPluginOptionsIOS } from '../types/cio-types';\nimport { logger } from '../utils/logger';\nimport { FileManagement } from './../helpers/utils/fileManagement';\nimport { isFcmPushProvider } from './utils';\n\nexport type CopyGoogleServicePlistOptions = {\n iosPath: string;\n appName: string | undefined;\n googleServicesFile: string | undefined;\n expoIosGoogleServicesFileSet: boolean;\n xcodeProject: XcodeProject;\n};\n\n/**\n * Copies the FCM GoogleService-Info.plist into the iOS project (when needed) and registers it\n * in the Xcode project's Resources group. Idempotent no-ops if a plist is already present\n * at either of the two well-known locations Expo / RN Firebase use.\n */\nexport function copyGoogleServicePlistFile({\n iosPath,\n appName,\n googleServicesFile,\n expoIosGoogleServicesFileSet,\n xcodeProject,\n}: CopyGoogleServicePlistOptions): void {\n const destination = `${iosPath}/GoogleService-Info.plist`;\n\n if (FileManagement.exists(destination)) {\n logger.info(`File already exists: ${destination}. Skipping...`);\n return;\n }\n\n if (appName && FileManagement.exists(`${iosPath}/${appName}/GoogleService-Info.plist`)) {\n // This is where RN Firebase potentially copies GoogleService-Info.plist\n // Do not copy if it's already done by Firebase to avoid conflict in Resources\n logger.info(\n `File already exists: ${iosPath}/${appName}/GoogleService-Info.plist. Skipping...`\n );\n return;\n }\n\n if (googleServicesFile && FileManagement.exists(googleServicesFile)) {\n if (expoIosGoogleServicesFileSet) {\n logger.warn(\n 'Specifying both Expo ios.googleServicesFile and Customer.io ios.pushNotification.googleServicesFile can cause a conflict' +\n ' duplicating GoogleService-Info.plist in the iOS project resources. Please remove Customer.io ios.pushNotification.googleServicesFile'\n );\n }\n\n try {\n FileManagement.copyFile(googleServicesFile, destination);\n addFileToXcodeProject(xcodeProject, 'GoogleService-Info.plist');\n } catch {\n logger.error(\n `There was an error copying your GoogleService-Info.plist file. You can copy it manually into ${destination}`\n );\n }\n } else {\n logger.error(\n `The Google Services file provided in ${googleServicesFile} doesn't seem to exist. You can copy it manually into ${destination}`\n );\n }\n}\n\nexport const withGoogleServicesJsonFile: ConfigPlugin<\n CustomerIOPluginOptionsIOS\n> = (config, cioProps) => {\n return withXcodeProject(config, async (props) => {\n const useFcm = isFcmPushProvider(cioProps);\n if (!useFcm) {\n // Nothing to do, for providers other than FCM, the Google services JSON file isn't needed\n return props;\n }\n\n logger.info(\n 'Only specify Customer.io ios.pushNotification.googleServicesFile config if you are not already including' +\n ' GoogleService-Info.plist as part of Firebase integration'\n );\n\n copyGoogleServicePlistFile({\n iosPath: props.modRequest.platformProjectRoot,\n appName: props.modRequest.projectName,\n googleServicesFile: cioProps.pushNotification?.googleServicesFile,\n expoIosGoogleServicesFileSet: Boolean(config.ios?.googleServicesFile),\n xcodeProject: props.modResults,\n });\n\n return props;\n });\n};\n\nfunction addFileToXcodeProject(project: XcodeProject, fileName: string) {\n const groupName = 'Resources';\n const filepath = fileName;\n\n if (!IOSConfig.XcodeUtils.ensureGroupRecursively(project, groupName)) {\n logger.error(\n `Error copying GoogleService-Info.plist. Failed to find or create '${groupName}' group in Xcode.`\n );\n return;\n }\n\n // Add GoogleService-Info.plist to the Xcode project\n IOSConfig.XcodeUtils.addResourceFileToGroup({\n project,\n filepath,\n groupName,\n isBuildFile: true,\n });\n}\n"],"mappings":"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","ignoreList":[]}
@@ -9,6 +9,16 @@ import { FileManagement } from './../helpers/utils/fileManagement';
9
9
  import { isExpoVersion53OrHigher, isFcmPushProvider } from './utils';
10
10
  const PLIST_FILENAME = `${CIO_NOTIFICATION_TARGET_NAME}-Info.plist`;
11
11
  const ENV_FILENAME = 'Env.swift';
12
+
13
+ // NSE source files registered in the Xcode group AND copied to the target
14
+ // directory. Single source of truth — both `addNotificationServiceExtensionToXcodeProject`
15
+ // (registers them in the PBXGroup) and `addRichPushXcodeProj` (copies them
16
+ // from the plugin's native-files dir) read the same arrays. Keeping these
17
+ // in sync is load-bearing: the Xcode group must reference the same files
18
+ // that exist on disk, or the build fails with "no such file" / unresolved
19
+ // references.
20
+ const NSE_PLATFORM_SPECIFIC_FILES = ['NotificationService.swift'];
21
+ const NSE_COMMON_FILES = [PLIST_FILENAME, 'NotificationService.h', 'NotificationService.m', ENV_FILENAME];
12
22
  const TARGETED_DEVICE_FAMILY = `"1,2"`;
13
23
  const addNotificationServiceExtension = async (options, xcodeProject, isExpo53OrHigher) => {
14
24
  try {
@@ -76,76 +86,35 @@ export const withCioNotificationsXcodeProject = (configOuter, props) => {
76
86
  return config;
77
87
  });
78
88
  };
79
- const addRichPushXcodeProj = async (options, xcodeProject) => {
80
- var _options$pushNotifica2, _options$pushNotifica3, _options$pushNotifica4;
89
+ const NSE_ENTITLEMENTS_FILENAME = 'NotificationService.entitlements';
90
+ /**
91
+ * Mutates the parsed XcodeProject to register the rich-push NotificationService
92
+ * extension target: creates a PBXGroup for its files, registers the group under
93
+ * the project's top-level group, adds the app_extension target, wires three
94
+ * build phases (Sources, Resources, Frameworks), configures the target's build
95
+ * settings (DEVELOPMENT_TEAM, IPHONEOS_DEPLOYMENT_TARGET, code-sign style,
96
+ * Swift version, and CODE_SIGN_ENTITLEMENTS when `appGroupId` is set), and
97
+ * stamps the development team attribute on both the new target and the
98
+ * project's main target attributes.
99
+ *
100
+ * Idempotent — returns the project unchanged if a target named
101
+ * `CIO_NOTIFICATION_TARGET_NAME` is already present.
102
+ */
103
+ export function addNotificationServiceExtensionToXcodeProject(xcodeProject, options) {
104
+ if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {
105
+ logger.warn(`${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`);
106
+ return xcodeProject;
107
+ }
81
108
  const {
82
109
  appleTeamId,
83
110
  bundleIdentifier,
84
- bundleShortVersion,
85
- bundleVersion,
86
- iosPath,
87
111
  iosDeploymentTarget,
88
- useFrameworks
112
+ appGroupId
89
113
  } = options;
90
- const isFcmProvider = isFcmPushProvider(options);
91
- await injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmProvider);
92
-
93
- // Check if `CIO_NOTIFICATION_TARGET_NAME` group already exist in the project
94
- // If true then skip creating a new group to avoid duplicate folders
95
- if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {
96
- logger.warn(`${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`);
97
- return;
98
- }
99
- const nsePath = `${iosPath}/${CIO_NOTIFICATION_TARGET_NAME}`;
100
- FileManagement.mkdir(nsePath, {
101
- recursive: true
102
- });
103
- const platformSpecificFiles = ['NotificationService.swift'];
104
- const nseEntitlementsFilename = 'NotificationService.entitlements';
105
- const appGroupId = (_options$pushNotifica2 = options.pushNotification) === null || _options$pushNotifica2 === void 0 ? void 0 : _options$pushNotifica2.appGroupId;
106
-
107
- // Write NSE entitlements file only when appGroupId is explicitly configured
108
- if (appGroupId) {
109
- const nseEntitlementsContent = `<?xml version="1.0" encoding="UTF-8"?>
110
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
111
- <plist version="1.0">
112
- <dict>
113
- <key>com.apple.security.application-groups</key>
114
- <array>
115
- <string>${appGroupId}</string>
116
- </array>
117
- </dict>
118
- </plist>
119
- `;
120
- FileManagement.writeFile(`${nsePath}/${nseEntitlementsFilename}`, nseEntitlementsContent);
121
- }
122
- const commonFiles = [PLIST_FILENAME, 'NotificationService.h', 'NotificationService.m', ENV_FILENAME];
123
- const getTargetFile = filename => `${nsePath}/${filename}`;
124
- // Copy platform-specific files
125
- platformSpecificFiles.forEach(filename => {
126
- const targetFile = getTargetFile(filename);
127
- FileManagement.copyFile(`${getIosNativeFilesPath()}/${isFcmProvider ? 'fcm' : 'apn'}/${filename}`, targetFile);
128
- });
129
-
130
- // Copy common files
131
- commonFiles.forEach(filename => {
132
- const targetFile = getTargetFile(filename);
133
- FileManagement.copyFile(`${getIosNativeFilesPath()}/common/${filename}`, targetFile);
134
- });
135
-
136
- /* MODIFY COPIED EXTENSION FILES */
137
- const infoPlistTargetFile = getTargetFile(PLIST_FILENAME);
138
- updateNseInfoPlist({
139
- bundleVersion,
140
- bundleShortVersion,
141
- infoPlistTargetFile
142
- });
143
- updateNseEnv(getTargetFile(ENV_FILENAME), (_options$pushNotifica3 = options.pushNotification) === null || _options$pushNotifica3 === void 0 ? void 0 : _options$pushNotifica3.env);
144
- updateNseNotificationService(getTargetFile('NotificationService.swift'), (_options$pushNotifica4 = options.pushNotification) === null || _options$pushNotifica4 === void 0 ? void 0 : _options$pushNotifica4.appGroupId);
145
114
 
146
115
  // The entitlements file is generated (not copied from source), so it's listed separately
147
- // for the Xcode group so it appears in the file navigator
148
- const allGroupFiles = [...platformSpecificFiles, ...commonFiles, ...(appGroupId ? [nseEntitlementsFilename] : [])];
116
+ // for the Xcode group so it appears in the file navigator.
117
+ const allGroupFiles = [...NSE_PLATFORM_SPECIFIC_FILES, ...NSE_COMMON_FILES, ...(appGroupId ? [NSE_ENTITLEMENTS_FILENAME] : [])];
149
118
 
150
119
  // Create new PBXGroup for the extension
151
120
  const extGroup = xcodeProject.addPbxGroup(allGroupFiles, CIO_NOTIFICATION_TARGET_NAME, CIO_NOTIFICATION_TARGET_NAME);
@@ -166,13 +135,8 @@ const addRichPushXcodeProj = async (options, xcodeProject) => {
166
135
  const projObjects = xcodeProject.hash.project.objects;
167
136
  projObjects.PBXTargetDependency = projObjects.PBXTargetDependency || {};
168
137
  projObjects.PBXContainerItemProxy = projObjects.PBXTargetDependency || {};
169
- if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {
170
- logger.warn(`${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`);
171
- return;
172
- }
173
138
 
174
- // Add the NSE target
175
- // This also adds PBXTargetDependency and PBXContainerItemProxy
139
+ // Add the NSE target. This also adds PBXTargetDependency and PBXContainerItemProxy.
176
140
  const nseTarget = xcodeProject.addTarget(CIO_NOTIFICATION_TARGET_NAME, 'app_extension', CIO_NOTIFICATION_TARGET_NAME, `${bundleIdentifier}.richpush`);
177
141
 
178
142
  // Add build phases to the new target
@@ -191,7 +155,7 @@ const addRichPushXcodeProj = async (options, xcodeProject) => {
191
155
  buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
192
156
  buildSettingsObj.SWIFT_VERSION = 4.2;
193
157
  if (appGroupId) {
194
- buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${CIO_NOTIFICATION_TARGET_NAME}/${nseEntitlementsFilename}`;
158
+ buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${CIO_NOTIFICATION_TARGET_NAME}/${NSE_ENTITLEMENTS_FILENAME}`;
195
159
  }
196
160
  }
197
161
  }
@@ -199,40 +163,124 @@ const addRichPushXcodeProj = async (options, xcodeProject) => {
199
163
  // Add development team to the target & the main
200
164
  xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId, nseTarget);
201
165
  xcodeProject.addTargetAttribute('DevelopmentTeam', appleTeamId);
166
+ return xcodeProject;
167
+ }
168
+ const addRichPushXcodeProj = async (options, xcodeProject) => {
169
+ var _options$pushNotifica2, _options$pushNotifica3;
170
+ const {
171
+ appleTeamId,
172
+ bundleIdentifier,
173
+ bundleShortVersion,
174
+ bundleVersion,
175
+ iosPath,
176
+ iosDeploymentTarget,
177
+ useFrameworks
178
+ } = options;
179
+ const isFcmProvider = isFcmPushProvider(options);
180
+ const appGroupId = (_options$pushNotifica2 = options.pushNotification) === null || _options$pushNotifica2 === void 0 ? void 0 : _options$pushNotifica2.appGroupId;
181
+ await injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmProvider);
182
+
183
+ // Skip the rest of the work if the NSE target is already in place. The pbxproj-mutating
184
+ // helper has its own idempotency check, but bailing out here also avoids redundant file
185
+ // copies and entitlements writes when prebuild re-runs against an already-prepared project.
186
+ if (xcodeProject.pbxTargetByName(CIO_NOTIFICATION_TARGET_NAME)) {
187
+ logger.warn(`${CIO_NOTIFICATION_TARGET_NAME} already exists in project. Skipping...`);
188
+ return;
189
+ }
190
+ const nsePath = `${iosPath}/${CIO_NOTIFICATION_TARGET_NAME}`;
191
+ FileManagement.mkdir(nsePath, {
192
+ recursive: true
193
+ });
194
+
195
+ // Write NSE entitlements file only when appGroupId is explicitly configured
196
+ if (appGroupId) {
197
+ const nseEntitlementsContent = `<?xml version="1.0" encoding="UTF-8"?>
198
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
199
+ <plist version="1.0">
200
+ <dict>
201
+ <key>com.apple.security.application-groups</key>
202
+ <array>
203
+ <string>${appGroupId}</string>
204
+ </array>
205
+ </dict>
206
+ </plist>
207
+ `;
208
+ FileManagement.writeFile(`${nsePath}/${NSE_ENTITLEMENTS_FILENAME}`, nseEntitlementsContent);
209
+ }
210
+ const getTargetFile = filename => `${nsePath}/${filename}`;
211
+
212
+ // Copy platform-specific files
213
+ NSE_PLATFORM_SPECIFIC_FILES.forEach(filename => {
214
+ FileManagement.copyFile(`${getIosNativeFilesPath()}/${isFcmProvider ? 'fcm' : 'apn'}/${filename}`, getTargetFile(filename));
215
+ });
216
+
217
+ // Copy common files
218
+ NSE_COMMON_FILES.forEach(filename => {
219
+ FileManagement.copyFile(`${getIosNativeFilesPath()}/common/${filename}`, getTargetFile(filename));
220
+ });
221
+
222
+ /* MODIFY COPIED EXTENSION FILES */
223
+ updateNseInfoPlist({
224
+ bundleVersion,
225
+ bundleShortVersion,
226
+ infoPlistTargetFile: getTargetFile(PLIST_FILENAME)
227
+ });
228
+ updateNseEnv(getTargetFile(ENV_FILENAME), (_options$pushNotifica3 = options.pushNotification) === null || _options$pushNotifica3 === void 0 ? void 0 : _options$pushNotifica3.env);
229
+ updateNseNotificationService(getTargetFile('NotificationService.swift'), appGroupId);
230
+
231
+ // Register the NSE target in the parsed Xcode project
232
+ addNotificationServiceExtensionToXcodeProject(xcodeProject, {
233
+ appleTeamId,
234
+ bundleIdentifier,
235
+ iosDeploymentTarget,
236
+ appGroupId
237
+ });
202
238
  };
203
- const updateNseInfoPlist = payload => {
204
- const BUNDLE_SHORT_VERSION_RE = /\{\{BUNDLE_SHORT_VERSION\}\}/;
205
- const BUNDLE_VERSION_RE = /\{\{BUNDLE_VERSION\}\}/;
206
- let plistFileString = FileManagement.readFile(payload.infoPlistTargetFile);
239
+
240
+ /**
241
+ * Pure string transform: substitutes the `{{BUNDLE_VERSION}}` and
242
+ * `{{BUNDLE_SHORT_VERSION}}` placeholders in the NSE Info.plist template.
243
+ * Either or both may be provided; missing values leave the corresponding
244
+ * placeholder untouched.
245
+ */
246
+ export function applyBundleVersionToNsePlist(content, payload) {
247
+ let next = content;
207
248
  if (payload.bundleVersion) {
208
- plistFileString = replaceCodeByRegex(plistFileString, BUNDLE_VERSION_RE, payload.bundleVersion);
249
+ next = replaceCodeByRegex(next, /\{\{BUNDLE_VERSION\}\}/, payload.bundleVersion);
209
250
  }
210
251
  if (payload.bundleShortVersion) {
211
- plistFileString = replaceCodeByRegex(plistFileString, BUNDLE_SHORT_VERSION_RE, payload.bundleShortVersion);
252
+ next = replaceCodeByRegex(next, /\{\{BUNDLE_SHORT_VERSION\}\}/, payload.bundleShortVersion);
212
253
  }
213
- FileManagement.writeFile(payload.infoPlistTargetFile, plistFileString);
254
+ return next;
255
+ }
256
+ const updateNseInfoPlist = payload => {
257
+ const next = applyBundleVersionToNsePlist(FileManagement.readFile(payload.infoPlistTargetFile), payload);
258
+ FileManagement.writeFile(payload.infoPlistTargetFile, next);
214
259
  };
215
- const updateNseNotificationService = (notificationServiceFile, appGroupId) => {
216
- const APP_GROUP_ID_BUILDER_LINE_RE = /\{\{APP_GROUP_ID_BUILDER_LINE\}\}/;
217
- let content = FileManagement.readFile(notificationServiceFile);
260
+
261
+ /**
262
+ * Pure string transform: substitutes the `{{APP_GROUP_ID_BUILDER_LINE}}`
263
+ * placeholder in NotificationService.swift with either the configured
264
+ * appGroupId builder line or an empty string.
265
+ */
266
+ export function applyAppGroupIdToNotificationService(content, appGroupId) {
218
267
  const builderLine = appGroupId ? ` .appGroupId(${JSON.stringify(appGroupId)})\n` : '';
219
- content = replaceCodeByRegex(content, APP_GROUP_ID_BUILDER_LINE_RE, builderLine);
220
- FileManagement.writeFile(notificationServiceFile, content);
268
+ return replaceCodeByRegex(content, /\{\{APP_GROUP_ID_BUILDER_LINE\}\}/, builderLine);
269
+ }
270
+ const updateNseNotificationService = (notificationServiceFile, appGroupId) => {
271
+ const next = applyAppGroupIdToNotificationService(FileManagement.readFile(notificationServiceFile), appGroupId);
272
+ FileManagement.writeFile(notificationServiceFile, next);
221
273
  };
222
- const updateNseEnv = (envFileName, richPushConfig) => {
223
- const CDP_API_KEY_RE = /\{\{CDP_API_KEY\}\}/;
224
- const REGION_RE = /\{\{REGION\}\}/;
225
- let envFileContent = FileManagement.readFile(envFileName);
226
274
 
227
- // Use merged config values (config takes precedence over env)
275
+ /**
276
+ * Pure string transform: substitutes the `{{CDP_API_KEY}}` and `{{REGION}}`
277
+ * placeholders in the NSE Env.swift template. Missing or invalid region
278
+ * falls back to `Region.US` and logs a warning.
279
+ */
280
+ export function applyRichPushConfigToEnv(content, richPushConfig) {
228
281
  const cdpApiKey = richPushConfig === null || richPushConfig === void 0 ? void 0 : richPushConfig.cdpApiKey;
229
282
  const region = richPushConfig === null || richPushConfig === void 0 ? void 0 : richPushConfig.region;
230
- if (!validateRichPushConfig(richPushConfig)) {
231
- return;
232
- }
233
- envFileContent = replaceCodeByRegex(envFileContent, CDP_API_KEY_RE, cdpApiKey || 'MISSING_API_KEY');
234
-
235
- // Simplify region mapping with case insensitive keys and fallback for invalid regions
283
+ let next = replaceCodeByRegex(content, /\{\{CDP_API_KEY\}\}/, cdpApiKey || 'MISSING_API_KEY');
236
284
  const regionKey = (region === null || region === void 0 ? void 0 : region.toLowerCase()) ?? '';
237
285
  const regionMap = {
238
286
  us: 'Region.US',
@@ -241,12 +289,18 @@ const updateNseEnv = (envFileName, richPushConfig) => {
241
289
  const mappedRegion = regionMap[regionKey];
242
290
  if (!mappedRegion) {
243
291
  logger.warn(`${regionKey} is an invalid region. Please use the values from the docs: https://docs.customer.io/integrations/sdk/expo/getting-started/packages-options/#configuring-the-expo-plugin`);
244
- // Fallback to US if invalid region provided
245
- envFileContent = replaceCodeByRegex(envFileContent, REGION_RE, regionMap.us);
292
+ next = replaceCodeByRegex(next, /\{\{REGION\}\}/, regionMap.us);
246
293
  } else {
247
- envFileContent = replaceCodeByRegex(envFileContent, REGION_RE, mappedRegion);
294
+ next = replaceCodeByRegex(next, /\{\{REGION\}\}/, mappedRegion);
248
295
  }
249
- FileManagement.writeFile(envFileName, envFileContent);
296
+ return next;
297
+ }
298
+ const updateNseEnv = (envFileName, richPushConfig) => {
299
+ if (!validateRichPushConfig(richPushConfig)) {
300
+ return;
301
+ }
302
+ const next = applyRichPushConfigToEnv(FileManagement.readFile(envFileName), richPushConfig);
303
+ FileManagement.writeFile(envFileName, next);
250
304
  };
251
305
  async function addPushNotificationFile(options, xcodeProject) {
252
306
  // Maybe copy a different file with FCM config based on config
@@ -281,12 +335,18 @@ async function addPushNotificationFile(options, xcodeProject) {
281
335
  xcodeProject.addToPbxGroup(group, classesKey);
282
336
  xcodeProject.addSourceFile(`${appName}/${targetFileName}`, null, group);
283
337
  }
284
- const updatePushFile = (options, envFileName) => {
285
- var _options$pushNotifica5, _options$pushNotifica6, _options$pushNotifica7, _options$pushNotifica8, _options$pushNotifica9, _options$pushNotifica0;
286
- const REGISTER_RE = /\{\{REGISTER_SNIPPET\}\}/;
287
- let envFileContent = FileManagement.readFile(envFileName);
288
- const disableNotificationRegistration = (_options$pushNotifica5 = options.pushNotification) === null || _options$pushNotifica5 === void 0 ? void 0 : _options$pushNotifica5.disableNotificationRegistration;
289
- const richPushConfig = (_options$pushNotifica6 = options.pushNotification) === null || _options$pushNotifica6 === void 0 ? void 0 : _options$pushNotifica6.env;
338
+
339
+ /**
340
+ * Pure string transform: substitutes every PushService.swift placeholder
341
+ * (`{{REGISTER_SNIPPET}}`, `{{CDP_API_KEY}}`, `{{REGION}}`,
342
+ * `{{AUTO_TRACK_PUSH_EVENTS}}`, `{{AUTO_FETCH_DEVICE_TOKEN}}`,
343
+ * `{{SHOW_PUSH_APP_IN_FOREGROUND}}`, `{{APP_GROUP_ID_BUILDER_LINE}}`) using
344
+ * the configured push-notification options. Validation of the rich-push
345
+ * config (cdpApiKey/region required) is the wrapper's responsibility.
346
+ */
347
+ export function applyConfigToPushFile(content, options) {
348
+ var _options$pushNotifica4, _options$pushNotifica5, _options$pushNotifica6, _options$pushNotifica7, _options$pushNotifica8, _options$pushNotifica9;
349
+ const richPushConfig = (_options$pushNotifica4 = options.pushNotification) === null || _options$pushNotifica4 === void 0 ? void 0 : _options$pushNotifica4.env;
290
350
  const {
291
351
  cdpApiKey,
292
352
  region
@@ -294,29 +354,34 @@ const updatePushFile = (options, envFileName) => {
294
354
  cdpApiKey: 'MISSING_API_KEY',
295
355
  region: undefined
296
356
  };
297
- if (!validateRichPushConfig(richPushConfig)) {
298
- return;
299
- }
300
- let snippet = '';
357
+ const disableNotificationRegistration = (_options$pushNotifica5 = options.pushNotification) === null || _options$pushNotifica5 === void 0 ? void 0 : _options$pushNotifica5.disableNotificationRegistration;
358
+
301
359
  // unless this property is explicitly set to true, push notification
302
360
  // registration will be added to the AppDelegate
303
- if (disableNotificationRegistration !== true) {
304
- snippet = CIO_REGISTER_PUSHNOTIFICATION_SNIPPET;
305
- }
306
- envFileContent = replaceCodeByRegex(envFileContent, REGISTER_RE, snippet);
307
- envFileContent = replaceCodeByRegex(envFileContent, /\{\{CDP_API_KEY\}\}/, cdpApiKey);
361
+ const registerSnippet = disableNotificationRegistration !== true ? CIO_REGISTER_PUSHNOTIFICATION_SNIPPET : '';
362
+ let next = replaceCodeByRegex(content, /\{\{REGISTER_SNIPPET\}\}/, registerSnippet);
363
+ next = replaceCodeByRegex(next, /\{\{CDP_API_KEY\}\}/, cdpApiKey);
308
364
  if (region) {
309
- envFileContent = replaceCodeByRegex(envFileContent, /\{\{REGION\}\}/, region.toUpperCase());
365
+ next = replaceCodeByRegex(next, /\{\{REGION\}\}/, region.toUpperCase());
310
366
  }
311
- const autoTrackPushEvents = ((_options$pushNotifica7 = options.pushNotification) === null || _options$pushNotifica7 === void 0 ? void 0 : _options$pushNotifica7.autoTrackPushEvents) !== false;
312
- envFileContent = replaceCodeByRegex(envFileContent, /\{\{AUTO_TRACK_PUSH_EVENTS\}\}/, autoTrackPushEvents.toString());
313
- const autoFetchDeviceToken = ((_options$pushNotifica8 = options.pushNotification) === null || _options$pushNotifica8 === void 0 ? void 0 : _options$pushNotifica8.autoFetchDeviceToken) !== false;
314
- envFileContent = replaceCodeByRegex(envFileContent, /\{\{AUTO_FETCH_DEVICE_TOKEN\}\}/, autoFetchDeviceToken.toString());
315
- const showPushAppInForeground = ((_options$pushNotifica9 = options.pushNotification) === null || _options$pushNotifica9 === void 0 ? void 0 : _options$pushNotifica9.showPushAppInForeground) !== false;
316
- envFileContent = replaceCodeByRegex(envFileContent, /\{\{SHOW_PUSH_APP_IN_FOREGROUND\}\}/, showPushAppInForeground.toString());
317
- const appGroupId = (_options$pushNotifica0 = options.pushNotification) === null || _options$pushNotifica0 === void 0 ? void 0 : _options$pushNotifica0.appGroupId;
367
+ const autoTrackPushEvents = ((_options$pushNotifica6 = options.pushNotification) === null || _options$pushNotifica6 === void 0 ? void 0 : _options$pushNotifica6.autoTrackPushEvents) !== false;
368
+ next = replaceCodeByRegex(next, /\{\{AUTO_TRACK_PUSH_EVENTS\}\}/, autoTrackPushEvents.toString());
369
+ const autoFetchDeviceToken = ((_options$pushNotifica7 = options.pushNotification) === null || _options$pushNotifica7 === void 0 ? void 0 : _options$pushNotifica7.autoFetchDeviceToken) !== false;
370
+ next = replaceCodeByRegex(next, /\{\{AUTO_FETCH_DEVICE_TOKEN\}\}/, autoFetchDeviceToken.toString());
371
+ const showPushAppInForeground = ((_options$pushNotifica8 = options.pushNotification) === null || _options$pushNotifica8 === void 0 ? void 0 : _options$pushNotifica8.showPushAppInForeground) !== false;
372
+ next = replaceCodeByRegex(next, /\{\{SHOW_PUSH_APP_IN_FOREGROUND\}\}/, showPushAppInForeground.toString());
373
+ const appGroupId = (_options$pushNotifica9 = options.pushNotification) === null || _options$pushNotifica9 === void 0 ? void 0 : _options$pushNotifica9.appGroupId;
318
374
  const appGroupIdBuilderLine = appGroupId ? ` .appGroupId(${JSON.stringify(appGroupId)})\n` : '';
319
- envFileContent = replaceCodeByRegex(envFileContent, /\{\{APP_GROUP_ID_BUILDER_LINE\}\}/, appGroupIdBuilderLine);
320
- FileManagement.writeFile(envFileName, envFileContent);
375
+ next = replaceCodeByRegex(next, /\{\{APP_GROUP_ID_BUILDER_LINE\}\}/, appGroupIdBuilderLine);
376
+ return next;
377
+ }
378
+ const updatePushFile = (options, envFileName) => {
379
+ var _options$pushNotifica0;
380
+ const richPushConfig = (_options$pushNotifica0 = options.pushNotification) === null || _options$pushNotifica0 === void 0 ? void 0 : _options$pushNotifica0.env;
381
+ if (!validateRichPushConfig(richPushConfig)) {
382
+ return;
383
+ }
384
+ const next = applyConfigToPushFile(FileManagement.readFile(envFileName), options);
385
+ FileManagement.writeFile(envFileName, next);
321
386
  };
322
387
  //# sourceMappingURL=withNotificationsXcodeProject.js.map