@hot-updater/react-native 1.0.0-rc.2 → 1.0.0-rc.21
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.
- package/android/proguard-rules.pro +17 -2
- package/android/src/main/java/com/hotupdater/BuiltInAssetResolver.kt +286 -0
- package/android/src/main/java/com/hotupdater/BundleFileStorageService.kt +954 -837
- package/android/src/main/java/com/hotupdater/BundleMetadata.kt +15 -11
- package/android/src/main/java/com/hotupdater/FileManagerService.kt +45 -0
- package/android/src/main/java/com/hotupdater/HotUpdaterException.kt +287 -22
- package/android/src/main/java/com/hotupdater/HotUpdaterImpl.kt +43 -31
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryManager.kt +37 -54
- package/android/src/main/java/com/hotupdater/HotUpdaterRecoveryState.kt +64 -0
- package/android/src/main/java/com/hotupdater/InstallIdentityService.kt +37 -0
- package/android/src/main/java/com/hotupdater/KeyValueStorageService.kt +86 -0
- package/android/src/main/java/com/hotupdater/NetworkState.kt +31 -0
- package/android/src/main/java/com/hotupdater/NoBackupStorage.kt +17 -0
- package/android/src/main/java/com/hotupdater/OkHttpDownloadService.kt +127 -50
- package/android/src/main/java/com/hotupdater/PreviousProcessExit.kt +89 -0
- package/android/src/main/java/com/hotupdater/ReactNativeValueConverters.kt +34 -0
- package/android/src/main/java/com/hotupdater/TarArchiveInputStream.kt +214 -375
- package/android/src/main/java/com/hotupdater/TarBrArchiveExtractor.kt +119 -0
- package/android/src/newarch/HotUpdater.kt +7 -9
- package/android/src/newarch/HotUpdaterModule.kt +109 -84
- package/android/src/oldarch/HotUpdater.kt +7 -9
- package/android/src/oldarch/HotUpdaterModule.kt +98 -74
- package/android/src/oldarch/HotUpdaterSpec.kt +4 -6
- package/ios/HotUpdater/Internal/BrotliFileDecompressor.swift +167 -0
- package/ios/HotUpdater/Internal/BuiltInAssetResolver.swift +196 -0
- package/ios/HotUpdater/Internal/BundleFileStorageService.swift +950 -1112
- package/ios/HotUpdater/Internal/BundleMetadata.swift +8 -53
- package/ios/HotUpdater/Internal/FileManagerService.swift +48 -0
- package/ios/HotUpdater/Internal/FileUtilities.swift +64 -0
- package/ios/HotUpdater/Internal/HotUpdater-Bridging-Header.h +0 -1
- package/ios/HotUpdater/Internal/HotUpdater.mm +13 -45
- package/ios/HotUpdater/Internal/HotUpdaterImpl.swift +190 -73
- package/ios/HotUpdater/Internal/KeyValueStorageService.swift +71 -0
- package/ios/HotUpdater/Internal/NotificationExtension.swift +0 -2
- package/ios/HotUpdater/Internal/TarArchiveExtractor.swift +182 -311
- package/ios/HotUpdater/Internal/URLSessionDownloadService.swift +119 -71
- package/ios/HotUpdater/Internal/UpdateFailure.swift +390 -0
- package/ios/HotUpdater/Recovery/HotUpdaterRecovery.h +16 -0
- package/ios/HotUpdater/Recovery/HotUpdaterRecovery.mm +83 -0
- package/ios/HotUpdater/Recovery/HotUpdaterRecoveryHooks.mm +49 -0
- package/lib/commonjs/appReady.js +111 -0
- package/lib/commonjs/appReady.js.map +1 -0
- package/lib/commonjs/checkForUpdate.js +125 -70
- package/lib/commonjs/checkForUpdate.js.map +1 -1
- package/lib/commonjs/clientPlugin.js +13 -0
- package/lib/commonjs/clientPlugin.js.map +1 -0
- package/lib/commonjs/error.js +4 -13
- package/lib/commonjs/error.js.map +1 -1
- package/lib/commonjs/fetchJSON.js +5 -2
- package/lib/commonjs/fetchJSON.js.map +1 -1
- package/lib/commonjs/httpClient.js +55 -92
- package/lib/commonjs/httpClient.js.map +1 -1
- package/lib/commonjs/index.js +68 -20
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/native.js +82 -62
- package/lib/commonjs/native.js.map +1 -1
- package/lib/commonjs/pluginHost.js +44 -0
- package/lib/commonjs/pluginHost.js.map +1 -0
- package/lib/commonjs/releaseCatalogCache.js +20 -61
- package/lib/commonjs/releaseCatalogCache.js.map +1 -1
- package/lib/commonjs/sdkVersion.js +1 -1
- package/lib/commonjs/sdkVersion.js.map +1 -1
- package/lib/commonjs/specs/NativeHotUpdater.js.map +1 -1
- package/lib/commonjs/store.js +3 -10
- package/lib/commonjs/store.js.map +1 -1
- package/lib/commonjs/updateError.js +132 -0
- package/lib/commonjs/updateError.js.map +1 -0
- package/lib/commonjs/wrap.js +44 -27
- package/lib/commonjs/wrap.js.map +1 -1
- package/lib/module/appReady.js +103 -0
- package/lib/module/appReady.js.map +1 -0
- package/lib/module/checkForUpdate.js +118 -65
- package/lib/module/checkForUpdate.js.map +1 -1
- package/lib/module/clientPlugin.js +4 -0
- package/lib/module/clientPlugin.js.map +1 -0
- package/lib/module/error.js +4 -13
- package/lib/module/error.js.map +1 -1
- package/lib/module/fetchJSON.js +3 -1
- package/lib/module/fetchJSON.js.map +1 -1
- package/lib/module/httpClient.js +53 -90
- package/lib/module/httpClient.js.map +1 -1
- package/lib/module/index.js +55 -22
- package/lib/module/index.js.map +1 -1
- package/lib/module/native.js +74 -54
- package/lib/module/native.js.map +1 -1
- package/lib/module/pluginHost.js +35 -0
- package/lib/module/pluginHost.js.map +1 -0
- package/lib/module/releaseCatalogCache.js +16 -56
- package/lib/module/releaseCatalogCache.js.map +1 -1
- package/lib/module/sdkVersion.js +1 -1
- package/lib/module/sdkVersion.js.map +1 -1
- package/lib/module/specs/NativeHotUpdater.js.map +1 -1
- package/lib/module/store.js +3 -10
- package/lib/module/store.js.map +1 -1
- package/lib/module/updateError.js +126 -0
- package/lib/module/updateError.js.map +1 -0
- package/lib/module/wrap.js +45 -28
- package/lib/module/wrap.js.map +1 -1
- package/lib/typescript/commonjs/appReady.d.ts +23 -0
- package/lib/typescript/commonjs/appReady.d.ts.map +1 -0
- package/lib/typescript/commonjs/checkForUpdate.d.ts +16 -4
- package/lib/typescript/commonjs/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/commonjs/clientPlugin.d.ts +2 -0
- package/lib/typescript/commonjs/clientPlugin.d.ts.map +1 -0
- package/lib/typescript/commonjs/error.d.ts +4 -13
- package/lib/typescript/commonjs/error.d.ts.map +1 -1
- package/lib/typescript/commonjs/fetchJSON.d.ts +3 -0
- package/lib/typescript/commonjs/fetchJSON.d.ts.map +1 -1
- package/lib/typescript/commonjs/httpClient.d.ts +3 -32
- package/lib/typescript/commonjs/httpClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +7 -12
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/native.d.ts +33 -23
- package/lib/typescript/commonjs/native.d.ts.map +1 -1
- package/lib/typescript/commonjs/pluginHost.d.ts +4 -0
- package/lib/typescript/commonjs/pluginHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/releaseCatalogCache.d.ts +6 -14
- package/lib/typescript/commonjs/releaseCatalogCache.d.ts.map +1 -1
- package/lib/typescript/commonjs/sdkVersion.d.ts +1 -1
- package/lib/typescript/commonjs/sdkVersion.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts +42 -47
- package/lib/typescript/commonjs/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/commonjs/store.d.ts +1 -3
- package/lib/typescript/commonjs/store.d.ts.map +1 -1
- package/lib/typescript/commonjs/types.d.ts +1 -1
- package/lib/typescript/commonjs/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/updateError.d.ts +26 -0
- package/lib/typescript/commonjs/updateError.d.ts.map +1 -0
- package/lib/typescript/commonjs/wrap.d.ts.map +1 -1
- package/lib/typescript/commonjs/wrap.types.d.ts +6 -7
- package/lib/typescript/commonjs/wrap.types.d.ts.map +1 -1
- package/lib/typescript/module/appReady.d.ts +23 -0
- package/lib/typescript/module/appReady.d.ts.map +1 -0
- package/lib/typescript/module/checkForUpdate.d.ts +16 -4
- package/lib/typescript/module/checkForUpdate.d.ts.map +1 -1
- package/lib/typescript/module/clientPlugin.d.ts +2 -0
- package/lib/typescript/module/clientPlugin.d.ts.map +1 -0
- package/lib/typescript/module/error.d.ts +4 -13
- package/lib/typescript/module/error.d.ts.map +1 -1
- package/lib/typescript/module/fetchJSON.d.ts +3 -0
- package/lib/typescript/module/fetchJSON.d.ts.map +1 -1
- package/lib/typescript/module/httpClient.d.ts +3 -32
- package/lib/typescript/module/httpClient.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +7 -12
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/native.d.ts +33 -23
- package/lib/typescript/module/native.d.ts.map +1 -1
- package/lib/typescript/module/pluginHost.d.ts +4 -0
- package/lib/typescript/module/pluginHost.d.ts.map +1 -0
- package/lib/typescript/module/releaseCatalogCache.d.ts +6 -14
- package/lib/typescript/module/releaseCatalogCache.d.ts.map +1 -1
- package/lib/typescript/module/sdkVersion.d.ts +1 -1
- package/lib/typescript/module/sdkVersion.d.ts.map +1 -1
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts +42 -47
- package/lib/typescript/module/specs/NativeHotUpdater.d.ts.map +1 -1
- package/lib/typescript/module/store.d.ts +1 -3
- package/lib/typescript/module/store.d.ts.map +1 -1
- package/lib/typescript/module/types.d.ts +1 -1
- package/lib/typescript/module/types.d.ts.map +1 -1
- package/lib/typescript/module/updateError.d.ts +26 -0
- package/lib/typescript/module/updateError.d.ts.map +1 -0
- package/lib/typescript/module/wrap.d.ts.map +1 -1
- package/lib/typescript/module/wrap.types.d.ts +6 -7
- package/lib/typescript/module/wrap.types.d.ts.map +1 -1
- package/package.json +7 -4
- package/src/appReady.ts +149 -0
- package/src/checkForUpdate.ts +152 -89
- package/src/clientPlugin.ts +17 -0
- package/src/error.ts +4 -14
- package/src/fetchJSON.ts +5 -1
- package/src/httpClient.ts +78 -157
- package/src/index.ts +87 -29
- package/src/native.ts +109 -104
- package/src/pluginHost.ts +45 -0
- package/src/releaseCatalogCache.ts +26 -140
- package/src/sdkVersion.ts +1 -1
- package/src/specs/NativeHotUpdater.ts +41 -48
- package/src/store.ts +2 -23
- package/src/types.ts +1 -1
- package/src/updateError.ts +153 -0
- package/src/wrap.tsx +59 -28
- package/src/wrap.types.ts +6 -7
- package/android/src/main/java/com/hotupdater/DecompressService.kt +0 -89
- package/android/src/main/java/com/hotupdater/DecompressionStrategy.kt +0 -26
- package/android/src/main/java/com/hotupdater/TarBrDecompressionStrategy.kt +0 -117
- package/android/src/main/java/com/hotupdater/TarGzDecompressionStrategy.kt +0 -117
- package/android/src/main/java/com/hotupdater/ZipDecompressionStrategy.kt +0 -192
- package/android/src/test/java/com/hotupdater/BsdiffPatchTest.kt +0 -46
- package/android/src/test/java/com/hotupdater/BundleFileStorageServiceTest.kt +0 -799
- package/android/src/test/java/com/hotupdater/HotUpdaterImplTest.kt +0 -273
- package/android/src/test/java/com/hotupdater/NativeConfigUtilsTest.kt +0 -20
- package/android/src/test/java/com/hotupdater/OkHttpDownloadServiceTest.kt +0 -111
- package/android/src/test/java/com/hotupdater/RelativePathResolverTest.kt +0 -41
- package/android/src/test/java/com/hotupdater/ReleaseCatalogCacheServiceTest.kt +0 -118
- package/android/src/test/java/com/hotupdater/TarArchiveInputStreamTest.kt +0 -68
- package/ios/HotUpdater/Internal/ArchiveExtractionUtilities.swift +0 -178
- package/ios/HotUpdater/Internal/DecompressService.swift +0 -112
- package/ios/HotUpdater/Internal/DecompressionStrategy.swift +0 -22
- package/ios/HotUpdater/Internal/StreamingTarArchiveExtractor.swift +0 -370
- package/ios/HotUpdater/Internal/TarBrDecompressionStrategy.swift +0 -39
- package/ios/HotUpdater/Internal/TarGzDecompressionStrategy.swift +0 -59
- package/ios/HotUpdater/Internal/ZipArchiveExtractor.swift +0 -482
- package/ios/HotUpdater/Internal/ZipDecompressionStrategy.swift +0 -56
- package/lib/commonjs/catalogCacheNative.spec.js +0 -31
- package/lib/commonjs/catalogCacheNative.spec.js.map +0 -1
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js +0 -604
- package/lib/commonjs/checkForUpdate.releaseCatalog.spec.js.map +0 -1
- package/lib/commonjs/httpClient.spec.js +0 -102
- package/lib/commonjs/httpClient.spec.js.map +0 -1
- package/lib/commonjs/index.spec.js +0 -298
- package/lib/commonjs/index.spec.js.map +0 -1
- package/lib/commonjs/iosInterop.spec.js +0 -18
- package/lib/commonjs/iosInterop.spec.js.map +0 -1
- package/lib/commonjs/native.spec.js +0 -795
- package/lib/commonjs/native.spec.js.map +0 -1
- package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js +0 -218
- package/lib/commonjs/notifyAppReadyInsights.boundary.spec.js.map +0 -1
- package/lib/commonjs/notifyAppReadyInsights.js +0 -133
- package/lib/commonjs/notifyAppReadyInsights.js.map +0 -1
- package/lib/commonjs/notifyAppReadyInsights.spec.js +0 -246
- package/lib/commonjs/notifyAppReadyInsights.spec.js.map +0 -1
- package/lib/commonjs/notifyAppReadyInsights.test-utils.js +0 -24
- package/lib/commonjs/notifyAppReadyInsights.test-utils.js.map +0 -1
- package/lib/commonjs/notifyAppReadyInsights.transport.spec.js +0 -117
- package/lib/commonjs/notifyAppReadyInsights.transport.spec.js.map +0 -1
- package/lib/commonjs/releaseCatalogCache.spec.js +0 -195
- package/lib/commonjs/releaseCatalogCache.spec.js.map +0 -1
- package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js +0 -64
- package/lib/commonjs/releaseCatalogCacheNativeContract.spec.js.map +0 -1
- package/lib/commonjs/store.notification.spec.js +0 -76
- package/lib/commonjs/store.notification.spec.js.map +0 -1
- package/lib/commonjs/store.spec.js +0 -316
- package/lib/commonjs/store.spec.js.map +0 -1
- package/lib/commonjs/wrap.spec.js +0 -296
- package/lib/commonjs/wrap.spec.js.map +0 -1
- package/lib/module/catalogCacheNative.spec.js +0 -31
- package/lib/module/catalogCacheNative.spec.js.map +0 -1
- package/lib/module/checkForUpdate.releaseCatalog.spec.js +0 -603
- package/lib/module/checkForUpdate.releaseCatalog.spec.js.map +0 -1
- package/lib/module/httpClient.spec.js +0 -102
- package/lib/module/httpClient.spec.js.map +0 -1
- package/lib/module/index.spec.js +0 -297
- package/lib/module/index.spec.js.map +0 -1
- package/lib/module/iosInterop.spec.js +0 -18
- package/lib/module/iosInterop.spec.js.map +0 -1
- package/lib/module/native.spec.js +0 -794
- package/lib/module/native.spec.js.map +0 -1
- package/lib/module/notifyAppReadyInsights.boundary.spec.js +0 -217
- package/lib/module/notifyAppReadyInsights.boundary.spec.js.map +0 -1
- package/lib/module/notifyAppReadyInsights.js +0 -128
- package/lib/module/notifyAppReadyInsights.js.map +0 -1
- package/lib/module/notifyAppReadyInsights.spec.js +0 -245
- package/lib/module/notifyAppReadyInsights.spec.js.map +0 -1
- package/lib/module/notifyAppReadyInsights.test-utils.js +0 -18
- package/lib/module/notifyAppReadyInsights.test-utils.js.map +0 -1
- package/lib/module/notifyAppReadyInsights.transport.spec.js +0 -116
- package/lib/module/notifyAppReadyInsights.transport.spec.js.map +0 -1
- package/lib/module/releaseCatalogCache.spec.js +0 -195
- package/lib/module/releaseCatalogCache.spec.js.map +0 -1
- package/lib/module/releaseCatalogCacheNativeContract.spec.js +0 -64
- package/lib/module/releaseCatalogCacheNativeContract.spec.js.map +0 -1
- package/lib/module/store.notification.spec.js +0 -77
- package/lib/module/store.notification.spec.js.map +0 -1
- package/lib/module/store.spec.js +0 -315
- package/lib/module/store.spec.js.map +0 -1
- package/lib/module/wrap.spec.js +0 -295
- package/lib/module/wrap.spec.js.map +0 -1
- package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts +0 -13
- package/lib/typescript/commonjs/notifyAppReadyInsights.d.ts.map +0 -1
- package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts +0 -8
- package/lib/typescript/commonjs/notifyAppReadyInsights.test-utils.d.ts.map +0 -1
- package/lib/typescript/module/notifyAppReadyInsights.d.ts +0 -13
- package/lib/typescript/module/notifyAppReadyInsights.d.ts.map +0 -1
- package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts +0 -8
- package/lib/typescript/module/notifyAppReadyInsights.test-utils.d.ts.map +0 -1
- package/src/catalogCacheNative.spec.ts +0 -63
- package/src/checkForUpdate.releaseCatalog.spec.ts +0 -596
- package/src/httpClient.spec.ts +0 -132
- package/src/index.spec.ts +0 -331
- package/src/iosInterop.spec.ts +0 -30
- package/src/native.spec.ts +0 -855
- package/src/notifyAppReadyInsights.boundary.spec.ts +0 -234
- package/src/notifyAppReadyInsights.spec.ts +0 -243
- package/src/notifyAppReadyInsights.test-utils.ts +0 -31
- package/src/notifyAppReadyInsights.transport.spec.ts +0 -130
- package/src/notifyAppReadyInsights.ts +0 -194
- package/src/releaseCatalogCache.spec.ts +0 -282
- package/src/releaseCatalogCacheNativeContract.spec.ts +0 -80
- package/src/store.notification.spec.ts +0 -92
- package/src/store.spec.ts +0 -372
- package/src/wrap.spec.ts +0 -367
|
@@ -84,6 +84,7 @@ public struct BundleMetadata: Codable {
|
|
|
84
84
|
var stableSelection: PersistedSelection?
|
|
85
85
|
var stagingSelection: PersistedSelection?
|
|
86
86
|
var verificationPending: Bool
|
|
87
|
+
var launchInProgress: Bool
|
|
87
88
|
var pendingTransition: PendingBundleTransition?
|
|
88
89
|
var pendingSelectionTransition: PendingSelectionTransition?
|
|
89
90
|
var highestSeenCatalogs: [String: CatalogHighWater]
|
|
@@ -98,6 +99,7 @@ public struct BundleMetadata: Codable {
|
|
|
98
99
|
case stableSelection = "stable_selection"
|
|
99
100
|
case stagingSelection = "staging_selection"
|
|
100
101
|
case verificationPending = "verification_pending"
|
|
102
|
+
case launchInProgress = "launch_in_progress"
|
|
101
103
|
case pendingTransition = "pending_transition"
|
|
102
104
|
case pendingSelectionTransition = "pending_selection_transition"
|
|
103
105
|
case highestSeenCatalogs = "highest_seen_catalogs"
|
|
@@ -113,6 +115,7 @@ public struct BundleMetadata: Codable {
|
|
|
113
115
|
stableSelection: PersistedSelection? = nil,
|
|
114
116
|
stagingSelection: PersistedSelection? = nil,
|
|
115
117
|
verificationPending: Bool = false,
|
|
118
|
+
launchInProgress: Bool = false,
|
|
116
119
|
pendingTransition: PendingBundleTransition? = nil,
|
|
117
120
|
pendingSelectionTransition: PendingSelectionTransition? = nil,
|
|
118
121
|
highestSeenCatalogs: [String: CatalogHighWater] = [:],
|
|
@@ -126,6 +129,7 @@ public struct BundleMetadata: Codable {
|
|
|
126
129
|
self.stableSelection = stableSelection
|
|
127
130
|
self.stagingSelection = stagingSelection
|
|
128
131
|
self.verificationPending = verificationPending
|
|
132
|
+
self.launchInProgress = launchInProgress
|
|
129
133
|
self.pendingTransition = pendingTransition
|
|
130
134
|
self.pendingSelectionTransition = pendingSelectionTransition
|
|
131
135
|
self.highestSeenCatalogs = highestSeenCatalogs
|
|
@@ -144,6 +148,7 @@ public struct BundleMetadata: Codable {
|
|
|
144
148
|
stagingSelection = try values.decodeIfPresent(PersistedSelection.self, forKey: .stagingSelection)
|
|
145
149
|
?? stagingBundleId.map(PersistedSelection.legacyBundle)
|
|
146
150
|
verificationPending = try values.decodeIfPresent(Bool.self, forKey: .verificationPending) ?? false
|
|
151
|
+
launchInProgress = try values.decodeIfPresent(Bool.self, forKey: .launchInProgress) ?? false
|
|
147
152
|
pendingTransition = try values.decodeIfPresent(PendingBundleTransition.self, forKey: .pendingTransition)
|
|
148
153
|
pendingSelectionTransition = try values.decodeIfPresent(PendingSelectionTransition.self, forKey: .pendingSelectionTransition)
|
|
149
154
|
highestSeenCatalogs = try values.decodeIfPresent([String: CatalogHighWater].self, forKey: .highestSeenCatalogs) ?? [:]
|
|
@@ -378,6 +383,8 @@ public struct LaunchReport: Codable {
|
|
|
378
383
|
}
|
|
379
384
|
}
|
|
380
385
|
|
|
386
|
+
/// The random id created once per app installation. It lives in
|
|
387
|
+
/// `NoBackupStorage`, so a device backup never carries it to another device.
|
|
381
388
|
public struct InstallIdentity: Codable {
|
|
382
389
|
static let installIdentityFilename = "install-identity.json"
|
|
383
390
|
|
|
@@ -407,11 +414,7 @@ public struct InstallIdentity: Codable {
|
|
|
407
414
|
let encoder = JSONEncoder()
|
|
408
415
|
encoder.outputFormatting = .prettyPrinted
|
|
409
416
|
let data = try encoder.encode(self)
|
|
410
|
-
|
|
411
|
-
if !FileManager.default.fileExists(atPath: directory.path) {
|
|
412
|
-
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
413
|
-
}
|
|
414
|
-
try data.write(to: file)
|
|
417
|
+
try NoBackupStorage.write(data, to: file)
|
|
415
418
|
return true
|
|
416
419
|
} catch {
|
|
417
420
|
print("[InstallIdentity] Failed to save install identity: \(error)")
|
|
@@ -419,51 +422,3 @@ public struct InstallIdentity: Codable {
|
|
|
419
422
|
}
|
|
420
423
|
}
|
|
421
424
|
}
|
|
422
|
-
|
|
423
|
-
public struct UserIdentity: Codable {
|
|
424
|
-
static let userIdentityFilename = "user-identity.json"
|
|
425
|
-
|
|
426
|
-
let userId: String?
|
|
427
|
-
let username: String?
|
|
428
|
-
|
|
429
|
-
init(userId: String?, username: String?) {
|
|
430
|
-
self.userId = userId
|
|
431
|
-
self.username = username
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
var isEmpty: Bool {
|
|
435
|
-
userId == nil && username == nil
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
static func load(from file: URL) -> UserIdentity? {
|
|
439
|
-
guard FileManager.default.fileExists(atPath: file.path) else {
|
|
440
|
-
return nil
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
do {
|
|
444
|
-
let data = try Data(contentsOf: file)
|
|
445
|
-
let identity = try JSONDecoder().decode(UserIdentity.self, from: data)
|
|
446
|
-
return identity.isEmpty ? nil : identity
|
|
447
|
-
} catch {
|
|
448
|
-
print("[UserIdentity] Failed to load user identity: \(error)")
|
|
449
|
-
return nil
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
func save(to file: URL) -> Bool {
|
|
454
|
-
do {
|
|
455
|
-
let encoder = JSONEncoder()
|
|
456
|
-
encoder.outputFormatting = .prettyPrinted
|
|
457
|
-
let data = try encoder.encode(self)
|
|
458
|
-
let directory = file.deletingLastPathComponent()
|
|
459
|
-
if !FileManager.default.fileExists(atPath: directory.path) {
|
|
460
|
-
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
|
|
461
|
-
}
|
|
462
|
-
try data.write(to: file)
|
|
463
|
-
return true
|
|
464
|
-
} catch {
|
|
465
|
-
print("[UserIdentity] Failed to save user identity: \(error)")
|
|
466
|
-
return false
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
@@ -17,6 +17,45 @@ protocol FileSystemService {
|
|
|
17
17
|
func contentsOfDirectory(atPath path: String) throws -> [String]
|
|
18
18
|
func attributesOfItem(atPath path: String) throws -> [FileAttributeKey: Any]
|
|
19
19
|
func documentsPath() -> String
|
|
20
|
+
/// Base directory for data that lives as long as the installation.
|
|
21
|
+
func applicationSupportPath() -> String
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// `Application Support/HotUpdater`: data the SDK keeps for the life of an
|
|
25
|
+
/// installation, such as the install id and plugin storage. Device backups
|
|
26
|
+
/// skip it, so restoring a backup onto another device never copies it there.
|
|
27
|
+
enum NoBackupStorage {
|
|
28
|
+
static let directoryName = "HotUpdater"
|
|
29
|
+
|
|
30
|
+
static func directory(in fileSystem: FileSystemService) -> URL {
|
|
31
|
+
URL(fileURLWithPath: fileSystem.applicationSupportPath(), isDirectory: true)
|
|
32
|
+
.appendingPathComponent(directoryName, isDirectory: true)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/// Atomically replaces `file` with `data`, creating its directory when
|
|
36
|
+
/// needed, and excludes the directory and the file from device backups.
|
|
37
|
+
static func write(_ data: Data, to file: URL) throws {
|
|
38
|
+
let directory = file.deletingLastPathComponent()
|
|
39
|
+
try FileManager.default.createDirectory(
|
|
40
|
+
at: directory,
|
|
41
|
+
withIntermediateDirectories: true
|
|
42
|
+
)
|
|
43
|
+
excludeFromBackup(directory)
|
|
44
|
+
try data.write(to: file, options: .atomic)
|
|
45
|
+
// An atomic write replaces the file, which drops its previous flag.
|
|
46
|
+
excludeFromBackup(file)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static func excludeFromBackup(_ url: URL) {
|
|
50
|
+
var url = url
|
|
51
|
+
var values = URLResourceValues()
|
|
52
|
+
values.isExcludedFromBackup = true
|
|
53
|
+
do {
|
|
54
|
+
try url.setResourceValues(values)
|
|
55
|
+
} catch {
|
|
56
|
+
NSLog("[NoBackupStorage] Failed to exclude \(url.path) from backups: \(error)")
|
|
57
|
+
}
|
|
58
|
+
}
|
|
20
59
|
}
|
|
21
60
|
|
|
22
61
|
class FileManagerService: FileSystemService {
|
|
@@ -89,4 +128,13 @@ class FileManagerService: FileSystemService {
|
|
|
89
128
|
return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
|
90
129
|
#endif
|
|
91
130
|
}
|
|
131
|
+
|
|
132
|
+
func applicationSupportPath() -> String {
|
|
133
|
+
#if os(tvOS)
|
|
134
|
+
// tvOS apps can only write purgeable files, so use Caches like documentsPath().
|
|
135
|
+
return NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
|
|
136
|
+
#else
|
|
137
|
+
return NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)[0]
|
|
138
|
+
#endif
|
|
139
|
+
}
|
|
92
140
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
enum FileUtilities {
|
|
4
|
+
static func readUpToCount(from handle: FileHandle, count: Int) throws -> Data? {
|
|
5
|
+
guard count >= 0 else {
|
|
6
|
+
throw NSError(
|
|
7
|
+
domain: "FileUtilities",
|
|
8
|
+
code: 1,
|
|
9
|
+
userInfo: [NSLocalizedDescriptionKey: "Invalid read size: \(count)"]
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if count == 0 {
|
|
14
|
+
return Data()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if #available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) {
|
|
18
|
+
return try handle.read(upToCount: count)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return handle.readData(ofLength: count)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static func normalizedRelativePath(from rawPath: String) -> String? {
|
|
25
|
+
let candidate = rawPath.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
26
|
+
guard !candidate.isEmpty,
|
|
27
|
+
!candidate.contains("\0"),
|
|
28
|
+
!candidate.contains("\\"),
|
|
29
|
+
!candidate.hasPrefix("/"),
|
|
30
|
+
candidate.range(of: #"^[A-Za-z]:"#, options: .regularExpression) == nil
|
|
31
|
+
else {
|
|
32
|
+
return nil
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let components = candidate.split(separator: "/").map(String.init)
|
|
36
|
+
guard !components.isEmpty,
|
|
37
|
+
components.count == candidate.split(separator: "/", omittingEmptySubsequences: false).count,
|
|
38
|
+
!components.contains(".."),
|
|
39
|
+
!components.contains(".")
|
|
40
|
+
else {
|
|
41
|
+
return nil
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return components.joined(separator: "/")
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static func fileURL(for relativePath: String, destinationRoot: String) throws -> URL {
|
|
48
|
+
let rootURL = URL(fileURLWithPath: destinationRoot, isDirectory: true)
|
|
49
|
+
let targetURL = rootURL.appendingPathComponent(relativePath)
|
|
50
|
+
let standardizedRoot = rootURL.standardizedFileURL.path
|
|
51
|
+
let standardizedTarget = targetURL.standardizedFileURL.path
|
|
52
|
+
|
|
53
|
+
guard standardizedTarget == standardizedRoot ||
|
|
54
|
+
standardizedTarget.hasPrefix(standardizedRoot + "/") else {
|
|
55
|
+
throw NSError(
|
|
56
|
+
domain: "FileUtilities",
|
|
57
|
+
code: 2,
|
|
58
|
+
userInfo: [NSLocalizedDescriptionKey: "Path traversal attempt detected: \(relativePath)"]
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return targetURL
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
#import "React/RCTConstants.h"
|
|
8
8
|
#import "React/RCTRootView.h"
|
|
9
9
|
#import "React/RCTUtils.h" // Needed for RCTPromiseResolveBlock/RejectBlock in Swift
|
|
10
|
-
#import <SSZipArchive/SSZipArchive.h>
|
|
11
10
|
#import "BsdiffPatchBridge.h"
|
|
12
11
|
|
|
13
12
|
@interface HotUpdaterRecoverySignalBridge : NSObject
|
|
@@ -274,8 +274,6 @@ extern "C" void *HotUpdaterCopyMinBundleId(void)
|
|
|
274
274
|
|
|
275
275
|
|
|
276
276
|
// Define Notification names used for observing Swift Core
|
|
277
|
-
NSNotificationName const HotUpdaterDownloadProgressUpdateNotification = @"HotUpdaterDownloadProgressUpdate";
|
|
278
|
-
NSNotificationName const HotUpdaterDownloadDidFinishNotification = @"HotUpdaterDownloadDidFinish";
|
|
279
277
|
NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUpdaterUpdateProgressDidChange";
|
|
280
278
|
|
|
281
279
|
@interface HotUpdaterRecoverySignalBridge : NSObject
|
|
@@ -300,8 +298,6 @@ NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUp
|
|
|
300
298
|
|
|
301
299
|
@implementation HotUpdater {
|
|
302
300
|
bool hasListeners;
|
|
303
|
-
// Keep track of tasks ONLY for removing observers when this ObjC instance is invalidated
|
|
304
|
-
NSMutableSet<NSURLSessionTask *> *observedTasks; // Changed to NSURLSessionTask for broader compatibility if needed
|
|
305
301
|
}
|
|
306
302
|
|
|
307
303
|
@synthesize bridge = _bridge;
|
|
@@ -314,16 +310,10 @@ NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUp
|
|
|
314
310
|
- (instancetype)init {
|
|
315
311
|
self = [super init];
|
|
316
312
|
if (self) {
|
|
317
|
-
observedTasks = [NSMutableSet set];
|
|
318
|
-
|
|
319
313
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
320
314
|
selector:@selector(handleDownloadProgress:)
|
|
321
315
|
name:HotUpdaterUpdateProgressDidChangeNotification
|
|
322
316
|
object:nil];
|
|
323
|
-
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
324
|
-
selector:@selector(handleDownloadCompletion:)
|
|
325
|
-
name:HotUpdaterDownloadDidFinishNotification
|
|
326
|
-
object:nil];
|
|
327
317
|
|
|
328
318
|
_lastUpdateTime = 0;
|
|
329
319
|
}
|
|
@@ -349,7 +339,6 @@ NSNotificationName const HotUpdaterUpdateProgressDidChangeNotification = @"HotUp
|
|
|
349
339
|
if (gHotUpdaterBridge == self.bridge) {
|
|
350
340
|
gHotUpdaterBridge = nil;
|
|
351
341
|
}
|
|
352
|
-
// Swift side should handle KVO observer removal for its tasks
|
|
353
342
|
[super invalidate];
|
|
354
343
|
}
|
|
355
344
|
|
|
@@ -520,14 +509,6 @@ RCT_EXPORT_MODULE();
|
|
|
520
509
|
}
|
|
521
510
|
}
|
|
522
511
|
|
|
523
|
-
- (void)handleDownloadCompletion:(NSNotification *)notification {
|
|
524
|
-
NSURLSessionTask *task = notification.object; // Task that finished
|
|
525
|
-
RCTLogInfo(@"[HotUpdater.mm] Received download completion notification for task: %@", task.originalRequest.URL);
|
|
526
|
-
// Swift side handles KVO observer removal internally now when task finishes.
|
|
527
|
-
// No specific cleanup needed here based on this notification anymore.
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
|
|
531
512
|
#pragma mark - React Native Events (Keep as is)
|
|
532
513
|
|
|
533
514
|
- (NSArray<NSString *> *)supportedEvents {
|
|
@@ -594,20 +575,17 @@ RCT_EXPORT_MODULE();
|
|
|
594
575
|
if (params.bundleId()) {
|
|
595
576
|
paramDict[@"bundleId"] = params.bundleId();
|
|
596
577
|
}
|
|
597
|
-
if (params.fileUrl()) {
|
|
598
|
-
paramDict[@"fileUrl"] = params.fileUrl();
|
|
599
|
-
}
|
|
600
|
-
if (params.fileHash()) {
|
|
601
|
-
paramDict[@"fileHash"] = params.fileHash();
|
|
602
|
-
}
|
|
603
578
|
if (params.manifestUrl()) {
|
|
604
579
|
paramDict[@"manifestUrl"] = params.manifestUrl();
|
|
605
580
|
}
|
|
606
581
|
if (params.manifestFileHash()) {
|
|
607
582
|
paramDict[@"manifestFileHash"] = params.manifestFileHash();
|
|
608
583
|
}
|
|
609
|
-
if (params.
|
|
610
|
-
paramDict[@"
|
|
584
|
+
if (params.archiveUrl()) {
|
|
585
|
+
paramDict[@"archiveUrl"] = params.archiveUrl();
|
|
586
|
+
}
|
|
587
|
+
if (params.assets()) {
|
|
588
|
+
paramDict[@"assets"] = params.assets();
|
|
611
589
|
}
|
|
612
590
|
if (params.channel()) {
|
|
613
591
|
paramDict[@"channel"] = params.channel();
|
|
@@ -682,19 +660,14 @@ RCT_EXPORT_MODULE();
|
|
|
682
660
|
return [impl getInstallId];
|
|
683
661
|
}
|
|
684
662
|
|
|
685
|
-
- (NSString * _Nullable)
|
|
686
|
-
HotUpdaterImpl *impl = [HotUpdater sharedImpl];
|
|
687
|
-
return [impl getUserId];
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
- (NSString * _Nullable)getUsername {
|
|
663
|
+
- (NSString * _Nullable)getStorageItem:(NSString *)key {
|
|
691
664
|
HotUpdaterImpl *impl = [HotUpdater sharedImpl];
|
|
692
|
-
return [impl
|
|
665
|
+
return [impl getStorageItem:key];
|
|
693
666
|
}
|
|
694
667
|
|
|
695
|
-
- (void)
|
|
668
|
+
- (void)setStorageItem:(NSString *)key value:(NSString * _Nullable)value {
|
|
696
669
|
HotUpdaterImpl *impl = [HotUpdater sharedImpl];
|
|
697
|
-
[impl
|
|
670
|
+
[impl setStorageItem:key value:value];
|
|
698
671
|
}
|
|
699
672
|
|
|
700
673
|
- (NSString * _Nullable)getBaseURL {
|
|
@@ -852,19 +825,14 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getInstallId) {
|
|
|
852
825
|
return [impl getInstallId];
|
|
853
826
|
}
|
|
854
827
|
|
|
855
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(
|
|
856
|
-
HotUpdaterImpl *impl = [HotUpdater sharedImpl];
|
|
857
|
-
return [impl getUserId];
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getUsername) {
|
|
828
|
+
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getStorageItem:(NSString *)key) {
|
|
861
829
|
HotUpdaterImpl *impl = [HotUpdater sharedImpl];
|
|
862
|
-
return [impl
|
|
830
|
+
return [impl getStorageItem:key];
|
|
863
831
|
}
|
|
864
832
|
|
|
865
|
-
RCT_EXPORT_METHOD(
|
|
833
|
+
RCT_EXPORT_METHOD(setStorageItem:(NSString *)key value:(NSString * _Nullable)value) {
|
|
866
834
|
HotUpdaterImpl *impl = [HotUpdater sharedImpl];
|
|
867
|
-
[impl
|
|
835
|
+
[impl setStorageItem:key value:value];
|
|
868
836
|
}
|
|
869
837
|
|
|
870
838
|
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getBaseURL) {
|