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
@@ -1 +1 @@
1
- {"version":3,"names":["_configPlugins","require","_utils","shouldDisableAndroid16Support","config","androidOptions","disableAndroid16Support","undefined","isExpoVersion53OrLower","withProjectBuildGradle","withExpoProjectBuildGradle","modResults","contents","includes","resolutionStrategy","replace"],"sources":["withProjectBuildGradle.ts"],"sourcesContent":["import { withProjectBuildGradle as withExpoProjectBuildGradle } from '@expo/config-plugins';\nimport type { ExpoConfig } from '@expo/config-types';\nimport { isExpoVersion53OrLower } from '../ios/utils';\nimport type { CustomerIOPluginOptionsAndroid } from '../types/cio-types';\n\n/**\n * Determines if the androidx dependency fix should be applied based on config and Expo version.\n * The fix disables Android 16 support by downgrading androidx dependencies.\n * @param config The Expo config\n * @param androidOptions The Android plugin options\n * @returns true if the fix should be applied (Android 16 disabled)\n */\nfunction shouldDisableAndroid16Support(\n config: ExpoConfig,\n androidOptions?: CustomerIOPluginOptionsAndroid\n): boolean {\n // If user explicitly sets the option, respect their choice\n if (androidOptions?.disableAndroid16Support !== undefined) {\n return androidOptions.disableAndroid16Support;\n }\n\n // Auto-detect: Disable Android 16 for Expo SDK 53 or lower, enable for 54+\n return isExpoVersion53OrLower(config);\n}\n\n/**\n * Adds dependency resolution strategy to force specific androidx versions.\n * This disables Android 16 support for apps using Expo SDK 53 or older gradle versions.\n *\n * The fix prevents newer androidx versions that require Android API 36 and AGP 8.9.1+\n * from being pulled in. Expo SDK 53 uses Android API 35 and AGP 8.8.2, so we force\n * compatible versions.\n *\n * Expo SDK 54+ should support newer gradle versions and won't need this fix.\n */\nexport function withProjectBuildGradle(\n config: ExpoConfig,\n androidOptions?: CustomerIOPluginOptionsAndroid\n): ExpoConfig {\n return withExpoProjectBuildGradle(config, (config) => {\n const { modResults } = config;\n\n // Check if Android 16 support should be disabled\n if (!shouldDisableAndroid16Support(config, androidOptions)) {\n return config;\n }\n\n // Skip if already applied\n if (modResults.contents.includes('androidx.core:core-ktx:1.13.1')) {\n return config;\n }\n\n const resolutionStrategy = `\n configurations.all {\n resolutionStrategy {\n // Disable Android 16 support by forcing older androidx versions\n // Compatible with API 35 and AGP 8.8.2 (prevents API 36/AGP 8.9.1+ requirement)\n force 'androidx.core:core-ktx:1.13.1'\n force 'androidx.lifecycle:lifecycle-process:2.8.7'\n }\n }`;\n\n // Add resolution strategy inside allprojects block\n modResults.contents = modResults.contents.replace(\n /allprojects\\s*\\{/,\n `allprojects {${resolutionStrategy}`\n );\n\n return config;\n });\n}\n"],"mappings":";;;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AAEA,IAAAC,MAAA,GAAAD,OAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASE,6BAA6BA,CACpCC,MAAkB,EAClBC,cAA+C,EACtC;EACT;EACA,IAAI,CAAAA,cAAc,aAAdA,cAAc,uBAAdA,cAAc,CAAEC,uBAAuB,MAAKC,SAAS,EAAE;IACzD,OAAOF,cAAc,CAACC,uBAAuB;EAC/C;;EAEA;EACA,OAAO,IAAAE,6BAAsB,EAACJ,MAAM,CAAC;AACvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASK,sBAAsBA,CACpCL,MAAkB,EAClBC,cAA+C,EACnC;EACZ,OAAO,IAAAK,qCAA0B,EAACN,MAAM,EAAGA,MAAM,IAAK;IACpD,MAAM;MAAEO;IAAW,CAAC,GAAGP,MAAM;;IAE7B;IACA,IAAI,CAACD,6BAA6B,CAACC,MAAM,EAAEC,cAAc,CAAC,EAAE;MAC1D,OAAOD,MAAM;IACf;;IAEA;IACA,IAAIO,UAAU,CAACC,QAAQ,CAACC,QAAQ,CAAC,+BAA+B,CAAC,EAAE;MACjE,OAAOT,MAAM;IACf;IAEA,MAAMU,kBAAkB,GAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;;IAEF;IACAH,UAAU,CAACC,QAAQ,GAAGD,UAAU,CAACC,QAAQ,CAACG,OAAO,CAC/C,kBAAkB,EAClB,gBAAgBD,kBAAkB,EACpC,CAAC;IAED,OAAOV,MAAM;EACf,CAAC,CAAC;AACJ","ignoreList":[]}
1
+ {"version":3,"names":["_configPlugins","require","_utils","shouldDisableAndroid16Support","config","androidOptions","disableAndroid16Support","undefined","isExpoVersion53OrLower","modifyProjectBuildGradleAndroid16Support","contents","options","includes","resolutionStrategy","replace","withProjectBuildGradle","withExpoProjectBuildGradle","modResults"],"sources":["withProjectBuildGradle.ts"],"sourcesContent":["import { withProjectBuildGradle as withExpoProjectBuildGradle } from '@expo/config-plugins';\nimport type { ExpoConfig } from '@expo/config-types';\nimport { isExpoVersion53OrLower } from '../ios/utils';\nimport type { CustomerIOPluginOptionsAndroid } from '../types/cio-types';\n\n/**\n * Determines if the androidx dependency fix should be applied based on config and Expo version.\n * The fix disables Android 16 support by downgrading androidx dependencies.\n * @param config The Expo config\n * @param androidOptions The Android plugin options\n * @returns true if the fix should be applied (Android 16 disabled)\n */\nfunction shouldDisableAndroid16Support(\n config: ExpoConfig,\n androidOptions?: CustomerIOPluginOptionsAndroid\n): boolean {\n // If user explicitly sets the option, respect their choice\n if (androidOptions?.disableAndroid16Support !== undefined) {\n return androidOptions.disableAndroid16Support;\n }\n\n // Auto-detect: Disable Android 16 for Expo SDK 53 or lower, enable for 54+\n return isExpoVersion53OrLower(config);\n}\n\n/**\n * Pure string transform: injects an androidx resolution-strategy block into the\n * project-level build.gradle's `allprojects { ... }` section when\n * `disableAndroid16Support` is true. Idempotent returns input unchanged if the\n * snippet is already present, or if the flag is false.\n */\nexport function modifyProjectBuildGradleAndroid16Support(\n contents: string,\n options: { disableAndroid16Support: boolean }\n): string {\n if (!options.disableAndroid16Support) {\n return contents;\n }\n\n if (contents.includes('androidx.core:core-ktx:1.13.1')) {\n return contents;\n }\n\n const resolutionStrategy = `\n configurations.all {\n resolutionStrategy {\n // Disable Android 16 support by forcing older androidx versions\n // Compatible with API 35 and AGP 8.8.2 (prevents API 36/AGP 8.9.1+ requirement)\n force 'androidx.core:core-ktx:1.13.1'\n force 'androidx.lifecycle:lifecycle-process:2.8.7'\n }\n }`;\n\n return contents.replace(\n /allprojects\\s*\\{/,\n `allprojects {${resolutionStrategy}`\n );\n}\n\n/**\n * Adds dependency resolution strategy to force specific androidx versions.\n * This disables Android 16 support for apps using Expo SDK 53 or older gradle versions.\n *\n * The fix prevents newer androidx versions that require Android API 36 and AGP 8.9.1+\n * from being pulled in. Expo SDK 53 uses Android API 35 and AGP 8.8.2, so we force\n * compatible versions.\n *\n * Expo SDK 54+ should support newer gradle versions and won't need this fix.\n */\nexport function withProjectBuildGradle(\n config: ExpoConfig,\n androidOptions?: CustomerIOPluginOptionsAndroid\n): ExpoConfig {\n return withExpoProjectBuildGradle(config, (config) => {\n config.modResults.contents = modifyProjectBuildGradleAndroid16Support(\n config.modResults.contents,\n { disableAndroid16Support: shouldDisableAndroid16Support(config, androidOptions) }\n );\n return config;\n });\n}\n"],"mappings":";;;;;;;AAAA,IAAAA,cAAA,GAAAC,OAAA;AAEA,IAAAC,MAAA,GAAAD,OAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASE,6BAA6BA,CACpCC,MAAkB,EAClBC,cAA+C,EACtC;EACT;EACA,IAAI,CAAAA,cAAc,aAAdA,cAAc,uBAAdA,cAAc,CAAEC,uBAAuB,MAAKC,SAAS,EAAE;IACzD,OAAOF,cAAc,CAACC,uBAAuB;EAC/C;;EAEA;EACA,OAAO,IAAAE,6BAAsB,EAACJ,MAAM,CAAC;AACvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASK,wCAAwCA,CACtDC,QAAgB,EAChBC,OAA6C,EACrC;EACR,IAAI,CAACA,OAAO,CAACL,uBAAuB,EAAE;IACpC,OAAOI,QAAQ;EACjB;EAEA,IAAIA,QAAQ,CAACE,QAAQ,CAAC,+BAA+B,CAAC,EAAE;IACtD,OAAOF,QAAQ;EACjB;EAEA,MAAMG,kBAAkB,GAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;EAEJ,OAAOH,QAAQ,CAACI,OAAO,CACrB,kBAAkB,EAClB,gBAAgBD,kBAAkB,EACpC,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,sBAAsBA,CACpCX,MAAkB,EAClBC,cAA+C,EACnC;EACZ,OAAO,IAAAW,qCAA0B,EAACZ,MAAM,EAAGA,MAAM,IAAK;IACpDA,MAAM,CAACa,UAAU,CAACP,QAAQ,GAAGD,wCAAwC,CACnEL,MAAM,CAACa,UAAU,CAACP,QAAQ,EAC1B;MAAEJ,uBAAuB,EAAEH,6BAA6B,CAACC,MAAM,EAAEC,cAAc;IAAE,CACnF,CAAC;IACD,OAAOD,MAAM;EACf,CAAC,CAAC;AACJ","ignoreList":[]}
@@ -3,16 +3,20 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.modifyProjectBuildGradleForGoogleServices = modifyProjectBuildGradleForGoogleServices;
6
7
  exports.withProjectGoogleServices = void 0;
7
8
  var _configPlugins = require("@expo/config-plugins");
8
9
  var _android = require("./../helpers/constants/android");
10
+ function modifyProjectBuildGradleForGoogleServices(contents) {
11
+ const regex = new RegExp(_android.CIO_PROJECT_GOOGLE_SNIPPET);
12
+ if (regex.test(contents)) {
13
+ return contents;
14
+ }
15
+ return contents.replace(_android.CIO_PROJECT_BUILDSCRIPTS_REGEX, `$1\n${_android.CIO_PROJECT_GOOGLE_SNIPPET}`);
16
+ }
9
17
  const withProjectGoogleServices = configOuter => {
10
18
  return (0, _configPlugins.withProjectBuildGradle)(configOuter, props => {
11
- const regex = new RegExp(_android.CIO_PROJECT_GOOGLE_SNIPPET);
12
- const match = props.modResults.contents.match(regex);
13
- if (!match) {
14
- props.modResults.contents = props.modResults.contents.replace(_android.CIO_PROJECT_BUILDSCRIPTS_REGEX, `$1\n${_android.CIO_PROJECT_GOOGLE_SNIPPET}`);
15
- }
19
+ props.modResults.contents = modifyProjectBuildGradleForGoogleServices(props.modResults.contents);
16
20
  return props;
17
21
  });
18
22
  };
@@ -1 +1 @@
1
- {"version":3,"names":["_configPlugins","require","_android","withProjectGoogleServices","configOuter","withProjectBuildGradle","props","regex","RegExp","CIO_PROJECT_GOOGLE_SNIPPET","match","modResults","contents","replace","CIO_PROJECT_BUILDSCRIPTS_REGEX","exports"],"sources":["withProjectGoogleServices.ts"],"sourcesContent":["import type { ConfigPlugin } from '@expo/config-plugins';\nimport { withProjectBuildGradle } from '@expo/config-plugins';\n\nimport {\n CIO_PROJECT_BUILDSCRIPTS_REGEX,\n CIO_PROJECT_GOOGLE_SNIPPET,\n} from './../helpers/constants/android';\nimport type { CustomerIOPluginOptionsAndroid } from './../types/cio-types';\n\nexport const withProjectGoogleServices: ConfigPlugin<\n CustomerIOPluginOptionsAndroid\n> = (configOuter) => {\n return withProjectBuildGradle(configOuter, (props) => {\n const regex = new RegExp(CIO_PROJECT_GOOGLE_SNIPPET);\n const match = props.modResults.contents.match(regex);\n if (!match) {\n props.modResults.contents = props.modResults.contents.replace(\n CIO_PROJECT_BUILDSCRIPTS_REGEX,\n `$1\\n${CIO_PROJECT_GOOGLE_SNIPPET}`\n );\n }\n\n return props;\n });\n};\n"],"mappings":";;;;;;AACA,IAAAA,cAAA,GAAAC,OAAA;AAEA,IAAAC,QAAA,GAAAD,OAAA;AAMO,MAAME,yBAEZ,GAAIC,WAAW,IAAK;EACnB,OAAO,IAAAC,qCAAsB,EAACD,WAAW,EAAGE,KAAK,IAAK;IACpD,MAAMC,KAAK,GAAG,IAAIC,MAAM,CAACC,mCAA0B,CAAC;IACpD,MAAMC,KAAK,GAAGJ,KAAK,CAACK,UAAU,CAACC,QAAQ,CAACF,KAAK,CAACH,KAAK,CAAC;IACpD,IAAI,CAACG,KAAK,EAAE;MACVJ,KAAK,CAACK,UAAU,CAACC,QAAQ,GAAGN,KAAK,CAACK,UAAU,CAACC,QAAQ,CAACC,OAAO,CAC3DC,uCAA8B,EAC9B,OAAOL,mCAA0B,EACnC,CAAC;IACH;IAEA,OAAOH,KAAK;EACd,CAAC,CAAC;AACJ,CAAC;AAACS,OAAA,CAAAZ,yBAAA,GAAAA,yBAAA","ignoreList":[]}
1
+ {"version":3,"names":["_configPlugins","require","_android","modifyProjectBuildGradleForGoogleServices","contents","regex","RegExp","CIO_PROJECT_GOOGLE_SNIPPET","test","replace","CIO_PROJECT_BUILDSCRIPTS_REGEX","withProjectGoogleServices","configOuter","withProjectBuildGradle","props","modResults","exports"],"sources":["withProjectGoogleServices.ts"],"sourcesContent":["import type { ConfigPlugin } from '@expo/config-plugins';\nimport { withProjectBuildGradle } from '@expo/config-plugins';\n\nimport {\n CIO_PROJECT_BUILDSCRIPTS_REGEX,\n CIO_PROJECT_GOOGLE_SNIPPET,\n} from './../helpers/constants/android';\nimport type { CustomerIOPluginOptionsAndroid } from './../types/cio-types';\n\nexport function modifyProjectBuildGradleForGoogleServices(contents: string): string {\n const regex = new RegExp(CIO_PROJECT_GOOGLE_SNIPPET);\n if (regex.test(contents)) {\n return contents;\n }\n return contents.replace(\n CIO_PROJECT_BUILDSCRIPTS_REGEX,\n `$1\\n${CIO_PROJECT_GOOGLE_SNIPPET}`\n );\n}\n\nexport const withProjectGoogleServices: ConfigPlugin<\n CustomerIOPluginOptionsAndroid\n> = (configOuter) => {\n return withProjectBuildGradle(configOuter, (props) => {\n props.modResults.contents = modifyProjectBuildGradleForGoogleServices(\n props.modResults.contents\n );\n return props;\n });\n};\n"],"mappings":";;;;;;;AACA,IAAAA,cAAA,GAAAC,OAAA;AAEA,IAAAC,QAAA,GAAAD,OAAA;AAMO,SAASE,yCAAyCA,CAACC,QAAgB,EAAU;EAClF,MAAMC,KAAK,GAAG,IAAIC,MAAM,CAACC,mCAA0B,CAAC;EACpD,IAAIF,KAAK,CAACG,IAAI,CAACJ,QAAQ,CAAC,EAAE;IACxB,OAAOA,QAAQ;EACjB;EACA,OAAOA,QAAQ,CAACK,OAAO,CACrBC,uCAA8B,EAC9B,OAAOH,mCAA0B,EACnC,CAAC;AACH;AAEO,MAAMI,yBAEZ,GAAIC,WAAW,IAAK;EACnB,OAAO,IAAAC,qCAAsB,EAACD,WAAW,EAAGE,KAAK,IAAK;IACpDA,KAAK,CAACC,UAAU,CAACX,QAAQ,GAAGD,yCAAyC,CACnEW,KAAK,CAACC,UAAU,CAACX,QACnB,CAAC;IACD,OAAOU,KAAK;EACd,CAAC,CAAC;AACJ,CAAC;AAACE,OAAA,CAAAL,yBAAA,GAAAA,yBAAA","ignoreList":[]}
@@ -5,17 +5,85 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.IOS_DEPLOYMENT_TARGET = exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = exports.DEFAULT_BUNDLE_VERSION = exports.DEFAULT_BUNDLE_SHORT_VERSION = exports.CIO_TARGET_NAME = exports.CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER = exports.CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2 = exports.CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = exports.CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET = exports.CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX = exports.CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = exports.CIO_NOTIFICATION_TARGET_NAME = exports.CIO_NATIVE_SDK_INITIALIZE_SNIPPET = exports.CIO_NATIVE_SDK_INITIALIZE_CALL = exports.CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX = exports.CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET = exports.CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX = exports.CIO_INITIALIZECIOSDK_SNIPPET = exports.CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = exports.CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX = exports.CIO_DIDFINISHLAUNCHINGMETHOD_REGEX = exports.CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = exports.CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX = exports.CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX = exports.CIO_DEEPLINK_COMMENT_REGEX = exports.CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET = exports.CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET = exports.CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = exports.CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET = exports.CIO_APPDELEGATEHEADER_REGEX = exports.CIO_APPDELEGATEHEADER_IMPORT_SNIPPET = exports.CIO_APPDELEGATEDECLARATION_REGEX = exports.BUNDLE_VERSION_TEMPLATE_REGEX = exports.BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = void 0;
7
7
  exports.getRelativePathToRNSDK = getRelativePathToRNSDK;
8
+ var _fs = _interopRequireDefault(require("fs"));
9
+ var semver = _interopRequireWildcard(require("semver"));
10
+ var _resolveRNSDK = require("../../utils/resolveRNSDK");
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
13
  const path = require('path');
9
- const resolveFrom = require('resolve-from');
10
- function getRelativePathToRNSDK(iosPath) {
11
- // Root path of the Expo project
12
- const rootAppPath = path.dirname(iosPath);
14
+ // Threshold at which React Native pod autolinking moves from
15
+ // @react-native-community/cli (lexical, symlink-preserving) to
16
+ // expo-modules-autolinking (realpath). The two flavors emit different
17
+ // :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy
18
+ // we must match whichever flavor will resolve the same package later.
19
+ const RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';
20
+ const PLUGIN_LOG_PREFIX = '[CustomerIO Plugin]';
13
21
 
14
- // Path of the cio RN package.json file. Example: test-app/node_modules/customerio-reactnative/package.json
15
- const pluginPackageJsonPath = resolveFrom.silent(rootAppPath, `customerio-reactnative/package.json`);
22
+ // Always-on so the trail shows up in customer-shared `expo prebuild`
23
+ // output without needing a separate verbose-mode opt-in.
24
+ function pluginLog(message) {
25
+ // eslint-disable-next-line no-console
26
+ console.log(`${PLUGIN_LOG_PREFIX} ${message}`);
27
+ }
16
28
 
17
- // Example: ../node_modules/customerio-reactnative
18
- return path.relative(iosPath, path.dirname(pluginPackageJsonPath));
29
+ /**
30
+ * Returns the relative path from the iOS project dir to the installed
31
+ * customerio-reactnative directory, in the exact form React Native pod
32
+ * autolinking will emit for the same package. The two autolinking
33
+ * flavors disagree on path shape under pnpm/yarn symlinks:
34
+ *
35
+ * - RN <0.80 (`@react-native-community/cli`): walks node_modules
36
+ * lexically, preserves symlinks. We keep the symlink path too —
37
+ * `tryResolveRNSDK` already does this without calling realpath.
38
+ *
39
+ * - RN >=0.80 (`expo-modules-autolinking`): realpaths the package
40
+ * via Node, emitting the underlying `.pnpm/...` (or yarn-classic)
41
+ * path. We match by realpath'ing the resolved directory.
42
+ *
43
+ * Decision points are logged so a customer's prebuild output is enough
44
+ * to triage path-resolution issues without a follow-up "set
45
+ * CUSTOMERIO_DEBUG_MODE and rerun" round-trip.
46
+ */
47
+ function getRelativePathToRNSDK(iosPath) {
48
+ const rootAppPath = path.dirname(iosPath);
49
+ pluginLog(`Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`);
50
+ const {
51
+ packageDir
52
+ } = (0, _resolveRNSDK.resolveRNSDK)(rootAppPath);
53
+ pluginLog(`customerio-reactnative resolved to: ${packageDir}`);
54
+ const rnVersion = (0, _resolveRNSDK.tryReadRNVersion)(rootAppPath);
55
+ pluginLog(`Detected react-native version: ${rnVersion ?? 'unknown'}`);
56
+ const useLexical = shouldUseLexicalPath(rnVersion);
57
+ pluginLog(useLexical ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking` : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`);
58
+ let absolutePath;
59
+ if (useLexical) {
60
+ absolutePath = packageDir;
61
+ } else {
62
+ try {
63
+ absolutePath = _fs.default.realpathSync(packageDir);
64
+ if (absolutePath !== packageDir) {
65
+ pluginLog(`Realpath differs from resolved dir: ${absolutePath}`);
66
+ }
67
+ } catch (err) {
68
+ pluginLog(`realpathSync failed (${err instanceof Error ? err.message : String(err)}); falling back to symlink path`);
69
+ absolutePath = packageDir;
70
+ }
71
+ }
72
+ const relativePath = path.relative(iosPath, absolutePath);
73
+ pluginLog(`Final Podfile :path => '${relativePath}'`);
74
+ return relativePath;
75
+ }
76
+ function shouldUseLexicalPath(rnVersion) {
77
+ if (!rnVersion) {
78
+ // Modern Expo (realpath) has been the working path for the last few
79
+ // SDKs, so it's the safer default when RN can't be detected.
80
+ return false;
81
+ }
82
+ const coerced = semver.valid(rnVersion) || semver.coerce(rnVersion);
83
+ if (!coerced) {
84
+ return false;
85
+ }
86
+ return semver.lt(coerced, RN_REALPATH_AUTOLINKING_MIN_VERSION);
19
87
  }
20
88
  const IOS_DEPLOYMENT_TARGET = exports.IOS_DEPLOYMENT_TARGET = '13.0';
21
89
  const GROUP_IDENTIFIER_TEMPLATE_REGEX = exports.GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
@@ -1 +1 @@
1
- {"version":3,"names":["path","require","resolveFrom","getRelativePathToRNSDK","iosPath","rootAppPath","dirname","pluginPackageJsonPath","silent","relative","IOS_DEPLOYMENT_TARGET","exports","GROUP_IDENTIFIER_TEMPLATE_REGEX","BUNDLE_SHORT_VERSION_TEMPLATE_REGEX","BUNDLE_VERSION_TEMPLATE_REGEX","CIO_DIDFINISHLAUNCHINGMETHOD_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX","CIO_APPDELEGATEDECLARATION_REGEX","CIO_APPDELEGATEHEADER_REGEX","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_DEEPLINK_COMMENT_REGEX","DEFAULT_BUNDLE_VERSION","DEFAULT_BUNDLE_SHORT_VERSION","CIO_TARGET_NAME","CIO_NOTIFICATION_TARGET_NAME","CIO_APPDELEGATEHEADER_IMPORT_SNIPPET","CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET","CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET","CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET","CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET","CIO_INITIALIZECIOSDK_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2","CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER","CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX","CIO_NATIVE_SDK_INITIALIZE_CALL","CIO_NATIVE_SDK_INITIALIZE_SNIPPET"],"sources":["ios.ts"],"sourcesContent":["const path = require('path');\nconst resolveFrom = require('resolve-from');\n\nexport function getRelativePathToRNSDK(iosPath: string) {\n // Root path of the Expo project\n const rootAppPath = path.dirname(iosPath);\n\n // Path of the cio RN package.json file. Example: test-app/node_modules/customerio-reactnative/package.json\n const pluginPackageJsonPath = resolveFrom.silent(\n rootAppPath,\n `customerio-reactnative/package.json`\n );\n\n // Example: ../node_modules/customerio-reactnative\n return path.relative(iosPath, path.dirname(pluginPackageJsonPath));\n}\n\nexport const IOS_DEPLOYMENT_TARGET = '13.0';\nexport const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;\nexport const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;\nexport const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;\nexport const CIO_DIDFINISHLAUNCHINGMETHOD_REGEX =\n /.*\\[super(\\s)application:application(\\s)didFinishLaunchingWithOptions:launchOptions\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX =\n /return \\[super application:application didFailToRegisterForRemoteNotificationsWithError:error\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX =\n /(- \\(void\\)application:\\(UIApplication \\*\\)application didFailToRegisterForRemoteNotificationsWithError:\\(NSError \\*\\)error(\\s|\\n)*?\\{)(.|\\n){2}.*\\n\\}/;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX =\n /return \\[super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken\\];/;\n\nexport const CIO_APPDELEGATEDECLARATION_REGEX =\n /@implementation AppDelegate(.|\\n)/;\n\nexport const CIO_APPDELEGATEHEADER_REGEX =\n /(@interface AppDelegate\\s*:\\s*EXAppDelegateWrapper\\s*)(<([^>]+)>)?/;\n\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*RCTBridge\\s*\\*\\s*\\w+\\s*=\\s*\\[\\s*self\\.reactDelegate\\s+createBridgeWithDelegate:self\\s+launchOptions:launchOptions\\s*\\];\\s*$/gm;\n\nexport const CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*return\\s\\[\\s*super\\s*application:\\s*application\\s*didFinishLaunchingWithOptions\\s*:\\s*launchOptions\\s*\\];/gm;\n\nexport const CIO_DEEPLINK_COMMENT_REGEX =\n /\\sDeep link workaround for app killed state start/gm;\nexport const DEFAULT_BUNDLE_VERSION = '1';\nexport const DEFAULT_BUNDLE_SHORT_VERSION = '1.0';\nexport const CIO_TARGET_NAME = 'CustomerIOSDK';\nexport const CIO_NOTIFICATION_TARGET_NAME = 'NotificationService';\n\nexport const CIO_APPDELEGATEHEADER_IMPORT_SNIPPET = `#import <UserNotifications/UserNotifications.h>`;\nexport const CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET =\n 'UNUserNotificationCenterDelegate';\nexport const CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = `\nCIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];\n`;\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET = `\nRCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:modifiedLaunchOptions];\n`;\n\nexport const CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET = `\nreturn [super application:application didFinishLaunchingWithOptions:modifiedLaunchOptions];`;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = `\n [super application:application didFailToRegisterForRemoteNotificationsWithError:error];\n [pnHandlerObj application:application error:error];\n`;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = `\n [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];\n return [pnHandlerObj application:application deviceToken:deviceToken];\n`;\n\nexport const CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = `\n // Register for push notifications\n [pnHandlerObj registerPushNotification];\n`;\n\nexport const CIO_INITIALIZECIOSDK_SNIPPET = ` \n [pnHandlerObj initializeCioSdk];\n\n// Code to make the CIO SDK compatible with expo-notifications package.\n// \n// The CIO SDK and expo-notifications both need to handle when a push gets clicked. However, iOS only allows one click handler to be set per app.\n// To get around this limitation, we set the CIO SDK as the click handler. The CIO SDK sets itself up so that when another SDK or host iOS app \n// sets itself as the click handler, the CIO SDK will still be able to handle when the push gets clicked, even though it's not the designated \n// click handler in iOS at runtime. \n// \n// This should work for most SDKs. However, expo-notifications is unique in it's implementation. It will not setup push click handling it if detects \n// that another SDK or host iOS app has already set itself as the click handler:\n// https://github.com/expo/expo/blob/1b29637bec0b9888e8bc8c310476293a3e2d9786/packages/expo-notifications/ios/EXNotifications/Notifications/EXNotificationCenterDelegate.m#L31-L37\n// ...to get around this, we must manually set it as the click handler after the CIO SDK. That's what this code block does.\n//\n// Note: Initialize the native iOS SDK and setup SDK push click handling before running this code. \n# if __has_include(<EXNotifications/EXNotificationCenterDelegate.h>)\n // Creating a new instance, as the comments in expo-notifications suggests, does not work. With this code, if you send a CIO push to device and click on it,\n // no push metrics reporting will occur.\n // EXNotificationCenterDelegate *notificationCenterDelegate = [[EXNotificationCenterDelegate alloc] init];\n\n // ...instead, get the singleton reference from Expo. \n id<UNUserNotificationCenterDelegate> notificationCenterDelegate = (id<UNUserNotificationCenterDelegate>) [EXModuleRegistryProvider getSingletonModuleForClass:[EXNotificationCenterDelegate class]];\n UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];\n center.delegate = notificationCenterDelegate;\n# endif\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET = `\n// Deep link workaround for app killed state start\nNSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];\n if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {\n NSDictionary *pushContent = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];\n if (pushContent[@\"CIO\"] && pushContent[@\"CIO\"][@\"push\"] && pushContent[@\"CIO\"][@\"push\"][@\"link\"]) {\n NSString *initialURL = pushContent[@\"CIO\"][@\"push\"][@\"link\"];\n if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {\n modifiedLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];\n }\n }\n }\n//Deep link workaround for app killed state ends\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET = `\n // Deep link workaround for app killed state start\n var modifiedLaunchOptions = launchOptions\n if let launchOptions = launchOptions,\n let pushContent = launchOptions[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any],\n let cio = pushContent[\"CIO\"] as? [String: Any],\n let push = cio[\"push\"] as? [String: Any],\n let link = push[\"link\"] as? String,\n !launchOptions.keys.contains(UIApplication.LaunchOptionsKey.url) {\n \n var mutableLaunchOptions = launchOptions\n mutableLaunchOptions[UIApplication.LaunchOptionsKey.url] = URL(string: link)\n modifiedLaunchOptions = mutableLaunchOptions\n }\n // Deep link workaround for app killed state ends\n`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = `\n@objc(registerPushNotification)\n public func registerPushNotification() {\n\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2 = `\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER = /\\{\\{REGISTER_SNIPPET\\}\\}/;\n// Regex to match MessagingPush initialization in AppDelegate (different from NSE initialization)\nexport const CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX = /(MessagingPush(?:APN|FCM)\\.initialize)/;\nexport const CIO_NATIVE_SDK_INITIALIZE_CALL = 'CustomerIOSDKInitializer.initialize()';\nexport const CIO_NATIVE_SDK_INITIALIZE_SNIPPET = `// Auto Initialize Native Customer.io SDK\n ${CIO_NATIVE_SDK_INITIALIZE_CALL}\n `;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_fs","_interopRequireDefault","require","semver","_interopRequireWildcard","_resolveRNSDK","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","path","RN_REALPATH_AUTOLINKING_MIN_VERSION","PLUGIN_LOG_PREFIX","pluginLog","message","console","log","getRelativePathToRNSDK","iosPath","rootAppPath","dirname","packageDir","resolveRNSDK","rnVersion","tryReadRNVersion","useLexical","shouldUseLexicalPath","absolutePath","fs","realpathSync","err","Error","String","relativePath","relative","coerced","valid","coerce","lt","IOS_DEPLOYMENT_TARGET","exports","GROUP_IDENTIFIER_TEMPLATE_REGEX","BUNDLE_SHORT_VERSION_TEMPLATE_REGEX","BUNDLE_VERSION_TEMPLATE_REGEX","CIO_DIDFINISHLAUNCHINGMETHOD_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX","CIO_APPDELEGATEDECLARATION_REGEX","CIO_APPDELEGATEHEADER_REGEX","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX","CIO_DEEPLINK_COMMENT_REGEX","DEFAULT_BUNDLE_VERSION","DEFAULT_BUNDLE_SHORT_VERSION","CIO_TARGET_NAME","CIO_NOTIFICATION_TARGET_NAME","CIO_APPDELEGATEHEADER_IMPORT_SNIPPET","CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET","CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET","CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET","CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET","CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET","CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET","CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET","CIO_INITIALIZECIOSDK_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET","CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET","CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2","CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER","CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX","CIO_NATIVE_SDK_INITIALIZE_CALL","CIO_NATIVE_SDK_INITIALIZE_SNIPPET"],"sources":["ios.ts"],"sourcesContent":["import fs from 'fs';\nimport * as semver from 'semver';\n\nconst path = require('path');\nimport { resolveRNSDK, tryReadRNVersion } from '../../utils/resolveRNSDK';\n\n// Threshold at which React Native pod autolinking moves from\n// @react-native-community/cli (lexical, symlink-preserving) to\n// expo-modules-autolinking (realpath). The two flavors emit different\n// :path strings on pnpm/yarn-symlink layouts, so to keep CocoaPods happy\n// we must match whichever flavor will resolve the same package later.\nconst RN_REALPATH_AUTOLINKING_MIN_VERSION = '0.80.0';\n\nconst PLUGIN_LOG_PREFIX = '[CustomerIO Plugin]';\n\n// Always-on so the trail shows up in customer-shared `expo prebuild`\n// output without needing a separate verbose-mode opt-in.\nfunction pluginLog(message: string): void {\n // eslint-disable-next-line no-console\n console.log(`${PLUGIN_LOG_PREFIX} ${message}`);\n}\n\n/**\n * Returns the relative path from the iOS project dir to the installed\n * customerio-reactnative directory, in the exact form React Native pod\n * autolinking will emit for the same package. The two autolinking\n * flavors disagree on path shape under pnpm/yarn symlinks:\n *\n * - RN <0.80 (`@react-native-community/cli`): walks node_modules\n * lexically, preserves symlinks. We keep the symlink path too —\n * `tryResolveRNSDK` already does this without calling realpath.\n *\n * - RN >=0.80 (`expo-modules-autolinking`): realpaths the package\n * via Node, emitting the underlying `.pnpm/...` (or yarn-classic)\n * path. We match by realpath'ing the resolved directory.\n *\n * Decision points are logged so a customer's prebuild output is enough\n * to triage path-resolution issues without a follow-up \"set\n * CUSTOMERIO_DEBUG_MODE and rerun\" round-trip.\n */\nexport function getRelativePathToRNSDK(iosPath: string) {\n const rootAppPath = path.dirname(iosPath);\n pluginLog(\n `Resolving customerio-reactnative for Podfile (iosPath=${iosPath}, projectRoot=${rootAppPath})`\n );\n\n const { packageDir } = resolveRNSDK(rootAppPath);\n pluginLog(`customerio-reactnative resolved to: ${packageDir}`);\n\n const rnVersion = tryReadRNVersion(rootAppPath);\n pluginLog(`Detected react-native version: ${rnVersion ?? 'unknown'}`);\n\n const useLexical = shouldUseLexicalPath(rnVersion);\n pluginLog(\n useLexical\n ? `RN <${RN_REALPATH_AUTOLINKING_MIN_VERSION} — using lexical/symlink path to match @react-native-community/cli autolinking`\n : `RN >=${RN_REALPATH_AUTOLINKING_MIN_VERSION} or unknown — using realpath to match expo-modules-autolinking`\n );\n\n let absolutePath: string;\n if (useLexical) {\n absolutePath = packageDir;\n } else {\n try {\n absolutePath = fs.realpathSync(packageDir);\n if (absolutePath !== packageDir) {\n pluginLog(`Realpath differs from resolved dir: ${absolutePath}`);\n }\n } catch (err) {\n pluginLog(\n `realpathSync failed (${\n err instanceof Error ? err.message : String(err)\n }); falling back to symlink path`\n );\n absolutePath = packageDir;\n }\n }\n\n const relativePath = path.relative(iosPath, absolutePath);\n pluginLog(`Final Podfile :path => '${relativePath}'`);\n return relativePath;\n}\n\nfunction shouldUseLexicalPath(rnVersion: string | null): boolean {\n if (!rnVersion) {\n // Modern Expo (realpath) has been the working path for the last few\n // SDKs, so it's the safer default when RN can't be detected.\n return false;\n }\n const coerced = semver.valid(rnVersion) || semver.coerce(rnVersion);\n if (!coerced) {\n return false;\n }\n return semver.lt(coerced, RN_REALPATH_AUTOLINKING_MIN_VERSION);\n}\n\nexport const IOS_DEPLOYMENT_TARGET = '13.0';\nexport const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;\nexport const BUNDLE_SHORT_VERSION_TEMPLATE_REGEX = /{{BUNDLE_SHORT_VERSION}}/gm;\nexport const BUNDLE_VERSION_TEMPLATE_REGEX = /{{BUNDLE_VERSION}}/gm;\nexport const CIO_DIDFINISHLAUNCHINGMETHOD_REGEX =\n /.*\\[super(\\s)application:application(\\s)didFinishLaunchingWithOptions:launchOptions\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_REGEX =\n /return \\[super application:application didFailToRegisterForRemoteNotificationsWithError:error\\];/;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERRORFULL_REGEX =\n /(- \\(void\\)application:\\(UIApplication \\*\\)application didFailToRegisterForRemoteNotificationsWithError:\\(NSError \\*\\)error(\\s|\\n)*?\\{)(.|\\n){2}.*\\n\\}/;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_REGEX =\n /return \\[super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken\\];/;\n\nexport const CIO_APPDELEGATEDECLARATION_REGEX =\n /@implementation AppDelegate(.|\\n)/;\n\nexport const CIO_APPDELEGATEHEADER_REGEX =\n /(@interface AppDelegate\\s*:\\s*EXAppDelegateWrapper\\s*)(<([^>]+)>)?/;\n\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*RCTBridge\\s*\\*\\s*\\w+\\s*=\\s*\\[\\s*self\\.reactDelegate\\s+createBridgeWithDelegate:self\\s+launchOptions:launchOptions\\s*\\];\\s*$/gm;\n\nexport const CIO_LAUNCHOPTIONS_DEEPLINK_MODIFIEDOPTIONS_REGEX =\n /^\\s*return\\s\\[\\s*super\\s*application:\\s*application\\s*didFinishLaunchingWithOptions\\s*:\\s*launchOptions\\s*\\];/gm;\n\nexport const CIO_DEEPLINK_COMMENT_REGEX =\n /\\sDeep link workaround for app killed state start/gm;\nexport const DEFAULT_BUNDLE_VERSION = '1';\nexport const DEFAULT_BUNDLE_SHORT_VERSION = '1.0';\nexport const CIO_TARGET_NAME = 'CustomerIOSDK';\nexport const CIO_NOTIFICATION_TARGET_NAME = 'NotificationService';\n\nexport const CIO_APPDELEGATEHEADER_IMPORT_SNIPPET = `#import <UserNotifications/UserNotifications.h>`;\nexport const CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET =\n 'UNUserNotificationCenterDelegate';\nexport const CIO_PUSHNOTIFICATIONHANDLERDECLARATION_SNIPPET = `\nCIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];\n`;\nexport const CIO_RCTBRIDGE_DEEPLINK_MODIFIEDOPTIONS_SNIPPET = `\nRCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:modifiedLaunchOptions];\n`;\n\nexport const CIO_LAUNCHOPTIONS_MODIFIEDOPTIONS_SNIPPET = `\nreturn [super application:application didFinishLaunchingWithOptions:modifiedLaunchOptions];`;\n\nexport const CIO_DIDFAILTOREGISTERFORREMOTENOTIFICATIONSWITHERROR_SNIPPET = `\n [super application:application didFailToRegisterForRemoteNotificationsWithError:error];\n [pnHandlerObj application:application error:error];\n`;\n\nexport const CIO_DIDREGISTERFORREMOTENOTIFICATIONSWITHDEVICETOKEN_SNIPPET = `\n [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];\n return [pnHandlerObj application:application deviceToken:deviceToken];\n`;\n\nexport const CIO_CONFIGURECIOSDKPUSHNOTIFICATION_SNIPPET = `\n // Register for push notifications\n [pnHandlerObj registerPushNotification];\n`;\n\nexport const CIO_INITIALIZECIOSDK_SNIPPET = ` \n [pnHandlerObj initializeCioSdk];\n\n// Code to make the CIO SDK compatible with expo-notifications package.\n// \n// The CIO SDK and expo-notifications both need to handle when a push gets clicked. However, iOS only allows one click handler to be set per app.\n// To get around this limitation, we set the CIO SDK as the click handler. The CIO SDK sets itself up so that when another SDK or host iOS app \n// sets itself as the click handler, the CIO SDK will still be able to handle when the push gets clicked, even though it's not the designated \n// click handler in iOS at runtime. \n// \n// This should work for most SDKs. However, expo-notifications is unique in it's implementation. It will not setup push click handling it if detects \n// that another SDK or host iOS app has already set itself as the click handler:\n// https://github.com/expo/expo/blob/1b29637bec0b9888e8bc8c310476293a3e2d9786/packages/expo-notifications/ios/EXNotifications/Notifications/EXNotificationCenterDelegate.m#L31-L37\n// ...to get around this, we must manually set it as the click handler after the CIO SDK. That's what this code block does.\n//\n// Note: Initialize the native iOS SDK and setup SDK push click handling before running this code. \n# if __has_include(<EXNotifications/EXNotificationCenterDelegate.h>)\n // Creating a new instance, as the comments in expo-notifications suggests, does not work. With this code, if you send a CIO push to device and click on it,\n // no push metrics reporting will occur.\n // EXNotificationCenterDelegate *notificationCenterDelegate = [[EXNotificationCenterDelegate alloc] init];\n\n // ...instead, get the singleton reference from Expo. \n id<UNUserNotificationCenterDelegate> notificationCenterDelegate = (id<UNUserNotificationCenterDelegate>) [EXModuleRegistryProvider getSingletonModuleForClass:[EXNotificationCenterDelegate class]];\n UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];\n center.delegate = notificationCenterDelegate;\n# endif\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SNIPPET = `\n// Deep link workaround for app killed state start\nNSMutableDictionary *modifiedLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];\n if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {\n NSDictionary *pushContent = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];\n if (pushContent[@\"CIO\"] && pushContent[@\"CIO\"][@\"push\"] && pushContent[@\"CIO\"][@\"push\"][@\"link\"]) {\n NSString *initialURL = pushContent[@\"CIO\"][@\"push\"][@\"link\"];\n if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {\n modifiedLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];\n }\n }\n }\n//Deep link workaround for app killed state ends\n`;\n\nexport const CIO_CONFIGUREDEEPLINK_KILLEDSTATE_SWIFT_SNIPPET = `\n // Deep link workaround for app killed state start\n var modifiedLaunchOptions = launchOptions\n if let launchOptions = launchOptions,\n let pushContent = launchOptions[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any],\n let cio = pushContent[\"CIO\"] as? [String: Any],\n let push = cio[\"push\"] as? [String: Any],\n let link = push[\"link\"] as? String,\n !launchOptions.keys.contains(UIApplication.LaunchOptionsKey.url) {\n \n var mutableLaunchOptions = launchOptions\n mutableLaunchOptions[UIApplication.LaunchOptionsKey.url] = URL(string: link)\n modifiedLaunchOptions = mutableLaunchOptions\n }\n // Deep link workaround for app killed state ends\n`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET = `\n@objc(registerPushNotification)\n public func registerPushNotification() {\n\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSHNOTIFICATION_SNIPPET_v2 = `\n let center = UNUserNotificationCenter.current()\n center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in\n if error == nil{\n DispatchQueue.main.async {\n UIApplication.shared.registerForRemoteNotifications()\n }\n }\n }`;\n\nexport const CIO_REGISTER_PUSH_NOTIFICATION_PLACEHOLDER = /\\{\\{REGISTER_SNIPPET\\}\\}/;\n// Regex to match MessagingPush initialization in AppDelegate (different from NSE initialization)\nexport const CIO_MESSAGING_PUSH_APP_DELEGATE_INIT_REGEX = /(MessagingPush(?:APN|FCM)\\.initialize)/;\nexport const CIO_NATIVE_SDK_INITIALIZE_CALL = 'CustomerIOSDKInitializer.initialize()';\nexport const CIO_NATIVE_SDK_INITIALIZE_SNIPPET = `// Auto Initialize Native Customer.io SDK\n ${CIO_NATIVE_SDK_INITIALIZE_CALL}\n `;\n"],"mappings":"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","ignoreList":[]}
@@ -3,66 +3,111 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.appendNotificationTargetToPodfile = appendNotificationTargetToPodfile;
6
7
  exports.buildHostAppPodSnippet = buildHostAppPodSnippet;
7
8
  exports.injectCIONotificationPodfileCode = injectCIONotificationPodfileCode;
8
9
  exports.injectCIOPodfileCode = injectCIOPodfileCode;
10
+ exports.injectHostAppPodfileCode = injectHostAppPodfileCode;
9
11
  var _logger = require("../../utils/logger");
10
12
  var _ios = require("../constants/ios");
11
13
  var _codeInjection = require("./codeInjection");
12
14
  var _fileManagement = require("./fileManagement");
13
- /** Builds the host app pod line for the Podfile (single subspec or :subspecs with location). Exported for tests. */
15
+ /** Builds the host-app pod snippet for the Podfile.
16
+ *
17
+ * The :path is resolved at prebuild time by `getRelativePathToRNSDK`,
18
+ * which dispatches on the installed React Native version so the path
19
+ * matches what RN pod autolinking will emit (lexical for RN <0.80,
20
+ * realpath for RN >=0.80). Baking the resolved string directly avoids
21
+ * any Ruby/install-time logic in the Podfile and keeps the snippet
22
+ * trivially diff-able.
23
+ *
24
+ * Exported for tests.
25
+ */
14
26
  function buildHostAppPodSnippet(iosPath, isFcmPushProvider, options) {
15
- const path = (0, _ios.getRelativePathToRNSDK)(iosPath);
27
+ const resolvedPath = (0, _ios.getRelativePathToRNSDK)(iosPath);
16
28
  const locationEnabled = (options === null || options === void 0 ? void 0 : options.locationEnabled) === true;
17
29
  const hasPush = (options === null || options === void 0 ? void 0 : options.hasPush) !== false;
18
30
  if (!locationEnabled) {
19
31
  const subspec = isFcmPushProvider ? 'fcm' : 'apn';
20
- return `pod 'customerio-reactnative/${subspec}', :path => '${path}'`;
32
+ return `pod 'customerio-reactnative/${subspec}', :path => '${resolvedPath}'`;
21
33
  }
22
34
  if (!hasPush) {
23
- return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${path}'`;
35
+ return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${resolvedPath}'`;
24
36
  }
25
37
  const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';
26
- return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${path}'`;
38
+ return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${resolvedPath}'`;
39
+ }
40
+ const HOST_APP_BLOCK_START = '# --- CustomerIO Host App START ---';
41
+ const HOST_APP_BLOCK_END = '# --- CustomerIO Host App END ---';
42
+ const NOTIFICATION_BLOCK_START = '# --- CustomerIO Notification START ---';
43
+ const NOTIFICATION_BLOCK_END = '# --- CustomerIO Notification END ---';
44
+
45
+ /**
46
+ * Pure string transform: given the existing Podfile contents, returns the
47
+ * Podfile with the CustomerIO host-app block injected before the Expo
48
+ * `post_install do |installer|` anchor. Idempotent — returns input unchanged
49
+ * if the block is already present.
50
+ */
51
+ function injectHostAppPodfileCode(podfileContent, iosPath, isFcmPushProvider, options) {
52
+ if (podfileContent.match(new RegExp(HOST_APP_BLOCK_START))) {
53
+ return podfileContent;
54
+ }
55
+
56
+ // We need to decide what line of code in the Podfile to insert our native code.
57
+ // The "post_install" line is always present in an Expo project Podfile so it's reliable.
58
+ // Find that line in the Podfile and then we will insert our code above that line.
59
+ const lineInPodfileToInjectSnippetBefore = /post_install do \|installer\|/;
60
+ const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);
61
+ const snippetToInjectInPodfile = `
62
+ ${HOST_APP_BLOCK_START}
63
+ ${podLine}
64
+ ${HOST_APP_BLOCK_END}
65
+ `.trim();
66
+ return (0, _codeInjection.injectCodeByRegex)(podfileContent, lineInPodfileToInjectSnippetBefore, snippetToInjectInPodfile).join('\n');
27
67
  }
28
68
  async function injectCIOPodfileCode(iosPath, isFcmPushProvider, options) {
29
- const blockStart = '# --- CustomerIO Host App START ---';
30
- const blockEnd = '# --- CustomerIO Host App END ---';
31
69
  const filename = `${iosPath}/Podfile`;
32
70
  const podfile = await _fileManagement.FileManagement.read(filename);
33
- const matches = podfile.match(new RegExp(blockStart));
34
- if (!matches) {
35
- // We need to decide what line of code in the Podfile to insert our native code.
36
- // The "post_install" line is always present in an Expo project Podfile so it's reliable.
37
- // Find that line in the Podfile and then we will insert our code above that line.
38
- const lineInPodfileToInjectSnippetBefore = /post_install do \|installer\|/;
39
- const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);
40
- const snippetToInjectInPodfile = `
41
- ${blockStart}
42
- ${podLine}
43
- ${blockEnd}
44
- `.trim();
45
- _fileManagement.FileManagement.write(filename, (0, _codeInjection.injectCodeByRegex)(podfile, lineInPodfileToInjectSnippetBefore, snippetToInjectInPodfile).join('\n'));
71
+ const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);
72
+ if (next !== podfile) {
73
+ _fileManagement.FileManagement.write(filename, next);
46
74
  } else {
47
75
  _logger.logger.info('CustomerIO Podfile snippets already exists. Skipping...');
48
76
  }
49
77
  }
50
- async function injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmPushProvider) {
51
- const filename = `${iosPath}/Podfile`;
52
- const podfile = await _fileManagement.FileManagement.read(filename);
53
- const blockStart = '# --- CustomerIO Notification START ---';
54
- const blockEnd = '# --- CustomerIO Notification END ---';
55
- const matches = podfile.match(new RegExp(blockStart));
56
- if (!matches) {
57
- const snippetToInjectInPodfile = `
58
- ${blockStart}
78
+
79
+ /**
80
+ * Pure string transform: given the existing Podfile contents, returns the
81
+ * Podfile with the rich-push NotificationService target block appended at
82
+ * the end. Idempotent returns input unchanged if the block is already
83
+ * present.
84
+ */
85
+ function appendNotificationTargetToPodfile(podfileContent, iosPath, isFcmPushProvider, useFrameworks) {
86
+ if (podfileContent.match(new RegExp(NOTIFICATION_BLOCK_START))) {
87
+ return podfileContent;
88
+ }
89
+ const snippetToAppend = `
90
+ ${NOTIFICATION_BLOCK_START}
59
91
  target 'NotificationService' do
60
92
  ${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}
61
93
  pod 'customerio-reactnative-richpush/${isFcmPushProvider ? 'fcm' : 'apn'}', :path => '${(0, _ios.getRelativePathToRNSDK)(iosPath)}'
62
94
  end
63
- ${blockEnd}
95
+ ${NOTIFICATION_BLOCK_END}
64
96
  `.trim();
65
- _fileManagement.FileManagement.append(filename, snippetToInjectInPodfile);
97
+
98
+ // Mirror FileManagement.append: append directly with no separator (real
99
+ // Podfiles end with a trailing newline, so the appended block starts on a
100
+ // fresh line in practice).
101
+ return `${podfileContent}${snippetToAppend}`;
102
+ }
103
+ async function injectCIONotificationPodfileCode(iosPath, useFrameworks, isFcmPushProvider) {
104
+ const filename = `${iosPath}/Podfile`;
105
+ const podfile = await _fileManagement.FileManagement.read(filename);
106
+ const next = appendNotificationTargetToPodfile(podfile, iosPath, isFcmPushProvider, useFrameworks);
107
+ if (next !== podfile) {
108
+ // FileManagement.append matches what the previous direct-append did.
109
+ // Slice off the leading content (already on disk) and append only the new tail.
110
+ _fileManagement.FileManagement.append(filename, next.slice(podfile.length));
66
111
  }
67
112
  }
68
113
  //# sourceMappingURL=injectCIOPodfileCode.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_logger","require","_ios","_codeInjection","_fileManagement","buildHostAppPodSnippet","iosPath","isFcmPushProvider","options","path","getRelativePathToRNSDK","locationEnabled","hasPush","subspec","pushSubspec","injectCIOPodfileCode","blockStart","blockEnd","filename","podfile","FileManagement","read","matches","match","RegExp","lineInPodfileToInjectSnippetBefore","podLine","snippetToInjectInPodfile","trim","write","injectCodeByRegex","join","logger","info","injectCIONotificationPodfileCode","useFrameworks","append"],"sources":["injectCIOPodfileCode.ts"],"sourcesContent":["import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';\nimport { logger } from '../../utils/logger';\nimport { getRelativePathToRNSDK } from '../constants/ios';\nimport { injectCodeByRegex } from './codeInjection';\nimport { FileManagement } from './fileManagement';\n\nexport type InjectCIOPodfileOptions = {\n /** When true, add the location subspec. When false/omit, use single push subspec only. */\n locationEnabled?: boolean;\n /** When false and locationEnabled, inject only :subspecs => ['location']. When true, use push + location. */\n hasPush?: boolean;\n};\n\n/** Builds the host app pod line for the Podfile (single subspec or :subspecs with location). Exported for tests. */\nexport function buildHostAppPodSnippet(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n const path = getRelativePathToRNSDK(iosPath);\n const locationEnabled = options?.locationEnabled === true;\n const hasPush = options?.hasPush !== false;\n\n if (!locationEnabled) {\n const subspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative/${subspec}', :path => '${path}'`;\n }\n\n if (!hasPush) {\n return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${path}'`;\n }\n\n const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${path}'`;\n}\n\nexport async function injectCIOPodfileCode(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n) {\n const blockStart = '# --- CustomerIO Host App START ---';\n const blockEnd = '# --- CustomerIO Host App END ---';\n\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const matches = podfile.match(new RegExp(blockStart));\n\n if (!matches) {\n // We need to decide what line of code in the Podfile to insert our native code.\n // The \"post_install\" line is always present in an Expo project Podfile so it's reliable.\n // Find that line in the Podfile and then we will insert our code above that line.\n const lineInPodfileToInjectSnippetBefore = /post_install do \\|installer\\|/;\n\n const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);\n\n const snippetToInjectInPodfile = `\n${blockStart}\n ${podLine}\n${blockEnd}\n`.trim();\n\n FileManagement.write(\n filename,\n injectCodeByRegex(\n podfile,\n lineInPodfileToInjectSnippetBefore,\n snippetToInjectInPodfile\n ).join('\\n')\n );\n } else {\n logger.info('CustomerIO Podfile snippets already exists. Skipping...');\n }\n}\n\nexport async function injectCIONotificationPodfileCode(\n iosPath: string,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n isFcmPushProvider: boolean\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n\n const blockStart = '# --- CustomerIO Notification START ---';\n const blockEnd = '# --- CustomerIO Notification END ---';\n\n const matches = podfile.match(new RegExp(blockStart));\n\n if (!matches) {\n const snippetToInjectInPodfile = `\n${blockStart}\ntarget 'NotificationService' do\n ${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}\n pod 'customerio-reactnative-richpush/${isFcmPushProvider ? 'fcm' : 'apn'\n }', :path => '${getRelativePathToRNSDK(iosPath)}'\nend\n${blockEnd}\n`.trim();\n\n FileManagement.append(filename, snippetToInjectInPodfile);\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_logger","require","_ios","_codeInjection","_fileManagement","buildHostAppPodSnippet","iosPath","isFcmPushProvider","options","resolvedPath","getRelativePathToRNSDK","locationEnabled","hasPush","subspec","pushSubspec","HOST_APP_BLOCK_START","HOST_APP_BLOCK_END","NOTIFICATION_BLOCK_START","NOTIFICATION_BLOCK_END","injectHostAppPodfileCode","podfileContent","match","RegExp","lineInPodfileToInjectSnippetBefore","podLine","snippetToInjectInPodfile","trim","injectCodeByRegex","join","injectCIOPodfileCode","filename","podfile","FileManagement","read","next","write","logger","info","appendNotificationTargetToPodfile","useFrameworks","snippetToAppend","injectCIONotificationPodfileCode","append","slice","length"],"sources":["injectCIOPodfileCode.ts"],"sourcesContent":["import type { CustomerIOPluginOptionsIOS } from '../../types/cio-types';\nimport { logger } from '../../utils/logger';\nimport { getRelativePathToRNSDK } from '../constants/ios';\nimport { injectCodeByRegex } from './codeInjection';\nimport { FileManagement } from './fileManagement';\n\nexport type InjectCIOPodfileOptions = {\n /** When true, add the location subspec. When false/omit, use single push subspec only. */\n locationEnabled?: boolean;\n /** When false and locationEnabled, inject only :subspecs => ['location']. When true, use push + location. */\n hasPush?: boolean;\n};\n\n/** Builds the host-app pod snippet for the Podfile.\n *\n * The :path is resolved at prebuild time by `getRelativePathToRNSDK`,\n * which dispatches on the installed React Native version so the path\n * matches what RN pod autolinking will emit (lexical for RN <0.80,\n * realpath for RN >=0.80). Baking the resolved string directly avoids\n * any Ruby/install-time logic in the Podfile and keeps the snippet\n * trivially diff-able.\n *\n * Exported for tests.\n */\nexport function buildHostAppPodSnippet(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n const resolvedPath = getRelativePathToRNSDK(iosPath);\n const locationEnabled = options?.locationEnabled === true;\n const hasPush = options?.hasPush !== false;\n\n if (!locationEnabled) {\n const subspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative/${subspec}', :path => '${resolvedPath}'`;\n }\n if (!hasPush) {\n return `pod 'customerio-reactnative', :subspecs => ['location'], :path => '${resolvedPath}'`;\n }\n const pushSubspec = isFcmPushProvider ? 'fcm' : 'apn';\n return `pod 'customerio-reactnative', :subspecs => ['${pushSubspec}', 'location'], :path => '${resolvedPath}'`;\n}\n\nconst HOST_APP_BLOCK_START = '# --- CustomerIO Host App START ---';\nconst HOST_APP_BLOCK_END = '# --- CustomerIO Host App END ---';\nconst NOTIFICATION_BLOCK_START = '# --- CustomerIO Notification START ---';\nconst NOTIFICATION_BLOCK_END = '# --- CustomerIO Notification END ---';\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the CustomerIO host-app block injected before the Expo\n * `post_install do |installer|` anchor. Idempotent — returns input unchanged\n * if the block is already present.\n */\nexport function injectHostAppPodfileCode(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n): string {\n if (podfileContent.match(new RegExp(HOST_APP_BLOCK_START))) {\n return podfileContent;\n }\n\n // We need to decide what line of code in the Podfile to insert our native code.\n // The \"post_install\" line is always present in an Expo project Podfile so it's reliable.\n // Find that line in the Podfile and then we will insert our code above that line.\n const lineInPodfileToInjectSnippetBefore = /post_install do \\|installer\\|/;\n const podLine = buildHostAppPodSnippet(iosPath, isFcmPushProvider, options);\n\n const snippetToInjectInPodfile = `\n${HOST_APP_BLOCK_START}\n ${podLine}\n${HOST_APP_BLOCK_END}\n`.trim();\n\n return injectCodeByRegex(\n podfileContent,\n lineInPodfileToInjectSnippetBefore,\n snippetToInjectInPodfile,\n ).join('\\n');\n}\n\nexport async function injectCIOPodfileCode(\n iosPath: string,\n isFcmPushProvider: boolean,\n options?: InjectCIOPodfileOptions\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = injectHostAppPodfileCode(podfile, iosPath, isFcmPushProvider, options);\n if (next !== podfile) {\n FileManagement.write(filename, next);\n } else {\n logger.info('CustomerIO Podfile snippets already exists. Skipping...');\n }\n}\n\n/**\n * Pure string transform: given the existing Podfile contents, returns the\n * Podfile with the rich-push NotificationService target block appended at\n * the end. Idempotent — returns input unchanged if the block is already\n * present.\n */\nexport function appendNotificationTargetToPodfile(\n podfileContent: string,\n iosPath: string,\n isFcmPushProvider: boolean,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n): string {\n if (podfileContent.match(new RegExp(NOTIFICATION_BLOCK_START))) {\n return podfileContent;\n }\n\n const snippetToAppend = `\n${NOTIFICATION_BLOCK_START}\ntarget 'NotificationService' do\n ${useFrameworks === 'static' ? 'use_frameworks! :linkage => :static' : ''}\n pod 'customerio-reactnative-richpush/${isFcmPushProvider ? 'fcm' : 'apn'}', :path => '${getRelativePathToRNSDK(iosPath)}'\nend\n${NOTIFICATION_BLOCK_END}\n`.trim();\n\n // Mirror FileManagement.append: append directly with no separator (real\n // Podfiles end with a trailing newline, so the appended block starts on a\n // fresh line in practice).\n return `${podfileContent}${snippetToAppend}`;\n}\n\nexport async function injectCIONotificationPodfileCode(\n iosPath: string,\n useFrameworks: CustomerIOPluginOptionsIOS['useFrameworks'],\n isFcmPushProvider: boolean\n) {\n const filename = `${iosPath}/Podfile`;\n const podfile = await FileManagement.read(filename);\n const next = appendNotificationTargetToPodfile(\n podfile,\n iosPath,\n isFcmPushProvider,\n useFrameworks,\n );\n if (next !== podfile) {\n // FileManagement.append matches what the previous direct-append did.\n // Slice off the leading content (already on disk) and append only the new tail.\n FileManagement.append(filename, next.slice(podfile.length));\n }\n}\n"],"mappings":";;;;;;;;;;AACA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,IAAA,GAAAD,OAAA;AACA,IAAAE,cAAA,GAAAF,OAAA;AACA,IAAAG,eAAA,GAAAH,OAAA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,sBAAsBA,CACpCC,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACzB;EACR,MAAMC,YAAY,GAAG,IAAAC,2BAAsB,EAACJ,OAAO,CAAC;EACpD,MAAMK,eAAe,GAAG,CAAAH,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEG,eAAe,MAAK,IAAI;EACzD,MAAMC,OAAO,GAAG,CAAAJ,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEI,OAAO,MAAK,KAAK;EAE1C,IAAI,CAACD,eAAe,EAAE;IACpB,MAAME,OAAO,GAAGN,iBAAiB,GAAG,KAAK,GAAG,KAAK;IACjD,OAAO,+BAA+BM,OAAO,gBAAgBJ,YAAY,GAAG;EAC9E;EACA,IAAI,CAACG,OAAO,EAAE;IACZ,OAAO,sEAAsEH,YAAY,GAAG;EAC9F;EACA,MAAMK,WAAW,GAAGP,iBAAiB,GAAG,KAAK,GAAG,KAAK;EACrD,OAAO,gDAAgDO,WAAW,6BAA6BL,YAAY,GAAG;AAChH;AAEA,MAAMM,oBAAoB,GAAG,qCAAqC;AAClE,MAAMC,kBAAkB,GAAG,mCAAmC;AAC9D,MAAMC,wBAAwB,GAAG,yCAAyC;AAC1E,MAAMC,sBAAsB,GAAG,uCAAuC;;AAEtE;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,wBAAwBA,CACtCC,cAAsB,EACtBd,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACzB;EACR,IAAIY,cAAc,CAACC,KAAK,CAAC,IAAIC,MAAM,CAACP,oBAAoB,CAAC,CAAC,EAAE;IAC1D,OAAOK,cAAc;EACvB;;EAEA;EACA;EACA;EACA,MAAMG,kCAAkC,GAAG,+BAA+B;EAC1E,MAAMC,OAAO,GAAGnB,sBAAsB,CAACC,OAAO,EAAEC,iBAAiB,EAAEC,OAAO,CAAC;EAE3E,MAAMiB,wBAAwB,GAAG;AACnC,EAAEV,oBAAoB;AACtB,IAAIS,OAAO;AACX,EAAER,kBAAkB;AACpB,CAAC,CAACU,IAAI,CAAC,CAAC;EAEN,OAAO,IAAAC,gCAAiB,EACtBP,cAAc,EACdG,kCAAkC,EAClCE,wBACF,CAAC,CAACG,IAAI,CAAC,IAAI,CAAC;AACd;AAEO,eAAeC,oBAAoBA,CACxCvB,OAAe,EACfC,iBAA0B,EAC1BC,OAAiC,EACjC;EACA,MAAMsB,QAAQ,GAAG,GAAGxB,OAAO,UAAU;EACrC,MAAMyB,OAAO,GAAG,MAAMC,8BAAc,CAACC,IAAI,CAACH,QAAQ,CAAC;EACnD,MAAMI,IAAI,GAAGf,wBAAwB,CAACY,OAAO,EAAEzB,OAAO,EAAEC,iBAAiB,EAAEC,OAAO,CAAC;EACnF,IAAI0B,IAAI,KAAKH,OAAO,EAAE;IACpBC,8BAAc,CAACG,KAAK,CAACL,QAAQ,EAAEI,IAAI,CAAC;EACtC,CAAC,MAAM;IACLE,cAAM,CAACC,IAAI,CAAC,yDAAyD,CAAC;EACxE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,iCAAiCA,CAC/ClB,cAAsB,EACtBd,OAAe,EACfC,iBAA0B,EAC1BgC,aAA0D,EAClD;EACR,IAAInB,cAAc,CAACC,KAAK,CAAC,IAAIC,MAAM,CAACL,wBAAwB,CAAC,CAAC,EAAE;IAC9D,OAAOG,cAAc;EACvB;EAEA,MAAMoB,eAAe,GAAG;AAC1B,EAAEvB,wBAAwB;AAC1B;AACA,IAAIsB,aAAa,KAAK,QAAQ,GAAG,qCAAqC,GAAG,EAAE;AAC3E,yCAAyChC,iBAAiB,GAAG,KAAK,GAAG,KAAK,gBAAgB,IAAAG,2BAAsB,EAACJ,OAAO,CAAC;AACzH;AACA,EAAEY,sBAAsB;AACxB,CAAC,CAACQ,IAAI,CAAC,CAAC;;EAEN;EACA;EACA;EACA,OAAO,GAAGN,cAAc,GAAGoB,eAAe,EAAE;AAC9C;AAEO,eAAeC,gCAAgCA,CACpDnC,OAAe,EACfiC,aAA0D,EAC1DhC,iBAA0B,EAC1B;EACA,MAAMuB,QAAQ,GAAG,GAAGxB,OAAO,UAAU;EACrC,MAAMyB,OAAO,GAAG,MAAMC,8BAAc,CAACC,IAAI,CAACH,QAAQ,CAAC;EACnD,MAAMI,IAAI,GAAGI,iCAAiC,CAC5CP,OAAO,EACPzB,OAAO,EACPC,iBAAiB,EACjBgC,aACF,CAAC;EACD,IAAIL,IAAI,KAAKH,OAAO,EAAE;IACpB;IACA;IACAC,8BAAc,CAACU,MAAM,CAACZ,QAAQ,EAAEI,IAAI,CAACS,KAAK,CAACZ,OAAO,CAACa,MAAM,CAAC,CAAC;EAC7D;AACF","ignoreList":[]}
@@ -7,6 +7,7 @@ exports.default = void 0;
7
7
  var _withCIOAndroid = require("./android/withCIOAndroid");
8
8
  var _utils = require("./ios/utils");
9
9
  var _withCIOIos = require("./ios/withCIOIos");
10
+ var _writeExpoVersion = require("./utils/writeExpoVersion");
10
11
  // Entry point for config plugin
11
12
  function withCustomerIOPlugin(config, props) {
12
13
  // Check if config is being used with unsupported Expo version
@@ -14,6 +15,12 @@ function withCustomerIOPlugin(config, props) {
14
15
  throw new Error('CustomerIO auto initialization (config property) requires Expo SDK 53 or higher. ' + 'Please upgrade to Expo SDK 53+ or use manual initialization instead. ' + 'See documentation for manual setup instructions.');
15
16
  }
16
17
 
18
+ // Belt-and-suspenders write of the plugin version into the RN SDK's
19
+ // package.json. The postinstall hook does the same write at install time;
20
+ // this covers installs where postinstall didn't run cleanly (pnpm with
21
+ // strict store layouts, --ignore-scripts, cached CI installs, etc).
22
+ config = (0, _writeExpoVersion.withExpoVersion)(config);
23
+
17
24
  // Apply platform specific modifications
18
25
  config = (0, _withCIOIos.withCIOIos)(config, props.config, props.ios, props.location);
19
26
  config = (0, _withCIOAndroid.withCIOAndroid)(config, props.config, props.android, props.location);
@@ -1 +1 @@
1
- {"version":3,"names":["_withCIOAndroid","require","_utils","_withCIOIos","withCustomerIOPlugin","config","props","isExpoVersion53OrHigher","Error","withCIOIos","ios","location","withCIOAndroid","android","_default","exports","default"],"sources":["index.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config-types';\n\nimport { withCIOAndroid } from './android/withCIOAndroid';\nimport { isExpoVersion53OrHigher } from './ios/utils';\nimport { withCIOIos } from './ios/withCIOIos';\nimport type {\n CustomerIOPluginOptions,\n LocationTrackingMode,\n NativeSDKConfig,\n} from './types/cio-types';\n\nexport type { LocationTrackingMode, NativeSDKConfig };\n\n// Entry point for config plugin\nfunction withCustomerIOPlugin(\n config: ExpoConfig,\n props: CustomerIOPluginOptions\n) {\n // Check if config is being used with unsupported Expo version\n if (props.config && !isExpoVersion53OrHigher(config)) {\n throw new Error(\n 'CustomerIO auto initialization (config property) requires Expo SDK 53 or higher. ' +\n 'Please upgrade to Expo SDK 53+ or use manual initialization instead. ' +\n 'See documentation for manual setup instructions.'\n );\n }\n\n // Apply platform specific modifications\n config = withCIOIos(config, props.config, props.ios, props.location);\n config = withCIOAndroid(config, props.config, props.android, props.location);\n\n return config;\n}\n\nexport default withCustomerIOPlugin;\n"],"mappings":";;;;;;AAEA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,WAAA,GAAAF,OAAA;AASA;AACA,SAASG,oBAAoBA,CAC3BC,MAAkB,EAClBC,KAA8B,EAC9B;EACA;EACA,IAAIA,KAAK,CAACD,MAAM,IAAI,CAAC,IAAAE,8BAAuB,EAACF,MAAM,CAAC,EAAE;IACpD,MAAM,IAAIG,KAAK,CACb,mFAAmF,GACnF,uEAAuE,GACvE,kDACF,CAAC;EACH;;EAEA;EACAH,MAAM,GAAG,IAAAI,sBAAU,EAACJ,MAAM,EAAEC,KAAK,CAACD,MAAM,EAAEC,KAAK,CAACI,GAAG,EAAEJ,KAAK,CAACK,QAAQ,CAAC;EACpEN,MAAM,GAAG,IAAAO,8BAAc,EAACP,MAAM,EAAEC,KAAK,CAACD,MAAM,EAAEC,KAAK,CAACO,OAAO,EAAEP,KAAK,CAACK,QAAQ,CAAC;EAE5E,OAAON,MAAM;AACf;AAAC,IAAAS,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEcZ,oBAAoB","ignoreList":[]}
1
+ {"version":3,"names":["_withCIOAndroid","require","_utils","_withCIOIos","_writeExpoVersion","withCustomerIOPlugin","config","props","isExpoVersion53OrHigher","Error","withExpoVersion","withCIOIos","ios","location","withCIOAndroid","android","_default","exports","default"],"sources":["index.ts"],"sourcesContent":["import type { ExpoConfig } from '@expo/config-types';\n\nimport { withCIOAndroid } from './android/withCIOAndroid';\nimport { isExpoVersion53OrHigher } from './ios/utils';\nimport { withCIOIos } from './ios/withCIOIos';\nimport type {\n CustomerIOPluginOptions,\n LocationTrackingMode,\n NativeSDKConfig,\n} from './types/cio-types';\nimport { withExpoVersion } from './utils/writeExpoVersion';\n\nexport type { LocationTrackingMode, NativeSDKConfig };\n\n// Entry point for config plugin\nfunction withCustomerIOPlugin(\n config: ExpoConfig,\n props: CustomerIOPluginOptions\n) {\n // Check if config is being used with unsupported Expo version\n if (props.config && !isExpoVersion53OrHigher(config)) {\n throw new Error(\n 'CustomerIO auto initialization (config property) requires Expo SDK 53 or higher. ' +\n 'Please upgrade to Expo SDK 53+ or use manual initialization instead. ' +\n 'See documentation for manual setup instructions.'\n );\n }\n\n // Belt-and-suspenders write of the plugin version into the RN SDK's\n // package.json. The postinstall hook does the same write at install time;\n // this covers installs where postinstall didn't run cleanly (pnpm with\n // strict store layouts, --ignore-scripts, cached CI installs, etc).\n config = withExpoVersion(config);\n\n // Apply platform specific modifications\n config = withCIOIos(config, props.config, props.ios, props.location);\n config = withCIOAndroid(config, props.config, props.android, props.location);\n\n return config;\n}\n\nexport default withCustomerIOPlugin;\n"],"mappings":";;;;;;AAEA,IAAAA,eAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AACA,IAAAE,WAAA,GAAAF,OAAA;AAMA,IAAAG,iBAAA,GAAAH,OAAA;AAIA;AACA,SAASI,oBAAoBA,CAC3BC,MAAkB,EAClBC,KAA8B,EAC9B;EACA;EACA,IAAIA,KAAK,CAACD,MAAM,IAAI,CAAC,IAAAE,8BAAuB,EAACF,MAAM,CAAC,EAAE;IACpD,MAAM,IAAIG,KAAK,CACb,mFAAmF,GACnF,uEAAuE,GACvE,kDACF,CAAC;EACH;;EAEA;EACA;EACA;EACA;EACAH,MAAM,GAAG,IAAAI,iCAAe,EAACJ,MAAM,CAAC;;EAEhC;EACAA,MAAM,GAAG,IAAAK,sBAAU,EAACL,MAAM,EAAEC,KAAK,CAACD,MAAM,EAAEC,KAAK,CAACK,GAAG,EAAEL,KAAK,CAACM,QAAQ,CAAC;EACpEP,MAAM,GAAG,IAAAQ,8BAAc,EAACR,MAAM,EAAEC,KAAK,CAACD,MAAM,EAAEC,KAAK,CAACQ,OAAO,EAAER,KAAK,CAACM,QAAQ,CAAC;EAE5E,OAAOP,MAAM;AACf;AAAC,IAAAU,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEcb,oBAAoB","ignoreList":[]}
@@ -3,6 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.modifyAppDelegateContents = modifyAppDelegateContents;
7
+ exports.modifyAppDelegateHeader = modifyAppDelegateHeader;
6
8
  exports.withAppDelegateModifications = void 0;
7
9
  var _configPlugins = require("@expo/config-plugins");
8
10
  var _Paths = require("@expo/config-plugins/build/ios/Paths");
@@ -65,9 +67,13 @@ const addFirebaseDelegateForwardDeclarationIfNeeded = stringContents => {
65
67
  stringContents = (0, _codeInjection.injectCodeByLineNumber)(stringContents, 0, '@protocol FIRMessagingDelegate;');
66
68
  return stringContents;
67
69
  };
68
- const addAppdelegateHeaderModification = stringContents => {
69
- // Add UNUserNotificationCenterDelegate if needed
70
- stringContents = stringContents.replace(_ios.CIO_APPDELEGATEHEADER_REGEX, (match, interfaceDeclaration, _groupedDelegates, existingDelegates) => {
70
+
71
+ /**
72
+ * Pure string transform: ensures the AppDelegate header (Objective-C path) declares
73
+ * `UNUserNotificationCenterDelegate` and imports `UserNotifications`. Idempotent.
74
+ */
75
+ function modifyAppDelegateHeader(headerContent) {
76
+ return headerContent.replace(_ios.CIO_APPDELEGATEHEADER_REGEX, (match, interfaceDeclaration, _groupedDelegates, existingDelegates) => {
71
77
  if (existingDelegates && existingDelegates.includes(_ios.CIO_APPDELEGATEHEADER_USER_NOTIFICATION_CENTER_SNIPPET)) {
72
78
  // The AppDelegate declaration already includes UNUserNotificationCenterDelegate, so we don't need to modify it
73
79
  return match;
@@ -83,8 +89,7 @@ ${interfaceDeclaration.trim()} <${_ios.CIO_APPDELEGATEHEADER_USER_NOTIFICATION_C
83
89
  `;
84
90
  }
85
91
  });
86
- return stringContents;
87
- };
92
+ }
88
93
  const addHandleDeeplinkInKilledState = stringContents => {
89
94
  // Find if the deep link code snippet is already present
90
95
  if ((0, _codeInjection.matchRegexExists)(stringContents, _ios.CIO_DEEPLINK_COMMENT_REGEX)) {
@@ -107,39 +112,48 @@ const addHandleDeeplinkInKilledState = stringContents => {
107
112
  }
108
113
  return stringContents;
109
114
  };
115
+
116
+ /**
117
+ * Pure string transform: produces the modified Objective-C AppDelegate.m / AppDelegate.mm
118
+ * contents wired with the Customer.io push pipeline (imports, declarations, notification
119
+ * configuration, registration callbacks, optional killed-state deep-link, FCM forward decl,
120
+ * Expo notifications header). The caller is responsible for the AppDelegate header file
121
+ * (.h) — see `modifyAppDelegateHeader`.
122
+ */
123
+ function modifyAppDelegateContents(contents, projectName, props) {
124
+ var _props$pushNotificati, _props$pushNotificati2;
125
+ let next = addImport(contents, projectName);
126
+ next = addNotificationHandlerDeclaration(next);
127
+
128
+ // unless this property is explicity set to true, push notification
129
+ // registration will be added to the AppDelegate
130
+ if (((_props$pushNotificati = props.pushNotification) === null || _props$pushNotificati === void 0 ? void 0 : _props$pushNotificati.disableNotificationRegistration) !== true) {
131
+ next = addNotificationConfiguration(next);
132
+ }
133
+ next = addInitializeNativeCioSdk(next);
134
+ if (((_props$pushNotificati2 = props.pushNotification) === null || _props$pushNotificati2 === void 0 ? void 0 : _props$pushNotificati2.handleDeeplinkInKilledState) === true) {
135
+ next = addHandleDeeplinkInKilledState(next);
136
+ }
137
+ next = addDidFailToRegisterForRemoteNotificationsWithError(next);
138
+ next = addDidRegisterForRemoteNotificationsWithDeviceToken(next);
139
+ if ((0, _utils.isFcmPushProvider)(props)) {
140
+ next = addFirebaseDelegateForwardDeclarationIfNeeded(next);
141
+ }
142
+ next = addExpoNotificationsHeaderModification(next);
143
+ return next;
144
+ }
110
145
  const withAppDelegateModifications = (configOuter, props) => {
111
146
  return (0, _configPlugins.withAppDelegate)(configOuter, async config => {
112
- let stringContents = config.modResults.contents;
147
+ const stringContents = config.modResults.contents;
113
148
  const regex = new RegExp(`#import <${config.modRequest.projectName}-Swift.h>`);
114
- const match = stringContents.match(regex);
115
- if (!match) {
116
- var _props$pushNotificati, _props$pushNotificati2;
117
- const headerPath = (0, _Paths.getAppDelegateHeaderFilePath)(config.modRequest.projectRoot);
118
- let headerContent = await _fileManagement.FileManagement.read(headerPath);
119
- headerContent = addAppdelegateHeaderModification(headerContent);
120
- _fileManagement.FileManagement.write(headerPath, headerContent);
121
- stringContents = addImport(stringContents, config.modRequest.projectName);
122
- stringContents = addNotificationHandlerDeclaration(stringContents);
123
-
124
- // unless this property is explicity set to true, push notification
125
- // registration will be added to the AppDelegate
126
- if (((_props$pushNotificati = props.pushNotification) === null || _props$pushNotificati === void 0 ? void 0 : _props$pushNotificati.disableNotificationRegistration) !== true) {
127
- stringContents = addNotificationConfiguration(stringContents);
128
- }
129
- stringContents = addInitializeNativeCioSdk(stringContents);
130
- if (((_props$pushNotificati2 = props.pushNotification) === null || _props$pushNotificati2 === void 0 ? void 0 : _props$pushNotificati2.handleDeeplinkInKilledState) === true) {
131
- stringContents = addHandleDeeplinkInKilledState(stringContents);
132
- }
133
- stringContents = addDidFailToRegisterForRemoteNotificationsWithError(stringContents);
134
- stringContents = addDidRegisterForRemoteNotificationsWithDeviceToken(stringContents);
135
- if ((0, _utils.isFcmPushProvider)(props)) {
136
- stringContents = addFirebaseDelegateForwardDeclarationIfNeeded(stringContents);
137
- }
138
- stringContents = addExpoNotificationsHeaderModification(stringContents);
139
- config.modResults.contents = stringContents;
140
- } else {
149
+ if (stringContents.match(regex)) {
141
150
  _logger.logger.info('Customerio AppDelegate changes already exist. Skipping...');
151
+ return config;
142
152
  }
153
+ const headerPath = (0, _Paths.getAppDelegateHeaderFilePath)(config.modRequest.projectRoot);
154
+ const headerContent = await _fileManagement.FileManagement.read(headerPath);
155
+ _fileManagement.FileManagement.write(headerPath, modifyAppDelegateHeader(headerContent));
156
+ config.modResults.contents = modifyAppDelegateContents(stringContents, config.modRequest.projectName, props);
143
157
  return config;
144
158
  });
145
159
  };