expo-modules-core 1.2.2 → 1.2.3

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 CHANGED
@@ -10,6 +10,13 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 1.2.3 — 2023-02-21
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - [iOS] Fixed URI with encoded `#` getting cut off. ([#21326](https://github.com/expo/expo/pull/21326) by [@lukmccall](https://github.com/lukmccall))
18
+ - [Android] Fail gracefully when the view cannot be constructed due to the missing activity. ([#21328](https://github.com/expo/expo/pull/21328) by [@lukmccall](https://github.com/lukmccall))
19
+
13
20
  ## 1.2.2 — 2023-02-14
14
21
 
15
22
  ### 🐛 Bug fixes
@@ -6,7 +6,7 @@ apply plugin: 'maven-publish'
6
6
  apply plugin: "de.undercouch.download"
7
7
 
8
8
  group = 'host.exp.exponent'
9
- version = '1.2.2'
9
+ version = '1.2.3'
10
10
 
11
11
  buildscript {
12
12
  def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
@@ -173,7 +173,7 @@ android {
173
173
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
174
174
  consumerProguardFiles 'proguard-rules.pro'
175
175
  versionCode 1
176
- versionName "1.2.2"
176
+ versionName "1.2.3"
177
177
  buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled.toString()
178
178
 
179
179
  testInstrumentationRunner "expo.modules.TestRunner"
@@ -4,9 +4,12 @@
4
4
  package expo.modules.kotlin.views
5
5
 
6
6
  import android.content.Context
7
+ import android.util.Log
7
8
  import android.view.View
8
9
  import android.view.ViewGroup
9
10
  import expo.modules.kotlin.AppContext
11
+ import expo.modules.kotlin.exception.CodedException
12
+ import expo.modules.kotlin.exception.UnexpectedException
10
13
  import expo.modules.kotlin.modules.DefinitionMarker
11
14
  import expo.modules.kotlin.types.toAnyType
12
15
  import kotlin.reflect.KClass
@@ -147,7 +150,11 @@ class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClas
147
150
 
148
151
  // Backward compatibility
149
152
  if (args.size == 1) {
150
- return@viewFactory primaryConstructor.call(context)
153
+ return@viewFactory try {
154
+ primaryConstructor.call(context)
155
+ } catch (e: Throwable) {
156
+ handleFailureDuringViewCreation(context, appContext, e)
157
+ }
151
158
  }
152
159
 
153
160
  val secondArgType = args[1].type
@@ -159,7 +166,24 @@ class ViewDefinitionBuilder<T : View>(@PublishedApi internal val viewType: KClas
159
166
  throw IllegalStateException("Android view has more constructor arguments than expected.")
160
167
  }
161
168
 
162
- return@viewFactory primaryConstructor.call(context, appContext)
169
+ return@viewFactory try {
170
+ primaryConstructor.call(context, appContext)
171
+ } catch (e: Throwable) {
172
+ handleFailureDuringViewCreation(context, appContext, e)
173
+ }
174
+ }
175
+
176
+ private fun handleFailureDuringViewCreation(context: Context, appContext: AppContext, e: Throwable): View {
177
+ Log.e("ExpoModulesCore", "Couldn't create view of type $viewType", e)
178
+
179
+ appContext.errorManager?.reportExceptionToLogBox(
180
+ if (e is CodedException) {
181
+ e
182
+ } else {
183
+ UnexpectedException(e)
184
+ }
185
+ )
186
+ return View(context)
163
187
  }
164
188
 
165
189
  private fun getPrimaryConstructor(): KFunction<T>? {
@@ -32,15 +32,29 @@ internal func toNSError(_ error: Error) -> NSError {
32
32
  Note that it encodes only characters that are not allowed in the url query and '#' that indicates the fragment part.
33
33
  */
34
34
  internal func percentEncodeUrlString(_ url: String) -> String? {
35
+ // URL contains '#' so it has a fragment part.
36
+ // We know that because that is the only allowed use case of the undecoded '#' symbol inside of the URL.
37
+ if url.contains("#") {
38
+ let urlParts = url.split(separator: "#")
39
+
40
+ // Encodes the url without the fragment part. It'll leave the fragment part untounched.
41
+ guard let parsed = percentEncodeUrlStringWithoutFragment(String(urlParts[0])) else {
42
+ return nil
43
+ }
44
+
45
+ // Concatenate encoded path with fragment.
46
+ return parsed + "#" + urlParts[1]
47
+ }
48
+
49
+ return percentEncodeUrlStringWithoutFragment(url)
50
+ }
51
+
52
+ private func percentEncodeUrlStringWithoutFragment(_ url: String) -> String? {
35
53
  // The value may come unencoded or already encoded, so first we try to decode it.
36
54
  // `removingPercentEncoding` returns nil when the string contains an invalid percent-encoded sequence,
37
55
  // but that usually means the value came unencoded, so it falls back to the given string.
38
56
  let decodedString = url.removingPercentEncoding ?? url
39
57
 
40
- // A `CharacterSet` with all query-allowed characters and the hash which is not allowed in the query,
41
- // but it must stay unencoded to indicate the start of the url fragment part.
42
- let allowedCharactersSet = CharacterSet.urlQueryAllowed.union(CharacterSet(charactersIn: "#"))
43
-
44
58
  // Do the percent encoding, but note that it may still return nil when it's not possible to encode for some reason.
45
- return decodedString.addingPercentEncoding(withAllowedCharacters: allowedCharactersSet)
59
+ return decodedString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
46
60
  }
@@ -43,6 +43,17 @@ class ConvertiblesSpec: ExpoSpec {
43
43
  expect(url.absoluteString) == urlString
44
44
  expect(url.absoluteString.removingPercentEncoding) == "https://expo.dev/?param=🥓"
45
45
  }
46
+
47
+ it("converts from url with encoded query containg the anchor") {
48
+ let query = "color=%230000ff"
49
+ let urlString = "https://expo.dev/?\(query)#anchor"
50
+ let url = try URL.convert(from: urlString)
51
+
52
+ expect(url.query) == query
53
+ expect(url.absoluteString) == urlString
54
+ expect(url.absoluteString.removingPercentEncoding) == "https://expo.dev/?color=#0000ff#anchor"
55
+ expect(url.fragment) == "anchor"
56
+ }
46
57
 
47
58
  it("converts from url containing percent character") {
48
59
  // The percent character alone requires percent-encoding to `%25`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -42,5 +42,5 @@
42
42
  "@testing-library/react-hooks": "^7.0.1",
43
43
  "expo-module-scripts": "^3.0.0"
44
44
  },
45
- "gitHead": "c8107d57eabaedff5d53bc8036d062db12a473c8"
45
+ "gitHead": "40dcd1732b69f09798a28691f6b17b820a2bbbf5"
46
46
  }