@callstack/react-native-brownfield 2.2.0 → 3.0.0-rc.1

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 (223) hide show
  1. package/lib/commonjs/expo-config-plugin/android/constants.js +2 -0
  2. package/lib/commonjs/expo-config-plugin/android/constants.js.map +1 -0
  3. package/lib/commonjs/expo-config-plugin/android/gradleHelpers.js +2 -0
  4. package/lib/commonjs/expo-config-plugin/android/gradleHelpers.js.map +1 -0
  5. package/lib/commonjs/expo-config-plugin/android/index.js +2 -0
  6. package/lib/commonjs/expo-config-plugin/android/index.js.map +1 -0
  7. package/lib/commonjs/expo-config-plugin/android/withAndroidModuleFiles.js +2 -0
  8. package/lib/commonjs/expo-config-plugin/android/withAndroidModuleFiles.js.map +1 -0
  9. package/lib/commonjs/expo-config-plugin/android/withBrownfieldAndroid.js +2 -0
  10. package/lib/commonjs/expo-config-plugin/android/withBrownfieldAndroid.js.map +1 -0
  11. package/lib/commonjs/expo-config-plugin/app.plugin.js +2 -0
  12. package/lib/commonjs/expo-config-plugin/app.plugin.js.map +1 -0
  13. package/lib/commonjs/expo-config-plugin/errors/SourceModificationError.js +2 -0
  14. package/lib/commonjs/expo-config-plugin/errors/SourceModificationError.js.map +1 -0
  15. package/lib/commonjs/expo-config-plugin/index.js +2 -0
  16. package/lib/commonjs/expo-config-plugin/index.js.map +1 -0
  17. package/lib/commonjs/expo-config-plugin/ios/index.js +2 -0
  18. package/lib/commonjs/expo-config-plugin/ios/index.js.map +1 -0
  19. package/lib/commonjs/expo-config-plugin/ios/podfileHelpers.js +31 -0
  20. package/lib/commonjs/expo-config-plugin/ios/podfileHelpers.js.map +1 -0
  21. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js +2 -0
  22. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -0
  23. package/lib/commonjs/expo-config-plugin/ios/withIosFrameworkFiles.js +2 -0
  24. package/lib/commonjs/expo-config-plugin/ios/withIosFrameworkFiles.js.map +1 -0
  25. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js +2 -0
  26. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js.map +1 -0
  27. package/lib/commonjs/expo-config-plugin/logging.js +2 -0
  28. package/lib/commonjs/expo-config-plugin/logging.js.map +1 -0
  29. package/lib/commonjs/expo-config-plugin/template/android/AndroidManifest.xml +4 -0
  30. package/lib/commonjs/expo-config-plugin/template/android/ReactNativeHostManager.kt +54 -0
  31. package/lib/commonjs/expo-config-plugin/template/android/build.gradle.kts +90 -0
  32. package/lib/commonjs/expo-config-plugin/template/android/consumer-rules.pro +0 -0
  33. package/lib/commonjs/expo-config-plugin/template/android/gradle.properties +8 -0
  34. package/lib/commonjs/expo-config-plugin/template/android/proguard-rules.pro +21 -0
  35. package/lib/commonjs/expo-config-plugin/template/engine.js +2 -0
  36. package/lib/commonjs/expo-config-plugin/template/engine.js.map +1 -0
  37. package/lib/commonjs/expo-config-plugin/template/ios/FrameworkInterface.swift +8 -0
  38. package/lib/commonjs/expo-config-plugin/template/ios/Info.plist +22 -0
  39. package/lib/commonjs/expo-config-plugin/template/ios/PodfileTargetBlock.rb +4 -0
  40. package/lib/commonjs/expo-config-plugin/template/ios/ReactNativeHostManager.swift +63 -0
  41. package/lib/commonjs/expo-config-plugin/template/ios/patchExpoPre55.sh +20 -0
  42. package/lib/commonjs/expo-config-plugin/types/BrownfieldPluginConfig.js +2 -0
  43. package/lib/commonjs/expo-config-plugin/types/BrownfieldPluginConfig.js.map +1 -0
  44. package/lib/commonjs/expo-config-plugin/types/RenderedTemplateFile.js +2 -0
  45. package/lib/commonjs/expo-config-plugin/types/RenderedTemplateFile.js.map +1 -0
  46. package/lib/commonjs/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.js +2 -0
  47. package/lib/commonjs/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.js.map +1 -0
  48. package/lib/commonjs/expo-config-plugin/types/index.js +2 -0
  49. package/lib/commonjs/expo-config-plugin/types/index.js.map +1 -0
  50. package/lib/commonjs/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.js +2 -0
  51. package/lib/commonjs/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.js.map +1 -0
  52. package/lib/commonjs/expo-config-plugin/withBrownfield.js +2 -0
  53. package/lib/commonjs/expo-config-plugin/withBrownfield.js.map +1 -0
  54. package/lib/module/expo-config-plugin/android/constants.js +2 -0
  55. package/lib/module/expo-config-plugin/android/constants.js.map +1 -0
  56. package/lib/module/expo-config-plugin/android/gradleHelpers.js +2 -0
  57. package/lib/module/expo-config-plugin/android/gradleHelpers.js.map +1 -0
  58. package/lib/module/expo-config-plugin/android/index.js +2 -0
  59. package/lib/module/expo-config-plugin/android/index.js.map +1 -0
  60. package/lib/module/expo-config-plugin/android/withAndroidModuleFiles.js +2 -0
  61. package/lib/module/expo-config-plugin/android/withAndroidModuleFiles.js.map +1 -0
  62. package/lib/module/expo-config-plugin/android/withBrownfieldAndroid.js +2 -0
  63. package/lib/module/expo-config-plugin/android/withBrownfieldAndroid.js.map +1 -0
  64. package/lib/module/expo-config-plugin/app.plugin.js +2 -0
  65. package/lib/module/expo-config-plugin/app.plugin.js.map +1 -0
  66. package/lib/module/expo-config-plugin/errors/SourceModificationError.js +2 -0
  67. package/lib/module/expo-config-plugin/errors/SourceModificationError.js.map +1 -0
  68. package/lib/module/expo-config-plugin/index.js +2 -0
  69. package/lib/module/expo-config-plugin/index.js.map +1 -0
  70. package/lib/module/expo-config-plugin/ios/index.js +2 -0
  71. package/lib/module/expo-config-plugin/ios/index.js.map +1 -0
  72. package/lib/module/expo-config-plugin/ios/podfileHelpers.js +31 -0
  73. package/lib/module/expo-config-plugin/ios/podfileHelpers.js.map +1 -0
  74. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js +2 -0
  75. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -0
  76. package/lib/module/expo-config-plugin/ios/withIosFrameworkFiles.js +2 -0
  77. package/lib/module/expo-config-plugin/ios/withIosFrameworkFiles.js.map +1 -0
  78. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js +2 -0
  79. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js.map +1 -0
  80. package/lib/module/expo-config-plugin/logging.js +2 -0
  81. package/lib/module/expo-config-plugin/logging.js.map +1 -0
  82. package/lib/module/expo-config-plugin/template/android/AndroidManifest.xml +4 -0
  83. package/lib/module/expo-config-plugin/template/android/ReactNativeHostManager.kt +54 -0
  84. package/lib/module/expo-config-plugin/template/android/build.gradle.kts +90 -0
  85. package/lib/module/expo-config-plugin/template/android/consumer-rules.pro +0 -0
  86. package/lib/module/expo-config-plugin/template/android/gradle.properties +8 -0
  87. package/lib/module/expo-config-plugin/template/android/proguard-rules.pro +21 -0
  88. package/lib/module/expo-config-plugin/template/engine.js +2 -0
  89. package/lib/module/expo-config-plugin/template/engine.js.map +1 -0
  90. package/lib/module/expo-config-plugin/template/ios/FrameworkInterface.swift +8 -0
  91. package/lib/module/expo-config-plugin/template/ios/Info.plist +22 -0
  92. package/lib/module/expo-config-plugin/template/ios/PodfileTargetBlock.rb +4 -0
  93. package/lib/module/expo-config-plugin/template/ios/ReactNativeHostManager.swift +63 -0
  94. package/lib/module/expo-config-plugin/template/ios/patchExpoPre55.sh +20 -0
  95. package/lib/module/expo-config-plugin/types/BrownfieldPluginConfig.js +2 -0
  96. package/lib/module/expo-config-plugin/types/BrownfieldPluginConfig.js.map +1 -0
  97. package/lib/module/expo-config-plugin/types/RenderedTemplateFile.js +2 -0
  98. package/lib/module/expo-config-plugin/types/RenderedTemplateFile.js.map +1 -0
  99. package/lib/module/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.js +2 -0
  100. package/lib/module/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.js.map +1 -0
  101. package/lib/module/expo-config-plugin/types/index.js +2 -0
  102. package/lib/module/expo-config-plugin/types/index.js.map +1 -0
  103. package/lib/module/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.js +2 -0
  104. package/lib/module/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.js.map +1 -0
  105. package/lib/module/expo-config-plugin/withBrownfield.js +2 -0
  106. package/lib/module/expo-config-plugin/withBrownfield.js.map +1 -0
  107. package/lib/typescript/commonjs/src/expo-config-plugin/android/constants.d.ts +3 -0
  108. package/lib/typescript/commonjs/src/expo-config-plugin/android/constants.d.ts.map +1 -0
  109. package/lib/typescript/commonjs/src/expo-config-plugin/android/gradleHelpers.d.ts +14 -0
  110. package/lib/typescript/commonjs/src/expo-config-plugin/android/gradleHelpers.d.ts.map +1 -0
  111. package/lib/typescript/commonjs/src/expo-config-plugin/android/index.d.ts +4 -0
  112. package/lib/typescript/commonjs/src/expo-config-plugin/android/index.d.ts.map +1 -0
  113. package/lib/typescript/commonjs/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts +24 -0
  114. package/lib/typescript/commonjs/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts.map +1 -0
  115. package/lib/typescript/commonjs/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts +13 -0
  116. package/lib/typescript/commonjs/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts.map +1 -0
  117. package/lib/typescript/commonjs/src/expo-config-plugin/app.plugin.d.ts +9 -0
  118. package/lib/typescript/commonjs/src/expo-config-plugin/app.plugin.d.ts.map +1 -0
  119. package/lib/typescript/commonjs/src/expo-config-plugin/errors/SourceModificationError.d.ts +3 -0
  120. package/lib/typescript/commonjs/src/expo-config-plugin/errors/SourceModificationError.d.ts.map +1 -0
  121. package/lib/typescript/commonjs/src/expo-config-plugin/index.d.ts +7 -0
  122. package/lib/typescript/commonjs/src/expo-config-plugin/index.d.ts.map +1 -0
  123. package/lib/typescript/commonjs/src/expo-config-plugin/ios/index.d.ts +5 -0
  124. package/lib/typescript/commonjs/src/expo-config-plugin/ios/index.d.ts.map +1 -0
  125. package/lib/typescript/commonjs/src/expo-config-plugin/ios/podfileHelpers.d.ts +8 -0
  126. package/lib/typescript/commonjs/src/expo-config-plugin/ios/podfileHelpers.d.ts.map +1 -0
  127. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withBrownfieldIos.d.ts +14 -0
  128. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -0
  129. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts +19 -0
  130. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts.map +1 -0
  131. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts +33 -0
  132. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -0
  133. package/lib/typescript/commonjs/src/expo-config-plugin/logging.d.ts +9 -0
  134. package/lib/typescript/commonjs/src/expo-config-plugin/logging.d.ts.map +1 -0
  135. package/lib/typescript/commonjs/src/expo-config-plugin/template/engine.d.ts +9 -0
  136. package/lib/typescript/commonjs/src/expo-config-plugin/template/engine.d.ts.map +1 -0
  137. package/lib/typescript/commonjs/src/expo-config-plugin/types/BrownfieldPluginConfig.d.ts +53 -0
  138. package/lib/typescript/commonjs/src/expo-config-plugin/types/BrownfieldPluginConfig.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/src/expo-config-plugin/types/RenderedTemplateFile.d.ts +5 -0
  140. package/lib/typescript/commonjs/src/expo-config-plugin/types/RenderedTemplateFile.d.ts.map +1 -0
  141. package/lib/typescript/commonjs/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts +50 -0
  142. package/lib/typescript/commonjs/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts.map +1 -0
  143. package/lib/typescript/commonjs/src/expo-config-plugin/types/index.d.ts +5 -0
  144. package/lib/typescript/commonjs/src/expo-config-plugin/types/index.d.ts.map +1 -0
  145. package/lib/typescript/commonjs/src/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.d.ts +36 -0
  146. package/lib/typescript/commonjs/src/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.d.ts.map +1 -0
  147. package/lib/typescript/commonjs/src/expo-config-plugin/withBrownfield.d.ts +5 -0
  148. package/lib/typescript/commonjs/src/expo-config-plugin/withBrownfield.d.ts.map +1 -0
  149. package/lib/typescript/module/src/expo-config-plugin/android/constants.d.ts +3 -0
  150. package/lib/typescript/module/src/expo-config-plugin/android/constants.d.ts.map +1 -0
  151. package/lib/typescript/module/src/expo-config-plugin/android/gradleHelpers.d.ts +14 -0
  152. package/lib/typescript/module/src/expo-config-plugin/android/gradleHelpers.d.ts.map +1 -0
  153. package/lib/typescript/module/src/expo-config-plugin/android/index.d.ts +4 -0
  154. package/lib/typescript/module/src/expo-config-plugin/android/index.d.ts.map +1 -0
  155. package/lib/typescript/module/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts +24 -0
  156. package/lib/typescript/module/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts.map +1 -0
  157. package/lib/typescript/module/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts +13 -0
  158. package/lib/typescript/module/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts.map +1 -0
  159. package/lib/typescript/module/src/expo-config-plugin/app.plugin.d.ts +9 -0
  160. package/lib/typescript/module/src/expo-config-plugin/app.plugin.d.ts.map +1 -0
  161. package/lib/typescript/module/src/expo-config-plugin/errors/SourceModificationError.d.ts +3 -0
  162. package/lib/typescript/module/src/expo-config-plugin/errors/SourceModificationError.d.ts.map +1 -0
  163. package/lib/typescript/module/src/expo-config-plugin/index.d.ts +7 -0
  164. package/lib/typescript/module/src/expo-config-plugin/index.d.ts.map +1 -0
  165. package/lib/typescript/module/src/expo-config-plugin/ios/index.d.ts +5 -0
  166. package/lib/typescript/module/src/expo-config-plugin/ios/index.d.ts.map +1 -0
  167. package/lib/typescript/module/src/expo-config-plugin/ios/podfileHelpers.d.ts +8 -0
  168. package/lib/typescript/module/src/expo-config-plugin/ios/podfileHelpers.d.ts.map +1 -0
  169. package/lib/typescript/module/src/expo-config-plugin/ios/withBrownfieldIos.d.ts +14 -0
  170. package/lib/typescript/module/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -0
  171. package/lib/typescript/module/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts +19 -0
  172. package/lib/typescript/module/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts.map +1 -0
  173. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts +33 -0
  174. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -0
  175. package/lib/typescript/module/src/expo-config-plugin/logging.d.ts +9 -0
  176. package/lib/typescript/module/src/expo-config-plugin/logging.d.ts.map +1 -0
  177. package/lib/typescript/module/src/expo-config-plugin/template/engine.d.ts +9 -0
  178. package/lib/typescript/module/src/expo-config-plugin/template/engine.d.ts.map +1 -0
  179. package/lib/typescript/module/src/expo-config-plugin/types/BrownfieldPluginConfig.d.ts +53 -0
  180. package/lib/typescript/module/src/expo-config-plugin/types/BrownfieldPluginConfig.d.ts.map +1 -0
  181. package/lib/typescript/module/src/expo-config-plugin/types/RenderedTemplateFile.d.ts +5 -0
  182. package/lib/typescript/module/src/expo-config-plugin/types/RenderedTemplateFile.d.ts.map +1 -0
  183. package/lib/typescript/module/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts +50 -0
  184. package/lib/typescript/module/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts.map +1 -0
  185. package/lib/typescript/module/src/expo-config-plugin/types/index.d.ts +5 -0
  186. package/lib/typescript/module/src/expo-config-plugin/types/index.d.ts.map +1 -0
  187. package/lib/typescript/module/src/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.d.ts +36 -0
  188. package/lib/typescript/module/src/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.d.ts.map +1 -0
  189. package/lib/typescript/module/src/expo-config-plugin/withBrownfield.d.ts +5 -0
  190. package/lib/typescript/module/src/expo-config-plugin/withBrownfield.d.ts.map +1 -0
  191. package/package.json +15 -3
  192. package/src/expo-config-plugin/android/constants.ts +2 -0
  193. package/src/expo-config-plugin/android/gradleHelpers.ts +72 -0
  194. package/src/expo-config-plugin/android/index.ts +6 -0
  195. package/src/expo-config-plugin/android/withAndroidModuleFiles.ts +139 -0
  196. package/src/expo-config-plugin/android/withBrownfieldAndroid.ts +48 -0
  197. package/src/expo-config-plugin/app.plugin.ts +10 -0
  198. package/src/expo-config-plugin/errors/SourceModificationError.ts +1 -0
  199. package/src/expo-config-plugin/index.ts +8 -0
  200. package/src/expo-config-plugin/ios/index.ts +7 -0
  201. package/src/expo-config-plugin/ios/podfileHelpers.ts +104 -0
  202. package/src/expo-config-plugin/ios/withBrownfieldIos.ts +95 -0
  203. package/src/expo-config-plugin/ios/withIosFrameworkFiles.ts +95 -0
  204. package/src/expo-config-plugin/ios/xcodeHelpers.ts +359 -0
  205. package/src/expo-config-plugin/logging.ts +29 -0
  206. package/src/expo-config-plugin/template/android/AndroidManifest.xml +4 -0
  207. package/src/expo-config-plugin/template/android/ReactNativeHostManager.kt +54 -0
  208. package/src/expo-config-plugin/template/android/build.gradle.kts +90 -0
  209. package/src/expo-config-plugin/template/android/consumer-rules.pro +0 -0
  210. package/src/expo-config-plugin/template/android/gradle.properties +8 -0
  211. package/src/expo-config-plugin/template/android/proguard-rules.pro +21 -0
  212. package/src/expo-config-plugin/template/engine.ts +26 -0
  213. package/src/expo-config-plugin/template/ios/FrameworkInterface.swift +8 -0
  214. package/src/expo-config-plugin/template/ios/Info.plist +22 -0
  215. package/src/expo-config-plugin/template/ios/PodfileTargetBlock.rb +4 -0
  216. package/src/expo-config-plugin/template/ios/ReactNativeHostManager.swift +63 -0
  217. package/src/expo-config-plugin/template/ios/patchExpoPre55.sh +20 -0
  218. package/src/expo-config-plugin/types/BrownfieldPluginConfig.ts +67 -0
  219. package/src/expo-config-plugin/types/RenderedTemplateFile.ts +4 -0
  220. package/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.ts +58 -0
  221. package/src/expo-config-plugin/types/index.ts +6 -0
  222. package/src/expo-config-plugin/types/ios/BrownfieldPluginIosConfig.ts +41 -0
  223. package/src/expo-config-plugin/withBrownfield.ts +112 -0
@@ -0,0 +1,139 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+
4
+ import { withDangerousMod, type ConfigPlugin } from '@expo/config-plugins';
5
+
6
+ import type {
7
+ RenderedTemplateFile,
8
+ ResolvedBrownfieldPluginConfigWithAndroid,
9
+ } from '../types';
10
+ import { Logger } from '../logging';
11
+ import { renderTemplate } from '../template/engine';
12
+
13
+ /**
14
+ * Creates the Android library module directory structure and files
15
+ */
16
+ export function createAndroidModule({
17
+ androidDir,
18
+ config,
19
+ rnVersion,
20
+ }: {
21
+ /**
22
+ * The root Android directory path
23
+ */
24
+ androidDir: string;
25
+
26
+ /**
27
+ * The resolved RN version
28
+ */
29
+ rnVersion: string;
30
+
31
+ /**
32
+ * The resolved Brownfield plugin configuration
33
+ */
34
+ config: ResolvedBrownfieldPluginConfigWithAndroid;
35
+ }): void {
36
+ const { android } = config;
37
+ const moduleDir = path.join(androidDir, android.moduleName);
38
+
39
+ Logger.logDebug(`Creating Android module in: ${androidDir}`);
40
+
41
+ // generate module files
42
+ const files: RenderedTemplateFile[] = [
43
+ {
44
+ relativePath: 'build.gradle.kts',
45
+ content: renderTemplate('android', 'build.gradle.kts', {
46
+ '{{PACKAGE_NAME}}': android.packageName,
47
+ '{{MIN_SDK_VERSION}}': android.minSdkVersion.toString(),
48
+ '{{COMPILE_SDK_VERSION}}': android.compileSdkVersion.toString(),
49
+ '{{GROUP_ID}}': android.groupId,
50
+ '{{ARTIFACT_ID}}': android.artifactId,
51
+ '{{ARTIFACT_VERSION}}': android.version,
52
+ '{{RN_VERSION}}': rnVersion,
53
+ }),
54
+ },
55
+ {
56
+ relativePath: 'gradle.properties',
57
+ content: renderTemplate('android', 'gradle.properties', {}),
58
+ },
59
+ {
60
+ relativePath: 'src/main/AndroidManifest.xml',
61
+ content: renderTemplate('android', 'AndroidManifest.xml', {}),
62
+ },
63
+ {
64
+ relativePath: `src/main/java/${config.android.packageName.replace(/\./g, '/')}/ReactNativeHostManager.kt`,
65
+ content: renderTemplate('android', 'ReactNativeHostManager.kt', {
66
+ '{{PACKAGE_NAME}}': android.packageName,
67
+ }),
68
+ },
69
+ {
70
+ relativePath: 'consumer-rules.pro',
71
+ content: renderTemplate('android', 'consumer-rules.pro', {}),
72
+ },
73
+ {
74
+ relativePath: 'proguard-rules.pro',
75
+ content: renderTemplate('android', 'proguard-rules.pro', {}),
76
+ },
77
+ ];
78
+
79
+ // write files, possibly creating directories
80
+ for (const file of files) {
81
+ const filePath = path.join(moduleDir, file.relativePath);
82
+ const fileDir = path.dirname(filePath);
83
+
84
+ // create directory if it doesn't exist
85
+ if (!fs.existsSync(fileDir)) {
86
+ fs.mkdirSync(fileDir, { recursive: true });
87
+ }
88
+
89
+ fs.writeFileSync(filePath, file.content, 'utf8');
90
+
91
+ Logger.logDebug(`Created file: ${filePath}`);
92
+ }
93
+
94
+ Logger.logDebug(
95
+ `Android module "${android.moduleName}" created at ${moduleDir}`
96
+ );
97
+ }
98
+
99
+ /**
100
+ * Dangerous mod that creates the Android module directory and files
101
+ */
102
+ export const withAndroidModuleFiles: ConfigPlugin<
103
+ ResolvedBrownfieldPluginConfigWithAndroid
104
+ > = (config, props) => {
105
+ return withDangerousMod(config, [
106
+ 'android',
107
+ async (dangerousConfig) => {
108
+ const androidDir = path.join(
109
+ dangerousConfig.modRequest.projectRoot,
110
+ 'android'
111
+ );
112
+
113
+ let rnVersion: string;
114
+ try {
115
+ const rnPkgPath = require.resolve('react-native/package.json', {
116
+ paths: [dangerousConfig.modRequest.projectRoot],
117
+ });
118
+
119
+ const rnPkg = require(rnPkgPath);
120
+
121
+ rnVersion = rnPkg.version;
122
+
123
+ Logger.logDebug(`Resolved react-native version: ${rnVersion}`);
124
+ } catch {
125
+ throw new Error(
126
+ 'Could not resolve react-native package version. Please ensure you have installed dependencies.'
127
+ );
128
+ }
129
+
130
+ createAndroidModule({
131
+ androidDir,
132
+ config: props,
133
+ rnVersion,
134
+ });
135
+
136
+ return dangerousConfig;
137
+ },
138
+ ]);
139
+ };
@@ -0,0 +1,48 @@
1
+ import {
2
+ withProjectBuildGradle,
3
+ withSettingsGradle,
4
+ type ConfigPlugin,
5
+ } from '@expo/config-plugins';
6
+
7
+ import { modifyRootBuildGradle, modifySettingsGradle } from './gradleHelpers';
8
+ import { withAndroidModuleFiles } from './withAndroidModuleFiles';
9
+ import type { ResolvedBrownfieldPluginConfigWithAndroid } from '../types';
10
+
11
+ /**
12
+ * Android Config Plugin for integration with @callstack/react-native-brownfield.
13
+ *
14
+ * This plugin:
15
+ * 1. Creates a new Android Library module for the Brownfield AAR
16
+ * 3. Modifies settings.gradle to include the new module
17
+ * 4. Modifies root build.gradle to add Brownfield Gradle plugin
18
+ * 5. Generates the ReactNativeHostManager class inside the module
19
+ */
20
+ export const withBrownfieldAndroid: ConfigPlugin<
21
+ ResolvedBrownfieldPluginConfigWithAndroid
22
+ > = (config, props) => {
23
+ const androidConfig = props.android;
24
+
25
+ // Step 1: modify root build.gradle to add Brownfield Gradle plugin dependency
26
+ config = withProjectBuildGradle(config, (gradleConfig) => {
27
+ gradleConfig.modResults.contents = modifyRootBuildGradle(
28
+ gradleConfig.modResults.contents
29
+ );
30
+
31
+ return gradleConfig;
32
+ });
33
+
34
+ // Step 2: modify settings.gradle to include the new module
35
+ config = withSettingsGradle(config, (settingsConfig) => {
36
+ settingsConfig.modResults.contents = modifySettingsGradle(
37
+ settingsConfig.modResults.contents,
38
+ androidConfig.moduleName
39
+ );
40
+
41
+ return settingsConfig;
42
+ });
43
+
44
+ // Step 3: create the Android module files using dangerous mod
45
+ config = withAndroidModuleFiles(config, props);
46
+
47
+ return config;
48
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Expo config plugin entry point
3
+ *
4
+ * This file is the entry point for the Expo config plugin.
5
+ * It's referenced in the package.json under "./app.plugin" export.
6
+ */
7
+
8
+ import withBrownfield from './withBrownfield';
9
+
10
+ export default withBrownfield;
@@ -0,0 +1 @@
1
+ export class SourceModificationError extends Error {}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Expo Config Plugin for integration with @callstack/react-native-brownfield.
3
+ * This plugin configures your Expo project to be packaged as an AAR (Android) or XCFramework (iOS).
4
+ */
5
+
6
+ import withBrownfield from './withBrownfield';
7
+
8
+ export default withBrownfield;
@@ -0,0 +1,7 @@
1
+ export { withBrownfieldIos } from './withBrownfieldIos';
2
+ export {
3
+ withIosFrameworkFiles,
4
+ createIosFramework,
5
+ } from './withIosFrameworkFiles';
6
+ export { addFrameworkTarget } from './xcodeHelpers';
7
+ export { modifyPodfile } from './podfileHelpers';
@@ -0,0 +1,104 @@
1
+ import { SourceModificationError } from '../errors/SourceModificationError';
2
+ import { Logger } from '../logging';
3
+ import { renderTemplate } from '../template/engine';
4
+
5
+ const BROWNFIELD_POD_HOOK_MARKER_START =
6
+ '# >>> react-native-brownfield expo phase ordering >>>';
7
+ const BROWNFIELD_POD_HOOK_MARKER_END =
8
+ '# <<< react-native-brownfield expo phase ordering <<<';
9
+
10
+ function ensureExpoPhaseOrderingHook(podfile: string): string {
11
+ if (podfile.includes(BROWNFIELD_POD_HOOK_MARKER_START)) {
12
+ return podfile;
13
+ }
14
+
15
+ const hook = `
16
+ ${BROWNFIELD_POD_HOOK_MARKER_START}
17
+ def reorder_brownfield_expo_patch_phase!(installer)
18
+ projects = installer.aggregate_targets.map(&:user_project).compact.uniq
19
+ projects.each do |project|
20
+ modified = false
21
+
22
+ project.native_targets.each do |target|
23
+ phases = target.build_phases
24
+ expo_idx = phases.index { |p| p.respond_to?(:name) && p.name == '[Expo] Configure project' }
25
+ patch_idx = phases.index { |p| p.respond_to?(:name) && p.name == 'Patch ExpoModulesProvider' }
26
+
27
+ next if expo_idx.nil? || patch_idx.nil?
28
+ next if patch_idx > expo_idx
29
+
30
+ patch = phases.delete_at(patch_idx)
31
+ expo_idx = phases.index { |p| p.respond_to?(:name) && p.name == '[Expo] Configure project' }
32
+ phases.insert(expo_idx + 1, patch)
33
+ modified = true
34
+ end
35
+
36
+ project.save if modified
37
+ end
38
+ end
39
+
40
+ post_integrate do |installer|
41
+ reorder_brownfield_expo_patch_phase!(installer)
42
+ end
43
+ ${BROWNFIELD_POD_HOOK_MARKER_END}
44
+ `;
45
+
46
+ return `${podfile.trimEnd()}\n\n${hook}\n`;
47
+ }
48
+
49
+ /**
50
+ * Modifies the Podfile to include the Brownfield framework target
51
+ * @param podfile The original Podfile content
52
+ * @param frameworkName The name of the framework target to add
53
+ * @returns The modified Podfile content
54
+ */
55
+ export function modifyPodfile(
56
+ podfile: string,
57
+ frameworkName: string,
58
+ isExpoPre55: boolean
59
+ ): string {
60
+ // check if the framework target is already included
61
+ if (podfile.includes(`target '${frameworkName}'`)) {
62
+ Logger.logDebug(
63
+ `Framework target "${frameworkName}" already in Podfile, skipping modification`
64
+ );
65
+ return podfile;
66
+ }
67
+
68
+ Logger.logDebug(`Modifying Podfile for framework: ${frameworkName}`);
69
+
70
+ // insert the framework target after the main target's "do"
71
+ const frameworkTargetBlock = renderTemplate('ios', 'PodfileTargetBlock.rb', {
72
+ '{{FRAMEWORK_NAME}}': frameworkName,
73
+ });
74
+
75
+ // find insertion point after the first target's content begins, before the end of the target block
76
+ const mainTargetMatch = podfile.match(
77
+ /(target\s+['"][^'"]+['"]\s+do\s*\n)([\s\S]*?)(^end\s*$)/m
78
+ );
79
+
80
+ if (!mainTargetMatch) {
81
+ throw new SourceModificationError(
82
+ 'Could not find main target in Podfile. Please manually add the framework target.'
83
+ );
84
+ }
85
+
86
+ const [, targetStart, targetContent] = mainTargetMatch;
87
+ const insertIndex =
88
+ podfile.indexOf(mainTargetMatch[0]) +
89
+ targetStart.length +
90
+ targetContent.length;
91
+
92
+ let modifiedPodfile =
93
+ podfile.slice(0, insertIndex) +
94
+ frameworkTargetBlock +
95
+ podfile.slice(insertIndex);
96
+
97
+ Logger.logDebug(`Added framework target "${frameworkName}" to Podfile`);
98
+
99
+ if (isExpoPre55) {
100
+ modifiedPodfile = ensureExpoPhaseOrderingHook(modifiedPodfile);
101
+ }
102
+
103
+ return modifiedPodfile;
104
+ }
@@ -0,0 +1,95 @@
1
+ import {
2
+ withXcodeProject,
3
+ withPodfile,
4
+ type ConfigPlugin,
5
+ } from '@expo/config-plugins';
6
+
7
+ import {
8
+ addExpoPre55ShellPatchScriptPhase,
9
+ addFrameworkTarget,
10
+ addSourceFilesBuildPhase,
11
+ copyBundleReactNativePhase,
12
+ } from './xcodeHelpers';
13
+ import { modifyPodfile } from './podfileHelpers';
14
+ import { withIosFrameworkFiles } from './withIosFrameworkFiles';
15
+ import type { ResolvedBrownfieldPluginConfigWithIos } from '../types';
16
+ import { Logger } from '../logging';
17
+
18
+ /**
19
+ * iOS Config Plugin for integration with @callstack/react-native-brownfield.
20
+ *
21
+ * This plugin:
22
+ * 1. Creates a new Framework target in the Xcode project
23
+ * 2. Configures the Podfile to include the framework target
24
+ * 3. Adds necessary build configuration
25
+ * 4. Adds script phase to patch `ExpoModulesProvider.swift`
26
+ * 5. Adds the "Bundle React Native code and images" phase of Expo app target to the framework target
27
+ */
28
+ export const withBrownfieldIos: ConfigPlugin<
29
+ ResolvedBrownfieldPluginConfigWithIos
30
+ > = (config, props) => {
31
+ const expoMajor = config.sdkVersion
32
+ ? parseInt(config.sdkVersion.split('.')[0], 10)
33
+ : -1;
34
+ const isExpoPre55 = expoMajor < 55;
35
+
36
+ // Step 1: modify the Xcode project to add framework target &
37
+ config = withXcodeProject(config, (xcodeConfig) => {
38
+ const { modResults: project, modRequest } = xcodeConfig;
39
+
40
+ const { frameworkTargetUUID, targetAlreadyExists } = addFrameworkTarget(
41
+ project,
42
+ modRequest,
43
+ props.ios
44
+ );
45
+
46
+ if (targetAlreadyExists) {
47
+ Logger.logDebug(
48
+ `Skipping further Xcode modifications as framework target was already present`
49
+ );
50
+
51
+ return xcodeConfig;
52
+ }
53
+
54
+ // copy the "Bundle React Native code and images" build phase from the main target to the framework target
55
+ copyBundleReactNativePhase(project, frameworkTargetUUID);
56
+
57
+ // for Expo SDK versions < 55, add a script phase to patch ExpoModulesProvider.swift
58
+ if (isExpoPre55) {
59
+ Logger.logDebug(
60
+ `Adding ExpoModulesProvider patch phase for Expo SDK ${config.sdkVersion}`
61
+ );
62
+
63
+ addExpoPre55ShellPatchScriptPhase(project, {
64
+ frameworkName: props.ios.frameworkName,
65
+ frameworkTargetUUID: frameworkTargetUUID,
66
+ });
67
+ } else {
68
+ Logger.logDebug(
69
+ `Skipping ExpoModulesProvider patch phase for Expo SDK ${config.sdkVersion}`
70
+ );
71
+ }
72
+
73
+ addSourceFilesBuildPhase(project, frameworkTargetUUID, props.ios);
74
+
75
+ return xcodeConfig;
76
+ });
77
+
78
+ // Step 2: modify Podfile to include the framework target
79
+ config = withPodfile(config, (podfileConfig) => {
80
+ const { frameworkName } = props.ios;
81
+
82
+ podfileConfig.modResults.contents = modifyPodfile(
83
+ podfileConfig.modResults.contents,
84
+ frameworkName,
85
+ isExpoPre55
86
+ );
87
+
88
+ return podfileConfig;
89
+ });
90
+
91
+ // Step 3: create the iOS framework files using dangerous mod
92
+ config = withIosFrameworkFiles(config, props);
93
+
94
+ return config;
95
+ };
@@ -0,0 +1,95 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+
4
+ import { withDangerousMod, type ConfigPlugin } from '@expo/config-plugins';
5
+
6
+ import type {
7
+ RenderedTemplateFile,
8
+ ResolvedBrownfieldPluginConfigWithIos,
9
+ } from '../types';
10
+ import { Logger } from '../logging';
11
+ import { renderTemplate } from '../template/engine';
12
+
13
+ /**
14
+ * Returns rendered source files for the iOS framework
15
+ * @param ios The iOS Brownfield plugin configuration
16
+ * @returns The list of framework source files
17
+ */
18
+ export function getFrameworkSourceFiles(
19
+ ios: ResolvedBrownfieldPluginConfigWithIos['ios']
20
+ ): RenderedTemplateFile[] {
21
+ return [
22
+ {
23
+ relativePath: `${ios.frameworkName}.swift`,
24
+ content: renderTemplate('ios', 'FrameworkInterface.swift', {}),
25
+ },
26
+ {
27
+ relativePath: 'Info.plist',
28
+ content: renderTemplate('ios', 'Info.plist', {
29
+ '{{BUNDLE_IDENTIFIER}}': ios.bundleIdentifier,
30
+ }),
31
+ },
32
+ {
33
+ relativePath: 'ReactNativeHostManager.swift',
34
+ content: renderTemplate('ios', 'ReactNativeHostManager.swift', {}),
35
+ },
36
+ ];
37
+ }
38
+
39
+ /**
40
+ * Creates the iOS framework directory structure and files
41
+ * @param iosDir The root iOS directory path
42
+ * @param config The resolved Brownfield plugin configuration
43
+ */
44
+ export function createIosFramework(
45
+ iosDir: string,
46
+ config: ResolvedBrownfieldPluginConfigWithIos
47
+ ) {
48
+ const { ios } = config;
49
+ const frameworkDir = path.join(iosDir, ios.frameworkName);
50
+
51
+ // check if framework directory if it exists
52
+ if (fs.existsSync(frameworkDir)) {
53
+ Logger.logDebug(`Framework directory already exists: ${frameworkDir}`);
54
+
55
+ return;
56
+ }
57
+
58
+ Logger.logDebug(`Creating iOS framework in: ${frameworkDir}`);
59
+
60
+ // create framework directory
61
+ if (!fs.existsSync(frameworkDir)) {
62
+ fs.mkdirSync(frameworkDir, { recursive: true });
63
+
64
+ Logger.logDebug(`Created directory: ${frameworkDir}`);
65
+ }
66
+
67
+ // write files
68
+ for (const file of getFrameworkSourceFiles(ios)) {
69
+ const filePath = path.join(frameworkDir, file.relativePath);
70
+
71
+ fs.writeFileSync(filePath, file.content, 'utf8');
72
+ }
73
+
74
+ Logger.logDebug(
75
+ `iOS framework "${ios.frameworkName}" files created at ${frameworkDir}`
76
+ );
77
+ }
78
+
79
+ /**
80
+ * Dangerous mod that creates the iOS framework directory and files
81
+ */
82
+ export const withIosFrameworkFiles: ConfigPlugin<
83
+ ResolvedBrownfieldPluginConfigWithIos
84
+ > = (config, props) => {
85
+ return withDangerousMod(config, [
86
+ 'ios',
87
+ async (dangerousConfig) => {
88
+ const iosDir = path.join(dangerousConfig.modRequest.projectRoot, 'ios');
89
+
90
+ createIosFramework(iosDir, props);
91
+
92
+ return dangerousConfig;
93
+ },
94
+ ]);
95
+ };