@callstack/react-native-brownfield 3.10.0 → 3.11.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 (47) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/ReactBrownfield.podspec +14 -1
  3. package/ios/BrownfieldDevLoadingViewBridge.h +11 -0
  4. package/ios/BrownfieldDevLoadingViewBridge.m +12 -0
  5. package/ios/Expo/ExpoHostRuntime.swift +64 -21
  6. package/ios/ReactNativeBrownfield.swift +14 -0
  7. package/ios/Vanilla/ReactNativeHostRuntime.swift +38 -12
  8. package/ios/swiftpm/Package.swift +27 -0
  9. package/ios/swiftpm/Sources/BrownfieldBundleSupport/BrownfieldBundleURLResolver.swift +28 -0
  10. package/ios/swiftpm/Tests/BrownfieldBundleSupportTests/BrownfieldBundleURLResolverTests.swift +156 -0
  11. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js +1 -1
  12. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -1
  13. package/lib/commonjs/expo-config-plugin/ios/withFmtFix.js +12 -0
  14. package/lib/commonjs/expo-config-plugin/ios/withFmtFix.js.map +1 -0
  15. package/lib/commonjs/expo-config-plugin/ios/withIosFrameworkFiles.js +1 -1
  16. package/lib/commonjs/expo-config-plugin/ios/withIosFrameworkFiles.js.map +1 -1
  17. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js +6 -1
  18. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js.map +1 -1
  19. package/lib/commonjs/expo-config-plugin/template/ios/FrameworkInterface.swift +4 -1
  20. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js +1 -1
  21. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -1
  22. package/lib/module/expo-config-plugin/ios/withFmtFix.js +12 -0
  23. package/lib/module/expo-config-plugin/ios/withFmtFix.js.map +1 -0
  24. package/lib/module/expo-config-plugin/ios/withIosFrameworkFiles.js +1 -1
  25. package/lib/module/expo-config-plugin/ios/withIosFrameworkFiles.js.map +1 -1
  26. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js +6 -1
  27. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js.map +1 -1
  28. package/lib/module/expo-config-plugin/template/ios/FrameworkInterface.swift +4 -1
  29. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -1
  30. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withFmtFix.d.ts +5 -0
  31. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withFmtFix.d.ts.map +1 -0
  32. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts +14 -0
  34. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -1
  35. package/lib/typescript/module/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -1
  36. package/lib/typescript/module/src/expo-config-plugin/ios/withFmtFix.d.ts +5 -0
  37. package/lib/typescript/module/src/expo-config-plugin/ios/withFmtFix.d.ts.map +1 -0
  38. package/lib/typescript/module/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts.map +1 -1
  39. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts +14 -0
  40. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -1
  41. package/package.json +2 -2
  42. package/src/expo-config-plugin/ios/withBrownfieldIos.ts +14 -2
  43. package/src/expo-config-plugin/ios/withFmtFix.ts +72 -0
  44. package/src/expo-config-plugin/ios/withIosFrameworkFiles.ts +10 -10
  45. package/src/expo-config-plugin/ios/xcodeHelpers.ts +130 -14
  46. package/src/expo-config-plugin/template/ios/FrameworkInterface.swift +4 -1
  47. /package/ios/{BrownfieldBundlePathResolver.swift → swiftpm/Sources/BrownfieldBundleSupport/BrownfieldBundlePathResolver.swift} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"xcodeHelpers.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/xcodeHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,YAAY,EAElB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAKlE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,iCAAiC,GACzC;IACD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAoIA;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,OAAO,EAAE,iCAAiC,QAkB3C;AAED,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC;AAE7E,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,wBAAwB,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,kCAAkC,EAAE,MAAM,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAOvE,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,qBAAqB,CAEvB;AAmJD,KAAK,0BAA0B,GAAG;IAChC,0BAA0B,EAAE,MAAM,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAgB,iDAAiD,CAC/D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,WAAW,EAAE,MAAM,EACnB,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,EAAE,0BAA0B,GAC3E,OAAO,CAwBT;AAoDD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,GACjB,IAAI,CAkDN;AA4DD,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,YAAY,EACrB,EACE,aAAa,EACb,mBAAmB,GACpB,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;CAC7B,QA2BF;AAED;;;;;;GAMG;AACH,wBAAgB,6CAA6C,CAC3D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,WAmC5B"}
1
+ {"version":3,"file":"xcodeHelpers.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/xcodeHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,YAAY,EAElB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAKlE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,iCAAiC,GACzC;IACD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAoIA;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,OAAO,EAAE,iCAAiC,QAkB3C;AAED,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC;AAE7E,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,wBAAwB,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,kCAAkC,EAAE,MAAM,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAOvE,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,qBAAqB,CAEvB;AAmJD,KAAK,0BAA0B,GAAG;IAChC,0BAA0B,EAAE,MAAM,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAgB,iDAAiD,CAC/D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,WAAW,EAAE,MAAM,EACnB,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,EAAE,0BAA0B,GAC3E,OAAO,CAwBT;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,EACE,aAAa,GACd,EAAE;IACD,sDAAsD;IACtD,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;CACpC,EACD,EACE,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,aAAa,EAAE,mBAAmB,GACnC,EAAE,iCAAiC,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CA8B3C;AAED,wBAAgB,qDAAqD,CACnE,WAAW,EAAE,MAAM,GAClB,MAAM,CAsBR;AAgCD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,GACjB,IAAI,CA+FN;AA4DD;;;GAGG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,YAAY,EACrB,EACE,aAAa,EACb,mBAAmB,GACpB,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;CAC7B,QAqCF;AAED;;;;;;GAMG;AACH,wBAAgB,6CAA6C,CAC3D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,WAmC5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"withBrownfieldIos.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/withBrownfieldIos.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAW9B,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,UAAU,CAAC;AAItE;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAC1C,qCAAqC,CA0EtC,CAAC"}
1
+ {"version":3,"file":"withBrownfieldIos.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/withBrownfieldIos.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAY9B,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,UAAU,CAAC;AAItE;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAC1C,qCAAqC,CAqFtC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type ConfigPlugin } from '@expo/config-plugins';
2
+ import type { ResolvedBrownfieldPluginConfigWithIos } from '../types';
3
+ export declare function injectFmtFixIntoPodfile(podfile: string): string;
4
+ export declare const withFmtFix: ConfigPlugin<ResolvedBrownfieldPluginConfigWithIos>;
5
+ //# sourceMappingURL=withFmtFix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withFmtFix.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/withFmtFix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEtE,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,UAAU,CAAC;AAiBtE,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAyC/D;AAED,eAAO,MAAM,UAAU,EAAE,YAAY,CAAC,qCAAqC,CASvE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"withIosFrameworkFiles.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/withIosFrameworkFiles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,KAAK,EACV,oBAAoB,EACpB,qCAAqC,EACtC,MAAM,UAAU,CAAC;AAIlB;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,qCAAqC,CAAC,KAAK,CAAC,GAChD,oBAAoB,EAAE,CAaxB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,qCAAqC,QA+B9C;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,YAAY,CAC9C,qCAAqC,CAYtC,CAAC"}
1
+ {"version":3,"file":"withIosFrameworkFiles.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/withIosFrameworkFiles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE3E,OAAO,KAAK,EACV,oBAAoB,EACpB,qCAAqC,EACtC,MAAM,UAAU,CAAC;AAIlB;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,qCAAqC,CAAC,KAAK,CAAC,GAChD,oBAAoB,EAAE,CAexB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,qCAAqC,QA6B9C;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,YAAY,CAC9C,qCAAqC,CAYtC,CAAC"}
@@ -39,6 +39,16 @@ type ResourcesBuildPhaseOptions = {
39
39
  buildFileComment: string;
40
40
  };
41
41
  export declare function ensureTargetHasFileReferenceInResourcesBuildPhase(project: XcodeProject, frameworkTargetUUID: string, fileRefUuid: string, { resourcesBuildPhaseComment, buildFileComment }: ResourcesBuildPhaseOptions): boolean;
42
+ /**
43
+ * Returns build settings for the framework target
44
+ * @param options The user configuration
45
+ * @returns Build settings object
46
+ */
47
+ export declare function getFrameworkBuildSettings({ configuration, }: {
48
+ /** Build configuration name ("Debug" or "Release") */
49
+ configuration: 'Debug' | 'Release';
50
+ }, { bundleIdentifier, deploymentTarget, frameworkName, frameworkVersion, buildSettings: customBuildSettings, }: ResolvedBrownfieldPluginIosConfig): Record<string, string | boolean | number>;
51
+ export declare function rewriteBundleReactNativePhaseScriptForFrameworkTarget(shellScript: string): string;
42
52
  /**
43
53
  * Finds the "Bundle React Native code and images" build phase from the main app target
44
54
  * and adds it to the framework target's build phases
@@ -46,6 +56,10 @@ export declare function ensureTargetHasFileReferenceInResourcesBuildPhase(projec
46
56
  * @param targetUuid The UUID of the framework target
47
57
  */
48
58
  export declare function copyBundleReactNativePhase(project: XcodeProject, targetUuid: string): void;
59
+ /**
60
+ * Adds the "Patch ExpoModulesProvider" shell script phase to the framework target.
61
+ * Safe to call on every prebuild: skips creation when the phase is already present.
62
+ */
49
63
  export declare function addExpoPre55ShellPatchScriptPhase(modRequest: ModProps<XcodeProject>, project: XcodeProject, { frameworkName, frameworkTargetUUID, }: {
50
64
  frameworkName: string;
51
65
  frameworkTargetUUID: string;
@@ -1 +1 @@
1
- {"version":3,"file":"xcodeHelpers.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/xcodeHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,YAAY,EAElB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAKlE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,iCAAiC,GACzC;IACD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAoIA;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,OAAO,EAAE,iCAAiC,QAkB3C;AAED,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC;AAE7E,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,wBAAwB,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,kCAAkC,EAAE,MAAM,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAOvE,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,qBAAqB,CAEvB;AAmJD,KAAK,0BAA0B,GAAG;IAChC,0BAA0B,EAAE,MAAM,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAgB,iDAAiD,CAC/D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,WAAW,EAAE,MAAM,EACnB,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,EAAE,0BAA0B,GAC3E,OAAO,CAwBT;AAoDD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,GACjB,IAAI,CAkDN;AA4DD,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,YAAY,EACrB,EACE,aAAa,EACb,mBAAmB,GACpB,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;CAC7B,QA2BF;AAED;;;;;;GAMG;AACH,wBAAgB,6CAA6C,CAC3D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,WAmC5B"}
1
+ {"version":3,"file":"xcodeHelpers.d.ts","sourceRoot":"","sources":["../../../../../../src/expo-config-plugin/ios/xcodeHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,YAAY,EAElB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAKlE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,iCAAiC,GACzC;IACD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAoIA;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,OAAO,EAAE,iCAAiC,QAkB3C;AAED,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC;AAE7E,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,wBAAwB,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,kCAAkC,EAAE,MAAM,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,cAAc,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAOvE,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,qBAAqB,CAEvB;AAmJD,KAAK,0BAA0B,GAAG;IAChC,0BAA0B,EAAE,MAAM,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAgB,iDAAiD,CAC/D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,EAC3B,WAAW,EAAE,MAAM,EACnB,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,EAAE,0BAA0B,GAC3E,OAAO,CAwBT;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,EACE,aAAa,GACd,EAAE;IACD,sDAAsD;IACtD,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;CACpC,EACD,EACE,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,aAAa,EAAE,mBAAmB,GACnC,EAAE,iCAAiC,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CA8B3C;AAED,wBAAgB,qDAAqD,CACnE,WAAW,EAAE,MAAM,GAClB,MAAM,CAsBR;AAgCD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,MAAM,GACjB,IAAI,CA+FN;AA4DD;;;GAGG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,EAClC,OAAO,EAAE,YAAY,EACrB,EACE,aAAa,EACb,mBAAmB,GACpB,EAAE;IACD,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;CAC7B,QAqCF;AAED;;;;;;GAMG;AACH,wBAAgB,6CAA6C,CAC3D,OAAO,EAAE,YAAY,EACrB,mBAAmB,EAAE,MAAM,WAmC5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@callstack/react-native-brownfield",
3
- "version": "3.10.0",
3
+ "version": "3.11.0",
4
4
  "license": "MIT",
5
5
  "author": "Michal Chudziak <mike.chudziak@callstack.com>",
6
6
  "bin": {
@@ -86,7 +86,7 @@
86
86
  "@expo/config-plugins": "^54.0.4"
87
87
  },
88
88
  "dependencies": {
89
- "@callstack/brownfield-cli": "^3.10.0"
89
+ "@callstack/brownfield-cli": "^3.11.0"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@babel/core": "^7.25.2",
@@ -11,6 +11,7 @@ import {
11
11
  copyBundleReactNativePhase,
12
12
  } from './xcodeHelpers';
13
13
  import { modifyPodfile } from './podfileHelpers';
14
+ import { injectFmtFixIntoPodfile } from './withFmtFix';
14
15
  import { ensureFrameworkHasExpoPlistResource } from './utils/expo-updates';
15
16
  import { withIosFrameworkFiles } from './withIosFrameworkFiles';
16
17
  import type { ResolvedBrownfieldPluginConfigWithIos } from '../types';
@@ -55,9 +56,18 @@ export const withBrownfieldIos: ConfigPlugin<
55
56
 
56
57
  if (targetAlreadyExists) {
57
58
  Logger.logDebug(
58
- `Skipping further Xcode modifications as framework target was already present`
59
+ `Framework target already present, syncing Brownfield build phases`
59
60
  );
60
61
 
62
+ copyBundleReactNativePhase(project, frameworkTargetUUID);
63
+
64
+ if (isExpoPre55) {
65
+ addExpoPre55ShellPatchScriptPhase(modRequest, project, {
66
+ frameworkName: props.ios.frameworkName,
67
+ frameworkTargetUUID: frameworkTargetUUID,
68
+ });
69
+ }
70
+
61
71
  return xcodeConfig;
62
72
  }
63
73
 
@@ -89,11 +99,13 @@ export const withBrownfieldIos: ConfigPlugin<
89
99
  config = withPodfile(config, (podfileConfig) => {
90
100
  const { frameworkName } = props.ios;
91
101
 
92
- podfileConfig.modResults.contents = modifyPodfile(
102
+ const modifiedPodfile = modifyPodfile(
93
103
  podfileConfig.modResults.contents,
94
104
  frameworkName,
95
105
  expoMajor
96
106
  );
107
+ podfileConfig.modResults.contents =
108
+ injectFmtFixIntoPodfile(modifiedPodfile);
97
109
 
98
110
  return podfileConfig;
99
111
  });
@@ -0,0 +1,72 @@
1
+ import { withPodfile, type ConfigPlugin } from '@expo/config-plugins';
2
+
3
+ import type { ResolvedBrownfieldPluginConfigWithIos } from '../types';
4
+
5
+ const FMT_FIX_MARKER =
6
+ '# Fix fmt 11.0.2 consteval compilation error with Xcode 26.4+';
7
+
8
+ const FMT_FIX_RUBY = `\
9
+ ${FMT_FIX_MARKER}
10
+ fmt_base = File.join(installer.sandbox.pod_dir('fmt'), 'include', 'fmt', 'base.h')
11
+ if File.exist?(fmt_base)
12
+ content = File.read(fmt_base)
13
+ patched = content.gsub(/^#\\s*define FMT_USE_CONSTEVAL 1$/, '# define FMT_USE_CONSTEVAL 0')
14
+ if patched != content
15
+ File.chmod(0644, fmt_base)
16
+ File.write(fmt_base, patched)
17
+ end
18
+ end`;
19
+
20
+ export function injectFmtFixIntoPodfile(podfile: string): string {
21
+ if (podfile.includes(FMT_FIX_MARKER)) {
22
+ return podfile;
23
+ }
24
+
25
+ const lines = podfile.split('\n');
26
+ const postInstallIndex = lines.findIndex((line) =>
27
+ /^\s*post_install do \|installer\|/.test(line)
28
+ );
29
+
30
+ if (postInstallIndex === -1) {
31
+ return podfile;
32
+ }
33
+
34
+ let depth = 0;
35
+ let insertionIndex = -1;
36
+
37
+ for (let index = postInstallIndex; index < lines.length; index += 1) {
38
+ const trimmed = lines[index].trim();
39
+
40
+ if (trimmed.endsWith(' do |installer|')) {
41
+ depth += 1;
42
+ continue;
43
+ }
44
+
45
+ if (trimmed === 'end') {
46
+ depth -= 1;
47
+
48
+ if (depth === 0) {
49
+ insertionIndex = index;
50
+ break;
51
+ }
52
+ }
53
+ }
54
+
55
+ if (insertionIndex === -1) {
56
+ return podfile;
57
+ }
58
+
59
+ lines.splice(insertionIndex, 0, FMT_FIX_RUBY);
60
+ return lines.join('\n');
61
+ }
62
+
63
+ export const withFmtFix: ConfigPlugin<ResolvedBrownfieldPluginConfigWithIos> = (
64
+ config
65
+ ) =>
66
+ withPodfile(config, (podfileConfig) => {
67
+ podfileConfig.modResults.contents = injectFmtFixIntoPodfile(
68
+ podfileConfig.modResults.contents
69
+ );
70
+
71
+ return podfileConfig;
72
+ });
@@ -21,7 +21,9 @@ export function getFrameworkSourceFiles(
21
21
  return [
22
22
  {
23
23
  relativePath: `${ios.frameworkName}.swift`,
24
- content: renderTemplate('ios', 'FrameworkInterface.swift', {}),
24
+ content: renderTemplate('ios', 'FrameworkInterface.swift', {
25
+ '{{BUNDLE_IDENTIFIER}}': ios.bundleIdentifier,
26
+ }),
25
27
  },
26
28
  {
27
29
  relativePath: 'Info.plist',
@@ -44,17 +46,15 @@ export function createIosFramework(
44
46
  const { ios } = config;
45
47
  const frameworkDir = path.join(iosDir, ios.frameworkName);
46
48
 
47
- // check if framework directory if it exists
48
- if (fs.existsSync(frameworkDir)) {
49
- Logger.logDebug(`Framework directory already exists: ${frameworkDir}`);
50
-
51
- return;
52
- }
53
-
54
- Logger.logDebug(`Creating iOS framework in: ${frameworkDir}`);
49
+ const frameworkDirExists = fs.existsSync(frameworkDir);
50
+ Logger.logDebug(
51
+ frameworkDirExists
52
+ ? `Updating iOS framework files in: ${frameworkDir}`
53
+ : `Creating iOS framework in: ${frameworkDir}`
54
+ );
55
55
 
56
56
  // create framework directory
57
- if (!fs.existsSync(frameworkDir)) {
57
+ if (!frameworkDirExists) {
58
58
  fs.mkdirSync(frameworkDir, { recursive: true });
59
59
 
60
60
  Logger.logDebug(`Created directory: ${frameworkDir}`);
@@ -401,7 +401,7 @@ export function ensureTargetHasFileReferenceInResourcesBuildPhase(
401
401
  * @param options The user configuration
402
402
  * @returns Build settings object
403
403
  */
404
- function getFrameworkBuildSettings(
404
+ export function getFrameworkBuildSettings(
405
405
  {
406
406
  configuration,
407
407
  }: {
@@ -424,6 +424,7 @@ function getFrameworkBuildSettings(
424
424
  USER_SCRIPT_SANDBOXING: 'NO',
425
425
  SKIP_INSTALL: 'NO',
426
426
  ENABLE_MODULE_VERIFIER: 'NO',
427
+ INSTALL_PATH: '"$(LOCAL_LIBRARY_DIR)/Frameworks"',
427
428
 
428
429
  // basic settings
429
430
  PRODUCT_BUNDLE_IDENTIFIER: `"${bundleIdentifier}"`,
@@ -446,6 +447,62 @@ function getFrameworkBuildSettings(
446
447
  };
447
448
  }
448
449
 
450
+ export function rewriteBundleReactNativePhaseScriptForFrameworkTarget(
451
+ shellScript: string
452
+ ): string {
453
+ const debugBundlingOverride = `# Brownfield framework packaging must embed JS in Debug builds.
454
+ if [[ "$CONFIGURATION" = *Debug* ]]; then
455
+ unset SKIP_BUNDLING
456
+ export FORCE_BUNDLING=1
457
+ fi
458
+ `;
459
+ const debugSkipBundlingBlock =
460
+ /if \[\[ "\$CONFIGURATION" = \*Debug\* \]\]; then\s+export SKIP_BUNDLING=1\s+fi\s*/m;
461
+
462
+ if (debugSkipBundlingBlock.test(shellScript)) {
463
+ return shellScript.replace(
464
+ debugSkipBundlingBlock,
465
+ `${debugBundlingOverride}\n`
466
+ );
467
+ }
468
+
469
+ if (shellScript.includes('export FORCE_BUNDLING=1')) {
470
+ return shellScript;
471
+ }
472
+
473
+ return `${debugBundlingOverride}\n${shellScript}`;
474
+ }
475
+
476
+ function decodePbxString(value: string | undefined): string {
477
+ if (!value) {
478
+ return '';
479
+ }
480
+
481
+ if (value.startsWith('"') && value.endsWith('"')) {
482
+ try {
483
+ return JSON.parse(value) as string;
484
+ } catch {
485
+ return value.slice(1, -1).replace(/\\"/g, '"');
486
+ }
487
+ }
488
+
489
+ return value;
490
+ }
491
+
492
+ function encodePbxString(value: string): string {
493
+ return JSON.stringify(value);
494
+ }
495
+
496
+ function hasBuildPhaseComment(
497
+ phase: { comment?: string },
498
+ expectedComment: string
499
+ ): boolean {
500
+ return (
501
+ phase.comment === expectedComment ||
502
+ phase.comment === `"${expectedComment}"`
503
+ );
504
+ }
505
+
449
506
  /**
450
507
  * Finds the "Bundle React Native code and images" build phase from the main app target
451
508
  * and adds it to the framework target's build phases
@@ -469,40 +526,85 @@ export function copyBundleReactNativePhase(
469
526
 
470
527
  // find the phase by name
471
528
  let existingPhaseUuid: string | null = null;
529
+ let existingPhase: Record<string, any> | null = null;
472
530
  for (const key of Object.keys(shellScriptPhases)) {
473
531
  if (key.endsWith('_comment')) continue;
474
532
  const phase = shellScriptPhases[key];
475
533
  if (phase.name === `"${buildPhaseName}"` || phase.name === buildPhaseName) {
476
534
  existingPhaseUuid = key;
535
+ existingPhase = phase;
477
536
  break;
478
537
  }
479
538
  }
480
539
 
481
- if (!existingPhaseUuid) {
540
+ if (!existingPhaseUuid || !existingPhase) {
482
541
  throw new SourceModificationError(
483
542
  `Could not find "${buildPhaseName}" build phase, skipping`
484
543
  );
485
544
  }
486
545
 
487
- // add the phase reference to the framework target's buildPhases array
488
546
  const nativeTargets = project.hash.project.objects.PBXNativeTarget;
489
547
  if (nativeTargets && nativeTargets[targetUuid]) {
490
548
  const target = nativeTargets[targetUuid];
491
549
  if (target.buildPhases) {
492
- // check if phase is already added
493
- if (
494
- !target.buildPhases.some(
495
- (phase: { value: string }) => phase.value === existingPhaseUuid
496
- )
497
- ) {
498
- target.buildPhases.push(
499
- createPbxCommentedReference(existingPhaseUuid, buildPhaseName)
550
+ const targetPhaseIndex = target.buildPhases.findIndex(
551
+ (phase: { comment?: string }) =>
552
+ hasBuildPhaseComment(phase, buildPhaseName)
553
+ );
554
+ const frameworkShellPath =
555
+ decodePbxString(existingPhase.shellPath) || '/bin/sh';
556
+ const frameworkShellScript =
557
+ rewriteBundleReactNativePhaseScriptForFrameworkTarget(
558
+ decodePbxString(existingPhase.shellScript)
500
559
  );
501
560
 
502
- Logger.logDebug(
503
- `Added "${buildPhaseName}" build phase to framework target ${target.name}`
504
- );
561
+ if (targetPhaseIndex !== -1) {
562
+ const currentPhaseUuid = target.buildPhases[targetPhaseIndex].value;
563
+ const currentPhase = shellScriptPhases[currentPhaseUuid];
564
+
565
+ if (currentPhase && currentPhaseUuid !== existingPhaseUuid) {
566
+ currentPhase.inputPaths = existingPhase.inputPaths ?? [];
567
+ currentPhase.outputPaths = existingPhase.outputPaths ?? [];
568
+ currentPhase.shellPath = encodePbxString(frameworkShellPath);
569
+ currentPhase.shellScript = encodePbxString(frameworkShellScript);
570
+
571
+ if (existingPhase.showEnvVarsInLog !== undefined) {
572
+ currentPhase.showEnvVarsInLog = existingPhase.showEnvVarsInLog;
573
+ }
574
+
575
+ Logger.logDebug(
576
+ `Updated framework-specific "${buildPhaseName}" build phase on target ${target.name}`
577
+ );
578
+ return;
579
+ }
580
+
581
+ if (currentPhaseUuid === existingPhaseUuid) {
582
+ target.buildPhases.splice(targetPhaseIndex, 1);
583
+ } else {
584
+ return;
585
+ }
586
+ }
587
+
588
+ const addedPhase = project.addBuildPhase(
589
+ [],
590
+ 'PBXShellScriptBuildPhase',
591
+ buildPhaseName,
592
+ targetUuid,
593
+ {
594
+ inputPaths: existingPhase.inputPaths ?? [],
595
+ outputPaths: existingPhase.outputPaths ?? [],
596
+ shellPath: frameworkShellPath,
597
+ shellScript: frameworkShellScript,
598
+ }
599
+ );
600
+
601
+ if (existingPhase.showEnvVarsInLog !== undefined) {
602
+ addedPhase.buildPhase.showEnvVarsInLog = existingPhase.showEnvVarsInLog;
505
603
  }
604
+
605
+ Logger.logDebug(
606
+ `Added framework-specific "${buildPhaseName}" build phase to target ${target.name}`
607
+ );
506
608
  }
507
609
  }
508
610
  }
@@ -565,6 +667,10 @@ function resolveAppTargetName(
565
667
  return null;
566
668
  }
567
669
 
670
+ /**
671
+ * Adds the "Patch ExpoModulesProvider" shell script phase to the framework target.
672
+ * Safe to call on every prebuild: skips creation when the phase is already present.
673
+ */
568
674
  export function addExpoPre55ShellPatchScriptPhase(
569
675
  modRequest: ModProps<XcodeProject>,
570
676
  project: XcodeProject,
@@ -586,6 +692,16 @@ export function addExpoPre55ShellPatchScriptPhase(
586
692
  );
587
693
  }
588
694
 
695
+ const existingBuildPhases =
696
+ project.pbxNativeTargetSection()[frameworkTargetUUID]?.buildPhases ?? [];
697
+ if (
698
+ existingBuildPhases.some((phase: { comment?: string }) =>
699
+ hasBuildPhaseComment(phase, 'Patch ExpoModulesProvider')
700
+ )
701
+ ) {
702
+ return;
703
+ }
704
+
589
705
  project.addBuildPhase(
590
706
  [
591
707
  // no associated files
@@ -2,7 +2,10 @@ import Foundation
2
2
  import ReactBrownfield
3
3
 
4
4
  // Initializes a Bundle instance that points at the framework target.
5
- public let ReactNativeBundle = Bundle(for: InternalClassForBundle.self)
5
+ public let ReactNativeBundle =
6
+ Bundle(identifier: "{{BUNDLE_IDENTIFIER}}")
7
+ ?? Bundle.allFrameworks.first { $0.bundleIdentifier == "{{BUNDLE_IDENTIFIER}}" }
8
+ ?? Bundle(for: InternalClassForBundle.self)
6
9
 
7
10
  class InternalClassForBundle {}
8
11