expo-manifests 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/android/build.gradle +14 -20
- package/android/src/main/AndroidManifest.xml +1 -2
- package/android/src/main/java/expo/modules/manifests/core/JSONObjectExtension.kt +17 -0
- package/android/src/main/java/expo/modules/manifests/core/Manifest.kt +50 -0
- package/android/src/test/java/expo/modules/manifests/core/ManifestTest.kt +59 -0
- package/android/src/{androidTest → test}/java/expo/modules/manifests/core/NewManifestTest.kt +0 -3
- package/ios/EXManifests/Manifest.swift +51 -1
- package/ios/Tests/ManifestSpec.swift +38 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,20 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.7.0 — 2023-06-21
|
|
14
|
+
|
|
15
|
+
### 📚 3rd party library updates
|
|
16
|
+
|
|
17
|
+
- Updated `junit` to `4.13.2`. ([#22395](https://github.com/expo/expo/pull/22395) by [@josephyanks](https://github.com/josephyanks))
|
|
18
|
+
|
|
19
|
+
### 🎉 New features
|
|
20
|
+
|
|
21
|
+
- Added `Manifests.getPluginProperties()` helper to query dedicated package's properties inside the `plugins` config. ([#22701](https://github.com/expo/expo/pull/22701) by [@kudo](https://github.com/kudo))
|
|
22
|
+
|
|
23
|
+
### 🐛 Bug fixes
|
|
24
|
+
|
|
25
|
+
- Fixed Android build warnings for Gradle version 8. ([#22537](https://github.com/expo/expo/pull/22537), [#22609](https://github.com/expo/expo/pull/22609) by [@kudo](https://github.com/kudo))
|
|
26
|
+
|
|
13
27
|
## 0.6.0 — 2023-05-08
|
|
14
28
|
|
|
15
29
|
### 🎉 New features
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '0.
|
|
6
|
+
version = '0.7.0'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -35,19 +35,11 @@ buildscript {
|
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
// Creating sources with comments
|
|
39
|
-
task androidSourcesJar(type: Jar) {
|
|
40
|
-
classifier = 'sources'
|
|
41
|
-
from android.sourceSets.main.java.srcDirs
|
|
42
|
-
}
|
|
43
|
-
|
|
44
38
|
afterEvaluate {
|
|
45
39
|
publishing {
|
|
46
40
|
publications {
|
|
47
41
|
release(MavenPublication) {
|
|
48
42
|
from components.release
|
|
49
|
-
// Add additional sourcesJar to artifacts
|
|
50
|
-
artifact(androidSourcesJar)
|
|
51
43
|
}
|
|
52
44
|
}
|
|
53
45
|
repositories {
|
|
@@ -70,11 +62,12 @@ android {
|
|
|
70
62
|
jvmTarget = JavaVersion.VERSION_11.majorVersion
|
|
71
63
|
}
|
|
72
64
|
|
|
65
|
+
namespace "expo.modules.manifests"
|
|
73
66
|
defaultConfig {
|
|
74
67
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
75
68
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
76
69
|
versionCode 31
|
|
77
|
-
versionName '0.
|
|
70
|
+
versionName '0.7.0'
|
|
78
71
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
79
72
|
}
|
|
80
73
|
lintOptions {
|
|
@@ -86,21 +79,22 @@ android {
|
|
|
86
79
|
sourceSets {
|
|
87
80
|
androidTest.assets.srcDirs += files("$projectDir/src/androidTest/schemas".toString())
|
|
88
81
|
}
|
|
82
|
+
publishing {
|
|
83
|
+
singleVariant("release") {
|
|
84
|
+
withSourcesJar()
|
|
85
|
+
}
|
|
86
|
+
}
|
|
89
87
|
}
|
|
90
88
|
|
|
91
89
|
dependencies {
|
|
92
90
|
implementation project(':expo-json-utils')
|
|
93
91
|
|
|
94
|
-
testImplementation 'junit:junit:4.
|
|
95
|
-
testImplementation 'androidx.test:core:1.
|
|
96
|
-
testImplementation 'org.mockito:mockito-core:
|
|
97
|
-
testImplementation 'io.mockk:mockk:1.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
androidTestImplementation 'androidx.test:core:1.4.0'
|
|
101
|
-
androidTestImplementation 'androidx.test:rules:1.4.0'
|
|
102
|
-
androidTestImplementation 'org.mockito:mockito-android:3.7.7'
|
|
103
|
-
androidTestImplementation 'io.mockk:mockk-android:1.12.3'
|
|
92
|
+
testImplementation 'junit:junit:4.13.2'
|
|
93
|
+
testImplementation 'androidx.test:core:1.5.0'
|
|
94
|
+
testImplementation 'org.mockito:mockito-core:4.0.0'
|
|
95
|
+
testImplementation 'io.mockk:mockk:1.13.5'
|
|
96
|
+
testImplementation 'org.json:json:20230227'
|
|
97
|
+
testImplementation "com.google.truth:truth:1.1.2"
|
|
104
98
|
|
|
105
99
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getKotlinVersion()}"
|
|
106
100
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
package expo.modules.manifests.core
|
|
4
|
+
|
|
5
|
+
import org.json.JSONObject
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Convert a [JSONObject] to Map<String, Any> recursively
|
|
9
|
+
*/
|
|
10
|
+
fun JSONObject.toMap(): Map<String, Any> {
|
|
11
|
+
return keys().asSequence().associateWith {
|
|
12
|
+
when (val value = this@toMap[it]) {
|
|
13
|
+
is JSONObject -> value.toMap()
|
|
14
|
+
else -> value
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -230,6 +230,18 @@ abstract class Manifest(protected val json: JSONObject) {
|
|
|
230
230
|
@Throws(JSONException::class)
|
|
231
231
|
fun getFacebookAutoInitEnabled(): Boolean = getExpoClientConfigRootObject()!!.require("facebookAutoInitEnabled")
|
|
232
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Queries the dedicated package properties in `plugins`
|
|
235
|
+
*/
|
|
236
|
+
@Throws(JSONException::class, IllegalArgumentException::class)
|
|
237
|
+
fun getPluginProperties(packageName: String): Map<String, Any>? {
|
|
238
|
+
val pluginsRawValue = getExpoClientConfigRootObject()?.getNullable<JSONArray>("plugins") ?: return null
|
|
239
|
+
val plugins = PluginType.fromRawArrayValue(pluginsRawValue) ?: return null
|
|
240
|
+
return plugins.filterIsInstance<PluginType.WithProps>()
|
|
241
|
+
.firstOrNull { it.plugin.first == packageName }
|
|
242
|
+
?.plugin?.second
|
|
243
|
+
}
|
|
244
|
+
|
|
233
245
|
companion object {
|
|
234
246
|
@JvmStatic fun fromManifestJson(manifestJson: JSONObject): Manifest {
|
|
235
247
|
return when {
|
|
@@ -246,3 +258,41 @@ abstract class Manifest(protected val json: JSONObject) {
|
|
|
246
258
|
}
|
|
247
259
|
}
|
|
248
260
|
}
|
|
261
|
+
|
|
262
|
+
internal typealias PluginWithProps = Pair<String, Map<String, Any>>
|
|
263
|
+
internal typealias PluginWithoutProps = String
|
|
264
|
+
internal sealed class PluginType {
|
|
265
|
+
data class WithProps(val plugin: PluginWithProps) : PluginType()
|
|
266
|
+
data class WithoutProps(val plugin: PluginWithoutProps) : PluginType()
|
|
267
|
+
|
|
268
|
+
companion object {
|
|
269
|
+
@Throws(IllegalArgumentException::class)
|
|
270
|
+
private fun fromRawValue(value: Any): PluginType? {
|
|
271
|
+
return when (value) {
|
|
272
|
+
is JSONArray -> {
|
|
273
|
+
if (value.length() != 2) {
|
|
274
|
+
throw IllegalArgumentException("Value for (key = plugins) has incorrect type")
|
|
275
|
+
}
|
|
276
|
+
val name = value.get(0) as? String ?: return null
|
|
277
|
+
val props = value.get(1) as? JSONObject ?: return null
|
|
278
|
+
WithProps(name to props.toMap())
|
|
279
|
+
}
|
|
280
|
+
is String -> {
|
|
281
|
+
WithoutProps(value)
|
|
282
|
+
}
|
|
283
|
+
else -> throw IllegalArgumentException("Value for (key = plugins) has incorrect type")
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@Throws(IllegalArgumentException::class)
|
|
288
|
+
fun fromRawArrayValue(value: JSONArray): List<PluginType> {
|
|
289
|
+
return mutableListOf<PluginType>().apply {
|
|
290
|
+
for (i in 0 until value.length()) {
|
|
291
|
+
fromRawValue(value.get(i))?.let {
|
|
292
|
+
add(it)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
package expo.modules.manifests.core
|
|
4
|
+
|
|
5
|
+
import com.google.common.truth.Truth
|
|
6
|
+
import org.json.JSONObject
|
|
7
|
+
import org.junit.Test
|
|
8
|
+
|
|
9
|
+
class ManifestTest {
|
|
10
|
+
@Test
|
|
11
|
+
fun getPluginProperties_emptyManifest_returnsNull() {
|
|
12
|
+
val manifestJson = JSONObject(emptyMap<String, Any>())
|
|
13
|
+
val manifest = Manifest.fromManifestJson(manifestJson)
|
|
14
|
+
Truth.assertThat(manifest.getPluginProperties("test")).isNull()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@Test
|
|
18
|
+
fun getPluginProperties_emptyPlugins_returnsNull() {
|
|
19
|
+
val manifestJson = JSONObject(mapOf<String, Any>("plugins" to emptyArray<Any>()))
|
|
20
|
+
val manifest = Manifest.fromManifestJson(manifestJson)
|
|
21
|
+
Truth.assertThat(manifest.getPluginProperties("test")).isNull()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Test
|
|
25
|
+
fun getPluginProperties_nonMatchedPlugins_returnsNull() {
|
|
26
|
+
val manifestJson = JSONObject(mapOf<String, Any>("plugins" to arrayOf("hello")))
|
|
27
|
+
val manifest = Manifest.fromManifestJson(manifestJson)
|
|
28
|
+
Truth.assertThat(manifest.getPluginProperties("test")).isNull()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Test
|
|
32
|
+
fun getPluginProperties_matchedPluginWithoutProps_returnsNull() {
|
|
33
|
+
val manifestJson = JSONObject(mapOf<String, Any>("plugins" to arrayOf("test")))
|
|
34
|
+
val manifest = Manifest.fromManifestJson(manifestJson)
|
|
35
|
+
Truth.assertThat(manifest.getPluginProperties("test")).isNull()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@Test
|
|
39
|
+
fun getPluginProperties_matchedPluginWithProps_returnsProps() {
|
|
40
|
+
val props = mapOf<String, Any>("foo" to "bar")
|
|
41
|
+
val pluginWithProp = arrayOf("test", props)
|
|
42
|
+
val manifestJson = JSONObject(mapOf<String, Any>("plugins" to arrayOf(pluginWithProp)))
|
|
43
|
+
val manifest = Manifest.fromManifestJson(manifestJson)
|
|
44
|
+
val result = manifest.getPluginProperties("test")
|
|
45
|
+
Truth.assertThat(result).isNotNull()
|
|
46
|
+
Truth.assertThat(result).containsExactlyEntriesIn(props)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@Test
|
|
50
|
+
fun getPluginProperties_matchedPluginWithNestedProps_returnsNestedProps() {
|
|
51
|
+
val props = mapOf<String, Any>("nested" to mapOf<String, Any>("insideNested" to true))
|
|
52
|
+
val pluginWithProp = arrayOf("test", props)
|
|
53
|
+
val manifestJson = JSONObject(mapOf<String, Any>("plugins" to arrayOf(pluginWithProp)))
|
|
54
|
+
val manifest = Manifest.fromManifestJson(manifestJson)
|
|
55
|
+
val result = manifest.getPluginProperties("test")
|
|
56
|
+
Truth.assertThat(result).isNotNull()
|
|
57
|
+
Truth.assertThat(result).containsExactlyEntriesIn(props)
|
|
58
|
+
}
|
|
59
|
+
}
|
package/android/src/{androidTest → test}/java/expo/modules/manifests/core/NewManifestTest.kt
RENAMED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
package expo.modules.manifests.core
|
|
2
2
|
|
|
3
|
-
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
|
|
4
3
|
import org.json.JSONObject
|
|
5
4
|
import org.junit.Assert
|
|
6
5
|
import org.junit.Test
|
|
7
|
-
import org.junit.runner.RunWith
|
|
8
6
|
|
|
9
|
-
@RunWith(AndroidJUnit4ClassRunner::class)
|
|
10
7
|
class NewManifestTest {
|
|
11
8
|
@Test
|
|
12
9
|
@Throws(Exception::class)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// this uses abstract class patterns
|
|
4
4
|
// swiftlint:disable unavailable_function
|
|
5
5
|
|
|
6
|
-
// swiftlint:disable type_body_length
|
|
6
|
+
// swiftlint:disable type_body_length file_length
|
|
7
7
|
|
|
8
8
|
import Foundation
|
|
9
9
|
import UIKit
|
|
@@ -322,6 +322,56 @@ public class Manifest: NSObject {
|
|
|
322
322
|
return jsEngine
|
|
323
323
|
}
|
|
324
324
|
|
|
325
|
+
/**
|
|
326
|
+
Queries the dedicated package properties in `plugins`
|
|
327
|
+
*/
|
|
328
|
+
public func getPluginProperties(packageName: String) -> [String: Any]? {
|
|
329
|
+
typealias PluginWithProps = (String, [String: Any])
|
|
330
|
+
typealias PluginWithoutProps = String
|
|
331
|
+
enum PluginType {
|
|
332
|
+
case withProps (PluginWithProps)
|
|
333
|
+
case withoutProps (PluginWithoutProps)
|
|
334
|
+
|
|
335
|
+
private static func fromRawValue(_ optionalValue: Any?) -> PluginType? {
|
|
336
|
+
guard let value = optionalValue else {
|
|
337
|
+
return nil
|
|
338
|
+
}
|
|
339
|
+
if let valueArray = value as? [Any],
|
|
340
|
+
let name = valueArray[0] as? String, let props = valueArray[1] as? [String: Any] {
|
|
341
|
+
return .withProps((name, props))
|
|
342
|
+
}
|
|
343
|
+
if let value = value as? String {
|
|
344
|
+
return .withoutProps(value)
|
|
345
|
+
}
|
|
346
|
+
let exception = NSException(
|
|
347
|
+
name: NSExceptionName.internalInconsistencyException,
|
|
348
|
+
reason: "Value for (key = plugins) has incorrect type",
|
|
349
|
+
userInfo: ["key": "plugins"]
|
|
350
|
+
)
|
|
351
|
+
exception.raise()
|
|
352
|
+
return nil
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
static func fromRawArrayValue(_ value: [Any]) -> [PluginType]? {
|
|
356
|
+
return value.compactMap { fromRawValue($0) }
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
guard let pluginsRawValue = expoClientConfigRootObject()?.optionalValue(forKey: "plugins") as [Any]?,
|
|
361
|
+
let plugins = PluginType.fromRawArrayValue(pluginsRawValue) else {
|
|
362
|
+
return nil
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
let firstMatchedPlugin = plugins.compactMap { item in
|
|
366
|
+
if case .withProps(let tuple) = item, tuple.0 == packageName {
|
|
367
|
+
return tuple
|
|
368
|
+
}
|
|
369
|
+
return nil
|
|
370
|
+
}.first
|
|
371
|
+
|
|
372
|
+
return firstMatchedPlugin?.1
|
|
373
|
+
}
|
|
374
|
+
|
|
325
375
|
private func expoGoSDKMajorVersion() -> Int {
|
|
326
376
|
let sdkVersion = expoGoSDKVersion()
|
|
327
377
|
let components = sdkVersion?.components(separatedBy: ".")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Copyright 2015-present 650 Industries. All rights reserved.
|
|
2
|
+
|
|
3
|
+
import ExpoModulesTestCore
|
|
4
|
+
|
|
5
|
+
@testable import EXManifests
|
|
6
|
+
|
|
7
|
+
final class ManifestSpec: ExpoSpec {
|
|
8
|
+
override func spec() {
|
|
9
|
+
describe("getPluginProperties") {
|
|
10
|
+
it("should return nil when plugin is not matched") {
|
|
11
|
+
var manifestJson: [String: Any] = [:]
|
|
12
|
+
var manifest = ManifestFactory.manifest(forManifestJSON: manifestJson)
|
|
13
|
+
expect(manifest.getPluginProperties(packageName: "test")).to(beNil())
|
|
14
|
+
|
|
15
|
+
manifestJson = ["plugins": []]
|
|
16
|
+
manifest = ManifestFactory.manifest(forManifestJSON: manifestJson)
|
|
17
|
+
expect(manifest.getPluginProperties(packageName: "test")).to(beNil())
|
|
18
|
+
|
|
19
|
+
manifestJson = ["plugins": ["hello"]]
|
|
20
|
+
manifest = ManifestFactory.manifest(forManifestJSON: manifestJson)
|
|
21
|
+
expect(manifest.getPluginProperties(packageName: "test")).to(beNil())
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
it("should return nil when the matched plugin has no properties") {
|
|
25
|
+
let manifestJson = ["plugins": ["test"]]
|
|
26
|
+
let manifest = ManifestFactory.manifest(forManifestJSON: manifestJson)
|
|
27
|
+
expect(manifest.getPluginProperties(packageName: "test")).to(beNil())
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
it("should return matched plugin properties") {
|
|
31
|
+
let manifestJson = ["plugins": [["test", ["foo": "bar"]]]]
|
|
32
|
+
let manifest = ManifestFactory.manifest(forManifestJSON: manifestJson)
|
|
33
|
+
let props = manifest.getPluginProperties(packageName: "test")
|
|
34
|
+
expect(props as? [String: String]) == ["foo": "bar"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-manifests",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Code to parse and use Expo and Expo Updates manifests.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"homepage": "https://docs.expo.dev/versions/latest/sdk/module-template",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"expo-json-utils": "~0.
|
|
23
|
+
"expo-json-utils": "~0.7.0"
|
|
24
24
|
},
|
|
25
|
-
"gitHead": "
|
|
25
|
+
"gitHead": "fa5ecca8251986b9f197cc14074eec0ab6dfb6db"
|
|
26
26
|
}
|