@hot-updater/react-native 0.21.12 → 0.21.14

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.
@@ -1,6 +1,6 @@
1
1
  import Foundation
2
2
 
3
- public enum BundleStorageError: Error {
3
+ public enum BundleStorageError: Error, CustomNSError {
4
4
  case bundleNotFound
5
5
  case directoryCreationFailed
6
6
  case downloadFailed(Error)
@@ -13,6 +13,92 @@ public enum BundleStorageError: Error {
13
13
  case copyOperationFailed(Error)
14
14
  case fileSystemError(Error)
15
15
  case unknown(Error?)
16
+
17
+ // CustomNSError protocol implementation
18
+ public static var errorDomain: String {
19
+ return "com.hotupdater.BundleStorageError"
20
+ }
21
+
22
+ public var errorCode: Int {
23
+ switch self {
24
+ case .bundleNotFound: return 1001
25
+ case .directoryCreationFailed: return 1002
26
+ case .downloadFailed: return 1003
27
+ case .extractionFailed: return 1004
28
+ case .invalidBundle: return 1005
29
+ case .invalidZipFile: return 1006
30
+ case .insufficientDiskSpace: return 1007
31
+ case .hashMismatch: return 1008
32
+ case .moveOperationFailed: return 1009
33
+ case .copyOperationFailed: return 1010
34
+ case .fileSystemError: return 1011
35
+ case .unknown: return 1099
36
+ }
37
+ }
38
+
39
+ public var errorUserInfo: [String: Any] {
40
+ var userInfo: [String: Any] = [:]
41
+
42
+ switch self {
43
+ case .bundleNotFound:
44
+ userInfo[NSLocalizedDescriptionKey] = "Bundle file not found in the downloaded archive"
45
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Ensure the bundle archive contains index.ios.bundle or main.jsbundle"
46
+
47
+ case .directoryCreationFailed:
48
+ userInfo[NSLocalizedDescriptionKey] = "Failed to create required directory for bundle storage"
49
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Check app permissions and available disk space"
50
+
51
+ case .downloadFailed(let underlyingError):
52
+ userInfo[NSLocalizedDescriptionKey] = "Failed to download bundle from server"
53
+ userInfo[NSUnderlyingErrorKey] = underlyingError
54
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Check network connection and try again"
55
+
56
+ case .extractionFailed(let underlyingError):
57
+ userInfo[NSLocalizedDescriptionKey] = "Failed to extract bundle archive"
58
+ userInfo[NSUnderlyingErrorKey] = underlyingError
59
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "The downloaded file may be corrupted. Try downloading again"
60
+
61
+ case .invalidBundle:
62
+ userInfo[NSLocalizedDescriptionKey] = "Downloaded archive does not contain a valid React Native bundle"
63
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Verify the bundle was built correctly with metro bundler"
64
+
65
+ case .invalidZipFile:
66
+ userInfo[NSLocalizedDescriptionKey] = "Downloaded file is not a valid ZIP archive"
67
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "The file may be corrupted during download"
68
+
69
+ case .insufficientDiskSpace:
70
+ userInfo[NSLocalizedDescriptionKey] = "Insufficient disk space to download and extract bundle"
71
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Free up device storage and try again"
72
+
73
+ case .hashMismatch:
74
+ userInfo[NSLocalizedDescriptionKey] = "Downloaded bundle hash does not match expected hash"
75
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "The file may have been corrupted or tampered with. Try downloading again"
76
+
77
+ case .moveOperationFailed(let underlyingError):
78
+ userInfo[NSLocalizedDescriptionKey] = "Failed to move bundle to final location"
79
+ userInfo[NSUnderlyingErrorKey] = underlyingError
80
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Check file system permissions"
81
+
82
+ case .copyOperationFailed(let underlyingError):
83
+ userInfo[NSLocalizedDescriptionKey] = "Failed to copy bundle files"
84
+ userInfo[NSUnderlyingErrorKey] = underlyingError
85
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Check available disk space and permissions"
86
+
87
+ case .fileSystemError(let underlyingError):
88
+ userInfo[NSLocalizedDescriptionKey] = "File system operation failed"
89
+ userInfo[NSUnderlyingErrorKey] = underlyingError
90
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Check app permissions and disk space"
91
+
92
+ case .unknown(let underlyingError):
93
+ userInfo[NSLocalizedDescriptionKey] = "An unknown error occurred during bundle update"
94
+ if let error = underlyingError {
95
+ userInfo[NSUnderlyingErrorKey] = error
96
+ }
97
+ userInfo[NSLocalizedRecoverySuggestionErrorKey] = "Please try again or contact support with error details"
98
+ }
99
+
100
+ return userInfo
101
+ }
16
102
  }
17
103
 
18
104
  /**
@@ -477,6 +563,35 @@ class BundleFileStorageService: BundleStorageService {
477
563
  }
478
564
  }
479
565
 
566
+ /**
567
+ * Logs detailed diagnostic information about a file system path.
568
+ * @param path The path to diagnose
569
+ * @param context Additional context for logging
570
+ */
571
+ private func logFileSystemDiagnostics(path: String, context: String) {
572
+ let fileManager = FileManager.default
573
+
574
+ // Check if path exists
575
+ let exists = fileManager.fileExists(atPath: path)
576
+ NSLog("[BundleStorage] [\(context)] Path exists: \(exists) - \(path)")
577
+
578
+ if exists {
579
+ do {
580
+ let attributes = try fileManager.attributesOfItem(atPath: path)
581
+ let size = attributes[.size] as? Int64 ?? 0
582
+ let permissions = attributes[.posixPermissions] as? Int ?? 0
583
+ NSLog("[BundleStorage] [\(context)] Size: \(size) bytes, Permissions: \(String(permissions, radix: 8))")
584
+ } catch {
585
+ NSLog("[BundleStorage] [\(context)] Failed to get attributes: \(error.localizedDescription)")
586
+ }
587
+ }
588
+
589
+ // Check parent directory
590
+ let parentPath = (path as NSString).deletingLastPathComponent
591
+ let parentExists = fileManager.fileExists(atPath: parentPath)
592
+ NSLog("[BundleStorage] [\(context)] Parent directory exists: \(parentExists) - \(parentPath)")
593
+ }
594
+
480
595
  /**
481
596
  * Processes a downloaded bundle file using the "tmp" rename approach.
482
597
  * This method is part of the asynchronous `updateBundle` flow and is expected to run on a background thread.
@@ -504,6 +619,7 @@ class BundleFileStorageService: BundleStorageService {
504
619
 
505
620
  // 1) Ensure the bundle file exists
506
621
  guard self.fileSystem.fileExists(atPath: location.path) else {
622
+ logFileSystemDiagnostics(path: location.path, context: "Download Location Missing")
507
623
  self.cleanupTemporaryFiles([tempDirectory])
508
624
  completion(.failure(BundleStorageError.fileSystemError(NSError(
509
625
  domain: "HotUpdaterError",
@@ -527,6 +643,7 @@ class BundleFileStorageService: BundleStorageService {
527
643
  // 4) Create tmpDir
528
644
  try self.fileSystem.createDirectory(atPath: tmpDir)
529
645
  NSLog("[BundleStorage] Created tmpDir: \(tmpDir)")
646
+ logFileSystemDiagnostics(path: tmpDir, context: "TmpDir Created")
530
647
 
531
648
  // 5) Verify file hash if provided
532
649
  if let expectedHash = fileHash {
@@ -544,14 +661,18 @@ class BundleFileStorageService: BundleStorageService {
544
661
 
545
662
  // 6) Unzip directly into tmpDir with progress tracking (0.8 - 1.0)
546
663
  NSLog("[BundleStorage] Extracting \(tempBundleFile) → \(tmpDir)")
664
+ logFileSystemDiagnostics(path: tempBundleFile, context: "Before Extraction")
547
665
  do {
548
666
  try self.decompressService.unzip(file: tempBundleFile, to: tmpDir, progressHandler: { unzipProgress in
549
667
  // Map unzip progress (0.0 - 1.0) to overall progress (0.8 - 1.0)
550
668
  progressHandler(0.8 + (unzipProgress * 0.2))
551
669
  })
552
670
  NSLog("[BundleStorage] Extraction complete at \(tmpDir)")
671
+ logFileSystemDiagnostics(path: tmpDir, context: "After Extraction")
553
672
  } catch {
554
- NSLog("[BundleStorage] Extraction failed: \(error.localizedDescription)")
673
+ let nsError = error as NSError
674
+ NSLog("[BundleStorage] Extraction failed - Domain: \(nsError.domain), Code: \(nsError.code), Description: \(nsError.localizedDescription)")
675
+ logFileSystemDiagnostics(path: tmpDir, context: "Extraction Failed")
555
676
  try? self.fileSystem.removeItem(atPath: tmpDir)
556
677
  self.cleanupTemporaryFiles([tempDirectory])
557
678
  completion(.failure(BundleStorageError.extractionFailed(error)))
@@ -565,6 +686,9 @@ class BundleFileStorageService: BundleStorageService {
565
686
  switch self.findBundleFile(in: tmpDir) {
566
687
  case .success(let maybeBundlePath):
567
688
  if let bundlePathInTmp = maybeBundlePath {
689
+ NSLog("[BundleStorage] Found valid bundle in tmpDir: \(bundlePathInTmp)")
690
+ logFileSystemDiagnostics(path: bundlePathInTmp, context: "Bundle Found")
691
+
568
692
  // 9) Remove any existing realDir
569
693
  if self.fileSystem.fileExists(atPath: realDir) {
570
694
  try self.fileSystem.removeItem(atPath: realDir)
@@ -572,8 +696,17 @@ class BundleFileStorageService: BundleStorageService {
572
696
  }
573
697
 
574
698
  // 10) Rename (move) tmpDir → realDir
575
- try self.fileSystem.moveItem(atPath: tmpDir, toPath: realDir)
576
- NSLog("[BundleStorage] Renamed tmpDir to realDir: \(realDir)")
699
+ do {
700
+ try self.fileSystem.moveItem(atPath: tmpDir, toPath: realDir)
701
+ NSLog("[BundleStorage] Renamed tmpDir to realDir: \(realDir)")
702
+ logFileSystemDiagnostics(path: realDir, context: "After Move")
703
+ } catch {
704
+ let nsError = error as NSError
705
+ NSLog("[BundleStorage] Move operation failed - Domain: \(nsError.domain), Code: \(nsError.code), Description: \(nsError.localizedDescription)")
706
+ logFileSystemDiagnostics(path: tmpDir, context: "Move Failed - Source")
707
+ logFileSystemDiagnostics(path: realDir, context: "Move Failed - Destination")
708
+ throw BundleStorageError.moveOperationFailed(error)
709
+ }
577
710
 
578
711
  // 11) Construct final bundlePath for preferences
579
712
  let finalBundlePath = (realDir as NSString).appendingPathComponent((bundlePathInTmp as NSString).lastPathComponent)
@@ -582,6 +715,7 @@ class BundleFileStorageService: BundleStorageService {
582
715
  let setResult = self.setBundleURL(localPath: finalBundlePath)
583
716
  switch setResult {
584
717
  case .success:
718
+ NSLog("[BundleStorage] Successfully set bundle URL: \(finalBundlePath)")
585
719
  // 13) Clean up the temporary directory
586
720
  self.cleanupTemporaryFiles([tempDirectory])
587
721
 
@@ -591,6 +725,8 @@ class BundleFileStorageService: BundleStorageService {
591
725
  // 15) Complete with success
592
726
  completion(.success(true))
593
727
  case .failure(let err):
728
+ let nsError = err as NSError
729
+ NSLog("[BundleStorage] Failed to set bundle URL - Domain: \(nsError.domain), Code: \(nsError.code), Description: \(nsError.localizedDescription)")
594
730
  // Preferences save failed → remove realDir and clean up
595
731
  try? self.fileSystem.removeItem(atPath: realDir)
596
732
  self.cleanupTemporaryFiles([tempDirectory])
@@ -598,11 +734,15 @@ class BundleFileStorageService: BundleStorageService {
598
734
  }
599
735
  } else {
600
736
  // No valid .jsbundle found → delete tmpDir and fail
737
+ NSLog("[BundleStorage] No valid bundle file found in tmpDir")
738
+ logFileSystemDiagnostics(path: tmpDir, context: "Invalid Bundle")
601
739
  try? self.fileSystem.removeItem(atPath: tmpDir)
602
740
  self.cleanupTemporaryFiles([tempDirectory])
603
741
  completion(.failure(BundleStorageError.invalidBundle))
604
742
  }
605
743
  case .failure(let findError):
744
+ let nsError = findError as NSError
745
+ NSLog("[BundleStorage] Error finding bundle file - Domain: \(nsError.domain), Code: \(nsError.code), Description: \(nsError.localizedDescription)")
606
746
  // Error scanning tmpDir → delete tmpDir and fail
607
747
  try? self.fileSystem.removeItem(atPath: tmpDir)
608
748
  self.cleanupTemporaryFiles([tempDirectory])
@@ -610,7 +750,9 @@ class BundleFileStorageService: BundleStorageService {
610
750
  }
611
751
  } catch let error {
612
752
  // Any failure during unzip or rename → clean tmpDir and fail
613
- NSLog("[BundleStorage] Error during tmpDir processing: \(error)")
753
+ let nsError = error as NSError
754
+ NSLog("[BundleStorage] Error during tmpDir processing - Domain: \(nsError.domain), Code: \(nsError.code), Description: \(nsError.localizedDescription)")
755
+ logFileSystemDiagnostics(path: tmpDir, context: "Processing Error")
614
756
  try? self.fileSystem.removeItem(atPath: tmpDir)
615
757
  self.cleanupTemporaryFiles([tempDirectory])
616
758
  completion(.failure(BundleStorageError.fileSystemError(error)))
@@ -174,15 +174,22 @@ import React
174
174
  NSLog("[HotUpdaterImpl] Update successful for \(bundleId). Resolving promise.")
175
175
  resolve(true)
176
176
  case .failure(let error):
177
- NSLog("[HotUpdaterImpl] Update failed for \(bundleId): \(error.localizedDescription). Rejecting promise.")
178
- reject("UPDATE_ERROR", error.localizedDescription, error)
177
+ let nsError = error as NSError
178
+ NSLog("[HotUpdaterImpl] Update failed for \(bundleId) - Domain: \(nsError.domain), Code: \(nsError.code), Description: \(nsError.localizedDescription)")
179
+
180
+ // Create a meaningful error code for React Native
181
+ let errorCode = "BUNDLE_STORAGE_ERROR_\(nsError.code)"
182
+ reject(errorCode, nsError.localizedDescription, nsError)
179
183
  }
180
184
  }
181
185
  }
182
186
  } catch let error {
183
187
  // Main error boundary - catch and convert all errors to JS rejection
184
- NSLog("[HotUpdaterImpl] Error in updateBundleFromJS: \(error.localizedDescription)")
185
- reject("UPDATE_ERROR", error.localizedDescription, error)
188
+ let nsError = error as NSError
189
+ NSLog("[HotUpdaterImpl] Error in updateBundleFromJS - Domain: \(nsError.domain), Code: \(nsError.code), Description: \(nsError.localizedDescription)")
190
+
191
+ let errorCode = "UPDATE_ERROR_\(nsError.code)"
192
+ reject(errorCode, nsError.localizedDescription, nsError)
186
193
  }
187
194
  }
188
195
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hot-updater/react-native",
3
- "version": "0.21.12",
3
+ "version": "0.21.14",
4
4
  "description": "React Native OTA solution for self-hosted",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -119,18 +119,18 @@
119
119
  "react-native": "0.79.1",
120
120
  "react-native-builder-bob": "^0.40.10",
121
121
  "typescript": "^5.8.3",
122
- "hot-updater": "0.21.12"
122
+ "hot-updater": "0.21.14"
123
123
  },
124
124
  "dependencies": {
125
125
  "use-sync-external-store": "1.5.0",
126
- "@hot-updater/cli-tools": "0.21.12",
127
- "@hot-updater/core": "0.21.12",
128
- "@hot-updater/js": "0.21.12",
129
- "@hot-updater/plugin-core": "0.21.12"
126
+ "@hot-updater/cli-tools": "0.21.14",
127
+ "@hot-updater/js": "0.21.14",
128
+ "@hot-updater/plugin-core": "0.21.14",
129
+ "@hot-updater/core": "0.21.14"
130
130
  },
131
131
  "scripts": {
132
- "build": "bob build && tsc -p plugin/tsconfig.json",
133
- "build:plugin": "tsc -p plugin/tsconfig.json",
132
+ "build": "bob build && tsc -p plugin/tsconfig.build.json",
133
+ "build:plugin": "tsc -p plugin/tsconfig.build.json",
134
134
  "test:type": "tsc --noEmit",
135
135
  "test": "vitest",
136
136
  "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
@@ -43,6 +43,7 @@ var cli_tools_1 = require("@hot-updater/cli-tools");
43
43
  var config_plugins_1 = require("expo/config-plugins");
44
44
  var hot_updater_1 = require("hot-updater");
45
45
  var package_json_1 = __importDefault(require("../../package.json"));
46
+ var transformers_1 = require("./transformers");
46
47
  var fingerprintCache = null;
47
48
  var getFingerprint = function () { return __awaiter(void 0, void 0, void 0, function () {
48
49
  return __generator(this, function (_a) {
@@ -61,35 +62,6 @@ var getFingerprint = function () { return __awaiter(void 0, void 0, void 0, func
61
62
  }
62
63
  });
63
64
  }); };
64
- /**
65
- * Helper to add lines if they don't exist, anchored by a specific string.
66
- */
67
- function addLinesOnce(contents, anchor, linesToAdd) {
68
- if (linesToAdd.every(function (line) { return contents.includes(line); })) {
69
- // All lines already exist, do nothing
70
- return contents;
71
- }
72
- // Check if the anchor exists
73
- if (!contents.includes(anchor)) {
74
- // Anchor not found, cannot add lines reliably.
75
- // Consider logging a warning or throwing an error here if necessary.
76
- return contents;
77
- }
78
- // Add lines after the anchor
79
- // Ensure newline separation
80
- return contents.replace(anchor, "".concat(anchor, "\n").concat(linesToAdd.join("\n")));
81
- }
82
- /**
83
- * Helper to replace content only if the target content exists and hasn't been replaced yet.
84
- */
85
- function replaceContentOnce(contents, searchRegex, replacement, checkIfAlreadyReplaced) {
86
- // If the replacement content is already present, assume it's done.
87
- if (contents.includes(checkIfAlreadyReplaced)) {
88
- return contents;
89
- }
90
- // Otherwise, perform the replacement if the search target exists.
91
- return contents.replace(searchRegex, replacement);
92
- }
93
65
  /**
94
66
  * Native code modifications - should only run once
95
67
  */
@@ -98,109 +70,14 @@ var withHotUpdaterNativeCode = function (config) {
98
70
  // === iOS: Objective-C & Swift in AppDelegate ===
99
71
  modifiedConfig = (0, config_plugins_1.withAppDelegate)(modifiedConfig, function (cfg) {
100
72
  var contents = cfg.modResults.contents;
101
- var iosImport = "#import <HotUpdater/HotUpdater.h>";
102
- var iosBundleUrl = "[HotUpdater bundleURL]";
103
- var iosOriginalBundleUrlRegex = /\[\[NSBundle mainBundle\] URLForResource:@"main" withExtension:@"jsbundle"\]/g;
104
- var iosAppDelegateHeader = '#import "AppDelegate.h"'; // Anchor for import
105
- var swiftImport = "import HotUpdater";
106
- var swiftBundleUrl = "HotUpdater.bundleURL()";
107
- var swiftOriginalBundleUrlRegex = /Bundle\.main\.url\(forResource: "?main"?, withExtension: "jsbundle"\)/g;
108
- var swiftReactImport = "import React"; // Anchor for import
109
- // --- Objective-C ---
110
- if (contents.includes(iosAppDelegateHeader)) {
111
- // Check if it's likely Obj-C
112
- // 1. Add import if missing
113
- contents = addLinesOnce(contents, iosAppDelegateHeader, [iosImport]);
114
- // 2. Replace bundleURL provider if the original exists and hasn't been replaced
115
- contents = replaceContentOnce(contents, iosOriginalBundleUrlRegex, iosBundleUrl, iosBundleUrl);
116
- }
117
- // --- Swift ---
118
- if (contents.includes(swiftReactImport)) {
119
- // Check if it's likely Swift
120
- // 1. Add import if missing
121
- contents = addLinesOnce(contents, swiftReactImport, [swiftImport]);
122
- // 2. Replace bundleURL provider if the original exists and hasn't been replaced
123
- contents = replaceContentOnce(contents, swiftOriginalBundleUrlRegex, swiftBundleUrl, swiftBundleUrl);
124
- }
73
+ contents = (0, transformers_1.transformIOS)(contents);
125
74
  cfg.modResults.contents = contents;
126
75
  return cfg;
127
76
  });
128
- // === Android: Kotlin & Java in MainApplication ===
77
+ // === Android: Kotlin in MainApplication ===
129
78
  modifiedConfig = (0, config_plugins_1.withMainApplication)(modifiedConfig, function (cfg) {
130
79
  var contents = cfg.modResults.contents;
131
- var kotlinImport = "import com.hotupdater.HotUpdater";
132
- var kotlinImportAnchor = "import com.facebook.react.ReactApplication";
133
- var kotlinReactNativeHostAnchor = "object : DefaultReactNativeHost(this) {"; // Start of block
134
- var kotlinMethodCheck = "HotUpdater.getJSBundleFile(applicationContext)"; // Unique part of the method body
135
- // Regex to find an existing getJSBundleFile override (non-greedy)
136
- var kotlinExistingMethodRegex = /^\s*override fun getJSBundleFile\(\): String\?\s*\{[\s\S]*?^\s*\}/gm;
137
- var kotlinHermesAnchor = "override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED";
138
- var kotlinNewArchAnchor = "override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED";
139
- var kotlinNewMethod = "\n override fun getJSBundleFile(): String? {\n return HotUpdater.getJSBundleFile(applicationContext)\n }";
140
- var javaImport = "import com.hotupdater.HotUpdater;";
141
- var javaImportAnchor = "import com.facebook.react.ReactApplication;";
142
- var javaReactNativeHostAnchor = "new DefaultReactNativeHost"; // Part of the instantiation
143
- var javaMethodCheck = "HotUpdater.Companion.getJSBundleFile"; // Unique part of the method body
144
- // Regex to find an existing getJSBundleFile override (non-greedy)
145
- var javaExistingMethodRegex = /^\s*@Override\s+protected String getJSBundleFile\(\)\s*\{[\s\S]*?^\s*\}/gm;
146
- var javaHermesBlockEndAnchor = "return BuildConfig.IS_HERMES_ENABLED;\n }"; // End of the isHermesEnabled method block
147
- var javaNewMethod = "\n @Override\n protected String getJSBundleFile() {\n return HotUpdater.Companion.getJSBundleFile(this.getApplication().getApplicationContext());\n }";
148
- // --- Kotlin ---
149
- if (contents.includes(kotlinReactNativeHostAnchor)) {
150
- // Check if likely Kotlin
151
- // 1. Add import if missing
152
- contents = addLinesOnce(contents, kotlinImportAnchor, [kotlinImport]);
153
- // 2. Add/Replace getJSBundleFile method if needed
154
- if (!contents.includes(kotlinMethodCheck)) {
155
- // Desired method content not found
156
- // Remove potentially existing (different) override first
157
- contents = contents.replace(kotlinExistingMethodRegex, "");
158
- // Add the new method after the isHermesEnabled property
159
- if (contents.includes(kotlinHermesAnchor)) {
160
- contents = contents.replace(kotlinHermesAnchor, "".concat(kotlinHermesAnchor, "\n").concat(kotlinNewMethod));
161
- }
162
- else if (contents.includes(kotlinNewArchAnchor)) {
163
- contents = contents.replace(kotlinNewArchAnchor, "".concat(kotlinNewArchAnchor, "\n").concat(kotlinNewMethod));
164
- }
165
- else {
166
- // Fallback: Add before the closing brace of the object if anchor not found
167
- var rnHostEndRegex = /(\s*object\s*:\s*DefaultReactNativeHost\s*\([\s\S]*?\n)(\s*\})\s*$/m;
168
- if (rnHostEndRegex.test(contents)) {
169
- contents = contents.replace(rnHostEndRegex, "$1".concat(kotlinNewMethod, "\n$2"));
170
- }
171
- else {
172
- throw new Error("[withHotUpdater] Kotlin: Could not find Hermes anchor or closing brace to insert getJSBundleFile.");
173
- }
174
- }
175
- }
176
- }
177
- // --- Java ---
178
- if (contents.includes(javaReactNativeHostAnchor) &&
179
- contents.includes("@Override")) {
180
- // Check if likely Java
181
- // 1. Add import if missing
182
- contents = addLinesOnce(contents, javaImportAnchor, [javaImport]);
183
- // 2. Add/Replace getJSBundleFile method if needed
184
- if (!contents.includes(javaMethodCheck)) {
185
- // Desired method content not found
186
- // Remove potentially existing (different) override first
187
- contents = contents.replace(javaExistingMethodRegex, "");
188
- // Add the new method after the isHermesEnabled method block
189
- if (contents.includes(javaHermesBlockEndAnchor)) {
190
- contents = contents.replace(javaHermesBlockEndAnchor, "".concat(javaHermesBlockEndAnchor, "\n").concat(javaNewMethod));
191
- }
192
- else {
193
- // Fallback: Add before the closing brace of the anonymous class
194
- var rnHostEndRegex = /(\s*new\s*DefaultReactNativeHost\s*\([\s\S]*?\n)(\s*\});\s*$/m;
195
- if (rnHostEndRegex.test(contents)) {
196
- contents = contents.replace(rnHostEndRegex, "$1".concat(javaNewMethod, "\n$2"));
197
- }
198
- else {
199
- throw new Error("[withHotUpdater] Java: Could not find Hermes anchor or closing brace to insert getJSBundleFile.");
200
- }
201
- }
202
- }
203
- }
80
+ contents = (0, transformers_1.transformAndroid)(contents);
204
81
  cfg.modResults.contents = contents;
205
82
  return cfg;
206
83
  });