expo-updates 1.0.0-canary-20250207-8bc5146 → 1.0.0-canary-20250219-4a5dade
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/CHANGELOG.md +4 -0
- package/android/build.gradle +26 -15
- package/android/src/main/java/expo/modules/updates/UpdatesUtils.kt +1 -1
- package/android/src/main/java/expo/modules/updates/launcher/DatabaseLauncher.kt +10 -4
- package/android/src/main/java/expo/modules/updates/loader/EmbeddedLoader.kt +3 -0
- package/android/src/main/java/expo/modules/updates/loader/FileDownloader.kt +24 -1
- package/android/src/main/java/expo/modules/updates/loader/Loader.kt +9 -2
- package/android/src/main/java/expo/modules/updates/loader/LoaderFiles.kt +1 -1
- package/android/src/main/java/expo/modules/updates/loader/RemoteLoader.kt +4 -1
- package/e2e/setup/project.ts +2 -0
- package/ios/EXUpdates/AppLoader/AppLoader.swift +10 -3
- package/ios/EXUpdates/AppLoader/EmbeddedAppLoader.swift +1 -1
- package/ios/EXUpdates/AppLoader/FileDownloader.swift +24 -0
- package/ios/EXUpdates/AppLoader/RemoteAppLoader.swift +2 -3
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
- fix E2E tests in Detox debug build ([#32951](https://github.com/expo/expo/pull/32951) by [@matejkriz](https://github.com/matejkriz))
|
|
19
19
|
- Fix issue where syncing codesigning config for bare projects would clobber existing Expo.plist config ([#34597](https://github.com/expo/expo/pull/34597) by [@brentvatne](https://github.com/brentvatne))
|
|
20
20
|
- Removed Apache Commons IO dependency and fixed crash issue on Android 7. ([#34638](https://github.com/expo/expo/pull/34638) by [@kudo](https://github.com/kudo))
|
|
21
|
+
- [Android] Fix `bytesToHex` `ArrayIndexOutOfBoundsException` during conversion. ([#34855](https://github.com/expo/expo/pull/34855) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
21
22
|
|
|
22
23
|
### 💡 Others
|
|
23
24
|
|
|
@@ -26,6 +27,9 @@
|
|
|
26
27
|
- [apple] Migrate remaining `expo-module.config.json` to unified platform syntax. ([#34445](https://github.com/expo/expo/pull/34445) by [@reichhartd](https://github.com/reichhartd))
|
|
27
28
|
- Fixed build error on iOS Expo Go. ([#34485](https://github.com/expo/expo/pull/34485) by [@kudo](https://github.com/kudo))
|
|
28
29
|
- Fixed Android unit test errors in BuilDataTest. ([#34510](https://github.com/expo/expo/pull/34510) by [@kudo](https://github.com/kudo))
|
|
30
|
+
- Fixed incorrect error log on Android. ([#34785](https://github.com/expo/expo/pull/34785) by [@kudo](https://github.com/kudo))
|
|
31
|
+
- [Android] Started using expo modules gradle plugin. ([#34806](https://github.com/expo/expo/pull/34806) by [@lukmccall](https://github.com/lukmccall))
|
|
32
|
+
- Add update id headers to asset requests ([#34453](https://github.com/expo/expo/pull/34453) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
29
33
|
|
|
30
34
|
## 0.26.10 - 2024-12-05
|
|
31
35
|
|
package/android/build.gradle
CHANGED
|
@@ -1,31 +1,42 @@
|
|
|
1
1
|
buildscript {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ext {
|
|
3
|
+
boolish = { value ->
|
|
4
|
+
return value.toString().toBoolean()
|
|
5
|
+
}
|
|
6
|
+
getKspVersion = {
|
|
7
|
+
if (rootProject.hasProperty("kspVersion")) {
|
|
8
|
+
return rootProject["kspVersion"]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// We can remove this path once we update the test environment
|
|
12
|
+
// to use the same version of Kotlin as the `expo/expo` repo.
|
|
13
|
+
def kotlinVersion = rootProject["kotlinVersion"]
|
|
14
|
+
if (kotlinVersion == "2.0.21") {
|
|
15
|
+
return "2.0.21-1.0.28"
|
|
16
|
+
} else if (kotlinVersion == "1.9.25") {
|
|
17
|
+
return "1.9.25-1.0.20"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return "1.9.24-1.0.20"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
5
23
|
|
|
6
24
|
repositories {
|
|
7
25
|
mavenCentral()
|
|
8
26
|
}
|
|
9
27
|
|
|
10
28
|
dependencies {
|
|
11
|
-
classpath "com.google.devtools.ksp:symbol-processing-gradle-plugin:${
|
|
29
|
+
classpath "com.google.devtools.ksp:symbol-processing-gradle-plugin:${getKspVersion()}"
|
|
12
30
|
}
|
|
13
31
|
}
|
|
14
32
|
|
|
15
33
|
apply plugin: 'com.android.library'
|
|
34
|
+
apply plugin: 'expo-module-gradle-plugin'
|
|
16
35
|
apply plugin: 'com.google.devtools.ksp'
|
|
17
36
|
|
|
18
37
|
group = 'host.exp.exponent'
|
|
19
38
|
version = '0.26.9'
|
|
20
39
|
|
|
21
|
-
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
22
|
-
apply from: expoModulesCorePlugin
|
|
23
|
-
applyKotlinExpoModulesCorePlugin()
|
|
24
|
-
applyKspJvmToolchain()
|
|
25
|
-
useCoreDependencies()
|
|
26
|
-
useDefaultAndroidSdkVersions()
|
|
27
|
-
useExpoPublishing()
|
|
28
|
-
|
|
29
40
|
// Utility method to derive boolean values from the environment or from Java properties,
|
|
30
41
|
// and return them as strings to be used in BuildConfig fields
|
|
31
42
|
def getBoolStringFromPropOrEnv(String name, Boolean defaultValue) {
|
|
@@ -117,7 +128,7 @@ dependencies {
|
|
|
117
128
|
testImplementation 'junit:junit:4.13.2'
|
|
118
129
|
testImplementation 'androidx.test:core:1.5.0'
|
|
119
130
|
testImplementation "io.mockk:mockk:$mockk_version"
|
|
120
|
-
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion
|
|
131
|
+
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion}"
|
|
121
132
|
testImplementation 'org.robolectric:robolectric:4.14.1'
|
|
122
133
|
|
|
123
134
|
androidTestImplementation 'com.squareup.okio:okio:2.9.0'
|
|
@@ -126,7 +137,7 @@ dependencies {
|
|
|
126
137
|
androidTestImplementation 'androidx.test:rules:1.5.0'
|
|
127
138
|
androidTestImplementation "io.mockk:mockk-android:$mockk_version"
|
|
128
139
|
androidTestImplementation "androidx.room:room-testing:$room_version"
|
|
129
|
-
androidTestImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion
|
|
140
|
+
androidTestImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion}"
|
|
130
141
|
|
|
131
|
-
implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion
|
|
142
|
+
implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}"
|
|
132
143
|
}
|
|
@@ -185,7 +185,7 @@ object UpdatesUtils {
|
|
|
185
185
|
fun bytesToHex(bytes: ByteArray): String {
|
|
186
186
|
val hexChars = CharArray(bytes.size * 2)
|
|
187
187
|
for (j in bytes.indices) {
|
|
188
|
-
val v =
|
|
188
|
+
val v = bytes[j].toInt() and 0xFF
|
|
189
189
|
hexChars[j * 2] = HEX_ARRAY[v ushr 4]
|
|
190
190
|
hexChars[j * 2 + 1] = HEX_ARRAY[v and 0x0F]
|
|
191
191
|
}
|
|
@@ -15,8 +15,10 @@ import expo.modules.updates.loader.LoaderFiles
|
|
|
15
15
|
import expo.modules.updates.logging.UpdatesErrorCode
|
|
16
16
|
import expo.modules.updates.logging.UpdatesLogger
|
|
17
17
|
import expo.modules.updates.manifest.EmbeddedManifestUtils
|
|
18
|
+
import expo.modules.updates.manifest.EmbeddedUpdate
|
|
18
19
|
import expo.modules.updates.manifest.ManifestMetadata
|
|
19
20
|
import expo.modules.updates.selectionpolicy.SelectionPolicy
|
|
21
|
+
import org.json.JSONObject
|
|
20
22
|
import java.io.File
|
|
21
23
|
|
|
22
24
|
/**
|
|
@@ -92,7 +94,10 @@ class DatabaseLauncher(
|
|
|
92
94
|
this.callback!!.onFailure(Exception("Launch asset relative path should not be null. Debug info: ${launchedUpdate!!.debugInfo()}"))
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
val
|
|
97
|
+
val embeddedUpdate = EmbeddedManifestUtils.getEmbeddedUpdate(context, configuration)
|
|
98
|
+
val extraHeaders = FileDownloader.getExtraHeadersForRemoteAssetRequest(launchedUpdate, embeddedUpdate?.updateEntity, launchedUpdate)
|
|
99
|
+
|
|
100
|
+
val launchAssetFile = ensureAssetExists(launchAsset, database, embeddedUpdate, extraHeaders)
|
|
96
101
|
if (launchAssetFile != null) {
|
|
97
102
|
this.launchAssetFile = launchAssetFile.toString()
|
|
98
103
|
}
|
|
@@ -107,7 +112,7 @@ class DatabaseLauncher(
|
|
|
107
112
|
}
|
|
108
113
|
val filename = asset.relativePath
|
|
109
114
|
if (filename != null) {
|
|
110
|
-
val assetFile = ensureAssetExists(asset, database)
|
|
115
|
+
val assetFile = ensureAssetExists(asset, database, embeddedUpdate, extraHeaders)
|
|
111
116
|
if (assetFile != null) {
|
|
112
117
|
this[asset] = Uri.fromFile(assetFile).toString()
|
|
113
118
|
}
|
|
@@ -170,13 +175,12 @@ class DatabaseLauncher(
|
|
|
170
175
|
}
|
|
171
176
|
}
|
|
172
177
|
|
|
173
|
-
fun ensureAssetExists(asset: AssetEntity, database: UpdatesDatabase): File? {
|
|
178
|
+
fun ensureAssetExists(asset: AssetEntity, database: UpdatesDatabase, embeddedUpdate: EmbeddedUpdate?, extraHeaders: JSONObject): File? {
|
|
174
179
|
val assetFile = File(updatesDirectory, asset.relativePath ?: "")
|
|
175
180
|
var assetFileExists = assetFile.exists()
|
|
176
181
|
if (!assetFileExists) {
|
|
177
182
|
// something has gone wrong, we're missing this asset
|
|
178
183
|
// first we check to see if a copy is embedded in the binary
|
|
179
|
-
val embeddedUpdate = EmbeddedManifestUtils.getEmbeddedUpdate(context, configuration)
|
|
180
184
|
if (embeddedUpdate != null) {
|
|
181
185
|
val embeddedAssets = embeddedUpdate.assetEntityList
|
|
182
186
|
var matchingEmbeddedAsset: AssetEntity? = null
|
|
@@ -204,9 +208,11 @@ class DatabaseLauncher(
|
|
|
204
208
|
return if (!assetFileExists) {
|
|
205
209
|
// we still don't have the asset locally, so try downloading it remotely
|
|
206
210
|
assetsToDownload++
|
|
211
|
+
|
|
207
212
|
fileDownloader.downloadAsset(
|
|
208
213
|
asset,
|
|
209
214
|
updatesDirectory,
|
|
215
|
+
extraHeaders,
|
|
210
216
|
object : AssetDownloadCallback {
|
|
211
217
|
override fun onFailure(e: Exception, assetEntity: AssetEntity) {
|
|
212
218
|
logger.error("Failed to load asset from disk or network", e, UpdatesErrorCode.AssetsFailedToLoad)
|
|
@@ -7,6 +7,7 @@ import expo.modules.updates.db.UpdatesDatabase
|
|
|
7
7
|
import expo.modules.updates.loader.FileDownloader.AssetDownloadCallback
|
|
8
8
|
import expo.modules.updates.loader.FileDownloader.RemoteUpdateDownloadCallback
|
|
9
9
|
import expo.modules.updates.UpdatesUtils
|
|
10
|
+
import expo.modules.updates.db.entity.UpdateEntity
|
|
10
11
|
import expo.modules.updates.logging.UpdatesLogger
|
|
11
12
|
import java.io.File
|
|
12
13
|
import java.io.FileNotFoundException
|
|
@@ -71,6 +72,8 @@ class EmbeddedLoader internal constructor(
|
|
|
71
72
|
assetEntity: AssetEntity,
|
|
72
73
|
updatesDirectory: File?,
|
|
73
74
|
configuration: UpdatesConfiguration,
|
|
75
|
+
requestedUpdate: UpdateEntity?,
|
|
76
|
+
embeddedUpdate: UpdateEntity?,
|
|
74
77
|
callback: AssetDownloadCallback
|
|
75
78
|
) {
|
|
76
79
|
val filename = UpdatesUtils.createFilenameForAsset(assetEntity)
|
|
@@ -450,6 +450,7 @@ class FileDownloader(
|
|
|
450
450
|
fun downloadAsset(
|
|
451
451
|
asset: AssetEntity,
|
|
452
452
|
destinationDirectory: File?,
|
|
453
|
+
extraHeaders: JSONObject,
|
|
453
454
|
callback: AssetDownloadCallback
|
|
454
455
|
) {
|
|
455
456
|
if (asset.url == null) {
|
|
@@ -467,7 +468,7 @@ class FileDownloader(
|
|
|
467
468
|
} else {
|
|
468
469
|
try {
|
|
469
470
|
downloadAssetAndVerifyHashAndWriteToPath(
|
|
470
|
-
createRequestForAsset(asset, configuration, context),
|
|
471
|
+
createRequestForAsset(asset, extraHeaders, configuration, context),
|
|
471
472
|
asset.expectedHash,
|
|
472
473
|
path,
|
|
473
474
|
object : FileDownloadCallback {
|
|
@@ -595,12 +596,14 @@ class FileDownloader(
|
|
|
595
596
|
|
|
596
597
|
internal fun createRequestForAsset(
|
|
597
598
|
assetEntity: AssetEntity,
|
|
599
|
+
extraHeaders: JSONObject,
|
|
598
600
|
configuration: UpdatesConfiguration,
|
|
599
601
|
context: Context
|
|
600
602
|
): Request {
|
|
601
603
|
return Request.Builder()
|
|
602
604
|
.url(assetEntity.url!!.toString())
|
|
603
605
|
.addHeadersFromJSONObject(assetEntity.extraRequestHeaders)
|
|
606
|
+
.addHeadersFromJSONObject(extraHeaders)
|
|
604
607
|
.header("Expo-Platform", "android")
|
|
605
608
|
.header("Expo-Protocol-Version", "1")
|
|
606
609
|
.header("Expo-API-Version", "1")
|
|
@@ -701,5 +704,25 @@ class FileDownloader(
|
|
|
701
704
|
|
|
702
705
|
return extraHeaders
|
|
703
706
|
}
|
|
707
|
+
|
|
708
|
+
fun getExtraHeadersForRemoteAssetRequest(
|
|
709
|
+
launchedUpdate: UpdateEntity?,
|
|
710
|
+
embeddedUpdate: UpdateEntity?,
|
|
711
|
+
requestedUpdate: UpdateEntity?
|
|
712
|
+
): JSONObject {
|
|
713
|
+
val extraHeaders = JSONObject()
|
|
714
|
+
|
|
715
|
+
launchedUpdate?.let {
|
|
716
|
+
extraHeaders.put("Expo-Current-Update-ID", it.id.toString().lowercase())
|
|
717
|
+
}
|
|
718
|
+
embeddedUpdate?.let {
|
|
719
|
+
extraHeaders.put("Expo-Embedded-Update-ID", it.id.toString().lowercase())
|
|
720
|
+
}
|
|
721
|
+
requestedUpdate?.let {
|
|
722
|
+
extraHeaders.put("Expo-Requested-Update-ID", it.id.toString().lowercase())
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
return extraHeaders
|
|
726
|
+
}
|
|
704
727
|
}
|
|
705
728
|
}
|
|
@@ -86,6 +86,8 @@ abstract class Loader protected constructor(
|
|
|
86
86
|
assetEntity: AssetEntity,
|
|
87
87
|
updatesDirectory: File?,
|
|
88
88
|
configuration: UpdatesConfiguration,
|
|
89
|
+
requestedUpdate: UpdateEntity?,
|
|
90
|
+
embeddedUpdate: UpdateEntity?,
|
|
89
91
|
callback: AssetDownloadCallback
|
|
90
92
|
)
|
|
91
93
|
|
|
@@ -204,7 +206,7 @@ abstract class Loader protected constructor(
|
|
|
204
206
|
// however, it's not ready, so we should try to download all the assets again.
|
|
205
207
|
updateEntity = existingUpdateEntity
|
|
206
208
|
}
|
|
207
|
-
downloadAllAssets(update
|
|
209
|
+
downloadAllAssets(update)
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
|
|
@@ -214,8 +216,11 @@ abstract class Loader protected constructor(
|
|
|
214
216
|
ERRORED
|
|
215
217
|
}
|
|
216
218
|
|
|
217
|
-
private fun downloadAllAssets(
|
|
219
|
+
private fun downloadAllAssets(update: Update) {
|
|
220
|
+
val assetList = update.assetEntityList
|
|
218
221
|
assetTotal = assetList.size
|
|
222
|
+
|
|
223
|
+
val embeddedUpdate = loaderFiles.readEmbeddedUpdate(context, configuration)
|
|
219
224
|
for (assetEntityCur in assetList) {
|
|
220
225
|
var assetEntity = assetEntityCur
|
|
221
226
|
|
|
@@ -243,6 +248,8 @@ abstract class Loader protected constructor(
|
|
|
243
248
|
assetEntity,
|
|
244
249
|
updatesDirectory,
|
|
245
250
|
configuration,
|
|
251
|
+
requestedUpdate = update.updateEntity,
|
|
252
|
+
embeddedUpdate = embeddedUpdate?.updateEntity,
|
|
246
253
|
object : AssetDownloadCallback {
|
|
247
254
|
override fun onFailure(e: Exception, assetEntity: AssetEntity) {
|
|
248
255
|
val identifier = if (assetEntity.hash != null) {
|
|
@@ -69,7 +69,7 @@ open class LoaderFiles {
|
|
|
69
69
|
context.resources.openRawResource(id)
|
|
70
70
|
.use { inputStream -> return UpdatesUtils.verifySHA256AndWriteToFile(inputStream, destination, null) }
|
|
71
71
|
} catch (e: Exception) {
|
|
72
|
-
Log.e(TAG, "Failed to copy asset
|
|
72
|
+
Log.e(TAG, "Failed to copy resource asset ${asset.resourcesFolder}/${asset.embeddedAssetFilename}", e)
|
|
73
73
|
throw e
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -55,9 +55,12 @@ class RemoteLoader internal constructor(
|
|
|
55
55
|
assetEntity: AssetEntity,
|
|
56
56
|
updatesDirectory: File?,
|
|
57
57
|
configuration: UpdatesConfiguration,
|
|
58
|
+
requestedUpdate: UpdateEntity?,
|
|
59
|
+
embeddedUpdate: UpdateEntity?,
|
|
58
60
|
callback: AssetDownloadCallback
|
|
59
61
|
) {
|
|
60
|
-
|
|
62
|
+
val extraHeaders = FileDownloader.getExtraHeadersForRemoteAssetRequest(launchedUpdate, embeddedUpdate, requestedUpdate)
|
|
63
|
+
mFileDownloader.downloadAsset(assetEntity, updatesDirectory, extraHeaders, callback)
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
companion object {
|
package/e2e/setup/project.ts
CHANGED
|
@@ -97,7 +97,7 @@ open class AppLoader: NSObject {
|
|
|
97
97
|
preconditionFailure("Must override in concrete class")
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
open func downloadAsset(_ asset: UpdateAsset) {
|
|
100
|
+
open func downloadAsset(_ asset: UpdateAsset, extraHeaders: [String: Any]) {
|
|
101
101
|
preconditionFailure("Must override in concrete class")
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -202,6 +202,13 @@ open class AppLoader: NSObject {
|
|
|
202
202
|
if let assets = updateManifest.assets(),
|
|
203
203
|
!assets.isEmpty {
|
|
204
204
|
self.assetsToLoad = assets
|
|
205
|
+
let embeddedUpdate = EmbeddedAppLoader.embeddedManifest(withConfig: self.config, database: self.database)
|
|
206
|
+
let extraHeaders = FileDownloader.extraHeadersForRemoteAssetRequest(
|
|
207
|
+
launchedUpdate: self.launchedUpdate,
|
|
208
|
+
embeddedUpdate: embeddedUpdate,
|
|
209
|
+
requestedUpdate: updateManifest
|
|
210
|
+
)
|
|
211
|
+
|
|
205
212
|
for asset in assets {
|
|
206
213
|
// before downloading, check to see if we already have this asset in the database
|
|
207
214
|
let matchingDbEntry = try? self.database.asset(withKey: asset.key)
|
|
@@ -226,11 +233,11 @@ open class AppLoader: NSObject {
|
|
|
226
233
|
self.handleAssetDownloadAlreadyExists(asset)
|
|
227
234
|
}
|
|
228
235
|
} else {
|
|
229
|
-
self.downloadAsset(asset)
|
|
236
|
+
self.downloadAsset(asset, extraHeaders: extraHeaders)
|
|
230
237
|
}
|
|
231
238
|
}
|
|
232
239
|
} else {
|
|
233
|
-
self.downloadAsset(asset)
|
|
240
|
+
self.downloadAsset(asset, extraHeaders: extraHeaders)
|
|
234
241
|
}
|
|
235
242
|
}
|
|
236
243
|
} else {
|
|
@@ -119,7 +119,7 @@ public final class EmbeddedAppLoader: AppLoader {
|
|
|
119
119
|
))
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
override public func downloadAsset(_ asset: UpdateAsset) {
|
|
122
|
+
override public func downloadAsset(_ asset: UpdateAsset, extraHeaders: [String: Any]) {
|
|
123
123
|
FileDownloader.assetFilesQueue.async {
|
|
124
124
|
self.handleAssetDownloadAlreadyExists(asset)
|
|
125
125
|
}
|
|
@@ -221,6 +221,30 @@ public final class FileDownloader {
|
|
|
221
221
|
return extraHeaders
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Get extra headers to pass into `downloadAsset:`
|
|
226
|
+
*/
|
|
227
|
+
static func extraHeadersForRemoteAssetRequest(
|
|
228
|
+
launchedUpdate: Update?,
|
|
229
|
+
embeddedUpdate: Update?,
|
|
230
|
+
requestedUpdate: Update?
|
|
231
|
+
) -> [String: Any] {
|
|
232
|
+
var extraHeaders: [String: Any] = [:]
|
|
233
|
+
if let launchedUpdate {
|
|
234
|
+
extraHeaders["Expo-Current-Update-ID"] = launchedUpdate.updateId.uuidString.lowercased()
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if let embeddedUpdate {
|
|
238
|
+
extraHeaders["Expo-Embedded-Update-ID"] = embeddedUpdate.updateId.uuidString.lowercased()
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if let requestedUpdate {
|
|
242
|
+
extraHeaders["Expo-Requested-Update-ID"] = requestedUpdate.updateId.uuidString.lowercased()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return extraHeaders
|
|
246
|
+
}
|
|
247
|
+
|
|
224
248
|
private static func setHTTPHeaderFields(_ headers: [String: Any?]?, onRequest request: inout URLRequest) {
|
|
225
249
|
guard let headers = headers else {
|
|
226
250
|
return
|
|
@@ -84,7 +84,7 @@ public final class RemoteAppLoader: AppLoader {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
override public func downloadAsset(_ asset: UpdateAsset) {
|
|
87
|
+
override public func downloadAsset(_ asset: UpdateAsset, extraHeaders: [String: Any]) {
|
|
88
88
|
let urlOnDisk = self.directory.appendingPathComponent(asset.filename)
|
|
89
89
|
|
|
90
90
|
FileDownloader.assetFilesQueue.async {
|
|
@@ -101,12 +101,11 @@ public final class RemoteAppLoader: AppLoader {
|
|
|
101
101
|
)
|
|
102
102
|
return
|
|
103
103
|
}
|
|
104
|
-
|
|
105
104
|
self.downloader.downloadAsset(
|
|
106
105
|
fromURL: assetUrl,
|
|
107
106
|
verifyingHash: asset.expectedHash,
|
|
108
107
|
toPath: urlOnDisk.path,
|
|
109
|
-
extraHeaders: asset.extraRequestHeaders ?? [:]
|
|
108
|
+
extraHeaders: extraHeaders.merging(asset.extraRequestHeaders ?? [:]) { current, _ in current }
|
|
110
109
|
) { data, response, _ in
|
|
111
110
|
DispatchQueue.global().async {
|
|
112
111
|
self.handleAssetDownload(withData: data, response: response, asset: asset)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-updates",
|
|
3
|
-
"version": "1.0.0-canary-
|
|
3
|
+
"version": "1.0.0-canary-20250219-4a5dade",
|
|
4
4
|
"description": "Fetches and manages remotely-hosted assets and updates to your app's JS bundle.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@expo/code-signing-certificates": "0.0.5",
|
|
42
|
-
"@expo/config": "11.0.0-canary-
|
|
43
|
-
"@expo/config-plugins": "9.0.16-canary-
|
|
42
|
+
"@expo/config": "11.0.0-canary-20250219-4a5dade",
|
|
43
|
+
"@expo/config-plugins": "9.0.16-canary-20250219-4a5dade",
|
|
44
44
|
"@expo/spawn-async": "^1.7.2",
|
|
45
45
|
"arg": "4.1.0",
|
|
46
46
|
"chalk": "^4.1.2",
|
|
47
|
-
"expo-eas-client": "0.13.3-canary-
|
|
48
|
-
"expo-manifests": "0.15.
|
|
49
|
-
"expo-structured-headers": "4.0.1-canary-
|
|
50
|
-
"expo-updates-interface": "1.0.1-canary-
|
|
47
|
+
"expo-eas-client": "0.13.3-canary-20250219-4a5dade",
|
|
48
|
+
"expo-manifests": "0.15.7-canary-20250219-4a5dade",
|
|
49
|
+
"expo-structured-headers": "4.0.1-canary-20250219-4a5dade",
|
|
50
|
+
"expo-updates-interface": "1.0.1-canary-20250219-4a5dade",
|
|
51
51
|
"fast-glob": "^3.3.2",
|
|
52
52
|
"fbemitter": "^3.0.0",
|
|
53
53
|
"ignore": "^5.3.1",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@types/jest": "^29.2.1",
|
|
58
58
|
"@types/node": "^18.19.34",
|
|
59
59
|
"@types/node-forge": "^1.0.0",
|
|
60
|
-
"expo-module-scripts": "4.0.
|
|
60
|
+
"expo-module-scripts": "4.0.5-canary-20250219-4a5dade",
|
|
61
61
|
"express": "^4.21.1",
|
|
62
62
|
"form-data": "^4.0.0",
|
|
63
63
|
"fs-extra": "~8.1.0",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"xstate": "^4.37.2"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"expo": "53.0.0-canary-
|
|
68
|
+
"expo": "53.0.0-canary-20250219-4a5dade",
|
|
69
69
|
"react": "*"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "4a5daded61d3d8b9d501059039ac74c09c25675b"
|
|
72
72
|
}
|