expo-constants 11.1.0 → 12.1.2
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 +36 -0
- package/android/build.gradle +6 -2
- package/android/src/main/java/expo/modules/constants/ConstantsModule.kt +35 -0
- package/android/src/main/java/expo/modules/constants/ConstantsPackage.kt +15 -0
- package/android/src/main/java/expo/modules/constants/ConstantsService.kt +134 -0
- package/android/src/main/java/expo/modules/constants/ExponentInstallationId.kt +112 -0
- package/build/Constants.js +25 -0
- package/build/Constants.js.map +1 -1
- package/build/Constants.types.d.ts +6 -0
- package/build/Constants.types.js.map +1 -1
- package/ios/EXConstants/EXConstantsService.m +62 -42
- package/ios/EXConstants.podspec +2 -1
- package/package.json +4 -4
- package/scripts/get-app-config-ios.sh +19 -25
- package/src/Constants.ts +30 -0
- package/src/Constants.types.ts +6 -0
- package/android/src/main/java/expo/modules/constants/ConstantsModule.java +0 -44
- package/android/src/main/java/expo/modules/constants/ConstantsPackage.java +0 -22
- package/android/src/main/java/expo/modules/constants/ConstantsService.java +0 -188
- package/android/src/main/java/expo/modules/constants/ExponentInstallationId.java +0 -110
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,42 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 12.1.2 — 2021-10-21
|
|
14
|
+
|
|
15
|
+
_This version does not introduce any user-facing changes._
|
|
16
|
+
|
|
17
|
+
## 12.1.1 — 2021-10-15
|
|
18
|
+
|
|
19
|
+
### 🛠 Breaking changes
|
|
20
|
+
|
|
21
|
+
- Deprecated `Constants.deviceYearClass`, moved to `expo-device` - `Device.deviceYearClass` ([#14691](https://github.com/expo/expo/pull/14691) by [@EvanBacon](https://github.com/EvanBacon))
|
|
22
|
+
- Deprecated `Constants.platform.ios.model`, moved to `expo-device` - `Device.modelName` ([#14691](https://github.com/expo/expo/pull/14691) by [@EvanBacon](https://github.com/EvanBacon))
|
|
23
|
+
|
|
24
|
+
### 🎉 New features
|
|
25
|
+
|
|
26
|
+
- Added support for iOS 15.0 devices ([#14640](https://github.com/expo/expo/pull/14640) by [@EvanBacon](https://github.com/EvanBacon))
|
|
27
|
+
|
|
28
|
+
## 12.1.0 — 2021-10-01
|
|
29
|
+
|
|
30
|
+
### 🐛 Bug fixes
|
|
31
|
+
|
|
32
|
+
- Don't include fonts from family "System Font" (introduced by iOS 15) ([#14577](https://github.com/expo/expo/pull/14577) by [@brentvatne](https://github.com/brentvatne))
|
|
33
|
+
|
|
34
|
+
## 12.0.0 — 2021-09-28
|
|
35
|
+
|
|
36
|
+
### 🛠 Breaking changes
|
|
37
|
+
|
|
38
|
+
- Dropped support for iOS 11.0 ([#14383](https://github.com/expo/expo/pull/14383) by [@cruzach](https://github.com/cruzach))
|
|
39
|
+
|
|
40
|
+
### 🐛 Bug fixes
|
|
41
|
+
|
|
42
|
+
- Fix building errors from use_frameworks! in Podfile. ([#14523](https://github.com/expo/expo/pull/14523) by [@kudo](https://github.com/kudo))
|
|
43
|
+
|
|
44
|
+
### 💡 Others
|
|
45
|
+
|
|
46
|
+
- Rewrite Android code to Kotlin. ([#14434](https://github.com/expo/expo/pull/14434) by [@kkafar](https://github.com/kkafar))
|
|
47
|
+
- Updated `@expo/config-plugins` ([#14443](https://github.com/expo/expo/pull/14443) by [@EvanBacon](https://github.com/EvanBacon))
|
|
48
|
+
|
|
13
49
|
## 11.1.0 — 2021-09-08
|
|
14
50
|
|
|
15
51
|
### 🎉 New features
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '
|
|
6
|
+
version = '12.1.2'
|
|
7
7
|
|
|
8
8
|
apply from: "../scripts/get-app-config-android.gradle"
|
|
9
9
|
|
|
@@ -55,11 +55,15 @@ android {
|
|
|
55
55
|
targetCompatibility JavaVersion.VERSION_1_8
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
kotlinOptions {
|
|
59
|
+
jvmTarget = JavaVersion.VERSION_1_8
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
defaultConfig {
|
|
59
63
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
60
64
|
targetSdkVersion safeExtGet("targetSdkVersion", 30)
|
|
61
65
|
versionCode 33
|
|
62
|
-
versionName "
|
|
66
|
+
versionName "12.1.2"
|
|
63
67
|
}
|
|
64
68
|
lintOptions {
|
|
65
69
|
abortOnError false
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
+
package expo.modules.constants
|
|
3
|
+
|
|
4
|
+
import android.content.Context
|
|
5
|
+
|
|
6
|
+
import expo.modules.core.ExportedModule
|
|
7
|
+
import expo.modules.core.ModuleRegistry
|
|
8
|
+
import expo.modules.core.ModuleRegistryDelegate
|
|
9
|
+
import expo.modules.core.Promise
|
|
10
|
+
import expo.modules.interfaces.constants.ConstantsInterface
|
|
11
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
12
|
+
|
|
13
|
+
class ConstantsModule(
|
|
14
|
+
context: Context,
|
|
15
|
+
private val moduleRegistryDelegate: ModuleRegistryDelegate = ModuleRegistryDelegate()
|
|
16
|
+
) : ExportedModule(context) {
|
|
17
|
+
|
|
18
|
+
private inline fun <reified T> moduleRegistry() = moduleRegistryDelegate.getFromModuleRegistry<T>()
|
|
19
|
+
|
|
20
|
+
private val constantsService: ConstantsInterface by moduleRegistry()
|
|
21
|
+
|
|
22
|
+
override fun getConstants(): Map<String, Any> = constantsService.constants
|
|
23
|
+
|
|
24
|
+
override fun getName() = "ExponentConstants"
|
|
25
|
+
|
|
26
|
+
override fun onCreate(moduleRegistry: ModuleRegistry) {
|
|
27
|
+
moduleRegistryDelegate.onCreate(moduleRegistry)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@ExpoMethod
|
|
31
|
+
fun getWebViewUserAgentAsync(promise: Promise) {
|
|
32
|
+
val userAgent = System.getProperty("http.agent")
|
|
33
|
+
promise.resolve(userAgent)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package expo.modules.constants
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
|
|
5
|
+
import expo.modules.core.BasePackage
|
|
6
|
+
import expo.modules.core.interfaces.InternalModule
|
|
7
|
+
import expo.modules.core.ExportedModule
|
|
8
|
+
|
|
9
|
+
class ConstantsPackage : BasePackage() {
|
|
10
|
+
override fun createInternalModules(context: Context): List<InternalModule> =
|
|
11
|
+
listOf(ConstantsService(context))
|
|
12
|
+
|
|
13
|
+
override fun createExportedModules(context: Context): List<ExportedModule> =
|
|
14
|
+
listOf(ConstantsModule(context))
|
|
15
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
package expo.modules.constants
|
|
2
|
+
|
|
3
|
+
import org.apache.commons.io.IOUtils
|
|
4
|
+
|
|
5
|
+
import com.facebook.device.yearclass.YearClass
|
|
6
|
+
|
|
7
|
+
import expo.modules.core.interfaces.InternalModule
|
|
8
|
+
import expo.modules.interfaces.constants.ConstantsInterface
|
|
9
|
+
|
|
10
|
+
import android.os.Build
|
|
11
|
+
import android.util.Log
|
|
12
|
+
import android.content.Context
|
|
13
|
+
import android.content.pm.PackageInfo
|
|
14
|
+
import android.content.pm.PackageManager
|
|
15
|
+
|
|
16
|
+
import java.io.FileNotFoundException
|
|
17
|
+
import java.lang.Exception
|
|
18
|
+
import java.nio.charset.StandardCharsets
|
|
19
|
+
import java.util.*
|
|
20
|
+
|
|
21
|
+
private val TAG = ConstantsService::class.java.simpleName
|
|
22
|
+
private const val CONFIG_FILE_NAME = "app.config"
|
|
23
|
+
|
|
24
|
+
open class ConstantsService(private val context: Context) : InternalModule, ConstantsInterface {
|
|
25
|
+
var statusBarHeightInternal = context.resources.getIdentifier("status_bar_height", "dimen", "android")
|
|
26
|
+
.takeIf { it > 0 }
|
|
27
|
+
?.let { (context.resources::getDimensionPixelSize)(it) }
|
|
28
|
+
?.let { pixels -> convertPixelsToDp(pixels.toFloat(), context) }
|
|
29
|
+
?: 0
|
|
30
|
+
|
|
31
|
+
private val sessionId = UUID.randomUUID().toString()
|
|
32
|
+
private val exponentInstallationId: ExponentInstallationId = ExponentInstallationId(context)
|
|
33
|
+
|
|
34
|
+
enum class ExecutionEnvironment(val string: String) {
|
|
35
|
+
BARE("bare"),
|
|
36
|
+
STANDALONE("standalone"),
|
|
37
|
+
STORE_CLIENT("storeClient");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override fun getExportedInterfaces(): List<Class<*>> = listOf(ConstantsInterface::class.java)
|
|
41
|
+
|
|
42
|
+
override fun getConstants(): Map<String, Any?> {
|
|
43
|
+
val constants = mutableMapOf(
|
|
44
|
+
"sessionId" to sessionId,
|
|
45
|
+
"executionEnvironment" to ExecutionEnvironment.BARE.string,
|
|
46
|
+
"statusBarHeight" to statusBarHeightInternal,
|
|
47
|
+
"deviceYearClass" to deviceYearClass,
|
|
48
|
+
"deviceName" to deviceName,
|
|
49
|
+
"isDevice" to isDevice,
|
|
50
|
+
"systemFonts" to systemFonts,
|
|
51
|
+
"systemVersion" to systemVersion,
|
|
52
|
+
"installationId" to getOrCreateInstallationId(),
|
|
53
|
+
"manifest" to appConfig,
|
|
54
|
+
"platform" to mapOf("android" to emptyMap<String, Any>())
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
|
|
59
|
+
constants["nativeAppVersion"] = pInfo.versionName
|
|
60
|
+
|
|
61
|
+
val versionCode = getLongVersionCode(pInfo).toInt()
|
|
62
|
+
constants["nativeBuildVersion"] = versionCode.toString()
|
|
63
|
+
} catch (e: PackageManager.NameNotFoundException) {
|
|
64
|
+
Log.e(TAG, "Exception: ", e)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return constants
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Just use package name in vanilla React Native apps.
|
|
71
|
+
override fun getAppScopeKey(): String? = context.packageName
|
|
72
|
+
|
|
73
|
+
override fun getAppOwnership() = "guest"
|
|
74
|
+
|
|
75
|
+
override fun getDeviceName(): String = Build.MODEL
|
|
76
|
+
|
|
77
|
+
override fun getDeviceYearClass() = YearClass.get(context)
|
|
78
|
+
|
|
79
|
+
override fun getIsDevice() = !isRunningOnGenymotion && !isRunningOnStockEmulator
|
|
80
|
+
|
|
81
|
+
override fun getStatusBarHeight() = statusBarHeightInternal
|
|
82
|
+
|
|
83
|
+
override fun getSystemVersion(): String = Build.VERSION.RELEASE
|
|
84
|
+
|
|
85
|
+
open fun getOrCreateInstallationId(): String = exponentInstallationId.getOrCreateUUID()
|
|
86
|
+
|
|
87
|
+
// From https://github.com/dabit3/react-native-fonts
|
|
88
|
+
override fun getSystemFonts() = listOf(
|
|
89
|
+
"normal",
|
|
90
|
+
"notoserif",
|
|
91
|
+
"sans-serif",
|
|
92
|
+
"sans-serif-light",
|
|
93
|
+
"sans-serif-thin",
|
|
94
|
+
"sans-serif-condensed",
|
|
95
|
+
"sans-serif-medium",
|
|
96
|
+
"serif",
|
|
97
|
+
"Roboto",
|
|
98
|
+
"monospace"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
private val appConfig: String?
|
|
102
|
+
get() {
|
|
103
|
+
try {
|
|
104
|
+
context.assets.open(CONFIG_FILE_NAME).use {
|
|
105
|
+
stream ->
|
|
106
|
+
return IOUtils.toString(stream, StandardCharsets.UTF_8)
|
|
107
|
+
}
|
|
108
|
+
} catch (e: FileNotFoundException) {
|
|
109
|
+
// do nothing, expected in managed apps
|
|
110
|
+
} catch (e: Exception) {
|
|
111
|
+
Log.e(TAG, "Error reading embedded app config", e)
|
|
112
|
+
}
|
|
113
|
+
return null
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
companion object {
|
|
117
|
+
private fun convertPixelsToDp(px: Float, context: Context): Int {
|
|
118
|
+
val resources = context.resources
|
|
119
|
+
val metrics = resources.displayMetrics
|
|
120
|
+
val dp = px / (metrics.densityDpi / 160f)
|
|
121
|
+
return dp.toInt()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private val isRunningOnGenymotion: Boolean
|
|
125
|
+
get() = Build.FINGERPRINT.contains("vbox")
|
|
126
|
+
|
|
127
|
+
private val isRunningOnStockEmulator: Boolean
|
|
128
|
+
get() = Build.FINGERPRINT.contains("generic")
|
|
129
|
+
|
|
130
|
+
private fun getLongVersionCode(info: PackageInfo) =
|
|
131
|
+
if (Build.VERSION.SDK_INT >= 28) info.longVersionCode
|
|
132
|
+
else info.versionCode.toLong()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
package expo.modules.constants
|
|
2
|
+
|
|
3
|
+
import android.util.Log
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.SharedPreferences
|
|
6
|
+
|
|
7
|
+
import java.util.UUID
|
|
8
|
+
import java.io.File
|
|
9
|
+
import java.io.FileReader
|
|
10
|
+
import java.io.FileWriter
|
|
11
|
+
import java.io.IOException
|
|
12
|
+
import java.io.BufferedReader
|
|
13
|
+
import kotlin.IllegalArgumentException
|
|
14
|
+
|
|
15
|
+
private val TAG = ExponentInstallationId::class.java.simpleName
|
|
16
|
+
private const val PREFERENCES_FILE_NAME = "host.exp.exponent.SharedPreferences"
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* An installation ID provider - it solves two purposes:
|
|
20
|
+
* - in installations that have a legacy UUID persisted
|
|
21
|
+
* in shared-across-expo-modules SharedPreferences,
|
|
22
|
+
* migrates the UUID from there to a non-backed-up file,
|
|
23
|
+
* - provides/creates a UUID unique per an installation.
|
|
24
|
+
*
|
|
25
|
+
* Similar class exists in expoview and expo-notifications.
|
|
26
|
+
*/
|
|
27
|
+
class ExponentInstallationId internal constructor(private val context: Context) {
|
|
28
|
+
private var uuid: String? = null
|
|
29
|
+
|
|
30
|
+
private val mSharedPreferences: SharedPreferences = context.getSharedPreferences(PREFERENCES_FILE_NAME, Context.MODE_PRIVATE)
|
|
31
|
+
|
|
32
|
+
fun getUUID(): String? {
|
|
33
|
+
// If it has already been cached, return the value.
|
|
34
|
+
if (uuid != null) {
|
|
35
|
+
return uuid
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Read from non-backed-up storage
|
|
39
|
+
val uuidFile = nonBackedUpUuidFile
|
|
40
|
+
try {
|
|
41
|
+
FileReader(uuidFile).use { fileReader ->
|
|
42
|
+
BufferedReader(fileReader).use { bufferedReader ->
|
|
43
|
+
// Cache for future calls
|
|
44
|
+
uuid = UUID.fromString(bufferedReader.readLine()).toString()
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (e: Exception) {
|
|
48
|
+
when (e) {
|
|
49
|
+
is IOException, is IllegalArgumentException -> { /* do nothing, try other sources */ }
|
|
50
|
+
else -> throw e
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// We could have returned inside try clause,
|
|
55
|
+
// but putting it like this here makes it immediately
|
|
56
|
+
// visible.
|
|
57
|
+
if (uuid != null) {
|
|
58
|
+
return uuid
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// In November 2020 we decided to move installationID (backed by LEGACY_UUID_KEY value) from
|
|
62
|
+
// backed-up SharedPreferences to a non-backed-up text file to fix issues where devices restored
|
|
63
|
+
// from backups have the same installation IDs as the devices where the backup was created.
|
|
64
|
+
val legacyUuid = mSharedPreferences.getString(LEGACY_UUID_KEY, null)
|
|
65
|
+
if (legacyUuid != null) {
|
|
66
|
+
uuid = legacyUuid
|
|
67
|
+
|
|
68
|
+
val uuidHasBeenSuccessfullyMigrated = try {
|
|
69
|
+
FileWriter(uuidFile).use { writer -> writer.write(legacyUuid) }
|
|
70
|
+
true
|
|
71
|
+
} catch (e: IOException) {
|
|
72
|
+
Log.e(TAG, "Error while migrating UUID from legacy storage. $e")
|
|
73
|
+
false
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// We only remove the value from old storage once it's set and saved in the new storage.
|
|
77
|
+
if (uuidHasBeenSuccessfullyMigrated) {
|
|
78
|
+
mSharedPreferences.edit().remove(LEGACY_UUID_KEY).apply()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Return either value from legacy storage or null
|
|
83
|
+
return uuid
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
fun getOrCreateUUID(): String {
|
|
87
|
+
val uuid = getUUID()
|
|
88
|
+
if (uuid != null) {
|
|
89
|
+
return uuid
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// We persist the new UUID in "session storage"
|
|
93
|
+
// so that if writing to persistent storage
|
|
94
|
+
// fails subsequent calls to get(orCreate)UUID
|
|
95
|
+
// return the same value.
|
|
96
|
+
this.uuid = UUID.randomUUID().toString()
|
|
97
|
+
try {
|
|
98
|
+
FileWriter(nonBackedUpUuidFile).use { writer -> writer.write(this.uuid) }
|
|
99
|
+
} catch (e: IOException) {
|
|
100
|
+
Log.e(TAG, "Error while writing new UUID. $e")
|
|
101
|
+
}
|
|
102
|
+
return this.uuid!!
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private val nonBackedUpUuidFile: File
|
|
106
|
+
get() = File(context.noBackupFilesDir, UUID_FILE_NAME)
|
|
107
|
+
|
|
108
|
+
companion object {
|
|
109
|
+
const val LEGACY_UUID_KEY = "uuid"
|
|
110
|
+
const val UUID_FILE_NAME = "expo_installation_uuid.txt"
|
|
111
|
+
}
|
|
112
|
+
}
|
package/build/Constants.js
CHANGED
|
@@ -39,6 +39,8 @@ if (!rawManifest && ExponentConstants && ExponentConstants.manifest) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
const { name, appOwnership, ...nativeConstants } = (ExponentConstants || {});
|
|
42
|
+
let warnedAboutDeviceYearClass = false;
|
|
43
|
+
let warnedAboutIosModel = false;
|
|
42
44
|
let warnedAboutInstallationId = false;
|
|
43
45
|
let warnedAboutDeviceId = false;
|
|
44
46
|
let warnedAboutLinkingUrl = false;
|
|
@@ -47,6 +49,14 @@ const constants = {
|
|
|
47
49
|
// Ensure this is null in bare workflow
|
|
48
50
|
appOwnership: appOwnership ?? null,
|
|
49
51
|
// Deprecated fields
|
|
52
|
+
get deviceYearClass() {
|
|
53
|
+
if (!warnedAboutDeviceYearClass) {
|
|
54
|
+
console.warn(`Constants.deviceYearClass has been deprecated in favor of expo-device's Device.deviceYearClass property. This API will be removed in SDK 45.`);
|
|
55
|
+
warnedAboutDeviceYearClass = true;
|
|
56
|
+
}
|
|
57
|
+
return nativeConstants.deviceYearClass;
|
|
58
|
+
},
|
|
59
|
+
// Deprecated fields
|
|
50
60
|
get installationId() {
|
|
51
61
|
if (!warnedAboutInstallationId) {
|
|
52
62
|
console.warn(`Constants.installationId has been deprecated in favor of generating and storing your own ID. Implement it using expo-application's androidId on Android and a storage API such as expo-secure-store on iOS and localStorage on the web. This API will be removed in SDK 44.`);
|
|
@@ -110,6 +120,21 @@ const constants = {
|
|
|
110
120
|
rawManifest = value;
|
|
111
121
|
},
|
|
112
122
|
};
|
|
123
|
+
// Add deprecation warning for `platform.ios.model`
|
|
124
|
+
if (constants?.platform?.ios) {
|
|
125
|
+
const originalModel = nativeConstants.platform.ios.model;
|
|
126
|
+
Object.defineProperty(constants.platform.ios, 'model', {
|
|
127
|
+
get() {
|
|
128
|
+
if (!warnedAboutIosModel) {
|
|
129
|
+
console.warn(`Constants.platform.ios.model has been deprecated in favor of expo-device's Device.modelName property. This API will be removed in SDK 45.`);
|
|
130
|
+
warnedAboutIosModel = true;
|
|
131
|
+
}
|
|
132
|
+
return originalModel;
|
|
133
|
+
},
|
|
134
|
+
// Prevent the warning from being thrown, or the value from being used when the user interacts with the entire object.
|
|
135
|
+
enumerable: false,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
113
138
|
function isAppManifest(manifest) {
|
|
114
139
|
return !isManifest(manifest);
|
|
115
140
|
}
|
package/build/Constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, NativeModulesProxy } from 'expo-modules-core';\nimport { Platform, NativeModules } from 'react-native';\n\nimport {\n AndroidManifest,\n AppManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n Manifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n} from './Constants.types';\nimport ExponentConstants from './ExponentConstants';\n\nexport {\n AndroidManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n};\n\nif (!ExponentConstants) {\n console.warn(\n \"No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?\"\n );\n}\n\nlet rawManifest: AppManifest | Manifest | null = null;\n// If expo-updates defines a non-empty manifest, prefer that one\nif (NativeModulesProxy.ExpoUpdates) {\n let updatesManifest;\n if (NativeModulesProxy.ExpoUpdates.manifest) {\n updatesManifest = NativeModulesProxy.ExpoUpdates.manifest;\n } else if (NativeModulesProxy.ExpoUpdates.manifestString) {\n updatesManifest = JSON.parse(NativeModulesProxy.ExpoUpdates.manifestString);\n }\n if (updatesManifest && Object.keys(updatesManifest).length > 0) {\n rawManifest = updatesManifest;\n }\n}\n\n// If dev-launcher defines a non-empty manifest, prefer that one\nif (NativeModules.EXDevLauncher) {\n let devLauncherManifest;\n if (NativeModules.EXDevLauncher.manifestString) {\n devLauncherManifest = JSON.parse(NativeModules.EXDevLauncher.manifestString);\n }\n\n if (devLauncherManifest && Object.keys(devLauncherManifest).length > 0) {\n rawManifest = devLauncherManifest;\n }\n}\n\n// Fall back to ExponentConstants.manifest if we don't have one from Updates\nif (!rawManifest && ExponentConstants && ExponentConstants.manifest) {\n rawManifest = ExponentConstants.manifest;\n // On Android we pass the manifest in JSON form so this step is necessary\n if (typeof rawManifest === 'string') {\n rawManifest = JSON.parse(rawManifest);\n }\n}\n\nconst { name, appOwnership, ...nativeConstants } = (ExponentConstants || {}) as any;\n\nlet warnedAboutInstallationId = false;\nlet warnedAboutDeviceId = false;\nlet warnedAboutLinkingUrl = false;\n\nconst constants = {\n ...nativeConstants,\n // Ensure this is null in bare workflow\n appOwnership: appOwnership ?? null,\n // Deprecated fields\n get installationId() {\n if (!warnedAboutInstallationId) {\n console.warn(\n `Constants.installationId has been deprecated in favor of generating and storing your own ID. Implement it using expo-application's androidId on Android and a storage API such as expo-secure-store on iOS and localStorage on the web. This API will be removed in SDK 44.`\n );\n warnedAboutInstallationId = true;\n }\n return nativeConstants.installationId;\n },\n // Legacy aliases\n get deviceId() {\n if (!warnedAboutDeviceId) {\n console.warn(\n `Constants.deviceId has been deprecated in favor of generating and storing your own ID. This API will be removed in SDK 44.`\n );\n warnedAboutDeviceId = true;\n }\n return nativeConstants.installationId;\n },\n get linkingUrl() {\n if (!warnedAboutLinkingUrl) {\n console.warn(\n `Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the Linking API directly. Constants.linkingUrl will be removed in SDK 44.`\n );\n warnedAboutLinkingUrl = true;\n }\n return nativeConstants.linkingUri;\n },\n get manifest(): AppManifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get manifest2(): Manifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n /**\n * Use `manifest` property by default.\n * This property is only used for internal purposes.\n * It behaves similarly to the original one, but suppresses warning upon no manifest available.\n * `expo-asset` uses it to prevent users from seeing mentioned warning.\n */\n get __unsafeNoWarnManifest(): AppManifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __unsafeNoWarnManifest2(): Manifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __rawManifest_TEST(): AppManifest | Manifest | null {\n return rawManifest;\n },\n set __rawManifest_TEST(value: AppManifest | Manifest | null) {\n rawManifest = value;\n },\n} as Constants;\n\nfunction isAppManifest(manifest: AppManifest | Manifest): manifest is AppManifest {\n return !isManifest(manifest);\n}\n\nfunction isManifest(manifest: AppManifest | Manifest): manifest is Manifest {\n return 'metadata' in manifest;\n}\n\nfunction getManifest(suppressWarning = false): AppManifest | Manifest | null {\n if (!rawManifest) {\n const invalidManifestType = rawManifest === null ? 'null' : 'undefined';\n if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.Bare &&\n Platform.OS !== 'web'\n ) {\n if (!suppressWarning) {\n console.warn(\n `Constants.manifest is ${invalidManifestType} because the embedded app.config could not be read. Ensure that you have installed the expo-constants build scripts if you need to read from Constants.manifest.`\n );\n }\n } else if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.StoreClient ||\n nativeConstants.executionEnvironment === ExecutionEnvironment.Standalone\n ) {\n // If we somehow get here, this is a truly exceptional state to be in.\n // Constants.manifest should *always* be defined in those contexts.\n throw new CodedError(\n 'ERR_CONSTANTS_MANIFEST_UNAVAILABLE',\n `Constants.manifest is ${invalidManifestType}, must be an object.`\n );\n }\n }\n return rawManifest;\n}\n\nexport default constants as Constants;\n"]}
|
|
1
|
+
{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, NativeModulesProxy } from 'expo-modules-core';\nimport { Platform, NativeModules } from 'react-native';\n\nimport {\n AndroidManifest,\n AppManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n Manifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n} from './Constants.types';\nimport ExponentConstants from './ExponentConstants';\n\nexport {\n AndroidManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n};\n\nif (!ExponentConstants) {\n console.warn(\n \"No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?\"\n );\n}\n\nlet rawManifest: AppManifest | Manifest | null = null;\n// If expo-updates defines a non-empty manifest, prefer that one\nif (NativeModulesProxy.ExpoUpdates) {\n let updatesManifest;\n if (NativeModulesProxy.ExpoUpdates.manifest) {\n updatesManifest = NativeModulesProxy.ExpoUpdates.manifest;\n } else if (NativeModulesProxy.ExpoUpdates.manifestString) {\n updatesManifest = JSON.parse(NativeModulesProxy.ExpoUpdates.manifestString);\n }\n if (updatesManifest && Object.keys(updatesManifest).length > 0) {\n rawManifest = updatesManifest;\n }\n}\n\n// If dev-launcher defines a non-empty manifest, prefer that one\nif (NativeModules.EXDevLauncher) {\n let devLauncherManifest;\n if (NativeModules.EXDevLauncher.manifestString) {\n devLauncherManifest = JSON.parse(NativeModules.EXDevLauncher.manifestString);\n }\n\n if (devLauncherManifest && Object.keys(devLauncherManifest).length > 0) {\n rawManifest = devLauncherManifest;\n }\n}\n\n// Fall back to ExponentConstants.manifest if we don't have one from Updates\nif (!rawManifest && ExponentConstants && ExponentConstants.manifest) {\n rawManifest = ExponentConstants.manifest;\n // On Android we pass the manifest in JSON form so this step is necessary\n if (typeof rawManifest === 'string') {\n rawManifest = JSON.parse(rawManifest);\n }\n}\n\nconst { name, appOwnership, ...nativeConstants } = (ExponentConstants || {}) as any;\n\nlet warnedAboutDeviceYearClass = false;\nlet warnedAboutIosModel = false;\nlet warnedAboutInstallationId = false;\nlet warnedAboutDeviceId = false;\nlet warnedAboutLinkingUrl = false;\n\nconst constants = {\n ...nativeConstants,\n // Ensure this is null in bare workflow\n appOwnership: appOwnership ?? null,\n // Deprecated fields\n get deviceYearClass() {\n if (!warnedAboutDeviceYearClass) {\n console.warn(\n `Constants.deviceYearClass has been deprecated in favor of expo-device's Device.deviceYearClass property. This API will be removed in SDK 45.`\n );\n warnedAboutDeviceYearClass = true;\n }\n return nativeConstants.deviceYearClass;\n },\n // Deprecated fields\n get installationId() {\n if (!warnedAboutInstallationId) {\n console.warn(\n `Constants.installationId has been deprecated in favor of generating and storing your own ID. Implement it using expo-application's androidId on Android and a storage API such as expo-secure-store on iOS and localStorage on the web. This API will be removed in SDK 44.`\n );\n warnedAboutInstallationId = true;\n }\n return nativeConstants.installationId;\n },\n // Legacy aliases\n get deviceId() {\n if (!warnedAboutDeviceId) {\n console.warn(\n `Constants.deviceId has been deprecated in favor of generating and storing your own ID. This API will be removed in SDK 44.`\n );\n warnedAboutDeviceId = true;\n }\n return nativeConstants.installationId;\n },\n get linkingUrl() {\n if (!warnedAboutLinkingUrl) {\n console.warn(\n `Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the Linking API directly. Constants.linkingUrl will be removed in SDK 44.`\n );\n warnedAboutLinkingUrl = true;\n }\n return nativeConstants.linkingUri;\n },\n get manifest(): AppManifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get manifest2(): Manifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n /**\n * Use `manifest` property by default.\n * This property is only used for internal purposes.\n * It behaves similarly to the original one, but suppresses warning upon no manifest available.\n * `expo-asset` uses it to prevent users from seeing mentioned warning.\n */\n get __unsafeNoWarnManifest(): AppManifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __unsafeNoWarnManifest2(): Manifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __rawManifest_TEST(): AppManifest | Manifest | null {\n return rawManifest;\n },\n set __rawManifest_TEST(value: AppManifest | Manifest | null) {\n rawManifest = value;\n },\n} as Constants;\n\n// Add deprecation warning for `platform.ios.model`\nif (constants?.platform?.ios) {\n const originalModel = nativeConstants.platform.ios.model;\n Object.defineProperty(constants.platform.ios, 'model', {\n get() {\n if (!warnedAboutIosModel) {\n console.warn(\n `Constants.platform.ios.model has been deprecated in favor of expo-device's Device.modelName property. This API will be removed in SDK 45.`\n );\n warnedAboutIosModel = true;\n }\n return originalModel;\n },\n // Prevent the warning from being thrown, or the value from being used when the user interacts with the entire object.\n enumerable: false,\n });\n}\n\nfunction isAppManifest(manifest: AppManifest | Manifest): manifest is AppManifest {\n return !isManifest(manifest);\n}\n\nfunction isManifest(manifest: AppManifest | Manifest): manifest is Manifest {\n return 'metadata' in manifest;\n}\n\nfunction getManifest(suppressWarning = false): AppManifest | Manifest | null {\n if (!rawManifest) {\n const invalidManifestType = rawManifest === null ? 'null' : 'undefined';\n if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.Bare &&\n Platform.OS !== 'web'\n ) {\n if (!suppressWarning) {\n console.warn(\n `Constants.manifest is ${invalidManifestType} because the embedded app.config could not be read. Ensure that you have installed the expo-constants build scripts if you need to read from Constants.manifest.`\n );\n }\n } else if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.StoreClient ||\n nativeConstants.executionEnvironment === ExecutionEnvironment.Standalone\n ) {\n // If we somehow get here, this is a truly exceptional state to be in.\n // Constants.manifest should *always* be defined in those contexts.\n throw new CodedError(\n 'ERR_CONSTANTS_MANIFEST_UNAVAILABLE',\n `Constants.manifest is ${invalidManifestType}, must be an object.`\n );\n }\n }\n return rawManifest;\n}\n\nexport default constants as Constants;\n"]}
|
|
@@ -17,6 +17,9 @@ export declare enum UserInterfaceIdiom {
|
|
|
17
17
|
export interface IOSManifest {
|
|
18
18
|
buildNumber: string;
|
|
19
19
|
platform: string;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Moved to `expo-device` - `Device.modelName`
|
|
22
|
+
*/
|
|
20
23
|
model: string | null;
|
|
21
24
|
userInterfaceIdiom: UserInterfaceIdiom;
|
|
22
25
|
systemVersion: string;
|
|
@@ -133,6 +136,9 @@ export interface NativeConstants {
|
|
|
133
136
|
appOwnership: AppOwnership | null;
|
|
134
137
|
debugMode: boolean;
|
|
135
138
|
deviceName?: string;
|
|
139
|
+
/**
|
|
140
|
+
* @deprecated Moved to `expo-device` - `Device.deviceYearClass`
|
|
141
|
+
*/
|
|
136
142
|
deviceYearClass: number | null;
|
|
137
143
|
executionEnvironment: ExecutionEnvironment;
|
|
138
144
|
experienceUrl: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Constants.types.js","sourceRoot":"","sources":["../src/Constants.types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,yCAAyB,CAAA;IACzB,6BAAa,CAAA;IACb,+BAAe,CAAA;AACjB,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAED,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,iDAAyB,CAAA;IACzB,mDAA2B,CAAA;AAC7B,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,yCAAmB,CAAA;IACnB,uCAAiB,CAAA;IACjB,iDAA2B,CAAA;AAC7B,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nexport enum AppOwnership {\n Standalone = 'standalone',\n Expo = 'expo',\n Guest = 'guest',\n}\n\nexport enum ExecutionEnvironment {\n Bare = 'bare',\n Standalone = 'standalone',\n StoreClient = 'storeClient',\n}\n\nexport enum UserInterfaceIdiom {\n Handset = 'handset',\n Tablet = 'tablet',\n Unsupported = 'unsupported',\n}\n\nexport interface IOSManifest {\n buildNumber: string;\n platform: string;\n model: string | null;\n userInterfaceIdiom: UserInterfaceIdiom;\n systemVersion: string;\n [key: string]: any;\n}\n\nexport interface AndroidManifest {\n versionCode: number;\n [key: string]: any;\n}\n\nexport interface WebManifest {\n [key: string]: any;\n}\n\nexport interface ManifestAsset {\n url: string;\n}\n\n/**\n * A modern manifest.\n */\nexport type Manifest = {\n id: string;\n createdAt: string;\n runtimeVersion: string;\n launchAsset: ManifestAsset;\n assets: ManifestAsset[];\n metadata: object;\n extra?: ClientScopingConfig & {\n expoClient?: ExpoClientConfig;\n expoGo?: ExpoGoConfig;\n eas?: EASConfig;\n };\n};\n\nexport type EASConfig = {\n /**\n * The ID for this project if it's using EAS. UUID. This value will not change when a project is transferred\n * between accounts or renamed.\n */\n projectId?: string;\n};\n\nexport type ClientScopingConfig = {\n /**\n * An opaque unique string for scoping client-side data to this project. This value\n * will not change when a project is transferred between accounts or renamed.\n */\n scopeKey?: string;\n};\n\nexport type ExpoGoConfig = {\n mainModuleName?: string;\n debuggerHost?: string;\n logUrl?: string;\n developer?: {\n tool?: string;\n [key: string]: any;\n };\n packagerOpts?: {\n hostType?: string;\n dev?: boolean;\n strict?: boolean;\n minify?: boolean;\n urlType?: string;\n urlRandomness?: string;\n lanType?: string;\n [key: string]: any;\n };\n};\n\nexport type ExpoClientConfig = ExpoConfig & {\n /** Published Apps Only */\n releaseId?: string;\n revisionId?: string;\n releaseChannel?: string;\n bundleUrl: string;\n hostUri?: string;\n publishedTime?: string;\n\n /**\n * The Expo account name and slug for this project.\n * @deprecated - Prefer `projectId` or `originalFullName` instead for identification and `scopeKey` for\n * scoping due to immutability.\n */\n id?: string;\n\n /**\n * The original Expo account name and slug for this project. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * will not change when a project is transferred between accounts or renamed.\n */\n originalFullName?: string;\n\n /**\n * The Expo account name and slug used for display purposes. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * may change when a project is transferred between accounts or renamed.\n */\n currentFullName?: string;\n};\n\n/**\n * A classic manifest https://docs.expo.io/guides/how-expo-works/#expo-manifest\n */\nexport type AppManifest = ExpoClientConfig &\n ExpoGoConfig &\n EASConfig &\n ClientScopingConfig & {\n [key: string]: any;\n };\n\nexport interface PlatformManifest {\n ios?: IOSManifest;\n android?: AndroidManifest;\n web?: WebManifest;\n detach?: {\n scheme?: string;\n [key: string]: any;\n };\n logUrl?: string;\n scheme?: string;\n hostUri?: string;\n developer?: string;\n [key: string]: any;\n}\n\nexport interface NativeConstants {\n name: 'ExponentConstants';\n appOwnership: AppOwnership | null;\n debugMode: boolean;\n deviceName?: string;\n deviceYearClass: number | null;\n executionEnvironment: ExecutionEnvironment;\n experienceUrl: string;\n // only nullable on web\n expoRuntimeVersion: string | null;\n /**\n * The version string of the Expo client currently running.\n * Returns `null` in bare workflow and web.\n */\n expoVersion: string | null;\n isDetached?: boolean;\n intentUri?: string;\n /**\n * @deprecated Constants.installationId is deprecated in favor of generating your own ID and\n * storing it. This API will be removed in SDK 44.\n */\n installationId: string;\n isDevice: boolean;\n isHeadless: boolean;\n linkingUri: string;\n nativeAppVersion: string | null;\n nativeBuildVersion: string | null;\n /**\n * Classic manifest for Expo apps using classic updates.\n * Returns `null` in bare workflow and when `manifest2` is non-null.\n */\n manifest: AppManifest | null;\n /**\n * New manifest for Expo apps using modern Expo Updates.\n * Returns `null` in bare workflow and when `manifest` is non-null.\n */\n manifest2: Manifest | null;\n sessionId: string;\n statusBarHeight: number;\n systemFonts: string[];\n systemVersion?: number;\n platform?: PlatformManifest;\n [key: string]: any;\n\n getWebViewUserAgentAsync: () => Promise<string | null>;\n}\n\nexport interface Constants extends NativeConstants {\n /**\n * @deprecated Constants.deviceId is deprecated in favor of generating your own ID and storing it.\n * This API will be removed in SDK 44.\n */\n deviceId?: string;\n /**\n * @deprecated Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the\n * Linking API directly. Constants.linkingUrl will be removed in SDK 44.\n */\n linkingUrl?: string;\n /**\n * @warning do not use this property. Use `manifest` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest?: AppManifest;\n /**\n * @warning do not use this property. Use `manifest2` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest2?: Manifest;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Constants.types.js","sourceRoot":"","sources":["../src/Constants.types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,yCAAyB,CAAA;IACzB,6BAAa,CAAA;IACb,+BAAe,CAAA;AACjB,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAED,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,iDAAyB,CAAA;IACzB,mDAA2B,CAAA;AAC7B,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,yCAAmB,CAAA;IACnB,uCAAiB,CAAA;IACjB,iDAA2B,CAAA;AAC7B,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nexport enum AppOwnership {\n Standalone = 'standalone',\n Expo = 'expo',\n Guest = 'guest',\n}\n\nexport enum ExecutionEnvironment {\n Bare = 'bare',\n Standalone = 'standalone',\n StoreClient = 'storeClient',\n}\n\nexport enum UserInterfaceIdiom {\n Handset = 'handset',\n Tablet = 'tablet',\n Unsupported = 'unsupported',\n}\n\nexport interface IOSManifest {\n buildNumber: string;\n platform: string;\n /**\n * @deprecated Moved to `expo-device` - `Device.modelName`\n */\n model: string | null;\n userInterfaceIdiom: UserInterfaceIdiom;\n systemVersion: string;\n [key: string]: any;\n}\n\nexport interface AndroidManifest {\n versionCode: number;\n [key: string]: any;\n}\n\nexport interface WebManifest {\n [key: string]: any;\n}\n\nexport interface ManifestAsset {\n url: string;\n}\n\n/**\n * A modern manifest.\n */\nexport type Manifest = {\n id: string;\n createdAt: string;\n runtimeVersion: string;\n launchAsset: ManifestAsset;\n assets: ManifestAsset[];\n metadata: object;\n extra?: ClientScopingConfig & {\n expoClient?: ExpoClientConfig;\n expoGo?: ExpoGoConfig;\n eas?: EASConfig;\n };\n};\n\nexport type EASConfig = {\n /**\n * The ID for this project if it's using EAS. UUID. This value will not change when a project is transferred\n * between accounts or renamed.\n */\n projectId?: string;\n};\n\nexport type ClientScopingConfig = {\n /**\n * An opaque unique string for scoping client-side data to this project. This value\n * will not change when a project is transferred between accounts or renamed.\n */\n scopeKey?: string;\n};\n\nexport type ExpoGoConfig = {\n mainModuleName?: string;\n debuggerHost?: string;\n logUrl?: string;\n developer?: {\n tool?: string;\n [key: string]: any;\n };\n packagerOpts?: {\n hostType?: string;\n dev?: boolean;\n strict?: boolean;\n minify?: boolean;\n urlType?: string;\n urlRandomness?: string;\n lanType?: string;\n [key: string]: any;\n };\n};\n\nexport type ExpoClientConfig = ExpoConfig & {\n /** Published Apps Only */\n releaseId?: string;\n revisionId?: string;\n releaseChannel?: string;\n bundleUrl: string;\n hostUri?: string;\n publishedTime?: string;\n\n /**\n * The Expo account name and slug for this project.\n * @deprecated - Prefer `projectId` or `originalFullName` instead for identification and `scopeKey` for\n * scoping due to immutability.\n */\n id?: string;\n\n /**\n * The original Expo account name and slug for this project. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * will not change when a project is transferred between accounts or renamed.\n */\n originalFullName?: string;\n\n /**\n * The Expo account name and slug used for display purposes. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * may change when a project is transferred between accounts or renamed.\n */\n currentFullName?: string;\n};\n\n/**\n * A classic manifest https://docs.expo.io/guides/how-expo-works/#expo-manifest\n */\nexport type AppManifest = ExpoClientConfig &\n ExpoGoConfig &\n EASConfig &\n ClientScopingConfig & {\n [key: string]: any;\n };\n\nexport interface PlatformManifest {\n ios?: IOSManifest;\n android?: AndroidManifest;\n web?: WebManifest;\n detach?: {\n scheme?: string;\n [key: string]: any;\n };\n logUrl?: string;\n scheme?: string;\n hostUri?: string;\n developer?: string;\n [key: string]: any;\n}\n\nexport interface NativeConstants {\n name: 'ExponentConstants';\n appOwnership: AppOwnership | null;\n debugMode: boolean;\n deviceName?: string;\n /**\n * @deprecated Moved to `expo-device` - `Device.deviceYearClass`\n */\n deviceYearClass: number | null;\n executionEnvironment: ExecutionEnvironment;\n experienceUrl: string;\n // only nullable on web\n expoRuntimeVersion: string | null;\n /**\n * The version string of the Expo client currently running.\n * Returns `null` in bare workflow and web.\n */\n expoVersion: string | null;\n isDetached?: boolean;\n intentUri?: string;\n /**\n * @deprecated Constants.installationId is deprecated in favor of generating your own ID and\n * storing it. This API will be removed in SDK 44.\n */\n installationId: string;\n isDevice: boolean;\n isHeadless: boolean;\n linkingUri: string;\n nativeAppVersion: string | null;\n nativeBuildVersion: string | null;\n /**\n * Classic manifest for Expo apps using classic updates.\n * Returns `null` in bare workflow and when `manifest2` is non-null.\n */\n manifest: AppManifest | null;\n /**\n * New manifest for Expo apps using modern Expo Updates.\n * Returns `null` in bare workflow and when `manifest` is non-null.\n */\n manifest2: Manifest | null;\n sessionId: string;\n statusBarHeight: number;\n systemFonts: string[];\n systemVersion?: number;\n platform?: PlatformManifest;\n [key: string]: any;\n\n getWebViewUserAgentAsync: () => Promise<string | null>;\n}\n\nexport interface Constants extends NativeConstants {\n /**\n * @deprecated Constants.deviceId is deprecated in favor of generating your own ID and storing it.\n * This API will be removed in SDK 44.\n */\n deviceId?: string;\n /**\n * @deprecated Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the\n * Linking API directly. Constants.linkingUrl will be removed in SDK 44.\n */\n linkingUrl?: string;\n /**\n * @warning do not use this property. Use `manifest` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest?: AppManifest;\n /**\n * @warning do not use this property. Use `manifest2` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest2?: Manifest;\n}\n"]}
|
|
@@ -130,10 +130,20 @@ EX_REGISTER_MODULE();
|
|
|
130
130
|
NSArray<NSString *> *familyNames = [UIFont familyNames];
|
|
131
131
|
NSMutableArray<NSString *> *fontNames = [NSMutableArray array];
|
|
132
132
|
for (NSString *familyName in familyNames) {
|
|
133
|
-
[
|
|
134
|
-
|
|
133
|
+
// "System Font" is added to [UIFont familyNames] in iOS 15, and the font names that
|
|
134
|
+
// correspond with it are dot prefixed .SFUI-* fonts which log the following warning
|
|
135
|
+
// when passed in to [UIFont fontNamesForFamilyName:name]:
|
|
136
|
+
// CoreText note: Client requested name “.SFUI-HeavyItalic”, it will get TimesNewRomanPSMT rather than the intended font.
|
|
137
|
+
// All system UI font access should be through proper APIs such as CTFontCreateUIFontForLanguage() or +[UIFont systemFontOfSize:]
|
|
138
|
+
//
|
|
139
|
+
if (![familyName isEqualToString:@"System Font"]) {
|
|
140
|
+
[fontNames addObject:familyName];
|
|
141
|
+
[fontNames addObjectsFromArray:[UIFont fontNamesForFamilyName:familyName]];
|
|
142
|
+
}
|
|
135
143
|
}
|
|
136
|
-
|
|
144
|
+
|
|
145
|
+
// Remove duplciates and sort alphabetically
|
|
146
|
+
return [[[NSSet setWithArray:fontNames] allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
|
137
147
|
}
|
|
138
148
|
|
|
139
149
|
# pragma mark - device info
|
|
@@ -187,21 +197,13 @@ EX_REGISTER_MODULE();
|
|
|
187
197
|
@"Watch6,4": @"Apple Watch Series 6",
|
|
188
198
|
|
|
189
199
|
// iPhone
|
|
190
|
-
|
|
191
|
-
@"iPhone1,2": @"iPhone 3G",
|
|
192
|
-
@"iPhone2,1": @"iPhone 3GS",
|
|
193
|
-
@"iPhone3,1": @"iPhone 4",
|
|
194
|
-
@"iPhone3,2": @"iPhone 4",
|
|
195
|
-
@"iPhone3,3": @"iPhone 4 (CDMA)",
|
|
196
|
-
@"iPhone4,1": @"iPhone 4S",
|
|
197
|
-
@"iPhone5,1": @"iPhone 5 (GSM)",
|
|
198
|
-
@"iPhone5,2": @"iPhone 5 (GSM+CDMA)",
|
|
199
|
-
@"iPhone5,3": @"iPhone 5C (GSM)",
|
|
200
|
-
@"iPhone5,4": @"iPhone 5C (GSM+CDMA)",
|
|
200
|
+
// iOS 12+
|
|
201
201
|
@"iPhone6,1": @"iPhone 5S (GSM)",
|
|
202
202
|
@"iPhone6,2": @"iPhone 5S (GSM+CDMA)",
|
|
203
203
|
@"iPhone7,1": @"iPhone 6 Plus",
|
|
204
204
|
@"iPhone7,2": @"iPhone 6",
|
|
205
|
+
|
|
206
|
+
// iOS 13+
|
|
205
207
|
@"iPhone8,1": @"iPhone 6s",
|
|
206
208
|
@"iPhone8,2": @"iPhone 6s Plus",
|
|
207
209
|
@"iPhone8,4": @"iPhone SE",
|
|
@@ -228,6 +230,11 @@ EX_REGISTER_MODULE();
|
|
|
228
230
|
@"iPhone13,3": @"iPhone 12 Pro",
|
|
229
231
|
@"iPhone13,4": @"iPhone 12 Pro Max",
|
|
230
232
|
|
|
233
|
+
@"iPhone14,2": @"iPhone 13 Pro",
|
|
234
|
+
@"iPhone14,3": @"iPhone 13 Pro Max",
|
|
235
|
+
@"iPhone14,4": @"iPhone 13 Mini",
|
|
236
|
+
@"iPhone14,5": @"iPhone 13",
|
|
237
|
+
|
|
231
238
|
// iPod
|
|
232
239
|
@"iPod1,1": @"iPod Touch",
|
|
233
240
|
@"iPod2,1": @"iPod Touch 2G",
|
|
@@ -287,11 +294,25 @@ EX_REGISTER_MODULE();
|
|
|
287
294
|
@"iPad8,6": @"iPad Pro 12.9-inch (3rd generation)",
|
|
288
295
|
@"iPad8,7": @"iPad Pro 12.9-inch (3rd generation)",
|
|
289
296
|
@"iPad8,8": @"iPad Pro 12.9-inch (3rd generation)",
|
|
290
|
-
@"iPad11,1": @"iPad Mini
|
|
291
|
-
@"iPad11,2": @"iPad Mini
|
|
292
|
-
@"iPad11,3": @"iPad Air (3rd generation)",
|
|
297
|
+
@"iPad11,1": @"iPad Mini (5th generation) (WiFi)",
|
|
298
|
+
@"iPad11,2": @"iPad Mini (5th generation)",
|
|
299
|
+
@"iPad11,3": @"iPad Air (3rd generation) (WiFi)",
|
|
293
300
|
@"iPad11,4": @"iPad Air (3rd generation)",
|
|
294
301
|
|
|
302
|
+
@"iPad11,6": @"iPad (8th generation)",
|
|
303
|
+
@"iPad11,7": @"iPad (8th generation)",
|
|
304
|
+
@"iPad13,1": @"iPad Air (4th generation) (WiFi)",
|
|
305
|
+
@"iPad13,2": @"iPad Air (4th generation) (WiFi+Cellular)",
|
|
306
|
+
@"iPad13,4": @"iPad Pro 11 inch (3th generation)",
|
|
307
|
+
@"iPad13,5": @"iPad Pro 11 inch (3th generation)",
|
|
308
|
+
@"iPad13,6": @"iPad Pro 11 inch (3th generation)",
|
|
309
|
+
@"iPad13,7": @"iPad Pro 11 inch (3th generation)",
|
|
310
|
+
@"iPad13,8": @"iPad Pro 12.9 inch (5th generation)",
|
|
311
|
+
@"iPad13,9": @"iPad Pro 12.9 inch (5th generation)",
|
|
312
|
+
@"iPad13,10": @"iPad Pro 12.9 inch (5th generation)",
|
|
313
|
+
@"iPad13,11": @"iPad Pro 12.9 inch (5th generation)",
|
|
314
|
+
@"iPad14,1": @"iPad Mini (6th generation) (WiFi)",
|
|
315
|
+
@"iPad14,2": @"iPad Mini (6th generation) (WiFi+Cellular)",
|
|
295
316
|
// Simulator
|
|
296
317
|
@"i386": @"Simulator",
|
|
297
318
|
@"arm64": @"Simulator",
|
|
@@ -322,30 +343,6 @@ EX_REGISTER_MODULE();
|
|
|
322
343
|
|
|
323
344
|
// TODO: apple TV and apple watch
|
|
324
345
|
NSDictionary *mapping = @{
|
|
325
|
-
// iPhone 1
|
|
326
|
-
@"iPhone1,1": @2007,
|
|
327
|
-
|
|
328
|
-
// iPhone 3G
|
|
329
|
-
@"iPhone1,2": @2008,
|
|
330
|
-
|
|
331
|
-
// iPhone 3GS
|
|
332
|
-
@"iPhone2,1": @2009,
|
|
333
|
-
|
|
334
|
-
// iPhone 4
|
|
335
|
-
@"iPhone3,1": @2010,
|
|
336
|
-
@"iPhone3,2": @2010,
|
|
337
|
-
@"iPhone3,3": @2010,
|
|
338
|
-
|
|
339
|
-
// iPhone 4S
|
|
340
|
-
@"iPhone4,1": @2011,
|
|
341
|
-
|
|
342
|
-
// iPhone 5
|
|
343
|
-
@"iPhone5,1": @2012,
|
|
344
|
-
@"iPhone5,2": @2012,
|
|
345
|
-
|
|
346
|
-
// iPhone 5S and 5C
|
|
347
|
-
@"iPhone5,3": @2013,
|
|
348
|
-
@"iPhone5,4": @2013,
|
|
349
346
|
@"iPhone6,1": @2013,
|
|
350
347
|
@"iPhone6,2": @2013,
|
|
351
348
|
|
|
@@ -371,7 +368,16 @@ EX_REGISTER_MODULE();
|
|
|
371
368
|
@"iPhone12,1": @2019, // iPhone 11
|
|
372
369
|
@"iPhone12,3": @2019, // iPhone 11 Pro
|
|
373
370
|
@"iPhone12,5": @2019, // iPhone 11 Pro Max
|
|
374
|
-
|
|
371
|
+
@"iPhone12,8": @2020, // iPhone SE 2nd Gen
|
|
372
|
+
@"iPhone13,1": @2020, // iPhone 12 mini
|
|
373
|
+
@"iPhone13,2": @2020, // iPhone 12
|
|
374
|
+
@"iPhone13,3": @2020, // iPhone 12 Pro
|
|
375
|
+
@"iPhone13,4": @2020, // iPhone 12 Pro Max
|
|
376
|
+
@"iPhone14,2": @2021, // iPhone 13 Pro
|
|
377
|
+
@"iPhone14,3": @2021, // iPhone 13 Pro Max
|
|
378
|
+
@"iPhone14,4": @2021, // iPhone 13 Mini
|
|
379
|
+
@"iPhone14,5": @2021, // iPhone 13
|
|
380
|
+
|
|
375
381
|
// iPod
|
|
376
382
|
@"iPod1,1": @2007,
|
|
377
383
|
@"iPod2,1": @2008,
|
|
@@ -435,6 +441,20 @@ EX_REGISTER_MODULE();
|
|
|
435
441
|
@"iPad11,2": @2019, // iPad Mini 5th Gen
|
|
436
442
|
@"iPad11,3": @2019, // iPad Air 3rd Gen (WiFi)
|
|
437
443
|
@"iPad11,4": @2019, // iPad Air 3rd Gen
|
|
444
|
+
@"iPad11,6": @2020, // iPad 8th Gen
|
|
445
|
+
@"iPad11,7": @2020, // iPad 8th Gen
|
|
446
|
+
@"iPad13,1": @2020, // iPad Air 4th Gen (WiFi)
|
|
447
|
+
@"iPad13,2": @2020, // iPad Air 4th Gen (WiFi+Cellular)
|
|
448
|
+
@"iPad13,4": @2021, // iPad Pro 11-inch 3rd Gen
|
|
449
|
+
@"iPad13,5": @2021, // iPad Pro 11-inch 3rd Gen
|
|
450
|
+
@"iPad13,6": @2021, // iPad Pro 11-inch 3rd Gen
|
|
451
|
+
@"iPad13,7": @2021, // iPad Pro 11-inch 3rd Gen
|
|
452
|
+
@"iPad13,8": @2021, // iPad Pro 12.9-inch 5th Gen
|
|
453
|
+
@"iPad13,9": @2021, // iPad Pro 12.9-inch 5th Gen
|
|
454
|
+
@"iPad13,10": @2021, // iPad Pro 12.9-inch 5th Gen
|
|
455
|
+
@"iPad13,11": @2021, // iPad Pro 12.9-inch 5th Gen
|
|
456
|
+
@"iPad14,1": @2021, // iPad mini (6th generation) (WiFi)
|
|
457
|
+
@"iPad14,2": @2021 // iPad mini (6th generation) (WiFi + cellular)
|
|
438
458
|
};
|
|
439
459
|
|
|
440
460
|
NSNumber *deviceYear = mapping[platform];
|
package/ios/EXConstants.podspec
CHANGED
|
@@ -10,8 +10,9 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.license = package['license']
|
|
11
11
|
s.author = package['author']
|
|
12
12
|
s.homepage = package['homepage']
|
|
13
|
-
s.platform = :ios, '
|
|
13
|
+
s.platform = :ios, '12.0'
|
|
14
14
|
s.source = { git: 'https://github.com/expo/expo.git' }
|
|
15
|
+
s.static_framework = true
|
|
15
16
|
|
|
16
17
|
s.dependency 'ExpoModulesCore'
|
|
17
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-constants",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.1.2",
|
|
4
4
|
"description": "Provides system information that remains constant throughout the lifetime of your app.",
|
|
5
5
|
"main": "build/Constants.js",
|
|
6
6
|
"types": "build/Constants.d.ts",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"preset": "expo-module-scripts"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@expo/config": "^
|
|
38
|
-
"expo-modules-core": "~0.
|
|
37
|
+
"@expo/config": "^5.0.9",
|
|
38
|
+
"expo-modules-core": "~0.4.4",
|
|
39
39
|
"uuid": "^3.3.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"expo-module-scripts": "^2.0.0"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "4fa0497a180ae707fa860cb03858630ab7af19f4"
|
|
45
45
|
}
|
|
@@ -2,29 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
set -eo pipefail
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
exit 0;
|
|
8
|
-
elif [[ "$CONFIGURATION" == *Debug* ]]; then
|
|
9
|
-
if [[ "$FORCE_BUNDLING" ]]; then
|
|
10
|
-
echo "FORCE_BUNDLING enabled; continuing get-app-config-ios.sh."
|
|
11
|
-
else
|
|
12
|
-
exit 0;
|
|
13
|
-
fi
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
DEST="$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH"
|
|
5
|
+
DEST="$CONFIGURATION_BUILD_DIR"
|
|
6
|
+
RESOURCE_BUNDLE_NAME="EXConstants.bundle"
|
|
17
7
|
NODE_BINARY=${NODE_BINARY:-node}
|
|
18
8
|
|
|
19
|
-
# ref: https://github.com/facebook/react-native/blob/c974cbff04a8d90ac0f856dbada3fc5a75c75b49/scripts/react-native-xcode.sh#L59-L65
|
|
20
|
-
# Path to expo-constants folder inside node_modules
|
|
21
|
-
EXPO_CONSTANTS_PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
22
|
-
# If PROJECT_ROOT is not specified, fallback to use Xcode PROJECT_DIR
|
|
23
|
-
PROJECT_ROOT=${PROJECT_ROOT:-"$PROJECT_DIR"}
|
|
24
|
-
PROJECT_ROOT=${PROJECT_ROOT:-"$EXPO_CONSTANTS_PACKAGE_DIR/../.."}
|
|
25
|
-
|
|
26
|
-
cd "$PROJECT_ROOT" || exit
|
|
27
|
-
|
|
28
9
|
if ! [ -x "$(command -v "$NODE_BINARY")" ]; then
|
|
29
10
|
echo 'Error: cannot find the node binary. Try setting the NODE_BINARY variable in the ' \
|
|
30
11
|
'"Bundle React Native code and images" Build Phase to the absolute path to your node binary. ' \
|
|
@@ -32,10 +13,23 @@ if ! [ -x "$(command -v "$NODE_BINARY")" ]; then
|
|
|
32
13
|
exit 1
|
|
33
14
|
fi
|
|
34
15
|
|
|
35
|
-
# For
|
|
36
|
-
|
|
37
|
-
|
|
16
|
+
# For classic main project build phases integration, will be no-op to prevent duplicated app.config creation.
|
|
17
|
+
#
|
|
18
|
+
# `$PROJECT_DIR` is passed by Xcode as the directory to the xcodeproj file.
|
|
19
|
+
# in classic main project setup it is something like /path/to/app/ios
|
|
20
|
+
# in new style pod project setup it is something like /path/to/app/ios/Pods
|
|
21
|
+
PROJECT_DIR_BASENAME=$(basename $PROJECT_DIR)
|
|
22
|
+
if [ "x$PROJECT_DIR_BASENAME" != "xPods" ]; then
|
|
38
23
|
exit 0
|
|
39
24
|
fi
|
|
40
25
|
|
|
41
|
-
|
|
26
|
+
# ref: https://github.com/facebook/react-native/blob/c974cbff04a8d90ac0f856dbada3fc5a75c75b49/scripts/react-native-xcode.sh#L59-L65
|
|
27
|
+
# Path to expo-constants folder inside node_modules
|
|
28
|
+
EXPO_CONSTANTS_PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
29
|
+
# If PROJECT_ROOT is not specified, fallback to use Xcode PROJECT_DIR
|
|
30
|
+
PROJECT_ROOT=${PROJECT_ROOT:-"$PROJECT_DIR/../.."}
|
|
31
|
+
PROJECT_ROOT=${PROJECT_ROOT:-"$EXPO_CONSTANTS_PACKAGE_DIR/../.."}
|
|
32
|
+
|
|
33
|
+
cd "$PROJECT_ROOT" || exit
|
|
34
|
+
|
|
35
|
+
"$NODE_BINARY" "${EXPO_CONSTANTS_PACKAGE_DIR}/scripts/getAppConfig.js" "$PROJECT_ROOT" "$DEST/$RESOURCE_BUNDLE_NAME"
|
package/src/Constants.ts
CHANGED
|
@@ -71,6 +71,8 @@ if (!rawManifest && ExponentConstants && ExponentConstants.manifest) {
|
|
|
71
71
|
|
|
72
72
|
const { name, appOwnership, ...nativeConstants } = (ExponentConstants || {}) as any;
|
|
73
73
|
|
|
74
|
+
let warnedAboutDeviceYearClass = false;
|
|
75
|
+
let warnedAboutIosModel = false;
|
|
74
76
|
let warnedAboutInstallationId = false;
|
|
75
77
|
let warnedAboutDeviceId = false;
|
|
76
78
|
let warnedAboutLinkingUrl = false;
|
|
@@ -80,6 +82,16 @@ const constants = {
|
|
|
80
82
|
// Ensure this is null in bare workflow
|
|
81
83
|
appOwnership: appOwnership ?? null,
|
|
82
84
|
// Deprecated fields
|
|
85
|
+
get deviceYearClass() {
|
|
86
|
+
if (!warnedAboutDeviceYearClass) {
|
|
87
|
+
console.warn(
|
|
88
|
+
`Constants.deviceYearClass has been deprecated in favor of expo-device's Device.deviceYearClass property. This API will be removed in SDK 45.`
|
|
89
|
+
);
|
|
90
|
+
warnedAboutDeviceYearClass = true;
|
|
91
|
+
}
|
|
92
|
+
return nativeConstants.deviceYearClass;
|
|
93
|
+
},
|
|
94
|
+
// Deprecated fields
|
|
83
95
|
get installationId() {
|
|
84
96
|
if (!warnedAboutInstallationId) {
|
|
85
97
|
console.warn(
|
|
@@ -150,6 +162,24 @@ const constants = {
|
|
|
150
162
|
},
|
|
151
163
|
} as Constants;
|
|
152
164
|
|
|
165
|
+
// Add deprecation warning for `platform.ios.model`
|
|
166
|
+
if (constants?.platform?.ios) {
|
|
167
|
+
const originalModel = nativeConstants.platform.ios.model;
|
|
168
|
+
Object.defineProperty(constants.platform.ios, 'model', {
|
|
169
|
+
get() {
|
|
170
|
+
if (!warnedAboutIosModel) {
|
|
171
|
+
console.warn(
|
|
172
|
+
`Constants.platform.ios.model has been deprecated in favor of expo-device's Device.modelName property. This API will be removed in SDK 45.`
|
|
173
|
+
);
|
|
174
|
+
warnedAboutIosModel = true;
|
|
175
|
+
}
|
|
176
|
+
return originalModel;
|
|
177
|
+
},
|
|
178
|
+
// Prevent the warning from being thrown, or the value from being used when the user interacts with the entire object.
|
|
179
|
+
enumerable: false,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
153
183
|
function isAppManifest(manifest: AppManifest | Manifest): manifest is AppManifest {
|
|
154
184
|
return !isManifest(manifest);
|
|
155
185
|
}
|
package/src/Constants.types.ts
CHANGED
|
@@ -21,6 +21,9 @@ export enum UserInterfaceIdiom {
|
|
|
21
21
|
export interface IOSManifest {
|
|
22
22
|
buildNumber: string;
|
|
23
23
|
platform: string;
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated Moved to `expo-device` - `Device.modelName`
|
|
26
|
+
*/
|
|
24
27
|
model: string | null;
|
|
25
28
|
userInterfaceIdiom: UserInterfaceIdiom;
|
|
26
29
|
systemVersion: string;
|
|
@@ -154,6 +157,9 @@ export interface NativeConstants {
|
|
|
154
157
|
appOwnership: AppOwnership | null;
|
|
155
158
|
debugMode: boolean;
|
|
156
159
|
deviceName?: string;
|
|
160
|
+
/**
|
|
161
|
+
* @deprecated Moved to `expo-device` - `Device.deviceYearClass`
|
|
162
|
+
*/
|
|
157
163
|
deviceYearClass: number | null;
|
|
158
164
|
executionEnvironment: ExecutionEnvironment;
|
|
159
165
|
experienceUrl: string;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
-
|
|
3
|
-
package expo.modules.constants;
|
|
4
|
-
|
|
5
|
-
import android.content.Context;
|
|
6
|
-
|
|
7
|
-
import java.util.Map;
|
|
8
|
-
|
|
9
|
-
import expo.modules.core.ExportedModule;
|
|
10
|
-
import expo.modules.core.ModuleRegistry;
|
|
11
|
-
import expo.modules.core.Promise;
|
|
12
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
13
|
-
|
|
14
|
-
import expo.modules.interfaces.constants.ConstantsInterface;
|
|
15
|
-
|
|
16
|
-
public class ConstantsModule extends ExportedModule {
|
|
17
|
-
private ModuleRegistry mModuleRegistry;
|
|
18
|
-
|
|
19
|
-
public ConstantsModule(Context context) {
|
|
20
|
-
super(context);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@Override
|
|
24
|
-
public Map<String, Object> getConstants() {
|
|
25
|
-
ConstantsInterface constantsService = mModuleRegistry.getModule(ConstantsInterface.class);
|
|
26
|
-
return constantsService.getConstants();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@Override
|
|
30
|
-
public String getName() {
|
|
31
|
-
return "ExponentConstants";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@Override
|
|
35
|
-
public void onCreate(ModuleRegistry moduleRegistry) {
|
|
36
|
-
mModuleRegistry = moduleRegistry;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
@ExpoMethod
|
|
40
|
-
public void getWebViewUserAgentAsync(Promise promise) {
|
|
41
|
-
String userAgent = System.getProperty("http.agent");
|
|
42
|
-
promise.resolve(userAgent);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
package expo.modules.constants;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
|
|
5
|
-
import java.util.Collections;
|
|
6
|
-
import java.util.List;
|
|
7
|
-
|
|
8
|
-
import expo.modules.core.ExportedModule;
|
|
9
|
-
import expo.modules.core.BasePackage;
|
|
10
|
-
import expo.modules.core.interfaces.InternalModule;
|
|
11
|
-
|
|
12
|
-
public class ConstantsPackage extends BasePackage {
|
|
13
|
-
@Override
|
|
14
|
-
public List<InternalModule> createInternalModules(Context context) {
|
|
15
|
-
return Collections.singletonList((InternalModule) new ConstantsService(context));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
@Override
|
|
19
|
-
public List<ExportedModule> createExportedModules(Context context) {
|
|
20
|
-
return Collections.singletonList((ExportedModule) new ConstantsModule(context));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
package expo.modules.constants;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
import android.content.pm.PackageInfo;
|
|
5
|
-
import android.content.pm.PackageManager;
|
|
6
|
-
import android.content.res.Resources;
|
|
7
|
-
import android.os.Build;
|
|
8
|
-
import androidx.annotation.Nullable;
|
|
9
|
-
import android.util.DisplayMetrics;
|
|
10
|
-
import android.util.Log;
|
|
11
|
-
|
|
12
|
-
import com.facebook.device.yearclass.YearClass;
|
|
13
|
-
|
|
14
|
-
import java.io.FileNotFoundException;
|
|
15
|
-
import java.io.InputStream;
|
|
16
|
-
import java.nio.charset.StandardCharsets;
|
|
17
|
-
import java.util.ArrayList;
|
|
18
|
-
import java.util.Collections;
|
|
19
|
-
import java.util.HashMap;
|
|
20
|
-
import java.util.List;
|
|
21
|
-
import java.util.Map;
|
|
22
|
-
import java.util.UUID;
|
|
23
|
-
|
|
24
|
-
import org.apache.commons.io.IOUtils;
|
|
25
|
-
import expo.modules.core.interfaces.InternalModule;
|
|
26
|
-
|
|
27
|
-
import expo.modules.interfaces.constants.ConstantsInterface;
|
|
28
|
-
|
|
29
|
-
public class ConstantsService implements InternalModule, ConstantsInterface {
|
|
30
|
-
private static final String TAG = ConstantsService.class.getSimpleName();
|
|
31
|
-
|
|
32
|
-
protected Context mContext;
|
|
33
|
-
protected int mStatusBarHeight = 0;
|
|
34
|
-
private String mSessionId = UUID.randomUUID().toString();
|
|
35
|
-
private ExponentInstallationId mExponentInstallationId;
|
|
36
|
-
private static final String CONFIG_FILE_NAME = "app.config";
|
|
37
|
-
|
|
38
|
-
public enum ExecutionEnvironment {
|
|
39
|
-
BARE("bare"),
|
|
40
|
-
STANDALONE("standalone"),
|
|
41
|
-
STORE_CLIENT("storeClient");
|
|
42
|
-
|
|
43
|
-
private final String mString;
|
|
44
|
-
|
|
45
|
-
ExecutionEnvironment(String string) {
|
|
46
|
-
mString = string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public String getString() {
|
|
50
|
-
return mString;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private static int convertPixelsToDp(float px, Context context) {
|
|
55
|
-
Resources resources = context.getResources();
|
|
56
|
-
DisplayMetrics metrics = resources.getDisplayMetrics();
|
|
57
|
-
float dp = px / (metrics.densityDpi / 160f);
|
|
58
|
-
return (int) dp;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
public ConstantsService(Context context) {
|
|
62
|
-
super();
|
|
63
|
-
mContext = context;
|
|
64
|
-
mExponentInstallationId = new ExponentInstallationId(mContext);
|
|
65
|
-
|
|
66
|
-
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
|
67
|
-
|
|
68
|
-
if (resourceId > 0) {
|
|
69
|
-
int statusBarHeightPixels = context.getResources().getDimensionPixelSize(resourceId);
|
|
70
|
-
// Convert from pixels to dip
|
|
71
|
-
mStatusBarHeight = convertPixelsToDp(statusBarHeightPixels, context);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
@Override
|
|
76
|
-
public List<Class> getExportedInterfaces() {
|
|
77
|
-
return Collections.singletonList((Class) ConstantsInterface.class);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@Nullable
|
|
81
|
-
public Map<String, Object> getConstants() {
|
|
82
|
-
Map<String, Object> constants = new HashMap<>();
|
|
83
|
-
|
|
84
|
-
constants.put("sessionId", mSessionId);
|
|
85
|
-
constants.put("executionEnvironment", ExecutionEnvironment.BARE.getString());
|
|
86
|
-
constants.put("statusBarHeight", getStatusBarHeight());
|
|
87
|
-
constants.put("deviceYearClass", getDeviceYearClass());
|
|
88
|
-
constants.put("deviceName", getDeviceName());
|
|
89
|
-
constants.put("isDevice", getIsDevice());
|
|
90
|
-
constants.put("systemFonts", getSystemFonts());
|
|
91
|
-
constants.put("systemVersion", getSystemVersion());
|
|
92
|
-
constants.put("installationId", getOrCreateInstallationId());
|
|
93
|
-
constants.put("manifest", getAppConfig());
|
|
94
|
-
|
|
95
|
-
PackageManager packageManager = mContext.getPackageManager();
|
|
96
|
-
try {
|
|
97
|
-
PackageInfo pInfo = packageManager.getPackageInfo(mContext.getPackageName(), 0);
|
|
98
|
-
constants.put("nativeAppVersion", pInfo.versionName);
|
|
99
|
-
|
|
100
|
-
int versionCode = (int)getLongVersionCode(pInfo);
|
|
101
|
-
constants.put("nativeBuildVersion", Integer.toString(versionCode));
|
|
102
|
-
} catch (PackageManager.NameNotFoundException e) {
|
|
103
|
-
Log.e(TAG, "Exception: ", e);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
Map<String, Object> platform = new HashMap<>();
|
|
107
|
-
Map<String, Object> androidPlatform = new HashMap<>();
|
|
108
|
-
|
|
109
|
-
platform.put("android", androidPlatform);
|
|
110
|
-
constants.put("platform", platform);
|
|
111
|
-
return constants;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
public String getAppScopeKey() {
|
|
115
|
-
// Just use package name in vanilla React Native apps.
|
|
116
|
-
return mContext.getPackageName();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
public String getAppOwnership() {
|
|
120
|
-
return "guest";
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
public String getDeviceName() {
|
|
124
|
-
return Build.MODEL;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
public int getDeviceYearClass() {
|
|
128
|
-
return YearClass.get(mContext);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
public boolean getIsDevice() {
|
|
132
|
-
return !isRunningOnGenymotion() && !isRunningOnStockEmulator();
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
public int getStatusBarHeight() {
|
|
136
|
-
return mStatusBarHeight;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
public String getSystemVersion() {
|
|
140
|
-
return Build.VERSION.RELEASE;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
public String getOrCreateInstallationId() {
|
|
144
|
-
return mExponentInstallationId.getOrCreateUUID();
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
public List<String> getSystemFonts() {
|
|
148
|
-
// From https://github.com/dabit3/react-native-fonts
|
|
149
|
-
List<String> result = new ArrayList<>();
|
|
150
|
-
result.add("normal");
|
|
151
|
-
result.add("notoserif");
|
|
152
|
-
result.add("sans-serif");
|
|
153
|
-
result.add("sans-serif-light");
|
|
154
|
-
result.add("sans-serif-thin");
|
|
155
|
-
result.add("sans-serif-condensed");
|
|
156
|
-
result.add("sans-serif-medium");
|
|
157
|
-
result.add("serif");
|
|
158
|
-
result.add("Roboto");
|
|
159
|
-
result.add("monospace");
|
|
160
|
-
return result;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private static boolean isRunningOnGenymotion() {
|
|
164
|
-
return Build.FINGERPRINT.contains("vbox");
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
private static boolean isRunningOnStockEmulator() {
|
|
168
|
-
return Build.FINGERPRINT.contains("generic");
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
private static long getLongVersionCode(PackageInfo info) {
|
|
172
|
-
if (Build.VERSION.SDK_INT >= 28) {
|
|
173
|
-
return info.getLongVersionCode();
|
|
174
|
-
}
|
|
175
|
-
return info.versionCode;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private @Nullable String getAppConfig() {
|
|
179
|
-
try (InputStream stream = mContext.getAssets().open(CONFIG_FILE_NAME)) {
|
|
180
|
-
return IOUtils.toString(stream, StandardCharsets.UTF_8);
|
|
181
|
-
} catch (FileNotFoundException e) {
|
|
182
|
-
// do nothing, expected in managed apps
|
|
183
|
-
} catch (Exception e) {
|
|
184
|
-
Log.e(TAG, "Error reading embedded app config", e);
|
|
185
|
-
}
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
package expo.modules.constants;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
import android.content.SharedPreferences;
|
|
5
|
-
import android.util.Log;
|
|
6
|
-
|
|
7
|
-
import java.io.BufferedReader;
|
|
8
|
-
import java.io.File;
|
|
9
|
-
import java.io.FileReader;
|
|
10
|
-
import java.io.FileWriter;
|
|
11
|
-
import java.io.IOException;
|
|
12
|
-
import java.util.UUID;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* An installation ID provider - it solves two purposes:
|
|
16
|
-
* - in installations that have a legacy UUID persisted
|
|
17
|
-
* in shared-across-expo-modules SharedPreferences,
|
|
18
|
-
* migrates the UUID from there to a non-backed-up file,
|
|
19
|
-
* - provides/creates a UUID unique per an installation.
|
|
20
|
-
*
|
|
21
|
-
* Similar class exists in expoview and expo-notifications.
|
|
22
|
-
*/
|
|
23
|
-
public class ExponentInstallationId {
|
|
24
|
-
private static final String TAG = ExponentInstallationId.class.getSimpleName();
|
|
25
|
-
|
|
26
|
-
public static final String LEGACY_UUID_KEY = "uuid";
|
|
27
|
-
public static final String UUID_FILE_NAME = "expo_installation_uuid.txt";
|
|
28
|
-
private static final String PREFERENCES_FILE_NAME = "host.exp.exponent.SharedPreferences";
|
|
29
|
-
|
|
30
|
-
private String mUuid;
|
|
31
|
-
private Context mContext;
|
|
32
|
-
private SharedPreferences mSharedPreferences;
|
|
33
|
-
|
|
34
|
-
/* package */ ExponentInstallationId(Context context) {
|
|
35
|
-
mContext = context;
|
|
36
|
-
mSharedPreferences = context.getSharedPreferences(PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public String getUUID() {
|
|
40
|
-
// If it has already been cached, return the value.
|
|
41
|
-
if (mUuid != null) {
|
|
42
|
-
return mUuid;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Read from non-backed-up storage
|
|
46
|
-
File uuidFile = getNonBackedUpUuidFile();
|
|
47
|
-
try (FileReader fileReader = new FileReader(uuidFile);
|
|
48
|
-
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
|
|
49
|
-
// Cache for future calls
|
|
50
|
-
mUuid = UUID.fromString(bufferedReader.readLine()).toString();
|
|
51
|
-
} catch (IOException | IllegalArgumentException e) {
|
|
52
|
-
// do nothing, try other sources
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// We could have returned inside try clause,
|
|
56
|
-
// but putting it like this here makes it immediately
|
|
57
|
-
// visible.
|
|
58
|
-
if (mUuid != null) {
|
|
59
|
-
return mUuid;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// In November 2020 we decided to move installationID (backed by LEGACY_UUID_KEY value) from backed-up SharedPreferences
|
|
63
|
-
// to a non-backed-up text file to fix issues where devices restored from backups have the same installation IDs
|
|
64
|
-
// as the devices where the backup was created.
|
|
65
|
-
String legacyUuid = mSharedPreferences.getString(LEGACY_UUID_KEY, null);
|
|
66
|
-
if (legacyUuid != null) {
|
|
67
|
-
mUuid = legacyUuid;
|
|
68
|
-
|
|
69
|
-
boolean uuidHasBeenSuccessfullyMigrated = true;
|
|
70
|
-
|
|
71
|
-
try (FileWriter writer = new FileWriter(uuidFile)) {
|
|
72
|
-
writer.write(legacyUuid);
|
|
73
|
-
} catch (IOException e) {
|
|
74
|
-
uuidHasBeenSuccessfullyMigrated = false;
|
|
75
|
-
Log.e(TAG, "Error while migrating UUID from legacy storage. " + e);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// We only remove the value from old storage once it's set and saved in the new storage.
|
|
79
|
-
if (uuidHasBeenSuccessfullyMigrated) {
|
|
80
|
-
mSharedPreferences.edit().remove(LEGACY_UUID_KEY).apply();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Return either value from legacy storage or null
|
|
85
|
-
return mUuid;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
public String getOrCreateUUID() {
|
|
89
|
-
String uuid = getUUID();
|
|
90
|
-
if (uuid != null) {
|
|
91
|
-
return uuid;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// We persist the new UUID in "session storage"
|
|
95
|
-
// so that if writing to persistent storage
|
|
96
|
-
// fails subsequent calls to get(orCreate)UUID
|
|
97
|
-
// return the same value.
|
|
98
|
-
mUuid = UUID.randomUUID().toString();
|
|
99
|
-
try (FileWriter writer = new FileWriter(getNonBackedUpUuidFile())) {
|
|
100
|
-
writer.write(mUuid);
|
|
101
|
-
} catch (IOException e) {
|
|
102
|
-
Log.e(TAG, "Error while writing new UUID. " + e);
|
|
103
|
-
}
|
|
104
|
-
return mUuid;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private File getNonBackedUpUuidFile() {
|
|
108
|
-
return new File(mContext.getNoBackupFilesDir(), UUID_FILE_NAME);
|
|
109
|
-
}
|
|
110
|
-
}
|