@callstack/react-native-brownfield 3.10.0 → 3.12.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 (56) hide show
  1. package/CHANGELOG.md +26 -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/android/utils/constants.js +1 -1
  12. package/lib/commonjs/expo-config-plugin/android/utils/constants.js.map +1 -1
  13. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js +1 -1
  14. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -1
  15. package/lib/commonjs/expo-config-plugin/ios/withFmtFix.js +12 -0
  16. package/lib/commonjs/expo-config-plugin/ios/withFmtFix.js.map +1 -0
  17. package/lib/commonjs/expo-config-plugin/ios/withIosFrameworkFiles.js +1 -1
  18. package/lib/commonjs/expo-config-plugin/ios/withIosFrameworkFiles.js.map +1 -1
  19. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js +6 -1
  20. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js.map +1 -1
  21. package/lib/commonjs/expo-config-plugin/template/ios/FrameworkInterface.swift +4 -1
  22. package/lib/module/expo-config-plugin/android/utils/constants.js +1 -1
  23. package/lib/module/expo-config-plugin/android/utils/constants.js.map +1 -1
  24. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js +1 -1
  25. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -1
  26. package/lib/module/expo-config-plugin/ios/withFmtFix.js +12 -0
  27. package/lib/module/expo-config-plugin/ios/withFmtFix.js.map +1 -0
  28. package/lib/module/expo-config-plugin/ios/withIosFrameworkFiles.js +1 -1
  29. package/lib/module/expo-config-plugin/ios/withIosFrameworkFiles.js.map +1 -1
  30. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js +6 -1
  31. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js.map +1 -1
  32. package/lib/module/expo-config-plugin/template/ios/FrameworkInterface.swift +4 -1
  33. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/constants.d.ts +2 -2
  34. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/constants.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -1
  36. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withFmtFix.d.ts +5 -0
  37. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withFmtFix.d.ts.map +1 -0
  38. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts.map +1 -1
  39. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts +14 -0
  40. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -1
  41. package/lib/typescript/module/src/expo-config-plugin/android/utils/constants.d.ts +2 -2
  42. package/lib/typescript/module/src/expo-config-plugin/android/utils/constants.d.ts.map +1 -1
  43. package/lib/typescript/module/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -1
  44. package/lib/typescript/module/src/expo-config-plugin/ios/withFmtFix.d.ts +5 -0
  45. package/lib/typescript/module/src/expo-config-plugin/ios/withFmtFix.d.ts.map +1 -0
  46. package/lib/typescript/module/src/expo-config-plugin/ios/withIosFrameworkFiles.d.ts.map +1 -1
  47. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts +14 -0
  48. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -1
  49. package/package.json +2 -2
  50. package/src/expo-config-plugin/android/utils/constants.ts +1 -1
  51. package/src/expo-config-plugin/ios/withBrownfieldIos.ts +14 -2
  52. package/src/expo-config-plugin/ios/withFmtFix.ts +72 -0
  53. package/src/expo-config-plugin/ios/withIosFrameworkFiles.ts +10 -10
  54. package/src/expo-config-plugin/ios/xcodeHelpers.ts +130 -14
  55. package/src/expo-config-plugin/template/ios/FrameworkInterface.swift +4 -1
  56. /package/ios/{BrownfieldBundlePathResolver.swift → swiftpm/Sources/BrownfieldBundleSupport/BrownfieldBundlePathResolver.swift} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @callstack/react-native-brownfield
2
2
 
3
+ ## 3.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#237](https://github.com/callstack/react-native-brownfield/pull/237) [`4186cc8`](https://github.com/callstack/react-native-brownfield/commit/4186cc8e2ed2fa7aa41e84cdba7a23f7035ee08d) Thanks [@hurali97](https://github.com/hurali97)! - Bump brownfield-gradle-plugin
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies []:
12
+ - @callstack/brownfield-cli@3.12.0
13
+
14
+ ## 3.11.0
15
+
16
+ ### Minor Changes
17
+
18
+ - [#317](https://github.com/callstack/react-native-brownfield/pull/317) [`c04301b`](https://github.com/callstack/react-native-brownfield/commit/c04301b79d288ab108aaa44d7c79dd876b8405e9) Thanks [@adamTrz](https://github.com/adamTrz)! - Add an opt-in iOS Debug mode for loading the embedded JavaScript bundle with `preferEmbeddedBundleInDebug`, fix `bundleURLOverride` fallback behavior when the override returns `nil`, and add native bundle-resolution tests.
19
+
20
+ ### Patch Changes
21
+
22
+ - [#361](https://github.com/callstack/react-native-brownfield/pull/361) [`aa14eb2`](https://github.com/callstack/react-native-brownfield/commit/aa14eb26e26ea1e6075b91027237e4b41b932b57) Thanks [@hurali97](https://github.com/hurali97)! - make EXUpdates as a dependency only when installed
23
+
24
+ - [#347](https://github.com/callstack/react-native-brownfield/pull/347) [`c19a81b`](https://github.com/callstack/react-native-brownfield/commit/c19a81b7502cc458d742ab947186591bb69cb261) Thanks [@marcinszalski-callstack](https://github.com/marcinszalski-callstack)! - fix: fix method to deallocate reactNativeFactory instance for expo
25
+
26
+ - Updated dependencies [[`3715ac7`](https://github.com/callstack/react-native-brownfield/commit/3715ac7783000756ef1c66ecfe24a85c5e43abab), [`05c557d`](https://github.com/callstack/react-native-brownfield/commit/05c557da9e2b6fca02e6e1a0b0fe71a909bab15f)]:
27
+ - @callstack/brownfield-cli@3.11.0
28
+
3
29
  ## 3.10.0
4
30
 
5
31
  ### Patch Changes
@@ -2,6 +2,18 @@ require 'json'
2
2
 
3
3
  package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
4
 
5
+ expo_updates_installed = lambda do
6
+ Pod::Executable.execute_command('node', [
7
+ '-p',
8
+ 'require.resolve("expo-updates/package.json", { paths: [process.argv[1]] })',
9
+ Pod::Config.instance.installation_root.to_s,
10
+ ])
11
+
12
+ true
13
+ rescue
14
+ false
15
+ end
16
+
5
17
  Pod::Spec.new do |spec|
6
18
  spec.name = "ReactBrownfield"
7
19
  spec.version = package['version']
@@ -15,6 +27,7 @@ Pod::Spec.new do |spec|
15
27
  spec.module_name = "ReactBrownfield"
16
28
  spec.source = { :git => "git@github.com:callstack/react-native-brownfield.git", :tag => "#{spec.version}" }
17
29
  spec.source_files = "ios/**/*.{h,m,mm,swift}"
30
+ spec.exclude_files = "ios/swiftpm/Package.swift", "ios/swiftpm/Tests/**/*"
18
31
  spec.pod_target_xcconfig = {
19
32
  # below: needed to build the XCFramework with `.swiftinterface` files, required by xcodebuild -create-xcframework to succeed
20
33
  'DEFINES_MODULE' => 'YES',
@@ -32,7 +45,7 @@ Pod::Spec.new do |spec|
32
45
 
33
46
  if ENV['REACT_NATIVE_BROWNFIELD_USE_EXPO_HOST'] == '1'
34
47
  spec.dependency 'Expo'
35
- spec.dependency 'EXUpdates'
48
+ spec.dependency 'EXUpdates' if expo_updates_installed.call
36
49
  end
37
50
 
38
51
  install_modules_dependencies(spec)
@@ -0,0 +1,11 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ NS_ASSUME_NONNULL_BEGIN
4
+
5
+ @interface BrownfieldDevLoadingViewBridge : NSObject
6
+
7
+ + (void)setEnabled:(BOOL)enabled;
8
+
9
+ @end
10
+
11
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,12 @@
1
+ #import "BrownfieldDevLoadingViewBridge.h"
2
+
3
+ #import <React/RCTDevLoadingViewSetEnabled.h>
4
+
5
+ @implementation BrownfieldDevLoadingViewBridge
6
+
7
+ + (void)setEnabled:(BOOL)enabled
8
+ {
9
+ RCTDevLoadingViewSetEnabled(enabled);
10
+ }
11
+
12
+ @end
@@ -16,6 +16,16 @@ final class ExpoHostRuntime {
16
16
  private var reactNativeFactory: RCTReactNativeFactory?
17
17
  private var expoDelegate: ExpoAppDelegate?
18
18
 
19
+ private func configureDevLoadingView(with bundleURL: URL? = nil) {
20
+ #if DEBUG
21
+ let resolvedBundleURL = bundleURL ?? delegate.bundleURL()
22
+ let shouldDisableDevLoadingView =
23
+ preferEmbeddedBundleInDebug && (resolvedBundleURL?.isFileURL ?? false)
24
+
25
+ BrownfieldDevLoadingViewBridge.setEnabled(!shouldDisableDevLoadingView)
26
+ #endif
27
+ }
28
+
19
29
  /**
20
30
  * Starts React Native with default parameters.
21
31
  */
@@ -35,12 +45,12 @@ final class ExpoHostRuntime {
35
45
  reactNativeFactory = ExpoReactNativeFactory(delegate: delegate)
36
46
  // below: https://github.com/expo/expo/pull/39418/changes/5abd332b55b2ee7daee848284ed5f7fe1639452e
37
47
  // has removed bindReactNativeFactory method from ExpoAppDelegate
38
- #if !EXPO_SDK_GTE_55 // this define comes from the Brownfield Expo config plugin
48
+ #if !EXPO_SDK_GTE_55 // this define comes from the Brownfield Expo config plugin
39
49
  guard let reactNativeFactory else { return }
40
50
  appDelegate.bindReactNativeFactory(reactNativeFactory)
41
51
  #endif
42
52
  expoDelegate = appDelegate
43
-
53
+
44
54
  if let onBundleLoaded {
45
55
  jsBundleLoadObserver.observeOnce(onBundleLoaded: onBundleLoaded)
46
56
  }
@@ -55,6 +65,9 @@ final class ExpoHostRuntime {
55
65
  return
56
66
  }
57
67
 
68
+ if let rootViewFactory = reactNativeFactory?.rootViewFactory {
69
+ (rootViewFactory as AnyObject).setValue(nil, forKey: "reactHost")
70
+ }
58
71
  reactNativeFactory = nil
59
72
  expoDelegate = nil
60
73
  }
@@ -87,6 +100,17 @@ final class ExpoHostRuntime {
87
100
  delegate.bundle = bundle
88
101
  }
89
102
  }
103
+
104
+ /**
105
+ * Prefer the embedded JavaScript bundle instead of Metro when this framework is built in Debug.
106
+ * Default value: false
107
+ */
108
+ public var preferEmbeddedBundleInDebug: Bool = false {
109
+ didSet {
110
+ delegate.preferEmbeddedBundleInDebug = preferEmbeddedBundleInDebug
111
+ }
112
+ }
113
+
90
114
  /**
91
115
  * Dynamic bundle URL provider called on every bundle load.
92
116
  * When set, this overrides the default bundleURL() behavior in the delegate.
@@ -103,11 +127,11 @@ final class ExpoHostRuntime {
103
127
  _ application: UIApplication,
104
128
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
105
129
  ) -> Bool {
106
- #if canImport(EXUpdates)
130
+ #if canImport(EXUpdates)
107
131
  if !AppController.isInitialized() {
108
132
  AppController.initializeWithoutStarting()
109
133
  }
110
- #endif
134
+ #endif
111
135
  return ExpoAppDelegateSubscriberManager.application(application, didFinishLaunchingWithOptions: launchOptions)
112
136
  }
113
137
 
@@ -129,7 +153,7 @@ final class ExpoHostRuntime {
129
153
  let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
130
154
  return (expoDelegate?.application(application, continue: userActivity, restorationHandler: restorationHandler) ?? false) || result
131
155
  }
132
-
156
+
133
157
  func application(
134
158
  _ application: UIApplication,
135
159
  willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
@@ -143,10 +167,11 @@ final class ExpoHostRuntime {
143
167
  launchOptions: [AnyHashable: Any]?
144
168
  ) -> UIView? {
145
169
  let bundleURL = delegate.bundleURL()
170
+ configureDevLoadingView(with: bundleURL)
146
171
 
147
172
  // below: https://github.com/expo/expo/commit/2013760c46cde1404872d181a691da72fbf207a4
148
173
  // has moved the recreateRootView method to ExpoReactNativeFactory
149
- #if EXPO_SDK_GTE_55 // this define comes from the Brownfield Expo config plugin
174
+ #if EXPO_SDK_GTE_55 // this define comes from the Brownfield Expo config plugin
150
175
  return (reactNativeFactory as? ExpoReactNativeFactory)?.recreateRootView(
151
176
  withBundleURL: bundleURL,
152
177
  moduleName: moduleName,
@@ -168,6 +193,7 @@ class ExpoHostRuntimeDelegate: ExpoReactNativeFactoryDelegate {
168
193
  var entryFile = ".expo/.virtual-metro-entry"
169
194
  var bundlePath = "main.jsbundle"
170
195
  var bundle = Bundle.main
196
+ var preferEmbeddedBundleInDebug = false
171
197
  var bundleURLOverride: (() -> URL?)? = nil
172
198
 
173
199
  override func sourceURL(for bridge: RCTBridge) -> URL? {
@@ -176,27 +202,44 @@ class ExpoHostRuntimeDelegate: ExpoReactNativeFactoryDelegate {
176
202
  }
177
203
 
178
204
  override func bundleURL() -> URL? {
179
- if let bundleURLProvider = bundleURLOverride { return bundleURLProvider() }
180
- #if DEBUG
181
- return RCTBundleURLProvider.sharedSettings().jsBundleURL(
182
- forBundleRoot: entryFile)
183
- #else
184
- #if canImport(EXUpdates)
185
- if AppController.isInitialized(),
186
- let launchAssetURL = AppController.sharedInstance.launchAssetUrl() {
187
- return launchAssetURL
188
- }
189
- #endif
190
205
  do {
191
- let (resourceName, fileExtension) = try BrownfieldBundlePathResolver.resourceComponents(
192
- from: bundlePath
206
+ #if DEBUG
207
+ let isDebug = true
208
+ #else
209
+ let isDebug = false
210
+ #endif
211
+
212
+ if let overriddenURL = bundleURLOverride?() {
213
+ return overriddenURL
214
+ }
215
+
216
+ #if canImport(EXUpdates)
217
+ if !isDebug,
218
+ AppController.isInitialized(),
219
+ let launchAssetURL = AppController.sharedInstance.launchAssetUrl()
220
+ {
221
+ return launchAssetURL
222
+ }
223
+ #endif
224
+
225
+ // The override is resolved here so it wins over the Expo Updates launch asset
226
+ // and the closure is not evaluated a second time inside the shared resolver.
227
+ return try BrownfieldBundleURLResolver.resolve(
228
+ isDebug: isDebug,
229
+ preferEmbeddedBundleInDebug: preferEmbeddedBundleInDebug,
230
+ bundlePath: bundlePath,
231
+ bundle: bundle,
232
+ bundleURLOverride: nil,
233
+ metroURL: {
234
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(
235
+ forBundleRoot: entryFile
236
+ )
237
+ }
193
238
  )
194
- return bundle.url(forResource: resourceName, withExtension: fileExtension)
195
239
  } catch {
196
240
  assertionFailure("Invalid bundlePath '\(bundlePath)': \(error)")
197
241
  return nil
198
242
  }
199
- #endif
200
243
  }
201
244
  }
202
245
  #endif
@@ -55,6 +55,20 @@ internal import Expo
55
55
  }
56
56
  }
57
57
 
58
+ /**
59
+ * Prefer the embedded JavaScript bundle instead of Metro when this framework is built in Debug.
60
+ * Default value: false
61
+ */
62
+ @objc public var preferEmbeddedBundleInDebug: Bool = false {
63
+ didSet {
64
+ #if canImport(Expo)
65
+ ExpoHostRuntime.shared.preferEmbeddedBundleInDebug = preferEmbeddedBundleInDebug
66
+ #else
67
+ ReactNativeHostRuntime.shared.preferEmbeddedBundleInDebug = preferEmbeddedBundleInDebug
68
+ #endif
69
+ }
70
+ }
71
+
58
72
  /**
59
73
  * Dynamic bundle URL provider called on every bundle load.
60
74
  * When set, this overrides the default bundleURL() behavior in the delegate.
@@ -8,6 +8,7 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
8
8
  var entryFile = "index"
9
9
  var bundlePath = "main.jsbundle"
10
10
  var bundle = Bundle.main
11
+ var preferEmbeddedBundleInDebug = false
11
12
  var bundleURLOverride: (() -> URL?)? = nil
12
13
  // MARK: - RCTReactNativeFactoryDelegate Methods
13
14
 
@@ -16,23 +17,27 @@ class ReactNativeBrownfieldDelegate: RCTDefaultReactNativeFactoryDelegate {
16
17
  }
17
18
 
18
19
  public override func bundleURL() -> URL? {
19
- if let bundleURLProvider = bundleURLOverride {
20
- return bundleURLProvider()
21
- }
22
-
23
- #if DEBUG
24
- return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: entryFile)
25
- #else
26
20
  do {
27
- let (resourceName, fileExtension) = try BrownfieldBundlePathResolver.resourceComponents(
28
- from: bundlePath
21
+ #if DEBUG
22
+ let isDebug = true
23
+ #else
24
+ let isDebug = false
25
+ #endif
26
+
27
+ return try BrownfieldBundleURLResolver.resolve(
28
+ isDebug: isDebug,
29
+ preferEmbeddedBundleInDebug: preferEmbeddedBundleInDebug,
30
+ bundlePath: bundlePath,
31
+ bundle: bundle,
32
+ bundleURLOverride: bundleURLOverride,
33
+ metroURL: {
34
+ RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: entryFile)
35
+ }
29
36
  )
30
- return bundle.url(forResource: resourceName, withExtension: fileExtension)
31
37
  } catch {
32
38
  assertionFailure("Invalid bundlePath '\(bundlePath)': \(error)")
33
39
  return nil
34
40
  }
35
- #endif
36
41
  }
37
42
  }
38
43
 
@@ -41,6 +46,15 @@ final class ReactNativeHostRuntime {
41
46
  private let jsBundleLoadObserver = JSBundleLoadObserver()
42
47
  private var delegate = ReactNativeBrownfieldDelegate()
43
48
 
49
+ private func configureDevLoadingView() {
50
+ #if DEBUG
51
+ let shouldDisableDevLoadingView =
52
+ preferEmbeddedBundleInDebug && (delegate.bundleURL()?.isFileURL ?? false)
53
+
54
+ BrownfieldDevLoadingViewBridge.setEnabled(!shouldDisableDevLoadingView)
55
+ #endif
56
+ }
57
+
44
58
  /**
45
59
  * Path to JavaScript root.
46
60
  * Default value: "index"
@@ -71,6 +85,16 @@ final class ReactNativeHostRuntime {
71
85
  }
72
86
  }
73
87
 
88
+ /**
89
+ * Prefer the embedded JavaScript bundle instead of Metro when this framework is built in Debug.
90
+ * Default value: false
91
+ */
92
+ public var preferEmbeddedBundleInDebug: Bool = false {
93
+ didSet {
94
+ delegate.preferEmbeddedBundleInDebug = preferEmbeddedBundleInDebug
95
+ }
96
+ }
97
+
74
98
  /**
75
99
  * Dynamic bundle URL provider called on every bundle load.
76
100
  * When set, this overrides the default bundleURL() behavior in the delegate.
@@ -113,7 +137,9 @@ final class ReactNativeHostRuntime {
113
137
  initialProps: [AnyHashable: Any]?,
114
138
  launchOptions: [AnyHashable: Any]? = nil
115
139
  ) -> UIView? {
116
- reactNativeFactory?.rootViewFactory.view(
140
+ configureDevLoadingView()
141
+
142
+ return reactNativeFactory?.rootViewFactory.view(
117
143
  withModuleName: moduleName,
118
144
  initialProperties: initialProps,
119
145
  launchOptions: launchOptions
@@ -0,0 +1,27 @@
1
+ // swift-tools-version: 5.9
2
+
3
+ import PackageDescription
4
+
5
+ let package = Package(
6
+ name: "BrownfieldBundleSupport",
7
+ platforms: [
8
+ .macOS(.v13),
9
+ ],
10
+ products: [
11
+ .library(
12
+ name: "BrownfieldBundleSupport",
13
+ targets: ["BrownfieldBundleSupport"]
14
+ ),
15
+ ],
16
+ targets: [
17
+ .target(
18
+ name: "BrownfieldBundleSupport",
19
+ path: "Sources/BrownfieldBundleSupport"
20
+ ),
21
+ .testTarget(
22
+ name: "BrownfieldBundleSupportTests",
23
+ dependencies: ["BrownfieldBundleSupport"],
24
+ path: "Tests/BrownfieldBundleSupportTests"
25
+ ),
26
+ ]
27
+ )
@@ -0,0 +1,28 @@
1
+ import Foundation
2
+
3
+ final class BrownfieldBundleURLResolver {
4
+ private init() {}
5
+
6
+ static func resolve(
7
+ isDebug: Bool,
8
+ preferEmbeddedBundleInDebug: Bool,
9
+ bundlePath: String,
10
+ bundle: Bundle,
11
+ bundleURLOverride: (() -> URL?)?,
12
+ metroURL: () -> URL?
13
+ ) throws -> URL? {
14
+ if let overriddenURL = bundleURLOverride?() {
15
+ return overriddenURL
16
+ }
17
+
18
+ if isDebug && !preferEmbeddedBundleInDebug {
19
+ return metroURL()
20
+ }
21
+
22
+ let (resourceName, fileExtension) = try BrownfieldBundlePathResolver.resourceComponents(
23
+ from: bundlePath
24
+ )
25
+
26
+ return bundle.url(forResource: resourceName, withExtension: fileExtension)
27
+ }
28
+ }
@@ -0,0 +1,156 @@
1
+ import XCTest
2
+ @testable import BrownfieldBundleSupport
3
+
4
+ final class BrownfieldBundleURLResolverTests: XCTestCase {
5
+ func test_debugResolutionPrefersBundledResourceWhenEnabled() throws {
6
+ let metroURL = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
7
+ let bundle = try makeFixtureBundle()
8
+
9
+ let resolvedURL = try BrownfieldBundleURLResolver.resolve(
10
+ isDebug: true,
11
+ preferEmbeddedBundleInDebug: true,
12
+ bundlePath: "main.jsbundle",
13
+ bundle: bundle,
14
+ bundleURLOverride: nil,
15
+ metroURL: { metroURL }
16
+ )
17
+
18
+ XCTAssertNotNil(resolvedURL)
19
+ XCTAssertEqual(resolvedURL?.lastPathComponent, "main.jsbundle")
20
+ XCTAssertNotEqual(resolvedURL, metroURL)
21
+ }
22
+
23
+ func test_debugResolutionUsesMetroByDefault() throws {
24
+ let metroURL = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
25
+ let bundle = try makeFixtureBundle()
26
+
27
+ let resolvedURL = try BrownfieldBundleURLResolver.resolve(
28
+ isDebug: true,
29
+ preferEmbeddedBundleInDebug: false,
30
+ bundlePath: "main.jsbundle",
31
+ bundle: bundle,
32
+ bundleURLOverride: nil,
33
+ metroURL: { metroURL }
34
+ )
35
+
36
+ XCTAssertEqual(resolvedURL, metroURL)
37
+ }
38
+
39
+ func test_releaseResolutionUsesBundledResource() throws {
40
+ let metroURL = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
41
+ let bundle = try makeFixtureBundle()
42
+
43
+ let resolvedURL = try BrownfieldBundleURLResolver.resolve(
44
+ isDebug: false,
45
+ preferEmbeddedBundleInDebug: false,
46
+ bundlePath: "main.jsbundle",
47
+ bundle: bundle,
48
+ bundleURLOverride: nil,
49
+ metroURL: { metroURL }
50
+ )
51
+
52
+ XCTAssertNotNil(resolvedURL)
53
+ XCTAssertEqual(resolvedURL?.lastPathComponent, "main.jsbundle")
54
+ XCTAssertNotEqual(resolvedURL, metroURL)
55
+ }
56
+
57
+ func test_bundleURLOverrideTakesPrecedenceWhenItReturnsAURL() throws {
58
+ let metroURL = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
59
+ let overrideURL = URL(string: "https://example.com/custom.bundle")!
60
+ let bundle = try makeFixtureBundle()
61
+
62
+ let resolvedURL = try BrownfieldBundleURLResolver.resolve(
63
+ isDebug: true,
64
+ preferEmbeddedBundleInDebug: false,
65
+ bundlePath: "main.jsbundle",
66
+ bundle: bundle,
67
+ bundleURLOverride: { overrideURL },
68
+ metroURL: { metroURL }
69
+ )
70
+
71
+ XCTAssertEqual(resolvedURL, overrideURL)
72
+ }
73
+
74
+ func test_bundleURLOverrideFallsBackWhenItReturnsNil() throws {
75
+ let metroURL = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
76
+ let bundle = try makeFixtureBundle()
77
+
78
+ let resolvedURL = try BrownfieldBundleURLResolver.resolve(
79
+ isDebug: true,
80
+ preferEmbeddedBundleInDebug: true,
81
+ bundlePath: "main.jsbundle",
82
+ bundle: bundle,
83
+ bundleURLOverride: { nil },
84
+ metroURL: { metroURL }
85
+ )
86
+
87
+ XCTAssertNotNil(resolvedURL)
88
+ XCTAssertEqual(resolvedURL?.lastPathComponent, "main.jsbundle")
89
+ XCTAssertNotEqual(resolvedURL, metroURL)
90
+ }
91
+
92
+ func test_invalidBundlePathThrows() {
93
+ XCTAssertThrowsError(
94
+ try BrownfieldBundleURLResolver.resolve(
95
+ isDebug: false,
96
+ preferEmbeddedBundleInDebug: false,
97
+ bundlePath: "mainjsbundle",
98
+ bundle: Bundle(for: Self.self),
99
+ bundleURLOverride: nil,
100
+ metroURL: { nil }
101
+ )
102
+ ) { error in
103
+ guard case let BrownfieldBundlePathResolver.Error.invalidBundlePath(bundlePath) = error else {
104
+ return XCTFail("Expected invalid bundle path error, got \(error)")
105
+ }
106
+
107
+ XCTAssertEqual(bundlePath, "mainjsbundle")
108
+ }
109
+ }
110
+
111
+ private func makeFixtureBundle() throws -> Bundle {
112
+ let fileManager = FileManager.default
113
+ let bundleURL = fileManager.temporaryDirectory
114
+ .appendingPathComponent("BrownfieldBundleFixture-\(UUID().uuidString).bundle")
115
+ let contentsURL = bundleURL.appendingPathComponent("Contents")
116
+ let resourcesURL = contentsURL.appendingPathComponent("Resources")
117
+ let plistURL = contentsURL.appendingPathComponent("Info.plist")
118
+ let fixtureURL = resourcesURL.appendingPathComponent("main.jsbundle")
119
+
120
+ try fileManager.createDirectory(at: resourcesURL, withIntermediateDirectories: true)
121
+
122
+ let plist = """
123
+ <?xml version="1.0" encoding="UTF-8"?>
124
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
125
+ <plist version="1.0">
126
+ <dict>
127
+ <key>CFBundleIdentifier</key>
128
+ <string>com.callstack.BrownfieldBundleFixture</string>
129
+ <key>CFBundleName</key>
130
+ <string>BrownfieldBundleFixture</string>
131
+ <key>CFBundlePackageType</key>
132
+ <string>BNDL</string>
133
+ <key>CFBundleVersion</key>
134
+ <string>1</string>
135
+ </dict>
136
+ </plist>
137
+ """
138
+
139
+ try plist.write(to: plistURL, atomically: true, encoding: .utf8)
140
+ try "console.log(\"fixture\");".write(to: fixtureURL, atomically: true, encoding: .utf8)
141
+
142
+ addTeardownBlock {
143
+ try? fileManager.removeItem(at: bundleURL)
144
+ }
145
+
146
+ guard let bundle = Bundle(url: bundleURL) else {
147
+ throw NSError(
148
+ domain: "BrownfieldBundleURLResolverTests",
149
+ code: 1,
150
+ userInfo: [NSLocalizedDescriptionKey: "Failed to create fixture bundle"]
151
+ )
152
+ }
153
+
154
+ return bundle
155
+ }
156
+ }
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,"__esModule",{value:true});exports.brownfieldGradlePluginDependency=exports.BROWNFIELD_PLUGIN_VERSION=void 0;var BROWNFIELD_PLUGIN_VERSION=exports.BROWNFIELD_PLUGIN_VERSION='1.1.0';var brownfieldGradlePluginDependency=exports.brownfieldGradlePluginDependency=`classpath("com.callstack.react:brownfield-gradle-plugin:${BROWNFIELD_PLUGIN_VERSION}")`;
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.brownfieldGradlePluginDependency=exports.BROWNFIELD_PLUGIN_VERSION=void 0;var BROWNFIELD_PLUGIN_VERSION=exports.BROWNFIELD_PLUGIN_VERSION='2.0.0-alpha01';var brownfieldGradlePluginDependency=exports.brownfieldGradlePluginDependency=`classpath("com.callstack.react:brownfield-gradle-plugin:${BROWNFIELD_PLUGIN_VERSION}")`;
2
2
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["BROWNFIELD_PLUGIN_VERSION","exports","brownfieldGradlePluginDependency"],"sourceRoot":"../../../../../src","sources":["expo-config-plugin/android/utils/constants.ts"],"mappings":"2IAAO,GAAM,CAAAA,yBAAyB,CAAAC,OAAA,CAAAD,yBAAA,CAAG,OAAO,CACzC,GAAM,CAAAE,gCAAgC,CAAAD,OAAA,CAAAC,gCAAA,CAAG,2DAA2DF,yBAAyB,IAAI","ignoreList":[]}
1
+ {"version":3,"names":["BROWNFIELD_PLUGIN_VERSION","exports","brownfieldGradlePluginDependency"],"sourceRoot":"../../../../../src","sources":["expo-config-plugin/android/utils/constants.ts"],"mappings":"2IAAO,GAAM,CAAAA,yBAAyB,CAAAC,OAAA,CAAAD,yBAAA,CAAG,eAAe,CACjD,GAAM,CAAAE,gCAAgC,CAAAD,OAAA,CAAAC,gCAAA,CAAG,2DAA2DF,yBAAyB,IAAI","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,"__esModule",{value:true});exports.withBrownfieldIos=void 0;var _configPlugins=require("@expo/config-plugins");var _xcodeHelpers=require("./xcodeHelpers");var _podfileHelpers=require("./podfileHelpers");var _expoUpdates=require("./utils/expo-updates");var _withIosFrameworkFiles=require("./withIosFrameworkFiles");var _logging=require("../logging");var _expoUtils=require("../expoUtils");var withBrownfieldIos=exports.withBrownfieldIos=function withBrownfieldIos(config,props){var _getExpoInfo=(0,_expoUtils.getExpoInfo)(config),isExpoPre55=_getExpoInfo.isExpoPre55,expoMajor=_getExpoInfo.expoMajor;config=(0,_configPlugins.withXcodeProject)(config,function(xcodeConfig){var project=xcodeConfig.modResults,modRequest=xcodeConfig.modRequest;var hasExpoUpdates=(0,_expoUtils.hasExpoUpdatesInstalled)(modRequest.projectRoot);var _addFrameworkTarget=(0,_xcodeHelpers.addFrameworkTarget)(project,modRequest,props.ios),frameworkTargetUUID=_addFrameworkTarget.frameworkTargetUUID,targetAlreadyExists=_addFrameworkTarget.targetAlreadyExists;if(hasExpoUpdates){(0,_expoUpdates.ensureFrameworkHasExpoPlistResource)(project,frameworkTargetUUID);}else{_logging.Logger.logDebug('Skipping Expo.plist framework resource wiring because expo-updates is not installed');}if(targetAlreadyExists){_logging.Logger.logDebug(`Skipping further Xcode modifications as framework target was already present`);return xcodeConfig;}(0,_xcodeHelpers.copyBundleReactNativePhase)(project,frameworkTargetUUID);if(isExpoPre55){_logging.Logger.logDebug(`Adding ExpoModulesProvider patch phase for Expo SDK ${config.sdkVersion}`);(0,_xcodeHelpers.addExpoPre55ShellPatchScriptPhase)(modRequest,project,{frameworkName:props.ios.frameworkName,frameworkTargetUUID:frameworkTargetUUID});}else{_logging.Logger.logDebug(`Skipping ExpoModulesProvider patch phase for Expo SDK ${config.sdkVersion}`);}(0,_xcodeHelpers.addSourceFilesBuildPhase)(project,frameworkTargetUUID,props.ios);return xcodeConfig;});config=(0,_configPlugins.withPodfile)(config,function(podfileConfig){var frameworkName=props.ios.frameworkName;podfileConfig.modResults.contents=(0,_podfileHelpers.modifyPodfile)(podfileConfig.modResults.contents,frameworkName,expoMajor);return podfileConfig;});config=(0,_withIosFrameworkFiles.withIosFrameworkFiles)(config,props);return config;};
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.withBrownfieldIos=void 0;var _configPlugins=require("@expo/config-plugins");var _xcodeHelpers=require("./xcodeHelpers");var _podfileHelpers=require("./podfileHelpers");var _withFmtFix=require("./withFmtFix");var _expoUpdates=require("./utils/expo-updates");var _withIosFrameworkFiles=require("./withIosFrameworkFiles");var _logging=require("../logging");var _expoUtils=require("../expoUtils");var withBrownfieldIos=exports.withBrownfieldIos=function withBrownfieldIos(config,props){var _getExpoInfo=(0,_expoUtils.getExpoInfo)(config),isExpoPre55=_getExpoInfo.isExpoPre55,expoMajor=_getExpoInfo.expoMajor;config=(0,_configPlugins.withXcodeProject)(config,function(xcodeConfig){var project=xcodeConfig.modResults,modRequest=xcodeConfig.modRequest;var hasExpoUpdates=(0,_expoUtils.hasExpoUpdatesInstalled)(modRequest.projectRoot);var _addFrameworkTarget=(0,_xcodeHelpers.addFrameworkTarget)(project,modRequest,props.ios),frameworkTargetUUID=_addFrameworkTarget.frameworkTargetUUID,targetAlreadyExists=_addFrameworkTarget.targetAlreadyExists;if(hasExpoUpdates){(0,_expoUpdates.ensureFrameworkHasExpoPlistResource)(project,frameworkTargetUUID);}else{_logging.Logger.logDebug('Skipping Expo.plist framework resource wiring because expo-updates is not installed');}if(targetAlreadyExists){_logging.Logger.logDebug(`Framework target already present, syncing Brownfield build phases`);(0,_xcodeHelpers.copyBundleReactNativePhase)(project,frameworkTargetUUID);if(isExpoPre55){(0,_xcodeHelpers.addExpoPre55ShellPatchScriptPhase)(modRequest,project,{frameworkName:props.ios.frameworkName,frameworkTargetUUID:frameworkTargetUUID});}return xcodeConfig;}(0,_xcodeHelpers.copyBundleReactNativePhase)(project,frameworkTargetUUID);if(isExpoPre55){_logging.Logger.logDebug(`Adding ExpoModulesProvider patch phase for Expo SDK ${config.sdkVersion}`);(0,_xcodeHelpers.addExpoPre55ShellPatchScriptPhase)(modRequest,project,{frameworkName:props.ios.frameworkName,frameworkTargetUUID:frameworkTargetUUID});}else{_logging.Logger.logDebug(`Skipping ExpoModulesProvider patch phase for Expo SDK ${config.sdkVersion}`);}(0,_xcodeHelpers.addSourceFilesBuildPhase)(project,frameworkTargetUUID,props.ios);return xcodeConfig;});config=(0,_configPlugins.withPodfile)(config,function(podfileConfig){var frameworkName=props.ios.frameworkName;var modifiedPodfile=(0,_podfileHelpers.modifyPodfile)(podfileConfig.modResults.contents,frameworkName,expoMajor);podfileConfig.modResults.contents=(0,_withFmtFix.injectFmtFixIntoPodfile)(modifiedPodfile);return podfileConfig;});config=(0,_withIosFrameworkFiles.withIosFrameworkFiles)(config,props);return config;};
2
2
  //# sourceMappingURL=withBrownfieldIos.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_configPlugins","require","_xcodeHelpers","_podfileHelpers","_expoUpdates","_withIosFrameworkFiles","_logging","_expoUtils","withBrownfieldIos","exports","config","props","_getExpoInfo","getExpoInfo","isExpoPre55","expoMajor","withXcodeProject","xcodeConfig","project","modResults","modRequest","hasExpoUpdates","hasExpoUpdatesInstalled","projectRoot","_addFrameworkTarget","addFrameworkTarget","ios","frameworkTargetUUID","targetAlreadyExists","ensureFrameworkHasExpoPlistResource","Logger","logDebug","copyBundleReactNativePhase","sdkVersion","addExpoPre55ShellPatchScriptPhase","frameworkName","addSourceFilesBuildPhase","withPodfile","podfileConfig","contents","modifyPodfile","withIosFrameworkFiles"],"sourceRoot":"../../../../src","sources":["expo-config-plugin/ios/withBrownfieldIos.ts"],"mappings":"0FAAA,IAAAA,cAAA,CAAAC,OAAA,yBAMA,IAAAC,aAAA,CAAAD,OAAA,mBAMA,IAAAE,eAAA,CAAAF,OAAA,qBACA,IAAAG,YAAA,CAAAH,OAAA,yBACA,IAAAI,sBAAA,CAAAJ,OAAA,4BAEA,IAAAK,QAAA,CAAAL,OAAA,eACA,IAAAM,UAAA,CAAAN,OAAA,iBAYO,GAAM,CAAAO,iBAEZ,CAAAC,OAAA,CAAAD,iBAAA,CAAG,QAFS,CAAAA,iBAEZA,CAAIE,MAAM,CAAEC,KAAK,CAAK,CACrB,IAAAC,YAAA,CAAmC,GAAAC,sBAAW,EAACH,MAAM,CAAC,CAA9CI,WAAW,CAAAF,YAAA,CAAXE,WAAW,CAAEC,SAAS,CAAAH,YAAA,CAATG,SAAS,CAG9BL,MAAM,CAAG,GAAAM,+BAAgB,EAACN,MAAM,CAAE,SAACO,WAAW,CAAK,CACjD,GAAoB,CAAAC,OAAO,CAAiBD,WAAW,CAA/CE,UAAU,CAAWC,UAAU,CAAKH,WAAW,CAA1BG,UAAU,CACvC,GAAM,CAAAC,cAAc,CAAG,GAAAC,kCAAuB,EAACF,UAAU,CAACG,WAAW,CAAC,CAEtE,IAAAC,mBAAA,CAAqD,GAAAC,gCAAkB,EACrEP,OAAO,CACPE,UAAU,CACVT,KAAK,CAACe,GACR,CAAC,CAJOC,mBAAmB,CAAAH,mBAAA,CAAnBG,mBAAmB,CAAEC,mBAAmB,CAAAJ,mBAAA,CAAnBI,mBAAmB,CAQhD,GAAIP,cAAc,CAAE,CAClB,GAAAQ,gDAAmC,EAACX,OAAO,CAAES,mBAAmB,CAAC,CACnE,CAAC,IAAM,CACLG,eAAM,CAACC,QAAQ,CACb,qFACF,CAAC,CACH,CAEA,GAAIH,mBAAmB,CAAE,CACvBE,eAAM,CAACC,QAAQ,CACb,8EACF,CAAC,CAED,MAAO,CAAAd,WAAW,CACpB,CAGA,GAAAe,wCAA0B,EAACd,OAAO,CAAES,mBAAmB,CAAC,CAGxD,GAAIb,WAAW,CAAE,CACfgB,eAAM,CAACC,QAAQ,CACb,uDAAuDrB,MAAM,CAACuB,UAAU,EAC1E,CAAC,CAED,GAAAC,+CAAiC,EAACd,UAAU,CAAEF,OAAO,CAAE,CACrDiB,aAAa,CAAExB,KAAK,CAACe,GAAG,CAACS,aAAa,CACtCR,mBAAmB,CAAEA,mBACvB,CAAC,CAAC,CACJ,CAAC,IAAM,CACLG,eAAM,CAACC,QAAQ,CACb,yDAAyDrB,MAAM,CAACuB,UAAU,EAC5E,CAAC,CACH,CAEA,GAAAG,sCAAwB,EAAClB,OAAO,CAAES,mBAAmB,CAAEhB,KAAK,CAACe,GAAG,CAAC,CAEjE,MAAO,CAAAT,WAAW,CACpB,CAAC,CAAC,CAGFP,MAAM,CAAG,GAAA2B,0BAAW,EAAC3B,MAAM,CAAE,SAAC4B,aAAa,CAAK,CAC9C,GAAQ,CAAAH,aAAa,CAAKxB,KAAK,CAACe,GAAG,CAA3BS,aAAa,CAErBG,aAAa,CAACnB,UAAU,CAACoB,QAAQ,CAAG,GAAAC,6BAAa,EAC/CF,aAAa,CAACnB,UAAU,CAACoB,QAAQ,CACjCJ,aAAa,CACbpB,SACF,CAAC,CAED,MAAO,CAAAuB,aAAa,CACtB,CAAC,CAAC,CAGF5B,MAAM,CAAG,GAAA+B,4CAAqB,EAAC/B,MAAM,CAAEC,KAAK,CAAC,CAE7C,MAAO,CAAAD,MAAM,CACf,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_configPlugins","require","_xcodeHelpers","_podfileHelpers","_withFmtFix","_expoUpdates","_withIosFrameworkFiles","_logging","_expoUtils","withBrownfieldIos","exports","config","props","_getExpoInfo","getExpoInfo","isExpoPre55","expoMajor","withXcodeProject","xcodeConfig","project","modResults","modRequest","hasExpoUpdates","hasExpoUpdatesInstalled","projectRoot","_addFrameworkTarget","addFrameworkTarget","ios","frameworkTargetUUID","targetAlreadyExists","ensureFrameworkHasExpoPlistResource","Logger","logDebug","copyBundleReactNativePhase","addExpoPre55ShellPatchScriptPhase","frameworkName","sdkVersion","addSourceFilesBuildPhase","withPodfile","podfileConfig","modifiedPodfile","modifyPodfile","contents","injectFmtFixIntoPodfile","withIosFrameworkFiles"],"sourceRoot":"../../../../src","sources":["expo-config-plugin/ios/withBrownfieldIos.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,12 @@
1
+ Object.defineProperty(exports,"__esModule",{value:true});exports.injectFmtFixIntoPodfile=injectFmtFixIntoPodfile;exports.withFmtFix=void 0;var _configPlugins=require("@expo/config-plugins");var FMT_FIX_MARKER='# Fix fmt 11.0.2 consteval compilation error with Xcode 26.4+';var FMT_FIX_RUBY=`\
2
+ ${FMT_FIX_MARKER}
3
+ fmt_base = File.join(installer.sandbox.pod_dir('fmt'), 'include', 'fmt', 'base.h')
4
+ if File.exist?(fmt_base)
5
+ content = File.read(fmt_base)
6
+ patched = content.gsub(/^#\\s*define FMT_USE_CONSTEVAL 1$/, '# define FMT_USE_CONSTEVAL 0')
7
+ if patched != content
8
+ File.chmod(0644, fmt_base)
9
+ File.write(fmt_base, patched)
10
+ end
11
+ end`;function injectFmtFixIntoPodfile(podfile){if(podfile.includes(FMT_FIX_MARKER)){return podfile;}var lines=podfile.split('\n');var postInstallIndex=lines.findIndex(function(line){return /^\s*post_install do \|installer\|/.test(line);});if(postInstallIndex===-1){return podfile;}var depth=0;var insertionIndex=-1;for(var index=postInstallIndex;index<lines.length;index+=1){var trimmed=lines[index].trim();if(trimmed.endsWith(' do |installer|')){depth+=1;continue;}if(trimmed==='end'){depth-=1;if(depth===0){insertionIndex=index;break;}}}if(insertionIndex===-1){return podfile;}lines.splice(insertionIndex,0,FMT_FIX_RUBY);return lines.join('\n');}var withFmtFix=exports.withFmtFix=function withFmtFix(config){return(0,_configPlugins.withPodfile)(config,function(podfileConfig){podfileConfig.modResults.contents=injectFmtFixIntoPodfile(podfileConfig.modResults.contents);return podfileConfig;});};
12
+ //# sourceMappingURL=withFmtFix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_configPlugins","require","FMT_FIX_MARKER","FMT_FIX_RUBY","injectFmtFixIntoPodfile","podfile","includes","lines","split","postInstallIndex","findIndex","line","test","depth","insertionIndex","index","length","trimmed","trim","endsWith","splice","join","withFmtFix","exports","config","withPodfile","podfileConfig","modResults","contents"],"sourceRoot":"../../../../src","sources":["expo-config-plugin/ios/withFmtFix.ts"],"mappings":"2IAAA,IAAAA,cAAA,CAAAC,OAAA,yBAIA,GAAM,CAAAC,cAAc,CAClB,+DAA+D,CAEjE,GAAM,CAAAC,YAAY,CAAG;AACrB,MAAMD,cAAc;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,CAED,QAAS,CAAAE,uBAAuBA,CAACC,OAAe,CAAU,CAC/D,GAAIA,OAAO,CAACC,QAAQ,CAACJ,cAAc,CAAC,CAAE,CACpC,MAAO,CAAAG,OAAO,CAChB,CAEA,GAAM,CAAAE,KAAK,CAAGF,OAAO,CAACG,KAAK,CAAC,IAAI,CAAC,CACjC,GAAM,CAAAC,gBAAgB,CAAGF,KAAK,CAACG,SAAS,CAAC,SAACC,IAAI,QAC5C,oCAAmC,CAACC,IAAI,CAACD,IAAI,CAAC,EAChD,CAAC,CAED,GAAIF,gBAAgB,GAAK,CAAC,CAAC,CAAE,CAC3B,MAAO,CAAAJ,OAAO,CAChB,CAEA,GAAI,CAAAQ,KAAK,CAAG,CAAC,CACb,GAAI,CAAAC,cAAc,CAAG,CAAC,CAAC,CAEvB,IAAK,GAAI,CAAAC,KAAK,CAAGN,gBAAgB,CAAEM,KAAK,CAAGR,KAAK,CAACS,MAAM,CAAED,KAAK,EAAI,CAAC,CAAE,CACnE,GAAM,CAAAE,OAAO,CAAGV,KAAK,CAACQ,KAAK,CAAC,CAACG,IAAI,CAAC,CAAC,CAEnC,GAAID,OAAO,CAACE,QAAQ,CAAC,iBAAiB,CAAC,CAAE,CACvCN,KAAK,EAAI,CAAC,CACV,SACF,CAEA,GAAII,OAAO,GAAK,KAAK,CAAE,CACrBJ,KAAK,EAAI,CAAC,CAEV,GAAIA,KAAK,GAAK,CAAC,CAAE,CACfC,cAAc,CAAGC,KAAK,CACtB,MACF,CACF,CACF,CAEA,GAAID,cAAc,GAAK,CAAC,CAAC,CAAE,CACzB,MAAO,CAAAT,OAAO,CAChB,CAEAE,KAAK,CAACa,MAAM,CAACN,cAAc,CAAE,CAAC,CAAEX,YAAY,CAAC,CAC7C,MAAO,CAAAI,KAAK,CAACc,IAAI,CAAC,IAAI,CAAC,CACzB,CAEO,GAAM,CAAAC,UAA+D,CAAAC,OAAA,CAAAD,UAAA,CAAG,QAAlE,CAAAA,UAA+DA,CAC1EE,MAAM,QAEN,GAAAC,0BAAW,EAACD,MAAM,CAAE,SAACE,aAAa,CAAK,CACrCA,aAAa,CAACC,UAAU,CAACC,QAAQ,CAAGxB,uBAAuB,CACzDsB,aAAa,CAACC,UAAU,CAACC,QAC3B,CAAC,CAED,MAAO,CAAAF,aAAa,CACtB,CAAC,CAAC","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.createIosFramework=createIosFramework;exports.getFrameworkSourceFiles=getFrameworkSourceFiles;exports.withIosFrameworkFiles=void 0;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var fs=_interopRequireWildcard(require("node:fs"));var path=_interopRequireWildcard(require("node:path"));var _configPlugins=require("@expo/config-plugins");var _logging=require("../logging");var _engine=require("../template/engine");function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function _interopRequireWildcard(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(var _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);}function getFrameworkSourceFiles(ios){return[{relativePath:`${ios.frameworkName}.swift`,content:(0,_engine.renderTemplate)('ios','FrameworkInterface.swift',{})},{relativePath:'Info.plist',content:(0,_engine.renderTemplate)('ios','Info.plist',{'{{BUNDLE_IDENTIFIER}}':ios.bundleIdentifier})}];}function createIosFramework(iosDir,config){var ios=config.ios;var frameworkDir=path.join(iosDir,ios.frameworkName);if(fs.existsSync(frameworkDir)){_logging.Logger.logDebug(`Framework directory already exists: ${frameworkDir}`);return;}_logging.Logger.logDebug(`Creating iOS framework in: ${frameworkDir}`);if(!fs.existsSync(frameworkDir)){fs.mkdirSync(frameworkDir,{recursive:true});_logging.Logger.logDebug(`Created directory: ${frameworkDir}`);}for(var file of getFrameworkSourceFiles(ios)){var filePath=path.join(frameworkDir,file.relativePath);fs.writeFileSync(filePath,file.content,'utf8');}_logging.Logger.logDebug(`iOS framework "${ios.frameworkName}" files created at ${frameworkDir}`);}var withIosFrameworkFiles=exports.withIosFrameworkFiles=function withIosFrameworkFiles(config,props){return(0,_configPlugins.withDangerousMod)(config,['ios',(function(){var _ref=(0,_asyncToGenerator2.default)(function*(dangerousConfig){var iosDir=path.join(dangerousConfig.modRequest.projectRoot,'ios');createIosFramework(iosDir,props);return dangerousConfig;});return function(_x){return _ref.apply(this,arguments);};}())]);};
1
+ var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.createIosFramework=createIosFramework;exports.getFrameworkSourceFiles=getFrameworkSourceFiles;exports.withIosFrameworkFiles=void 0;var _asyncToGenerator2=_interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));var fs=_interopRequireWildcard(require("node:fs"));var path=_interopRequireWildcard(require("node:path"));var _configPlugins=require("@expo/config-plugins");var _logging=require("../logging");var _engine=require("../template/engine");function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap(),n=new WeakMap();return(_interopRequireWildcard=function _interopRequireWildcard(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(var _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);}function getFrameworkSourceFiles(ios){return[{relativePath:`${ios.frameworkName}.swift`,content:(0,_engine.renderTemplate)('ios','FrameworkInterface.swift',{'{{BUNDLE_IDENTIFIER}}':ios.bundleIdentifier})},{relativePath:'Info.plist',content:(0,_engine.renderTemplate)('ios','Info.plist',{'{{BUNDLE_IDENTIFIER}}':ios.bundleIdentifier})}];}function createIosFramework(iosDir,config){var ios=config.ios;var frameworkDir=path.join(iosDir,ios.frameworkName);var frameworkDirExists=fs.existsSync(frameworkDir);_logging.Logger.logDebug(frameworkDirExists?`Updating iOS framework files in: ${frameworkDir}`:`Creating iOS framework in: ${frameworkDir}`);if(!frameworkDirExists){fs.mkdirSync(frameworkDir,{recursive:true});_logging.Logger.logDebug(`Created directory: ${frameworkDir}`);}for(var file of getFrameworkSourceFiles(ios)){var filePath=path.join(frameworkDir,file.relativePath);fs.writeFileSync(filePath,file.content,'utf8');}_logging.Logger.logDebug(`iOS framework "${ios.frameworkName}" files created at ${frameworkDir}`);}var withIosFrameworkFiles=exports.withIosFrameworkFiles=function withIosFrameworkFiles(config,props){return(0,_configPlugins.withDangerousMod)(config,['ios',(function(){var _ref=(0,_asyncToGenerator2.default)(function*(dangerousConfig){var iosDir=path.join(dangerousConfig.modRequest.projectRoot,'ios');createIosFramework(iosDir,props);return dangerousConfig;});return function(_x){return _ref.apply(this,arguments);};}())]);};
2
2
  //# sourceMappingURL=withIosFrameworkFiles.js.map