From 4e349b9b81e177207e85d96c4b33c8515b82c894 Mon Sep 17 00:00:00 2001 From: noproblem23 Date: Sat, 1 Apr 2023 13:52:44 +0200 Subject: [PATCH] feat: Fabric support (#2686) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hello everyone, the support for new architecture (fabric) is finally landing 🚀 . I've taken a lot of time but I've had to re-understand the whole codebase, the old arch, the new arch, and I did not want to take too many shortcuts. This release should be mostly non breaking (except for a few well deserved props removals). HOWEVER, this is a lot of code over a lot of time. Mistakes can happen, if you feel unsafe stick to v11 for a lil' while. Finally this will unblock many PR (sorry for the conflicts in advance), so let's get releasing again 🔥 If you appreciate my work please to [sponsor me](https://github.com/sponsors/Titozzz) BREAKING CHANGE: - If you are using custom native implementation are still possible on the old arch but many classes were moved / renamed so they will need some changes - removed the following props: androidHardwareAccelerationDisabled (deprecated), urlPrefixesForDefaultIntent (unused) --- .circleci/config.yml | 2 +- .github/workflows/macos-ci.yml | 2 + .github/workflows/windows-ci.yml | 21 +- README.md | 98 +- android/build.gradle | 178 +- android/gradle.properties | 5 +- .../webview/RNCBasicAuthCredential.java | 11 + .../webview/RNCWebChromeClient.java | 346 ++ .../webview/RNCWebView.java | 337 ++ .../webview/RNCWebViewClient.java | 312 ++ ...bViewConfig.java => RNCWebViewConfig.java} | 7 +- .../webview/RNCWebViewFileProvider.java | 2 +- .../webview/RNCWebViewManager.java | 1853 -------- .../webview/RNCWebViewManagerImpl.kt | 639 +++ .../webview/RNCWebViewModule.java | 550 --- .../webview/RNCWebViewModuleImpl.java | 544 +++ .../webview/RNCWebViewPackage.java | 56 + .../webview/RNCWebViewPackage.kt | 15 - .../webview/RNCWebViewManager.java | 511 +++ .../webview/RNCWebViewModule.java | 57 + .../webview/RNCWebViewManager.java | 306 ++ .../webview/RNCWebViewModule.java | 59 + apple/RNCWebView.h | 133 +- apple/RNCWebView.mm | 502 ++ apple/RNCWebViewDecisionManager.h | 20 + apple/RNCWebViewDecisionManager.m | 47 + apple/RNCWebViewImpl.h | 145 + apple/{RNCWebView.m => RNCWebViewImpl.m} | 390 +- apple/RNCWebViewManager.h | 12 +- ...CWebViewManager.m => RNCWebViewManager.mm} | 233 +- bin/setup | 26 - docs/Contributing.md | 13 +- docs/Custom-Android.md | 6 +- docs/README.french.md | 95 +- docs/Reference.md | 48 +- docs/Reference.portuguese.md | 37 +- example/App.tsx | 4 +- example/android/gradle.properties | 11 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/examples/Downloads.tsx | 4 +- example/examples/Messaging.tsx | 14 +- example/examples/NativeWebpage.tsx | 11 +- example/ios/.xcode.env | 1 + example/ios/Podfile.lock | 552 +-- example/macos/Podfile.lock | 4 +- package.json | 43 +- react-native-webview.podspec | 23 +- react-native.config.js | 3 +- src/NativeRNCWebView.ts | 14 + src/RNCWebViewNativeComponent.ts | 272 ++ src/WebView.android.tsx | 91 +- src/WebView.ios.tsx | 78 +- src/WebView.macos.tsx | 19 +- src/WebView.windows.tsx | 7 +- src/WebViewNativeComponent.android.ts | 8 - src/WebViewNativeComponent.ios.ts | 8 - src/WebViewTypes.ts | 111 +- .../__snapshots__/WebViewShared-test.js.snap | 2 +- yarn.lock | 4084 +++++++++-------- 59 files changed, 7324 insertions(+), 5660 deletions(-) create mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java create mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java create mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java create mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java rename android/src/main/java/com/reactnativecommunity/webview/{WebViewConfig.java => RNCWebViewConfig.java} (77%) delete mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java create mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt delete mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java create mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java create mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java delete mode 100644 android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.kt create mode 100644 android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java create mode 100644 android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java create mode 100644 android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java create mode 100644 android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java create mode 100644 apple/RNCWebView.mm create mode 100644 apple/RNCWebViewDecisionManager.h create mode 100644 apple/RNCWebViewDecisionManager.m create mode 100644 apple/RNCWebViewImpl.h rename apple/{RNCWebView.m => RNCWebViewImpl.m} (92%) rename apple/{RNCWebViewManager.m => RNCWebViewManager.mm} (52%) delete mode 100755 bin/setup create mode 100644 example/ios/.xcode.env create mode 100644 src/NativeRNCWebView.ts create mode 100644 src/RNCWebViewNativeComponent.ts delete mode 100644 src/WebViewNativeComponent.android.ts delete mode 100644 src/WebViewNativeComponent.ios.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index 3265522..82e26d4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ defaults: &defaults working_directory: ~/code docker: - - image: cimg/node:14.17.6-browsers + - image: cimg/node:18.13.0-browsers version: 2 jobs: diff --git a/.github/workflows/macos-ci.yml b/.github/workflows/macos-ci.yml index d8f1c95..472f6f2 100644 --- a/.github/workflows/macos-ci.yml +++ b/.github/workflows/macos-ci.yml @@ -21,6 +21,8 @@ jobs: key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - name: Install npm dependencies run: yarn --frozen-lockfile + - name: Install macos dependencies + run: yarn add:macos - name: Install Pods run: pod install working-directory: example/macos diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index d56326a..9a02704 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -4,35 +4,28 @@ on: [pull_request] jobs: run-windows-tests: name: Build & run tests - runs-on: windows-2019 + runs-on: windows-2022 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 name: Checkout Code - name: Setup Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: '^14' + cache: 'yarn' - name: Setup MSBuild - uses: microsoft/setup-msbuild@v1.0.2 - - - name: Check node modules cache - uses: actions/cache@v1 - id: yarn-cache + uses: microsoft/setup-msbuild@v1.1.3 with: - path: ./node_modules - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- + vs-version: '[17.0,)' + msbuild-architecture: x64 - name: Install node modules - if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn --pure-lockfile - name: yarn build - if: steps.yarn-cache.outputs.cache-hit == 'true' run: | yarn build yarn tsc diff --git a/README.md b/README.md index c38914f..c0f3716 100644 --- a/README.md +++ b/README.md @@ -1,109 +1,81 @@ -# React Native WebView - a Modern, Cross-Platform WebView for React Native +# React Native WebView -[![star this repo](https://img.shields.io/github/stars/react-native-webview/react-native-webview?style=flat-square) +![star this repo](https://img.shields.io/github/stars/react-native-webview/react-native-webview?style=flat-square) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) -[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors) -[![Known Vulnerabilities](https://snyk.io/test/github/react-native-webview/react-native-webview/badge.svg?style=flat-square)](https://snyk.io/test/github/react-native-webview/react-native-webview) [![NPM Version](https://img.shields.io/npm/v/react-native-webview.svg?style=flat-square)](https://www.npmjs.com/package/react-native-webview) -[![Lean Core Extracted](https://img.shields.io/badge/Lean%20Core-Extracted-brightgreen.svg?style=flat-square)][lean-core-issue] +![Npm Downloads](https://img.shields.io/npm/dm/react-native-webview.svg) -**React Native WebView** is a modern, well-supported, and cross-platform WebView for React Native. It is intended to be a replacement for the built-in WebView (which was [removed from core](https://github.com/react-native-community/discussions-and-proposals/pull/3)). +**React Native WebView** is a community maintained WebView component for React Native. It is intended to be a replacement for the built-in WebView (which was [removed from core](https://github.com/react-native-community/discussions-and-proposals/pull/3)). -## Core Maintainers - Sponsoring companies +### Maintainers -_This project is maintained for free by these people using both their free time and their company work time._ +**Many thanks to these companies** for providing us with time to work on open source. +Please note that maintainers spend a lot of free time working on this too so feel free to sponsor them, **it really makes a difference.** -- [Thibault Malbranche](https://github.com/Titozzz) ([Twitter @titozzz](https://twitter.com/titozzz)) from [Brigad](https://www.brigad.co/en-gb/about-us) -- [Jamon Holmgren](https://github.com/jamonholmgren) ([Twitter @jamonholmgren](https://twitter.com/jamonholmgren)) from [Infinite Red](https://infinite.red/react-native) -- [Alexander Sklar](https://github.com/asklar) ([Twitter @alexsklar](https://twitter.com/alexsklar)) from [React Native for Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) -- [Chiara Mooney](https://github.com/chiaramooney) from [React Native for Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) +- [Thibault Malbranche](https://github.com/Titozzz) ([Twitter @titozzz](https://twitter.com/titozzz)) from [Brigad](https://www.brigad.co/en-gb/about-us) +[*Sponsor me* ❤️ !](https://github.com/sponsors/Titozzz) -## Platforms Supported -- [x] iOS -- [x] Android -- [x] macOS -- [x] Windows -- [x] Expo (Android, iOS) +Windows and macOS are managed by Microsoft, notably: +- [Alexander Sklar](https://github.com/asklar) ([Twitter @alexsklar](https://twitter.com/alexsklar)) from [React Native for Windows](https://microsoft.github.io/react-native-windows/) +- [Chiara Mooney](https://github.com/chiaramooney) from [React Native for Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) -## Getting Started +Shout-out to [Jamon Holmgren](https://github.com/jamonholmgren) from [Infinite Red](https://infinite.red) for helping a lot with the repo when he had more available time. -Read our [Getting Started Guide](docs/Getting-Started.md). If any step seems unclear, please create a detailed issue. +### Disclaimer -## Versioning +Maintaining WebView is very complex, because it is often used for many different usecases (rendering svgs, pdfs, login flows, and much more). We also support many platforms and both architecture of react-native. -This project follows [semantic versioning](https://semver.org/). We do not hesitate to release breaking changes but they will be in a major version. +Since WebView was extracted from React Native core, nearly 500 pull requests have been merged. +Considering that we have limited time, issues will mostly serve as a discussion place for the community, while **we will prioritize reviewing and merging pull requests.** -**Breaking History:** +### Platform compatibility -Current Version: ![version](https://img.shields.io/npm/v/react-native-webview.svg) +This project is compatible with **iOS**, **Android**, **Windows** and **macOS**. +This project support both **the old** (paper) **and the new architecture** (fabric). +This project is compatible with [expo](https://docs.expo.dev/versions/latest/sdk/webview/). -- [11.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v11.0.0) - Android setSupportMultipleWindows. -- [10.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v10.0.0) - Android Gradle plugin is only required when opening the project stand-alone -- [9.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v9.0.0) - props updates to injectedJavaScript are no longer immutable. -- [8.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v8.0.0) - onNavigationStateChange now triggers with hash url changes -- [7.0.1](https://github.com/react-native-webview/react-native-webview/releases/tag/v7.0.1) - Removed UIWebView -- [6.0.**2**](https://github.com/react-native-webview/react-native-webview/releases/tag/v6.0.2) - Update to AndroidX. Make sure to enable it in your project's `android/gradle.properties`. See [Getting Started Guide](docs/Getting-Started.md). -- [5.0.**1**](https://github.com/react-native-webview/react-native-webview/releases/tag/v5.0.0) - Refactored the old postMessage implementation for communication from webview to native. -- [4.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v4.0.0) - Added cache (enabled by default). -- [3.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v3.0.0) - WKWebview: Add shared process pool so cookies and localStorage are shared across webviews in iOS (enabled by default). -- [2.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v2.0.0) - First release this is a replica of the core webview component +### Getting Started -**Upcoming:** +Read our [Getting Started Guide](docs/Getting-Started.md). If any step seems unclear, please create a pull request. -- this.webView.postMessage() removal (never documented and less flexible than injectJavascript) -> [how to migrate](https://github.com/react-native-webview/react-native-webview/issues/809) -- Kotlin rewrite -- Maybe Swift rewrite +### Versioning -## Usage +This project follows [semantic versioning](https://semver.org/). We do not hesitate to release breaking changes but they will be in a major version. + +### Usage Import the `WebView` component from `react-native-webview` and use it like so: -```jsx +```tsx import React, { Component } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { WebView } from 'react-native-webview'; // ... -class MyWebComponent extends Component { - render() { - return ; - } +const MyWebComponent = () => { + return ; } ``` For more, read the [API Reference](./docs/Reference.md) and [Guide](./docs/Guide.md). If you're interested in contributing, check out the [Contributing Guide](./docs/Contributing.md). -## Common issues +### Common issues - If you're getting `Invariant Violation: Native component for "RNCWebView does not exist"` it likely means you forgot to run `react-native link` or there was some error with the linking process - If you encounter a build error during the task `:app:mergeDexRelease`, you need to enable multidex support in `android/app/build.gradle` as discussed in [this issue](https://github.com/react-native-webview/react-native-webview/issues/1344#issuecomment-650544648) -## Contributing - -See [Contributing.md](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Contributing.md) +#### Contributing -## Contributors +Contributions are welcome, see [Contributing.md](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Contributing.md) -Thanks goes to these wonderful people ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key-)): - - - -
Thibault Malbranche
Thibault Malbranche

💻 🤔 👀 📖 🚧 ⚠️ 🚇 💬
Jamon Holmgren
Jamon Holmgren

💻 🤔 👀 📖 🚧 ⚠️ 💡 💬
Andrei Pfeiffer
Andrei Pfeiffer

💻 👀 🤔
Michael Diarmid
Michael Diarmid

💻 👀 🤔 🔧
Scott Mathson
Scott Mathson

💻 📖
Margaret
Margaret

💻 📖
Jordan Sexton
Jordan Sexton

💻 📖
Malcolm Scruggs
Malcolm Scruggs

💻 🔧 ⚠️
Momazo7u7
Momazo7u7

📖
Marco
Marco

📖
Julien Eluard
Julien Eluard

📖
Jian Wei
Jian Wei

💻 📖
Sergei Butko
Sergei Butko

📖
TMomemt
TMomemt

💻
Eric Lewis
Eric Lewis

💻 📖
Daniel Vicory
Daniel Vicory

💻 📖
- - - -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! - -## License +### License MIT -## Translations +### Translations This readme is available in: - [Brazilian portuguese](docs/README.portuguese.md) - [French](docs/README.french.md) - -[lean-core-issue]: https://github.com/facebook/react-native/issues/23313 diff --git a/android/build.gradle b/android/build.gradle index fbede17..b38e813 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,137 +1,91 @@ -buildscript { - ext.getExtOrDefault = {name -> - return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['ReactNativeWebView_' + name] - } +import java.nio.file.Paths - // The Android Gradle plugin is only required when opening the android folder stand-alone. - // This avoids unnecessary downloads and potential conflicts when the library is included as a - // module dependency in an application project. - if (project == rootProject) { - repositories { - mavenCentral() - google() - } - - dependencies { - classpath("com.android.tools.build:gradle:3.6.0") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}") +buildscript { + ext.safeExtGet = {prop -> + rootProject.ext.has(prop) ? rootProject.ext.get(prop) : project.properties['ReactNativeWebView_' + prop] } - } else { repositories { - mavenCentral() + google() + gradlePluginPortal() } - dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}") + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion')}") + classpath("com.android.tools.build:gradle:7.0.4") } - } } -def getExtOrIntegerDefault(name) { - return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['ReactNativeWebView_' + name]).toInteger() +def getExtOrIntegerDefault(prop) { + return rootProject.ext.has(prop) ? rootProject.ext.get(prop) : (project.properties['ReactNativeWebView_' + prop]).toInteger() } -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' - -android { - compileSdkVersion getExtOrIntegerDefault('compileSdkVersion') - defaultConfig { - minSdkVersion getExtOrIntegerDefault('minSdkVersion') - targetSdkVersion getExtOrIntegerDefault('targetSdkVersion') - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - minifyEnabled false +static def findNodeModulePath(baseDir, packageName) { + def basePath = baseDir.toPath().normalize() + // Node's module resolution algorithm searches up to the root directory, + // after which the base path will be null + while (basePath) { + def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName) + if (candidatePath.toFile().exists()) { + return candidatePath.toString() + } + basePath = basePath.getParent() } - } - lintOptions { - disable 'GradleCompatible' - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } + return null } -repositories { - mavenCentral() - google() - - def found = false - def defaultDir = null - def androidSourcesName = 'React Native sources' - - if (rootProject.ext.has('reactNativeAndroidRoot')) { - defaultDir = rootProject.ext.get('reactNativeAndroidRoot') - } else { - defaultDir = new File( - projectDir, - '/../../../node_modules/react-native/android' - ) - } - - if (defaultDir.exists()) { - maven { - url defaultDir.toString() - name androidSourcesName - } - - logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}") - found = true - } else { - def parentDir = rootProject.projectDir +def isNewArchitectureEnabled() { + return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" +} - 1.upto(5, { - if (found) return true - parentDir = parentDir.parentFile - def androidSourcesDir = new File( - parentDir, - 'node_modules/react-native' - ) +apply plugin: 'com.android.library' +if (isNewArchitectureEnabled()) { + apply plugin: 'com.facebook.react' +} +apply plugin: 'kotlin-android' - def androidPrebuiltBinaryDir = new File( - parentDir, - 'node_modules/react-native/android' - ) +android { + compileSdkVersion getExtOrIntegerDefault('compileSdkVersion') - if (androidPrebuiltBinaryDir.exists()) { - maven { - url androidPrebuiltBinaryDir.toString() - name androidSourcesName - } + defaultConfig { + minSdkVersion getExtOrIntegerDefault('minSdkVersion') + targetSdkVersion getExtOrIntegerDefault('targetSdkVersion') + buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() + } - logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}") - found = true - } else if (androidSourcesDir.exists()) { - maven { - url androidSourcesDir.toString() - name androidSourcesName + sourceSets { + main { + if (isNewArchitectureEnabled()) { + java.srcDirs += ['src/newarch'] + } else { + java.srcDirs += ['src/oldarch'] + } } + } +} - logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}") - found = true - } - }) - } +def reactNativePath = findNodeModulePath(projectDir, "react-native") +def codegenPath = findNodeModulePath(projectDir, "react-native-codegen") - if (!found) { - throw new GradleException( - "${project.name}: unable to locate React Native android sources. " + - "Ensure you have you installed React Native as a dependency in your project and try again." - ) - } +repositories { + maven { + url "${reactNativePath}/android" + } + mavenCentral() + google() } -def kotlin_version = getExtOrDefault('kotlinVersion') -def webkit_version = getExtOrDefault('webkitVersion') - dependencies { - //noinspection GradleDynamicVersion - implementation 'com.facebook.react:react-native:+' - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation "androidx.webkit:webkit:$webkit_version" + implementation 'com.facebook.react:react-native:+' + implementation "org.jetbrains.kotlin:kotlin-stdlib:${safeExtGet('kotlinVersion')}" + implementation "androidx.webkit:webkit:${safeExtGet('webkitVersion')}" +} + +if (isNewArchitectureEnabled()) { + react { + jsRootDir = file("../src/") + libraryName = "rncwebview" + codegenJavaPackageName = "com.reactnativecommunity.webview" + codegenDir = new File(codegenPath) + reactNativeDir = new File(reactNativePath) + } } diff --git a/android/gradle.properties b/android/gradle.properties index e6f0f5e..c17e066 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,6 +1,5 @@ ReactNativeWebView_kotlinVersion=1.6.0 ReactNativeWebView_webkitVersion=1.4.0 -ReactNativeWebView_compileSdkVersion=29 -ReactNativeWebView_buildToolsVersion=29.0.3 -ReactNativeWebView_targetSdkVersion=28 +ReactNativeWebView_compileSdkVersion=31 +ReactNativeWebView_targetSdkVersion=31 ReactNativeWebView_minSdkVersion=21 diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java b/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java new file mode 100644 index 0000000..57587ee --- /dev/null +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java @@ -0,0 +1,11 @@ +package com.reactnativecommunity.webview; + +class RNCBasicAuthCredential { + String username; + String password; + + RNCBasicAuthCredential(String username, String password) { + this.username = username; + this.password = password; + } +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java new file mode 100644 index 0000000..109cd03 --- /dev/null +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java @@ -0,0 +1,346 @@ +package com.reactnativecommunity.webview; + +import android.Manifest; +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.os.Message; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.ConsoleMessage; +import android.webkit.GeolocationPermissions; +import android.webkit.PermissionRequest; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.widget.FrameLayout; + +import androidx.annotation.RequiresApi; +import androidx.core.content.ContextCompat; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.common.build.ReactBuildConfig; +import com.facebook.react.modules.core.PermissionAwareActivity; +import com.facebook.react.modules.core.PermissionListener; +import com.facebook.react.uimanager.UIManagerHelper; +import com.reactnativecommunity.webview.events.TopLoadingProgressEvent; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class RNCWebChromeClient extends WebChromeClient implements LifecycleEventListener { + protected static final FrameLayout.LayoutParams FULLSCREEN_LAYOUT_PARAMS = new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER); + + protected static final int FULLSCREEN_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_FULLSCREEN | + View.SYSTEM_UI_FLAG_IMMERSIVE | + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + + protected static final int COMMON_PERMISSION_REQUEST = 3; + + protected RNCWebView mWebView; + + protected View mVideoView; + protected WebChromeClient.CustomViewCallback mCustomViewCallback; + + /* + * - Permissions - + * As native permissions are asynchronously handled by the PermissionListener, many fields have + * to be stored to send permissions results to the webview + */ + + // Webview camera & audio permission callback + protected PermissionRequest permissionRequest; + // Webview camera & audio permission already granted + protected List grantedPermissions; + + // Webview geolocation permission callback + protected GeolocationPermissions.Callback geolocationPermissionCallback; + // Webview geolocation permission origin callback + protected String geolocationPermissionOrigin; + + // true if native permissions dialog is shown, false otherwise + protected boolean permissionsRequestShown = false; + // Pending Android permissions for the next request + protected List pendingPermissions = new ArrayList<>(); + + protected RNCWebView.ProgressChangedFilter progressChangedFilter = null; + protected boolean mAllowsProtectedMedia = false; + + public RNCWebChromeClient(RNCWebView webView) { + this.mWebView = webView; + } + + @Override + public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { + + final WebView newWebView = new WebView(view.getContext()); + final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; + transport.setWebView(newWebView); + resultMsg.sendToTarget(); + + return true; + } + + @Override + public boolean onConsoleMessage(ConsoleMessage message) { + if (ReactBuildConfig.DEBUG) { + return super.onConsoleMessage(message); + } + // Ignore console logs in non debug builds. + return true; + } + + @Override + public void onProgressChanged(WebView webView, int newProgress) { + super.onProgressChanged(webView, newProgress); + final String url = webView.getUrl(); + if (progressChangedFilter.isWaitingForCommandLoadUrl()) { + return; + } + WritableMap event = Arguments.createMap(); + event.putDouble("target", webView.getId()); + event.putString("title", webView.getTitle()); + event.putString("url", url); + event.putBoolean("canGoBack", webView.canGoBack()); + event.putBoolean("canGoForward", webView.canGoForward()); + event.putDouble("progress", (float) newProgress / 100); + + int reactTag = webView.getId(); + UIManagerHelper.getEventDispatcherForReactTag(this.mWebView.getThemedReactContext(), reactTag).dispatchEvent(new TopLoadingProgressEvent(reactTag, event)); + } + + @Override + public void onPermissionRequest(final PermissionRequest request) { + + grantedPermissions = new ArrayList<>(); + + ArrayList requestedAndroidPermissions = new ArrayList<>(); + for (String requestedResource : request.getResources()) { + String androidPermission = null; + + if (requestedResource.equals(PermissionRequest.RESOURCE_AUDIO_CAPTURE)) { + androidPermission = Manifest.permission.RECORD_AUDIO; + } else if (requestedResource.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) { + androidPermission = Manifest.permission.CAMERA; + } else if(requestedResource.equals(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID)) { + if (mAllowsProtectedMedia) { + grantedPermissions.add(requestedResource); + } else { + /** + * Legacy handling (Kept in case it was working under some conditions (given Android version or something)) + * + * Try to ask user to grant permission using Activity.requestPermissions + * + * Find more details here: https://github.com/react-native-webview/react-native-webview/pull/2732 + */ + androidPermission = PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID; + } } + // TODO: RESOURCE_MIDI_SYSEX, RESOURCE_PROTECTED_MEDIA_ID. + if (androidPermission != null) { + if (ContextCompat.checkSelfPermission(this.mWebView.getThemedReactContext(), androidPermission) == PackageManager.PERMISSION_GRANTED) { + grantedPermissions.add(requestedResource); + } else { + requestedAndroidPermissions.add(androidPermission); + } + } + } + + // If all the permissions are already granted, send the response to the WebView synchronously + if (requestedAndroidPermissions.isEmpty()) { + request.grant(grantedPermissions.toArray(new String[0])); + grantedPermissions = null; + return; + } + + // Otherwise, ask to Android System for native permissions asynchronously + + this.permissionRequest = request; + + requestPermissions(requestedAndroidPermissions); + } + + + @Override + public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { + + if (ContextCompat.checkSelfPermission(this.mWebView.getThemedReactContext(), Manifest.permission.ACCESS_FINE_LOCATION) + != PackageManager.PERMISSION_GRANTED) { + + /* + * Keep the trace of callback and origin for the async permission request + */ + geolocationPermissionCallback = callback; + geolocationPermissionOrigin = origin; + + requestPermissions(Collections.singletonList(Manifest.permission.ACCESS_FINE_LOCATION)); + + } else { + callback.invoke(origin, true, false); + } + } + + private PermissionAwareActivity getPermissionAwareActivity() { + Activity activity = this.mWebView.getThemedReactContext().getCurrentActivity(); + if (activity == null) { + throw new IllegalStateException("Tried to use permissions API while not attached to an Activity."); + } else if (!(activity instanceof PermissionAwareActivity)) { + throw new IllegalStateException("Tried to use permissions API but the host Activity doesn't implement PermissionAwareActivity."); + } + return (PermissionAwareActivity) activity; + } + + private synchronized void requestPermissions(List permissions) { + + /* + * If permissions request dialog is displayed on the screen and another request is sent to the + * activity, the last permission asked is skipped. As a work-around, we use pendingPermissions + * to store next required permissions. + */ + + if (permissionsRequestShown) { + pendingPermissions.addAll(permissions); + return; + } + + PermissionAwareActivity activity = getPermissionAwareActivity(); + permissionsRequestShown = true; + + activity.requestPermissions( + permissions.toArray(new String[0]), + COMMON_PERMISSION_REQUEST, + webviewPermissionsListener + ); + + // Pending permissions have been sent, the list can be cleared + pendingPermissions.clear(); + } + + + private PermissionListener webviewPermissionsListener = (requestCode, permissions, grantResults) -> { + + permissionsRequestShown = false; + + /* + * As a "pending requests" approach is used, requestCode cannot help to define if the request + * came from geolocation or camera/audio. This is why shouldAnswerToPermissionRequest is used + */ + boolean shouldAnswerToPermissionRequest = false; + + for (int i = 0; i < permissions.length; i++) { + + String permission = permissions[i]; + boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED; + + if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) + && geolocationPermissionCallback != null + && geolocationPermissionOrigin != null) { + + if (granted) { + geolocationPermissionCallback.invoke(geolocationPermissionOrigin, true, false); + } else { + geolocationPermissionCallback.invoke(geolocationPermissionOrigin, false, false); + } + + geolocationPermissionCallback = null; + geolocationPermissionOrigin = null; + } + + if (permission.equals(Manifest.permission.RECORD_AUDIO)) { + if (granted && grantedPermissions != null) { + grantedPermissions.add(PermissionRequest.RESOURCE_AUDIO_CAPTURE); + } + shouldAnswerToPermissionRequest = true; + } + + if (permission.equals(Manifest.permission.CAMERA)) { + if (granted && grantedPermissions != null) { + grantedPermissions.add(PermissionRequest.RESOURCE_VIDEO_CAPTURE); + } + shouldAnswerToPermissionRequest = true; + } + + if (permission.equals(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID)) { + if (granted && grantedPermissions != null) { + grantedPermissions.add(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID); + } + shouldAnswerToPermissionRequest = true; + } + } + + if (shouldAnswerToPermissionRequest + && permissionRequest != null + && grantedPermissions != null) { + permissionRequest.grant(grantedPermissions.toArray(new String[0])); + permissionRequest = null; + grantedPermissions = null; + } + + if (!pendingPermissions.isEmpty()) { + requestPermissions(pendingPermissions); + return false; + } + + return true; + }; + + protected void openFileChooser(ValueCallback filePathCallback, String acceptType) { + this.mWebView.getThemedReactContext().getNativeModule(RNCWebViewModule.class).startPhotoPickerIntent(filePathCallback, acceptType); + } + + protected void openFileChooser(ValueCallback filePathCallback) { + this.mWebView.getThemedReactContext().getNativeModule(RNCWebViewModule.class).startPhotoPickerIntent(filePathCallback, ""); + } + + protected void openFileChooser(ValueCallback filePathCallback, String acceptType, String capture) { + this.mWebView.getThemedReactContext().getNativeModule(RNCWebViewModule.class).startPhotoPickerIntent(filePathCallback, acceptType); + } + + @Override + public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { + String[] acceptTypes = fileChooserParams.getAcceptTypes(); + boolean allowMultiple = fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE; + + return this.mWebView.getThemedReactContext().getNativeModule(RNCWebViewModule.class).startPhotoPickerIntent(filePathCallback, acceptTypes, allowMultiple); + } + + @Override + public void onHostResume() { + if (mVideoView != null && mVideoView.getSystemUiVisibility() != FULLSCREEN_SYSTEM_UI_VISIBILITY) { + mVideoView.setSystemUiVisibility(FULLSCREEN_SYSTEM_UI_VISIBILITY); + } + } + + @Override + public void onHostPause() { } + + @Override + public void onHostDestroy() { } + + protected ViewGroup getRootView() { + return this.mWebView.getThemedReactContext().getCurrentActivity().findViewById(android.R.id.content); + } + + public void setProgressChangedFilter(RNCWebView.ProgressChangedFilter filter) { + progressChangedFilter = filter; + } + + /** + * Set whether or not protected media should be allowed + * /!\ Setting this to false won't revoke permission already granted to the current webpage. + * In order to do so, you'd need to reload the page /!\ + */ + public void setAllowsProtectedMedia(boolean enabled) { + mAllowsProtectedMedia = enabled; + } +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java new file mode 100644 index 0000000..f998614 --- /dev/null +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java @@ -0,0 +1,337 @@ +package com.reactnativecommunity.webview; + +import androidx.annotation.Nullable; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Build; +import android.text.TextUtils; +import android.util.AttributeSet; + +import android.view.MotionEvent; +import android.view.View; +import android.webkit.JavascriptInterface; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.CatalystInstance; +import com.facebook.react.bridge.LifecycleEventListener; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeArray; +import com.facebook.react.bridge.WritableNativeMap; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIManagerHelper; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.events.ContentSizeChangeEvent; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.EventDispatcher; +import com.facebook.react.views.scroll.OnScrollDispatchHelper; +import com.facebook.react.views.scroll.ScrollEvent; +import com.facebook.react.views.scroll.ScrollEventType; +import com.reactnativecommunity.webview.events.TopLoadingProgressEvent; +import com.reactnativecommunity.webview.events.TopMessageEvent; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +public class RNCWebView extends WebView implements LifecycleEventListener { + protected @Nullable + String injectedJS; + protected @Nullable + String injectedJSBeforeContentLoaded; + protected static final String JAVASCRIPT_INTERFACE = "ReactNativeWebView"; + + /** + * android.webkit.WebChromeClient fundamentally does not support JS injection into frames other + * than the main frame, so these two properties are mostly here just for parity with iOS & macOS. + */ + protected boolean injectedJavaScriptForMainFrameOnly = true; + protected boolean injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true; + + protected boolean messagingEnabled = false; + protected @Nullable + String messagingModuleName; + protected @Nullable + RNCWebViewClient mRNCWebViewClient; + protected @Nullable + CatalystInstance mCatalystInstance; + protected boolean sendContentSizeChangeEvents = false; + private OnScrollDispatchHelper mOnScrollDispatchHelper; + protected boolean hasScrollEvent = false; + protected boolean nestedScrollEnabled = false; + protected ProgressChangedFilter progressChangedFilter; + + /** + * WebView must be created with an context of the current activity + *

+ * Activity Context is required for creation of dialogs internally by WebView + * Reactive Native needed for access to ReactNative internal system functionality + */ + public RNCWebView(ThemedReactContext reactContext) { + super(reactContext); + this.createCatalystInstance(); + progressChangedFilter = new ProgressChangedFilter(); + } + + public void setIgnoreErrFailedForThisURL(String url) { + mRNCWebViewClient.setIgnoreErrFailedForThisURL(url); + } + + public void setBasicAuthCredential(RNCBasicAuthCredential credential) { + mRNCWebViewClient.setBasicAuthCredential(credential); + } + + public void setSendContentSizeChangeEvents(boolean sendContentSizeChangeEvents) { + this.sendContentSizeChangeEvents = sendContentSizeChangeEvents; + } + + public void setHasScrollEvent(boolean hasScrollEvent) { + this.hasScrollEvent = hasScrollEvent; + } + + public void setNestedScrollEnabled(boolean nestedScrollEnabled) { + this.nestedScrollEnabled = nestedScrollEnabled; + } + + @Override + public void onHostResume() { + // do nothing + } + + @Override + public void onHostPause() { + // do nothing + } + + @Override + public void onHostDestroy() { + cleanupCallbacksAndDestroy(); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (this.nestedScrollEnabled) { + requestDisallowInterceptTouchEvent(true); + } + return super.onTouchEvent(event); + } + + @Override + protected void onSizeChanged(int w, int h, int ow, int oh) { + super.onSizeChanged(w, h, ow, oh); + + if (sendContentSizeChangeEvents) { + dispatchEvent( + this, + new ContentSizeChangeEvent( + this.getId(), + w, + h + ) + ); + } + } + + @Override + public void setWebViewClient(WebViewClient client) { + super.setWebViewClient(client); + if (client instanceof RNCWebViewClient) { + mRNCWebViewClient = (RNCWebViewClient) client; + mRNCWebViewClient.setProgressChangedFilter(progressChangedFilter); + } + } + + WebChromeClient mWebChromeClient; + @Override + public void setWebChromeClient(WebChromeClient client) { + this.mWebChromeClient = client; + super.setWebChromeClient(client); + if (client instanceof RNCWebChromeClient) { + ((RNCWebChromeClient) client).setProgressChangedFilter(progressChangedFilter); + } + } + + public WebChromeClient getWebChromeClient() { + return this.mWebChromeClient; + } + + public @Nullable + RNCWebViewClient getRNCWebViewClient() { + return mRNCWebViewClient; + } + + protected RNCWebViewBridge createRNCWebViewBridge(RNCWebView webView) { + return new RNCWebViewBridge(webView); + } + + protected void createCatalystInstance() { + ThemedReactContext reactContext = (ThemedReactContext) this.getContext(); + + if (reactContext != null) { + mCatalystInstance = reactContext.getCatalystInstance(); + } + } + + @SuppressLint("AddJavascriptInterface") + public void setMessagingEnabled(boolean enabled) { + if (messagingEnabled == enabled) { + return; + } + + messagingEnabled = enabled; + + if (enabled) { + addJavascriptInterface(createRNCWebViewBridge(this), JAVASCRIPT_INTERFACE); + } else { + removeJavascriptInterface(JAVASCRIPT_INTERFACE); + } + } + + protected void evaluateJavascriptWithFallback(String script) { + evaluateJavascript(script, null); + } + + public void callInjectedJavaScript() { + if (getSettings().getJavaScriptEnabled() && + injectedJS != null && + !TextUtils.isEmpty(injectedJS)) { + evaluateJavascriptWithFallback("(function() {\n" + injectedJS + ";\n})();"); + } + } + + public void callInjectedJavaScriptBeforeContentLoaded() { + if (getSettings().getJavaScriptEnabled() && + injectedJSBeforeContentLoaded != null && + !TextUtils.isEmpty(injectedJSBeforeContentLoaded)) { + evaluateJavascriptWithFallback("(function() {\n" + injectedJSBeforeContentLoaded + ";\n})();"); + } + } + + public void onMessage(String message) { + ThemedReactContext reactContext = getThemedReactContext(); + RNCWebView mWebView = this; + + if (mRNCWebViewClient != null) { + WebView webView = this; + webView.post(new Runnable() { + @Override + public void run() { + if (mRNCWebViewClient == null) { + return; + } + WritableMap data = mRNCWebViewClient.createWebViewEvent(webView, webView.getUrl()); + data.putString("data", message); + + if (mCatalystInstance != null) { + mWebView.sendDirectMessage("onMessage", data); + } else { + dispatchEvent(webView, new TopMessageEvent(webView.getId(), data)); + } + } + }); + } else { + WritableMap eventData = Arguments.createMap(); + eventData.putString("data", message); + + if (mCatalystInstance != null) { + this.sendDirectMessage("onMessage", eventData); + } else { + dispatchEvent(this, new TopMessageEvent(this.getId(), eventData)); + } + } + } + + protected void sendDirectMessage(final String method, WritableMap data) { + WritableNativeMap event = new WritableNativeMap(); + event.putMap("nativeEvent", data); + + WritableNativeArray params = new WritableNativeArray(); + params.pushMap(event); + + mCatalystInstance.callFunction(messagingModuleName, method, params); + } + + protected void onScrollChanged(int x, int y, int oldX, int oldY) { + super.onScrollChanged(x, y, oldX, oldY); + + if (!hasScrollEvent) { + return; + } + + if (mOnScrollDispatchHelper == null) { + mOnScrollDispatchHelper = new OnScrollDispatchHelper(); + } + + if (mOnScrollDispatchHelper.onScrollChanged(x, y)) { + ScrollEvent event = ScrollEvent.obtain( + this.getId(), + ScrollEventType.SCROLL, + x, + y, + mOnScrollDispatchHelper.getXFlingVelocity(), + mOnScrollDispatchHelper.getYFlingVelocity(), + this.computeHorizontalScrollRange(), + this.computeVerticalScrollRange(), + this.getWidth(), + this.getHeight()); + + dispatchEvent(this, event); + } + } + + protected void dispatchEvent(WebView webView, Event event) { + ThemedReactContext reactContext = getThemedReactContext(); + int reactTag = webView.getId(); + UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag).dispatchEvent(event); + } + + protected void cleanupCallbacksAndDestroy() { + setWebViewClient(null); + destroy(); + } + + @Override + public void destroy() { + if (mWebChromeClient != null) { + mWebChromeClient.onHideCustomView(); + } + super.destroy(); + } + + public ThemedReactContext getThemedReactContext() { + return (ThemedReactContext) this.getContext(); + } + + protected class RNCWebViewBridge { + RNCWebView mWebView; + + RNCWebViewBridge(RNCWebView c) { + mWebView = c; + } + + /** + * This method is called whenever JavaScript running within the web view calls: + * - window[JAVASCRIPT_INTERFACE].postMessage + */ + @JavascriptInterface + public void postMessage(String message) { + mWebView.onMessage(message); + } + } + + + protected static class ProgressChangedFilter { + private boolean waitingForCommandLoadUrl = false; + + public void setWaitingForCommandLoadUrl(boolean isWaiting) { + waitingForCommandLoadUrl = isWaiting; + } + + public boolean isWaitingForCommandLoadUrl() { + return waitingForCommandLoadUrl; + } + } +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java new file mode 100644 index 0000000..1a1da85 --- /dev/null +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java @@ -0,0 +1,312 @@ +package com.reactnativecommunity.webview; + +import android.annotation.TargetApi; +import android.graphics.Bitmap; +import android.net.http.SslError; +import android.os.Build; +import android.os.SystemClock; +import android.util.Log; +import android.webkit.HttpAuthHandler; +import android.webkit.RenderProcessGoneDetail; +import android.webkit.SslErrorHandler; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.core.util.Pair; + +import com.facebook.common.logging.FLog; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIManagerHelper; +import com.reactnativecommunity.webview.events.TopHttpErrorEvent; +import com.reactnativecommunity.webview.events.TopLoadingErrorEvent; +import com.reactnativecommunity.webview.events.TopLoadingFinishEvent; +import com.reactnativecommunity.webview.events.TopLoadingStartEvent; +import com.reactnativecommunity.webview.events.TopRenderProcessGoneEvent; +import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent; + +import java.util.concurrent.atomic.AtomicReference; + +public class RNCWebViewClient extends WebViewClient { + private static String TAG = "RNCWebViewClient"; + protected static final int SHOULD_OVERRIDE_URL_LOADING_TIMEOUT = 250; + + protected boolean mLastLoadFailed = false; + protected RNCWebView.ProgressChangedFilter progressChangedFilter = null; + protected @Nullable String ignoreErrFailedForThisURL = null; + protected @Nullable RNCBasicAuthCredential basicAuthCredential = null; + + public void setIgnoreErrFailedForThisURL(@Nullable String url) { + ignoreErrFailedForThisURL = url; + } + + public void setBasicAuthCredential(@Nullable RNCBasicAuthCredential credential) { + basicAuthCredential = credential; + } + + @Override + public void onPageFinished(WebView webView, String url) { + super.onPageFinished(webView, url); + + if (!mLastLoadFailed) { + RNCWebView reactWebView = (RNCWebView) webView; + + reactWebView.callInjectedJavaScript(); + + emitFinishEvent(webView, url); + } + } + + @Override + public void onPageStarted(WebView webView, String url, Bitmap favicon) { + super.onPageStarted(webView, url, favicon); + mLastLoadFailed = false; + + RNCWebView reactWebView = (RNCWebView) webView; + reactWebView.callInjectedJavaScriptBeforeContentLoaded(); + int reactTag = webView.getId(); + + UIManagerHelper.getEventDispatcherForReactTag((ReactContext) webView.getContext(), reactTag).dispatchEvent(new TopLoadingStartEvent( + webView.getId(), + createWebViewEvent(webView, url))); + } + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + final RNCWebView rncWebView = (RNCWebView) view; + final boolean isJsDebugging = ((ReactContext) view.getContext()).getJavaScriptContextHolder().get() == 0; + + if (!isJsDebugging && rncWebView.mCatalystInstance != null) { + final Pair> lock = RNCWebViewModuleImpl.shouldOverrideUrlLoadingLock.getNewLock(); + final double lockIdentifier = lock.first; + final AtomicReference lockObject = lock.second; + + final WritableMap event = createWebViewEvent(view, url); + event.putDouble("lockIdentifier", lockIdentifier); + rncWebView.sendDirectMessage("onShouldStartLoadWithRequest", event); + + try { + assert lockObject != null; + synchronized (lockObject) { + final long startTime = SystemClock.elapsedRealtime(); + while (lockObject.get() == RNCWebViewModuleImpl.ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.UNDECIDED) { + if (SystemClock.elapsedRealtime() - startTime > SHOULD_OVERRIDE_URL_LOADING_TIMEOUT) { + FLog.w(TAG, "Did not receive response to shouldOverrideUrlLoading in time, defaulting to allow loading."); + RNCWebViewModuleImpl.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier); + return false; + } + lockObject.wait(SHOULD_OVERRIDE_URL_LOADING_TIMEOUT); + } + } + } catch (InterruptedException e) { + FLog.e(TAG, "shouldOverrideUrlLoading was interrupted while waiting for result.", e); + RNCWebViewModuleImpl.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier); + return false; + } + + final boolean shouldOverride = lockObject.get() == RNCWebViewModuleImpl.ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.SHOULD_OVERRIDE; + RNCWebViewModuleImpl.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier); + + return shouldOverride; + } else { + FLog.w(TAG, "Couldn't use blocking synchronous call for onShouldStartLoadWithRequest due to debugging or missing Catalyst instance, falling back to old event-and-load."); + progressChangedFilter.setWaitingForCommandLoadUrl(true); + + int reactTag = view.getId(); + UIManagerHelper.getEventDispatcherForReactTag((ReactContext) view.getContext(), reactTag).dispatchEvent(new TopShouldStartLoadWithRequestEvent( + reactTag, + createWebViewEvent(view, url))); + return true; + } + } + + @TargetApi(Build.VERSION_CODES.N) + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + final String url = request.getUrl().toString(); + return this.shouldOverrideUrlLoading(view, url); + } + + @Override + public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { + if (basicAuthCredential != null) { + handler.proceed(basicAuthCredential.username, basicAuthCredential.password); + return; + } + super.onReceivedHttpAuthRequest(view, handler, host, realm); + } + + @Override + public void onReceivedSslError(final WebView webView, final SslErrorHandler handler, final SslError error) { + // onReceivedSslError is called for most requests, per Android docs: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%2520android.webkit.SslErrorHandler,%2520android.net.http.SslError) + // WebView.getUrl() will return the top-level window URL. + // If a top-level navigation triggers this error handler, the top-level URL will be the failing URL (not the URL of the currently-rendered page). + // This is desired behavior. We later use these values to determine whether the request is a top-level navigation or a subresource request. + String topWindowUrl = webView.getUrl(); + String failingUrl = error.getUrl(); + + // Cancel request after obtaining top-level URL. + // If request is cancelled before obtaining top-level URL, undesired behavior may occur. + // Undesired behavior: Return value of WebView.getUrl() may be the current URL instead of the failing URL. + handler.cancel(); + + if (!topWindowUrl.equalsIgnoreCase(failingUrl)) { + // If error is not due to top-level navigation, then do not call onReceivedError() + Log.w(TAG, "Resource blocked from loading due to SSL error. Blocked URL: "+failingUrl); + return; + } + + int code = error.getPrimaryError(); + String description = ""; + String descriptionPrefix = "SSL error: "; + + // https://developer.android.com/reference/android/net/http/SslError.html + switch (code) { + case SslError.SSL_DATE_INVALID: + description = "The date of the certificate is invalid"; + break; + case SslError.SSL_EXPIRED: + description = "The certificate has expired"; + break; + case SslError.SSL_IDMISMATCH: + description = "Hostname mismatch"; + break; + case SslError.SSL_INVALID: + description = "A generic error occurred"; + break; + case SslError.SSL_NOTYETVALID: + description = "The certificate is not yet valid"; + break; + case SslError.SSL_UNTRUSTED: + description = "The certificate authority is not trusted"; + break; + default: + description = "Unknown SSL Error"; + break; + } + + description = descriptionPrefix + description; + + this.onReceivedError( + webView, + code, + description, + failingUrl + ); + } + + @Override + public void onReceivedError( + WebView webView, + int errorCode, + String description, + String failingUrl) { + + if (ignoreErrFailedForThisURL != null + && failingUrl.equals(ignoreErrFailedForThisURL) + && errorCode == -1 + && description.equals("net::ERR_FAILED")) { + + // This is a workaround for a bug in the WebView. + // See these chromium issues for more context: + // https://bugs.chromium.org/p/chromium/issues/detail?id=1023678 + // https://bugs.chromium.org/p/chromium/issues/detail?id=1050635 + // This entire commit should be reverted once this bug is resolved in chromium. + setIgnoreErrFailedForThisURL(null); + return; + } + + super.onReceivedError(webView, errorCode, description, failingUrl); + mLastLoadFailed = true; + + // In case of an error JS side expect to get a finish event first, and then get an error event + // Android WebView does it in the opposite way, so we need to simulate that behavior + emitFinishEvent(webView, failingUrl); + + WritableMap eventData = createWebViewEvent(webView, failingUrl); + eventData.putDouble("code", errorCode); + eventData.putString("description", description); + + int reactTag = webView.getId(); + UIManagerHelper.getEventDispatcherForReactTag((ReactContext) webView.getContext(), reactTag).dispatchEvent(new TopLoadingErrorEvent(webView.getId(), eventData)); + } + + @RequiresApi(api = Build.VERSION_CODES.M) + @Override + public void onReceivedHttpError( + WebView webView, + WebResourceRequest request, + WebResourceResponse errorResponse) { + super.onReceivedHttpError(webView, request, errorResponse); + + if (request.isForMainFrame()) { + WritableMap eventData = createWebViewEvent(webView, request.getUrl().toString()); + eventData.putInt("statusCode", errorResponse.getStatusCode()); + eventData.putString("description", errorResponse.getReasonPhrase()); + + int reactTag = webView.getId(); + UIManagerHelper.getEventDispatcherForReactTag((ReactContext) webView.getContext(), reactTag).dispatchEvent(new TopHttpErrorEvent(webView.getId(), eventData)); + } + } + + @TargetApi(Build.VERSION_CODES.O) + @Override + public boolean onRenderProcessGone(WebView webView, RenderProcessGoneDetail detail) { + // WebViewClient.onRenderProcessGone was added in O. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + return false; + } + super.onRenderProcessGone(webView, detail); + + if(detail.didCrash()){ + Log.e(TAG, "The WebView rendering process crashed."); + } + else{ + Log.w(TAG, "The WebView rendering process was killed by the system."); + } + + // if webView is null, we cannot return any event + // since the view is already dead/disposed + // still prevent the app crash by returning true. + if(webView == null){ + return true; + } + + WritableMap event = createWebViewEvent(webView, webView.getUrl()); + event.putBoolean("didCrash", detail.didCrash()); + int reactTag = webView.getId(); + UIManagerHelper.getEventDispatcherForReactTag((ReactContext) webView.getContext(), reactTag).dispatchEvent(new TopRenderProcessGoneEvent(webView.getId(), event)); + + // returning false would crash the app. + return true; + } + + protected void emitFinishEvent(WebView webView, String url) { + int reactTag = webView.getId(); + UIManagerHelper.getEventDispatcherForReactTag((ReactContext) webView.getContext(), reactTag).dispatchEvent(new TopLoadingFinishEvent(webView.getId(), createWebViewEvent(webView, url))); + } + + protected WritableMap createWebViewEvent(WebView webView, String url) { + WritableMap event = Arguments.createMap(); + event.putDouble("target", webView.getId()); + // Don't use webView.getUrl() here, the URL isn't updated to the new value yet in callbacks + // like onPageFinished + event.putString("url", url); + event.putBoolean("loading", !mLastLoadFailed && webView.getProgress() != 100); + event.putString("title", webView.getTitle()); + event.putBoolean("canGoBack", webView.canGoBack()); + event.putBoolean("canGoForward", webView.canGoForward()); + return event; + } + + public void setProgressChangedFilter(RNCWebView.ProgressChangedFilter filter) { + progressChangedFilter = filter; + } +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/WebViewConfig.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewConfig.java similarity index 77% rename from android/src/main/java/com/reactnativecommunity/webview/WebViewConfig.java rename to android/src/main/java/com/reactnativecommunity/webview/RNCWebViewConfig.java index ac917db..eea047d 100644 --- a/android/src/main/java/com/reactnativecommunity/webview/WebViewConfig.java +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewConfig.java @@ -6,7 +6,6 @@ * Implement this interface in order to config your {@link WebView}. An instance of that * implementation will have to be given as a constructor argument to {@link RNCWebViewManager}. */ -public interface WebViewConfig { - - void configWebView(WebView webView); -} +public interface RNCWebViewConfig { + void configWebView(WebView webView); +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java index cadd8ed..919b3ad 100644 --- a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java @@ -11,4 +11,4 @@ public class RNCWebViewFileProvider extends FileProvider { // This class intentionally left blank. -} +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java deleted file mode 100644 index 9cfe821..0000000 --- a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java +++ /dev/null @@ -1,1853 +0,0 @@ -package com.reactnativecommunity.webview; - -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.DownloadManager; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.Manifest; -import android.net.http.SslError; -import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.os.Message; -import android.os.SystemClock; -import android.text.TextUtils; -import android.util.Log; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; -import android.webkit.ConsoleMessage; -import android.webkit.CookieManager; -import android.webkit.DownloadListener; -import android.webkit.GeolocationPermissions; -import android.webkit.HttpAuthHandler; -import android.webkit.JavascriptInterface; -import android.webkit.RenderProcessGoneDetail; -import android.webkit.SslErrorHandler; -import android.webkit.PermissionRequest; -import android.webkit.ValueCallback; -import android.webkit.WebChromeClient; -import android.webkit.WebResourceRequest; -import android.webkit.WebResourceResponse; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.FrameLayout; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.core.content.ContextCompat; -import androidx.core.util.Pair; -import androidx.webkit.WebSettingsCompat; -import androidx.webkit.WebViewFeature; - -import com.facebook.common.logging.FLog; -import com.facebook.react.modules.core.PermissionAwareActivity; -import com.facebook.react.modules.core.PermissionListener; -import com.facebook.react.views.scroll.ScrollEvent; -import com.facebook.react.views.scroll.ScrollEventType; -import com.facebook.react.views.scroll.OnScrollDispatchHelper; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.CatalystInstance; -import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.bridge.ReadableMapKeySetIterator; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeArray; -import com.facebook.react.bridge.WritableNativeMap; -import com.facebook.react.common.MapBuilder; -import com.facebook.react.common.build.ReactBuildConfig; -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.uimanager.SimpleViewManager; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.UIManagerModule; -import com.facebook.react.uimanager.annotations.ReactProp; -import com.facebook.react.uimanager.events.ContentSizeChangeEvent; -import com.facebook.react.uimanager.events.Event; -import com.facebook.react.uimanager.events.EventDispatcher; -import com.reactnativecommunity.webview.RNCWebViewModule.ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState; -import com.reactnativecommunity.webview.events.TopLoadingErrorEvent; -import com.reactnativecommunity.webview.events.TopHttpErrorEvent; -import com.reactnativecommunity.webview.events.TopLoadingFinishEvent; -import com.reactnativecommunity.webview.events.TopLoadingProgressEvent; -import com.reactnativecommunity.webview.events.TopLoadingStartEvent; -import com.reactnativecommunity.webview.events.TopMessageEvent; -import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent; -import com.reactnativecommunity.webview.events.TopRenderProcessGoneEvent; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.UnsupportedEncodingException; -import java.lang.IllegalArgumentException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -/** - * Manages instances of {@link WebView} - *

- * Can accept following commands: - * - GO_BACK - * - GO_FORWARD - * - RELOAD - * - LOAD_URL - *

- * {@link WebView} instances could emit following direct events: - * - topLoadingFinish - * - topLoadingStart - * - topLoadingStart - * - topLoadingProgress - * - topShouldStartLoadWithRequest - *

- * Each event will carry the following properties: - * - target - view's react tag - * - url - url set for the webview - * - loading - whether webview is in a loading state - * - title - title of the current page - * - canGoBack - boolean, whether there is anything on a history stack to go back - * - canGoForward - boolean, whether it is possible to request GO_FORWARD command - */ -@ReactModule(name = RNCWebViewManager.REACT_CLASS) -public class RNCWebViewManager extends SimpleViewManager { - private static final String TAG = "RNCWebViewManager"; - - public static final int COMMAND_GO_BACK = 1; - public static final int COMMAND_GO_FORWARD = 2; - public static final int COMMAND_RELOAD = 3; - public static final int COMMAND_STOP_LOADING = 4; - public static final int COMMAND_POST_MESSAGE = 5; - public static final int COMMAND_INJECT_JAVASCRIPT = 6; - public static final int COMMAND_LOAD_URL = 7; - public static final int COMMAND_FOCUS = 8; - - // android commands - public static final int COMMAND_CLEAR_FORM_DATA = 1000; - public static final int COMMAND_CLEAR_CACHE = 1001; - public static final int COMMAND_CLEAR_HISTORY = 1002; - - protected static final String REACT_CLASS = "RNCWebView"; - protected static final String HTML_ENCODING = "UTF-8"; - protected static final String HTML_MIME_TYPE = "text/html"; - protected static final String JAVASCRIPT_INTERFACE = "ReactNativeWebView"; - protected static final String HTTP_METHOD_POST = "POST"; - // Use `webView.loadUrl("about:blank")` to reliably reset the view - // state and release page resources (including any running JavaScript). - protected static final String BLANK_URL = "about:blank"; - protected static final int SHOULD_OVERRIDE_URL_LOADING_TIMEOUT = 250; - protected static final String DEFAULT_DOWNLOADING_MESSAGE = "Downloading"; - protected static final String DEFAULT_LACK_PERMISSION_TO_DOWNLOAD_MESSAGE = - "Cannot download files as permission was denied. Please provide permission to write to storage, in order to download files."; - protected WebViewConfig mWebViewConfig; - - protected RNCWebChromeClient mWebChromeClient = null; - protected boolean mAllowsFullscreenVideo = false; - protected boolean mAllowsProtectedMedia = false; - protected @Nullable String mUserAgent = null; - protected @Nullable String mUserAgentWithApplicationName = null; - protected @Nullable String mDownloadingMessage = null; - protected @Nullable String mLackPermissionToDownloadMessage = null; - - public RNCWebViewManager() { - mWebViewConfig = new WebViewConfig() { - public void configWebView(WebView webView) { - } - }; - } - - public RNCWebViewManager(WebViewConfig webViewConfig) { - mWebViewConfig = webViewConfig; - } - - @Override - public String getName() { - return REACT_CLASS; - } - - protected RNCWebView createRNCWebViewInstance(ThemedReactContext reactContext) { - return new RNCWebView(reactContext); - } - - @Override - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - protected WebView createViewInstance(ThemedReactContext reactContext) { - RNCWebView webView = createRNCWebViewInstance(reactContext); - setupWebChromeClient(reactContext, webView); - reactContext.addLifecycleEventListener(webView); - mWebViewConfig.configWebView(webView); - WebSettings settings = webView.getSettings(); - settings.setBuiltInZoomControls(true); - settings.setDisplayZoomControls(false); - settings.setDomStorageEnabled(true); - settings.setSupportMultipleWindows(true); - - settings.setAllowFileAccess(false); - settings.setAllowContentAccess(false); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - settings.setAllowFileAccessFromFileURLs(false); - setAllowUniversalAccessFromFileURLs(webView, false); - } - setMixedContentMode(webView, "never"); - - // Fixes broken full-screen modals/galleries due to body height being 0. - webView.setLayoutParams( - new LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT)); - - if (ReactBuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - WebView.setWebContentsDebuggingEnabled(true); - } - - webView.setDownloadListener(new DownloadListener() { - public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { - webView.setIgnoreErrFailedForThisURL(url); - - RNCWebViewModule module = getModule(reactContext); - - DownloadManager.Request request; - try { - request = new DownloadManager.Request(Uri.parse(url)); - } catch (IllegalArgumentException e) { - Log.w(TAG, "Unsupported URI, aborting download", e); - return; - } - - String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); - String downloadMessage = "Downloading " + fileName; - - //Attempt to add cookie, if it exists - URL urlObj = null; - try { - urlObj = new URL(url); - String baseUrl = urlObj.getProtocol() + "://" + urlObj.getHost(); - String cookie = CookieManager.getInstance().getCookie(baseUrl); - request.addRequestHeader("Cookie", cookie); - } catch (MalformedURLException e) { - Log.w(TAG, "Error getting cookie for DownloadManager", e); - } - - //Finish setting up request - request.addRequestHeader("User-Agent", userAgent); - request.setTitle(fileName); - request.setDescription(downloadMessage); - request.allowScanningByMediaScanner(); - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); - - module.setDownloadRequest(request); - - if (module.grantFileDownloaderPermissions(getDownloadingMessage(), getLackPermissionToDownloadMessage())) { - module.downloadFile(getDownloadingMessage()); - } - } - }); - - return webView; - } - - private String getDownloadingMessage() { - return mDownloadingMessage == null ? DEFAULT_DOWNLOADING_MESSAGE : mDownloadingMessage; - } - - private String getLackPermissionToDownloadMessage() { - return mDownloadingMessage == null ? DEFAULT_LACK_PERMISSION_TO_DOWNLOAD_MESSAGE : mLackPermissionToDownloadMessage; - } - - @ReactProp(name = "javaScriptEnabled") - public void setJavaScriptEnabled(WebView view, boolean enabled) { - view.getSettings().setJavaScriptEnabled(enabled); - } - - @ReactProp(name = "setBuiltInZoomControls") - public void setBuiltInZoomControls(WebView view, boolean enabled) { - view.getSettings().setBuiltInZoomControls(enabled); - } - - @ReactProp(name = "setDisplayZoomControls") - public void setDisplayZoomControls(WebView view, boolean enabled) { - view.getSettings().setDisplayZoomControls(enabled); - } - - @ReactProp(name = "setSupportMultipleWindows") - public void setSupportMultipleWindows(WebView view, boolean enabled){ - view.getSettings().setSupportMultipleWindows(enabled); - } - - @ReactProp(name = "showsHorizontalScrollIndicator") - public void setShowsHorizontalScrollIndicator(WebView view, boolean enabled) { - view.setHorizontalScrollBarEnabled(enabled); - } - - @ReactProp(name = "showsVerticalScrollIndicator") - public void setShowsVerticalScrollIndicator(WebView view, boolean enabled) { - view.setVerticalScrollBarEnabled(enabled); - } - - @ReactProp(name = "downloadingMessage") - public void setDownloadingMessage(WebView view, String message) { - mDownloadingMessage = message; - } - - @ReactProp(name = "lackPermissionToDownloadMessage") - public void setLackPermissionToDownlaodMessage(WebView view, String message) { - mLackPermissionToDownloadMessage = message; - } - - @ReactProp(name = "cacheEnabled") - public void setCacheEnabled(WebView view, boolean enabled) { - view.getSettings().setCacheMode(enabled ? WebSettings.LOAD_DEFAULT : WebSettings.LOAD_NO_CACHE); - } - - @ReactProp(name = "cacheMode") - public void setCacheMode(WebView view, String cacheModeString) { - Integer cacheMode; - switch (cacheModeString) { - case "LOAD_CACHE_ONLY": - cacheMode = WebSettings.LOAD_CACHE_ONLY; - break; - case "LOAD_CACHE_ELSE_NETWORK": - cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK; - break; - case "LOAD_NO_CACHE": - cacheMode = WebSettings.LOAD_NO_CACHE; - break; - case "LOAD_DEFAULT": - default: - cacheMode = WebSettings.LOAD_DEFAULT; - break; - } - view.getSettings().setCacheMode(cacheMode); - } - - @ReactProp(name = "androidHardwareAccelerationDisabled") - public void setHardwareAccelerationDisabled(WebView view, boolean disabled) { - if (disabled) { - view.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } - } - - @ReactProp(name = "androidLayerType") - public void setLayerType(WebView view, String layerTypeString) { - int layerType = View.LAYER_TYPE_NONE; - switch (layerTypeString) { - case "hardware": - layerType = View.LAYER_TYPE_HARDWARE; - break; - case "software": - layerType = View.LAYER_TYPE_SOFTWARE; - break; - } - view.setLayerType(layerType, null); - } - - - @ReactProp(name = "overScrollMode") - public void setOverScrollMode(WebView view, String overScrollModeString) { - Integer overScrollMode; - switch (overScrollModeString) { - case "never": - overScrollMode = View.OVER_SCROLL_NEVER; - break; - case "content": - overScrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS; - break; - case "always": - default: - overScrollMode = View.OVER_SCROLL_ALWAYS; - break; - } - view.setOverScrollMode(overScrollMode); - } - - @ReactProp(name = "nestedScrollEnabled") - public void setNestedScrollEnabled(WebView view, boolean enabled) { - ((RNCWebView) view).setNestedScrollEnabled(enabled); - } - - @ReactProp(name = "thirdPartyCookiesEnabled") - public void setThirdPartyCookiesEnabled(WebView view, boolean enabled) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - CookieManager.getInstance().setAcceptThirdPartyCookies(view, enabled); - } - } - - @ReactProp(name = "textZoom") - public void setTextZoom(WebView view, int value) { - view.getSettings().setTextZoom(value); - } - - @ReactProp(name = "scalesPageToFit") - public void setScalesPageToFit(WebView view, boolean enabled) { - view.getSettings().setLoadWithOverviewMode(enabled); - view.getSettings().setUseWideViewPort(enabled); - } - - @ReactProp(name = "domStorageEnabled") - public void setDomStorageEnabled(WebView view, boolean enabled) { - view.getSettings().setDomStorageEnabled(enabled); - } - - @ReactProp(name = "userAgent") - public void setUserAgent(WebView view, @Nullable String userAgent) { - if (userAgent != null) { - mUserAgent = userAgent; - } else { - mUserAgent = null; - } - this.setUserAgentString(view); - } - - @ReactProp(name = "applicationNameForUserAgent") - public void setApplicationNameForUserAgent(WebView view, @Nullable String applicationName) { - if(applicationName != null) { - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - String defaultUserAgent = WebSettings.getDefaultUserAgent(view.getContext()); - mUserAgentWithApplicationName = defaultUserAgent + " " + applicationName; - } - } else { - mUserAgentWithApplicationName = null; - } - this.setUserAgentString(view); - } - - protected void setUserAgentString(WebView view) { - if(mUserAgent != null) { - view.getSettings().setUserAgentString(mUserAgent); - } else if(mUserAgentWithApplicationName != null) { - view.getSettings().setUserAgentString(mUserAgentWithApplicationName); - } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - // handle unsets of `userAgent` prop as long as device is >= API 17 - view.getSettings().setUserAgentString(WebSettings.getDefaultUserAgent(view.getContext())); - } - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - @ReactProp(name = "mediaPlaybackRequiresUserAction") - public void setMediaPlaybackRequiresUserAction(WebView view, boolean requires) { - view.getSettings().setMediaPlaybackRequiresUserGesture(requires); - } - - @ReactProp(name = "javaScriptCanOpenWindowsAutomatically") - public void setJavaScriptCanOpenWindowsAutomatically(WebView view, boolean enabled) { - view.getSettings().setJavaScriptCanOpenWindowsAutomatically(enabled); - } - - @ReactProp(name = "allowFileAccessFromFileURLs") - public void setAllowFileAccessFromFileURLs(WebView view, boolean allow) { - view.getSettings().setAllowFileAccessFromFileURLs(allow); - } - - @ReactProp(name = "allowUniversalAccessFromFileURLs") - public void setAllowUniversalAccessFromFileURLs(WebView view, boolean allow) { - view.getSettings().setAllowUniversalAccessFromFileURLs(allow); - } - - @ReactProp(name = "saveFormDataDisabled") - public void setSaveFormDataDisabled(WebView view, boolean disable) { - view.getSettings().setSaveFormData(!disable); - } - - @ReactProp(name = "injectedJavaScript") - public void setInjectedJavaScript(WebView view, @Nullable String injectedJavaScript) { - ((RNCWebView) view).setInjectedJavaScript(injectedJavaScript); - } - - @ReactProp(name = "injectedJavaScriptBeforeContentLoaded") - public void setInjectedJavaScriptBeforeContentLoaded(WebView view, @Nullable String injectedJavaScriptBeforeContentLoaded) { - ((RNCWebView) view).setInjectedJavaScriptBeforeContentLoaded(injectedJavaScriptBeforeContentLoaded); - } - - @ReactProp(name = "injectedJavaScriptForMainFrameOnly") - public void setInjectedJavaScriptForMainFrameOnly(WebView view, boolean enabled) { - ((RNCWebView) view).setInjectedJavaScriptForMainFrameOnly(enabled); - } - - @ReactProp(name = "injectedJavaScriptBeforeContentLoadedForMainFrameOnly") - public void setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(WebView view, boolean enabled) { - ((RNCWebView) view).setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(enabled); - } - - @ReactProp(name = "messagingEnabled") - public void setMessagingEnabled(WebView view, boolean enabled) { - ((RNCWebView) view).setMessagingEnabled(enabled); - } - - @ReactProp(name = "messagingModuleName") - public void setMessagingModuleName(WebView view, String moduleName) { - ((RNCWebView) view).setMessagingModuleName(moduleName); - } - - @ReactProp(name = "incognito") - public void setIncognito(WebView view, boolean enabled) { - // Don't do anything when incognito is disabled - if (!enabled) { - return; - } - - // Remove all previous cookies - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - CookieManager.getInstance().removeAllCookies(null); - } else { - CookieManager.getInstance().removeAllCookie(); - } - - // Disable caching - view.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); - view.clearHistory(); - view.clearCache(true); - - // No form data or autofill enabled - view.clearFormData(); - view.getSettings().setSavePassword(false); - view.getSettings().setSaveFormData(false); - } - - @ReactProp(name = "source") - public void setSource(WebView view, @Nullable ReadableMap source) { - if (source != null) { - if (source.hasKey("html")) { - String html = source.getString("html"); - String baseUrl = source.hasKey("baseUrl") ? source.getString("baseUrl") : ""; - view.loadDataWithBaseURL(baseUrl, html, HTML_MIME_TYPE, HTML_ENCODING, null); - return; - } - if (source.hasKey("uri")) { - String url = source.getString("uri"); - String previousUrl = view.getUrl(); - if (previousUrl != null && previousUrl.equals(url)) { - return; - } - if (source.hasKey("method")) { - String method = source.getString("method"); - if (method.equalsIgnoreCase(HTTP_METHOD_POST)) { - byte[] postData = null; - if (source.hasKey("body")) { - String body = source.getString("body"); - try { - postData = body.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - postData = body.getBytes(); - } - } - if (postData == null) { - postData = new byte[0]; - } - view.postUrl(url, postData); - return; - } - } - HashMap headerMap = new HashMap<>(); - if (source.hasKey("headers")) { - ReadableMap headers = source.getMap("headers"); - ReadableMapKeySetIterator iter = headers.keySetIterator(); - while (iter.hasNextKey()) { - String key = iter.nextKey(); - if ("user-agent".equals(key.toLowerCase(Locale.ENGLISH))) { - if (view.getSettings() != null) { - view.getSettings().setUserAgentString(headers.getString(key)); - } - } else { - headerMap.put(key, headers.getString(key)); - } - } - } - view.loadUrl(url, headerMap); - return; - } - } - view.loadUrl(BLANK_URL); - } - - @ReactProp(name = "basicAuthCredential") - public void setBasicAuthCredential(WebView view, @Nullable ReadableMap credential) { - @Nullable BasicAuthCredential basicAuthCredential = null; - if (credential != null) { - if (credential.hasKey("username") && credential.hasKey("password")) { - String username = credential.getString("username"); - String password = credential.getString("password"); - basicAuthCredential = new BasicAuthCredential(username, password); - } - } - ((RNCWebView) view).setBasicAuthCredential(basicAuthCredential); - } - - @ReactProp(name = "onContentSizeChange") - public void setOnContentSizeChange(WebView view, boolean sendContentSizeChangeEvents) { - ((RNCWebView) view).setSendContentSizeChangeEvents(sendContentSizeChangeEvents); - } - - @ReactProp(name = "mixedContentMode") - public void setMixedContentMode(WebView view, @Nullable String mixedContentMode) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - if (mixedContentMode == null || "never".equals(mixedContentMode)) { - view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW); - } else if ("always".equals(mixedContentMode)) { - view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); - } else if ("compatibility".equals(mixedContentMode)) { - view.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE); - } - } - } - - @ReactProp(name = "urlPrefixesForDefaultIntent") - public void setUrlPrefixesForDefaultIntent( - WebView view, - @Nullable ReadableArray urlPrefixesForDefaultIntent) { - RNCWebViewClient client = ((RNCWebView) view).getRNCWebViewClient(); - if (client != null && urlPrefixesForDefaultIntent != null) { - client.setUrlPrefixesForDefaultIntent(urlPrefixesForDefaultIntent); - } - } - - @ReactProp(name = "allowsFullscreenVideo") - public void setAllowsFullscreenVideo( - WebView view, - @Nullable Boolean allowsFullscreenVideo) { - mAllowsFullscreenVideo = allowsFullscreenVideo != null && allowsFullscreenVideo; - setupWebChromeClient((ReactContext)view.getContext(), view); - } - - @ReactProp(name = "allowFileAccess") - public void setAllowFileAccess( - WebView view, - @Nullable Boolean allowFileAccess) { - view.getSettings().setAllowFileAccess(allowFileAccess != null && allowFileAccess); - } - - @ReactProp(name = "geolocationEnabled") - public void setGeolocationEnabled( - WebView view, - @Nullable Boolean isGeolocationEnabled) { - view.getSettings().setGeolocationEnabled(isGeolocationEnabled != null && isGeolocationEnabled); - } - - @ReactProp(name = "onScroll") - public void setOnScroll(WebView view, boolean hasScrollEvent) { - ((RNCWebView) view).setHasScrollEvent(hasScrollEvent); - } - - @ReactProp(name = "forceDarkOn") - public void setForceDarkOn(WebView view, boolean enabled) { - // Only Android 10+ support dark mode - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - // Switch WebView dark mode - if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { - int forceDarkMode = enabled ? WebSettingsCompat.FORCE_DARK_ON : WebSettingsCompat.FORCE_DARK_OFF; - WebSettingsCompat.setForceDark(view.getSettings(), forceDarkMode); - } - - // Set how WebView content should be darkened. - // PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: checks for the "color-scheme" tag. - // If present, it uses media queries. If absent, it applies user-agent (automatic) - // More information about Force Dark Strategy can be found here: - // https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setForceDarkStrategy(android.webkit.WebSettings) - if (enabled && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) { - WebSettingsCompat.setForceDarkStrategy(view.getSettings(), WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING); - } - } - } - - @ReactProp(name = "minimumFontSize") - public void setMinimumFontSize(WebView view, int fontSize) { - view.getSettings().setMinimumFontSize(fontSize); - } - - @ReactProp(name = "allowsProtectedMedia") - public void setAllowsProtectedMedia(WebView view, boolean enabled) { - // This variable is used to keep consistency - // in case a new WebChromeClient is created - // (eg. when mAllowsFullScreenVideo changes) - mAllowsProtectedMedia = enabled; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - WebChromeClient client = view.getWebChromeClient(); - if (client != null && client instanceof RNCWebChromeClient) { - ((RNCWebChromeClient) client).setAllowsProtectedMedia(enabled); - } - } - } - - @Override - protected void addEventEmitters(ThemedReactContext reactContext, WebView view) { - // Do not register default touch emitter and let WebView implementation handle touches - view.setWebViewClient(new RNCWebViewClient()); - } - - @Override - public Map getExportedCustomDirectEventTypeConstants() { - Map export = super.getExportedCustomDirectEventTypeConstants(); - if (export == null) { - export = MapBuilder.newHashMap(); - } - // Default events but adding them here explicitly for clarity - export.put(TopLoadingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingStart")); - export.put(TopLoadingFinishEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingFinish")); - export.put(TopLoadingErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingError")); - export.put(TopMessageEvent.EVENT_NAME, MapBuilder.of("registrationName", "onMessage")); - // !Default events but adding them here explicitly for clarity - - export.put(TopLoadingProgressEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingProgress")); - export.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShouldStartLoadWithRequest")); - export.put(ScrollEventType.getJSEventName(ScrollEventType.SCROLL), MapBuilder.of("registrationName", "onScroll")); - export.put(TopHttpErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onHttpError")); - export.put(TopRenderProcessGoneEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRenderProcessGone")); - return export; - } - - @Override - public @Nullable - Map getCommandsMap() { - return MapBuilder.builder() - .put("goBack", COMMAND_GO_BACK) - .put("goForward", COMMAND_GO_FORWARD) - .put("reload", COMMAND_RELOAD) - .put("stopLoading", COMMAND_STOP_LOADING) - .put("postMessage", COMMAND_POST_MESSAGE) - .put("injectJavaScript", COMMAND_INJECT_JAVASCRIPT) - .put("loadUrl", COMMAND_LOAD_URL) - .put("requestFocus", COMMAND_FOCUS) - .put("clearFormData", COMMAND_CLEAR_FORM_DATA) - .put("clearCache", COMMAND_CLEAR_CACHE) - .put("clearHistory", COMMAND_CLEAR_HISTORY) - .build(); - } - - @Override - public void receiveCommand(@NonNull WebView root, String commandId, @Nullable ReadableArray args) { - switch (commandId) { - case "goBack": - root.goBack(); - break; - case "goForward": - root.goForward(); - break; - case "reload": - root.reload(); - break; - case "stopLoading": - root.stopLoading(); - break; - case "postMessage": - try { - RNCWebView reactWebView = (RNCWebView) root; - JSONObject eventInitDict = new JSONObject(); - eventInitDict.put("data", args.getString(0)); - reactWebView.evaluateJavascriptWithFallback("(function () {" + - "var event;" + - "var data = " + eventInitDict.toString() + ";" + - "try {" + - "event = new MessageEvent('message', data);" + - "} catch (e) {" + - "event = document.createEvent('MessageEvent');" + - "event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" + - "}" + - "document.dispatchEvent(event);" + - "})();"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - break; - case "injectJavaScript": - RNCWebView reactWebView = (RNCWebView) root; - reactWebView.evaluateJavascriptWithFallback(args.getString(0)); - break; - case "loadUrl": - if (args == null) { - throw new RuntimeException("Arguments for loading an url are null!"); - } - ((RNCWebView) root).progressChangedFilter.setWaitingForCommandLoadUrl(false); - root.loadUrl(args.getString(0)); - break; - case "requestFocus": - root.requestFocus(); - break; - case "clearFormData": - root.clearFormData(); - break; - case "clearCache": - boolean includeDiskFiles = args != null && args.getBoolean(0); - root.clearCache(includeDiskFiles); - break; - case "clearHistory": - root.clearHistory(); - break; - } - super.receiveCommand(root, commandId, args); - } - - @Override - public void onDropViewInstance(WebView webView) { - super.onDropViewInstance(webView); - ((ThemedReactContext) webView.getContext()).removeLifecycleEventListener((RNCWebView) webView); - ((RNCWebView) webView).cleanupCallbacksAndDestroy(); - mWebChromeClient = null; - } - - public static RNCWebViewModule getModule(ReactContext reactContext) { - return reactContext.getNativeModule(RNCWebViewModule.class); - } - - protected void setupWebChromeClient(ReactContext reactContext, WebView webView) { - Activity activity = reactContext.getCurrentActivity(); - - if (mAllowsFullscreenVideo && activity != null) { - int initialRequestedOrientation = activity.getRequestedOrientation(); - - mWebChromeClient = new RNCWebChromeClient(reactContext, webView) { - @Override - public Bitmap getDefaultVideoPoster() { - return Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888); - } - - @Override - public void onShowCustomView(View view, CustomViewCallback callback) { - if (mVideoView != null) { - callback.onCustomViewHidden(); - return; - } - - mVideoView = view; - mCustomViewCallback = callback; - - activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - mVideoView.setSystemUiVisibility(FULLSCREEN_SYSTEM_UI_VISIBILITY); - activity.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - ); - } - - mVideoView.setBackgroundColor(Color.BLACK); - - // Since RN's Modals interfere with the View hierarchy - // we will decide which View to hide if the hierarchy - // does not match (i.e., the WebView is within a Modal) - // NOTE: We could use `mWebView.getRootView()` instead of `getRootView()` - // but that breaks the Modal's styles and layout, so we need this to render - // in the main View hierarchy regardless - ViewGroup rootView = getRootView(); - rootView.addView(mVideoView, FULLSCREEN_LAYOUT_PARAMS); - - // Different root views, we are in a Modal - if (rootView.getRootView() != mWebView.getRootView()) { - mWebView.getRootView().setVisibility(View.GONE); - } else { - // Same view hierarchy (no Modal), just hide the WebView then - mWebView.setVisibility(View.GONE); - } - - mReactContext.addLifecycleEventListener(this); - } - - @Override - public void onHideCustomView() { - if (mVideoView == null) { - return; - } - - // Same logic as above - ViewGroup rootView = getRootView(); - - if (rootView.getRootView() != mWebView.getRootView()) { - mWebView.getRootView().setVisibility(View.VISIBLE); - } else { - // Same view hierarchy (no Modal) - mWebView.setVisibility(View.VISIBLE); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - - rootView.removeView(mVideoView); - mCustomViewCallback.onCustomViewHidden(); - - mVideoView = null; - mCustomViewCallback = null; - - activity.setRequestedOrientation(initialRequestedOrientation); - - mReactContext.removeLifecycleEventListener(this); - } - }; - } else { - if (mWebChromeClient != null) { - mWebChromeClient.onHideCustomView(); - } - - mWebChromeClient = new RNCWebChromeClient(reactContext, webView) { - @Override - public Bitmap getDefaultVideoPoster() { - return Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888); - } - }; - } - mWebChromeClient.setAllowsProtectedMedia(mAllowsProtectedMedia); - webView.setWebChromeClient(mWebChromeClient); - } - - protected static class RNCWebViewClient extends WebViewClient { - - protected boolean mLastLoadFailed = false; - protected @Nullable - ReadableArray mUrlPrefixesForDefaultIntent; - protected RNCWebView.ProgressChangedFilter progressChangedFilter = null; - protected @Nullable String ignoreErrFailedForThisURL = null; - protected @Nullable BasicAuthCredential basicAuthCredential = null; - - public void setIgnoreErrFailedForThisURL(@Nullable String url) { - ignoreErrFailedForThisURL = url; - } - - public void setBasicAuthCredential(@Nullable BasicAuthCredential credential) { - basicAuthCredential = credential; - } - - @Override - public void onPageFinished(WebView webView, String url) { - super.onPageFinished(webView, url); - - if (!mLastLoadFailed) { - RNCWebView reactWebView = (RNCWebView) webView; - - reactWebView.callInjectedJavaScript(); - - emitFinishEvent(webView, url); - } - } - - @Override - public void onPageStarted(WebView webView, String url, Bitmap favicon) { - super.onPageStarted(webView, url, favicon); - mLastLoadFailed = false; - - RNCWebView reactWebView = (RNCWebView) webView; - reactWebView.callInjectedJavaScriptBeforeContentLoaded(); - - ((RNCWebView) webView).dispatchEvent( - webView, - new TopLoadingStartEvent( - webView.getId(), - createWebViewEvent(webView, url))); - } - - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - final RNCWebView rncWebView = (RNCWebView) view; - final boolean isJsDebugging = ((ReactContext) view.getContext()).getJavaScriptContextHolder().get() == 0; - - if (!isJsDebugging && rncWebView.mCatalystInstance != null) { - final Pair> lock = RNCWebViewModule.shouldOverrideUrlLoadingLock.getNewLock(); - final int lockIdentifier = lock.first; - final AtomicReference lockObject = lock.second; - - final WritableMap event = createWebViewEvent(view, url); - event.putInt("lockIdentifier", lockIdentifier); - rncWebView.sendDirectMessage("onShouldStartLoadWithRequest", event); - - try { - assert lockObject != null; - synchronized (lockObject) { - final long startTime = SystemClock.elapsedRealtime(); - while (lockObject.get() == ShouldOverrideCallbackState.UNDECIDED) { - if (SystemClock.elapsedRealtime() - startTime > SHOULD_OVERRIDE_URL_LOADING_TIMEOUT) { - FLog.w(TAG, "Did not receive response to shouldOverrideUrlLoading in time, defaulting to allow loading."); - RNCWebViewModule.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier); - return false; - } - lockObject.wait(SHOULD_OVERRIDE_URL_LOADING_TIMEOUT); - } - } - } catch (InterruptedException e) { - FLog.e(TAG, "shouldOverrideUrlLoading was interrupted while waiting for result.", e); - RNCWebViewModule.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier); - return false; - } - - final boolean shouldOverride = lockObject.get() == ShouldOverrideCallbackState.SHOULD_OVERRIDE; - RNCWebViewModule.shouldOverrideUrlLoadingLock.removeLock(lockIdentifier); - - return shouldOverride; - } else { - FLog.w(TAG, "Couldn't use blocking synchronous call for onShouldStartLoadWithRequest due to debugging or missing Catalyst instance, falling back to old event-and-load."); - progressChangedFilter.setWaitingForCommandLoadUrl(true); - ((RNCWebView) view).dispatchEvent( - view, - new TopShouldStartLoadWithRequestEvent( - view.getId(), - createWebViewEvent(view, url))); - return true; - } - } - - @TargetApi(Build.VERSION_CODES.N) - @Override - public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - final String url = request.getUrl().toString(); - return this.shouldOverrideUrlLoading(view, url); - } - - @Override - public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { - if (basicAuthCredential != null) { - handler.proceed(basicAuthCredential.username, basicAuthCredential.password); - return; - } - super.onReceivedHttpAuthRequest(view, handler, host, realm); - } - - @Override - public void onReceivedSslError(final WebView webView, final SslErrorHandler handler, final SslError error) { - // onReceivedSslError is called for most requests, per Android docs: https://developer.android.com/reference/android/webkit/WebViewClient#onReceivedSslError(android.webkit.WebView,%2520android.webkit.SslErrorHandler,%2520android.net.http.SslError) - // WebView.getUrl() will return the top-level window URL. - // If a top-level navigation triggers this error handler, the top-level URL will be the failing URL (not the URL of the currently-rendered page). - // This is desired behavior. We later use these values to determine whether the request is a top-level navigation or a subresource request. - String topWindowUrl = webView.getUrl(); - String failingUrl = error.getUrl(); - - // Cancel request after obtaining top-level URL. - // If request is cancelled before obtaining top-level URL, undesired behavior may occur. - // Undesired behavior: Return value of WebView.getUrl() may be the current URL instead of the failing URL. - handler.cancel(); - - if (!topWindowUrl.equalsIgnoreCase(failingUrl)) { - // If error is not due to top-level navigation, then do not call onReceivedError() - Log.w(TAG, "Resource blocked from loading due to SSL error. Blocked URL: "+failingUrl); - return; - } - - int code = error.getPrimaryError(); - String description = ""; - String descriptionPrefix = "SSL error: "; - - // https://developer.android.com/reference/android/net/http/SslError.html - switch (code) { - case SslError.SSL_DATE_INVALID: - description = "The date of the certificate is invalid"; - break; - case SslError.SSL_EXPIRED: - description = "The certificate has expired"; - break; - case SslError.SSL_IDMISMATCH: - description = "Hostname mismatch"; - break; - case SslError.SSL_INVALID: - description = "A generic error occurred"; - break; - case SslError.SSL_NOTYETVALID: - description = "The certificate is not yet valid"; - break; - case SslError.SSL_UNTRUSTED: - description = "The certificate authority is not trusted"; - break; - default: - description = "Unknown SSL Error"; - break; - } - - description = descriptionPrefix + description; - - this.onReceivedError( - webView, - code, - description, - failingUrl - ); - } - - @Override - public void onReceivedError( - WebView webView, - int errorCode, - String description, - String failingUrl) { - - if (ignoreErrFailedForThisURL != null - && failingUrl.equals(ignoreErrFailedForThisURL) - && errorCode == -1 - && description.equals("net::ERR_FAILED")) { - - // This is a workaround for a bug in the WebView. - // See these chromium issues for more context: - // https://bugs.chromium.org/p/chromium/issues/detail?id=1023678 - // https://bugs.chromium.org/p/chromium/issues/detail?id=1050635 - // This entire commit should be reverted once this bug is resolved in chromium. - setIgnoreErrFailedForThisURL(null); - return; - } - - super.onReceivedError(webView, errorCode, description, failingUrl); - mLastLoadFailed = true; - - // In case of an error JS side expect to get a finish event first, and then get an error event - // Android WebView does it in the opposite way, so we need to simulate that behavior - emitFinishEvent(webView, failingUrl); - - WritableMap eventData = createWebViewEvent(webView, failingUrl); - eventData.putDouble("code", errorCode); - eventData.putString("description", description); - - ((RNCWebView) webView).dispatchEvent( - webView, - new TopLoadingErrorEvent(webView.getId(), eventData)); - } - - @RequiresApi(api = Build.VERSION_CODES.M) - @Override - public void onReceivedHttpError( - WebView webView, - WebResourceRequest request, - WebResourceResponse errorResponse) { - super.onReceivedHttpError(webView, request, errorResponse); - - if (request.isForMainFrame()) { - WritableMap eventData = createWebViewEvent(webView, request.getUrl().toString()); - eventData.putInt("statusCode", errorResponse.getStatusCode()); - eventData.putString("description", errorResponse.getReasonPhrase()); - - ((RNCWebView) webView).dispatchEvent( - webView, - new TopHttpErrorEvent(webView.getId(), eventData)); - } - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public boolean onRenderProcessGone(WebView webView, RenderProcessGoneDetail detail) { - // WebViewClient.onRenderProcessGone was added in O. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - return false; - } - super.onRenderProcessGone(webView, detail); - - if(detail.didCrash()){ - Log.e(TAG, "The WebView rendering process crashed."); - } - else{ - Log.w(TAG, "The WebView rendering process was killed by the system."); - } - - // if webView is null, we cannot return any event - // since the view is already dead/disposed - // still prevent the app crash by returning true. - if(webView == null){ - return true; - } - - WritableMap event = createWebViewEvent(webView, webView.getUrl()); - event.putBoolean("didCrash", detail.didCrash()); - - ((RNCWebView) webView).dispatchEvent( - webView, - new TopRenderProcessGoneEvent(webView.getId(), event) - ); - - // returning false would crash the app. - return true; - } - - protected void emitFinishEvent(WebView webView, String url) { - ((RNCWebView) webView).dispatchEvent( - webView, - new TopLoadingFinishEvent( - webView.getId(), - createWebViewEvent(webView, url))); - } - - protected WritableMap createWebViewEvent(WebView webView, String url) { - WritableMap event = Arguments.createMap(); - event.putDouble("target", webView.getId()); - // Don't use webView.getUrl() here, the URL isn't updated to the new value yet in callbacks - // like onPageFinished - event.putString("url", url); - event.putBoolean("loading", !mLastLoadFailed && webView.getProgress() != 100); - event.putString("title", webView.getTitle()); - event.putBoolean("canGoBack", webView.canGoBack()); - event.putBoolean("canGoForward", webView.canGoForward()); - return event; - } - - public void setUrlPrefixesForDefaultIntent(ReadableArray specialUrls) { - mUrlPrefixesForDefaultIntent = specialUrls; - } - - public void setProgressChangedFilter(RNCWebView.ProgressChangedFilter filter) { - progressChangedFilter = filter; - } - } - - protected static class RNCWebChromeClient extends WebChromeClient implements LifecycleEventListener { - protected static final FrameLayout.LayoutParams FULLSCREEN_LAYOUT_PARAMS = new FrameLayout.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.CENTER); - - @RequiresApi(api = Build.VERSION_CODES.KITKAT) - protected static final int FULLSCREEN_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | - View.SYSTEM_UI_FLAG_FULLSCREEN | - View.SYSTEM_UI_FLAG_IMMERSIVE | - View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; - - protected static final int COMMON_PERMISSION_REQUEST = 3; - - protected ReactContext mReactContext; - protected View mWebView; - - protected View mVideoView; - protected WebChromeClient.CustomViewCallback mCustomViewCallback; - - /* - * - Permissions - - * As native permissions are asynchronously handled by the PermissionListener, many fields have - * to be stored to send permissions results to the webview - */ - - // Webview camera & audio permission callback - protected PermissionRequest permissionRequest; - // Webview camera & audio permission already granted - protected List grantedPermissions; - - // Webview geolocation permission callback - protected GeolocationPermissions.Callback geolocationPermissionCallback; - // Webview geolocation permission origin callback - protected String geolocationPermissionOrigin; - - // true if native permissions dialog is shown, false otherwise - protected boolean permissionsRequestShown = false; - // Pending Android permissions for the next request - protected List pendingPermissions = new ArrayList<>(); - - protected RNCWebView.ProgressChangedFilter progressChangedFilter = null; - - // True if protected media should be allowed, false otherwise - protected boolean mAllowsProtectedMedia = false; - - public RNCWebChromeClient(ReactContext reactContext, WebView webView) { - this.mReactContext = reactContext; - this.mWebView = webView; - } - - @Override - public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { - - final WebView newWebView = new WebView(view.getContext()); - final WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; - transport.setWebView(newWebView); - resultMsg.sendToTarget(); - - return true; - } - - @Override - public boolean onConsoleMessage(ConsoleMessage message) { - if (ReactBuildConfig.DEBUG) { - return super.onConsoleMessage(message); - } - // Ignore console logs in non debug builds. - return true; - } - - @Override - public void onProgressChanged(WebView webView, int newProgress) { - super.onProgressChanged(webView, newProgress); - final String url = webView.getUrl(); - if (progressChangedFilter.isWaitingForCommandLoadUrl()) { - return; - } - WritableMap event = Arguments.createMap(); - event.putDouble("target", webView.getId()); - event.putString("title", webView.getTitle()); - event.putString("url", url); - event.putBoolean("canGoBack", webView.canGoBack()); - event.putBoolean("canGoForward", webView.canGoForward()); - event.putDouble("progress", (float) newProgress / 100); - ((RNCWebView) webView).dispatchEvent( - webView, - new TopLoadingProgressEvent( - webView.getId(), - event)); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public void onPermissionRequest(final PermissionRequest request) { - - grantedPermissions = new ArrayList<>(); - - ArrayList requestedAndroidPermissions = new ArrayList<>(); - for (String requestedResource : request.getResources()) { - String androidPermission = null; - - if (requestedResource.equals(PermissionRequest.RESOURCE_AUDIO_CAPTURE)) { - androidPermission = Manifest.permission.RECORD_AUDIO; - } else if (requestedResource.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) { - androidPermission = Manifest.permission.CAMERA; - } else if(requestedResource.equals(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID)) { - if (mAllowsProtectedMedia) { - grantedPermissions.add(requestedResource); - } else { - /** - * Legacy handling (Kept in case it was working under some conditions (given Android version or something)) - * - * Try to ask user to grant permission using Activity.requestPermissions - * - * Find more details here: https://github.com/react-native-webview/react-native-webview/pull/2732 - */ - androidPermission = PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID; - } - } - // TODO: RESOURCE_MIDI_SYSEX. - - if (androidPermission != null) { - if (ContextCompat.checkSelfPermission(mReactContext, androidPermission) == PackageManager.PERMISSION_GRANTED) { - grantedPermissions.add(requestedResource); - } else { - requestedAndroidPermissions.add(androidPermission); - } - } - } - - // If all the permissions are already granted, send the response to the WebView synchronously - if (requestedAndroidPermissions.isEmpty()) { - request.grant(grantedPermissions.toArray(new String[0])); - grantedPermissions = null; - return; - } - - // Otherwise, ask to Android System for native permissions asynchronously - - this.permissionRequest = request; - - requestPermissions(requestedAndroidPermissions); - } - - - @Override - public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) { - - if (ContextCompat.checkSelfPermission(mReactContext, Manifest.permission.ACCESS_FINE_LOCATION) - != PackageManager.PERMISSION_GRANTED) { - - /* - * Keep the trace of callback and origin for the async permission request - */ - geolocationPermissionCallback = callback; - geolocationPermissionOrigin = origin; - - requestPermissions(Collections.singletonList(Manifest.permission.ACCESS_FINE_LOCATION)); - - } else { - callback.invoke(origin, true, false); - } - } - - private PermissionAwareActivity getPermissionAwareActivity() { - Activity activity = mReactContext.getCurrentActivity(); - if (activity == null) { - throw new IllegalStateException("Tried to use permissions API while not attached to an Activity."); - } else if (!(activity instanceof PermissionAwareActivity)) { - throw new IllegalStateException("Tried to use permissions API but the host Activity doesn't implement PermissionAwareActivity."); - } - return (PermissionAwareActivity) activity; - } - - private synchronized void requestPermissions(List permissions) { - - /* - * If permissions request dialog is displayed on the screen and another request is sent to the - * activity, the last permission asked is skipped. As a work-around, we use pendingPermissions - * to store next required permissions. - */ - - if (permissionsRequestShown) { - pendingPermissions.addAll(permissions); - return; - } - - PermissionAwareActivity activity = getPermissionAwareActivity(); - permissionsRequestShown = true; - - activity.requestPermissions( - permissions.toArray(new String[0]), - COMMON_PERMISSION_REQUEST, - webviewPermissionsListener - ); - - // Pending permissions have been sent, the list can be cleared - pendingPermissions.clear(); - } - - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - private PermissionListener webviewPermissionsListener = (requestCode, permissions, grantResults) -> { - - permissionsRequestShown = false; - - /* - * As a "pending requests" approach is used, requestCode cannot help to define if the request - * came from geolocation or camera/audio. This is why shouldAnswerToPermissionRequest is used - */ - boolean shouldAnswerToPermissionRequest = false; - - for (int i = 0; i < permissions.length; i++) { - - String permission = permissions[i]; - boolean granted = grantResults[i] == PackageManager.PERMISSION_GRANTED; - - if (permission.equals(Manifest.permission.ACCESS_FINE_LOCATION) - && geolocationPermissionCallback != null - && geolocationPermissionOrigin != null) { - - if (granted) { - geolocationPermissionCallback.invoke(geolocationPermissionOrigin, true, false); - } else { - geolocationPermissionCallback.invoke(geolocationPermissionOrigin, false, false); - } - - geolocationPermissionCallback = null; - geolocationPermissionOrigin = null; - } - - if (permission.equals(Manifest.permission.RECORD_AUDIO)) { - if (granted && grantedPermissions != null) { - grantedPermissions.add(PermissionRequest.RESOURCE_AUDIO_CAPTURE); - } - shouldAnswerToPermissionRequest = true; - } - - if (permission.equals(Manifest.permission.CAMERA)) { - if (granted && grantedPermissions != null) { - grantedPermissions.add(PermissionRequest.RESOURCE_VIDEO_CAPTURE); - } - shouldAnswerToPermissionRequest = true; - } - - if (permission.equals(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID)) { - if (granted && grantedPermissions != null) { - grantedPermissions.add(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID); - } - shouldAnswerToPermissionRequest = true; - } - } - - if (shouldAnswerToPermissionRequest - && permissionRequest != null - && grantedPermissions != null) { - permissionRequest.grant(grantedPermissions.toArray(new String[0])); - permissionRequest = null; - grantedPermissions = null; - } - - if (!pendingPermissions.isEmpty()) { - requestPermissions(pendingPermissions); - return false; - } - - return true; - }; - - protected void openFileChooser(ValueCallback filePathCallback, String acceptType) { - getModule(mReactContext).startPhotoPickerIntent(filePathCallback, acceptType); - } - - protected void openFileChooser(ValueCallback filePathCallback) { - getModule(mReactContext).startPhotoPickerIntent(filePathCallback, ""); - } - - protected void openFileChooser(ValueCallback filePathCallback, String acceptType, String capture) { - getModule(mReactContext).startPhotoPickerIntent(filePathCallback, acceptType); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { - String[] acceptTypes = fileChooserParams.getAcceptTypes(); - boolean allowMultiple = fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE; - return getModule(mReactContext).startPhotoPickerIntent(filePathCallback, acceptTypes, allowMultiple); - } - - @Override - public void onHostResume() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mVideoView != null && mVideoView.getSystemUiVisibility() != FULLSCREEN_SYSTEM_UI_VISIBILITY) { - mVideoView.setSystemUiVisibility(FULLSCREEN_SYSTEM_UI_VISIBILITY); - } - } - - @Override - public void onHostPause() { } - - @Override - public void onHostDestroy() { } - - protected ViewGroup getRootView() { - return (ViewGroup) mReactContext.getCurrentActivity().findViewById(android.R.id.content); - } - - public void setProgressChangedFilter(RNCWebView.ProgressChangedFilter filter) { - progressChangedFilter = filter; - } - - /** - * Set whether or not protected media should be allowed - * /!\ Setting this to false won't revoke permission already granted to the current webpage. - * In order to do so, you'd need to reload the page /!\ - */ - public void setAllowsProtectedMedia(boolean enabled) { - mAllowsProtectedMedia = enabled; - } - } - - /** - * Subclass of {@link WebView} that implements {@link LifecycleEventListener} interface in order - * to call {@link WebView#destroy} on activity destroy event and also to clear the client - */ - protected static class RNCWebView extends WebView implements LifecycleEventListener { - protected @Nullable - String injectedJS; - protected @Nullable - String injectedJSBeforeContentLoaded; - - /** - * android.webkit.WebChromeClient fundamentally does not support JS injection into frames other - * than the main frame, so these two properties are mostly here just for parity with iOS & macOS. - */ - protected boolean injectedJavaScriptForMainFrameOnly = true; - protected boolean injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true; - - protected boolean messagingEnabled = false; - protected @Nullable - String messagingModuleName; - protected @Nullable - RNCWebViewClient mRNCWebViewClient; - protected @Nullable - CatalystInstance mCatalystInstance; - protected boolean sendContentSizeChangeEvents = false; - private OnScrollDispatchHelper mOnScrollDispatchHelper; - protected boolean hasScrollEvent = false; - protected boolean nestedScrollEnabled = false; - protected ProgressChangedFilter progressChangedFilter; - - /** - * WebView must be created with an context of the current activity - *

- * Activity Context is required for creation of dialogs internally by WebView - * Reactive Native needed for access to ReactNative internal system functionality - */ - public RNCWebView(ThemedReactContext reactContext) { - super(reactContext); - this.createCatalystInstance(); - progressChangedFilter = new ProgressChangedFilter(); - } - - public void setIgnoreErrFailedForThisURL(String url) { - mRNCWebViewClient.setIgnoreErrFailedForThisURL(url); - } - - public void setBasicAuthCredential(BasicAuthCredential credential) { - mRNCWebViewClient.setBasicAuthCredential(credential); - } - - public void setSendContentSizeChangeEvents(boolean sendContentSizeChangeEvents) { - this.sendContentSizeChangeEvents = sendContentSizeChangeEvents; - } - - public void setHasScrollEvent(boolean hasScrollEvent) { - this.hasScrollEvent = hasScrollEvent; - } - - public void setNestedScrollEnabled(boolean nestedScrollEnabled) { - this.nestedScrollEnabled = nestedScrollEnabled; - } - - @Override - public void onHostResume() { - // do nothing - } - - @Override - public void onHostPause() { - // do nothing - } - - @Override - public void onHostDestroy() { - cleanupCallbacksAndDestroy(); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if (this.nestedScrollEnabled) { - requestDisallowInterceptTouchEvent(true); - } - return super.onTouchEvent(event); - } - - @Override - protected void onSizeChanged(int w, int h, int ow, int oh) { - super.onSizeChanged(w, h, ow, oh); - - if (sendContentSizeChangeEvents) { - dispatchEvent( - this, - new ContentSizeChangeEvent( - this.getId(), - w, - h - ) - ); - } - } - - @Override - public void setWebViewClient(WebViewClient client) { - super.setWebViewClient(client); - if (client instanceof RNCWebViewClient) { - mRNCWebViewClient = (RNCWebViewClient) client; - mRNCWebViewClient.setProgressChangedFilter(progressChangedFilter); - } - } - - WebChromeClient mWebChromeClient; - @Override - public void setWebChromeClient(WebChromeClient client) { - this.mWebChromeClient = client; - super.setWebChromeClient(client); - if (client instanceof RNCWebChromeClient) { - ((RNCWebChromeClient) client).setProgressChangedFilter(progressChangedFilter); - } - } - - public @Nullable - RNCWebViewClient getRNCWebViewClient() { - return mRNCWebViewClient; - } - - public void setInjectedJavaScript(@Nullable String js) { - injectedJS = js; - } - - public void setInjectedJavaScriptBeforeContentLoaded(@Nullable String js) { - injectedJSBeforeContentLoaded = js; - } - - public void setInjectedJavaScriptForMainFrameOnly(boolean enabled) { - injectedJavaScriptForMainFrameOnly = enabled; - } - - public void setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(boolean enabled) { - injectedJavaScriptBeforeContentLoadedForMainFrameOnly = enabled; - } - - protected RNCWebViewBridge createRNCWebViewBridge(RNCWebView webView) { - return new RNCWebViewBridge(webView); - } - - protected void createCatalystInstance() { - ReactContext reactContext = (ReactContext) this.getContext(); - - if (reactContext != null) { - mCatalystInstance = reactContext.getCatalystInstance(); - } - } - - @SuppressLint("AddJavascriptInterface") - public void setMessagingEnabled(boolean enabled) { - if (messagingEnabled == enabled) { - return; - } - - messagingEnabled = enabled; - - if (enabled) { - addJavascriptInterface(createRNCWebViewBridge(this), JAVASCRIPT_INTERFACE); - } else { - removeJavascriptInterface(JAVASCRIPT_INTERFACE); - } - } - - public void setMessagingModuleName(String moduleName) { - messagingModuleName = moduleName; - } - - protected void evaluateJavascriptWithFallback(String script) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - evaluateJavascript(script, null); - return; - } - - try { - loadUrl("javascript:" + URLEncoder.encode(script, "UTF-8")); - } catch (UnsupportedEncodingException e) { - // UTF-8 should always be supported - throw new RuntimeException(e); - } - } - - public void callInjectedJavaScript() { - if (getSettings().getJavaScriptEnabled() && - injectedJS != null && - !TextUtils.isEmpty(injectedJS)) { - evaluateJavascriptWithFallback("(function() {\n" + injectedJS + ";\n})();"); - } - } - - public void callInjectedJavaScriptBeforeContentLoaded() { - if (getSettings().getJavaScriptEnabled() && - injectedJSBeforeContentLoaded != null && - !TextUtils.isEmpty(injectedJSBeforeContentLoaded)) { - evaluateJavascriptWithFallback("(function() {\n" + injectedJSBeforeContentLoaded + ";\n})();"); - } - } - - public void onMessage(String message) { - ReactContext reactContext = (ReactContext) this.getContext(); - RNCWebView mContext = this; - - if (mRNCWebViewClient != null) { - WebView webView = this; - webView.post(new Runnable() { - @Override - public void run() { - if (mRNCWebViewClient == null) { - return; - } - WritableMap data = mRNCWebViewClient.createWebViewEvent(webView, webView.getUrl()); - data.putString("data", message); - - if (mCatalystInstance != null) { - mContext.sendDirectMessage("onMessage", data); - } else { - dispatchEvent(webView, new TopMessageEvent(webView.getId(), data)); - } - } - }); - } else { - WritableMap eventData = Arguments.createMap(); - eventData.putString("data", message); - - if (mCatalystInstance != null) { - this.sendDirectMessage("onMessage", eventData); - } else { - dispatchEvent(this, new TopMessageEvent(this.getId(), eventData)); - } - } - } - - protected void sendDirectMessage(final String method, WritableMap data) { - WritableNativeMap event = new WritableNativeMap(); - event.putMap("nativeEvent", data); - - WritableNativeArray params = new WritableNativeArray(); - params.pushMap(event); - - mCatalystInstance.callFunction(messagingModuleName, method, params); - } - - protected void onScrollChanged(int x, int y, int oldX, int oldY) { - super.onScrollChanged(x, y, oldX, oldY); - - if (!hasScrollEvent) { - return; - } - - if (mOnScrollDispatchHelper == null) { - mOnScrollDispatchHelper = new OnScrollDispatchHelper(); - } - - if (mOnScrollDispatchHelper.onScrollChanged(x, y)) { - ScrollEvent event = ScrollEvent.obtain( - this.getId(), - ScrollEventType.SCROLL, - x, - y, - mOnScrollDispatchHelper.getXFlingVelocity(), - mOnScrollDispatchHelper.getYFlingVelocity(), - this.computeHorizontalScrollRange(), - this.computeVerticalScrollRange(), - this.getWidth(), - this.getHeight()); - - dispatchEvent(this, event); - } - } - - protected void dispatchEvent(WebView webView, Event event) { - ReactContext reactContext = (ReactContext) webView.getContext(); - EventDispatcher eventDispatcher = - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); - eventDispatcher.dispatchEvent(event); - } - - protected void cleanupCallbacksAndDestroy() { - setWebViewClient(null); - destroy(); - } - - @Override - public void destroy() { - if (mWebChromeClient != null) { - mWebChromeClient.onHideCustomView(); - } - super.destroy(); - } - - protected class RNCWebViewBridge { - RNCWebView mContext; - - RNCWebViewBridge(RNCWebView c) { - mContext = c; - } - - /** - * This method is called whenever JavaScript running within the web view calls: - * - window[JAVASCRIPT_INTERFACE].postMessage - */ - @JavascriptInterface - public void postMessage(String message) { - mContext.onMessage(message); - } - } - - protected static class ProgressChangedFilter { - private boolean waitingForCommandLoadUrl = false; - - public void setWaitingForCommandLoadUrl(boolean isWaiting) { - waitingForCommandLoadUrl = isWaiting; - } - - public boolean isWaitingForCommandLoadUrl() { - return waitingForCommandLoadUrl; - } - } - } -} - -class BasicAuthCredential { - String username; - String password; - - BasicAuthCredential(String username, String password) { - this.username = username; - this.password = password; - } -} diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt new file mode 100644 index 0000000..25f9c54 --- /dev/null +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt @@ -0,0 +1,639 @@ +package com.reactnativecommunity.webview + +import android.app.DownloadManager +import android.content.pm.ActivityInfo +import android.graphics.Bitmap +import android.graphics.Color +import android.net.Uri +import android.os.Build +import android.os.Environment +import android.util.Log +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.webkit.CookieManager +import android.webkit.DownloadListener +import android.webkit.WebSettings +import android.webkit.WebView +import androidx.webkit.WebSettingsCompat +import androidx.webkit.WebViewFeature +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.ReadableMap +import com.facebook.react.common.MapBuilder +import com.facebook.react.common.build.ReactBuildConfig +import com.facebook.react.uimanager.ThemedReactContext +import org.json.JSONException +import org.json.JSONObject +import java.io.UnsupportedEncodingException +import java.net.MalformedURLException +import java.net.URL +import java.util.* + + +class RNCWebViewManagerImpl { + companion object { + const val NAME = "RNCWebView" + } + + private val TAG = "RNCWebViewManagerImpl" + private var mWebViewConfig: RNCWebViewConfig = RNCWebViewConfig { webView: WebView? -> } + private var mAllowsFullscreenVideo = false + private var mAllowsProtectedMedia = false + private var mDownloadingMessage: String? = null + private var mLackPermissionToDownloadMessage: String? = null + + private var mUserAgent: String? = null + private var mUserAgentWithApplicationName: String? = null + private val HTML_ENCODING = "UTF-8" + private val HTML_MIME_TYPE = "text/html" + private val HTTP_METHOD_POST = "POST" + + // Use `webView.loadUrl("about:blank")` to reliably reset the view + // state and release page resources (including any running JavaScript). + private val BLANK_URL = "about:blank" + + private val DEFAULT_DOWNLOADING_MESSAGE = "Downloading" + private val DEFAULT_LACK_PERMISSION_TO_DOWNLOAD_MESSAGE = + "Cannot download files as permission was denied. Please provide permission to write to storage, in order to download files." + + fun createRNCWebViewInstance(context: ThemedReactContext): RNCWebView { + return RNCWebView(context) + } + + fun createViewInstance(context: ThemedReactContext): RNCWebView { + val webView = createRNCWebViewInstance(context) + return createViewInstance(context, webView); + } + + fun createViewInstance(context: ThemedReactContext, webView: RNCWebView): RNCWebView { + setupWebChromeClient(webView) + context.addLifecycleEventListener(webView) + mWebViewConfig.configWebView(webView) + val settings = webView.settings + settings.builtInZoomControls = true + settings.displayZoomControls = false + settings.domStorageEnabled = true + settings.setSupportMultipleWindows(true) + settings.allowFileAccess = false + settings.allowContentAccess = false + settings.allowFileAccessFromFileURLs = false + setAllowUniversalAccessFromFileURLs(webView, false) + setMixedContentMode(webView, "never") + + // Fixes broken full-screen modals/galleries due to body height being 0. + webView.layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + if (ReactBuildConfig.DEBUG) { + WebView.setWebContentsDebuggingEnabled(true) + } + webView.setDownloadListener(DownloadListener { url, userAgent, contentDisposition, mimetype, contentLength -> + webView.setIgnoreErrFailedForThisURL(url) + val module = webView.themedReactContext.getNativeModule(RNCWebViewModule::class.java) ?: return@DownloadListener + val request: DownloadManager.Request = try { + DownloadManager.Request(Uri.parse(url)) + } catch (e: IllegalArgumentException) { + Log.w(TAG, "Unsupported URI, aborting download", e) + return@DownloadListener + } + val fileName = URLUtil.guessFileName(url, contentDisposition, mimetype) + val downloadMessage = "Downloading $fileName" + + //Attempt to add cookie, if it exists + var urlObj: URL? = null + try { + urlObj = URL(url) + val baseUrl = urlObj.protocol + "://" + urlObj.host + val cookie = CookieManager.getInstance().getCookie(baseUrl) + request.addRequestHeader("Cookie", cookie) + } catch (e: MalformedURLException) { + Log.w(TAG, "Error getting cookie for DownloadManager", e) + } + + //Finish setting up request + request.addRequestHeader("User-Agent", userAgent) + request.setTitle(fileName) + request.setDescription(downloadMessage) + request.allowScanningByMediaScanner() + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName) + module.setDownloadRequest(request) + if (module.grantFileDownloaderPermissions( + getDownloadingMessageOrDefault(), + getLackPermissionToDownloadMessageOrDefault() + ) + ) { + module.downloadFile( + getDownloadingMessageOrDefault() + ) + } + }) + return webView + } + + private fun setupWebChromeClient( + webView: RNCWebView, + ) { + val activity = webView.themedReactContext.currentActivity + if (mAllowsFullscreenVideo && activity != null) { + val initialRequestedOrientation = activity.requestedOrientation + val webChromeClient: RNCWebChromeClient = + object : RNCWebChromeClient(webView) { + override fun getDefaultVideoPoster(): Bitmap? { + return Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888) + } + + override fun onShowCustomView(view: View, callback: CustomViewCallback) { + if (mVideoView != null) { + callback.onCustomViewHidden() + return + } + mVideoView = view + mCustomViewCallback = callback + activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED + mVideoView.systemUiVisibility = FULLSCREEN_SYSTEM_UI_VISIBILITY + activity.window.setFlags( + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + ) + mVideoView.setBackgroundColor(Color.BLACK) + + // Since RN's Modals interfere with the View hierarchy + // we will decide which View to hide if the hierarchy + // does not match (i.e., the WebView is within a Modal) + // NOTE: We could use `mWebView.getRootView()` instead of `getRootView()` + // but that breaks the Modal's styles and layout, so we need this to render + // in the main View hierarchy regardless + val rootView = rootView + rootView.addView(mVideoView, FULLSCREEN_LAYOUT_PARAMS) + + // Different root views, we are in a Modal + if (rootView.rootView !== mWebView.rootView) { + mWebView.rootView.visibility = View.GONE + } else { + // Same view hierarchy (no Modal), just hide the WebView then + mWebView.visibility = View.GONE + } + mWebView.themedReactContext.addLifecycleEventListener(this) + } + + override fun onHideCustomView() { + if (mVideoView == null) { + return + } + + // Same logic as above + val rootView = rootView + if (rootView.rootView !== mWebView.rootView) { + mWebView.rootView.visibility = View.VISIBLE + } else { + // Same view hierarchy (no Modal) + mWebView.visibility = View.VISIBLE + } + activity.window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) + rootView.removeView(mVideoView) + mCustomViewCallback.onCustomViewHidden() + mVideoView = null + mCustomViewCallback = null + activity.requestedOrientation = initialRequestedOrientation + mWebView.themedReactContext.removeLifecycleEventListener(this) + } + } + webChromeClient.setAllowsProtectedMedia(mAllowsProtectedMedia); + webView.webChromeClient = webChromeClient + } else { + var webChromeClient = webView.webChromeClient as RNCWebChromeClient? + webChromeClient?.onHideCustomView() + webChromeClient = object : RNCWebChromeClient(webView) { + override fun getDefaultVideoPoster(): Bitmap? { + return Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888) + } + } + webChromeClient.setAllowsProtectedMedia(mAllowsProtectedMedia); + webView.webChromeClient = webChromeClient + } + } + + fun setUserAgent(view: WebView, userAgent: String?) { + mUserAgent = userAgent + setUserAgentString(view) + } + + fun setApplicationNameForUserAgent(view: WebView, applicationName: String?) { + when { + applicationName != null -> { + val defaultUserAgent = WebSettings.getDefaultUserAgent(view.context) + mUserAgentWithApplicationName = "$defaultUserAgent $applicationName" + } + else -> { + mUserAgentWithApplicationName = null + } + } + setUserAgentString(view) + } + + private fun setUserAgentString(view: WebView) { + when { + mUserAgent != null -> { + view.settings.userAgentString = mUserAgent + } + mUserAgentWithApplicationName != null -> { + view.settings.userAgentString = mUserAgentWithApplicationName + } + else -> { + view.settings.userAgentString = WebSettings.getDefaultUserAgent(view.context) + } + } + } + + fun setBasicAuthCredential(view: WebView, credential: ReadableMap?) { + var basicAuthCredential: RNCBasicAuthCredential? = null + if (credential != null) { + if (credential.hasKey("username") && credential.hasKey("password")) { + val username = credential.getString("username") + val password = credential.getString("password") + basicAuthCredential = RNCBasicAuthCredential(username, password) + } + } + (view as RNCWebView).setBasicAuthCredential(basicAuthCredential) + } + + fun onDropViewInstance(webView: RNCWebView) { + webView.themedReactContext.removeLifecycleEventListener(webView) + webView.cleanupCallbacksAndDestroy() + webView.mWebChromeClient = null + } + + val COMMAND_GO_BACK = 1 + val COMMAND_GO_FORWARD = 2 + val COMMAND_RELOAD = 3 + val COMMAND_STOP_LOADING = 4 + val COMMAND_POST_MESSAGE = 5 + val COMMAND_INJECT_JAVASCRIPT = 6 + val COMMAND_LOAD_URL = 7 + val COMMAND_FOCUS = 8 + + // android commands + val COMMAND_CLEAR_FORM_DATA = 1000 + val COMMAND_CLEAR_CACHE = 1001 + val COMMAND_CLEAR_HISTORY = 1002 + + fun getCommandsMap(): Map? { + return MapBuilder.builder() + .put("goBack", COMMAND_GO_BACK) + .put("goForward", COMMAND_GO_FORWARD) + .put("reload", COMMAND_RELOAD) + .put("stopLoading", COMMAND_STOP_LOADING) + .put("postMessage", COMMAND_POST_MESSAGE) + .put("injectJavaScript", COMMAND_INJECT_JAVASCRIPT) + .put("loadUrl", COMMAND_LOAD_URL) + .put("requestFocus", COMMAND_FOCUS) + .put("clearFormData", COMMAND_CLEAR_FORM_DATA) + .put("clearCache", COMMAND_CLEAR_CACHE) + .put("clearHistory", COMMAND_CLEAR_HISTORY) + .build() + } + + fun receiveCommand(webView: RNCWebView, commandId: String, args: ReadableArray) { + when (commandId) { + "goBack" -> webView.goBack() + "goForward" -> webView.goForward() + "reload" -> webView.reload() + "stopLoading" -> webView.stopLoading() + "postMessage" -> try { + val eventInitDict = JSONObject() + eventInitDict.put("data", args.getString(0)) + webView.evaluateJavascriptWithFallback( + "(function () {" + + "var event;" + + "var data = " + eventInitDict.toString() + ";" + + "try {" + + "event = new MessageEvent('message', data);" + + "} catch (e) {" + + "event = document.createEvent('MessageEvent');" + + "event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" + + "}" + + "document.dispatchEvent(event);" + + "})();" + ) + } catch (e: JSONException) { + throw RuntimeException(e) + } + "injectJavaScript" -> webView.evaluateJavascriptWithFallback(args.getString(0)) + "loadUrl" -> { + if (args == null) { + throw RuntimeException("Arguments for loading an url are null!") + } + webView.progressChangedFilter.setWaitingForCommandLoadUrl(false) + webView.loadUrl(args.getString(0)) + } + "requestFocus" -> webView.requestFocus() + "clearFormData" -> webView.clearFormData() + "clearCache" -> { + val includeDiskFiles = args != null && args.getBoolean(0) + webView.clearCache(includeDiskFiles) + } + "clearHistory" -> webView.clearHistory() + } + } + + fun setMixedContentMode(view: WebView, mixedContentMode: String?) { + if (mixedContentMode == null || "never" == mixedContentMode) { + view.settings.mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW + } else if ("always" == mixedContentMode) { + view.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW + } else if ("compatibility" == mixedContentMode) { + view.settings.mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE + } + } + + fun setAllowUniversalAccessFromFileURLs(view: WebView, allow: Boolean) { + view.settings.allowUniversalAccessFromFileURLs = allow + } + + private fun getDownloadingMessageOrDefault(): String? { + return mDownloadingMessage ?: DEFAULT_DOWNLOADING_MESSAGE + } + + private fun getLackPermissionToDownloadMessageOrDefault(): String? { + return mLackPermissionToDownloadMessage + ?: DEFAULT_LACK_PERMISSION_TO_DOWNLOAD_MESSAGE + } + + fun setSource(view: RNCWebView, source: ReadableMap?, newArch: Boolean = true) { + if (source != null) { + if (source.hasKey("html")) { + val html = source.getString("html") + val baseUrl = if (source.hasKey("baseUrl")) source.getString("baseUrl") else "" + view.loadDataWithBaseURL( + baseUrl, + html!!, + HTML_MIME_TYPE, + HTML_ENCODING, + null + ) + return + } + if (source.hasKey("uri")) { + val url = source.getString("uri") + val previousUrl = view.url + if (previousUrl != null && previousUrl == url) { + return + } + if (source.hasKey("method")) { + val method = source.getString("method") + if (method.equals(HTTP_METHOD_POST, ignoreCase = true)) { + var postData: ByteArray? = null + if (source.hasKey("body")) { + val body = source.getString("body") + postData = try { + body!!.toByteArray(charset("UTF-8")) + } catch (e: UnsupportedEncodingException) { + body!!.toByteArray() + } + } + if (postData == null) { + postData = ByteArray(0) + } + view.postUrl(url!!, postData) + return + } + } + val headerMap = HashMap() + if (source.hasKey("headers")) { + if (newArch) { + val headerArray = source.getArray("headers"); + for (header in headerArray!!.toArrayList()) { + val headerCasted = header as HashMap + val name = headerCasted.get("name") ?: "" + val value = headerCasted.get("value") ?: "" + if ("user-agent" == name.lowercase(Locale.ENGLISH)) { + view.settings.userAgentString = value + } else { + headerMap[name] = value + } + } + } else { + val headers = source.getMap("headers") + val iter = headers!!.keySetIterator() + while (iter.hasNextKey()) { + val key = iter.nextKey() + if ("user-agent" == key.lowercase(Locale.ENGLISH)) { + view.settings.userAgentString = headers.getString(key) + } else { + headerMap[key] = headers.getString(key) + } + } + } + } + view.loadUrl(url!!, headerMap) + return + } + } + view.loadUrl(BLANK_URL) + } + + fun setMessagingModuleName(view: RNCWebView, value: String?) { + view.messagingModuleName = value + } + + fun setCacheEnabled(view: RNCWebView, enabled: Boolean) { + view.settings.cacheMode = if (enabled) WebSettings.LOAD_DEFAULT else WebSettings.LOAD_NO_CACHE + } + + fun setIncognito(view: RNCWebView, enabled: Boolean) { + // Don't do anything when incognito is disabled + if (!enabled) { + return; + } + + // Remove all previous cookies + CookieManager.getInstance().removeAllCookies(null); + + // Disable caching + view.settings.cacheMode = WebSettings.LOAD_NO_CACHE + view.clearHistory(); + view.clearCache(true); + + // No form data or autofill enabled + view.clearFormData(); + view.settings.savePassword = false; + view.settings.saveFormData = false; + } + + fun setInjectedJavaScript(view: RNCWebView, injectedJavaScript: String?) { + view.injectedJS = injectedJavaScript + } + + fun setInjectedJavaScriptBeforeContentLoaded(view: RNCWebView, value: String?) { + view.injectedJSBeforeContentLoaded = value + } + + fun setInjectedJavaScriptForMainFrameOnly(view: RNCWebView, value: Boolean) { + view.injectedJavaScriptForMainFrameOnly = value + } + + fun setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(view: RNCWebView, value: Boolean) { + view.injectedJavaScriptBeforeContentLoadedForMainFrameOnly = value + } + + fun setJavaScriptCanOpenWindowsAutomatically(view: RNCWebView, value: Boolean) { + view.settings.javaScriptCanOpenWindowsAutomatically = value + } + + fun setShowsVerticalScrollIndicator(view: RNCWebView, value: Boolean) { + view.isVerticalScrollBarEnabled = value + } + + fun setShowsHorizontalScrollIndicator(view: RNCWebView, value: Boolean) { + view.isHorizontalScrollBarEnabled = value + } + + fun setMessagingEnabled(view: RNCWebView, value: Boolean) { + view.setMessagingEnabled(value) + } + + fun setMediaPlaybackRequiresUserAction(view: RNCWebView, value: Boolean) { + view.settings.mediaPlaybackRequiresUserGesture = value + } + + fun setHasOnScroll(view: RNCWebView, value: Boolean) { + view.setHasScrollEvent(value) + } + + fun setJavaScriptEnabled(view: RNCWebView, enabled: Boolean) { + view.settings.javaScriptEnabled = enabled + } + + fun setAllowFileAccess(view: RNCWebView, allowFileAccess: Boolean) { + view.settings.allowFileAccess = allowFileAccess; + } + + fun setAllowFileAccessFromFileURLs(view: RNCWebView, value: Boolean) { + view.settings.allowFileAccessFromFileURLs = value; + } + + fun setAllowsFullscreenVideo(view: RNCWebView, value: Boolean) { + mAllowsFullscreenVideo = value + setupWebChromeClient(view) + } + + fun setAndroidLayerType(view: RNCWebView, layerTypeString: String?) { + val layerType = when (layerTypeString) { + "hardware" -> View.LAYER_TYPE_HARDWARE + "software" -> View.LAYER_TYPE_SOFTWARE + else -> View.LAYER_TYPE_NONE + } + view.setLayerType(layerType, null) + } + + fun setCacheMode(view: RNCWebView, cacheModeString: String?) { + view.settings.cacheMode = when (cacheModeString) { + "LOAD_CACHE_ONLY" -> WebSettings.LOAD_CACHE_ONLY + "LOAD_CACHE_ELSE_NETWORK" -> WebSettings.LOAD_CACHE_ELSE_NETWORK + "LOAD_NO_CACHE" -> WebSettings.LOAD_NO_CACHE + "LOAD_DEFAULT" -> WebSettings.LOAD_DEFAULT + else -> WebSettings.LOAD_DEFAULT + } + } + + fun setDomStorageEnabled(view: RNCWebView, value: Boolean) { + view.settings.domStorageEnabled = value + } + + fun setDownloadingMessage(value: String?) { + mDownloadingMessage = value + } + + fun setForceDarkOn(view: RNCWebView, enabled: Boolean) { + // Only Android 10+ support dark mode + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { + val forceDarkMode = + if (enabled) WebSettingsCompat.FORCE_DARK_ON else WebSettingsCompat.FORCE_DARK_OFF + WebSettingsCompat.setForceDark(view.settings, forceDarkMode) + } + + // Set how WebView content should be darkened. + // PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: checks for the "color-scheme" tag. + // If present, it uses media queries. If absent, it applies user-agent (automatic) + // More information about Force Dark Strategy can be found here: + // https://developer.android.com/reference/androidx/webkit/WebSettingsCompat#setForceDarkStrategy(android.webkit.WebSettings) + if (enabled && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) { + WebSettingsCompat.setForceDarkStrategy( + view.settings, + WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING + ) + } + } + } + + fun setGeolocationEnabled(view: RNCWebView, value: Boolean) { + view.settings.setGeolocationEnabled(value) + } + + fun setLackPermissionToDownloadMessage(value: String?) { + mLackPermissionToDownloadMessage = value + } + + fun setMinimumFontSize(view: RNCWebView, value: Int) { + view.settings.minimumFontSize = value + } + + fun setAllowsProtectedMedia(view: RNCWebView, enabled: Boolean) { + // This variable is used to keep consistency + // in case a new WebChromeClient is created + // (eg. when mAllowsFullScreenVideo changes) + mAllowsProtectedMedia = enabled + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val client = view.webChromeClient + if (client != null && client is RNCWebChromeClient) { + client.setAllowsProtectedMedia(enabled) + } + } + } + + fun setNestedScrollEnabled(view: RNCWebView, value: Boolean) { + view.nestedScrollEnabled = value + } + + fun setOverScrollMode(view: RNCWebView, overScrollModeString: String?) { + view.overScrollMode = when (overScrollModeString) { + "never" -> View.OVER_SCROLL_NEVER + "content" -> View.OVER_SCROLL_IF_CONTENT_SCROLLS + "always" -> View.OVER_SCROLL_ALWAYS + else -> View.OVER_SCROLL_ALWAYS + } + } + + fun setSaveFormDataDisabled(view: RNCWebView, disabled: Boolean) { + view.settings.saveFormData = !disabled + } + + fun setScalesPageToFit(view: RNCWebView, value: Boolean) { + view.settings.loadWithOverviewMode = value + view.settings.useWideViewPort = value + } + + fun setSetBuiltInZoomControls(view: RNCWebView, value: Boolean) { + view.settings.builtInZoomControls = value + } + + fun setSetDisplayZoomControls(view: RNCWebView, value: Boolean) { + view.settings.displayZoomControls = value + + } + + fun setSetSupportMultipleWindows(view: RNCWebView, value: Boolean) { + view.settings.setSupportMultipleWindows(value) + } + + fun setTextZoom(view: RNCWebView, value: Int) { + view.settings.textZoom = value + } + + fun setThirdPartyCookiesEnabled(view: RNCWebView, enabled: Boolean) { + CookieManager.getInstance().setAcceptThirdPartyCookies(view, enabled) + } +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java deleted file mode 100644 index bd276c1..0000000 --- a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java +++ /dev/null @@ -1,550 +0,0 @@ -package com.reactnativecommunity.webview; - -import android.Manifest; -import android.app.Activity; -import android.app.DownloadManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.os.Parcelable; -import android.provider.MediaStore; - -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.core.content.ContextCompat; -import androidx.core.content.FileProvider; -import androidx.core.util.Pair; - -import android.util.Log; -import android.webkit.MimeTypeMap; -import android.webkit.ValueCallback; -import android.webkit.WebChromeClient; -import android.widget.Toast; - -import com.facebook.react.bridge.ActivityEventListener; -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactContextBaseJavaModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.modules.core.PermissionAwareActivity; -import com.facebook.react.modules.core.PermissionListener; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.concurrent.atomic.AtomicReference; - -import static android.app.Activity.RESULT_OK; - -@ReactModule(name = RNCWebViewModule.MODULE_NAME) -public class RNCWebViewModule extends ReactContextBaseJavaModule implements ActivityEventListener { - public static final String MODULE_NAME = "RNCWebView"; - private static final int PICKER = 1; - private static final int PICKER_LEGACY = 3; - private static final int FILE_DOWNLOAD_PERMISSION_REQUEST = 1; - private ValueCallback filePathCallbackLegacy; - private ValueCallback filePathCallback; - private File outputImage; - private File outputVideo; - private DownloadManager.Request downloadRequest; - - protected static class ShouldOverrideUrlLoadingLock { - protected enum ShouldOverrideCallbackState { - UNDECIDED, - SHOULD_OVERRIDE, - DO_NOT_OVERRIDE, - } - - private int nextLockIdentifier = 1; - private final HashMap> shouldOverrideLocks = new HashMap<>(); - - public synchronized Pair> getNewLock() { - final int lockIdentifier = nextLockIdentifier++; - final AtomicReference shouldOverride = new AtomicReference<>(ShouldOverrideCallbackState.UNDECIDED); - shouldOverrideLocks.put(lockIdentifier, shouldOverride); - return new Pair<>(lockIdentifier, shouldOverride); - } - - @Nullable - public synchronized AtomicReference getLock(Integer lockIdentifier) { - return shouldOverrideLocks.get(lockIdentifier); - } - - public synchronized void removeLock(Integer lockIdentifier) { - shouldOverrideLocks.remove(lockIdentifier); - } - } - - protected static final ShouldOverrideUrlLoadingLock shouldOverrideUrlLoadingLock = new ShouldOverrideUrlLoadingLock(); - - private enum MimeType { - DEFAULT("*/*"), - IMAGE("image"), - VIDEO("video"); - - private final String value; - - MimeType(String value) { - this.value = value; - } - } - - private PermissionListener getWebviewFileDownloaderPermissionListener(String downloadingMessage, String lackPermissionToDownloadMessage) { - return new PermissionListener() { - @Override - public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - switch (requestCode) { - case FILE_DOWNLOAD_PERMISSION_REQUEST: { - // If request is cancelled, the result arrays are empty. - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - if (downloadRequest != null) { - downloadFile(downloadingMessage); - } - } else { - Toast.makeText(getCurrentActivity().getApplicationContext(), lackPermissionToDownloadMessage, Toast.LENGTH_LONG).show(); - } - return true; - } - } - return false; - } - }; - } - - public RNCWebViewModule(ReactApplicationContext reactContext) { - super(reactContext); - reactContext.addActivityEventListener(this); - } - - @Override - public String getName() { - return MODULE_NAME; - } - - @ReactMethod - public void isFileUploadSupported(final Promise promise) { - Boolean result = false; - int current = Build.VERSION.SDK_INT; - if (current >= Build.VERSION_CODES.LOLLIPOP) { - result = true; - } - if (current >= Build.VERSION_CODES.JELLY_BEAN && current <= Build.VERSION_CODES.JELLY_BEAN_MR2) { - result = true; - } - promise.resolve(result); - } - - @ReactMethod(isBlockingSynchronousMethod = true) - public void onShouldStartLoadWithRequestCallback(final boolean shouldStart, final int lockIdentifier) { - final AtomicReference lockObject = shouldOverrideUrlLoadingLock.getLock(lockIdentifier); - if (lockObject != null) { - synchronized (lockObject) { - lockObject.set(shouldStart ? ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.DO_NOT_OVERRIDE : ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.SHOULD_OVERRIDE); - lockObject.notify(); - } - } - } - - public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { - - if (filePathCallback == null && filePathCallbackLegacy == null) { - return; - } - - boolean imageTaken = false; - boolean videoTaken = false; - - if (outputImage != null && outputImage.length() > 0) { - imageTaken = true; - } - if (outputVideo != null && outputVideo.length() > 0) { - videoTaken = true; - } - - // based off of which button was pressed, we get an activity result and a file - // the camera activity doesn't properly return the filename* (I think?) so we use - // this filename instead - switch (requestCode) { - case PICKER: - if (resultCode != RESULT_OK) { - if (filePathCallback != null) { - filePathCallback.onReceiveValue(null); - } - } else { - if (imageTaken) { - filePathCallback.onReceiveValue(new Uri[]{getOutputUri(outputImage)}); - } else if (videoTaken) { - filePathCallback.onReceiveValue(new Uri[]{getOutputUri(outputVideo)}); - } else { - filePathCallback.onReceiveValue(this.getSelectedFiles(data, resultCode)); - } - } - break; - case PICKER_LEGACY: - if (resultCode != RESULT_OK) { - filePathCallbackLegacy.onReceiveValue(null); - } else { - if (imageTaken) { - filePathCallbackLegacy.onReceiveValue(getOutputUri(outputImage)); - } else if (videoTaken) { - filePathCallbackLegacy.onReceiveValue(getOutputUri(outputVideo)); - } else { - filePathCallbackLegacy.onReceiveValue(data.getData()); - } - } - break; - - } - - if (outputImage != null && !imageTaken) { - outputImage.delete(); - } - if (outputVideo != null && !videoTaken) { - outputVideo.delete(); - } - - filePathCallback = null; - filePathCallbackLegacy = null; - outputImage = null; - outputVideo = null; - } - - public void onNewIntent(Intent intent) { - } - - private Uri[] getSelectedFiles(Intent data, int resultCode) { - if (data == null) { - return null; - } - - // we have multiple files selected - if (data.getClipData() != null) { - final int numSelectedFiles = data.getClipData().getItemCount(); - Uri[] result = new Uri[numSelectedFiles]; - for (int i = 0; i < numSelectedFiles; i++) { - result[i] = data.getClipData().getItemAt(i).getUri(); - } - return result; - } - - // we have one file selected - if (data.getData() != null && resultCode == RESULT_OK && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - return WebChromeClient.FileChooserParams.parseResult(resultCode, data); - } - - return null; - } - - public void startPhotoPickerIntent(ValueCallback filePathCallback, String acceptType) { - filePathCallbackLegacy = filePathCallback; - - Intent fileChooserIntent = getFileChooserIntent(acceptType); - Intent chooserIntent = Intent.createChooser(fileChooserIntent, ""); - - ArrayList extraIntents = new ArrayList<>(); - if (acceptsImages(acceptType)) { - Intent photoIntent = getPhotoIntent(); - if (photoIntent != null) { - extraIntents.add(photoIntent); - } - } - if (acceptsVideo(acceptType)) { - Intent videoIntent = getVideoIntent(); - if (videoIntent != null) { - extraIntents.add(videoIntent); - } - } - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{})); - - if (chooserIntent.resolveActivity(getCurrentActivity().getPackageManager()) != null) { - getCurrentActivity().startActivityForResult(chooserIntent, PICKER_LEGACY); - } else { - Log.w("RNCWebViewModule", "there is no Activity to handle this Intent"); - } - } - - @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) - public boolean startPhotoPickerIntent(final ValueCallback callback, final String[] acceptTypes, final boolean allowMultiple) { - filePathCallback = callback; - - ArrayList extraIntents = new ArrayList<>(); - if (!needsCameraPermission()) { - if (acceptsImages(acceptTypes)) { - Intent photoIntent = getPhotoIntent(); - if (photoIntent != null) { - extraIntents.add(photoIntent); - } - } - if (acceptsVideo(acceptTypes)) { - Intent videoIntent = getVideoIntent(); - if (videoIntent != null) { - extraIntents.add(videoIntent); - } - } - } - - Intent fileSelectionIntent = getFileChooserIntent(acceptTypes, allowMultiple); - - Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); - chooserIntent.putExtra(Intent.EXTRA_INTENT, fileSelectionIntent); - chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{})); - - if (chooserIntent.resolveActivity(getCurrentActivity().getPackageManager()) != null) { - getCurrentActivity().startActivityForResult(chooserIntent, PICKER); - } else { - Log.w("RNCWebViewModule", "there is no Activity to handle this Intent"); - } - - return true; - } - - public void setDownloadRequest(DownloadManager.Request request) { - this.downloadRequest = request; - } - - public void downloadFile(String downloadingMessage) { - DownloadManager dm = (DownloadManager) getCurrentActivity().getBaseContext().getSystemService(Context.DOWNLOAD_SERVICE); - - try { - dm.enqueue(this.downloadRequest); - } catch (IllegalArgumentException e) { - Log.w("RNCWebViewModule", "Unsupported URI, aborting download", e); - return; - } - - Toast.makeText(getCurrentActivity().getApplicationContext(), downloadingMessage, Toast.LENGTH_LONG).show(); - } - - public boolean grantFileDownloaderPermissions(String downloadingMessage, String lackPermissionToDownloadMessage) { - // Permission not required for Android Q and above - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - return true; - } - - boolean result = ContextCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; - if (!result && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - PermissionAwareActivity activity = getPermissionAwareActivity(); - activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, FILE_DOWNLOAD_PERMISSION_REQUEST, getWebviewFileDownloaderPermissionListener(downloadingMessage, lackPermissionToDownloadMessage)); - } - - return result; - } - - protected boolean needsCameraPermission() { - boolean needed = false; - - PackageManager packageManager = getCurrentActivity().getPackageManager(); - try { - String[] requestedPermissions = packageManager.getPackageInfo(getReactApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions; - if (Arrays.asList(requestedPermissions).contains(Manifest.permission.CAMERA) - && ContextCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - needed = true; - } - } catch (PackageManager.NameNotFoundException e) { - needed = true; - } - - return needed; - } - - private Intent getPhotoIntent() { - Intent intent = null; - - try { - outputImage = getCapturedFile(MimeType.IMAGE); - Uri outputImageUri = getOutputUri(outputImage); - intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - intent.putExtra(MediaStore.EXTRA_OUTPUT, outputImageUri); - } catch (IOException | IllegalArgumentException e) { - Log.e("CREATE FILE", "Error occurred while creating the File", e); - e.printStackTrace(); - } - - return intent; - } - - private Intent getVideoIntent() { - Intent intent = null; - - try { - outputVideo = getCapturedFile(MimeType.VIDEO); - Uri outputVideoUri = getOutputUri(outputVideo); - intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); - intent.putExtra(MediaStore.EXTRA_OUTPUT, outputVideoUri); - } catch (IOException | IllegalArgumentException e) { - Log.e("CREATE FILE", "Error occurred while creating the File", e); - e.printStackTrace(); - } - - return intent; - } - - private Intent getFileChooserIntent(String acceptTypes) { - String _acceptTypes = acceptTypes; - if (acceptTypes.isEmpty()) { - _acceptTypes = MimeType.DEFAULT.value; - } - if (acceptTypes.matches("\\.\\w+")) { - _acceptTypes = getMimeTypeFromExtension(acceptTypes.replace(".", "")); - } - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType(_acceptTypes); - return intent; - } - - private Intent getFileChooserIntent(String[] acceptTypes, boolean allowMultiple) { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); - intent.addCategory(Intent.CATEGORY_OPENABLE); - intent.setType(MimeType.DEFAULT.value); - intent.putExtra(Intent.EXTRA_MIME_TYPES, getAcceptedMimeType(acceptTypes)); - intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple); - return intent; - } - - private Boolean acceptsImages(String types) { - String mimeType = types; - if (types.matches("\\.\\w+")) { - mimeType = getMimeTypeFromExtension(types.replace(".", "")); - } - return mimeType.isEmpty() || mimeType.toLowerCase().contains(MimeType.IMAGE.value); - } - - private Boolean acceptsImages(String[] types) { - String[] mimeTypes = getAcceptedMimeType(types); - return arrayContainsString(mimeTypes, MimeType.DEFAULT.value) || arrayContainsString(mimeTypes, MimeType.IMAGE.value); - } - - private Boolean acceptsVideo(String types) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return false; - } - - String mimeType = types; - if (types.matches("\\.\\w+")) { - mimeType = getMimeTypeFromExtension(types.replace(".", "")); - } - return mimeType.isEmpty() || mimeType.toLowerCase().contains(MimeType.VIDEO.value); - } - - private Boolean acceptsVideo(String[] types) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return false; - } - - String[] mimeTypes = getAcceptedMimeType(types); - return arrayContainsString(mimeTypes, MimeType.DEFAULT.value) || arrayContainsString(mimeTypes, MimeType.VIDEO.value); - } - - private Boolean arrayContainsString(String[] array, String pattern) { - for (String content : array) { - if (content.contains(pattern)) { - return true; - } - } - return false; - } - - private String[] getAcceptedMimeType(String[] types) { - if (noAcceptTypesSet(types)) { - return new String[]{MimeType.DEFAULT.value}; - } - String[] mimeTypes = new String[types.length]; - for (int i = 0; i < types.length; i++) { - String t = types[i]; - // convert file extensions to mime types - if (t.matches("\\.\\w+")) { - String mimeType = getMimeTypeFromExtension(t.replace(".", "")); - if(mimeType != null) { - mimeTypes[i] = mimeType; - } else { - mimeTypes[i] = t; - } - } else { - mimeTypes[i] = t; - } - } - return mimeTypes; - } - - private String getMimeTypeFromExtension(String extension) { - String type = null; - if (extension != null) { - type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - } - return type; - } - - private Uri getOutputUri(File capturedFile) { - // for versions below 6.0 (23) we use the old File creation & permissions model - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - return Uri.fromFile(capturedFile); - } - - // for versions 6.0+ (23) we use the FileProvider to avoid runtime permissions - String packageName = getReactApplicationContext().getPackageName(); - return FileProvider.getUriForFile(getReactApplicationContext(), packageName + ".fileprovider", capturedFile); - } - - private File getCapturedFile(MimeType mimeType) throws IOException { - String prefix = ""; - String suffix = ""; - String dir = ""; - - switch (mimeType) { - case IMAGE: - prefix = "image-"; - suffix = ".jpg"; - dir = Environment.DIRECTORY_PICTURES; - break; - case VIDEO: - prefix = "video-"; - suffix = ".mp4"; - dir = Environment.DIRECTORY_MOVIES; - break; - - default: - break; - } - - String filename = prefix + String.valueOf(System.currentTimeMillis()) + suffix; - File outputFile = null; - - // for versions below 6.0 (23) we use the old File creation & permissions model - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - // only this Directory works on all tested Android versions - // ctx.getExternalFilesDir(dir) was failing on Android 5.0 (sdk 21) - File storageDir = Environment.getExternalStoragePublicDirectory(dir); - outputFile = new File(storageDir, filename); - } else { - File storageDir = getReactApplicationContext().getExternalFilesDir(null); - outputFile = File.createTempFile(prefix, suffix, storageDir); - } - - return outputFile; - } - - private Boolean noAcceptTypesSet(String[] types) { - // when our array returned from getAcceptTypes() has no values set from the webview - // i.e. , without any "accept" attr - // will be an array with one empty string element, afaik - - return types.length == 0 || (types.length == 1 && types[0] != null && types[0].length() == 0); - } - - private PermissionAwareActivity getPermissionAwareActivity() { - Activity activity = getCurrentActivity(); - if (activity == null) { - throw new IllegalStateException("Tried to use permissions API while not attached to an Activity."); - } else if (!(activity instanceof PermissionAwareActivity)) { - throw new IllegalStateException("Tried to use permissions API but the host Activity doesn't implement PermissionAwareActivity."); - } - return (PermissionAwareActivity) activity; - } -} diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java new file mode 100644 index 0000000..95b99c2 --- /dev/null +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java @@ -0,0 +1,544 @@ +package com.reactnativecommunity.webview; + +import android.Manifest; +import android.app.Activity; +import android.app.DownloadManager; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.Parcelable; +import android.provider.MediaStore; + +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.core.util.Pair; + +import android.util.Log; +import android.webkit.MimeTypeMap; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.widget.Toast; + +import com.facebook.common.activitylistener.ActivityListenerManager; +import com.facebook.react.bridge.ActivityEventListener; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.modules.core.PermissionAwareActivity; +import com.facebook.react.modules.core.PermissionListener; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.concurrent.atomic.AtomicReference; + +import static android.app.Activity.RESULT_OK; + +public class RNCWebViewModuleImpl implements ActivityEventListener { + public static final String NAME = "RNCWebView"; + + public static final int PICKER = 1; + public static final int PICKER_LEGACY = 3; + public static final int FILE_DOWNLOAD_PERMISSION_REQUEST = 1; + + final private ReactApplicationContext mContext; + + private DownloadManager.Request mDownloadRequest; + + private ValueCallback mFilePathCallbackLegacy; + private ValueCallback mFilePathCallback; + private File mOutputImage; + private File mOutputVideo; + + public RNCWebViewModuleImpl(ReactApplicationContext context) { + mContext = context; + context.addActivityEventListener(this); + } + + @Override + public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { + if (mFilePathCallback == null && mFilePathCallbackLegacy == null) { + return; + } + + boolean imageTaken = false; + boolean videoTaken = false; + + if (mOutputImage != null && mOutputImage.length() > 0) { + imageTaken = true; + } + if (mOutputVideo != null && mOutputVideo.length() > 0) { + videoTaken = true; + } + + // based off of which button was pressed, we get an activity result and a file + // the camera activity doesn't properly return the filename* (I think?) so we use + // this filename instead + switch (requestCode) { + case RNCWebViewModuleImpl.PICKER: + if (resultCode != RESULT_OK) { + if (mFilePathCallback != null) { + mFilePathCallback.onReceiveValue(null); + } + } else { + if (imageTaken) { + mFilePathCallback.onReceiveValue(new Uri[]{getOutputUri(mOutputImage)}); + } else if (videoTaken) { + mFilePathCallback.onReceiveValue(new Uri[]{getOutputUri(mOutputVideo)}); + } else { + mFilePathCallback.onReceiveValue(getSelectedFiles(data, resultCode)); + } + } + break; + case RNCWebViewModuleImpl.PICKER_LEGACY: + if (resultCode != RESULT_OK) { + mFilePathCallbackLegacy.onReceiveValue(null); + } else { + if (imageTaken) { + mFilePathCallbackLegacy.onReceiveValue(getOutputUri(mOutputImage)); + } else if (videoTaken) { + mFilePathCallbackLegacy.onReceiveValue(getOutputUri(mOutputVideo)); + } else { + mFilePathCallbackLegacy.onReceiveValue(data.getData()); + } + } + break; + + } + + if (mOutputImage != null && !imageTaken) { + mOutputImage.delete(); + } + if (mOutputVideo != null && !videoTaken) { + mOutputVideo.delete(); + } + + mFilePathCallback = null; + mFilePathCallbackLegacy = null; + mOutputImage = null; + mOutputVideo = null; + } + + @Override + public void onNewIntent(Intent intent) { + + } + + protected static class ShouldOverrideUrlLoadingLock { + protected enum ShouldOverrideCallbackState { + UNDECIDED, + SHOULD_OVERRIDE, + DO_NOT_OVERRIDE, + } + + private double nextLockIdentifier = 1; + private final HashMap> shouldOverrideLocks = new HashMap<>(); + + public synchronized Pair> getNewLock() { + final double lockIdentifier = nextLockIdentifier++; + final AtomicReference shouldOverride = new AtomicReference<>(ShouldOverrideCallbackState.UNDECIDED); + shouldOverrideLocks.put(lockIdentifier, shouldOverride); + return new Pair<>(lockIdentifier, shouldOverride); + } + + @Nullable + public synchronized AtomicReference getLock(Double lockIdentifier) { + return shouldOverrideLocks.get(lockIdentifier); + } + + public synchronized void removeLock(Double lockIdentifier) { + shouldOverrideLocks.remove(lockIdentifier); + } + } + + protected static final ShouldOverrideUrlLoadingLock shouldOverrideUrlLoadingLock = new ShouldOverrideUrlLoadingLock(); + + private enum MimeType { + DEFAULT("*/*"), + IMAGE("image"), + VIDEO("video"); + + private final String value; + + MimeType(String value) { + this.value = value; + } + } + + private PermissionListener getWebviewFileDownloaderPermissionListener(String downloadingMessage, String lackPermissionToDownloadMessage) { + return new PermissionListener() { + @Override + public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + switch (requestCode) { + case FILE_DOWNLOAD_PERMISSION_REQUEST: { + // If request is cancelled, the result arrays are empty. + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + if (mDownloadRequest != null) { + downloadFile(downloadingMessage); + } + } else { + Toast.makeText(mContext, lackPermissionToDownloadMessage, Toast.LENGTH_LONG).show(); + } + return true; + } + } + return false; + } + }; + } + + public boolean isFileUploadSupported() { + return true; + } + + public void shouldStartLoadWithLockIdentifier(boolean shouldStart, double lockIdentifier) { + final AtomicReference lockObject = shouldOverrideUrlLoadingLock.getLock(lockIdentifier); + if (lockObject != null) { + synchronized (lockObject) { + lockObject.set(shouldStart ? ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.DO_NOT_OVERRIDE : ShouldOverrideUrlLoadingLock.ShouldOverrideCallbackState.SHOULD_OVERRIDE); + lockObject.notify(); + } + } + } + + public Uri[] getSelectedFiles(Intent data, int resultCode) { + if (data == null) { + return null; + } + + // we have multiple files selected + if (data.getClipData() != null) { + final int numSelectedFiles = data.getClipData().getItemCount(); + Uri[] result = new Uri[numSelectedFiles]; + for (int i = 0; i < numSelectedFiles; i++) { + result[i] = data.getClipData().getItemAt(i).getUri(); + } + return result; + } + + // we have one file selected + if (data.getData() != null && resultCode == RESULT_OK && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + return WebChromeClient.FileChooserParams.parseResult(resultCode, data); + } + + return null; + } + + public void startPhotoPickerIntent(String acceptType, ValueCallback callback) { + mFilePathCallbackLegacy = callback; + Activity activity = mContext.getCurrentActivity(); + Intent fileChooserIntent = getFileChooserIntent(acceptType); + Intent chooserIntent = Intent.createChooser(fileChooserIntent, ""); + + ArrayList extraIntents = new ArrayList<>(); + if (acceptsImages(acceptType)) { + Intent photoIntent = getPhotoIntent(); + if (photoIntent != null) { + extraIntents.add(photoIntent); + } + } + if (acceptsVideo(acceptType)) { + Intent videoIntent = getVideoIntent(); + if (videoIntent != null) { + extraIntents.add(videoIntent); + } + } + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{})); + + if (chooserIntent.resolveActivity(activity.getPackageManager()) != null) { + activity.startActivityForResult(chooserIntent, PICKER_LEGACY); + } else { + Log.w("RNCWebViewModule", "there is no Activity to handle this Intent"); + } + } + + public boolean startPhotoPickerIntent(final String[] acceptTypes, final boolean allowMultiple, ValueCallback callback) { + mFilePathCallback = callback; + Activity activity = mContext.getCurrentActivity(); + + ArrayList extraIntents = new ArrayList<>(); + if (!needsCameraPermission()) { + if (acceptsImages(acceptTypes)) { + Intent photoIntent = getPhotoIntent(); + if (photoIntent != null) { + extraIntents.add(photoIntent); + } + } + if (acceptsVideo(acceptTypes)) { + Intent videoIntent = getVideoIntent(); + if (videoIntent != null) { + extraIntents.add(videoIntent); + } + } + } + + Intent fileSelectionIntent = getFileChooserIntent(acceptTypes, allowMultiple); + + Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); + chooserIntent.putExtra(Intent.EXTRA_INTENT, fileSelectionIntent); + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{})); + + if (chooserIntent.resolveActivity(activity.getPackageManager()) != null) { + activity.startActivityForResult(chooserIntent, PICKER); + } else { + Log.w("RNCWebViewModule", "there is no Activity to handle this Intent"); + } + + return true; + } + + public void setDownloadRequest(DownloadManager.Request request) { + mDownloadRequest = request; + } + + public void downloadFile(String downloadingMessage) { + DownloadManager dm = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE); + + try { + dm.enqueue(mDownloadRequest); + } catch (IllegalArgumentException e) { + Log.w("RNCWebViewModule", "Unsupported URI, aborting download", e); + return; + } + + Toast.makeText(mContext, downloadingMessage, Toast.LENGTH_LONG).show(); + } + + public boolean grantFileDownloaderPermissions(String downloadingMessage, String lackPermissionToDownloadMessage) { + Activity activity = mContext.getCurrentActivity(); + // Permission not required for Android Q and above + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + return true; + } + + boolean result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + if (!result && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + PermissionAwareActivity PAactivity = getPermissionAwareActivity(); + PAactivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, FILE_DOWNLOAD_PERMISSION_REQUEST, getWebviewFileDownloaderPermissionListener(downloadingMessage, lackPermissionToDownloadMessage)); + } + + return result; + } + + protected boolean needsCameraPermission() { + Activity activity = mContext.getCurrentActivity(); + boolean needed = false; + + PackageManager packageManager = activity.getPackageManager(); + try { + String[] requestedPermissions = packageManager.getPackageInfo(activity.getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions; + if (Arrays.asList(requestedPermissions).contains(Manifest.permission.CAMERA) + && ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + needed = true; + } + } catch (PackageManager.NameNotFoundException e) { + needed = true; + } + + return needed; + } + + public Intent getPhotoIntent() { + Intent intent = null; + + try { + mOutputImage = getCapturedFile(MimeType.IMAGE); + Uri outputImageUri = getOutputUri(mOutputImage); + intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + intent.putExtra(MediaStore.EXTRA_OUTPUT, outputImageUri); + } catch (IOException | IllegalArgumentException e) { + Log.e("CREATE FILE", "Error occurred while creating the File", e); + e.printStackTrace(); + } + + return intent; + } + + public Intent getVideoIntent() { + Intent intent = null; + + try { + mOutputVideo = getCapturedFile(MimeType.VIDEO); + Uri outputVideoUri = getOutputUri(mOutputVideo); + intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + intent.putExtra(MediaStore.EXTRA_OUTPUT, outputVideoUri); + } catch (IOException | IllegalArgumentException e) { + Log.e("CREATE FILE", "Error occurred while creating the File", e); + e.printStackTrace(); + } + + return intent; + } + + private Intent getFileChooserIntent(String acceptTypes) { + String _acceptTypes = acceptTypes; + if (acceptTypes.isEmpty()) { + _acceptTypes = MimeType.DEFAULT.value; + } + if (acceptTypes.matches("\\.\\w+")) { + _acceptTypes = getMimeTypeFromExtension(acceptTypes.replace(".", "")); + } + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType(_acceptTypes); + return intent; + } + + private Intent getFileChooserIntent(String[] acceptTypes, boolean allowMultiple) { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType(MimeType.DEFAULT.value); + intent.putExtra(Intent.EXTRA_MIME_TYPES, getAcceptedMimeType(acceptTypes)); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple); + return intent; + } + + private Boolean acceptsImages(String types) { + String mimeType = types; + if (types.matches("\\.\\w+")) { + mimeType = getMimeTypeFromExtension(types.replace(".", "")); + } + return mimeType.isEmpty() || mimeType.toLowerCase().contains(MimeType.IMAGE.value); + } + + private Boolean acceptsImages(String[] types) { + String[] mimeTypes = getAcceptedMimeType(types); + return arrayContainsString(mimeTypes, MimeType.DEFAULT.value) || arrayContainsString(mimeTypes, MimeType.IMAGE.value); + } + + private Boolean acceptsVideo(String types) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return false; + } + + String mimeType = types; + if (types.matches("\\.\\w+")) { + mimeType = getMimeTypeFromExtension(types.replace(".", "")); + } + return mimeType.isEmpty() || mimeType.toLowerCase().contains(MimeType.VIDEO.value); + } + + private Boolean acceptsVideo(String[] types) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return false; + } + + String[] mimeTypes = getAcceptedMimeType(types); + return arrayContainsString(mimeTypes, MimeType.DEFAULT.value) || arrayContainsString(mimeTypes, MimeType.VIDEO.value); + } + + private Boolean arrayContainsString(String[] array, String pattern) { + for (String content : array) { + if (content.contains(pattern)) { + return true; + } + } + return false; + } + + private String[] getAcceptedMimeType(String[] types) { + if (noAcceptTypesSet(types)) { + return new String[]{MimeType.DEFAULT.value}; + } + String[] mimeTypes = new String[types.length]; + for (int i = 0; i < types.length; i++) { + String t = types[i]; + // convert file extensions to mime types + if (t.matches("\\.\\w+")) { + String mimeType = getMimeTypeFromExtension(t.replace(".", "")); + if(mimeType != null) { + mimeTypes[i] = mimeType; + } else { + mimeTypes[i] = t; + } + } else { + mimeTypes[i] = t; + } + } + return mimeTypes; + } + + private String getMimeTypeFromExtension(String extension) { + String type = null; + if (extension != null) { + type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); + } + return type; + } + + public Uri getOutputUri(File capturedFile) { + // for versions below 6.0 (23) we use the old File creation & permissions model + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return Uri.fromFile(capturedFile); + } + + // for versions 6.0+ (23) we use the FileProvider to avoid runtime permissions + String packageName = mContext.getPackageName(); + return FileProvider.getUriForFile(mContext, packageName + ".fileprovider", capturedFile); + } + + public File getCapturedFile(MimeType mimeType) throws IOException { + String prefix = ""; + String suffix = ""; + String dir = ""; + + switch (mimeType) { + case IMAGE: + prefix = "image-"; + suffix = ".jpg"; + dir = Environment.DIRECTORY_PICTURES; + break; + case VIDEO: + prefix = "video-"; + suffix = ".mp4"; + dir = Environment.DIRECTORY_MOVIES; + break; + + default: + break; + } + + String filename = prefix + String.valueOf(System.currentTimeMillis()) + suffix; + File outputFile = null; + + // for versions below 6.0 (23) we use the old File creation & permissions model + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + // only this Directory works on all tested Android versions + // ctx.getExternalFilesDir(dir) was failing on Android 5.0 (sdk 21) + File storageDir = Environment.getExternalStoragePublicDirectory(dir); + outputFile = new File(storageDir, filename); + } else { + File storageDir = mContext.getExternalFilesDir(null); + outputFile = File.createTempFile(prefix, suffix, storageDir); + } + + return outputFile; + } + + private Boolean noAcceptTypesSet(String[] types) { + // when our array returned from getAcceptTypes() has no values set from the webview + // i.e. , without any "accept" attr + // will be an array with one empty string element, afaik + + return types.length == 0 || (types.length == 1 && types[0] != null && types[0].length() == 0); + } + + private PermissionAwareActivity getPermissionAwareActivity() { + Activity activity = mContext.getCurrentActivity(); + if (activity == null) { + throw new IllegalStateException("Tried to use permissions API while not attached to an Activity."); + } else if (!(activity instanceof PermissionAwareActivity)) { + throw new IllegalStateException("Tried to use permissions API but the host Activity doesn't implement PermissionAwareActivity."); + } + return (PermissionAwareActivity) activity; + } +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java new file mode 100644 index 0000000..24e55ed --- /dev/null +++ b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java @@ -0,0 +1,56 @@ +package com.reactnativecommunity.webview; + +import androidx.annotation.Nullable; + +import com.facebook.react.TurboReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.module.model.ReactModuleInfo; +import com.facebook.react.module.model.ReactModuleInfoProvider; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RNCWebViewPackage extends TurboReactPackage { + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + List viewManagers = new ArrayList<>(); + viewManagers.add(new RNCWebViewManager()); + return viewManagers; + } + + @Override + public ReactModuleInfoProvider getReactModuleInfoProvider() { + return () -> { + final Map moduleInfos = new HashMap<>(); + boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; + moduleInfos.put( + RNCWebViewModuleImpl.NAME, + new ReactModuleInfo( + RNCWebViewModuleImpl.NAME, + RNCWebViewModuleImpl.NAME, + false, // canOverrideExistingModule + false, // needsEagerInit + true, // hasConstants + false, // isCxxModule + isTurboModule // isTurboModule + )); + return moduleInfos; + }; + } + + @Nullable + @Override + public NativeModule getModule(String name, ReactApplicationContext reactContext) { + if (name.equals(RNCWebViewModuleImpl.NAME)) { + return new RNCWebViewModule(reactContext); + } else { + return null; + } + } + +} \ No newline at end of file diff --git a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.kt b/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.kt deleted file mode 100644 index 2b74c74..0000000 --- a/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.reactnativecommunity.webview - -import com.facebook.react.ReactPackage -import com.facebook.react.bridge.ReactApplicationContext - - -class RNCWebViewPackage: ReactPackage { - override fun createNativeModules(reactContext: ReactApplicationContext) = listOf( - RNCWebViewModule(reactContext) - ) - - override fun createViewManagers(reactContext: ReactApplicationContext) = listOf( - RNCWebViewManager() - ) -} diff --git a/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java b/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java new file mode 100644 index 0000000..28ef443 --- /dev/null +++ b/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java @@ -0,0 +1,511 @@ +package com.reactnativecommunity.webview; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.common.MapBuilder; +import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.uimanager.SimpleViewManager; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.ViewManagerDelegate; +import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.viewmanagers.RNCWebViewManagerDelegate; +import com.facebook.react.viewmanagers.RNCWebViewManagerInterface; +import com.facebook.react.views.scroll.ScrollEventType; +import com.reactnativecommunity.webview.events.TopHttpErrorEvent; +import com.reactnativecommunity.webview.events.TopLoadingErrorEvent; +import com.reactnativecommunity.webview.events.TopLoadingFinishEvent; +import com.reactnativecommunity.webview.events.TopLoadingProgressEvent; +import com.reactnativecommunity.webview.events.TopLoadingStartEvent; +import com.reactnativecommunity.webview.events.TopMessageEvent; +import com.reactnativecommunity.webview.events.TopRenderProcessGoneEvent; +import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Map; + +@ReactModule(name = RNCWebViewManagerImpl.NAME) +public class RNCWebViewManager extends SimpleViewManager + implements RNCWebViewManagerInterface { + + private final ViewManagerDelegate mDelegate; + private final RNCWebViewManagerImpl mRNCWebViewManagerImpl; + + public RNCWebViewManager() { + mDelegate = new RNCWebViewManagerDelegate<>(this); + mRNCWebViewManagerImpl = new RNCWebViewManagerImpl(); + } + + @Nullable + @Override + protected ViewManagerDelegate getDelegate() { + return mDelegate; + } + + @NonNull + @Override + public String getName() { + return RNCWebViewManagerImpl.NAME; + } + + @NonNull + @Override + protected RNCWebView createViewInstance(@NonNull ThemedReactContext context) { + return mRNCWebViewManagerImpl.createViewInstance(context); + } + + @Override + @ReactProp(name = "allowFileAccess") + public void setAllowFileAccess(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowFileAccess(view, value); + } + + @Override + @ReactProp(name = "allowFileAccessFromFileURLs") + public void setAllowFileAccessFromFileURLs(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowFileAccessFromFileURLs(view, value); + + } + + @Override + @ReactProp(name = "allowUniversalAccessFromFileURLs") + public void setAllowUniversalAccessFromFileURLs(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowUniversalAccessFromFileURLs(view, value); + } + + @Override + @ReactProp(name = "allowsFullscreenVideo") + public void setAllowsFullscreenVideo(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowsFullscreenVideo(view, value); + } + + @Override + @ReactProp(name = "allowsProtectedMedia") + public void setAllowsProtectedMedia(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowsProtectedMedia(view, value); + } + + @Override + @ReactProp(name = "androidLayerType") + public void setAndroidLayerType(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setAndroidLayerType(view, value); + } + + @Override + @ReactProp(name = "applicationNameForUserAgent") + public void setApplicationNameForUserAgent(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setApplicationNameForUserAgent(view, value); + } + + @Override + @ReactProp(name = "basicAuthCredential") + public void setBasicAuthCredential(RNCWebView view, @Nullable ReadableMap value) { + mRNCWebViewManagerImpl.setBasicAuthCredential(view, value); + } + + @Override + @ReactProp(name = "cacheEnabled") + public void setCacheEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setCacheEnabled(view, value); + } + + @Override + @ReactProp(name = "cacheMode") + public void setCacheMode(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setCacheMode(view, value); + } + + @Override + @ReactProp(name = "domStorageEnabled") + public void setDomStorageEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setDomStorageEnabled(view, value); + } + + @Override + @ReactProp(name = "downloadingMessage") + public void setDownloadingMessage(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setDownloadingMessage(value); + } + + @Override + @ReactProp(name = "forceDarkOn") + public void setForceDarkOn(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setForceDarkOn(view, value); + } + + @Override + @ReactProp(name = "geolocationEnabled") + public void setGeolocationEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setGeolocationEnabled(view, value); + } + + @Override + @ReactProp(name = "hasOnScroll") + public void setHasOnScroll(RNCWebView view, boolean hasScrollEvent) { + mRNCWebViewManagerImpl.setHasOnScroll(view, hasScrollEvent); + } + + @Override + @ReactProp(name = "incognito") + public void setIncognito(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setIncognito(view, value); + } + + @Override + @ReactProp(name = "injectedJavaScript") + public void setInjectedJavaScript(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setInjectedJavaScript(view, value); + } + + @Override + @ReactProp(name = "injectedJavaScriptBeforeContentLoaded") + public void setInjectedJavaScriptBeforeContentLoaded(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setInjectedJavaScriptBeforeContentLoaded(view, value); + } + + @Override + @ReactProp(name = "injectedJavaScriptForMainFrameOnly") + public void setInjectedJavaScriptForMainFrameOnly(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setInjectedJavaScriptForMainFrameOnly(view, value); + + } + + @Override + @ReactProp(name = "injectedJavaScriptBeforeContentLoadedForMainFrameOnly") + public void setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(view, value); + + } + + @Override + @ReactProp(name = "javaScriptCanOpenWindowsAutomatically") + public void setJavaScriptCanOpenWindowsAutomatically(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setJavaScriptCanOpenWindowsAutomatically(view, value); + } + + @ReactProp(name = "javaScriptEnabled") + public void setJavaScriptEnabled(RNCWebView view, boolean enabled) { + mRNCWebViewManagerImpl.setJavaScriptEnabled(view, enabled); + } + + @Override + @ReactProp(name = "lackPermissionToDownloadMessage") + public void setLackPermissionToDownloadMessage(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setLackPermissionToDownloadMessage(value); + } + + @Override + @ReactProp(name = "mediaPlaybackRequiresUserAction") + public void setMediaPlaybackRequiresUserAction(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setMediaPlaybackRequiresUserAction(view, value); + } + + @Override + @ReactProp(name = "messagingEnabled") + public void setMessagingEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setMessagingEnabled(view, value); + } + + @Override + @ReactProp(name = "messagingModuleName") + public void setMessagingModuleName(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setMessagingModuleName(view, value); + } + + @Override + @ReactProp(name = "minimumFontSize") + public void setMinimumFontSize(RNCWebView view, int value) { + mRNCWebViewManagerImpl.setMinimumFontSize(view, value); + } + + @Override + @ReactProp(name = "mixedContentMode") + public void setMixedContentMode(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setMixedContentMode(view, value); + } + + @Override + @ReactProp(name = "nestedScrollEnabled") + public void setNestedScrollEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setNestedScrollEnabled(view, value); + } + + @Override + @ReactProp(name = "overScrollMode") + public void setOverScrollMode(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setOverScrollMode(view, value); + } + + @Override + @ReactProp(name = "saveFormDataDisabled") + public void setSaveFormDataDisabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSaveFormDataDisabled(view, value); + } + + @Override + @ReactProp(name = "scalesPageToFit") + public void setScalesPageToFit(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setScalesPageToFit(view, value); + } + + @Override + @ReactProp(name = "setBuiltInZoomControls") + public void setSetBuiltInZoomControls(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSetBuiltInZoomControls(view, value); + } + + @Override + @ReactProp(name = "setDisplayZoomControls") + public void setSetDisplayZoomControls(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSetDisplayZoomControls(view, value); + } + + @Override + @ReactProp(name = "setSupportMultipleWindows") + public void setSetSupportMultipleWindows(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSetSupportMultipleWindows(view, value); + } + + @Override + @ReactProp(name = "showsHorizontalScrollIndicator") + public void setShowsHorizontalScrollIndicator(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setShowsHorizontalScrollIndicator(view, value); + } + + @Override + @ReactProp(name = "showsVerticalScrollIndicator") + public void setShowsVerticalScrollIndicator(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setShowsVerticalScrollIndicator(view, value); + } + + @Override + @ReactProp(name = "newSource") + public void setNewSource(RNCWebView view, @Nullable ReadableMap value) { + mRNCWebViewManagerImpl.setSource(view, value, true); + } + + @Override + @ReactProp(name = "textZoom") + public void setTextZoom(RNCWebView view, int value) { + mRNCWebViewManagerImpl.setTextZoom(view, value); + } + + @Override + @ReactProp(name = "thirdPartyCookiesEnabled") + public void setThirdPartyCookiesEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setThirdPartyCookiesEnabled(view, value); + } + + /* iOS PROPS - no implemented here */ + @Override + public void setAllowingReadAccessToURL(RNCWebView view, @Nullable String value) {} + + @Override + public void setAllowsBackForwardNavigationGestures(RNCWebView view, boolean value) {} + + @Override + public void setAllowsInlineMediaPlayback(RNCWebView view, boolean value) {} + + @Override + public void setAllowsAirPlayForMediaPlayback(RNCWebView view, boolean value) {} + + @Override + public void setAllowsLinkPreview(RNCWebView view, boolean value) {} + + @Override + public void setAutomaticallyAdjustContentInsets(RNCWebView view, boolean value) {} + + @Override + public void setAutoManageStatusBarEnabled(RNCWebView view, boolean value) {} + + @Override + public void setBounces(RNCWebView view, boolean value) {} + + @Override + public void setContentInset(RNCWebView view, @Nullable ReadableMap value) {} + + @Override + public void setContentInsetAdjustmentBehavior(RNCWebView view, @Nullable String value) {} + + @Override + public void setContentMode(RNCWebView view, @Nullable String value) {} + + @Override + public void setDataDetectorTypes(RNCWebView view, @Nullable ReadableArray value) {} + + @Override + public void setDecelerationRate(RNCWebView view, double value) {} + + @Override + public void setDirectionalLockEnabled(RNCWebView view, boolean value) {} + + @Override + public void setEnableApplePay(RNCWebView view, boolean value) {} + + @Override + public void setHideKeyboardAccessoryView(RNCWebView view, boolean value) {} + + @Override + public void setKeyboardDisplayRequiresUserAction(RNCWebView view, boolean value) {} + + @Override + public void setPagingEnabled(RNCWebView view, boolean value) {} + + @Override + public void setPullToRefreshEnabled(RNCWebView view, boolean value) {} + + @Override + public void setScrollEnabled(RNCWebView view, boolean value) {} + + @Override + public void setSharedCookiesEnabled(RNCWebView view, boolean value) {} + + @Override + public void setUseSharedProcessPool(RNCWebView view, boolean value) {} + + @Override + public void setLimitsNavigationsToAppBoundDomains(RNCWebView view, boolean value) {} + + @Override + public void setTextInteractionEnabled(RNCWebView view, boolean value) {} + + @Override + public void setHasOnFileDownload(RNCWebView view, boolean value) {} + + @Override + public void setMenuItems(RNCWebView view, ReadableArray value) {} + + @Override + public void setMediaCapturePermissionGrantType(RNCWebView view, @Nullable String value) {} + /* !iOS PROPS - no implemented here */ + + @Override + @ReactProp(name = "userAgent") + public void setUserAgent(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setUserAgent(view, value); + } + + // These will never be called because we use the shared impl for now + @Override + public void goBack(RNCWebView view) { + view.goBack(); + } + + @Override + public void goForward(RNCWebView view) { + view.goForward(); + } + + @Override + public void reload(RNCWebView view) { + view.reload(); + } + + @Override + public void stopLoading(RNCWebView view) { + view.stopLoading(); + } + + @Override + public void injectJavaScript(RNCWebView view, String javascript) { + view.evaluateJavascriptWithFallback(javascript); + } + + @Override + public void requestFocus(RNCWebView view) { + view.requestFocus(); + } + + @Override + public void postMessage(RNCWebView view, String data) { + try { + JSONObject eventInitDict = new JSONObject(); + eventInitDict.put("data", data); + view.evaluateJavascriptWithFallback( + "(function () {" + + "var event;" + + "var data = " + eventInitDict.toString() + ";" + + "try {" + + "event = new MessageEvent('message', data);" + + "} catch (e) {" + + "event = document.createEvent('MessageEvent');" + + "event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" + + "}" + + "document.dispatchEvent(event);" + + "})();" + ); + } catch (JSONException e) { + throw new RuntimeException(e); + } + } + + @Override + public void loadUrl(RNCWebView view, String url) { + view.loadUrl(url); + } + + @Override + public void clearFormData(RNCWebView view) { + view.clearFormData(); + } + + @Override + public void clearCache(RNCWebView view, boolean includeDiskFiles) { + view.clearCache(includeDiskFiles); + } + + @Override + public void clearHistory(RNCWebView view) { + view.clearHistory(); + } + // !These will never be called + + @Override + protected void addEventEmitters(@NonNull ThemedReactContext reactContext, RNCWebView view) { + // Do not register default touch emitter and let WebView implementation handle touches + view.setWebViewClient(new RNCWebViewClient()); + } + + @Override + public Map getExportedCustomDirectEventTypeConstants() { + Map export = super.getExportedCustomDirectEventTypeConstants(); + if (export == null) { + export = MapBuilder.newHashMap(); + } + // Default events but adding them here explicitly for clarity + export.put(TopLoadingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingStart")); + export.put(TopLoadingFinishEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingFinish")); + export.put(TopLoadingErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingError")); + export.put(TopMessageEvent.EVENT_NAME, MapBuilder.of("registrationName", "onMessage")); + // !Default events but adding them here explicitly for clarity + + export.put(TopLoadingProgressEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingProgress")); + export.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShouldStartLoadWithRequest")); + export.put(ScrollEventType.getJSEventName(ScrollEventType.SCROLL), MapBuilder.of("registrationName", "onScroll")); + export.put(TopHttpErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onHttpError")); + export.put(TopRenderProcessGoneEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRenderProcessGone")); + return export; + } + + @Override + public @Nullable + Map getCommandsMap() { + return mRNCWebViewManagerImpl.getCommandsMap(); + } + + @Override + public void receiveCommand(@NonNull RNCWebView reactWebView, String commandId, @Nullable ReadableArray args) { + mRNCWebViewManagerImpl.receiveCommand(reactWebView, commandId, args); + super.receiveCommand(reactWebView, commandId, args); + } + + @Override + public void onDropViewInstance(@NonNull RNCWebView view) { + mRNCWebViewManagerImpl.onDropViewInstance(view); + super.onDropViewInstance(view); + } +} \ No newline at end of file diff --git a/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java b/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java new file mode 100644 index 0000000..3af5926 --- /dev/null +++ b/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java @@ -0,0 +1,57 @@ +package com.reactnativecommunity.webview; + +import android.app.DownloadManager; +import android.net.Uri; +import android.webkit.ValueCallback; + +import androidx.annotation.NonNull; + +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.module.annotations.ReactModule; + +@ReactModule(name = RNCWebViewModuleImpl.NAME) +public class RNCWebViewModule extends NativeRNCWebViewSpec { + final private RNCWebViewModuleImpl mRNCWebViewModuleImpl; + + public RNCWebViewModule(ReactApplicationContext reactContext) { + super(reactContext); + mRNCWebViewModuleImpl = new RNCWebViewModuleImpl(reactContext); + } + + @Override + public void isFileUploadSupported(final Promise promise) { + promise.resolve(mRNCWebViewModuleImpl.isFileUploadSupported()); + } + + @Override + public void shouldStartLoadWithLockIdentifier(boolean shouldStart, double lockIdentifier) { + mRNCWebViewModuleImpl.shouldStartLoadWithLockIdentifier(shouldStart, lockIdentifier); + } + + public void startPhotoPickerIntent(ValueCallback filePathCallback, String acceptType) { + mRNCWebViewModuleImpl.startPhotoPickerIntent(acceptType, filePathCallback); + } + + public boolean startPhotoPickerIntent(final ValueCallback callback, final String[] acceptTypes, final boolean allowMultiple) { + return mRNCWebViewModuleImpl.startPhotoPickerIntent(acceptTypes, allowMultiple, callback); + } + + public void setDownloadRequest(DownloadManager.Request request) { + mRNCWebViewModuleImpl.setDownloadRequest(request); + } + + public void downloadFile(String downloadingMessage) { + mRNCWebViewModuleImpl.downloadFile(downloadingMessage); + } + + public boolean grantFileDownloaderPermissions(String downloadingMessage, String lackPermissionToDownloadMessage) { + return mRNCWebViewModuleImpl.grantFileDownloaderPermissions(downloadingMessage, lackPermissionToDownloadMessage); + } + + @NonNull + @Override + public String getName() { + return RNCWebViewModuleImpl.NAME; + } +} \ No newline at end of file diff --git a/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java b/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java new file mode 100644 index 0000000..4c03b51 --- /dev/null +++ b/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java @@ -0,0 +1,306 @@ +package com.reactnativecommunity.webview; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.common.MapBuilder; +import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.uimanager.SimpleViewManager; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.views.scroll.ScrollEventType; +import com.reactnativecommunity.webview.events.TopHttpErrorEvent; +import com.reactnativecommunity.webview.events.TopLoadingErrorEvent; +import com.reactnativecommunity.webview.events.TopLoadingFinishEvent; +import com.reactnativecommunity.webview.events.TopLoadingProgressEvent; +import com.reactnativecommunity.webview.events.TopLoadingStartEvent; +import com.reactnativecommunity.webview.events.TopMessageEvent; +import com.reactnativecommunity.webview.events.TopRenderProcessGoneEvent; +import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent; + +import android.graphics.Color; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Map; +import java.util.HashMap; + +public class RNCWebViewManager extends SimpleViewManager { + + private final RNCWebViewManagerImpl mRNCWebViewManagerImpl; + + public RNCWebViewManager() { + mRNCWebViewManagerImpl = new RNCWebViewManagerImpl(); + } + + @Override + public String getName() { + return RNCWebViewManagerImpl.NAME; + } + + @Override + public RNCWebView createViewInstance(ThemedReactContext context) { + return mRNCWebViewManagerImpl.createViewInstance(context); + } + + public RNCWebView createViewInstance(ThemedReactContext context, RNCWebView webView) { + return mRNCWebViewManagerImpl.createViewInstance(context, webView); + } + + @ReactProp(name = "allowFileAccess") + public void setAllowFileAccess(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowFileAccess(view, value); + } + + @ReactProp(name = "allowFileAccessFromFileURLs") + public void setAllowFileAccessFromFileURLs(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowFileAccessFromFileURLs(view, value); + + } + + @ReactProp(name = "allowUniversalAccessFromFileURLs") + public void setAllowUniversalAccessFromFileURLs(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowUniversalAccessFromFileURLs(view, value); + } + + @ReactProp(name = "allowsFullscreenVideo") + public void setAllowsFullscreenVideo(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowsFullscreenVideo(view, value); + } + + @ReactProp(name = "allowsProtectedMedia") + public void setAllowsProtectedMedia(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setAllowsProtectedMedia(view, value); + } + + @ReactProp(name = "androidLayerType") + public void setAndroidLayerType(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setAndroidLayerType(view, value); + } + + @ReactProp(name = "applicationNameForUserAgent") + public void setApplicationNameForUserAgent(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setApplicationNameForUserAgent(view, value); + } + + @ReactProp(name = "basicAuthCredential") + public void setBasicAuthCredential(RNCWebView view, @Nullable ReadableMap value) { + mRNCWebViewManagerImpl.setBasicAuthCredential(view, value); + } + + @ReactProp(name = "cacheEnabled") + public void setCacheEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setCacheEnabled(view, value); + } + + @ReactProp(name = "cacheMode") + public void setCacheMode(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setCacheMode(view, value); + } + + @ReactProp(name = "domStorageEnabled") + public void setDomStorageEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setDomStorageEnabled(view, value); + } + + @ReactProp(name = "downloadingMessage") + public void setDownloadingMessage(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setDownloadingMessage(value); + } + + @ReactProp(name = "forceDarkOn") + public void setForceDarkOn(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setForceDarkOn(view, value); + } + + @ReactProp(name = "geolocationEnabled") + public void setGeolocationEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setGeolocationEnabled(view, value); + } + + @ReactProp(name = "hasOnScroll") + public void setHasOnScroll(RNCWebView view, boolean hasScrollEvent) { + mRNCWebViewManagerImpl.setHasOnScroll(view, hasScrollEvent); + } + + @ReactProp(name = "incognito") + public void setIncognito(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setIncognito(view, value); + } + + @ReactProp(name = "injectedJavaScript") + public void setInjectedJavaScript(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setInjectedJavaScript(view, value); + } + + @ReactProp(name = "injectedJavaScriptBeforeContentLoaded") + public void setInjectedJavaScriptBeforeContentLoaded(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setInjectedJavaScriptBeforeContentLoaded(view, value); + } + + @ReactProp(name = "injectedJavaScriptForMainFrameOnly") + public void setInjectedJavaScriptForMainFrameOnly(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setInjectedJavaScriptForMainFrameOnly(view, value); + + } + + @ReactProp(name = "injectedJavaScriptBeforeContentLoadedForMainFrameOnly") + public void setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly(view, value); + + } + + @ReactProp(name = "javaScriptCanOpenWindowsAutomatically") + public void setJavaScriptCanOpenWindowsAutomatically(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setJavaScriptCanOpenWindowsAutomatically(view, value); + } + + @ReactProp(name = "javaScriptEnabled") + public void setJavaScriptEnabled(RNCWebView view, boolean enabled) { + mRNCWebViewManagerImpl.setJavaScriptEnabled(view, enabled); + } + + @ReactProp(name = "lackPermissionToDownloadMessage") + public void setLackPermissionToDownloadMessage(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setLackPermissionToDownloadMessage(value); + } + + @ReactProp(name = "mediaPlaybackRequiresUserAction") + public void setMediaPlaybackRequiresUserAction(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setMediaPlaybackRequiresUserAction(view, value); + } + + @ReactProp(name = "messagingEnabled") + public void setMessagingEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setMessagingEnabled(view, value); + } + + @ReactProp(name = "messagingModuleName") + public void setMessagingModuleName(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setMessagingModuleName(view, value); + } + + @ReactProp(name = "minimumFontSize") + public void setMinimumFontSize(RNCWebView view, int value) { + mRNCWebViewManagerImpl.setMinimumFontSize(view, value); + } + + @ReactProp(name = "mixedContentMode") + public void setMixedContentMode(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setMixedContentMode(view, value); + } + + @ReactProp(name = "nestedScrollEnabled") + public void setNestedScrollEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setNestedScrollEnabled(view, value); + } + + @ReactProp(name = "overScrollMode") + public void setOverScrollMode(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setOverScrollMode(view, value); + } + + @ReactProp(name = "saveFormDataDisabled") + public void setSaveFormDataDisabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSaveFormDataDisabled(view, value); + } + + @ReactProp(name = "scalesPageToFit") + public void setScalesPageToFit(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setScalesPageToFit(view, value); + } + + @ReactProp(name = "setBuiltInZoomControls") + public void setSetBuiltInZoomControls(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSetBuiltInZoomControls(view, value); + } + + @ReactProp(name = "setDisplayZoomControls") + public void setSetDisplayZoomControls(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSetDisplayZoomControls(view, value); + } + + @ReactProp(name = "setSupportMultipleWindows") + public void setSetSupportMultipleWindows(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setSetSupportMultipleWindows(view, value); + } + + @ReactProp(name = "showsHorizontalScrollIndicator") + public void setShowsHorizontalScrollIndicator(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setShowsHorizontalScrollIndicator(view, value); + } + + @ReactProp(name = "showsVerticalScrollIndicator") + public void setShowsVerticalScrollIndicator(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setShowsVerticalScrollIndicator(view, value); + } + + @ReactProp(name = "source") + public void setSource(RNCWebView view, @Nullable ReadableMap value) { + mRNCWebViewManagerImpl.setSource(view, value, false); + } + + @ReactProp(name = "textZoom") + public void setTextZoom(RNCWebView view, int value) { + mRNCWebViewManagerImpl.setTextZoom(view, value); + } + + @ReactProp(name = "thirdPartyCookiesEnabled") + public void setThirdPartyCookiesEnabled(RNCWebView view, boolean value) { + mRNCWebViewManagerImpl.setThirdPartyCookiesEnabled(view, value); + } + + @ReactProp(name = "userAgent") + public void setUserAgent(RNCWebView view, @Nullable String value) { + mRNCWebViewManagerImpl.setUserAgent(view, value); + } + + @Override + protected void addEventEmitters(@NonNull ThemedReactContext reactContext, RNCWebView view) { + // Do not register default touch emitter and let WebView implementation handle touches + view.setWebViewClient(new RNCWebViewClient()); + } + + @Override + public Map getExportedCustomDirectEventTypeConstants() { + Map export = super.getExportedCustomDirectEventTypeConstants(); + if (export == null) { + export = MapBuilder.newHashMap(); + } + // Default events but adding them here explicitly for clarity + export.put(TopLoadingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingStart")); + export.put(TopLoadingFinishEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingFinish")); + export.put(TopLoadingErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingError")); + export.put(TopMessageEvent.EVENT_NAME, MapBuilder.of("registrationName", "onMessage")); + // !Default events but adding them here explicitly for clarity + + export.put(TopLoadingProgressEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingProgress")); + export.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME, MapBuilder.of("registrationName", "onShouldStartLoadWithRequest")); + export.put(ScrollEventType.getJSEventName(ScrollEventType.SCROLL), MapBuilder.of("registrationName", "onScroll")); + export.put(TopHttpErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onHttpError")); + export.put(TopRenderProcessGoneEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRenderProcessGone")); + return export; + } + + @Override + public @Nullable + Map getCommandsMap() { + return mRNCWebViewManagerImpl.getCommandsMap(); + } + + @Override + public void receiveCommand(@NonNull RNCWebView reactWebView, String commandId, @Nullable ReadableArray args) { + mRNCWebViewManagerImpl.receiveCommand(reactWebView, commandId, args); + super.receiveCommand(reactWebView, commandId, args); + } + + @Override + public void onDropViewInstance(@NonNull RNCWebView view) { + mRNCWebViewManagerImpl.onDropViewInstance(view); + super.onDropViewInstance(view); + } +} \ No newline at end of file diff --git a/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java b/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java new file mode 100644 index 0000000..e220d72 --- /dev/null +++ b/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java @@ -0,0 +1,59 @@ +package com.reactnativecommunity.webview; + +import android.app.DownloadManager; +import android.net.Uri; + +import androidx.annotation.NonNull; +import android.webkit.ValueCallback; + +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.module.annotations.ReactModule; + +@ReactModule(name = RNCWebViewModuleImpl.NAME) +public class RNCWebViewModule extends ReactContextBaseJavaModule { + final private RNCWebViewModuleImpl mRNCWebViewModuleImpl; + + public RNCWebViewModule(ReactApplicationContext reactContext) { + super(reactContext); + mRNCWebViewModuleImpl = new RNCWebViewModuleImpl(reactContext); + } + + @ReactMethod + public void isFileUploadSupported(final Promise promise) { + promise.resolve(mRNCWebViewModuleImpl.isFileUploadSupported()); + } + + @ReactMethod + public void shouldStartLoadWithLockIdentifier(boolean shouldStart, double lockIdentifier) { + mRNCWebViewModuleImpl.shouldStartLoadWithLockIdentifier(shouldStart, lockIdentifier); + } + + public void startPhotoPickerIntent(ValueCallback filePathCallback, String acceptType) { + mRNCWebViewModuleImpl.startPhotoPickerIntent(acceptType, filePathCallback); + } + + public boolean startPhotoPickerIntent(final ValueCallback callback, final String[] acceptTypes, final boolean allowMultiple) { + return mRNCWebViewModuleImpl.startPhotoPickerIntent(acceptTypes, allowMultiple, callback); + } + + public void setDownloadRequest(DownloadManager.Request request) { + mRNCWebViewModuleImpl.setDownloadRequest(request); + } + + public void downloadFile(String downloadingMessage) { + mRNCWebViewModuleImpl.downloadFile(downloadingMessage); + } + + public boolean grantFileDownloaderPermissions(String downloadingMessage, String lackPermissionToDownloadMessage) { + return mRNCWebViewModuleImpl.grantFileDownloaderPermissions(downloadingMessage, lackPermissionToDownloadMessage); + } + + @NonNull + @Override + public String getName() { + return RNCWebViewModuleImpl.NAME; + } +} \ No newline at end of file diff --git a/apple/RNCWebView.h b/apple/RNCWebView.h index 90c9d62..d359365 100644 --- a/apple/RNCWebView.h +++ b/apple/RNCWebView.h @@ -1,118 +1,29 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +// This guard prevent this file to be compiled in the old architecture. +#ifdef RCT_NEW_ARCH_ENABLED +#import +#import +#import +#import +#import -#import -#import -#import +#ifndef NativeComponentExampleComponentView_h +#define NativeComponentExampleComponentView_h -typedef enum RNCWebViewPermissionGrantType : NSUInteger { - RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt, - RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny, - RNCWebViewPermissionGrantType_Deny, - RNCWebViewPermissionGrantType_Grant, - RNCWebViewPermissionGrantType_Prompt -} RNCWebViewPermissionGrantType; - -@class RNCWebView; - -@protocol RNCWebViewDelegate - -- (BOOL)webView:(RNCWebView *_Nonnull)webView -shouldStartLoadForRequest:(NSMutableDictionary *_Nonnull)request - withCallback:(RCTDirectEventBlock _Nonnull)callback; - -@end - -@interface RNCWeakScriptMessageDelegate : NSObject - -@property (nonatomic, weak, nullable) id scriptDelegate; - -- (nullable instancetype)initWithDelegate:(id _Nullable)scriptDelegate; +NS_ASSUME_NONNULL_BEGIN +@interface RNCWebView : RCTViewComponentView @end -@interface RNCWebView : RCTView - -@property (nonatomic, weak) id _Nullable delegate; -@property (nonatomic, copy) NSDictionary * _Nullable source; -@property (nonatomic, assign) BOOL messagingEnabled; -@property (nonatomic, copy) NSString * _Nullable injectedJavaScript; -@property (nonatomic, copy) NSString * _Nullable injectedJavaScriptBeforeContentLoaded; -@property (nonatomic, assign) BOOL injectedJavaScriptForMainFrameOnly; -@property (nonatomic, assign) BOOL injectedJavaScriptBeforeContentLoadedForMainFrameOnly; -@property (nonatomic, assign) BOOL scrollEnabled; -@property (nonatomic, assign) BOOL sharedCookiesEnabled; -@property (nonatomic, assign) BOOL autoManageStatusBarEnabled; -@property (nonatomic, assign) BOOL pagingEnabled; -@property (nonatomic, assign) CGFloat decelerationRate; -@property (nonatomic, assign) BOOL allowsInlineMediaPlayback; -@property (nonatomic, assign) BOOL allowsAirPlayForMediaPlayback; -@property (nonatomic, assign) BOOL bounces; -@property (nonatomic, assign) BOOL mediaPlaybackRequiresUserAction; -#if WEBKIT_IOS_10_APIS_AVAILABLE -@property (nonatomic, assign) WKDataDetectorTypes dataDetectorTypes; -#endif -@property (nonatomic, assign) UIEdgeInsets contentInset; -@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets; -@property (nonatomic, assign) BOOL keyboardDisplayRequiresUserAction; -@property (nonatomic, assign) BOOL hideKeyboardAccessoryView; -@property (nonatomic, assign) BOOL allowsBackForwardNavigationGestures; -@property (nonatomic, assign) BOOL incognito; -@property (nonatomic, assign) BOOL useSharedProcessPool; -@property (nonatomic, copy) NSString * _Nullable userAgent; -@property (nonatomic, copy) NSString * _Nullable applicationNameForUserAgent; -@property (nonatomic, assign) BOOL cacheEnabled; -@property (nonatomic, assign) BOOL javaScriptEnabled; -@property (nonatomic, assign) BOOL javaScriptCanOpenWindowsAutomatically; -@property (nonatomic, assign) BOOL allowFileAccessFromFileURLs; -@property (nonatomic, assign) BOOL allowUniversalAccessFromFileURLs; -@property (nonatomic, assign) BOOL allowsLinkPreview; -@property (nonatomic, assign) BOOL showsHorizontalScrollIndicator; -@property (nonatomic, assign) BOOL showsVerticalScrollIndicator; -@property (nonatomic, assign) BOOL directionalLockEnabled; -@property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch; -@property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL; -@property (nonatomic, copy) NSDictionary * _Nullable basicAuthCredential; -@property (nonatomic, assign) BOOL pullToRefreshEnabled; -@property (nonatomic, assign) BOOL enableApplePay; -@property (nonatomic, copy) NSArray * _Nullable menuItems; -@property (nonatomic, copy) RCTDirectEventBlock onCustomMenuSelection; -#if !TARGET_OS_OSX -@property (nonatomic, weak) UIRefreshControl * _Nullable refreshControl; -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ -@property (nonatomic, assign) WKContentMode contentMode; -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ -@property (nonatomic, assign) BOOL limitsNavigationsToAppBoundDomains; -#endif +namespace facebook { +namespace react { + bool operator==(const RNCWebViewMenuItemsStruct& a, const RNCWebViewMenuItemsStruct& b) + { + return b.key == a.key && b.label == a.label; + } +} +} -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* iOS 14.5 */ -@property (nonatomic, assign) BOOL textInteractionEnabled; -#endif +NS_ASSUME_NONNULL_END -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ -@property (nonatomic, assign) RNCWebViewPermissionGrantType mediaCapturePermissionGrantType; -#endif - -+ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential; -+ (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates; -- (void)postMessage:(NSString *_Nullable)message; -- (void)injectJavaScript:(NSString *_Nullable)script; -- (void)goForward; -- (void)goBack; -- (void)reload; -- (void)stopLoading; -- (void)requestFocus; -#if !TARGET_OS_OSX -- (void)addPullToRefreshControl; -- (void)pullToRefresh:(UIRefreshControl *_Nonnull)refreshControl; -#endif - -@end +#endif /* NativeComponentExampleComponentView_h */ +#endif /* RCT_NEW_ARCH_ENABLED */ diff --git a/apple/RNCWebView.mm b/apple/RNCWebView.mm new file mode 100644 index 0000000..f664e93 --- /dev/null +++ b/apple/RNCWebView.mm @@ -0,0 +1,502 @@ +// This guard prevent the code from being compiled in the old architecture +#ifdef RCT_NEW_ARCH_ENABLED +#import "RNCWebView.h" +#import "RNCWebViewImpl.h" + +#import +#import +#import +#import + +#import "RCTFabricComponentsPlugins.h" + +using namespace facebook::react; + +auto stringToOnShouldStartLoadWithRequestNavigationTypeEnum(std::string value) { + if (value == "click") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Click; + if (value == "formsubmit") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Formsubmit; + if (value == "backforward") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Backforward; + if (value == "reload") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Reload; + if (value == "formresubmit") return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Formresubmit; + return RNCWebViewEventEmitter::OnShouldStartLoadWithRequestNavigationType::Other; +} + +auto stringToOnLoadingStartNavigationTypeEnum(std::string value) { + if (value == "click") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Click; + if (value == "formsubmit") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Formsubmit; + if (value == "backforward") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Backforward; + if (value == "reload") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Reload; + if (value == "formresubmit") return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Formresubmit; + return RNCWebViewEventEmitter::OnLoadingStartNavigationType::Other; +} + +auto stringToOnLoadingFinishNavigationTypeEnum(std::string value) { + if (value == "click") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Click; + if (value == "formsubmit") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Formsubmit; + if (value == "backforward") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Backforward; + if (value == "reload") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Reload; + if (value == "formresubmit") return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Formresubmit; + return RNCWebViewEventEmitter::OnLoadingFinishNavigationType::Other; +} + +@interface RNCWebView () + +@end + +@implementation RNCWebView { + RNCWebViewImpl * _view; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} + +// Reproduce the idea from here: https://github.com/facebook/react-native/blob/8bd3edec88148d0ab1f225d2119435681fbbba33/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.mm#L142 +- (void)prepareForRecycle { + [super prepareForRecycle]; + [_view destroyWebView]; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + + _view = [[RNCWebViewImpl alloc] init]; + + _view.onShouldStartLoadWithRequest = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnShouldStartLoadWithRequest data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .navigationType = stringToOnShouldStartLoadWithRequestNavigationTypeEnum(std::string([[dictionary valueForKey:@"navigationType"] UTF8String])), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .isTopFrame = [[dictionary valueForKey:@"isTopFrame"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue], + .mainDocumentURL = std::string([[dictionary valueForKey:@"mainDocumentURL"] UTF8String]) + }; + webViewEventEmitter->onShouldStartLoadWithRequest(data); + }; + }; + _view.onLoadingStart = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnLoadingStart data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .navigationType = stringToOnLoadingStartNavigationTypeEnum(std::string([[dictionary valueForKey:@"navigationType"] UTF8String])), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue], + .mainDocumentURL = std::string([[dictionary valueForKey:@"mainDocumentURL"] UTF8String], [[dictionary valueForKey:@"mainDocumentURL"] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) + }; + webViewEventEmitter->onLoadingStart(data); + } + }; + _view.onLoadingError = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnLoadingError data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .code = [[dictionary valueForKey:@"code"] intValue], + .description = std::string([[dictionary valueForKey:@"description"] UTF8String]), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue], + .domain = std::string([[dictionary valueForKey:@"domain"] UTF8String]) + }; + webViewEventEmitter->onLoadingError(data); + } + }; + _view.onMessage = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnMessage data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue], + .data = std::string([[dictionary valueForKey:@"data"] UTF8String]) + }; + webViewEventEmitter->onMessage(data); + } + }; + _view.onLoadingFinish = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnLoadingFinish data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .navigationType = stringToOnLoadingFinishNavigationTypeEnum(std::string([[dictionary valueForKey:@"navigationType"] UTF8String], [[dictionary valueForKey:@"navigationType"] lengthOfBytesUsingEncoding:NSUTF8StringEncoding])), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue], + .mainDocumentURL = std::string([[dictionary valueForKey:@"mainDocumentURL"] UTF8String], [[dictionary valueForKey:@"mainDocumentURL"] lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) + }; + webViewEventEmitter->onLoadingFinish(data); + } + }; + _view.onLoadingProgress = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnLoadingProgress data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue], + .progress = [[dictionary valueForKey:@"progress"] doubleValue] + }; + webViewEventEmitter->onLoadingProgress(data); + } + }; + _view.onContentProcessDidTerminate = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnContentProcessDidTerminate data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue] + }; + webViewEventEmitter->onContentProcessDidTerminate(data); + } + }; + _view.onCustomMenuSelection = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnCustomMenuSelection data = { + .selectedText = std::string([[dictionary valueForKey:@"selectedText"] UTF8String]), + .key = std::string([[dictionary valueForKey:@"key"] UTF8String]), + .label = std::string([[dictionary valueForKey:@"label"] UTF8String]) + + }; + webViewEventEmitter->onCustomMenuSelection(data); + } + }; + _view.onScroll = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + NSDictionary* contentOffset = [dictionary valueForKey:@"contentOffset"]; + NSDictionary* contentInset = [dictionary valueForKey:@"contentInset"]; + NSDictionary* contentSize = [dictionary valueForKey:@"contentSize"]; + NSDictionary* layoutMeasurement = [dictionary valueForKey:@"layoutMeasurement"]; + double zoomScale = [[dictionary valueForKey:@"zoomScale"] doubleValue]; + + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnScroll data = { + .contentOffset = { + .x = [[contentOffset valueForKey:@"x"] doubleValue], + .y = [[contentOffset valueForKey:@"y"] doubleValue] + }, + .contentInset = { + .left = [[contentInset valueForKey:@"left"] doubleValue], + .right = [[contentInset valueForKey:@"right"] doubleValue], + .top = [[contentInset valueForKey:@"top"] doubleValue], + .bottom = [[contentInset valueForKey:@"bottom"] doubleValue] + }, + .contentSize = { + .width = [[contentSize valueForKey:@"width"] doubleValue], + .height = [[contentSize valueForKey:@"height"] doubleValue] + }, + .layoutMeasurement = { + .width = [[layoutMeasurement valueForKey:@"width"] doubleValue], + .height = [[layoutMeasurement valueForKey:@"height"] doubleValue] }, + .zoomScale = zoomScale + }; + webViewEventEmitter->onScroll(data); + } + }; + _view.onHttpError = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnHttpError data = { + .url = std::string([[dictionary valueForKey:@"url"] UTF8String]), + .lockIdentifier = [[dictionary valueForKey:@"lockIdentifier"] doubleValue], + .title = std::string([[dictionary valueForKey:@"title"] UTF8String]), + .statusCode = [[dictionary valueForKey:@"statusCode"] intValue], + .description = std::string([[dictionary valueForKey:@"description"] UTF8String]), + .canGoBack = [[dictionary valueForKey:@"canGoBack"] boolValue], + .canGoForward = [[dictionary valueForKey:@"canGoBack"] boolValue], + .loading = [[dictionary valueForKey:@"loading"] boolValue] + }; + webViewEventEmitter->onHttpError(data); + } + }; + self.contentView = _view; + } + return self; +} + +- (void)updateEventEmitter:(EventEmitter::Shared const &)eventEmitter +{ + [super updateEventEmitter:eventEmitter]; +} + +- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps +{ + const auto &oldViewProps = *std::static_pointer_cast(_props); + const auto &newViewProps = *std::static_pointer_cast(props); + +#define REMAP_WEBVIEW_PROP(name) \ + if (oldViewProps.name != newViewProps.name) { \ + _view.name = newViewProps.name; \ + } + +#define REMAP_WEBVIEW_STRING_PROP(name) \ + if (oldViewProps.name != newViewProps.name) { \ + _view.name = RCTNSStringFromString(newViewProps.name); \ + } + + REMAP_WEBVIEW_PROP(scrollEnabled) + REMAP_WEBVIEW_STRING_PROP(injectedJavaScript) + REMAP_WEBVIEW_STRING_PROP(injectedJavaScriptBeforeContentLoaded) + REMAP_WEBVIEW_PROP(injectedJavaScriptForMainFrameOnly) + REMAP_WEBVIEW_PROP(injectedJavaScriptBeforeContentLoadedForMainFrameOnly) + REMAP_WEBVIEW_PROP(javaScriptEnabled) + REMAP_WEBVIEW_PROP(javaScriptCanOpenWindowsAutomatically) + REMAP_WEBVIEW_PROP(allowFileAccessFromFileURLs) + REMAP_WEBVIEW_PROP(allowUniversalAccessFromFileURLs) + REMAP_WEBVIEW_PROP(allowsInlineMediaPlayback) + REMAP_WEBVIEW_PROP(allowsAirPlayForMediaPlayback) + REMAP_WEBVIEW_PROP(mediaPlaybackRequiresUserAction) + REMAP_WEBVIEW_PROP(automaticallyAdjustContentInsets) + REMAP_WEBVIEW_PROP(autoManageStatusBarEnabled) + REMAP_WEBVIEW_PROP(hideKeyboardAccessoryView) + REMAP_WEBVIEW_PROP(allowsBackForwardNavigationGestures) + REMAP_WEBVIEW_PROP(incognito) + REMAP_WEBVIEW_PROP(pagingEnabled) + REMAP_WEBVIEW_STRING_PROP(applicationNameForUserAgent) + REMAP_WEBVIEW_PROP(cacheEnabled) + REMAP_WEBVIEW_PROP(allowsLinkPreview) + REMAP_WEBVIEW_STRING_PROP(allowingReadAccessToURL) + + REMAP_WEBVIEW_PROP(messagingEnabled) + REMAP_WEBVIEW_PROP(enableApplePay) + REMAP_WEBVIEW_PROP(pullToRefreshEnabled) + REMAP_WEBVIEW_PROP(bounces) + REMAP_WEBVIEW_PROP(useSharedProcessPool) + REMAP_WEBVIEW_STRING_PROP(userAgent) + REMAP_WEBVIEW_PROP(sharedCookiesEnabled) + #if !TARGET_OS_OSX + REMAP_WEBVIEW_PROP(decelerationRate) + #endif // !TARGET_OS_OSX + REMAP_WEBVIEW_PROP(directionalLockEnabled) + REMAP_WEBVIEW_PROP(showsHorizontalScrollIndicator) + REMAP_WEBVIEW_PROP(showsVerticalScrollIndicator) + REMAP_WEBVIEW_PROP(keyboardDisplayRequiresUserAction) + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ + REMAP_WEBVIEW_PROP(automaticallyAdjustContentInsets) +#endif +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ + REMAP_WEBVIEW_PROP(limitsNavigationsToAppBoundDomains) +#endif +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* iOS 14.5 */ + REMAP_WEBVIEW_PROP(textInteractionEnabled) +#endif + + if (oldViewProps.dataDetectorTypes != newViewProps.dataDetectorTypes) { + WKDataDetectorTypes dataDetectorTypes = WKDataDetectorTypeNone; + if (dataDetectorTypes & RNCWebViewDataDetectorTypes::Address) { + dataDetectorTypes |= WKDataDetectorTypeAddress; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::Link) { + dataDetectorTypes |= WKDataDetectorTypeLink; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::CalendarEvent) { + dataDetectorTypes |= WKDataDetectorTypeCalendarEvent; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::TrackingNumber) { + dataDetectorTypes |= WKDataDetectorTypeTrackingNumber; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::FlightNumber) { + dataDetectorTypes |= WKDataDetectorTypeFlightNumber; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::LookupSuggestion) { + dataDetectorTypes |= WKDataDetectorTypeLookupSuggestion; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::PhoneNumber) { + dataDetectorTypes |= WKDataDetectorTypePhoneNumber; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::All) { + dataDetectorTypes |= WKDataDetectorTypeAll; + } else if (dataDetectorTypes & RNCWebViewDataDetectorTypes::None) { + dataDetectorTypes = WKDataDetectorTypeNone; + } + [_view setDataDetectorTypes:dataDetectorTypes]; + } + if (oldViewProps.contentInset.top != newViewProps.contentInset.top || oldViewProps.contentInset.left != newViewProps.contentInset.left || oldViewProps.contentInset.right != newViewProps.contentInset.right || oldViewProps.contentInset.bottom != newViewProps.contentInset.bottom) { + UIEdgeInsets edgesInsets = { + .top = newViewProps.contentInset.top, + .left = newViewProps.contentInset.left, + .right = newViewProps.contentInset.right, + .bottom = newViewProps.contentInset.bottom + }; + [_view setContentInset: edgesInsets]; + } + + if (oldViewProps.basicAuthCredential.username != newViewProps.basicAuthCredential.username || oldViewProps.basicAuthCredential.password != newViewProps.basicAuthCredential.password) { + [_view setBasicAuthCredential: @{ + @"username": RCTNSStringFromString(newViewProps.basicAuthCredential.username), + @"password": RCTNSStringFromString(newViewProps.basicAuthCredential.password) + }]; + } + if (oldViewProps.contentInsetAdjustmentBehavior != newViewProps.contentInsetAdjustmentBehavior) { + if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::Never) { + [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentNever]; + } else if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::Automatic) { + [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentAutomatic]; + } else if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::ScrollableAxes) { + [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentScrollableAxes]; + } else if (newViewProps.contentInsetAdjustmentBehavior == RNCWebViewContentInsetAdjustmentBehavior::Always) { + [_view setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentAlways]; + } + } + + if (oldViewProps.menuItems != newViewProps.menuItems) { + NSMutableArray *newMenuItems = [NSMutableArray array]; + + for (const auto &menuItem: newViewProps.menuItems) { + [newMenuItems addObject:@{ + @"key": RCTNSStringFromString(menuItem.key), + @"label": RCTNSStringFromString(menuItem.label), + }]; + + } + [_view setMenuItems:newMenuItems]; + } + if (oldViewProps.hasOnFileDownload != newViewProps.hasOnFileDownload) { + if (newViewProps.hasOnFileDownload) { + _view.onFileDownload = [self](NSDictionary* dictionary) { + if (_eventEmitter) { + auto webViewEventEmitter = std::static_pointer_cast(_eventEmitter); + facebook::react::RNCWebViewEventEmitter::OnFileDownload data = { + .downloadUrl = std::string([[dictionary valueForKey:@"downloadUrl"] UTF8String]) + }; + webViewEventEmitter->onFileDownload(data); + } + }; + } else { + _view.onFileDownload = nil; + } + } +// +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ + if (oldViewProps.contentMode != newViewProps.contentMode) { + if (newViewProps.contentMode == RNCWebViewContentMode::Recommended) { + [_view setContentMode: WKContentModeRecommended]; + } else if (newViewProps.contentMode == RNCWebViewContentMode::Mobile) { + [_view setContentMode:WKContentModeMobile]; + } else if (newViewProps.contentMode == RNCWebViewContentMode::Desktop) { + [_view setContentMode:WKContentModeDesktop]; + } + } +#endif + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ + if (oldViewProps.mediaCapturePermissionGrantType != newViewProps.mediaCapturePermissionGrantType) { + if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::Prompt) { + [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_Prompt]; + } else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::Grant) { + [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_Grant]; + } else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::Deny) { + [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_Deny]; + }else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::GrantIfSameHostElsePrompt) { + [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt]; + }else if (newViewProps.mediaCapturePermissionGrantType == RNCWebViewMediaCapturePermissionGrantType::GrantIfSameHostElseDeny) { + [_view setMediaCapturePermissionGrantType:RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny]; + } + } +#endif + + NSMutableDictionary* source = [[NSMutableDictionary alloc] init]; + if (!newViewProps.newSource.uri.empty()) { + [source setValue:RCTNSStringFromString(newViewProps.newSource.uri) forKey:@"uri"]; + } + NSMutableDictionary* headers = [[NSMutableDictionary alloc] init]; + for (auto & element : newViewProps.newSource.headers) { + [headers setValue:RCTNSStringFromString(element.value) forKey:RCTNSStringFromString(element.name)]; + } + if (headers.count > 0) { + [source setObject:headers forKey:@"headers"]; + } + if (!newViewProps.newSource.baseUrl.empty()) { + [source setValue:RCTNSStringFromString(newViewProps.newSource.baseUrl) forKey:@"baseUrl"]; + } + if (!newViewProps.newSource.body.empty()) { + [source setValue:RCTNSStringFromString(newViewProps.newSource.body) forKey:@"body"]; + } + if (!newViewProps.newSource.html.empty()) { + [source setValue:RCTNSStringFromString(newViewProps.newSource.html) forKey:@"html"]; + } + if (!newViewProps.newSource.method.empty()) { + [source setValue:RCTNSStringFromString(newViewProps.newSource.method) forKey:@"method"]; + } + [_view setSource:source]; + + [super updateProps:props oldProps:oldProps]; +} + +- (void)handleCommand:(nonnull const NSString *)commandName args:(nonnull const NSArray *)args { + RCTRNCWebViewHandleCommand(self, commandName, args); +} + + +Class RNCWebViewCls(void) +{ + return RNCWebView.class; +} + +- (void)goBack { + [_view goBack]; +} + +- (void)goForward { + [_view goForward]; +} + +- (void)injectJavaScript:(nonnull NSString *)javascript { + [_view injectJavaScript:javascript]; +} + +- (void)loadUrl:(nonnull NSString *)url { + // android only +} + +- (void)postMessage:(nonnull NSString *)data { + [_view postMessage:data]; +} + +- (void)reload { + [_view reload]; +} + +- (void)requestFocus { + [_view requestFocus]; +} + +- (void)stopLoading { + [_view stopLoading]; +} + +- (void)clearFormData { + // android only +} + +- (void)clearCache:(BOOL)includeDiskFiles { + // android only +} + +- (void)clearHistory { + // android only +} + +@end +#endif diff --git a/apple/RNCWebViewDecisionManager.h b/apple/RNCWebViewDecisionManager.h new file mode 100644 index 0000000..29735a3 --- /dev/null +++ b/apple/RNCWebViewDecisionManager.h @@ -0,0 +1,20 @@ +#import +#import +#import + +typedef void (^DecisionBlock)(BOOL); + +@interface RNCWebViewDecisionManager : NSObject { + int nextLockIdentifier; + NSMutableDictionary *decisionHandlers; +} + +@property (nonatomic) int nextLockIdentifier; +@property (nonatomic, retain) NSMutableDictionary *decisionHandlers; + ++ (id) getInstance; + +- (int)setDecisionHandler:(DecisionBlock)handler; +- (void) setResult:(BOOL)shouldStart + forLockIdentifier:(int)lockIdentifier; +@end diff --git a/apple/RNCWebViewDecisionManager.m b/apple/RNCWebViewDecisionManager.m new file mode 100644 index 0000000..aa90548 --- /dev/null +++ b/apple/RNCWebViewDecisionManager.m @@ -0,0 +1,47 @@ +#import "RNCWebViewDecisionManager.h" + + + +@implementation RNCWebViewDecisionManager + +@synthesize nextLockIdentifier; +@synthesize decisionHandlers; + ++ (id)getInstance { + static RNCWebViewDecisionManager *lockManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + lockManager = [[self alloc] init]; + }); + return lockManager; +} + +- (int)setDecisionHandler:(DecisionBlock)decisionHandler { + int lockIdentifier = self.nextLockIdentifier++; + + [self.decisionHandlers setObject:decisionHandler forKey:@(lockIdentifier)]; + return lockIdentifier; +} + +- (void) setResult:(BOOL)shouldStart + forLockIdentifier:(int)lockIdentifier { + DecisionBlock handler = [self.decisionHandlers objectForKey:@(lockIdentifier)]; + if (handler == nil) { + RCTLogWarn(@"Lock not found"); + return; + } + handler(shouldStart); + [self.decisionHandlers removeObjectForKey:@(lockIdentifier)]; +} + +- (id)init { + if (self = [super init]) { + self.nextLockIdentifier = 1; + self.decisionHandlers = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (void)dealloc {} + +@end diff --git a/apple/RNCWebViewImpl.h b/apple/RNCWebViewImpl.h new file mode 100644 index 0000000..3d2eadf --- /dev/null +++ b/apple/RNCWebViewImpl.h @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import +#import +#import + +#if !TARGET_OS_OSX +#import +#endif // !TARGET_OS_OSX + +#import "RNCWebViewDecisionManager.h" + +typedef enum RNCWebViewPermissionGrantType : NSUInteger { + RNCWebViewPermissionGrantType_GrantIfSameHost_ElsePrompt, + RNCWebViewPermissionGrantType_GrantIfSameHost_ElseDeny, + RNCWebViewPermissionGrantType_Deny, + RNCWebViewPermissionGrantType_Grant, + RNCWebViewPermissionGrantType_Prompt +} RNCWebViewPermissionGrantType; + +@class RNCWebViewImpl; + +NS_ASSUME_NONNULL_BEGIN + +@protocol RNCWebViewDelegate + +- (BOOL)webView:(RNCWebViewImpl *)webView +shouldStartLoadForRequest:(NSMutableDictionary *)request + withCallback:(RCTDirectEventBlock)callback; + +@end + +@interface RNCWeakScriptMessageDelegate : NSObject + +@property (nonatomic, weak, nullable) id scriptDelegate; + +- (nullable instancetype)initWithDelegate:(id _Nullable)scriptDelegate; + +@end + +@interface RNCWebViewImpl : RCTView +@property (nonatomic, copy) RCTDirectEventBlock onFileDownload; +@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart; +@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish; +@property (nonatomic, copy) RCTDirectEventBlock onLoadingError; +@property (nonatomic, copy) RCTDirectEventBlock onLoadingProgress; +@property (nonatomic, copy) RCTDirectEventBlock onShouldStartLoadWithRequest; +@property (nonatomic, copy) RCTDirectEventBlock onHttpError; +@property (nonatomic, copy) RCTDirectEventBlock onMessage; +@property (nonatomic, copy) RCTDirectEventBlock onScroll; +@property (nonatomic, copy) RCTDirectEventBlock onContentProcessDidTerminate; + + +@property (nonatomic, weak) id _Nullable delegate; +@property (nonatomic, copy) NSDictionary * _Nullable source; +@property (nonatomic, assign) BOOL messagingEnabled; +@property (nonatomic, copy) NSString * _Nullable injectedJavaScript; +@property (nonatomic, copy) NSString * _Nullable injectedJavaScriptBeforeContentLoaded; +@property (nonatomic, assign) BOOL injectedJavaScriptForMainFrameOnly; +@property (nonatomic, assign) BOOL injectedJavaScriptBeforeContentLoadedForMainFrameOnly; +@property (nonatomic, assign) BOOL scrollEnabled; +@property (nonatomic, assign) BOOL sharedCookiesEnabled; +@property (nonatomic, assign) BOOL autoManageStatusBarEnabled; +@property (nonatomic, assign) BOOL pagingEnabled; +@property (nonatomic, assign) CGFloat decelerationRate; +@property (nonatomic, assign) BOOL allowsInlineMediaPlayback; +@property (nonatomic, assign) BOOL allowsAirPlayForMediaPlayback; +@property (nonatomic, assign) BOOL bounces; +@property (nonatomic, assign) BOOL mediaPlaybackRequiresUserAction; +@property (nonatomic, assign) UIEdgeInsets contentInset; +@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets; +@property (nonatomic, assign) BOOL keyboardDisplayRequiresUserAction; +@property (nonatomic, assign) BOOL hideKeyboardAccessoryView; +@property (nonatomic, assign) BOOL allowsBackForwardNavigationGestures; +@property (nonatomic, assign) BOOL incognito; +@property (nonatomic, assign) BOOL useSharedProcessPool; +@property (nonatomic, copy) NSString * _Nullable userAgent; +@property (nonatomic, copy) NSString * _Nullable applicationNameForUserAgent; +@property (nonatomic, assign) BOOL cacheEnabled; +@property (nonatomic, assign) BOOL javaScriptEnabled; +@property (nonatomic, assign) BOOL javaScriptCanOpenWindowsAutomatically; +@property (nonatomic, assign) BOOL allowFileAccessFromFileURLs; +@property (nonatomic, assign) BOOL allowUniversalAccessFromFileURLs; +@property (nonatomic, assign) BOOL allowsLinkPreview; +@property (nonatomic, assign) BOOL showsHorizontalScrollIndicator; +@property (nonatomic, assign) BOOL showsVerticalScrollIndicator; +@property (nonatomic, assign) BOOL directionalLockEnabled; +@property (nonatomic, assign) BOOL ignoreSilentHardwareSwitch; +@property (nonatomic, copy) NSString * _Nullable allowingReadAccessToURL; +@property (nonatomic, copy) NSDictionary * _Nullable basicAuthCredential; +@property (nonatomic, assign) BOOL pullToRefreshEnabled; +@property (nonatomic, assign) BOOL enableApplePay; +@property (nonatomic, copy) NSArray * _Nullable menuItems; +@property (nonatomic, copy) RCTDirectEventBlock onCustomMenuSelection; +#if !TARGET_OS_OSX +@property (nonatomic, assign) WKDataDetectorTypes dataDetectorTypes; +@property (nonatomic, weak) UIRefreshControl * _Nullable refreshControl; +#endif + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ +@property (nonatomic, assign) WKContentMode contentMode; +#endif + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ +@property (nonatomic, assign) BOOL limitsNavigationsToAppBoundDomains; +#endif + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140500 /* iOS 14.5 */ +@property (nonatomic, assign) BOOL textInteractionEnabled; +#endif + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 150000 /* iOS 15 */ +@property (nonatomic, assign) RNCWebViewPermissionGrantType mediaCapturePermissionGrantType; +#endif + +#if !TARGET_OS_OSX +- (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior; +#endif // !TARGET_OS_OSX + ++ (void)setClientAuthenticationCredential:(nullable NSURLCredential*)credential; ++ (void)setCustomCertificatesForHost:(nullable NSDictionary *)certificates; +- (void)postMessage:(NSString *_Nullable)message; +- (void)injectJavaScript:(NSString *_Nullable)script; +- (void)goForward; +- (void)goBack; +- (void)reload; +- (void)stopLoading; +- (void)requestFocus; +#ifdef RCT_NEW_ARCH_ENABLED +- (void)destroyWebView; +#endif +#if !TARGET_OS_OSX +- (void)addPullToRefreshControl; +- (void)pullToRefresh:(UIRefreshControl *)refreshControl; +#endif + +@end + +NS_ASSUME_NONNULL_END diff --git a/apple/RNCWebView.m b/apple/RNCWebViewImpl.m similarity index 92% rename from apple/RNCWebView.m rename to apple/RNCWebViewImpl.m index 7570d8d..c6d18bb 100644 --- a/apple/RNCWebView.m +++ b/apple/RNCWebViewImpl.m @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -#import "RNCWebView.h" +#import "RNCWebViewImpl.h" #import #import #import "RNCWKProcessPoolManager.h" @@ -37,7 +37,7 @@ -(id)inputAccessoryView if (_webView == nil) { return nil; } - + if ([_webView respondsToSelector:@selector(inputAssistantItem)]) { UITextInputAssistantItem *inputAssistantItem = [_webView inputAssistantItem]; inputAssistantItem.leadingBarButtonGroups = @[]; @@ -53,8 +53,8 @@ @interface RNCWKWebView : WKWebView @end @implementation RNCWKWebView - (void)scrollWheel:(NSEvent *)theEvent { - RNCWebView *rncWebView = (RNCWebView *)[self superview]; - RCTAssert([rncWebView isKindOfClass:[rncWebView class]], @"superview must be an RNCWebView"); + RNCWebViewImpl *rncWebView = (RNCWebViewImpl *)[self superview]; + RCTAssert([rncWebView isKindOfClass:[rncWebView class]], @"superview must be an RNCWebViewImpl"); if (![rncWebView scrollEnabled]) { [[self nextResponder] scrollWheel:theEvent]; return; @@ -64,22 +64,12 @@ - (void)scrollWheel:(NSEvent *)theEvent { @end #endif // TARGET_OS_OSX -@interface RNCWebView () -@property (nonatomic, copy) RCTDirectEventBlock onFileDownload; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingError; -@property (nonatomic, copy) RCTDirectEventBlock onLoadingProgress; -@property (nonatomic, copy) RCTDirectEventBlock onShouldStartLoadWithRequest; -@property (nonatomic, copy) RCTDirectEventBlock onHttpError; -@property (nonatomic, copy) RCTDirectEventBlock onMessage; -@property (nonatomic, copy) RCTDirectEventBlock onScroll; -@property (nonatomic, copy) RCTDirectEventBlock onContentProcessDidTerminate; #if !TARGET_OS_OSX @property (nonatomic, copy) WKWebView *webView; #else @@ -90,7 +80,7 @@ @interface RNCWebView () = 110000 /* __IPHONE_11_0 */ UIScrollViewContentInsetAdjustmentBehavior _savedContentInsetAdjustmentBehavior; #endif @@ -141,7 +131,7 @@ - (instancetype)initWithFrame:(CGRect)frame _injectedJavaScriptForMainFrameOnly = YES; _injectedJavaScriptBeforeContentLoaded = nil; _injectedJavaScriptBeforeContentLoadedForMainFrameOnly = YES; - + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ _savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; #endif @@ -153,13 +143,13 @@ - (instancetype)initWithFrame:(CGRect)frame _mediaCapturePermissionGrantType = RNCWebViewPermissionGrantType_Prompt; #endif } - + #if !TARGET_OS_OSX [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(appDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; - + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(appWillResignActive) name:UIApplicationWillResignActiveNotification @@ -175,19 +165,19 @@ - (instancetype)initWithFrame:(CGRect)frame addObserver:self selector:@selector(keyboardWillShow) name:UIKeyboardWillShowNotification object:nil]; - + // Workaround for StatusBar appearance bug for iOS 12 // https://github.com/react-native-webview/react-native-webview/issues/62 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showFullScreenVideoStatusBars) name:UIWindowDidBecomeVisibleNotification object:nil]; - + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideFullScreenVideoStatusBars) name:UIWindowDidBecomeHiddenNotification object:nil]; - + } #endif // !TARGET_OS_OSX return self; @@ -213,17 +203,17 @@ - (void)startLongPress:(UILongPressGestureRecognizer *)pressSender } UIMenuController *menuController = [UIMenuController sharedMenuController]; NSMutableArray *menuControllerItems = [NSMutableArray arrayWithCapacity:self.menuItems.count]; - + for(NSDictionary *menuItem in self.menuItems) { NSString *menuItemLabel = [RCTConvert NSString:menuItem[@"label"]]; NSString *menuItemKey = [RCTConvert NSString:menuItem[@"key"]]; NSString *sel = [NSString stringWithFormat:@"%@%@", CUSTOM_SELECTOR, menuItemKey]; UIMenuItem *item = [[UIMenuItem alloc] initWithTitle: menuItemLabel action: NSSelectorFromString(sel)]; - + [menuControllerItems addObject: item]; } - + menuController.menuItems = menuControllerItems; [menuController setMenuVisible:YES animated:YES]; } @@ -300,7 +290,7 @@ - (BOOL)canPerformAction:(SEL)action withSender:(id)sender NSString *sel = NSStringFromSelector(action); // Do any of them have our custom keys? NSRange match = [sel rangeOfString:CUSTOM_SELECTOR]; - + if (match.location == 0) { return YES; } @@ -375,7 +365,7 @@ - (WKWebViewConfiguration *)setUpWkWebViewConfig wkWebViewConfig.processPool = [[RNCWKProcessPoolManager sharedManager] sharedProcessPool]; } wkWebViewConfig.userContentController = [WKUserContentController new]; - + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ if (@available(iOS 13.0, *)) { WKWebpagePreferences *pagePrefs = [[WKWebpagePreferences alloc]init]; @@ -383,7 +373,7 @@ - (WKWebViewConfiguration *)setUpWkWebViewConfig wkWebViewConfig.defaultWebpagePreferences = pagePrefs; } #endif - + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 /* iOS 14 */ if (@available(iOS 14.0, *)) { if ([wkWebViewConfig respondsToSelector:@selector(limitsNavigationsToAppBoundDomains)]) { @@ -393,32 +383,28 @@ - (WKWebViewConfiguration *)setUpWkWebViewConfig } } #endif - + // Shim the HTML5 history API: [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self] name:HistoryShimName]; [self resetupScripts:wkWebViewConfig]; - + if(@available(macos 10.11, ios 9.0, *)) { wkWebViewConfig.allowsAirPlayForMediaPlayback = _allowsAirPlayForMediaPlayback; } - + #if !TARGET_OS_OSX wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback; -#if WEBKIT_IOS_10_APIS_AVAILABLE wkWebViewConfig.mediaTypesRequiringUserActionForPlayback = _mediaPlaybackRequiresUserAction ? WKAudiovisualMediaTypeAll : WKAudiovisualMediaTypeNone; wkWebViewConfig.dataDetectorTypes = _dataDetectorTypes; -#else - wkWebViewConfig.mediaPlaybackRequiresUserAction = _mediaPlaybackRequiresUserAction; -#endif #endif // !TARGET_OS_OSX - + if (_applicationNameForUserAgent) { wkWebViewConfig.applicationNameForUserAgent = [NSString stringWithFormat:@"%@ %@", wkWebViewConfig.applicationNameForUserAgent, _applicationNameForUserAgent]; } - + return wkWebViewConfig; } @@ -431,7 +417,7 @@ - (void)didMoveToWindow #else _webView = [[RNCWKWebView alloc] initWithFrame:self.bounds configuration: wkWebViewConfig]; #endif // !TARGET_OS_OSX - + [self setBackgroundColor: _savedBackgroundColor]; #if !TARGET_OS_OSX _webView.scrollView.delegate = self; @@ -453,19 +439,21 @@ - (void)didMoveToWindow _webView.allowsLinkPreview = _allowsLinkPreview; [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures; - + _webView.customUserAgent = _userAgent; -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + +#if !TARGET_OS_OSX if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { _webView.scrollView.contentInsetAdjustmentBehavior = _savedContentInsetAdjustmentBehavior; } -#endif +#endif // !TARGET_OS_OSX + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ if (@available(iOS 13.0, *)) { _webView.scrollView.automaticallyAdjustsScrollIndicatorInsets = _savedAutomaticallyAdjustsScrollIndicatorInsets; } #endif - + [self addSubview:_webView]; [self setHideKeyboardAccessoryView: _savedHideKeyboardAccessoryView]; [self setKeyboardDisplayRequiresUserAction: _savedKeyboardDisplayRequiresUserAction]; @@ -476,7 +464,7 @@ - (void)didMoveToWindow if (self.menuItems != nil) { UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(startLongPress:)]; longPress.delegate = self; - + longPress.minimumPressDuration = 0.4f; longPress.numberOfTouchesRequired = 1; longPress.cancelsTouchesInView = YES; @@ -491,7 +479,11 @@ - (void)setAllowsBackForwardNavigationGestures:(BOOL)allowsBackForwardNavigation _webView.allowsBackForwardNavigationGestures = _allowsBackForwardNavigationGestures; } +#ifdef RCT_NEW_ARCH_ENABLED +- (void)destroyWebView +#else - (void)removeFromSuperview +#endif { if (_webView) { [_webView.configuration.userContentController removeScriptMessageHandlerForName:HistoryShimName]; @@ -507,8 +499,10 @@ - (void)removeFromSuperview _onContentProcessDidTerminate(event); } } - + +#ifndef RCT_NEW_ARCH_ENABLED [super removeFromSuperview]; +#endif } #if !TARGET_OS_OSX @@ -518,7 +512,7 @@ -(void)showFullScreenVideoStatusBars if (!_autoManageStatusBarEnabled) { return; } - + _isFullScreenVideoOpen = YES; RCTUnsafeExecuteOnMainQueueSync(^{ [RCTSharedApplication() setStatusBarStyle:self->_savedStatusBarStyle animated:YES]; @@ -532,7 +526,7 @@ -(void)hideFullScreenVideoStatusBars if (!_autoManageStatusBarEnabled) { return; } - + _isFullScreenVideoOpen = NO; RCTUnsafeExecuteOnMainQueueSync(^{ [RCTSharedApplication() setStatusBarHidden:self->_savedStatusBarHidden animated:YES]; @@ -591,7 +585,7 @@ - (void)setBackgroundColor:(RCTUIColor *)backgroundColor if (_webView == nil) { return; } - + CGFloat alpha = CGColorGetAlpha(backgroundColor.CGColor); BOOL opaque = (alpha == 1.0); #if !TARGET_OS_OSX @@ -609,21 +603,22 @@ - (void)setBackgroundColor:(RCTUIColor *)backgroundColor #endif // !TARGET_OS_OSX } -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ +#if !TARGET_OS_OSX - (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior { _savedContentInsetAdjustmentBehavior = behavior; if (_webView == nil) { return; } - + if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { CGPoint contentOffset = _webView.scrollView.contentOffset; _webView.scrollView.contentInsetAdjustmentBehavior = behavior; _webView.scrollView.contentOffset = contentOffset; } } -#endif +#endif // !TARGET_OS_OSX + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* __IPHONE_13_0 */ - (void)setAutomaticallyAdjustsScrollIndicatorInsets:(BOOL)automaticallyAdjustsScrollIndicatorInsets{ _savedAutomaticallyAdjustsScrollIndicatorInsets = automaticallyAdjustsScrollIndicatorInsets; @@ -635,6 +630,7 @@ - (void)setAutomaticallyAdjustsScrollIndicatorInsets:(BOOL)automaticallyAdjustsS } } #endif + /** * This method is called whenever JavaScript running within the web view calls: * - window.webkit.messageHandlers[MessageHandlerName].postMessage @@ -661,7 +657,7 @@ - (void)setSource:(NSDictionary *)source { if (![_source isEqualToDictionary:source]) { _source = [source copy]; - + if (_webView != nil) { [self visitSource]; } @@ -672,7 +668,7 @@ - (void)setAllowingReadAccessToURL:(NSString *)allowingReadAccessToURL { if (![_allowingReadAccessToURL isEqualToString:allowingReadAccessToURL]) { _allowingReadAccessToURL = [allowingReadAccessToURL copy]; - + if (_webView != nil) { [self visitSource]; } @@ -716,28 +712,30 @@ - (void)visitSource NSArray *httpCookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:urlString]; [self writeCookiesToWebView:httpCookies completion:nil]; } - + NSURLRequest *request = [self requestForSource:_source]; - + __weak WKWebView *webView = _webView; + NSString *allowingReadAccessToURL = _allowingReadAccessToURL; + [self syncCookiesToWebView:^{ // Because of the way React works, as pages redirect, we actually end up // passing the redirect urls back here, so we ignore them if trying to load // the same url. We'll expose a call to 'reload' to allow a user to load // the existing page. - if ([request.URL isEqual:_webView.URL]) { + if ([request.URL isEqual:webView.URL]) { return; } if (!request.URL) { // Clear the webview - [_webView loadHTMLString:@"" baseURL:nil]; + [webView loadHTMLString:@"" baseURL:nil]; return; } if (request.URL.host) { - [_webView loadRequest:request]; + [webView loadRequest:request]; } else { - NSURL* readAccessUrl = _allowingReadAccessToURL ? [RCTConvert NSURL:_allowingReadAccessToURL] : request.URL; - [_webView loadFileURL:request.URL allowingReadAccessToURL:readAccessUrl]; + NSURL* readAccessUrl = allowingReadAccessToURL ? [RCTConvert NSURL:allowingReadAccessToURL] : request.URL; + [webView loadFileURL:request.URL allowingReadAccessToURL:readAccessUrl]; } }]; } @@ -749,29 +747,29 @@ -(void)setKeyboardDisplayRequiresUserAction:(BOOL)keyboardDisplayRequiresUserAct _savedKeyboardDisplayRequiresUserAction = keyboardDisplayRequiresUserAction; return; } - + if (_savedKeyboardDisplayRequiresUserAction == true) { return; } - + UIView* subview; - + for (UIView* view in _webView.scrollView.subviews) { if([[view.class description] hasPrefix:@"WK"]) subview = view; } - + if(subview == nil) return; - + Class class = subview.class; - + NSOperatingSystemVersion iOS_11_3_0 = (NSOperatingSystemVersion){11, 3, 0}; NSOperatingSystemVersion iOS_12_2_0 = (NSOperatingSystemVersion){12, 2, 0}; NSOperatingSystemVersion iOS_13_0_0 = (NSOperatingSystemVersion){13, 0, 0}; - + Method method; IMP override; - + if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_13_0_0]) { // iOS 13.0.0 - Future SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:"); @@ -807,7 +805,7 @@ -(void)setKeyboardDisplayRequiresUserAction:(BOOL)keyboardDisplayRequiresUserAct ((void (*)(id, SEL, void*, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3); }); } - + method_setImplementation(method, override); } @@ -817,34 +815,34 @@ -(void)setHideKeyboardAccessoryView:(BOOL)hideKeyboardAccessoryView _savedHideKeyboardAccessoryView = hideKeyboardAccessoryView; return; } - + if (_savedHideKeyboardAccessoryView == false) { return; } - + UIView* subview; - + for (UIView* view in _webView.scrollView.subviews) { if([[view.class description] hasPrefix:@"WK"]) subview = view; } - + if(subview == nil) return; - + NSString* name = [NSString stringWithFormat:@"%@_SwizzleHelperWK", subview.class.superclass]; Class newClass = NSClassFromString(name); - + if(newClass == nil) { newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0); if(!newClass) return; - + Method method = class_getInstanceMethod([_SwizzleHelperWK class], @selector(inputAccessoryView)); class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method)); - + objc_registerClassPair(newClass); } - + object_setClass(subview, newClass); } @@ -935,8 +933,8 @@ - (void)postMessage:(NSString *)message - (void)layoutSubviews { [super layoutSubviews]; - - // Ensure webview takes the position and dimensions of RNCWebView + + // Ensure webview takes the position and dimensions of RNCWebViewImpl _webView.frame = self.bounds; #if !TARGET_OS_OSX _webView.scrollView.contentInset = _contentInset; @@ -1077,7 +1075,7 @@ - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSSt #else NSAlert *alert = [[NSAlert alloc] init]; [alert setMessageText:prompt]; - + const NSRect RCTSingleTextFieldFrame = NSMakeRect(0.0, 0.0, 275.0, 22.0); NSTextField *textField = [[NSTextField alloc] initWithFrame:RCTSingleTextFieldFrame]; textField.cell.scrollable = YES; @@ -1086,7 +1084,7 @@ - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSSt } textField.stringValue = defaultText; [alert setAccessoryView:textField]; - + [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button")]; [alert addButtonWithTitle:NSLocalizedString(@"Cancel", @"Cancel button")]; [alert beginSheetModalForWindow:[NSApp keyWindow] completionHandler:^(NSModalResponse response) { @@ -1143,58 +1141,79 @@ - (void) webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { - static NSDictionary *navigationTypes; - static dispatch_once_t onceToken; - - dispatch_once(&onceToken, ^{ - navigationTypes = @{ - @(WKNavigationTypeLinkActivated): @"click", - @(WKNavigationTypeFormSubmitted): @"formsubmit", - @(WKNavigationTypeBackForward): @"backforward", - @(WKNavigationTypeReload): @"reload", - @(WKNavigationTypeFormResubmitted): @"formresubmit", - @(WKNavigationTypeOther): @"other", - }; - }); - - WKNavigationType navigationType = navigationAction.navigationType; - NSURLRequest *request = navigationAction.request; - BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL]; - - if (_onShouldStartLoadWithRequest) { - NSMutableDictionary *event = [self baseEvent]; - if (request.mainDocumentURL) { - [event addEntriesFromDictionary: @{ - @"mainDocumentURL": (request.mainDocumentURL).absoluteString, - }]; - } - [event addEntriesFromDictionary: @{ - @"url": (request.URL).absoluteString, - @"navigationType": navigationTypes[@(navigationType)], - @"isTopFrame": @(isTopFrame) - }]; - if (![self.delegate webView:self - shouldStartLoadForRequest:event - withCallback:_onShouldStartLoadWithRequest]) { - decisionHandler(WKNavigationActionPolicyCancel); - return; + static NSDictionary *navigationTypes; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + navigationTypes = @{ + @(WKNavigationTypeLinkActivated): @"click", + @(WKNavigationTypeFormSubmitted): @"formsubmit", + @(WKNavigationTypeBackForward): @"backforward", + @(WKNavigationTypeReload): @"reload", + @(WKNavigationTypeFormResubmitted): @"formresubmit", + @(WKNavigationTypeOther): @"other", + }; + }); + + WKNavigationType navigationType = navigationAction.navigationType; + NSURLRequest *request = navigationAction.request; + BOOL isTopFrame = [request.URL isEqual:request.mainDocumentURL]; + + if (_onShouldStartLoadWithRequest) { + NSMutableDictionary *event = [self baseEvent]; + int lockIdentifier = [[RNCWebViewDecisionManager getInstance] setDecisionHandler: ^(BOOL shouldStart){ + dispatch_async(dispatch_get_main_queue(), ^{ + if (!shouldStart) { + decisionHandler(WKNavigationActionPolicyCancel); + return; + } + if (self->_onLoadingStart) { + // We have this check to filter out iframe requests and whatnot + if (isTopFrame) { + NSMutableDictionary *event = [self baseEvent]; + [event addEntriesFromDictionary: @{ + @"url": (request.URL).absoluteString, + @"navigationType": navigationTypes[@(navigationType)] + }]; + self->_onLoadingStart(event); + } + } + + // Allow all navigation by default + decisionHandler(WKNavigationActionPolicyAllow); + }); + + }]; + if (request.mainDocumentURL) { + [event addEntriesFromDictionary: @{ + @"mainDocumentURL": (request.mainDocumentURL).absoluteString, + }]; + } + [event addEntriesFromDictionary: @{ + @"url": (request.URL).absoluteString, + @"navigationType": navigationTypes[@(navigationType)], + @"isTopFrame": @(isTopFrame), + @"lockIdentifier": @(lockIdentifier) + }]; + _onShouldStartLoadWithRequest(event); + // decisionHandler(WKNavigationActionPolicyAllow); + return; } - } - - if (_onLoadingStart) { - // We have this check to filter out iframe requests and whatnot - if (isTopFrame) { - NSMutableDictionary *event = [self baseEvent]; - [event addEntriesFromDictionary: @{ - @"url": (request.URL).absoluteString, - @"navigationType": navigationTypes[@(navigationType)] - }]; - _onLoadingStart(event); + + if (_onLoadingStart) { + // We have this check to filter out iframe requests and whatnot + if (isTopFrame) { + NSMutableDictionary *event = [self baseEvent]; + [event addEntriesFromDictionary: @{ + @"url": (request.URL).absoluteString, + @"navigationType": navigationTypes[@(navigationType)] + }]; + _onLoadingStart(event); + } } - } - - // Allow all navigation by default - decisionHandler(WKNavigationActionPolicyAllow); + + // Allow all navigation by default + decisionHandler(WKNavigationActionPolicyAllow); } /** @@ -1223,26 +1242,26 @@ - (void) webView:(WKWebView *)webView if ([navigationResponse.response isKindOfClass:[NSHTTPURLResponse class]]) { NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response; NSInteger statusCode = response.statusCode; - + if (statusCode >= 400) { NSMutableDictionary *httpErrorEvent = [self baseEvent]; [httpErrorEvent addEntriesFromDictionary: @{ @"url": response.URL.absoluteString, @"statusCode": @(statusCode) }]; - + _onHttpError(httpErrorEvent); } - + NSString *disposition = nil; - if (@available(iOS 13, *)) { + if (@available(iOS 13, macOS 10.15, *)) { disposition = [response valueForHTTPHeaderField:@"Content-Disposition"]; } BOOL isAttachment = disposition != nil && [disposition hasPrefix:@"attachment"]; if (isAttachment || !navigationResponse.canShowMIMEType) { if (_onFileDownload) { policy = WKNavigationResponsePolicyCancel; - + NSMutableDictionary *downloadEvent = [self baseEvent]; [downloadEvent addEntriesFromDictionary: @{ @"downloadUrl": (response.URL).absoluteString, @@ -1252,7 +1271,7 @@ - (void) webView:(WKWebView *)webView } } } - + decisionHandler(policy); } @@ -1272,7 +1291,7 @@ - (void) webView:(WKWebView *)webView // http://stackoverflow.com/questions/1024748/how-do-i-fix-nsurlerrordomain-error-999-in-iphone-3-0-os return; } - + if ([error.domain isEqualToString:@"WebKitErrorDomain"] && (error.code == 102 || error.code == 101)) { // Error code 102 "Frame load interrupted" is raised by the WKWebView @@ -1280,7 +1299,7 @@ - (void) webView:(WKWebView *)webView // implementing OAuth with a WebView. return; } - + NSMutableDictionary *event = [self baseEvent]; [event addEntriesFromDictionary:@{ @"didFailProvisionalNavigation": @YES, @@ -1358,13 +1377,15 @@ - (void)webView:(WKWebView *)webView - (void)cookiesDidChangeInCookieStore:(WKHTTPCookieStore *)cookieStore { - if(_sharedCookiesEnabled && @available(iOS 11.0, *)) { - // Write all cookies from WKWebView back to sharedHTTPCookieStorage - [cookieStore getAllCookies:^(NSArray* cookies) { - for (NSHTTPCookie *cookie in cookies) { - [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; - } - }]; + if (@available(iOS 11.0, *)) { + if(_sharedCookiesEnabled) { + // Write all cookies from WKWebView back to sharedHTTPCookieStorage + [cookieStore getAllCookies:^(NSArray* cookies) { + for (NSHTTPCookie *cookie in cookies) { + [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; + } + }]; + } } } @@ -1391,7 +1412,7 @@ - (void)reload * manually call [_webView loadRequest:request]. */ NSURLRequest *request = [self requestForSource:self.source]; - + if (request.URL && !_webView.URL.absoluteString.length) { [_webView loadRequest:request]; } else { @@ -1417,13 +1438,13 @@ - (void)pullToRefresh:(UIRefreshControl *)refreshControl - (void)setPullToRefreshEnabled:(BOOL)pullToRefreshEnabled { _pullToRefreshEnabled = pullToRefreshEnabled; - + if (pullToRefreshEnabled) { [self addPullToRefreshControl]; } else { [_refreshControl removeFromSuperview]; } - + [self setBounces:_bounces]; } #endif // !TARGET_OS_OSX @@ -1451,23 +1472,30 @@ - (void)setBounces:(BOOL)bounces - (void)setInjectedJavaScript:(NSString *)source { _injectedJavaScript = source; - + self.atEndScript = source == nil ? nil : [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:_injectedJavaScriptForMainFrameOnly]; - + if(_webView != nil){ [self resetupScripts:_webView.configuration]; } } +- (void)setEnableApplePay:(BOOL)enableApplePay { + _enableApplePay = enableApplePay; + if(_webView != nil){ + [self resetupScripts:_webView.configuration]; + } +} + - (void)setInjectedJavaScriptBeforeContentLoaded:(NSString *)source { _injectedJavaScriptBeforeContentLoaded = source; - + self.atStartScript = source == nil ? nil : [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:_injectedJavaScriptBeforeContentLoadedForMainFrameOnly]; - + if(_webView != nil){ [self resetupScripts:_webView.configuration]; } @@ -1485,7 +1513,7 @@ - (void)setInjectedJavaScriptBeforeContentLoadedForMainFrameOnly:(BOOL)mainFrame - (void)setMessagingEnabled:(BOOL)messagingEnabled { _messagingEnabled = messagingEnabled; - + self.postMessageScript = _messagingEnabled ? [ [WKUserScript alloc] @@ -1505,7 +1533,7 @@ - (void)setMessagingEnabled:(BOOL)messagingEnabled { forMainFrameOnly:YES ] : nil; - + if(_webView != nil){ [self resetupScripts:_webView.configuration]; } @@ -1513,22 +1541,28 @@ - (void)setMessagingEnabled:(BOOL)messagingEnabled { - (void)writeCookiesToWebView:(NSArray*)cookies completion:(void (^)(void))completion { // The required cookie APIs only became available on iOS 11 - if(_sharedCookiesEnabled && @available(iOS 11.0, *)) { - dispatch_async(dispatch_get_main_queue(), ^{ - dispatch_group_t group = dispatch_group_create(); - for (NSHTTPCookie *cookie in cookies) { - dispatch_group_enter(group); - [_webView.configuration.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:^{ - dispatch_group_leave(group); - }]; - } - dispatch_group_notify(group, dispatch_get_main_queue(), ^{ - if (completion) { - completion(); + if (@available(iOS 11.0, *)) { + if (_sharedCookiesEnabled) { + __weak WKWebView *webView = _webView; + dispatch_async(dispatch_get_main_queue(), ^{ + dispatch_group_t group = dispatch_group_create(); + for (NSHTTPCookie *cookie in cookies) { + dispatch_group_enter(group); + [webView.configuration.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:^{ + dispatch_group_leave(group); + }]; } + dispatch_group_notify(group, dispatch_get_main_queue(), ^{ + if (completion) { + completion(); + } + }); }); - }); - } else if (completion) { + return; + } + } + + if (completion) { completion(); } } @@ -1548,7 +1582,7 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig { } return; } - + NSString *html5HistoryAPIShimSource = [NSString stringWithFormat: @"(function(history) {\n" " function notify(type) {\n" @@ -1571,7 +1605,7 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig { ]; WKUserScript *script = [[WKUserScript alloc] initWithSource:html5HistoryAPIShimSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; [wkWebViewConfig.userContentController addUserScript:script]; - + if(_sharedCookiesEnabled) { // More info to sending cookies with WKWebView // https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303 @@ -1587,7 +1621,7 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig { }]; } else { NSMutableString *script = [NSMutableString string]; - + // Clear all existing cookies in a direct called function. This ensures that no // javascript error will break the web content javascript. // We keep this code here, if someone requires that Cookies are also removed within the @@ -1605,7 +1639,7 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig { [script appendString:@" }\n"]; [script appendString:@"})();\n\n"]; */ - + // Set cookies in a direct called function. This ensures that no // javascript error will break the web content javascript. // Generates JS: document.cookie = "key=value; Path=/; Expires=Thu, 01 Jan 20xx 00:00:01 GMT;" @@ -1626,14 +1660,14 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig { [script appendString:@";\n"]; } [script appendString:@"})();\n"]; - + WKUserScript* cookieInScript = [[WKUserScript alloc] initWithSource:script injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES]; [wkWebViewConfig.userContentController addUserScript:cookieInScript]; } } - + if(_messagingEnabled){ if (self.postMessageScript){ [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self] @@ -1652,7 +1686,7 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig { - (NSURLRequest *)requestForSource:(id)json { NSURLRequest *request = [RCTConvert NSURLRequest:self.source]; - + // If sharedCookiesEnabled we automatically add all application cookies to the // http request. This is automatically done on iOS 11+ in the WebView constructor. // Se we need to manually add these shared cookies here only for iOS versions < 11. diff --git a/apple/RNCWebViewManager.h b/apple/RNCWebViewManager.h index 83ba6eb..af000be 100644 --- a/apple/RNCWebViewManager.h +++ b/apple/RNCWebViewManager.h @@ -1,13 +1,9 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +#ifndef RNCWebViewManager_h +#define RNCWebViewManager_h #import @interface RNCWebViewManager : RCTViewManager -@property (nonatomic, copy) NSArray * _Nullable menuItems; -@property (nonatomic, copy) RCTDirectEventBlock onCustomMenuSelection; @end + +#endif /* RNCWebViewManager_h */ diff --git a/apple/RNCWebViewManager.m b/apple/RNCWebViewManager.mm similarity index 52% rename from apple/RNCWebViewManager.m rename to apple/RNCWebViewManager.mm index 401e40e..0f121f3 100644 --- a/apple/RNCWebViewManager.m +++ b/apple/RNCWebViewManager.mm @@ -1,18 +1,19 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +#import #import "RNCWebViewManager.h" +#import "RNCWebViewImpl.h" +#import "RNCWebViewDecisionManager.h" +#ifdef RCT_NEW_ARCH_ENABLED +#import "RNCWebViewSpec/RNCWebViewSpec.h" +#endif -#import -#import -#import "RNCWebView.h" - -@interface RNCWebViewManager () -@end +#if TARGET_OS_OSX +#define RNCView NSView +@class NSView; +#else +#define RNCView UIView +@class UIView; +#endif // TARGET_OS_OSX @implementation RCTConvert (WKWebView) #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 /* iOS 13 */ @@ -34,26 +35,22 @@ @implementation RCTConvert (WKWebView) #endif @end -@implementation RNCWebViewManager -{ - NSConditionLock *_shouldStartLoadLock; - BOOL _shouldStartLoad; + +@implementation RNCWebViewManager { + NSConditionLock *_shouldStartLoadLock; + BOOL _shouldStartLoad; } -RCT_EXPORT_MODULE() +RCT_EXPORT_MODULE(RNCWebView) -#if !TARGET_OS_OSX -- (UIView *)view -#else -- (RCTUIView *)view -#endif // !TARGET_OS_OSX +- (RNCView *)view { - RNCWebView *webView = [RNCWebView new]; - webView.delegate = self; - return webView; + return [[RNCWebViewImpl alloc] init]; } RCT_EXPORT_VIEW_PROPERTY(source, NSDictionary) +// New arch only +RCT_CUSTOM_VIEW_PROPERTY(newSource, NSDictionary, RNCWebViewImpl) {} RCT_EXPORT_VIEW_PROPERTY(onFileDownload, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLoadingStart, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLoadingFinish, RCTDirectEventBlock) @@ -73,9 +70,7 @@ - (RCTUIView *)view RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL) RCT_EXPORT_VIEW_PROPERTY(allowsAirPlayForMediaPlayback, BOOL) RCT_EXPORT_VIEW_PROPERTY(mediaPlaybackRequiresUserAction, BOOL) -#if WEBKIT_IOS_10_APIS_AVAILABLE RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes) -#endif RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL) RCT_EXPORT_VIEW_PROPERTY(autoManageStatusBarEnabled, BOOL) @@ -120,170 +115,108 @@ - (RCTUIView *)view RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(enableApplePay, BOOL) RCT_EXPORT_VIEW_PROPERTY(menuItems, NSArray); +// New arch only +RCT_CUSTOM_VIEW_PROPERTY(hasOnFileDownload, BOOL, RNCWebViewImpl) {} RCT_EXPORT_VIEW_PROPERTY(onCustomMenuSelection, RCTDirectEventBlock) - -RCT_EXPORT_METHOD(postMessage:(nonnull NSNumber *)reactTag message:(NSString *)message) -{ - [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RNCWebView *view = viewRegistry[reactTag]; - if (![view isKindOfClass:[RNCWebView class]]) { - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); - } else { - [view postMessage:message]; - } - }]; -} - -RCT_CUSTOM_VIEW_PROPERTY(pullToRefreshEnabled, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(pullToRefreshEnabled, BOOL, RNCWebViewImpl) { view.pullToRefreshEnabled = json == nil ? false : [RCTConvert BOOL: json]; } -RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(bounces, BOOL, RNCWebViewImpl) { view.bounces = json == nil ? true : [RCTConvert BOOL: json]; } -RCT_CUSTOM_VIEW_PROPERTY(useSharedProcessPool, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(useSharedProcessPool, BOOL, RNCWebViewImpl) { view.useSharedProcessPool = json == nil ? true : [RCTConvert BOOL: json]; } -RCT_CUSTOM_VIEW_PROPERTY(userAgent, NSString, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(userAgent, NSString, RNCWebViewImpl) { view.userAgent = [RCTConvert NSString: json]; } -RCT_CUSTOM_VIEW_PROPERTY(scrollEnabled, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(scrollEnabled, BOOL, RNCWebViewImpl) { view.scrollEnabled = json == nil ? true : [RCTConvert BOOL: json]; } -RCT_CUSTOM_VIEW_PROPERTY(sharedCookiesEnabled, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(sharedCookiesEnabled, BOOL, RNCWebViewImpl) { view.sharedCookiesEnabled = json == nil ? false : [RCTConvert BOOL: json]; } #if !TARGET_OS_OSX -RCT_CUSTOM_VIEW_PROPERTY(decelerationRate, CGFloat, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(decelerationRate, CGFloat, RNCWebViewImpl) { view.decelerationRate = json == nil ? UIScrollViewDecelerationRateNormal : [RCTConvert CGFloat: json]; } #endif // !TARGET_OS_OSX -RCT_CUSTOM_VIEW_PROPERTY(directionalLockEnabled, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(directionalLockEnabled, BOOL, RNCWebViewImpl) { view.directionalLockEnabled = json == nil ? true : [RCTConvert BOOL: json]; } -RCT_CUSTOM_VIEW_PROPERTY(showsHorizontalScrollIndicator, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(showsHorizontalScrollIndicator, BOOL, RNCWebViewImpl) { view.showsHorizontalScrollIndicator = json == nil ? true : [RCTConvert BOOL: json]; } -RCT_CUSTOM_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL, RNCWebViewImpl) { view.showsVerticalScrollIndicator = json == nil ? true : [RCTConvert BOOL: json]; } -RCT_CUSTOM_VIEW_PROPERTY(keyboardDisplayRequiresUserAction, BOOL, RNCWebView) { +RCT_CUSTOM_VIEW_PROPERTY(keyboardDisplayRequiresUserAction, BOOL, RNCWebViewImpl) { view.keyboardDisplayRequiresUserAction = json == nil ? true : [RCTConvert BOOL: json]; } -RCT_EXPORT_METHOD(injectJavaScript:(nonnull NSNumber *)reactTag script:(NSString *)script) -{ - [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RNCWebView *view = viewRegistry[reactTag]; - if (![view isKindOfClass:[RNCWebView class]]) { - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); - } else { - [view injectJavaScript:script]; - } - }]; -} - -RCT_EXPORT_METHOD(goBack:(nonnull NSNumber *)reactTag) -{ - [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RNCWebView *view = viewRegistry[reactTag]; - if (![view isKindOfClass:[RNCWebView class]]) { - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); - } else { - [view goBack]; - } - }]; -} - -RCT_EXPORT_METHOD(goForward:(nonnull NSNumber *)reactTag) -{ - [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RNCWebView *view = viewRegistry[reactTag]; - if (![view isKindOfClass:[RNCWebView class]]) { - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); - } else { - [view goForward]; - } - }]; -} - -RCT_EXPORT_METHOD(reload:(nonnull NSNumber *)reactTag) -{ - [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RNCWebView *view = viewRegistry[reactTag]; - if (![view isKindOfClass:[RNCWebView class]]) { - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); - } else { - [view reload]; - } - }]; -} - -RCT_EXPORT_METHOD(stopLoading:(nonnull NSNumber *)reactTag) -{ - [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RNCWebView *view = viewRegistry[reactTag]; - if (![view isKindOfClass:[RNCWebView class]]) { - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); - } else { - [view stopLoading]; - } - }]; -} - -RCT_EXPORT_METHOD(requestFocus:(nonnull NSNumber *)reactTag) -{ - [self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { - RNCWebView *view = viewRegistry[reactTag]; - if (![view isKindOfClass:[RNCWebView class]]) { - RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); - } else { - [view requestFocus]; - } - }]; -} - -#pragma mark - Exported synchronous methods +#if !TARGET_OS_OSX + #define BASE_VIEW_PER_OS() UIView +#else + #define BASE_VIEW_PER_OS() NSView +#endif -- (BOOL) webView:(RNCWebView *)webView -shouldStartLoadForRequest:(NSMutableDictionary *)request - withCallback:(RCTDirectEventBlock)callback +#define QUICK_RCT_EXPORT_COMMAND_METHOD(name) \ +RCT_EXPORT_METHOD(name:(nonnull NSNumber *)reactTag) \ +{ \ +[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { \ + RNCWebViewImpl *view = (RNCWebViewImpl *)viewRegistry[reactTag]; \ + if (![view isKindOfClass:[RNCWebViewImpl class]]) { \ + RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); \ + } else { \ + [view name]; \ + } \ + }]; \ +} +#define QUICK_RCT_EXPORT_COMMAND_METHOD_PARAMS(name, in_param, out_param) \ +RCT_EXPORT_METHOD(name:(nonnull NSNumber *)reactTag in_param) \ +{ \ +[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { \ + RNCWebViewImpl *view = (RNCWebViewImpl *)viewRegistry[reactTag]; \ + if (![view isKindOfClass:[RNCWebViewImpl class]]) { \ + RCTLogError(@"Invalid view returned from registry, expecting RNCWebView, got: %@", view); \ + } else { \ + [view name:out_param]; \ + } \ + }]; \ +} + +QUICK_RCT_EXPORT_COMMAND_METHOD(reload) +QUICK_RCT_EXPORT_COMMAND_METHOD(goBack) +QUICK_RCT_EXPORT_COMMAND_METHOD(goForward) +QUICK_RCT_EXPORT_COMMAND_METHOD(stopLoading) +QUICK_RCT_EXPORT_COMMAND_METHOD(requestFocus) + +QUICK_RCT_EXPORT_COMMAND_METHOD_PARAMS(postMessage, message:(NSString *)message, message) +QUICK_RCT_EXPORT_COMMAND_METHOD_PARAMS(injectJavaScript, script:(NSString *)script, script) + +RCT_EXPORT_METHOD(shouldStartLoadWithLockIdentifier:(BOOL)shouldStart + lockIdentifier:(double)lockIdentifier) { - _shouldStartLoadLock = [[NSConditionLock alloc] initWithCondition:arc4random()]; - _shouldStartLoad = YES; - request[@"lockIdentifier"] = @(_shouldStartLoadLock.condition); - callback(request); - - // Block the main thread for a maximum of 250ms until the JS thread returns - if ([_shouldStartLoadLock lockWhenCondition:0 beforeDate:[NSDate dateWithTimeIntervalSinceNow:.25]]) { - BOOL returnValue = _shouldStartLoad; - [_shouldStartLoadLock unlock]; - _shouldStartLoadLock = nil; - return returnValue; - } else { - RCTLogWarn(@"Did not receive response to shouldStartLoad in time, defaulting to YES"); - return YES; - } + [[RNCWebViewDecisionManager getInstance] setResult:shouldStart forLockIdentifier:(int)lockIdentifier]; } -RCT_EXPORT_METHOD(startLoadWithResult:(BOOL)result lockIdentifier:(NSInteger)lockIdentifier) +// Thanks to this guard, we won't compile this code when we build for the old architecture. +#ifdef RCT_NEW_ARCH_ENABLED +- (std::shared_ptr)getTurboModule: + (const facebook::react::ObjCTurboModule::InitParams &)params { - if ([_shouldStartLoadLock tryLockWhenCondition:lockIdentifier]) { - _shouldStartLoad = result; - [_shouldStartLoadLock unlockWithCondition:0]; - } else { - RCTLogWarn(@"startLoadWithResult invoked with invalid lockIdentifier: " - "got %lld, expected %lld", (long long)lockIdentifier, (long long)_shouldStartLoadLock.condition); - } + return std::make_shared(params); } +#endif @end diff --git a/bin/setup b/bin/setup deleted file mode 100755 index 38212df..0000000 --- a/bin/setup +++ /dev/null @@ -1,26 +0,0 @@ -#! /bin/bash - -# Node installed? -if ! [ -x "$(command -v node)" ]; then - echo 'Error: node is not installed.' >&2 - - if ! [ -x "$(command -v brew)" ]; then - echo 'Go here to install: https://nodejs.org/en/download/' - fi - - if [ -x "$(command -v brew)" ]; then - echo 'You have Homebrew installed, so run "brew install node".' - fi - - exit 1 -fi - -# React Native installed? -if ! [ -x "$(command -v react-native)" ]; then - echo 'Error: React Native is not installed.' >&2 - echo 'Go here: https://reactnative.dev/docs/getting-started.html' >&2 - echo 'Use the "Building Projects With Native Code" option.' - exit 1 -fi - -# TODO: Automate setup on new machines diff --git a/docs/Contributing.md b/docs/Contributing.md index 90669bb..a8db1b1 100644 --- a/docs/Contributing.md +++ b/docs/Contributing.md @@ -59,8 +59,7 @@ The Windows example app will be built, the Metro bundler will launch, and the ex In a new `react-native init` project, do this: ``` -$ yarn add ../react-native-webview -$ react-native link react-native-webview +$ yarn add ``` You may run into a problem where the `jest-haste-map` module map says react-native was added twice: @@ -83,11 +82,15 @@ And then re-run the packager: $ react-native start --reset-cache ``` -When you make a change, you'll probably need to unlink, remove, re-add, and re-link `react-native-webview`: +You may also see a console warning about "Invalid hook call," followed by a render error that "null is not an object (evaluating 'dispatcher.useRef')." Resolving this is similar to the above, but this time remove `react-native-webview/node_modules/react`. + +(if you remove `react` before `react-native`, you may see another render error for "View config getter callback for component 'RNCWebView' must be a function," just remove `react-native` as well to fix this) + +When you make a change, you'll probably need to remove and re-add `react-native-webview`: ``` -$ react-native unlink react-native-webview && yarn remove react-native-webview -$ yarn add ../react-native-webview && react-native link react-native-webview +$ yarn remove react-native-webview +$ yarn add ../react-native-webview ``` ## Notes diff --git a/docs/Custom-Android.md b/docs/Custom-Android.md index e873e90..47a3873 100644 --- a/docs/Custom-Android.md +++ b/docs/Custom-Android.md @@ -25,8 +25,8 @@ public class CustomWebViewManager extends RNCWebViewManager { } @Override - protected RNCWebView createRNCWebViewInstance(ThemedReactContext reactContext) { - return new CustomWebView(reactContext); + protected RNCWebView createViewInstance(ThemedReactContext reactContext) { + return super.createViewInstance(reactContext, new CustomWebView(reactContext)); } @Override @@ -35,7 +35,7 @@ public class CustomWebViewManager extends RNCWebViewManager { } @Override - protected void addEventEmitters(ThemedReactContext reactContext, WebView view) { + protected void addEventEmitters(ThemedReactContext reactContext, RNCWebView view) { view.setWebViewClient(new CustomWebViewClient()); } } diff --git a/docs/README.french.md b/docs/README.french.md index 0e5f30d..da434e8 100644 --- a/docs/README.french.md +++ b/docs/README.french.md @@ -1,81 +1,63 @@ +# React Native WebView -# React Native WebView - Une WebView moderne et multiplateforme pour React Native - -[![star this repo](http://githubbadges.com/star.svg?user=react-native-webview&repo=react-native-webview&style=flat)](https://github.com/react-native-webview/react-native-webview) +![star this repo](https://img.shields.io/github/stars/react-native-webview/react-native-webview?style=flat-square) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) -[![All Contributors](https://img.shields.io/badge/all_contributors-16-orange.svg?style=flat-square)](#contributors) -[![Known Vulnerabilities](https://snyk.io/test/github/react-native-webview/react-native-webview/badge.svg?style=flat-square)](https://snyk.io/test/github/react-native-webview/react-native-webview) [![NPM Version](https://img.shields.io/npm/v/react-native-webview.svg?style=flat-square)](https://www.npmjs.com/package/react-native-webview) -[![Lean Core Extracted](https://img.shields.io/badge/Lean%20Core-Extracted-brightgreen.svg?style=flat-square)][lean-core-issue] - -**React Native WebView** est une WebView moderne, soutenue et multiplateforme pour React Native. Elle est destinée à remplacer la WebView built-in (qui va être [retiré du noyau](https://github.com/react-native-community/discussions-and-proposals/pull/3)). +![Npm Downloads](https://img.shields.io/npm/dm/react-native-webview.svg) -## Mainteneurs principaux - Compagnies sponsors +**React Native WebView** est un composent WebView maintenu par la communauté. Il existe en remplacement au composant WebView de React Native (qui a [été retiré du core](https://github.com/react-native-community/discussions-and-proposals/pull/3)). -_Ce projet est maintenu gratuitement par ces personnes durant leur temps libre et leur temps de travail._ +### Contributeurs -- [Thibault Malbranche](https://github.com/Titozzz) ([Twitter @titozzz](https://twitter.com/titozzz)) de [Brigad](https://brigad.co/about) -- [Jamon Holmgren](https://github.com/jamonholmgren) ([Twitter @jamonholmgren](https://twitter.com/jamonholmgren)) de [Infinite Red](https://infinite.red/react-native) -- [Alexander Sklar](https://github.com/asklar) ([Twitter @alexsklar](https://twitter.com/alexsklar)) de [React Native Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) -- [Chiara Mooney](https://github.com/chiaramooney) de [React Native Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) +**Merci beaucoup aux entreprises** pour nous permettre de travailler sur de l'open source. +Également beaucoup de temps personnel est investi pour maintenir ce projet, n'hésitez pas à nous sponsoriser, **ça aide vraiment.** -## Plateformes supportées +- [Thibault Malbranche](https://github.com/Titozzz) ([Twitter @titozzz](https://twitter.com/titozzz)) de [Brigad](https://www.brigad.co/fr-fr/about-us) +[*Me Sponsor* ❤️ !](https://github.com/sponsors/Titozzz) -- [x] iOS -- [x] Android -- [x] macOS -- [x] Windows +Windows et macOS sont maintenues par Microsoft, notamment: +- [Alexander Sklar](https://github.com/asklar) ([Twitter @alexsklar](https://twitter.com/alexsklar)) de [React Native for Windows](https://microsoft.github.io/react-native-windows/) +- [Chiara Mooney](https://github.com/chiaramooney) de [React Native for Windows @ Microsoft](https://microsoft.github.io/react-native-windows/) -_Note: Le support de React Native WebView par Expo a débuté avec [Expo SDK v33.0.0](https://blog.expo.io/expo-sdk-v33-0-0-is-now-available-52d1c99dfe4c)._ +Grand merci à [Jamon Holmgren](https://github.com/jamonholmgren) de [Infinite Red](https://infinite.red) pour l'aide apportée lorsqu'il avait plus de temps disponible. -## Débuter +### Disclaimer -Lisez attentivement notre guide (exclusivement en anglais) [Getting Started Guide](docs/Getting-Started.md). Si la moindre étape ne semble pas claire, merci de créer une **issue** détaillée. +Maintenir la WebView est très compliqué, à cause de ses nombreux usages (rendering svgs, pdfs, login flows, et autres). On supporte également de nombreuses plateformes et les deux architectures de React Native. -## Versionnage +Depuis que la WebView a été retirée du core, près de 500 PR ont été mergées. +En considérant que nous possédons un temps limité, les issues github serviront principalement comme lieu d'échange pour la communauté, tandis que **nous prioriserons les reviews et les merges de pull requests** -Ce projet suit la [gestion sémantique de version](https://semver.org/). Nous n'hésitons pas à publier des modifications "breaking-change", mais elles seront intégrées dans une version majeure. +### Platform compatibles +Ce projet est compatible avec **iOS**, **Android**, **Windows** et **macOS**. +Ce projet supporte à la fois **l'ancienne** (paper) **et la nouvelle architecture** (fabric). +Ce projet est compatible avec [expo](https://docs.expo.dev/versions/latest/sdk/webview/). +## Débuter -**Historique des versions majeures:** - -Current Version: ![version](https://img.shields.io/npm/v/react-native-webview.svg) - -- [11.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v11.0.0) - Android setSupportMultipleWindows. -- [10.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v10.0.0) - Le plugin Android Gradle n'est obligatoire qu'en ouvrant le projet en mode **stand-alone** -- [9.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v9.0.0) - Les mises à jour des props via injectedJavaScript ne sont plus immuables -- [8.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v8.0.0) - Désormais onNavigationStateChange se déclenche au changement du hash de l'url -- [7.0.1](https://github.com/react-native-webview/react-native-webview/releases/tag/v7.0.1) - Suppression de UIWebView -- [6.0.**2**](https://github.com/react-native-webview/react-native-webview/releases/tag/v6.0.2) - Mise à jour d'AndroidX. Soyez attentif à l'activer dans vos projet via `android/gradle.properties`. Voir [Getting Started Guide](docs/Getting-Started.md). -- [5.0.**1**](https://github.com/react-native-webview/react-native-webview/releases/tag/v5.0.0) - Remaniement de l'ancienne implémentation de postMessage pour communiquer de la webview à react native. -- [4.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v4.0.0) - Ajout d'un cache (activé par défaut). -- [3.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v3.0.0) - WKWebview : Ajout d'un pool de processus partagé pour que les cookies et localStorage soient partagés entre les webviews dans iOS (activé par défaut). -- [2.0.0](https://github.com/react-native-webview/react-native-webview/releases/tag/v2.0.0) - Première version, il s'agit d'une réplique du composant webview de base. +Lisez attentivement notre guide (exclusivement en anglais) [Getting Started Guide](docs/Getting-Started.md). Si la moindre étape ne semble pas claire, merci de créer une **issue** détaillée. -**A venir:** +## Versionnage -- Suppression de this.webView.postMessage() (jamais documenté et moins dynamique que injectJavascript) -> [comment migrer](https://github.com/react-native-webview/react-native-webview/issues/809) -- Réécriture du code Kotlin -- Peut-être réécrutire du code Swift +Ce projet suit la [gestion sémantique de version](https://semver.org/). Nous n'hésitons pas à publier des modifications "breaking-change", mais elles seront intégrées dans une version majeure. ## Utilisation Importez le composant `WebView` de `react-native-webview` et utilisez le de la manière suivante : -```jsx +```tsx import React, { Component } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { WebView } from 'react-native-webview'; // ... -class MyWebComponent extends Component { - render() { - return ; - } +const MyWebComponent = () => { + return ; } ``` + Pour plus de détails, lisez la [Référence API](./docs/Reference.md) et le [Guide](./docs/Guide.md). Si vous êtes intéressé à contribuer, lisez le [Guide de contribution](./docs/Contributing.md). ## Problèmes communs @@ -87,28 +69,9 @@ Pour plus de détails, lisez la [Référence API](./docs/Reference.md) et le [Gu Voir [Contributing.md](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Contributing.md) -## Contributeurs - -Un grand remerciement aux contributeurs ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key-)): - - - -
Thibault Malbranche
Thibault Malbranche

💻 🤔 👀 📖 🚧 ⚠️ 🚇 💬
Jamon Holmgren
Jamon Holmgren

💻 🤔 👀 📖 🚧 ⚠️ 💡 💬
Andrei Pfeiffer
Andrei Pfeiffer

💻 👀 🤔
Michael Diarmid
Michael Diarmid

💻 👀 🤔 🔧
Scott Mathson
Scott Mathson

💻 📖
Margaret
Margaret

💻 📖
Jordan Sexton
Jordan Sexton

💻 📖
Malcolm Scruggs
Malcolm Scruggs

💻 🔧 ⚠️
Momazo7u7
Momazo7u7

📖
Marco
Marco

📖
Julien Eluard
Julien Eluard

📖
Jian Wei
Jian Wei

💻 📖
Sergei Butko
Sergei Butko

📖
TMomemt
TMomemt

💻
Eric Lewis
Eric Lewis

💻 📖
Daniel Vicory
Daniel Vicory

💻 📖
- - - - -Ce projet suit les spécifications [all-contributors](https://github.com/all-contributors/all-contributors). Les contributions de toute nature sont les bienvenues ! - -## License - -MIT - ## Translations This readme is available in: - [English](../README.md) - [Brazilian portuguese](README.portuguese.md) - -[lean-core-issue]: https://github.com/facebook/react-native/issues/23313 diff --git a/docs/Reference.md b/docs/Reference.md index b3157ed..c97ca91 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -36,7 +36,6 @@ This document lays out the current public properties and methods for the React N - [`domStorageEnabled`](Reference.md#domstorageenabled) - [`javaScriptEnabled`](Reference.md#javascriptenabled) - [`javaScriptCanOpenWindowsAutomatically`](Reference.md#javascriptcanopenwindowsautomatically) -- [`androidHardwareAccelerationDisabled`](Reference.md#androidHardwareAccelerationDisabled) - [`androidLayerType`](Reference.md#androidLayerType) - [`mixedContentMode`](Reference.md#mixedcontentmode) - [`thirdPartyCookiesEnabled`](Reference.md#thirdpartycookiesenabled) @@ -60,8 +59,6 @@ This document lays out the current public properties and methods for the React N - [`allowFileAccessFromFileURLs`](Reference.md#allowFileAccessFromFileURLs) - [`allowUniversalAccessFromFileURLs`](Reference.md#allowUniversalAccessFromFileURLs) - [`allowingReadAccessToURL`](Reference.md#allowingReadAccessToURL) -- [`url`](Reference.md#url) -- [`html`](Reference.md#html) - [`keyboardDisplayRequiresUserAction`](Reference.md#keyboardDisplayRequiresUserAction) - [`hideKeyboardAccessoryView`](Reference.md#hidekeyboardaccessoryview) - [`allowsBackForwardNavigationGestures`](Reference.md#allowsbackforwardnavigationgestures) @@ -581,13 +578,13 @@ url ### `onContentProcessDidTerminate`[⬆](#props-index) -Function that is invoked when the `WebView` content process is terminated. +Function that is invoked when the `WebView` content process is terminated. | Type | Required | Platform | | -------- | -------- | ----------------------- | | function | No | iOS and macOS WKWebView | -iOS Web views use a separate process to render and manage web content. WebKit calls this method when the process for the specified web view terminates for any reason. +iOS Web views use a separate process to render and manage web content. WebKit calls this method when the process for the specified web view terminates for any reason. The reason is not necessarily a crash. For instance, since iOS WebViews are not included in the total RAM of the app, they can be terminated independently of the app to liberate memory for new apps the user is opening. It's not unexpected to have WebViews get terminated after a while in the background. Example: @@ -850,16 +847,6 @@ A Boolean value indicating whether JavaScript can open windows without user inte --- -### `androidHardwareAccelerationDisabled`[⬆](#props-index) - -**Deprecated.** Use the `androidLayerType` prop instead. - -| Type | Required | Platform | -| ---- | -------- | -------- | -| bool | No | Android | - ---- - ### `androidLayerType`[⬆](#props-index) Specifies the layer type. @@ -870,7 +857,6 @@ Possible values for `androidLayerType` are: - `software` - The view has a software layer. A software layer is backed by a bitmap and causes the view to be rendered using Android's software rendering pipeline, even if hardware acceleration is enabled. - `hardware` - The view has a hardware layer. A hardware layer is backed by a hardware specific texture and causes the view to be rendered using Android's hardware rendering pipeline, but only if hardware acceleration is turned on for the view hierarchy. -Avoid setting both `androidLayerType` and `androidHardwareAccelerationDisabled` props at the same time, as this may cause undefined behaviour. | Type | Required | Platform | | ------ | -------- | -------- | @@ -1072,7 +1058,7 @@ Boolean value that determines whether scrolling is enabled in the `WebView`. The ### `nestedScrollEnabled`[⬆](#props-index) -Boolean value that determines whether scrolling is possible in the `WebView` when used inside a `ScrollView` on Android. The default value is `false`. +Boolean value that determines whether scrolling is possible in the `WebView` when used inside a `ScrollView` on Android. The default value is `false`. Setting this to `true` will prevent the `ScrollView` to scroll when scrolling from inside the `WebView`. @@ -1094,7 +1080,7 @@ Sets whether the WebView should use its built-in zoom mechanisms. The default va ### `setDisplayZoomControls`[⬆](#props-index) -Sets whether the WebView should display on-screen zoom controls when using the built-in zoom mechanisms (see `setBuiltInZoomControls`). The default value is `false`. +Sets whether the WebView should display on-screen zoom controls when using the built-in zoom mechanisms (see `setBuiltInZoomControls`). The default value is `false`. | Type | Required | Platform | | ---- | -------- | ------------- | @@ -1173,26 +1159,6 @@ A String value that indicates which URLs the WebView's file can then reference i --- -### `url`[⬆](#props-index) - -**Deprecated.** Use the `source` prop instead. - -| Type | Required | -| ------ | -------- | -| string | No | - ---- - -### `html`[⬆](#props-index) - -**Deprecated.** Use the `source` prop instead. - -| Type | Required | -| ------ | -------- | -| string | No | - ---- - ### `keyboardDisplayRequiresUserAction`[⬆](#props-index) If false, web content can programmatically display the keyboard. The default value is `true`. @@ -1531,7 +1497,7 @@ Function called when a custom menu item is selected. It receives a Native event | function | No | iOS | ```javascript - { const { label } = webViewEvent.nativeEvent; // The name of the menu item, i.e. 'Tweet' @@ -1601,8 +1567,8 @@ This is the message that is shown in the Toast when the webview is unable to dow Whether or not the Webview can play media protected by DRM. Default is false. /!\ Setting this to false won't revoke the permission already granted to the current webpage. In order to do so, you'd have to reload the page as well. /!\ -| Type | Required | Platform | -| ------ | -------- | -------- | +| Type | Required | Platform | +| ------- | -------- | -------- | | boolean | No | Android | ## Methods diff --git a/docs/Reference.portuguese.md b/docs/Reference.portuguese.md index b50a5bc..a415391 100644 --- a/docs/Reference.portuguese.md +++ b/docs/Reference.portuguese.md @@ -36,7 +36,6 @@ Este documento apresenta as propriedades e métodos públicos para o React Nativ - [`domStorageEnabled`](Reference.portuguese.md#domstorageenabled) - [`javaScriptEnabled`](Reference.portuguese.md#javascriptenabled) - [`javaScriptCanOpenWindowsAutomatically`](Reference.portuguese.md#javascriptcanopenwindowsautomatically) -- [`androidHardwareAccelerationDisabled`](Reference.portuguese.md#androidHardwareAccelerationDisabled) - [`androidLayerType`](Reference.portuguese.md#androidLayerType) - [`mixedContentMode`](Reference.portuguese.md#mixedcontentmode) - [`thirdPartyCookiesEnabled`](Reference.portuguese.md#thirdpartycookiesenabled) @@ -60,8 +59,6 @@ Este documento apresenta as propriedades e métodos públicos para o React Nativ - [`allowFileAccessFromFileURLs`](Reference.portuguese.md#allowFileAccessFromFileURLs) - [`allowUniversalAccessFromFileURLs`](Reference.portuguese.md#allowUniversalAccessFromFileURLs) - [`allowingReadAccessToURL`](Reference.portuguese.md#allowingReadAccessToURL) -- [`url`](Reference.portuguese.md#url) -- [`html`](Reference.portuguese.md#html) - [`keyboardDisplayRequiresUserAction`](Reference.portuguese.md#keyboardDisplayRequiresUserAction) - [`hideKeyboardAccessoryView`](Reference.portuguese.md#hidekeyboardaccessoryview) - [`allowsBackForwardNavigationGestures`](Reference.portuguese.md#allowsbackforwardnavigationgestures) @@ -841,16 +838,6 @@ Um valor booleano que indica se o JavaScript pode abrir janelas sem interação --- -### `androidHardwareAccelerationDisabled`[⬆](#props-index) - -**Descontinuado.** Em vez disso, use o prop `androidLayerType`. - -| Tipo | Requerido | Plataforma | -| ---- | --------- | ---------- | -| bool | Não | Android | - ---- - ### `androidLayerType`[⬆](#props-index) Especifica o tipo de camada. @@ -861,8 +848,6 @@ Os valores possíveis para `androidLayerType` são: - `software` - A visão tem uma camada de software. Uma camada de software é apoiada por um bitmap e faz com que a exibição seja renderizada usando o pipeline de renderização de software do Android, mesmo se a aceleração de hardware estiver habilitada. - `hardware` - A visualização tem uma camada de hardware. Uma camada de hardware é apoiada por uma textura específica de hardware e faz com que a exibição seja renderizada usando o pipeline de renderização de hardware do Android, mas somente se a aceleração de hardware estiver ativada para a hierarquia de exibição. -Evite definir as props `androidLayerType` e `androidHardwareAccelerationDisabled` ao mesmo tempo, pois isso pode causar um comportamento indefinido. - | Tipo | Requerido | Plataforma | | ------ | --------- | ---------- | | string | Não | Android | @@ -1163,26 +1148,6 @@ Um valor String que indica quais URLs o arquivo da WebView pode referenciar em s --- -### `url`[⬆](#props-index) - -**Descontinuado.** Em vez disso, use a propriedade `source`. - -| Tipo | Requerido | -| ------ | --------- | -| string | Não | - ---- - -### `html`[⬆](#props-index) - -**Descontinuado.** Em vez disso, use a propriedade `source`. - -| Tipo | Requerido | -| ------ | --------- | -| string | Não | - ---- - ### `keyboardDisplayRequiresUserAction`[⬆](#props-index) Se false, o conteúdo da Web pode exibir programaticamente o teclado. O valor padrão é `true`. @@ -1521,7 +1486,7 @@ Função chamada quando um item de menu personalizado é selecionado. Ele recebe | function | Não | iOS | ```javascript - { const { label } = webViewEvent.nativeEvent; // O nome do item de menu, ou seja, 'Tweet' diff --git a/example/App.tsx b/example/App.tsx index 497b8a3..ebb4ae3 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -104,8 +104,8 @@ const TESTS = { } }; -type Props = {}; -type State = {restarting: boolean; currentTest: Object}; +interface Props {} +interface State {restarting: boolean; currentTest: Object} export default class App extends Component { state = { diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 771053d..ac1b10a 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -3,6 +3,7 @@ # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. + # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html @@ -30,5 +31,15 @@ android.enableJetifier=true # Native defaults to. To disable Flipper, set it to `false`. #FLIPPER_VERSION=0.125.0 +# Enable Fabric at runtime. +#USE_FABRIC=1 + +# Enable new architecture, i.e. Fabric + TurboModule - implies USE_FABRIC=1. +# Note that this is incompatible with web debugging. +newArchEnabled=false + # Uncomment the line below if building react-native from source #ANDROID_NDK_VERSION=21.4.7075529 + +# Version of Kotlin to build against. +#KOTLIN_VERSION=1.7.10 diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 2e6e589..ae04661 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/example/examples/Downloads.tsx b/example/examples/Downloads.tsx index ebea2cb..13c1d5f 100644 --- a/example/examples/Downloads.tsx +++ b/example/examples/Downloads.tsx @@ -27,8 +27,8 @@ const HTML = ` `; -type Props = {}; -type State = {}; +interface Props {} +interface State {} export default class Downloads extends Component { state = {}; diff --git a/example/examples/Messaging.tsx b/example/examples/Messaging.tsx index afd6a60..46680d7 100644 --- a/example/examples/Messaging.tsx +++ b/example/examples/Messaging.tsx @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {View, Alert} from 'react-native'; +import {View, Alert, TextInput} from 'react-native'; import WebView from 'react-native-webview'; @@ -21,13 +21,20 @@ const HTML = `\n

+

Nothing received yet

+ @@ -48,6 +55,9 @@ export default class Messaging extends Component { render() { return ( + { + this.webView.current.postMessage(e.nativeEvent.text); + }}/> { state = {}; @@ -15,6 +15,13 @@ export default class NativeWebpage extends Component { { + console.log("onShouldStartLoadWithRequest", event); + return true; + }} + onLoadStart={(event) => { + console.log("onLoadStart", event.nativeEvent); + }} /> ); diff --git a/example/ios/.xcode.env b/example/ios/.xcode.env new file mode 100644 index 0000000..d85cff7 --- /dev/null +++ b/example/ios/.xcode.env @@ -0,0 +1 @@ +export NODE_BINARY=/usr/local/bin/node diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index b7b149e..2a1e1b0 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,290 +1,321 @@ PODS: - boost (1.76.0) - DoubleConversion (1.1.6) - - FBLazyVector (0.68.5) - - FBReactNativeSpec (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - RCTRequired (= 0.68.5) - - RCTTypeSafety (= 0.68.5) - - React-Core (= 0.68.5) - - React-jsi (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) + - FBLazyVector (0.71.3) + - FBReactNativeSpec (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - RCTRequired (= 0.71.3) + - RCTTypeSafety (= 0.71.3) + - React-Core (= 0.71.3) + - React-jsi (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) - fmt (6.2.1) - glog (0.3.5) - - RCT-Folly (2021.06.28.00-v2): + - RCT-Folly (2021.07.22.00): - boost - DoubleConversion - fmt (~> 6.2.1) - glog - - RCT-Folly/Default (= 2021.06.28.00-v2) - - RCT-Folly/Default (2021.06.28.00-v2): + - RCT-Folly/Default (= 2021.07.22.00) + - RCT-Folly/Default (2021.07.22.00): - boost - DoubleConversion - fmt (~> 6.2.1) - glog - - RCTRequired (0.68.5) - - RCTTypeSafety (0.68.5): - - FBLazyVector (= 0.68.5) - - RCT-Folly (= 2021.06.28.00-v2) - - RCTRequired (= 0.68.5) - - React-Core (= 0.68.5) - - React (0.68.5): - - React-Core (= 0.68.5) - - React-Core/DevSupport (= 0.68.5) - - React-Core/RCTWebSocket (= 0.68.5) - - React-RCTActionSheet (= 0.68.5) - - React-RCTAnimation (= 0.68.5) - - React-RCTBlob (= 0.68.5) - - React-RCTImage (= 0.68.5) - - React-RCTLinking (= 0.68.5) - - React-RCTNetwork (= 0.68.5) - - React-RCTSettings (= 0.68.5) - - React-RCTText (= 0.68.5) - - React-RCTVibration (= 0.68.5) - - React-callinvoker (0.68.5) - - React-Codegen (0.68.5): - - FBReactNativeSpec (= 0.68.5) - - RCT-Folly (= 2021.06.28.00-v2) - - RCTRequired (= 0.68.5) - - RCTTypeSafety (= 0.68.5) - - React-Core (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-Core (0.68.5): + - RCTRequired (0.71.3) + - RCTTypeSafety (0.71.3): + - FBLazyVector (= 0.71.3) + - RCTRequired (= 0.71.3) + - React-Core (= 0.71.3) + - React (0.71.3): + - React-Core (= 0.71.3) + - React-Core/DevSupport (= 0.71.3) + - React-Core/RCTWebSocket (= 0.71.3) + - React-RCTActionSheet (= 0.71.3) + - React-RCTAnimation (= 0.71.3) + - React-RCTBlob (= 0.71.3) + - React-RCTImage (= 0.71.3) + - React-RCTLinking (= 0.71.3) + - React-RCTNetwork (= 0.71.3) + - React-RCTSettings (= 0.71.3) + - React-RCTText (= 0.71.3) + - React-RCTVibration (= 0.71.3) + - React-callinvoker (0.71.3) + - React-Codegen (0.71.3): + - FBReactNativeSpec + - RCT-Folly + - RCTRequired + - RCTTypeSafety + - React-Core + - React-jsc + - React-jsi + - React-jsiexecutor + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - React-Core (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-Core/Default (= 0.68.5) - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.71.3) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/CoreModulesHeaders (0.68.5): + - React-Core/CoreModulesHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/Default (0.68.5): + - React-Core/Default (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - RCT-Folly (= 2021.07.22.00) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/DevSupport (0.68.5): + - React-Core/DevSupport (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-Core/Default (= 0.68.5) - - React-Core/RCTWebSocket (= 0.68.5) - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-jsinspector (= 0.68.5) - - React-perflogger (= 0.68.5) + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.71.3) + - React-Core/RCTWebSocket (= 0.71.3) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-jsinspector (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTActionSheetHeaders (0.68.5): + - React-Core/RCTActionSheetHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTAnimationHeaders (0.68.5): + - React-Core/RCTAnimationHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTBlobHeaders (0.68.5): + - React-Core/RCTBlobHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTImageHeaders (0.68.5): + - React-Core/RCTImageHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTLinkingHeaders (0.68.5): + - React-Core/RCTLinkingHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTNetworkHeaders (0.68.5): + - React-Core/RCTNetworkHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTSettingsHeaders (0.68.5): + - React-Core/RCTSettingsHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTTextHeaders (0.68.5): + - React-Core/RCTTextHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTVibrationHeaders (0.68.5): + - React-Core/RCTVibrationHeaders (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) + - RCT-Folly (= 2021.07.22.00) - React-Core/Default - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-Core/RCTWebSocket (0.68.5): + - React-Core/RCTWebSocket (0.71.3): - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-Core/Default (= 0.68.5) - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsiexecutor (= 0.68.5) - - React-perflogger (= 0.68.5) + - RCT-Folly (= 2021.07.22.00) + - React-Core/Default (= 0.71.3) + - React-cxxreact (= 0.71.3) + - React-jsc + - React-jsi (= 0.71.3) + - React-jsiexecutor (= 0.71.3) + - React-perflogger (= 0.71.3) - Yoga - - React-CoreModules (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - RCTTypeSafety (= 0.68.5) - - React-Codegen (= 0.68.5) - - React-Core/CoreModulesHeaders (= 0.68.5) - - React-jsi (= 0.68.5) - - React-RCTImage (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-cxxreact (0.68.5): - - boost (= 1.76.0) - - DoubleConversion - - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-callinvoker (= 0.68.5) - - React-jsi (= 0.68.5) - - React-jsinspector (= 0.68.5) - - React-logger (= 0.68.5) - - React-perflogger (= 0.68.5) - - React-runtimeexecutor (= 0.68.5) - - React-jsi (0.68.5): + - React-CoreModules (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.71.3) + - React-Codegen (= 0.71.3) + - React-Core/CoreModulesHeaders (= 0.71.3) + - React-jsi (= 0.71.3) + - React-RCTBlob + - React-RCTImage (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-cxxreact (0.71.3): - boost (= 1.76.0) - DoubleConversion - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-jsi/Default (= 0.68.5) - - React-jsi/Default (0.68.5): + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.71.3) + - React-jsi (= 0.71.3) + - React-jsinspector (= 0.71.3) + - React-logger (= 0.71.3) + - React-perflogger (= 0.71.3) + - React-runtimeexecutor (= 0.71.3) + - React-jsc (0.71.3): + - React-jsc/Fabric (= 0.71.3) + - React-jsi (= 0.71.3) + - React-jsc/Fabric (0.71.3): + - React-jsi (= 0.71.3) + - React-jsi (0.71.3): - boost (= 1.76.0) - DoubleConversion - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-jsiexecutor (0.68.5): + - RCT-Folly (= 2021.07.22.00) + - React-jsiexecutor (0.71.3): - DoubleConversion - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-perflogger (= 0.68.5) - - React-jsinspector (0.68.5) - - React-logger (0.68.5): + - RCT-Folly (= 2021.07.22.00) + - React-cxxreact (= 0.71.3) + - React-jsi (= 0.71.3) + - React-perflogger (= 0.71.3) + - React-jsinspector (0.71.3) + - React-logger (0.71.3): - glog - - react-native-webview (11.26.0): + - react-native-webview (12.0.0-rc.2): + - React-Core + - React-perflogger (0.71.3) + - React-RCTActionSheet (0.71.3): + - React-Core/RCTActionSheetHeaders (= 0.71.3) + - React-RCTAnimation (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.71.3) + - React-Codegen (= 0.71.3) + - React-Core/RCTAnimationHeaders (= 0.71.3) + - React-jsi (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-RCTAppDelegate (0.71.3): + - RCT-Folly + - RCTRequired + - RCTTypeSafety - React-Core - - React-perflogger (0.68.5) - - React-RCTActionSheet (0.68.5): - - React-Core/RCTActionSheetHeaders (= 0.68.5) - - React-RCTAnimation (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - RCTTypeSafety (= 0.68.5) - - React-Codegen (= 0.68.5) - - React-Core/RCTAnimationHeaders (= 0.68.5) - - React-jsi (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-RCTBlob (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - React-Codegen (= 0.68.5) - - React-Core/RCTBlobHeaders (= 0.68.5) - - React-Core/RCTWebSocket (= 0.68.5) - - React-jsi (= 0.68.5) - - React-RCTNetwork (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-RCTImage (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - RCTTypeSafety (= 0.68.5) - - React-Codegen (= 0.68.5) - - React-Core/RCTImageHeaders (= 0.68.5) - - React-jsi (= 0.68.5) - - React-RCTNetwork (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-RCTLinking (0.68.5): - - React-Codegen (= 0.68.5) - - React-Core/RCTLinkingHeaders (= 0.68.5) - - React-jsi (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-RCTNetwork (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - RCTTypeSafety (= 0.68.5) - - React-Codegen (= 0.68.5) - - React-Core/RCTNetworkHeaders (= 0.68.5) - - React-jsi (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-RCTSettings (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - RCTTypeSafety (= 0.68.5) - - React-Codegen (= 0.68.5) - - React-Core/RCTSettingsHeaders (= 0.68.5) - - React-jsi (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-RCTText (0.68.5): - - React-Core/RCTTextHeaders (= 0.68.5) - - React-RCTVibration (0.68.5): - - RCT-Folly (= 2021.06.28.00-v2) - - React-Codegen (= 0.68.5) - - React-Core/RCTVibrationHeaders (= 0.68.5) - - React-jsi (= 0.68.5) - - ReactCommon/turbomodule/core (= 0.68.5) - - React-runtimeexecutor (0.68.5): - - React-jsi (= 0.68.5) - - ReactCommon/turbomodule/core (0.68.5): + - ReactCommon/turbomodule/core + - React-RCTBlob (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - React-Codegen (= 0.71.3) + - React-Core/RCTBlobHeaders (= 0.71.3) + - React-Core/RCTWebSocket (= 0.71.3) + - React-jsi (= 0.71.3) + - React-RCTNetwork (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-RCTImage (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.71.3) + - React-Codegen (= 0.71.3) + - React-Core/RCTImageHeaders (= 0.71.3) + - React-jsi (= 0.71.3) + - React-RCTNetwork (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-RCTLinking (0.71.3): + - React-Codegen (= 0.71.3) + - React-Core/RCTLinkingHeaders (= 0.71.3) + - React-jsi (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-RCTNetwork (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.71.3) + - React-Codegen (= 0.71.3) + - React-Core/RCTNetworkHeaders (= 0.71.3) + - React-jsi (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-RCTSettings (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - RCTTypeSafety (= 0.71.3) + - React-Codegen (= 0.71.3) + - React-Core/RCTSettingsHeaders (= 0.71.3) + - React-jsi (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-RCTText (0.71.3): + - React-Core/RCTTextHeaders (= 0.71.3) + - React-RCTVibration (0.71.3): + - RCT-Folly (= 2021.07.22.00) + - React-Codegen (= 0.71.3) + - React-Core/RCTVibrationHeaders (= 0.71.3) + - React-jsi (= 0.71.3) + - ReactCommon/turbomodule/core (= 0.71.3) + - React-runtimeexecutor (0.71.3): + - React-jsi (= 0.71.3) + - ReactCommon/turbomodule/bridging (0.71.3): + - DoubleConversion + - glog + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.71.3) + - React-Core (= 0.71.3) + - React-cxxreact (= 0.71.3) + - React-jsi (= 0.71.3) + - React-logger (= 0.71.3) + - React-perflogger (= 0.71.3) + - ReactCommon/turbomodule/core (0.71.3): - DoubleConversion - glog - - RCT-Folly (= 2021.06.28.00-v2) - - React-callinvoker (= 0.68.5) - - React-Core (= 0.68.5) - - React-cxxreact (= 0.68.5) - - React-jsi (= 0.68.5) - - React-logger (= 0.68.5) - - React-perflogger (= 0.68.5) + - RCT-Folly (= 2021.07.22.00) + - React-callinvoker (= 0.71.3) + - React-Core (= 0.71.3) + - React-cxxreact (= 0.71.3) + - React-jsi (= 0.71.3) + - React-logger (= 0.71.3) + - React-perflogger (= 0.71.3) - ReactTestApp-DevSupport (2.3.2): - React-Core - React-jsi @@ -304,10 +335,10 @@ DEPENDENCIES: - React-callinvoker (from `../../node_modules/react-native/ReactCommon/callinvoker`) - React-Codegen (from `build/generated/ios`) - React-Core (from `../../node_modules/react-native/`) - - React-Core/DevSupport (from `../../node_modules/react-native/`) - React-Core/RCTWebSocket (from `../../node_modules/react-native/`) - React-CoreModules (from `../../node_modules/react-native/React/CoreModules`) - React-cxxreact (from `../../node_modules/react-native/ReactCommon/cxxreact`) + - React-jsc (from `../../node_modules/react-native/ReactCommon/jsc`) - React-jsi (from `../../node_modules/react-native/ReactCommon/jsi`) - React-jsiexecutor (from `../../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`) @@ -316,6 +347,7 @@ DEPENDENCIES: - React-perflogger (from `../../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../../node_modules/react-native/Libraries/NativeAnimation`) + - React-RCTAppDelegate (from `../../node_modules/react-native/Libraries/AppDelegate`) - React-RCTBlob (from `../../node_modules/react-native/Libraries/Blob`) - React-RCTImage (from `../../node_modules/react-native/Libraries/Image`) - React-RCTLinking (from `../../node_modules/react-native/Libraries/LinkingIOS`) @@ -362,6 +394,8 @@ EXTERNAL SOURCES: :path: "../../node_modules/react-native/React/CoreModules" React-cxxreact: :path: "../../node_modules/react-native/ReactCommon/cxxreact" + React-jsc: + :path: "../../node_modules/react-native/ReactCommon/jsc" React-jsi: :path: "../../node_modules/react-native/ReactCommon/jsi" React-jsiexecutor: @@ -378,6 +412,8 @@ EXTERNAL SOURCES: :path: "../../node_modules/react-native/Libraries/ActionSheetIOS" React-RCTAnimation: :path: "../../node_modules/react-native/Libraries/NativeAnimation" + React-RCTAppDelegate: + :path: "../../node_modules/react-native/Libraries/AppDelegate" React-RCTBlob: :path: "../../node_modules/react-native/Libraries/Blob" React-RCTImage: @@ -404,41 +440,43 @@ EXTERNAL SOURCES: :path: "../../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - boost: a7c83b31436843459a1961bfd74b96033dc77234 - DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 - FBLazyVector: 2b47ff52037bd9ae07cc9b051c9975797814b736 - FBReactNativeSpec: 077145af227b87804441c945101b5587c04ad00c + boost: 57d2868c099736d80fcd648bf211b4431e51a558 + DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 + FBLazyVector: 60195509584153283780abdac5569feffb8f08cc + FBReactNativeSpec: 5b217c2677f8edae343b6646dad608d5d3147fc0 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - glog: 476ee3e89abb49e07f822b48323c51c57124b572 - RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8 - RCTRequired: 0f06b6068f530932d10e1a01a5352fad4eaacb74 - RCTTypeSafety: b0ee81f10ef1b7d977605a2b266823dabd565e65 - React: 3becd12bd51ea8a43bdde7e09d0f40fba7820e03 - React-callinvoker: 11abfff50e6bf7a55b3a90b4dc2187f71f224593 - React-Codegen: f8946ce0768fb8e92e092e30944489c4b2955b2d - React-Core: 203cdb6ee2657b198d97d41031c249161060e6ca - React-CoreModules: 6eb0c06a4a223fde2cb6a8d0f44f58b67e808942 - React-cxxreact: afb0c6c07d19adbd850747fedeac20c6832d40b9 - React-jsi: 14d37a6db2af2c1a49f6f5c2e4ee667c364ae45c - React-jsiexecutor: 45c0496ca8cef6b02d9fa0274c25cf458fe91a56 - React-jsinspector: eb202e43b3879aba9a14f3f65788aec85d4e1ea9 - React-logger: 98f663b292a60967ebbc6d803ae96c1381183b6d - react-native-webview: 994b9f8fbb504d6314dc40d83f94f27c6831b3bf - React-perflogger: 0458a87ea9a7342079e7a31b0d32b3734fb8415f - React-RCTActionSheet: 22538001ea2926dea001111dd2846c13a0730bc9 - React-RCTAnimation: 732ce66878d4aa151d56a0d142b1105aa12fd313 - React-RCTBlob: 9cb9e3e9a41d27be34aaf89b0e0f52c7ca415d57 - React-RCTImage: 6bd16627eb9c4bb79903c4cdec7c551266ee1a5b - React-RCTLinking: e9edfc8919c8fa9a3f3c7b34362811f58a2ebba4 - React-RCTNetwork: 880eccd21bbe2660a0b63da5ccba75c46eceeaa6 - React-RCTSettings: 8c85d8188c97d6c6bd470af6631a6c4555b79bb3 - React-RCTText: bbd275ee287730c5acbab1aadc0db39c25c5c64e - React-RCTVibration: 9819a3bf6230e4b2a99877c21268b0b2416157a1 - React-runtimeexecutor: b1f1995089b90696dbc2a7ffe0059a80db5c8eb1 - ReactCommon: 149e2c0acab9bac61378da0db5b2880a1b5ff59b + glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b + RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 + RCTRequired: bec48f07daf7bcdc2655a0cde84e07d24d2a9e2a + RCTTypeSafety: 171394eebacf71e1cfad79dbfae7ee8fc16ca80a + React: d7433ccb6a8c36e4cbed59a73c0700fc83c3e98a + React-callinvoker: 15f165009bd22ae829b2b600e50bcc98076ce4b8 + React-Codegen: df9d3975a10b29c1dfa4baa7678449e9d9648ca7 + React-Core: 882014e745cdad5788c5c8aa1a0f4661880aad69 + React-CoreModules: e0cbc1a4f4f3f60e23c476fef7ab37be363ea8c1 + React-cxxreact: bde3dde79b6d8e2dae76197ad75c11883f7d152d + React-jsc: 30670396f92f5f9bab121bf8c303f5a0a507061b + React-jsi: 103a8ff6586095e0e6853522f8eea37ca0226f99 + React-jsiexecutor: 891dad49e50d35fba97eeb43a35ae7470a8e10b2 + React-jsinspector: 9f7c9137605e72ca0343db4cea88006cb94856dd + React-logger: 957e5dc96d9dbffc6e0f15e0ee4d2b42829ff207 + react-native-webview: 2f7e47e1273ed81b98bb2ce7ad8c3c1a872cf073 + React-perflogger: af8a3d31546077f42d729b949925cc4549f14def + React-RCTActionSheet: 57cc5adfefbaaf0aae2cf7e10bccd746f2903673 + React-RCTAnimation: 11c61e94da700c4dc915cf134513764d87fc5e2b + React-RCTAppDelegate: 3057d5a551fbe3ac8bac361761f4c74ba2e5ab17 + React-RCTBlob: 0e49a4ecd4d5276c79bea13d1c4b21f99da45121 + React-RCTImage: 7a9226b0944f1e76e8e01e35a9245c2477cdbabb + React-RCTLinking: bbe8cc582046a9c04f79c235b73c93700263e8b4 + React-RCTNetwork: fc2ca322159dc54e06508d4f5c3e934da63dc013 + React-RCTSettings: f1e9db2cdf946426d3f2b210e4ff4ce0f0d842ef + React-RCTText: 1c41dd57e5d742b1396b4eeb251851ce7ff0fca1 + React-RCTVibration: 5199a180d04873366a83855de55ac33ce60fe4d5 + React-runtimeexecutor: 7bf0dafc7b727d93c8cb94eb00a9d3753c446c3e + ReactCommon: 5768a505f0bc7b798dc2becdd3ee6442224f796c ReactTestApp-DevSupport: 1646ce70be36400a60ca18608284f3f7099a35c1 ReactTestApp-Resources: ff5f151e465e890010b417ce65ca6c5de6aeccbb - Yoga: c4d61225a466f250c35c1ee78d2d0b3d41fe661c + Yoga: 5ed1699acbba8863755998a4245daa200ff3817b PODFILE CHECKSUM: 8344c021910ed9b6a9bb9985ff8f7f05a68b19c1 diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index ffcf2fa..689d3ef 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -218,7 +218,7 @@ PODS: - React-jsinspector (0.68.62) - React-logger (0.68.62): - glog - - react-native-webview (11.26.0): + - react-native-webview (12.0.0-rc.0): - React-Core - React-perflogger (0.68.62) - React-RCTActionSheet (0.68.62): @@ -423,7 +423,7 @@ SPEC CHECKSUMS: React-jsiexecutor: 1862151d3f809499c82d7f66a3ca624b4d6b49d9 React-jsinspector: 39348b9a3417419aea646f41cba625e1a7bbbd30 React-logger: 7a2e45e85d0fe59edb6d4fb2cbcbb9981ab9486e - react-native-webview: 994b9f8fbb504d6314dc40d83f94f27c6831b3bf + react-native-webview: bf1329769290feefad471977132b5fb6c8288f71 React-perflogger: 20ae52b52ce2c0e1e257e0c0502f8f08a0b43ff9 React-RCTActionSheet: 2a62f3135a621bbf90504a28205cf5ef05b27bea React-RCTAnimation: 219eb987ed34c38cbf13096062da7ddc142f0fac diff --git a/package.json b/package.json index 959e863..b9148f9 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "homepage": "https://github.com/react-native-webview/react-native-webview#readme", "scripts": { "android": "react-native run-android", - "ios": "react-native run-ios --project-path example/ios", + "ios": "react-native run-ios", "macos": "react-native run-macos --scheme WebviewExample --project-path example/macos", "start": "cd example && react-native start", "windows": "install-windows-test-app --project-directory example/windows && react-native run-windows --root example --arch x64", @@ -23,7 +23,8 @@ "build": "yarn tsc", "prepare": "yarn build", "appium": "appium", - "test:windows": "yarn jest --setupFiles=./jest-setups/jest.setup.js" + "test:windows": "yarn jest --setupFiles=./jest-setups/jest.setup.js", + "add:macos": "yarn add react-native-macos@0.68.62" }, "rn-docs": { "title": "Webview", @@ -42,9 +43,8 @@ "@babel/runtime": "^7.0.0", "@semantic-release/git": "7.0.16", "@types/invariant": "^2.2.30", - "@types/jest": "^26.0.0", - "@types/react": "^17.0.0", - "@types/react-native": "^0.67.3", + "@types/jest": "^29.4.0", + "@types/react": "18.0.27", "@types/selenium-webdriver": "4.0.9", "@typescript-eslint/eslint-plugin": "2.1.0", "@typescript-eslint/parser": "2.1.0", @@ -57,13 +57,12 @@ "eslint-plugin-react": "7.14.3", "eslint-plugin-react-hooks": "^4.5.0", "eslint-plugin-react-native": "3.7.0", - "jest": "^26.6.3", - "metro-react-native-babel-preset": "^0.67.0", - "react": "17.0.2", - "react-native": "0.68.5", - "react-native-macos": "0.68.62", - "react-native-test-app": "2.3.2", - "react-native-windows": "0.68.4", + "jest": "^29.4.1", + "metro-react-native-babel-preset": "0.73.7", + "react": "18.2.0", + "react-native": "0.71.3", + "react-native-test-app": "2.3.12", + "react-native-windows": "0.71.0", "selenium-appium": "1.0.2", "selenium-webdriver": "4.0.0-alpha.7", "semantic-release": "15.13.24", @@ -75,15 +74,31 @@ "url": "https://github.com/react-native-webview/react-native-webview.git" }, "files": [ - "android", + "android/src", + "android/build.gradle", + "android/gradle.properties", "apple", "ios", "macos", "windows", "lib", + "src", "index.js", "index.d.ts", "react-native-webview.podspec", "react-native.config.js" - ] + ], + "resolutions": { + "@react-native-community/cli": "10.1.3", + "@react-native-community/cli-platform-android": "10.1.3", + "@react-native-community/cli-platform-ios": "10.1.1" + }, + "codegenConfig": { + "name": "RNCWebViewSpec", + "type": "all", + "jsSrcsDir": "./src", + "android": { + "javaPackageName": "com.reactnativecommunity.webview" + } + } } diff --git a/react-native-webview.podspec b/react-native-webview.podspec index 7ed0835..b6f164a 100644 --- a/react-native-webview.podspec +++ b/react-native-webview.podspec @@ -2,6 +2,8 @@ require 'json' package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) +folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' + Pod::Spec.new do |s| s.name = package['name'] s.version = package['version'] @@ -13,7 +15,24 @@ Pod::Spec.new do |s| s.platforms = { :ios => "9.0", :osx => "10.13" } s.source = { :git => "https://github.com/react-native-webview/react-native-webview.git", :tag => "v#{s.version}" } - s.source_files = "apple/**/*.{h,m}" - s.dependency 'React-Core' + s.source_files = "apple/**/*.{h,m,mm,swift}" + + s.dependency "React-Core" + + if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then + s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" + s.pod_target_xcconfig = { + "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", + "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" + } + + s.dependency "React-RCTFabric" + s.dependency "React-Codegen" + s.dependency "RCT-Folly" + s.dependency "RCTRequired" + s.dependency "RCTTypeSafety" + s.dependency "ReactCommon/turbomodule/core" + end end diff --git a/react-native.config.js b/react-native.config.js index 154ceaf..2736685 100644 --- a/react-native.config.js +++ b/react-native.config.js @@ -4,7 +4,6 @@ const project = (() => { try { const { androidManifestPath, - iosProjectPath, windowsProjectPath, } = require('react-native-test-app'); return { @@ -15,7 +14,7 @@ const project = (() => { ), }, ios: { - project: iosProjectPath('example/ios'), + sourceDir: 'example/ios', }, windows: fs.existsSync('example/windows/WebviewExample.sln') && { sourceDir: path.join('example', 'windows'), diff --git a/src/NativeRNCWebView.ts b/src/NativeRNCWebView.ts new file mode 100644 index 0000000..6497e7e --- /dev/null +++ b/src/NativeRNCWebView.ts @@ -0,0 +1,14 @@ +/* eslint-disable import/no-duplicates */ +import type { TurboModule } from 'react-native'; +import { TurboModuleRegistry } from 'react-native'; +import {Int32} from 'react-native/Libraries/Types/CodegenTypes'; + +export interface Spec extends TurboModule { + readonly getConstants: () => {}; + + // your module methods go here, for example: + isFileUploadSupported(): Promise; + shouldStartLoadWithLockIdentifier(shouldStart: boolean, lockIdentifier: Int32): void; +} + +export default TurboModuleRegistry.getEnforcing('RNCWebView'); \ No newline at end of file diff --git a/src/RNCWebViewNativeComponent.ts b/src/RNCWebViewNativeComponent.ts new file mode 100644 index 0000000..0472b75 --- /dev/null +++ b/src/RNCWebViewNativeComponent.ts @@ -0,0 +1,272 @@ +import type { HostComponent, ViewProps } from 'react-native'; +import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; +import {DirectEventHandler,Double, Int32, WithDefault} from 'react-native/Libraries/Types/CodegenTypes'; +import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; + +export type WebViewNativeEvent = Readonly<{ + url: string; + loading: boolean; + title: string; + canGoBack: boolean; + canGoForward: boolean; + lockIdentifier: Double; +}> +export type WebViewCustomMenuSelectionEvent = Readonly<{ + label: string; + key: string; + selectedText: string; +}> +export type WebViewMessageEvent = Readonly<{ + url: string; + loading: boolean; + title: string; + canGoBack: boolean; + canGoForward: boolean; + lockIdentifier: Double; + data: string; +}> +export type WebViewHttpErrorEvent = Readonly<{ + url: string; + loading: boolean; + title: string; + canGoBack: boolean; + canGoForward: boolean; + lockIdentifier: Double; + description: string; + statusCode: Int32; +}> + +export type WebViewErrorEvent = Readonly<{ + url: string; + loading: boolean; + title: string; + canGoBack: boolean; + canGoForward: boolean; + lockIdentifier: Double; + domain?: string; + code: Int32; + description: string; +}> + +export type WebViewNativeProgressEvent = Readonly< { + url: string; + loading: boolean; + title: string; + canGoBack: boolean; + canGoForward: boolean; + lockIdentifier: Double; + progress: Double; +}> + +export type WebViewNavigationEvent = Readonly< { + url: string; + loading: boolean; + title: string; + canGoBack: boolean; + canGoForward: boolean; + lockIdentifier: Double; + navigationType: + | 'click' + | 'formsubmit' + | 'backforward' + | 'reload' + | 'formresubmit' + | 'other'; + mainDocumentURL?: string; +}> + +export type ShouldStartLoadRequestEvent = Readonly<{ + url: string; + loading: boolean; + title: string; + canGoBack: boolean; + canGoForward: boolean; + lockIdentifier: Double; + navigationType: + | 'click' + | 'formsubmit' + | 'backforward' + | 'reload' + | 'formresubmit' + | 'other'; + mainDocumentURL?: string; + isTopFrame: boolean; +}> + +type ScrollEvent = Readonly<{ + contentInset: { + bottom: Double, + left: Double, + right: Double, + top: Double, + }, + contentOffset: { + y: Double, + x: Double, + }, + contentSize: { + height: Double, + width: Double, + }, + layoutMeasurement: { + height: Double, + width: Double, + }, + targetContentOffset?: { + y: Double, + x: Double, + }, + velocity?: { + y: Double, + x: Double, + }, + zoomScale?: Double, + responderIgnoreScroll?: boolean, +}> + +type WebViewRenderProcessGoneEvent = Readonly<{ + didCrash: boolean; +}> + +type WebViewDownloadEvent = Readonly<{ + downloadUrl: string; +}> + +// type MenuItem = Readonly<{label: string, key: string}>; + +export interface NativeProps extends ViewProps { + // Android only + allowFileAccess?: boolean; + allowsProtectedMedia?: boolean; + allowsFullscreenVideo?: boolean; + androidLayerType?: WithDefault<'none' | 'software' | 'hardware', 'none'>; + cacheMode?: WithDefault<'LOAD_DEFAULT' | 'LOAD_CACHE_ELSE_NETWORK' | 'LOAD_NO_CACHE' | 'LOAD_CACHE_ONLY', 'LOAD_DEFAULT'>; + domStorageEnabled?: boolean; + downloadingMessage?: string; + forceDarkOn?: boolean; + geolocationEnabled?: boolean; + lackPermissionToDownloadMessage?: string; + messagingModuleName: string; + minimumFontSize?: Int32; + mixedContentMode?: WithDefault<'never' | 'always' | 'compatibility', 'never'>; + nestedScrollEnabled?: boolean; + onContentSizeChange?: DirectEventHandler; + onRenderProcessGone?: DirectEventHandler; + overScrollMode?: string; + saveFormDataDisabled?: boolean; + scalesPageToFit?: boolean; + setBuiltInZoomControls?: boolean; + setDisplayZoomControls?: boolean; + setSupportMultipleWindows?: boolean; + textZoom?: Int32; + thirdPartyCookiesEnabled?: boolean; + // Workaround to watch if listener if defined + hasOnScroll?: boolean; + // !Android only + + // iOS only + allowingReadAccessToURL?: string; + allowsBackForwardNavigationGestures?: boolean; + allowsInlineMediaPlayback?: boolean; + allowsAirPlayForMediaPlayback?: boolean; + allowsLinkPreview?: boolean; + automaticallyAdjustContentInsets?: boolean; + autoManageStatusBarEnabled?: boolean; + bounces?: boolean; + contentInset?: Readonly<{ + top?: Double; + left?: Double; + bottom?: Double; + right?: Double; + }>; + contentInsetAdjustmentBehavior?: WithDefault<'never' | 'automatic' | 'scrollableAxes' | 'always', 'never'>; + contentMode?: WithDefault<'recommended' | 'mobile' | 'desktop', 'recommended'>; + dataDetectorTypes?: WithDefault< + // eslint-disable-next-line @typescript-eslint/array-type + ReadonlyArray<'address' | 'link' | 'calendarEvent' | 'trackingNumber' | 'flightNumber' | 'lookupSuggestion' | 'phoneNumber' | 'all' | 'none'>, + 'phoneNumber' + >; + decelerationRate?: Double; + directionalLockEnabled?: boolean; + enableApplePay?: boolean; + hideKeyboardAccessoryView?: boolean; + keyboardDisplayRequiresUserAction?: boolean; + limitsNavigationsToAppBoundDomains?: boolean; + mediaCapturePermissionGrantType?: WithDefault<'prompt' | 'grant' | 'deny' | 'grantIfSameHostElsePrompt' | 'grantIfSameHostElseDeny', 'prompt'>; + pagingEnabled?: boolean; + pullToRefreshEnabled?: boolean; + scrollEnabled?: boolean; + sharedCookiesEnabled?: boolean; + textInteractionEnabled?: boolean; + useSharedProcessPool?: boolean; + onContentProcessDidTerminate?: DirectEventHandler; + onCustomMenuSelection?: DirectEventHandler; + onFileDownload?: DirectEventHandler; + // eslint-disable-next-line @typescript-eslint/array-type + menuItems?: ReadonlyArray>; + // Workaround to watch if listener if defined + hasOnFileDownload?: boolean; + // !iOS only + + allowFileAccessFromFileURLs?: boolean; + allowUniversalAccessFromFileURLs?: boolean; + applicationNameForUserAgent?: string; + basicAuthCredential?: Readonly<{ + username: string; + password: string; + }>; + cacheEnabled?: boolean; + incognito?: boolean; + injectedJavaScript?: string; + injectedJavaScriptBeforeContentLoaded?: string; + injectedJavaScriptForMainFrameOnly?: boolean; + injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean; + javaScriptCanOpenWindowsAutomatically?: boolean; + javaScriptEnabled?: boolean; + mediaPlaybackRequiresUserAction?: boolean; + messagingEnabled: boolean; + onLoadingError: DirectEventHandler; + onLoadingFinish: DirectEventHandler; + onLoadingProgress: DirectEventHandler; + onLoadingStart: DirectEventHandler; + onHttpError: DirectEventHandler; + onMessage: DirectEventHandler; + onScroll?: DirectEventHandler; + onShouldStartLoadWithRequest: DirectEventHandler; + showsHorizontalScrollIndicator?: boolean; + showsVerticalScrollIndicator?: boolean; + newSource: Readonly<{ + uri?: string + method?: string; + body?: string; + // eslint-disable-next-line @typescript-eslint/array-type + headers?: ReadonlyArray>; + html?: string; + baseUrl?: string; + }>; + userAgent?: string; +} + +export interface NativeCommands { + goBack: (viewRef: React.ElementRef> ) => void; + goForward: (viewRef: React.ElementRef>) => void; + reload: (viewRef: React.ElementRef>) => void; + stopLoading: (viewRef: React.ElementRef>) => void; + injectJavaScript: (viewRef: React.ElementRef>, javascript: string) => void; + requestFocus: (viewRef: React.ElementRef>) => void; + postMessage: (viewRef: React.ElementRef>, data: string) => void; + // Android Only + loadUrl: (viewRef: React.ElementRef>, url: string) => void; + clearFormData: (viewRef: React.ElementRef>) => void; + clearCache: (viewRef: React.ElementRef>, includeDiskFiles: boolean) => void; + clearHistory: (viewRef: React.ElementRef>) => void; + // !Android Only +} + +export const Commands = codegenNativeCommands({ + supportedCommands: ['goBack', 'goForward', 'reload', 'stopLoading', 'injectJavaScript', 'requestFocus', 'postMessage', 'loadUrl', 'clearFormData', 'clearCache', 'clearHistory'], +}); + +export default codegenNativeComponent( + 'RNCWebView' +) as HostComponent; \ No newline at end of file diff --git a/src/WebView.android.tsx b/src/WebView.android.tsx index 8f3a21d..e187562 100644 --- a/src/WebView.android.tsx +++ b/src/WebView.android.tsx @@ -1,19 +1,18 @@ -import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react'; +import React, { forwardRef, ReactElement, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react'; import { Image, View, - NativeModules, ImageSourcePropType, + HostComponent, } from 'react-native'; import BatchedBridge from 'react-native/Libraries/BatchedBridge/BatchedBridge'; -// @ts-expect-error react-native doesn't have this type -import codegenNativeCommandsUntyped from 'react-native/Libraries/Utilities/codegenNativeCommands'; import invariant from 'invariant'; -import RNCWebView from "./WebViewNativeComponent.android"; +import RNCWebView, {Commands, NativeProps} from "./RNCWebViewNativeComponent"; +import RNCWebViewModule from "./NativeRNCWebView"; import { defaultOriginWhitelist, defaultRenderError, @@ -21,18 +20,11 @@ import { useWebWiewLogic, } from './WebViewShared'; import { - AndroidWebViewProps, - NativeWebViewAndroid, + AndroidWebViewProps, WebViewSourceUri, } from './WebViewTypes'; import styles from './WebView.styles'; -const codegenNativeCommands = codegenNativeCommandsUntyped as (options: { supportedCommands: (keyof T)[] }) => T; - -const Commands = codegenNativeCommands({ - supportedCommands: ['goBack', 'goForward', 'reload', 'stopLoading', 'injectJavaScript', 'requestFocus', 'postMessage', 'clearFormData', 'clearCache', 'clearHistory', 'loadUrl'], -}); - const { resolveAssetSource } = Image; /** @@ -49,7 +41,6 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ allowFileAccess = false, saveFormDataDisabled = false, cacheEnabled = true, - androidHardwareAccelerationDisabled = false, androidLayerType = "none", originWhitelist = defaultOriginWhitelist, setSupportMultipleWindows = true, @@ -76,14 +67,14 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ ...otherProps }, ref) => { const messagingModuleName = useRef(`WebViewMessageHandler${uniqueRef += 1}`).current; - const webViewRef = useRef(null); + const webViewRef = useRef> | null>(null); const onShouldStartLoadWithRequestCallback = useCallback((shouldStart: boolean, url: string, lockIdentifier?: number) => { if (lockIdentifier) { - NativeModules.RNCWebView.onShouldStartLoadWithRequestCallback(shouldStart, lockIdentifier); - } else if (shouldStart) { + RNCWebViewModule.shouldStartLoadWithLockIdentifier(shouldStart, lockIdentifier); + } else if (shouldStart && webViewRef.current) { Commands.loadUrl(webViewRef.current, url); } }, []); @@ -105,20 +96,23 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ }) useImperativeHandle(ref, () => ({ - goForward: () => Commands.goForward(webViewRef.current), - goBack: () => Commands.goBack(webViewRef.current), + goForward: () => webViewRef.current && Commands.goForward(webViewRef.current), + goBack: () => webViewRef.current && Commands.goBack(webViewRef.current), reload: () => { setViewState( 'LOADING', - ); Commands.reload(webViewRef.current) + ); + if (webViewRef.current) { + Commands.reload(webViewRef.current) + } }, - stopLoading: () => Commands.stopLoading(webViewRef.current), - postMessage: (data: string) => Commands.postMessage(webViewRef.current, data), - injectJavaScript: (data: string) => Commands.injectJavaScript(webViewRef.current, data), - requestFocus: () => Commands.requestFocus(webViewRef.current), - clearFormData: () => Commands.clearFormData(webViewRef.current), - clearCache: (includeDiskFiles: boolean) => Commands.clearCache(webViewRef.current, includeDiskFiles), - clearHistory: () => Commands.clearHistory(webViewRef.current), + stopLoading: () => webViewRef.current && Commands.stopLoading(webViewRef.current), + postMessage: (data: string) => webViewRef.current && Commands.postMessage(webViewRef.current, data), + injectJavaScript: (data: string) => webViewRef.current && Commands.injectJavaScript(webViewRef.current, data), + requestFocus: () => webViewRef.current && Commands.requestFocus(webViewRef.current), + clearFormData: () => webViewRef.current && Commands.clearFormData(webViewRef.current), + clearCache: (includeDiskFiles: boolean) => webViewRef.current && Commands.clearCache(webViewRef.current, includeDiskFiles), + clearHistory: () => webViewRef.current && Commands.clearHistory(webViewRef.current), }), [setViewState, webViewRef]); const directEventCallbacks = useMemo(() => ({ @@ -130,16 +124,18 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ BatchedBridge.registerCallableModule(messagingModuleName, directEventCallbacks); }, [messagingModuleName, directEventCallbacks]) - let otherView = null; + let otherView: ReactElement | undefined; if (viewState === 'LOADING') { otherView = (renderLoading || defaultRenderLoading)(); } else if (viewState === 'ERROR') { invariant(lastErrorEvent != null, 'lastErrorEvent expected to be non-null'); - otherView = (renderError || defaultRenderError)( - lastErrorEvent.domain, - lastErrorEvent.code, - lastErrorEvent.description, - ); + if (lastErrorEvent) { + otherView = (renderError || defaultRenderError)( + lastErrorEvent.domain, + lastErrorEvent.code, + lastErrorEvent.description, + ); + } } else if (viewState !== 'IDLE') { console.error(`RNCWebView invalid state encountered: ${viewState}`); } @@ -157,9 +153,22 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ } } - const NativeWebView - = (nativeConfig?.component as (typeof NativeWebViewAndroid | undefined)) || RNCWebView; + = (nativeConfig?.component as (typeof RNCWebView | undefined)) || RNCWebView; + + const sourceResolved = resolveAssetSource(source as ImageSourcePropType) + const newSource = typeof sourceResolved === "object" ? Object.entries(sourceResolved as WebViewSourceUri).reduce((prev, [currKey, currValue]) => { + return { + ...prev, + [currKey]: currKey === "headers" && currValue && typeof currValue === "object" ? Object.entries(currValue).map( + ([key, value]) => { + return { + name: key, + value + } + }) : currValue + } + }, {}) : sourceResolved const webView = (({ messagingEnabled={typeof onMessageProp === 'function'} messagingModuleName={messagingModuleName} + hasOnScroll={!!otherProps.onScroll} onLoadingError={onLoadingError} onLoadingFinish={onLoadingFinish} onLoadingProgress={onLoadingProgress} @@ -175,10 +185,11 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ onRenderProcessGone={onRenderProcessGone} onMessage={onMessage} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} - ref={webViewRef} // TODO: find a better way to type this. - source={resolveAssetSource(source as ImageSourcePropType)} + // @ts-expect-error source is old arch + source={sourceResolved} + newSource={newSource} style={webViewStyles} overScrollMode={overScrollMode} javaScriptEnabled={javaScriptEnabled} @@ -188,7 +199,6 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ allowFileAccess={allowFileAccess} saveFormDataDisabled={saveFormDataDisabled} cacheEnabled={cacheEnabled} - androidHardwareAccelerationDisabled={androidHardwareAccelerationDisabled} androidLayerType={androidLayerType} setSupportMultipleWindows={setSupportMultipleWindows} setBuiltInZoomControls={setBuiltInZoomControls} @@ -206,9 +216,8 @@ const WebViewComponent = forwardRef<{}, AndroidWebViewProps>(({ }); // native implementation should return "true" only for Android 5+ -const isFileUploadSupported: () => Promise - = NativeModules.RNCWebView.isFileUploadSupported(); +const { isFileUploadSupported } = RNCWebViewModule; -const WebView = Object.assign(WebViewComponent, {isFileUploadSupported}); +const WebView = Object.assign(WebViewComponent, { isFileUploadSupported }); export default WebView; diff --git a/src/WebView.ios.tsx b/src/WebView.ios.tsx index 221fa17..3ffda25 100644 --- a/src/WebView.ios.tsx +++ b/src/WebView.ios.tsx @@ -2,14 +2,14 @@ import React, { forwardRef, useCallback, useImperativeHandle, useRef } from 'rea import { Image, View, - NativeModules, ImageSourcePropType, + HostComponent, } from 'react-native'; import invariant from 'invariant'; -// @ts-expect-error react-native doesn't have this type -import codegenNativeCommandsUntyped from 'react-native/Libraries/Utilities/codegenNativeCommands'; -import RNCWebView from "./WebViewNativeComponent.ios"; +import RNCWebView, {Commands, NativeProps} from "./RNCWebViewNativeComponent"; +import RNCWebViewModule from "./NativeRNCWebView"; + import { defaultOriginWhitelist, defaultRenderError, @@ -19,18 +19,12 @@ import { import { IOSWebViewProps, DecelerationRateConstant, - NativeWebViewIOS, - ViewManager, + WebViewSourceUri, } from './WebViewTypes'; import styles from './WebView.styles'; -const codegenNativeCommands = codegenNativeCommandsUntyped as (options: { supportedCommands: (keyof T)[] }) => T; - -const Commands = codegenNativeCommands({ - supportedCommands: ['goBack', 'goForward', 'reload', 'stopLoading', 'injectJavaScript', 'requestFocus', 'postMessage', 'loadUrl'], -}); const { resolveAssetSource } = Image; const processDecelerationRate = ( @@ -45,8 +39,6 @@ const processDecelerationRate = ( return newDecelerationRate; }; -const RNCWebViewManager = NativeModules.RNCWebViewManager as ViewManager; - const useWarnIfChanges = (value: T, name: string) => { const ref = useRef(value); if (ref.current !== value) { @@ -91,19 +83,15 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>(({ onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp, ...otherProps }, ref) => { - const webViewRef = useRef(null); + const webViewRef = useRef> | null>(null); const onShouldStartLoadWithRequestCallback = useCallback(( shouldStart: boolean, _url: string, lockIdentifier = 0, ) => { - const viewManager - = (nativeConfig?.viewManager) - || RNCWebViewManager; - - viewManager.startLoadWithResult(!!shouldStart, lockIdentifier); - }, [nativeConfig?.viewManager]); + RNCWebViewModule.shouldStartLoadWithLockIdentifier(shouldStart, lockIdentifier); + }, []); const { onLoadingStart, onShouldStartLoadWithRequest, onMessage, viewState, setViewState, lastErrorEvent, onHttpError, onLoadingError, onLoadingFinish, onLoadingProgress, onContentProcessDidTerminate } = useWebWiewLogic({ onNavigationStateChange, @@ -122,17 +110,20 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>(({ }); useImperativeHandle(ref, () => ({ - goForward: () => Commands.goForward(webViewRef.current), - goBack: () => Commands.goBack(webViewRef.current), + goForward: () => webViewRef.current && Commands.goForward(webViewRef.current), + goBack: () => webViewRef.current && Commands.goBack(webViewRef.current), reload: () => { setViewState( 'LOADING', - ); Commands.reload(webViewRef.current) + ); + if (webViewRef.current) { + Commands.reload(webViewRef.current) + } }, - stopLoading: () => Commands.stopLoading(webViewRef.current), - postMessage: (data: string) => Commands.postMessage(webViewRef.current, data), - injectJavaScript: (data: string) => Commands.injectJavaScript(webViewRef.current, data), - requestFocus: () => Commands.requestFocus(webViewRef.current), + stopLoading: () => webViewRef.current && Commands.stopLoading(webViewRef.current), + postMessage: (data: string) => webViewRef.current && Commands.postMessage(webViewRef.current, data), + injectJavaScript: (data: string) => webViewRef.current && Commands.injectJavaScript(webViewRef.current, data), + requestFocus: () => webViewRef.current && Commands.requestFocus(webViewRef.current), }), [setViewState, webViewRef]); @@ -148,9 +139,9 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>(({ } else if (viewState === 'ERROR') { invariant(lastErrorEvent != null, 'lastErrorEvent expected to be non-null'); otherView = (renderError || defaultRenderError)( - lastErrorEvent.domain, - lastErrorEvent.code, - lastErrorEvent.description, + lastErrorEvent?.domain, + lastErrorEvent?.code ?? 0, + lastErrorEvent?.description ?? '', ); } else if (viewState !== 'IDLE') { console.error(`RNCWebView invalid state encountered: ${viewState}`); @@ -162,9 +153,23 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>(({ const decelerationRate = processDecelerationRate(decelerationRateProp); const NativeWebView - = (nativeConfig?.component as typeof NativeWebViewIOS | undefined) + = (nativeConfig?.component as typeof RNCWebView | undefined) || RNCWebView; + const sourceResolved = resolveAssetSource(source as ImageSourcePropType) + const newSource = typeof sourceResolved === "object" ? Object.entries(sourceResolved as WebViewSourceUri).reduce((prev, [currKey, currValue]) => { + return { + ...prev, + [currKey]: currKey === "headers" && currValue && typeof currValue === "object" ? Object.entries(currValue).map( + ([key, value]) => { + return { + name: key, + value + } + }) : currValue + } + }, {}) : sourceResolved + const webView = ( (({ textInteractionEnabled={textInteractionEnabled} decelerationRate={decelerationRate} messagingEnabled={typeof onMessageProp === 'function'} + messagingModuleName="" // android ONLY onLoadingError={onLoadingError} onLoadingFinish={onLoadingFinish} onLoadingProgress={onLoadingProgress} @@ -188,15 +194,17 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>(({ injectedJavaScriptBeforeContentLoaded={injectedJavaScriptBeforeContentLoaded} injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={injectedJavaScriptBeforeContentLoadedForMainFrameOnly} - dataDetectorTypes={dataDetectorTypes} + dataDetectorTypes={!dataDetectorTypes || Array.isArray(dataDetectorTypes) ? dataDetectorTypes : [dataDetectorTypes]} allowsAirPlayForMediaPlayback={allowsAirPlayForMediaPlayback} allowsInlineMediaPlayback={allowsInlineMediaPlayback} incognito={incognito} mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction} - ref={webViewRef} - // TODO: find a better way to type this. - source={resolveAssetSource(source as ImageSourcePropType)} + newSource={newSource} style={webViewStyles} + hasOnFileDownload={!!onFileDownload} + ref={webViewRef} + // @ts-expect-error old arch only + source={sourceResolved} {...nativeConfig?.props} /> ); diff --git a/src/WebView.macos.tsx b/src/WebView.macos.tsx index d4860be..d9b91bd 100644 --- a/src/WebView.macos.tsx +++ b/src/WebView.macos.tsx @@ -2,14 +2,13 @@ import React, { forwardRef, useCallback, useImperativeHandle, useRef } from 'rea import { Image, View, - NativeModules, ImageSourcePropType, } from 'react-native'; import invariant from 'invariant'; -// @ts-expect-error react-native doesn't have this type -import codegenNativeCommandsUntyped from 'react-native/Libraries/Utilities/codegenNativeCommands'; +import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; import RNCWebView from "./WebViewNativeComponent.macos"; +import RNCWebViewModule from "./NativeRNCWebView"; import { defaultOriginWhitelist, defaultRenderError, @@ -19,22 +18,16 @@ import { import { MacOSWebViewProps, NativeWebViewMacOS, - ViewManager, } from './WebViewTypes'; import styles from './WebView.styles'; - -const codegenNativeCommands = codegenNativeCommandsUntyped as (options: { supportedCommands: (keyof T)[] }) => T; - const Commands = codegenNativeCommands({ supportedCommands: ['goBack', 'goForward', 'reload', 'stopLoading', 'injectJavaScript', 'requestFocus', 'postMessage', 'loadUrl'], }); const { resolveAssetSource } = Image; -const RNCWebViewManager = NativeModules.RNCWebViewManager as ViewManager; - const useWarnIfChanges = (value: T, name: string) => { const ref = useRef(value); if (ref.current !== value) { @@ -79,12 +72,8 @@ const WebViewComponent = forwardRef<{}, MacOSWebViewProps>(({ _url: string, lockIdentifier = 0, ) => { - const viewManager - = (nativeConfig?.viewManager) - || RNCWebViewManager; - - viewManager.startLoadWithResult(!!shouldStart, lockIdentifier); - }, [nativeConfig?.viewManager]); + RNCWebViewModule.shouldStartLoadWithLockIdentifier(!!shouldStart, lockIdentifier); + }, []); const { onLoadingStart, onShouldStartLoadWithRequest, onMessage, viewState, setViewState, lastErrorEvent, onHttpError, onLoadingError, onLoadingFinish, onLoadingProgress, onContentProcessDidTerminate } = useWebWiewLogic({ onNavigationStateChange, diff --git a/src/WebView.windows.tsx b/src/WebView.windows.tsx index 843c6ff..79121a9 100644 --- a/src/WebView.windows.tsx +++ b/src/WebView.windows.tsx @@ -17,8 +17,7 @@ import { ImageSourcePropType, NativeModules, } from 'react-native'; -// @ts-expect-error react-native doesn't have this type -import codegenNativeCommandsUntyped from 'react-native/Libraries/Utilities/codegenNativeCommands'; +import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; import invariant from 'invariant'; import {RCTWebView, RCTWebView2} from "./WebViewNativeComponent.windows"; import { useWebWiewLogic, defaultOriginWhitelist, defaultRenderError, defaultRenderLoading, } from './WebViewShared'; @@ -29,8 +28,6 @@ import { import styles from './WebView.styles'; -const codegenNativeCommands = codegenNativeCommandsUntyped as (options: { supportedCommands: (keyof T)[] }) => T; - const Commands = codegenNativeCommands({ supportedCommands: ['goBack', 'goForward', 'reload', 'stopLoading', 'injectJavaScript', 'requestFocus', 'postMessage', 'loadUrl'], }); @@ -59,7 +56,7 @@ const WebViewComponent = forwardRef<{}, WindowsWebViewProps>(({ ...otherProps }, ref) => { const webViewRef = useRef(null); - + const RCTWebViewString = useWebView2 ? 'RCTWebView2' : 'RCTWebView'; const onShouldStartLoadWithRequestCallback = useCallback((shouldStart: boolean, url: string, lockIdentifier?: number) => { diff --git a/src/WebViewNativeComponent.android.ts b/src/WebViewNativeComponent.android.ts deleted file mode 100644 index 130a54a..0000000 --- a/src/WebViewNativeComponent.android.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { requireNativeComponent } from "react-native"; -import type { NativeWebViewAndroid } from "./WebViewTypes"; - -const RNCWebView: typeof NativeWebViewAndroid = requireNativeComponent( - 'RNCWebView', -); - -export default RNCWebView; diff --git a/src/WebViewNativeComponent.ios.ts b/src/WebViewNativeComponent.ios.ts deleted file mode 100644 index 96d03d5..0000000 --- a/src/WebViewNativeComponent.ios.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { requireNativeComponent } from "react-native"; -import type { NativeWebViewIOS } from "./WebViewTypes"; - -const RNCWebView: typeof NativeWebViewIOS = requireNativeComponent( - 'RNCWebView', -); - -export default RNCWebView; diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index cba759a..b30b7c0 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -1,17 +1,18 @@ /* eslint-disable react/no-multi-comp, max-classes-per-file */ -import { ReactElement, Component } from 'react'; +import { ReactElement, Component, ComponentProps } from 'react'; import { NativeSyntheticEvent, ViewProps, StyleProp, ViewStyle, NativeMethodsMixin, - Constructor, UIManagerStatic, NativeScrollEvent, } from 'react-native'; +import type NativeWebViewComponent from './RNCWebViewNativeComponent' + type WebViewCommands = | 'goForward' | 'goBack' @@ -55,11 +56,8 @@ interface ErrorState extends BaseState { export type State = NormalState | ErrorState; -// eslint-disable-next-line react/prefer-stateless-function -declare class NativeWebViewIOSComponent extends Component {} -declare const NativeWebViewIOSBase: Constructor & - typeof NativeWebViewIOSComponent; -export class NativeWebViewIOS extends NativeWebViewIOSBase {} +// eslint-disable-next-line @typescript-eslint/no-type-alias, @typescript-eslint/no-explicit-any +type Constructor = new (...args: any[]) => T; // eslint-disable-next-line react/prefer-stateless-function declare class NativeWebViewMacOSComponent extends Component {} @@ -67,12 +65,6 @@ declare const NativeWebViewMacOSBase: Constructor & typeof NativeWebViewMacOSComponent; export class NativeWebViewMacOS extends NativeWebViewMacOSBase {} -// eslint-disable-next-line react/prefer-stateless-function -declare class NativeWebViewAndroidComponent extends Component {} -declare const NativeWebViewAndroidBase: Constructor & - typeof NativeWebViewAndroidComponent; -export class NativeWebViewAndroid extends NativeWebViewAndroidBase {} - // eslint-disable-next-line react/prefer-stateless-function declare class NativeWebViewWindowsComponent extends Component {} declare const NativeWebViewWindowsBase: Constructor & @@ -241,7 +233,7 @@ export interface WebViewCustomMenuItems { export type WebViewSource = WebViewSourceUri | WebViewSourceHtml; export interface ViewManager { - startLoadWithResult: Function; + shouldStartLoadWithLockIdentifier: Function; } export interface WebViewNativeConfig { @@ -249,9 +241,8 @@ export interface WebViewNativeConfig { * The native component used to render the WebView. */ component?: - | typeof NativeWebViewIOS | typeof NativeWebViewMacOS - | typeof NativeWebViewAndroid; + | typeof NativeWebViewComponent; /** * Set props directly on the native component WebView. Enables custom props which the * original WebView doesn't pass through. @@ -311,38 +302,6 @@ export interface CommonNativeWebViewProps extends ViewProps { basicAuthCredential?: BasicAuthCredential; } -export interface AndroidNativeWebViewProps extends CommonNativeWebViewProps { - cacheMode?: CacheMode; - allowFileAccess?: boolean; - scalesPageToFit?: boolean; - allowFileAccessFromFileURLs?: boolean; - allowsFullscreenVideo?: boolean; - allowUniversalAccessFromFileURLs?: boolean; - androidHardwareAccelerationDisabled?: boolean; - androidLayerType?: AndroidLayerType; - domStorageEnabled?: boolean; - geolocationEnabled?: boolean; - javaScriptEnabled?: boolean; - mixedContentMode?: 'never' | 'always' | 'compatibility'; - onContentSizeChange?: (event: WebViewEvent) => void; - onRenderProcessGone?: (event: WebViewRenderProcessGoneEvent) => void; - overScrollMode?: OverScrollModeType; - saveFormDataDisabled?: boolean; - setSupportMultipleWindows?: boolean; - textZoom?: number; - thirdPartyCookiesEnabled?: boolean; - messagingModuleName?: string; - setBuiltInZoomControls?: boolean; - setDisplayZoomControls?: boolean; - nestedScrollEnabled?: boolean; - readonly urlPrefixesForDefaultIntent?: string[]; - forceDarkOn?: boolean; - minimumFontSize?: number; - downloadingMessage?: string; - lackPermissionToDownloadMessage?: string; - allowsProtectedMedia?: boolean; -} - export declare type ContentInsetAdjustmentBehavior = | 'automatic' | 'scrollableAxes' @@ -358,37 +317,6 @@ export declare type MediaCapturePermissionGrantType = export declare type ContentMode = 'recommended' | 'mobile' | 'desktop'; -export interface IOSNativeWebViewProps extends CommonNativeWebViewProps { - allowingReadAccessToURL?: string; - allowsBackForwardNavigationGestures?: boolean; - allowsInlineMediaPlayback?: boolean; - allowsAirPlayForMediaPlayback?: boolean; - allowsLinkPreview?: boolean; - allowFileAccessFromFileURLs?: boolean; - allowUniversalAccessFromFileURLs?: boolean; - automaticallyAdjustContentInsets?: boolean; - autoManageStatusBarEnabled?: boolean; - bounces?: boolean; - contentInset?: ContentInsetProp; - contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior; - contentMode?: ContentMode; - readonly dataDetectorTypes?: DataDetectorTypes | DataDetectorTypes[]; - decelerationRate?: number; - directionalLockEnabled?: boolean; - hideKeyboardAccessoryView?: boolean; - javaScriptEnabled?: boolean; - pagingEnabled?: boolean; - scrollEnabled?: boolean; - useSharedProcessPool?: boolean; - onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void; - injectedJavaScriptForMainFrameOnly?: boolean; - injectedJavaScriptBeforeContentLoadedForMainFrameOnly?: boolean; - onFileDownload?: (event: FileDownloadEvent) => void; - limitsNavigationsToAppBoundDomains?: boolean; - textInteractionEnabled?: boolean; - mediaCapturePermissionGrantType?: MediaCapturePermissionGrantType; -} - export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps { allowingReadAccessToURL?: string; allowFileAccessFromFileURLs?: boolean; @@ -744,7 +672,12 @@ export interface IOSWebViewProps extends WebViewSharedProps { * `selectedText`: the text selected on the document * @platform ios */ - onCustomMenuSelection?: (event: WebViewEvent) => void; + onCustomMenuSelection?: (event: {nativeEvent: { + label: string; + key: string; + selectedText: string; + } + }) => void; } export interface MacOSWebViewProps extends WebViewSharedProps { @@ -988,22 +921,6 @@ export interface AndroidWebViewProps extends WebViewSharedProps { */ setSupportMultipleWindows?: boolean; - /** - * Used on Android only, controls whether the given list of URL prefixes should - * make {@link com.facebook.react.views.webview.ReactWebViewClient} to launch a - * default activity intent for those URL instead of loading it within the webview. - * Use this to list URLs that WebView cannot handle, e.g. a PDF url. - * @platform android - */ - readonly urlPrefixesForDefaultIntent?: string[]; - - /** - * Boolean value to disable Hardware Acceleration in the `WebView`. Used on Android only - * as Hardware Acceleration is a feature only for Android. The default value is `false`. - * @platform android - */ - androidHardwareAccelerationDisabled?: boolean; - /** * https://developer.android.com/reference/android/webkit/WebView#setLayerType(int,%20android.graphics.Paint) * Sets the layerType. Possible values are: @@ -1170,7 +1087,7 @@ export interface WebViewSharedProps extends ViewProps { /** * Function that is invoked when the `WebView` scrolls. */ - onScroll?: (event: WebViewScrollEvent) => void; + onScroll?: ComponentProps['onScroll']; /** * Function that is invoked when the `WebView` has finished loading. diff --git a/src/__tests__/__snapshots__/WebViewShared-test.js.snap b/src/__tests__/__snapshots__/WebViewShared-test.js.snap index 57d8ea1..dfc866c 100644 --- a/src/__tests__/__snapshots__/WebViewShared-test.js.snap +++ b/src/__tests__/__snapshots__/WebViewShared-test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`WebViewShared exports defaultOriginWhitelist 1`] = ` -Array [ +[ "http://*", "https://*", ] diff --git a/yarn.lock b/yarn.lock index 717276e..a34fc4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -68,19 +68,19 @@ dependencies: tslib "^2.2.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: - "@babel/highlight" "^7.16.7" + "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" - integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== +"@babel/compat-data@^7.20.5": + version "7.20.10" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" + integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== -"@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.14.0", "@babel/core@^7.7.5": +"@babel/core@^7.0.0", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.14.0": version "7.17.8" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.8.tgz#3dac27c190ebc3a4381110d46c80e77efe172e1a" integrity sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ== @@ -101,29 +101,51 @@ json5 "^2.1.2" semver "^6.3.0" -"@babel/generator@^7.14.0", "@babel/generator@^7.17.3", "@babel/generator@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.7.tgz#8da2599beb4a86194a3b24df6c085931d9ee45ad" - integrity sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w== +"@babel/core@^7.11.6", "@babel/core@^7.20.0": + version "7.20.12" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" + integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== dependencies: - "@babel/types" "^7.17.0" + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.7" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-module-transforms" "^7.20.11" + "@babel/helpers" "^7.20.7" + "@babel/parser" "^7.20.7" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.12" + "@babel/types" "^7.20.7" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + +"@babel/generator@^7.17.7", "@babel/generator@^7.7.2": + version "7.20.14" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.14.tgz#9fa772c9f86a46c6ac9b321039400712b96f64ce" + integrity sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg== + dependencies: + "@babel/types" "^7.20.7" + "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" - source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" - integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== +"@babel/generator@^7.20.0", "@babel/generator@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" + integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.20.7" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== +"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/types" "^7.18.6" "@babel/helper-builder-react-jsx-experimental@^7.10.4": version "7.10.5" @@ -142,37 +164,51 @@ "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-compilation-targets@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" - integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb" + integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" + "@babel/compat-data" "^7.20.5" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + lru-cache "^5.1.1" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.16.7": - version "7.17.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" - integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-member-expression-to-functions" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - -"@babel/helper-create-regexp-features-plugin@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" - integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - regexpu-core "^4.7.0" +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" + integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + +"@babel/helper-create-class-features-plugin@^7.20.12": + version "7.20.12" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz#4349b928e79be05ed2d1643b20b99bb87c503819" + integrity sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-member-expression-to-functions" "^7.20.7" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.20.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/helper-split-export-declaration" "^7.18.6" + +"@babel/helper-create-regexp-features-plugin@^7.10.4", "@babel/helper-create-regexp-features-plugin@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c" + integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" "@babel/helper-define-map@^7.10.4": version "7.10.5" @@ -183,82 +219,84 @@ "@babel/types" "^7.10.5" lodash "^4.17.19" -"@babel/helper-environment-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" - integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== - dependencies: - "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" - integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== +"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== dependencies: - "@babel/types" "^7.10.4" + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" -"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" - integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== - dependencies: - "@babel/helper-get-function-arity" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-get-function-arity@^7.10.4", "@babel/helper-get-function-arity@^7.16.7": +"@babel/helper-get-function-arity@^7.10.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== dependencies: "@babel/types" "^7.16.7" -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-member-expression-to-functions@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" - integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q== +"@babel/helper-member-expression-to-functions@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" + integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.9" -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== +"@babel/helper-member-expression-to-functions@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz#a6f26e919582275a93c3aa6594756d71b0bb7f05" + integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.20.7" -"@babel/helper-module-transforms@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" - integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" + "@babel/types" "^7.18.6" -"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" - integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== +"@babel/helper-module-transforms@^7.17.7", "@babel/helper-module-transforms@^7.20.11": + version "7.20.11" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0" + integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== dependencies: - "@babel/types" "^7.16.7" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.10" + "@babel/types" "^7.20.7" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" - integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== +"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.8.0": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" + integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== + +"@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== "@babel/helper-regex@^7.10.4": version "7.10.5" @@ -267,97 +305,151 @@ dependencies: lodash "^4.17.19" -"@babel/helper-remap-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" - integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-wrap-function" "^7.16.8" - "@babel/types" "^7.16.8" +"@babel/helper-remap-async-to-generator@^7.16.8", "@babel/helper-remap-async-to-generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-replace-supers@^7.10.4", "@babel/helper-replace-supers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" + integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-replace-supers@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331" + integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.20.7" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.7" + "@babel/types" "^7.20.7" + +"@babel/helper-simple-access@^7.17.7", "@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + +"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" + integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== + dependencies: + "@babel/types" "^7.18.9" + +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0", "@babel/helper-skip-transparent-expression-wrappers@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" + integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== + dependencies: + "@babel/types" "^7.20.0" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helper-wrap-function@^7.18.9": + version "7.18.11" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz#bff23ace436e3f6aefb61f85ffae2291c80ed1fb" + integrity sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w== + dependencies: + "@babel/helper-function-name" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.11" + "@babel/types" "^7.18.10" -"@babel/helper-replace-supers@^7.10.4", "@babel/helper-replace-supers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" - integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-member-expression-to-functions" "^7.16.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/helper-simple-access@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" - integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== - dependencies: - "@babel/types" "^7.17.0" - -"@babel/helper-skip-transparent-expression-wrappers@^7.11.0", "@babel/helper-skip-transparent-expression-wrappers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" - integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== - dependencies: - "@babel/types" "^7.16.0" - -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - -"@babel/helper-wrap-function@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" - integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== +"@babel/helpers@^7.17.8": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.13.tgz#e3cb731fb70dc5337134cadc24cbbad31cc87ad2" + integrity sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg== dependencies: - "@babel/helper-function-name" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.8" - "@babel/types" "^7.16.8" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.13" + "@babel/types" "^7.20.7" -"@babel/helpers@^7.17.8": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.8.tgz#288450be8c6ac7e4e44df37bcc53d345e07bc106" - integrity sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw== +"@babel/helpers@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce" + integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA== dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.20.7" + "@babel/types" "^7.20.7" -"@babel/highlight@^7.16.7": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" - integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-validator-identifier" "^7.18.6" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3", "@babel/parser@^7.17.8": +"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7": version "7.17.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240" integrity sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ== +"@babel/parser@^7.17.8", "@babel/parser@^7.20.13": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.13.tgz#ddf1eb5a813588d2fb1692b70c6fce75b945c088" + integrity sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw== + +"@babel/parser@^7.20.0", "@babel/parser@^7.20.7": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" + integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== + +"@babel/plugin-proposal-async-generator-functions@^7.0.0": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz#85ea478c98b0095c3e4102bff3b67d306ed24952" + integrity sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.13.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" - integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-export-default-from@^7.0.0": version "7.10.4" @@ -436,12 +528,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.16.7", "@babel/plugin-syntax-flow@^7.2.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.16.7.tgz#202b147e5892b8452bbb0bb269c7ed2539ab8832" - integrity sha512-UDo3YGQO0jH6ytzVwgSLv9i/CzMcUjbKenL67dTrAZPPv6GFAtDhe6jqnvmoKzC/7htNTohhos+onPtDMqJwaQ== +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.18.6", "@babel/plugin-syntax-flow@^7.2.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz#774d825256f2379d06139be0c723c4dd444f3ca1" + integrity sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" @@ -464,6 +556,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -513,12 +612,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" - integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== +"@babel/plugin-syntax-typescript@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" + integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" "@babel/plugin-transform-arrow-functions@^7.0.0": version "7.10.4" @@ -578,21 +684,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-exponentiation-operator@^7.0.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" - integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== +"@babel/plugin-transform-flow-strip-types@^7.0.0": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.18.9.tgz#5b4cc521426263b5ce08893a2db41097ceba35bf" + integrity sha512-+G6rp2zRuOAInY5wcggsx4+QVao1qPM0osC9fTUVlAV3zOrzTCnrMAFVnR6+a3T8wz1wFIH7KhYMcMB3u1n80A== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-flow" "^7.18.6" -"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz#291fb140c78dabbf87f2427e7c7c332b126964b8" - integrity sha512-mzmCq3cNsDpZZu9FADYYyfZJIOrSONmHcop2XEKPdBNMa4PDC4eEvcOvzZaCNcjKu72v0XQlA5y1g58aLRXdYg== +"@babel/plugin-transform-flow-strip-types@^7.16.7": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz#e9e8606633287488216028719638cbbb2f2dde8f" + integrity sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-flow" "^7.16.7" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-syntax-flow" "^7.18.6" "@babel/plugin-transform-for-of@^7.0.0": version "7.10.4" @@ -633,12 +739,13 @@ "@babel/helper-simple-access" "^7.17.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-object-assign@^7.0.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.10.4.tgz#f7c8f54ce8052ccd8b9da9b3358848423221c338" - integrity sha512-6zccDhYEICfMeQqIjuY5G09/yhKzG30DKHJeYBQUHIsJH7c2jXSGvgwRalufLAXAq432OSlsEfAOLlzEsQzxVw== +"@babel/plugin-transform-named-capturing-groups-regex@^7.0.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" + integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-object-super@^7.0.0": version "7.10.4" @@ -696,13 +803,6 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.0.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" - integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== - dependencies: - regenerator-transform "^0.14.2" - "@babel/plugin-transform-runtime@^7.0.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.11.0.tgz#e27f78eb36f19448636e05c33c90fd9ad9b8bccf" @@ -744,14 +844,23 @@ "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-typescript@^7.16.7", "@babel/plugin-transform-typescript@^7.5.0": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" - integrity sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ== +"@babel/plugin-transform-typescript@^7.16.7": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.13.tgz#e3581b356b8694f6ff450211fe6774eaff8d25ab" + integrity sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/plugin-syntax-typescript" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.20.12" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-typescript" "^7.20.0" + +"@babel/plugin-transform-typescript@^7.5.0": + version "7.18.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.12.tgz#712e9a71b9e00fde9f8c0238e0cceee86ab2f8fd" + integrity sha512-2vjjam0cum0miPkenUbQswKowuxs/NjMwIKEq0zwegRxXk12C9YOF9STXnaUptITOtOJHKHpzvvWYOjbm6tc0w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-typescript" "^7.18.6" "@babel/plugin-transform-unicode-regex@^7.0.0": version "7.10.4" @@ -798,44 +907,61 @@ pirates "^4.0.5" source-map-support "^0.5.16" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.4.3", "@babel/runtime@^7.4.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.4.3", "@babel/runtime@^7.4.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7": version "7.11.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.0.0", "@babel/template@^7.16.7", "@babel/template@^7.3.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" +"@babel/template@^7.0.0", "@babel/template@^7.16.7", "@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + +"@babel/traverse@^7.14.0", "@babel/traverse@^7.18.11", "@babel/traverse@^7.18.9", "@babel/traverse@^7.20.0", "@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.7": + version "7.20.12" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.12.tgz#7f0f787b3a67ca4475adef1f56cb94f6abd4a4b5" + integrity sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.7" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + debug "^4.1.0" + globals "^11.1.0" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3": - version "7.17.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" - integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.3" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.3" - "@babel/types" "^7.17.0" +"@babel/traverse@^7.17.3", "@babel/traverse@^7.20.13", "@babel/traverse@^7.7.2": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473" + integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.7" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.13" + "@babel/types" "^7.20.7" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" - integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== +"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" + integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -843,14 +969,6 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - "@dabh/diagnostics@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" @@ -897,172 +1015,221 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" - integrity sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g== +"@jest/console@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.1.tgz#cbc31d73f6329f693b3d34b365124de797704fff" + integrity sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^29.4.1" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^26.6.2" - jest-util "^26.6.2" + jest-message-util "^29.4.1" + jest-util "^29.4.1" slash "^3.0.0" -"@jest/core@^26.6.3": - version "26.6.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.6.3.tgz#7639fcb3833d748a4656ada54bde193051e45fad" - integrity sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw== +"@jest/core@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.1.tgz#91371179b5959951e211dfaeea4277a01dcca14f" + integrity sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA== dependencies: - "@jest/console" "^26.6.2" - "@jest/reporters" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^29.4.1" + "@jest/reporters" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" + ci-info "^3.2.0" exit "^0.1.2" - graceful-fs "^4.2.4" - jest-changed-files "^26.6.2" - jest-config "^26.6.3" - jest-haste-map "^26.6.2" - jest-message-util "^26.6.2" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-resolve-dependencies "^26.6.3" - jest-runner "^26.6.3" - jest-runtime "^26.6.3" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" - jest-watcher "^26.6.2" - micromatch "^4.0.2" - p-each-series "^2.1.0" - rimraf "^3.0.0" + graceful-fs "^4.2.9" + jest-changed-files "^29.4.0" + jest-config "^29.4.1" + jest-haste-map "^29.4.1" + jest-message-util "^29.4.1" + jest-regex-util "^29.2.0" + jest-resolve "^29.4.1" + jest-resolve-dependencies "^29.4.1" + jest-runner "^29.4.1" + jest-runtime "^29.4.1" + jest-snapshot "^29.4.1" + jest-util "^29.4.1" + jest-validate "^29.4.1" + jest-watcher "^29.4.1" + micromatch "^4.0.4" + pretty-format "^29.4.1" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/create-cache-key-function@^27.0.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz#7448fae15602ea95c828f5eceed35c202a820b31" - integrity sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ== +"@jest/create-cache-key-function@^29.2.1": + version "29.3.1" + resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.3.1.tgz#3a0970ea595ab3d9507244edbcef14d6b016cdc9" + integrity sha512-4i+E+E40gK13K78ffD/8cy4lSSqeWwyXeTZoq16tndiCP12hC8uQsPJdIu5C6Kf22fD8UbBk71so7s/6VwpUOQ== dependencies: - "@jest/types" "^27.5.1" + "@jest/types" "^29.3.1" -"@jest/environment@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" - integrity sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA== +"@jest/environment@^29.3.1": + version "29.3.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.3.1.tgz#eb039f726d5fcd14698acd072ac6576d41cfcaa6" + integrity sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag== dependencies: - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/fake-timers" "^29.3.1" + "@jest/types" "^29.3.1" "@types/node" "*" - jest-mock "^26.6.2" + jest-mock "^29.3.1" -"@jest/fake-timers@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" - integrity sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA== +"@jest/environment@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.1.tgz#52d232a85cdc995b407a940c89c86568f5a88ffe" + integrity sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg== dependencies: - "@jest/types" "^26.6.2" - "@sinonjs/fake-timers" "^6.0.1" + "@jest/fake-timers" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" - jest-message-util "^26.6.2" - jest-mock "^26.6.2" - jest-util "^26.6.2" + jest-mock "^29.4.1" -"@jest/globals@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" - integrity sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA== +"@jest/expect-utils@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.1.tgz#105b9f3e2c48101f09cae2f0a4d79a1b3a419cbb" + integrity sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ== dependencies: - "@jest/environment" "^26.6.2" - "@jest/types" "^26.6.2" - expect "^26.6.2" + jest-get-type "^29.2.0" -"@jest/reporters@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.6.2.tgz#1f518b99637a5f18307bd3ecf9275f6882a667f6" - integrity sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw== +"@jest/expect@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.1.tgz#3338fa20f547bb6e550c4be37d6f82711cc13c38" + integrity sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw== + dependencies: + expect "^29.4.1" + jest-snapshot "^29.4.1" + +"@jest/fake-timers@^29.3.1": + version "29.3.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.3.1.tgz#b140625095b60a44de820876d4c14da1aa963f67" + integrity sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A== + dependencies: + "@jest/types" "^29.3.1" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^29.3.1" + jest-mock "^29.3.1" + jest-util "^29.3.1" + +"@jest/fake-timers@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.1.tgz#7b673131e8ea2a2045858f08241cace5d518b42b" + integrity sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw== + dependencies: + "@jest/types" "^29.4.1" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.4.1" + jest-mock "^29.4.1" + jest-util "^29.4.1" + +"@jest/globals@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.1.tgz#3cd78c5567ab0249f09fbd81bf9f37a7328f4713" + integrity sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA== + dependencies: + "@jest/environment" "^29.4.1" + "@jest/expect" "^29.4.1" + "@jest/types" "^29.4.1" + jest-mock "^29.4.1" + +"@jest/reporters@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.1.tgz#50d509c08575c75e3cd2176d72ec3786419d5e04" + integrity sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" + "@jridgewell/trace-mapping" "^0.3.15" + "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.4" + glob "^7.1.3" + graceful-fs "^4.2.9" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.3" + istanbul-lib-instrument "^5.1.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - jest-haste-map "^26.6.2" - jest-resolve "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" + istanbul-reports "^3.1.3" + jest-message-util "^29.4.1" + jest-util "^29.4.1" + jest-worker "^29.4.1" slash "^3.0.0" - source-map "^0.6.0" string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^7.0.0" - optionalDependencies: - node-notifier "^8.0.0" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" -"@jest/source-map@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" - integrity sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA== +"@jest/schemas@^29.0.0": + version "29.0.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" + integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== + dependencies: + "@sinclair/typebox" "^0.24.1" + +"@jest/schemas@^29.4.0": + version "29.4.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.0.tgz#0d6ad358f295cc1deca0b643e6b4c86ebd539f17" + integrity sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ== dependencies: + "@sinclair/typebox" "^0.25.16" + +"@jest/source-map@^29.2.0": + version "29.2.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" + integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" - graceful-fs "^4.2.4" - source-map "^0.6.0" + graceful-fs "^4.2.9" -"@jest/test-result@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" - integrity sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ== +"@jest/test-result@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.1.tgz#997f19695e13b34779ceb3c288a416bd26c3238d" + integrity sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ== dependencies: - "@jest/console" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^29.4.1" + "@jest/types" "^29.4.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^26.6.3": - version "26.6.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz#98e8a45100863886d074205e8ffdc5a7eb582b17" - integrity sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw== +"@jest/test-sequencer@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.1.tgz#f7a006ec7058b194a10cf833c88282ef86d578fd" + integrity sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w== dependencies: - "@jest/test-result" "^26.6.2" - graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-runner "^26.6.3" - jest-runtime "^26.6.3" + "@jest/test-result" "^29.4.1" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" + slash "^3.0.0" -"@jest/transform@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" - integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== +"@jest/transform@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.1.tgz#e4f517841bb795c7dcdee1ba896275e2c2d26d4a" + integrity sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg== dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^26.6.2" - babel-plugin-istanbul "^6.0.0" + "@babel/core" "^7.11.6" + "@jest/types" "^29.4.1" + "@jridgewell/trace-mapping" "^0.3.15" + babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-regex-util "^26.0.0" - jest-util "^26.6.2" - micromatch "^4.0.2" - pirates "^4.0.1" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" + jest-regex-util "^29.2.0" + jest-util "^29.4.1" + micromatch "^4.0.4" + pirates "^4.0.4" slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" + write-file-atomic "^5.0.0" "@jest/types@^26.6.2": version "26.6.2" @@ -1086,6 +1253,30 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^29.3.1": + version "29.3.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.3.1.tgz#7c5a80777cb13e703aeec6788d044150341147e3" + integrity sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA== + dependencies: + "@jest/schemas" "^29.0.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jest/types@^29.4.1": + version "29.4.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.1.tgz#f9f83d0916f50696661da72766132729dcb82ecb" + integrity sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA== + dependencies: + "@jest/schemas" "^29.4.0" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jimp/bmp@^0.10.3": version "0.10.3" resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.10.3.tgz#79a23678e8389865c62e77b0dccc3e069dfc27f0" @@ -1658,24 +1849,64 @@ dependencies: core-js "^2.5.7" +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + "@jridgewell/resolve-uri@^3.0.3": version "3.0.5" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.11" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== -"@jridgewell/trace-mapping@^0.3.0": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" - integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== +"@jridgewell/trace-mapping@^0.3.0", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1835,124 +2066,130 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.3.0.tgz#0d740709fd65845c9cab215d5581e9fa80c59520" integrity sha512-7lmGpLL/7EHQcLVBxxOesgQQS7JSxzF/Xqx7VNMxAQbo14dzJEX6Ks0hb4LHqEMpCrKpErWXi4JxYCGrRJgx9A== -"@react-native-community/cli-debugger-ui@^7.0.3": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-7.0.3.tgz#3eeeacc5a43513cbcae56e5e965d77726361bcb4" - integrity sha512-G4SA6jFI0j22o+j+kYP8/7sxzbCDqSp2QiHA/X5E0lsGEd2o9qN2zbIjiFr8b8k+VVAYSUONhoC0+uKuINvmkA== +"@react-native-community/cli-clean@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-10.1.1.tgz#4c73ce93a63a24d70c0089d4025daac8184ff504" + integrity sha512-iNsrjzjIRv9yb5y309SWJ8NDHdwYtnCpmxZouQDyOljUdC9MwdZ4ChbtA4rwQyAwgOVfS9F/j56ML3Cslmvrxg== + dependencies: + "@react-native-community/cli-tools" "^10.1.1" + chalk "^4.1.2" + execa "^1.0.0" + prompts "^2.4.0" + +"@react-native-community/cli-config@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-10.1.1.tgz#08dcc5d7ca1915647dc06507ed853fe0c1488395" + integrity sha512-p4mHrjC+s/ayiNVG6T35GdEGdP6TuyBUg5plVGRJfTl8WT6LBfLYLk+fz/iETrEZ/YkhQIsQcEUQC47MqLNHog== + dependencies: + "@react-native-community/cli-tools" "^10.1.1" + chalk "^4.1.2" + cosmiconfig "^5.1.0" + deepmerge "^3.2.0" + glob "^7.1.3" + joi "^17.2.1" + +"@react-native-community/cli-debugger-ui@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-10.0.0.tgz#4bb6d41c7e46449714dc7ba5d9f5b41ef0ea7c57" + integrity sha512-8UKLcvpSNxnUTRy8CkCl27GGLqZunQ9ncGYhSrWyKrU9SWBJJGeZwi2k2KaoJi5FvF2+cD0t8z8cU6lsq2ZZmA== dependencies: serve-static "^1.13.1" -"@react-native-community/cli-hermes@^6.3.0": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-6.3.0.tgz#92b2f07d08626a60f6893c3e3d57c1538c8fb5a7" - integrity sha512-Uhbm9bubyZLZ12vFCIfWbE/Qi3SBTbYIN/TC08EudTLhv/KbPomCQnmFsnJ7AXQFuOZJs73mBxoEAYSbRbwyVA== +"@react-native-community/cli-doctor@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-10.1.1.tgz#6d60a2df74ea112d1f3b41491b6ee0948daa4fb3" + integrity sha512-9uvUhr6aJu4C7pCTsD9iRS/38tx1mzIrWuEQoh2JffTXg9MOq4jesvobkyKFRD90nOvqunEvfpnWnRdWcZO0Wg== dependencies: - "@react-native-community/cli-platform-android" "^6.3.0" - "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-config" "^10.1.1" + "@react-native-community/cli-platform-ios" "^10.1.1" + "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" + command-exists "^1.2.8" + envinfo "^7.7.2" + execa "^1.0.0" hermes-profile-transformer "^0.0.6" ip "^1.1.5" + node-stream-zip "^1.9.1" + ora "^5.4.1" + prompts "^2.4.0" + semver "^6.3.0" + strip-ansi "^5.2.0" + sudo-prompt "^9.0.0" + wcwidth "^1.0.1" -"@react-native-community/cli-platform-android@^6.3.0": - version "6.3.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-6.3.0.tgz#ab7d156bd69a392493323eeaba839a874c0e201f" - integrity sha512-d5ufyYcvrZoHznYm5bjBXaiHIJv552t5gYtQpnUsxBhHSQ8QlaNmlLUyeSPRDfOw4ND9b0tPHqs4ufwx6vp/fQ== +"@react-native-community/cli-hermes@^10.1.3": + version "10.1.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-10.1.3.tgz#440e2ff0f2ac9aba0ca1daee6ffaaf9c093437cc" + integrity sha512-uYl8MLBtuu6bj0tDUzVGf30nK5i9haBv7F0u+NCOq31+zVjcwiUplrCuLorb2dMLMF+Fno9wDxi66W9MxoW4nA== dependencies: - "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-platform-android" "^10.1.3" + "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" - execa "^1.0.0" - fs-extra "^8.1.0" - glob "^7.1.3" - jetifier "^1.6.2" - lodash "^4.17.15" - logkitty "^0.7.1" - slash "^3.0.0" - xmldoc "^1.1.2" + hermes-profile-transformer "^0.0.6" + ip "^1.1.5" -"@react-native-community/cli-platform-android@^7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-7.0.1.tgz#d165897edf401f9bceff1f361ef446528133cb52" - integrity sha512-nOr0aMkxAymCnbtsQwXBlyoRN2Y+IzC7Qz5T+/zyWwEbTY8SKQI8uV+8+qttUvzSvuXa2PeXsTWluuliOS8KCw== +"@react-native-community/cli-platform-android@10.0.0", "@react-native-community/cli-platform-android@10.1.3", "@react-native-community/cli-platform-android@^10.1.3": + version "10.1.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-10.1.3.tgz#8380799cd4d3f9a0ca568b0f5b4ae9e462ce3669" + integrity sha512-8YZEpBL6yd9l4CIoFcLOgrV8x2GDujdqrdWrNsNERDAbsiFwqAQvfjyyb57GAZVuEPEJCoqUlGlMCwOh3XQb9A== dependencies: - "@react-native-community/cli-tools" "^7.0.1" + "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" execa "^1.0.0" - fs-extra "^8.1.0" glob "^7.1.3" - jetifier "^1.6.2" - lodash "^4.17.15" logkitty "^0.7.1" - slash "^3.0.0" - xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-7.0.1.tgz#1c27af85229246b7a528e97f093e38859896cc93" - integrity sha512-PLRIbzrCzSedmpjuFtQqcqUD45G8q7sEciI1lf5zUbVMXqjIBwJWS7iz8235PyWwj8J4MNHohLC+oyRueFtbGg== +"@react-native-community/cli-platform-ios@10.0.0", "@react-native-community/cli-platform-ios@10.1.1", "@react-native-community/cli-platform-ios@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.1.1.tgz#39ed6810117d8e7330d3aa4d85818fb6ae358785" + integrity sha512-EB9/L8j1LqrqyfJtLRixU+d8FIP6Pr83rEgUgXgya/u8wk3h/bvX70w+Ff2skwjdPLr5dLUQ/n5KFX4r3bsNmA== dependencies: - "@react-native-community/cli-tools" "^7.0.1" + "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" execa "^1.0.0" glob "^7.1.3" - js-yaml "^3.13.1" - lodash "^4.17.15" ora "^5.4.1" - plist "^3.0.2" - xcode "^3.0.0" -"@react-native-community/cli-plugin-metro@^7.0.3": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-7.0.3.tgz#b381ed2f68a0b126e4fa238f1956a44846e1ef8a" - integrity sha512-HJrEkFbxv9DNixsGwO+Q0zCcZMghDltyzeB9yQ//D5ZR4ZUEuAIPrRDdEp9xVw0WkBxAIZs6KXLux2/yPMwLhA== +"@react-native-community/cli-plugin-metro@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.1.1.tgz#8b8689c921f6f0aeafa7ea9aabbde4c482b376b7" + integrity sha512-wEp47le4mzlelDF5sfkaaujUDYcuLep5HZqlcMx7PkL7BA3/fSHdDo1SblqaLgZ1ca6vFU+kfbHueLDct+xwFg== dependencies: - "@react-native-community/cli-server-api" "^7.0.3" - "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-server-api" "^10.1.1" + "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" - metro "^0.67.0" - metro-config "^0.67.0" - metro-core "^0.67.0" - metro-react-native-babel-transformer "^0.67.0" - metro-resolver "^0.67.0" - metro-runtime "^0.67.0" + execa "^1.0.0" + metro "0.73.7" + metro-config "0.73.7" + metro-core "0.73.7" + metro-react-native-babel-transformer "0.73.7" + metro-resolver "0.73.7" + metro-runtime "0.73.7" readline "^1.3.0" -"@react-native-community/cli-server-api@^7.0.3": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-7.0.3.tgz#ba9695a2fdfef22750d141153efd94baf641129b" - integrity sha512-JDrLsrkBgNxbG2u3fouoVGL9tKrXUrTsaNwr+oCV+3XyMwbVe42r/OaQ681/iW/7mHXjuVkDnMcp7BMg7e2yJg== +"@react-native-community/cli-server-api@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-10.1.1.tgz#e382269de281bb380c2e685431364fbbb8c1cb3a" + integrity sha512-NZDo/wh4zlm8as31UEBno2bui8+ufzsZV+KN7QjEJWEM0levzBtxaD+4je0OpfhRIIkhaRm2gl/vVf7OYAzg4g== dependencies: - "@react-native-community/cli-debugger-ui" "^7.0.3" - "@react-native-community/cli-tools" "^6.2.0" + "@react-native-community/cli-debugger-ui" "^10.0.0" + "@react-native-community/cli-tools" "^10.1.1" compression "^1.7.1" connect "^3.6.5" errorhandler "^1.5.0" - nocache "^2.1.0" + nocache "^3.0.1" pretty-format "^26.6.2" serve-static "^1.13.1" ws "^7.5.1" -"@react-native-community/cli-tools@^6.2.0": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-6.2.0.tgz#8f4adc2d83ab96e5654348533c8fa602742c4fce" - integrity sha512-08ssz4GMEnRxC/1FgTTN/Ud7mExQi5xMphItPjfHiTxpZPhrFn+IMx6mya0ncFEhhxQ207wYlJMRLPRRdBZ8oA== +"@react-native-community/cli-tools@^10.1.1": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-10.1.1.tgz#fa66e509c0d3faa31f7bb87ed7d42ad63f368ddd" + integrity sha512-+FlwOnZBV+ailEzXjcD8afY2ogFEBeHOw/8+XXzMgPaquU2Zly9B+8W089tnnohO3yfiQiZqkQlElP423MY74g== dependencies: appdirsjs "^1.2.4" chalk "^4.1.2" - lodash "^4.17.15" - mime "^2.4.1" - node-fetch "^2.6.0" - open "^6.2.0" - semver "^6.3.0" - shell-quote "1.6.1" - -"@react-native-community/cli-tools@^7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-7.0.1.tgz#73790d6ca2825e42a70a770c1b403a6777e690d6" - integrity sha512-0xra4hKNA5PR2zYVXsDMNiXMGaDNoNRYMY6eTP2aVIxQbqIcVMDWSyCA8wMWX5iOpMWg0cZGaQ6a77f3Rlb34g== - dependencies: - appdirsjs "^1.2.4" - chalk "^4.1.2" - lodash "^4.17.15" + find-up "^5.0.0" mime "^2.4.1" node-fetch "^2.6.0" open "^6.2.0" @@ -1960,59 +2197,48 @@ semver "^6.3.0" shell-quote "^1.7.3" -"@react-native-community/cli-types@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-6.0.0.tgz#90269fbdc7229d5e3b8f2f3e029a94083551040d" - integrity sha512-K493Fk2DMJC0ZM8s8gnfseKxGasIhuDaCUDeLZcoCSFlrjKEuEs1BKKEJiev0CARhKEXKOyyp/uqYM9nWhisNw== +"@react-native-community/cli-types@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-10.0.0.tgz#046470c75ec18f8b3bd906e54e43a6f678e01a45" + integrity sha512-31oUM6/rFBZQfSmDQsT1DX/5fjqfxg7sf2u8kTPJK7rXVya5SRpAMaCXsPAG0omsmJxXt+J9HxUi3Ic+5Ux5Iw== dependencies: - ora "^3.4.0" + joi "^17.2.1" -"@react-native-community/cli@^7.0.3": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-7.0.3.tgz#1addb462d71786fcbbd266fbceb41819b8cf7839" - integrity sha512-WyJOA829KAhU1pw2MDQt0YhOS9kyR2KqyqgJyTuQhzFVCBPX4F5aDEkZYYn4jdldaDHCPrLJ3ho3gxYTXy+x7w== - dependencies: - "@react-native-community/cli-debugger-ui" "^7.0.3" - "@react-native-community/cli-hermes" "^6.3.0" - "@react-native-community/cli-plugin-metro" "^7.0.3" - "@react-native-community/cli-server-api" "^7.0.3" - "@react-native-community/cli-tools" "^6.2.0" - "@react-native-community/cli-types" "^6.0.0" - appdirsjs "^1.2.4" +"@react-native-community/cli@10.0.0", "@react-native-community/cli@10.1.3": + version "10.1.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-10.1.3.tgz#ad610c46da9fc7c717272024ec757dc646726506" + integrity sha512-kzh6bYLGN1q1q0IiczKSP1LTrovFeVzppYRTKohPI9VdyZwp7b5JOgaQMB/Ijtwm3MxBDrZgV9AveH/eUmUcKQ== + dependencies: + "@react-native-community/cli-clean" "^10.1.1" + "@react-native-community/cli-config" "^10.1.1" + "@react-native-community/cli-debugger-ui" "^10.0.0" + "@react-native-community/cli-doctor" "^10.1.1" + "@react-native-community/cli-hermes" "^10.1.3" + "@react-native-community/cli-plugin-metro" "^10.1.1" + "@react-native-community/cli-server-api" "^10.1.1" + "@react-native-community/cli-tools" "^10.1.1" + "@react-native-community/cli-types" "^10.0.0" chalk "^4.1.2" - command-exists "^1.2.8" - commander "^2.19.0" - cosmiconfig "^5.1.0" - deepmerge "^3.2.0" - envinfo "^7.7.2" + commander "^9.4.1" execa "^1.0.0" find-up "^4.1.0" fs-extra "^8.1.0" - glob "^7.1.3" graceful-fs "^4.1.3" - joi "^17.2.1" - leven "^3.1.0" - lodash "^4.17.15" - minimist "^1.2.0" - node-stream-zip "^1.9.1" - ora "^3.4.0" - pretty-format "^26.6.2" prompts "^2.4.0" semver "^6.3.0" - serve-static "^1.13.1" - strip-ansi "^5.2.0" - sudo-prompt "^9.0.0" - wcwidth "^1.0.1" -"@react-native-windows/cli@0.68.2": - version "0.68.2" - resolved "https://registry.yarnpkg.com/@react-native-windows/cli/-/cli-0.68.2.tgz#6c47f9e5c43a4132892a9bf1df5f58ead09b851e" - integrity sha512-hbWUy4EiWapkLfP5rouMb7yRiVvltOAJex1WlwfEfbVLWPg0WAf1mtMfc10VViorFk6xNL9JjVPzbaUO4tO58A== - dependencies: - "@react-native-windows/fs" "0.68.0" - "@react-native-windows/package-utils" "0.68.0" - "@react-native-windows/telemetry" "0.68.2" - "@xmldom/xmldom" "^0.7.5" +"@react-native-windows/cli@0.71.0": + version "0.71.0" + resolved "https://registry.yarnpkg.com/@react-native-windows/cli/-/cli-0.71.0.tgz#2e18423eeef6048b206edf7f14e4efe4610d6ff2" + integrity sha512-NlkapPGJGC4Gg6xW5gDqFziNbUFFCU3bXBwKVBt9WZeSrmxKfW1Nc0nSWVxt8Tn0pfF2480px0N/HDY/rfwpYg== + dependencies: + "@react-native-windows/codegen" "0.71.0" + "@react-native-windows/fs" "0.71.0" + "@react-native-windows/package-utils" "0.71.0" + "@react-native-windows/telemetry" "0.71.0" + "@typescript-eslint/eslint-plugin" "^5.30.5" + "@typescript-eslint/parser" "^5.30.5" + "@xmldom/xmldom" "^0.7.7" chalk "^4.1.0" cli-spinners "^2.2.0" envinfo "^7.5.0" @@ -2030,61 +2256,76 @@ xml-parser "^1.2.1" xpath "^0.0.27" -"@react-native-windows/find-repo-root@0.68.0": - version "0.68.0" - resolved "https://registry.yarnpkg.com/@react-native-windows/find-repo-root/-/find-repo-root-0.68.0.tgz#efbc5af3a4952a7e7712f8d6bd73b8de858f3d7d" - integrity sha512-YuSUlrRdr6SNPapf4b77yi3U/rfTeYhetBpSwm1L/jq3UT8Wm4Z/JSBZg2UioYIeQV6xrNRjlLQHKjDBzmxOkQ== +"@react-native-windows/codegen@0.71.0": + version "0.71.0" + resolved "https://registry.yarnpkg.com/@react-native-windows/codegen/-/codegen-0.71.0.tgz#f31aecc0c595642a073c2531ee3dab0469843ffd" + integrity sha512-sLheajiQwC3fXZDm9cZ6uZQQ3LrL2Mlm8t24FS6p7g3JqshyRvLeYr6EFaI7RzvWbvzAW1tBUTVVVMvhWrE2jQ== dependencies: + "@react-native-windows/fs" "0.71.0" + "@typescript-eslint/eslint-plugin" "^5.30.5" + "@typescript-eslint/parser" "^5.30.5" + chalk "^4.1.0" + globby "^11.0.4" + mustache "^4.0.1" + source-map-support "^0.5.19" + yargs "^16.2.0" + +"@react-native-windows/find-repo-root@0.71.0": + version "0.71.0" + resolved "https://registry.yarnpkg.com/@react-native-windows/find-repo-root/-/find-repo-root-0.71.0.tgz#51faaa2406f180714433d6df71dedb7b3a98353a" + integrity sha512-znR9i2J7nA0C7OXOlDy8aHUL7eYHDZrn1CAv2VKyUC0aKxuA0MHT4sJaXLzUUknQu6XUjrK2eDLKaoaEfjE45Q== + dependencies: + "@react-native-windows/fs" "0.71.0" + "@typescript-eslint/eslint-plugin" "^5.30.5" + "@typescript-eslint/parser" "^5.30.5" find-up "^4.1.0" -"@react-native-windows/fs@0.68.0": - version "0.68.0" - resolved "https://registry.yarnpkg.com/@react-native-windows/fs/-/fs-0.68.0.tgz#bdf722b9c7475e66de9a580b37cdb7136af797a4" - integrity sha512-2ZnL0NVs6zJQgXypyX1Arh7Xyo8mG1yKw1ephbOX5U6J7HLlnsx3X1sANGIz+JcAjA9jEJ08r9DHbH93NvzFWA== +"@react-native-windows/fs@0.71.0": + version "0.71.0" + resolved "https://registry.yarnpkg.com/@react-native-windows/fs/-/fs-0.71.0.tgz#7aaeb83c33a77dd032d987efdd0528e22430c2a1" + integrity sha512-hQkJ9nSUzBs+UUKJhhH4N+59lrcSws94x2kOu8EbjlK8ZNqQgwm6WPDmyKD10xdZnnuNs8xA47WZIUSn028nYw== dependencies: + "@typescript-eslint/eslint-plugin" "^5.30.5" + "@typescript-eslint/parser" "^5.30.5" graceful-fs "^4.2.8" -"@react-native-windows/package-utils@0.68.0": - version "0.68.0" - resolved "https://registry.yarnpkg.com/@react-native-windows/package-utils/-/package-utils-0.68.0.tgz#072b838fd106aedaff746ae6fab5173b6c61880a" - integrity sha512-IgcZib3Ydhosk8HoN/9l/im/EzeualqQPku/aRUyLehKjYEi7YksUDEM3un9bWyAwCeT9gpIjbEnEFwODQdvZg== +"@react-native-windows/package-utils@0.71.0": + version "0.71.0" + resolved "https://registry.yarnpkg.com/@react-native-windows/package-utils/-/package-utils-0.71.0.tgz#587900ddca58058633b7c990c15898ce4d1fbb0e" + integrity sha512-HBn8lTvCA6tf+yu3mrLvZzhsUtOPBrMSn9zSFL0f6LDI9C4CHaGIzEqRmAwfmG3CHB1xc2get9VGKRMKQqDmlQ== dependencies: - "@react-native-windows/find-repo-root" "0.68.0" - "@react-native-windows/fs" "0.68.0" + "@react-native-windows/find-repo-root" "0.71.0" + "@react-native-windows/fs" "0.71.0" + "@typescript-eslint/eslint-plugin" "^5.30.5" + "@typescript-eslint/parser" "^5.30.5" get-monorepo-packages "^1.2.0" lodash "^4.17.15" -"@react-native-windows/telemetry@0.68.2": - version "0.68.2" - resolved "https://registry.yarnpkg.com/@react-native-windows/telemetry/-/telemetry-0.68.2.tgz#c693f66e9e4032cce6256ef777c0033b7e5fb262" - integrity sha512-tkd7eJM3Jhs6aenL0Iz8msRbK22GGgYvaSViCLBkenlwOdF0AE/r0+NAGGXzOxHz89GIDYUhj5rtpln83NtWXA== +"@react-native-windows/telemetry@0.71.0": + version "0.71.0" + resolved "https://registry.yarnpkg.com/@react-native-windows/telemetry/-/telemetry-0.71.0.tgz#dd4997526d5fc08ad5de8e7db505d59b51a9d602" + integrity sha512-lVsAAhIz7CUX5yzONqIkl9zhgrIKSjfONWxVYoTUGTq/PPHqOfGNTw751DSWzlmvUZgxG1zzVfYPit1Blw07DA== dependencies: - "@react-native-windows/fs" "0.68.0" - "@xmldom/xmldom" "^0.7.5" + "@react-native-windows/fs" "0.71.0" + "@typescript-eslint/eslint-plugin" "^5.30.5" + "@typescript-eslint/parser" "^5.30.5" + "@xmldom/xmldom" "^0.7.7" applicationinsights "^2.3.1" ci-info "^3.2.0" envinfo "^7.8.1" lodash "^4.17.21" - node-machine-id "^1.1.12" os-locale "^5.0.0" xpath "^0.0.27" -"@react-native-windows/virtualized-list@0.68.0": - version "0.68.0" - resolved "https://registry.yarnpkg.com/@react-native-windows/virtualized-list/-/virtualized-list-0.68.0.tgz#06b63d21bad896c2bd37d6b5544f90f0f4fa838b" - integrity sha512-XKqwn7FWDUVanr42sNT+547je2YwCq38I3YR+iq1WcmH5TiQ5E+KF5jXvPv7oOFuWJzzXzjiRZUfEwMv2qqoMg== - dependencies: - invariant "^2.2.4" - "@react-native/assets@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e" integrity sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ== -"@react-native/normalize-color@*", "@react-native/normalize-color@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.0.0.tgz#da955909432474a9a0fe1cbffc66576a0447f567" - integrity sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw== +"@react-native/normalize-color@*", "@react-native/normalize-color@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" + integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== "@react-native/polyfills@2.0.0": version "2.0.0" @@ -2197,6 +2438,16 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== + +"@sinclair/typebox@^0.25.16": + version "0.25.21" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272" + integrity sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g== + "@sindresorhus/is@^3.0.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-3.1.2.tgz#548650de521b344e3781fbdb0ece4aa6f729afb8" @@ -2209,10 +2460,24 @@ dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" - integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== +"@sinonjs/commons@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== + dependencies: + "@sinonjs/commons" "^2.0.0" + +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== dependencies: "@sinonjs/commons" "^1.7.0" @@ -2223,18 +2488,13 @@ dependencies: defer-to-connect "^2.0.0" -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": - version "7.1.18" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" - integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== +"@types/babel__core@^7.1.14": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" + integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" @@ -2254,7 +2514,7 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": version "7.14.2" resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== @@ -2294,10 +2554,10 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== +"@types/graceful-fs@^4.1.3": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" @@ -2330,18 +2590,18 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^26.0.0": - version "26.0.24" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" - integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== +"@types/jest@^29.4.0": + version "29.4.0" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.4.0.tgz#a8444ad1704493e84dbf07bb05990b275b3b9206" + integrity sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ== dependencies: - jest-diff "^26.0.0" - pretty-format "^26.0.0" + expect "^29.0.0" + pretty-format "^29.0.0" -"@types/json-schema@^7.0.3": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/keyv@*": version "3.1.1" @@ -2378,10 +2638,10 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== -"@types/prettier@^2.0.0": - version "2.4.4" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" - integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== +"@types/prettier@^2.1.5": + version "2.7.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" + integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== "@types/prop-types@*": version "15.7.3" @@ -2395,17 +2655,10 @@ dependencies: "@types/node" "*" -"@types/react-native@^0.67.3": - version "0.67.3" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.3.tgz#baba111c8ce1a45a6034c15f6f0ad98826239780" - integrity sha512-hF4uOZFl2PPQtGWOtLoafrlCJeU815X3PgfVePM+7EhOIZhYXKH7+p3R3cZSnwVnrU5Ep/JfiHimMDliY3o8oQ== - dependencies: - "@types/react" "*" - -"@types/react@*", "@types/react@^17.0.0": - version "17.0.39" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce" - integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug== +"@types/react@18.0.27": + version "18.0.27" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.27.tgz#d9425abe187a00f8a5ec182b010d4fd9da703b71" + integrity sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -2443,6 +2696,11 @@ resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.0.9.tgz#12621e55b2ef8f6c98bd17fe23fa720c6cba16bd" integrity sha512-HopIwBE7GUXsscmt/J0DhnFXLSmO04AfxT6b8HAprknwka7pqEWquWDMXxCjd+NUHK9MkCe1SDKKsMiNmCItbQ== +"@types/semver@^7.3.12": + version "7.3.13" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" + integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== + "@types/stack-utils@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" @@ -2479,6 +2737,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^17.0.8": + version "17.0.19" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.19.tgz#8dbecdc9ab48bee0cb74f6e3327de3fa0d0c98ae" + integrity sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ== + dependencies: + "@types/yargs-parser" "*" + "@types/yauzl@^2.9.1": version "2.9.1" resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af" @@ -2497,6 +2762,21 @@ regexpp "^2.0.1" tsutils "^3.14.0" +"@typescript-eslint/eslint-plugin@^5.30.5": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.0.tgz#54f8368d080eb384a455f60c2ee044e948a8ce67" + integrity sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ== + dependencies: + "@typescript-eslint/scope-manager" "5.48.0" + "@typescript-eslint/type-utils" "5.48.0" + "@typescript-eslint/utils" "5.48.0" + debug "^4.3.4" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + regexpp "^3.2.0" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/experimental-utils@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.1.0.tgz#0837229f0e75a32db0db9bf662ad0eface914453" @@ -2516,6 +2796,39 @@ "@typescript-eslint/typescript-estree" "2.1.0" eslint-visitor-keys "^1.0.0" +"@typescript-eslint/parser@^5.30.5": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.48.0.tgz#02803355b23884a83e543755349809a50b7ed9ba" + integrity sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg== + dependencies: + "@typescript-eslint/scope-manager" "5.48.0" + "@typescript-eslint/types" "5.48.0" + "@typescript-eslint/typescript-estree" "5.48.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.48.0": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz#607731cb0957fbc52fd754fd79507d1b6659cecf" + integrity sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow== + dependencies: + "@typescript-eslint/types" "5.48.0" + "@typescript-eslint/visitor-keys" "5.48.0" + +"@typescript-eslint/type-utils@5.48.0": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.48.0.tgz#40496dccfdc2daa14a565f8be80ad1ae3882d6d6" + integrity sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g== + dependencies: + "@typescript-eslint/typescript-estree" "5.48.0" + "@typescript-eslint/utils" "5.48.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.48.0": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.0.tgz#d725da8dfcff320aab2ac6f65c97b0df30058449" + integrity sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw== + "@typescript-eslint/typescript-estree@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.1.0.tgz#88e676cc9760516711f6fe43958adc31b93de8e5" @@ -2526,6 +2839,41 @@ lodash.unescape "4.0.1" semver "^6.2.0" +"@typescript-eslint/typescript-estree@5.48.0": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz#a7f04bccb001003405bb5452d43953a382c2fac2" + integrity sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw== + dependencies: + "@typescript-eslint/types" "5.48.0" + "@typescript-eslint/visitor-keys" "5.48.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.48.0": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.0.tgz#eee926af2733f7156ad8d15e51791e42ce300273" + integrity sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ== + dependencies: + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.48.0" + "@typescript-eslint/types" "5.48.0" + "@typescript-eslint/typescript-estree" "5.48.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.48.0": + version "5.48.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz#4446d5e7f6cadde7140390c0e284c8702d944904" + integrity sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q== + dependencies: + "@typescript-eslint/types" "5.48.0" + eslint-visitor-keys "^3.3.0" + "@wdio/config@5.22.4": version "5.22.4" resolved "https://registry.yarnpkg.com/@wdio/config/-/config-5.22.4.tgz#053d4ba0a8b0dae6be740b1b7b9ab25abac2799e" @@ -2603,10 +2951,10 @@ dependencies: "@wdio/logger" "6.0.16" -"@xmldom/xmldom@^0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d" - integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A== +"@xmldom/xmldom@^0.7.7": + version "0.7.9" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.9.tgz#7f9278a50e737920e21b297b8a35286e9942c056" + integrity sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA== JSONStream@^1.0.4, JSONStream@^1.3.4, JSONStream@^1.3.5: version "1.3.5" @@ -2616,11 +2964,6 @@ JSONStream@^1.0.4, JSONStream@^1.3.4, JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - abbrev@1, abbrev@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -2646,33 +2989,20 @@ accepts@^1.3.7, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.34" negotiator "0.6.3" -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - acorn-jsx@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== -acorn-walk@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - acorn@^7.1.1: version "7.4.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== -acorn@^8.2.4: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== +acorn@^8.5.0: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== adbkit-apkreader@^3.1.2: version "3.2.0" @@ -2695,13 +3025,6 @@ agent-base@5: resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c" integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g== -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - agent-base@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -2799,10 +3122,10 @@ ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.0, ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" @@ -2819,6 +3142,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + ansi-wrap@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" @@ -2839,14 +3167,6 @@ any-base@^1.1.0: resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - anymatch@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -3565,11 +3885,6 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -3589,16 +3904,6 @@ array-includes@^3.0.3, array-includes@^3.1.1: es-abstract "^1.17.0" is-string "^1.0.5" -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -3707,17 +4012,17 @@ async-lock@^1.0.0, async-lock@^1.2.2: resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.4.tgz#80d0d612383045dd0c30eb5aad08510c1397cb91" integrity sha512-UBQJC2pbeyGutIfYmErGc9RaJYnpZ1FHaxuKwb0ahvGiiCkPUf3p67Io+YLPmmv3RHY+mF6JEtNW8FlHsraAaA== -async@^2.4.0, async@^2.6.0, async@^2.6.2, async@^2.6.3: +async@^2.6.0, async@^2.6.2, async@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== dependencies: lodash "^4.17.14" -async@^3.1.0, async@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== +async@^3.1.0, async@^3.2.0, async@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== asyncbox@2.x, asyncbox@^2.0.2, asyncbox@^2.0.4, asyncbox@^2.3.0, asyncbox@^2.3.1, asyncbox@^2.3.2, asyncbox@^2.5.2, asyncbox@^2.5.3, asyncbox@^2.6.0: version "2.6.0" @@ -3772,18 +4077,17 @@ babel-core@^7.0.0-bridge.0: resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== -babel-jest@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" - integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== +babel-jest@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.1.tgz#01fa167e27470b35c2d4a1b841d9586b1764da19" + integrity sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg== dependencies: - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/babel__core" "^7.1.7" - babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^26.6.2" + "@jest/transform" "^29.4.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.4.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" slash "^3.0.0" babel-plugin-dynamic-import-node@^2.3.3: @@ -3793,7 +4097,7 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-istanbul@^6.0.0: +babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== @@ -3804,14 +4108,14 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" - integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== +babel-plugin-jest-hoist@^29.4.0: + version "29.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz#3fd3dfcedf645932df6d0c9fc3d9a704dd860248" + integrity sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" - "@types/babel__core" "^7.0.0" + "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: @@ -3870,12 +4174,12 @@ babel-preset-fbjs@^3.4.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" - integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== +babel-preset-jest@^29.4.0: + version "29.4.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz#c2b03c548b02dea0a18ae21d5759c136f9251ee4" + integrity sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA== dependencies: - babel-plugin-jest-hoist "^26.6.2" + babel-plugin-jest-hoist "^29.4.0" babel-preset-current-node-syntax "^1.0.0" babel-runtime@^6.26.0: @@ -3891,7 +4195,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.3.1, base64-js@^1.5.1: +base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -3933,7 +4237,7 @@ before-after-hook@^2.0.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A== -big-integer@1.6.x, big-integer@^1.6.44: +big-integer@^1.6.44: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== @@ -4003,20 +4307,13 @@ boxen@^1.2.1: term-size "^1.2.0" widest-line "^2.0.0" -bplist-creator@0.1.0, bplist-creator@^0: +bplist-creator@^0: version "0.1.0" resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.1.0.tgz#018a2d1b587f769e379ef5519103730f8963ba1e" integrity sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg== dependencies: stream-buffers "2.2.x" -bplist-parser@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.3.1.tgz#e1c90b2ca2a9f9474cc72f6862bbf3fee8341fd1" - integrity sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA== - dependencies: - big-integer "1.6.x" - bplist-parser@^0.2: version "0.2.0" resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" @@ -4055,21 +4352,15 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browserslist@^4.17.5: - version "4.18.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" - integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ== +browserslist@^4.21.3: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== dependencies: - caniuse-lite "^1.0.30001280" - electron-to-chromium "^1.3.896" - escalade "^3.1.1" - node-releases "^2.0.1" - picocolors "^1.0.0" + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" bser@2.1.1: version "2.1.1" @@ -4106,14 +4397,6 @@ buffer@^5.1.0, buffer@^5.2.0, buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.0.2" ieee754 "^1.1.4" -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - bufferpack@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/bufferpack/-/bufferpack-0.0.6.tgz#fb3d8738a0e1e4e03bcff99f9a75f9ec18a9d73e" @@ -4246,22 +4529,15 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001280: - version "1.0.30001312" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" - integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" +caniuse-lite@^1.0.30001400: + version "1.0.30001442" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz#40337f1cf3be7c637b061e2f78582dc1daec0614" + integrity sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow== capture-stack-trace@^1.0.0: version "1.0.1" @@ -4365,10 +4641,10 @@ circular-json@^0.5.9: resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d" integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ== -cjs-module-lexer@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" - integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== class-utils@^0.3.5: version "0.3.6" @@ -4484,6 +4760,15 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" @@ -4633,11 +4918,16 @@ command-exists@^1.2.8: resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== -commander@^2.11.0, commander@^2.19.0: +commander@^2.11.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^9.4.1: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" @@ -4846,13 +5136,18 @@ conventional-commits-parser@^3.0.0, conventional-commits-parser@^3.0.7: through2 "^3.0.0" trim-off-newlines "^1.0.0" -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -4955,7 +5250,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4979,23 +5274,6 @@ css-value@^0.0.1: resolved "https://registry.yarnpkg.com/css-value/-/css-value-0.0.1.tgz#5efd6c2eea5ea1fd6b6ac57ec0427b18452424ea" integrity sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo= -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - csstype@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8" @@ -5018,15 +5296,6 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - dateformat@^3.0.0, dateformat@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" @@ -5051,12 +5320,12 @@ debug@3.1.0, debug@=3.1.0: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: - ms "^2.1.1" + ms "2.1.2" debug@^3.1.0, debug@^3.1.1: version "3.2.6" @@ -5065,6 +5334,13 @@ debug@^3.1.0, debug@^3.1.1: dependencies: ms "^2.1.1" +debug@~4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -5083,11 +5359,6 @@ decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decimal.js@^10.2.1: - version "10.3.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" - integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== - decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -5100,6 +5371,11 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" @@ -5193,10 +5469,10 @@ depd@~2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -deprecated-react-native-prop-types@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz#c10c6ee75ff2b6de94bb127f142b814e6e08d9ab" - integrity sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA== +deprecated-react-native-prop-types@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.1.tgz#a275f84cd8519cd1665e8df3c99e9067d57a23ec" + integrity sha512-J0jCJcsk4hMlIb7xwOZKLfMpuJn6l8UtrPEzzQV5ewz5gvKNYakhBuq9h2rWX7YwHHJZFhU5W8ye7dB9oN8VcQ== dependencies: "@react-native/normalize-color" "*" invariant "*" @@ -5266,10 +5542,10 @@ diagnostic-channel@1.1.0: dependencies: semver "^5.3.0" -diff-sequences@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" - integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== +diff-sequences@^29.3.1: + version "29.3.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" + integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== dir-glob@^2.0.0: version "2.2.2" @@ -5312,13 +5588,6 @@ dom-walk@^0.1.0: resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - dot-prop@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4" @@ -5383,10 +5652,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.896: - version "1.4.75" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz#d1ad9bb46f2f1bf432118c2be21d27ffeae82fdd" - integrity sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q== +electron-to-chromium@^1.4.251: + version "1.4.284" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -5395,10 +5664,10 @@ emitter-listener@^1.0.1, emitter-listener@^1.1.1: dependencies: shimmer "^1.2.0" -emittery@^0.7.1: - version "0.7.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" - integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^7.0.1, emoji-regex@^7.0.2: version "7.0.3" @@ -5561,18 +5830,6 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - eslint-config-airbnb-base@^14.0.0: version "14.2.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz#fe89c24b3f9dc8008c9c0d0d88c28f95ed65e9c4" @@ -5686,12 +5943,12 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" - integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== +eslint-scope@^5.0.0, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: - esrecurse "^4.1.0" + esrecurse "^4.3.0" estraverse "^4.1.1" eslint-utils@^1.4.0, eslint-utils@^1.4.2: @@ -5701,11 +5958,28 @@ eslint-utils@^1.4.0, eslint-utils@^1.4.2: dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + eslint@6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.3.0.tgz#1f1a902f67bfd4c354e7288b81e40654d927eb6a" @@ -5758,7 +6032,7 @@ espree@^6.1.1: acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" -esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: +esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -5770,14 +6044,14 @@ esquery@^1.0.1: dependencies: estraverse "^5.1.0" -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== +esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -5807,16 +6081,6 @@ eventemitter3@^3.1.2: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== - execa@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" @@ -5887,6 +6151,21 @@ execa@^4.0.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + exif-parser@^0.1.12: version "0.1.12" resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" @@ -5910,17 +6189,16 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" - integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== +expect@^29.0.0, expect@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.1.tgz#58cfeea9cbf479b64ed081fd1e074ac8beb5a1fe" + integrity sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A== dependencies: - "@jest/types" "^26.6.2" - ansi-styles "^4.0.0" - jest-get-type "^26.3.0" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-regex-util "^26.0.0" + "@jest/expect-utils" "^29.4.1" + jest-get-type "^29.2.0" + jest-matcher-utils "^29.4.1" + jest-message-util "^29.4.1" + jest-util "^29.4.1" express@^4.16.2: version "4.17.1" @@ -6042,19 +6320,18 @@ fast-deep-equal@^3.1.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.0.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== +fast-glob@^3.0.3, fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -6204,6 +6481,14 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + find-versions@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" @@ -6238,15 +6523,10 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== -flow-parser@0.*: - version "0.171.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.171.0.tgz#5ffae78f050e43513abc86add9f19a97fcbabcdb" - integrity sha512-cqEsgic6HH81Pz0IQLeyuoh0O8Y7ECAIdZ0idPQ9P1jZ/kHB9KK0hwqnjVtqTGog15JURkIxvyXm+9pAb6uuSQ== - -flow-parser@^0.121.0: - version "0.121.0" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.121.0.tgz#9f9898eaec91a9f7c323e9e992d81ab5c58e618f" - integrity sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg== +flow-parser@0.*, flow-parser@^0.185.0: + version "0.185.2" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.185.2.tgz#cb7ee57f77377d6c5d69a469e980f6332a15e492" + integrity sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ== flush-write-stream@^1.0.0: version "1.1.1" @@ -6352,15 +6632,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - integrity sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - fs-extra@^8.0.0, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -6401,7 +6672,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@2.x, fsevents@^2.1.2, fsevents@^2.3.2: +fsevents@2.x, fsevents@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -6521,6 +6792,11 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -6545,10 +6821,10 @@ git-log-parser@^1.2.0: through2 "~2.0.0" traverse "~0.6.6" -glob-parent@^5.0.0, glob-parent@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== +glob-parent@^5.0.0, glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" @@ -6609,6 +6885,18 @@ globby@^10.0.0: merge2 "^1.2.3" slash "^3.0.0" +globby@^11.0.4, globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + globby@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" @@ -6665,11 +6953,6 @@ grapheme-splitter@^1.0.2: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - handlebars@^4.7.6: version "4.7.6" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" @@ -6763,22 +7046,17 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hermes-engine@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.11.0.tgz#bb224730d230a02a5af02c4e090d1f52d57dd3db" - integrity sha512-7aMUlZja2IyLYAcZ69NBnwJAR5ZOYlSllj0oMpx08a8HzxHOys0eKCzfphrf6D0vX1JGO1QQvVsQKe6TkYherw== +hermes-estree@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.8.0.tgz#530be27243ca49f008381c1f3e8b18fb26bf9ec0" + integrity sha512-W6JDAOLZ5pMPMjEiQGLCXSSV7pIBEgRR5zGkxgmzGSXHOxqV5dC/M1Zevqpbm9TZDE5tu358qZf8Vkzmsc+u7Q== -hermes-estree@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.5.0.tgz#36432a2b12f01b217244da098924efdfdfc12327" - integrity sha512-1h8rvG23HhIR5K6Kt0e5C7BC72J1Ath/8MmSta49vxXp/j6wl7IMHvIRFYBQr35tWnQY97dSGR2uoAJ5pHUQkg== - -hermes-parser@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.5.0.tgz#8b678dd8b29a08b57cbaf60adba4896494c59a53" - integrity sha512-ARnJBScKAkkq8j3BHrNGBUv/4cSpZNbKDsVizEtzmsFeqC67Dopa5s4XRe+e3wN52Dh5Mj2kDB5wJvhcxwDkPg== +hermes-parser@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.8.0.tgz#116dceaba32e45b16d6aefb5c4c830eaeba2d257" + integrity sha512-yZKalg1fTYG5eOiToLUaw69rQfZq/fi+/NtEXRU7N87K/XobNRhRWorh80oSge2lWUiZfTgUvRJH+XgZWrhoqA== dependencies: - hermes-estree "0.5.0" + hermes-estree "0.8.0" hermes-profile-transformer@^0.0.6: version "0.0.6" @@ -6804,13 +7082,6 @@ hosted-git-info@^3.0.0: dependencies: lru-cache "^6.0.0" -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" @@ -6864,15 +7135,6 @@ http-proxy-agent@^3.0.0: agent-base "5" debug "4" -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -6911,19 +7173,16 @@ https-proxy-agent@^4.0.0: agent-base "5" debug "4" -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -6945,7 +7204,7 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.4, ieee754@^1.2.1: +ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -6977,10 +7236,10 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.1.1, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== image-size@^0.6.0: version "0.6.3" @@ -7200,13 +7459,6 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - is-cidr@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.1.tgz#e92ef121bdec2782271a77ce487a8b8df3718ab7" @@ -7226,6 +7478,13 @@ is-core-module@^2.8.1: dependencies: has "^1.0.3" +is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -7317,10 +7576,10 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" @@ -7395,11 +7654,6 @@ is-plain-object@^4.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-4.1.1.tgz#1a14d6452cbd50790edc7fdaa0aed5a40a35ebb5" integrity sha512-5Aw8LLVsDlZsETVMhoMXzqsXwQqr/0vlnBYzIXJbYo2F4yYlhLHs+Ez7Bod7IIQKWkJbJfxrWD7pA1Dw1TKrwA== -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" @@ -7446,7 +7700,7 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -7521,16 +7775,6 @@ istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" - istanbul-lib-instrument@^5.0.4: version "5.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" @@ -7542,6 +7786,17 @@ istanbul-lib-instrument@^5.0.4: istanbul-lib-coverage "^3.2.0" semver "^6.3.0" +istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + istanbul-lib-report@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" @@ -7560,10 +7815,10 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2: - version "3.1.4" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" - integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -7573,328 +7828,327 @@ java-properties@^1.0.0: resolved "https://registry.yarnpkg.com/java-properties/-/java-properties-1.0.2.tgz#ccd1fa73907438a5b5c38982269d0e771fe78211" integrity sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ== -jest-changed-files@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.6.2.tgz#f6198479e1cc66f22f9ae1e22acaa0b429c042d0" - integrity sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ== +jest-changed-files@^29.4.0: + version "29.4.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.0.tgz#ac2498bcd394228f7eddcadcf928b3583bf2779d" + integrity sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w== dependencies: - "@jest/types" "^26.6.2" - execa "^4.0.0" - throat "^5.0.0" + execa "^5.0.0" + p-limit "^3.1.0" -jest-cli@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.6.3.tgz#43117cfef24bc4cd691a174a8796a532e135e92a" - integrity sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg== +jest-circus@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.1.tgz#ff1b63eb04c3b111cefea9489e8dbadd23ce49bd" + integrity sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA== dependencies: - "@jest/core" "^26.6.3" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/environment" "^29.4.1" + "@jest/expect" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/types" "^29.4.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^29.4.1" + jest-matcher-utils "^29.4.1" + jest-message-util "^29.4.1" + jest-runtime "^29.4.1" + jest-snapshot "^29.4.1" + jest-util "^29.4.1" + p-limit "^3.1.0" + pretty-format "^29.4.1" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.1.tgz#7abef96944f300feb9b76f68b1eb2d68774fe553" + integrity sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ== + dependencies: + "@jest/core" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/types" "^29.4.1" chalk "^4.0.0" exit "^0.1.2" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" import-local "^3.0.2" - is-ci "^2.0.0" - jest-config "^26.6.3" - jest-util "^26.6.2" - jest-validate "^26.6.2" + jest-config "^29.4.1" + jest-util "^29.4.1" + jest-validate "^29.4.1" prompts "^2.0.1" - yargs "^15.4.1" + yargs "^17.3.1" -jest-config@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.6.3.tgz#64f41444eef9eb03dc51d5c53b75c8c71f645349" - integrity sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg== +jest-config@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.1.tgz#e62670c6c980ec21d75941806ec4d0c0c6402728" + integrity sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg== dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^26.6.3" - "@jest/types" "^26.6.2" - babel-jest "^26.6.3" + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.4.1" + "@jest/types" "^29.4.1" + babel-jest "^29.4.1" chalk "^4.0.0" + ci-info "^3.2.0" deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.4" - jest-environment-jsdom "^26.6.2" - jest-environment-node "^26.6.2" - jest-get-type "^26.3.0" - jest-jasmine2 "^26.6.3" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" - micromatch "^4.0.2" - pretty-format "^26.6.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.4.1" + jest-environment-node "^29.4.1" + jest-get-type "^29.2.0" + jest-regex-util "^29.2.0" + jest-resolve "^29.4.1" + jest-runner "^29.4.1" + jest-util "^29.4.1" + jest-validate "^29.4.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.4.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" -jest-diff@^26.0.0, jest-diff@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" - integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== +jest-diff@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.1.tgz#9a6dc715037e1fa7a8a44554e7d272088c4029bd" + integrity sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw== dependencies: chalk "^4.0.0" - diff-sequences "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" + diff-sequences "^29.3.1" + jest-get-type "^29.2.0" + pretty-format "^29.4.1" -jest-docblock@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" - integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== +jest-docblock@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" + integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== dependencies: detect-newline "^3.0.0" -jest-each@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.6.2.tgz#02526438a77a67401c8a6382dfe5999952c167cb" - integrity sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A== +jest-each@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.1.tgz#05ce9979e7486dbd0f5d41895f49ccfdd0afce01" + integrity sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^29.4.1" chalk "^4.0.0" - jest-get-type "^26.3.0" - jest-util "^26.6.2" - pretty-format "^26.6.2" - -jest-environment-jsdom@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" - integrity sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q== - dependencies: - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + jest-get-type "^29.2.0" + jest-util "^29.4.1" + pretty-format "^29.4.1" + +jest-environment-node@^29.2.1: + version "29.3.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.3.1.tgz#5023b32472b3fba91db5c799a0d5624ad4803e74" + integrity sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag== + dependencies: + "@jest/environment" "^29.3.1" + "@jest/fake-timers" "^29.3.1" + "@jest/types" "^29.3.1" "@types/node" "*" - jest-mock "^26.6.2" - jest-util "^26.6.2" - jsdom "^16.4.0" + jest-mock "^29.3.1" + jest-util "^29.3.1" -jest-environment-node@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.6.2.tgz#824e4c7fb4944646356f11ac75b229b0035f2b0c" - integrity sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag== +jest-environment-node@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.1.tgz#22550b7d0f8f0b16228639c9f88ca04bbf3c1974" + integrity sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg== dependencies: - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/environment" "^29.4.1" + "@jest/fake-timers" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" - jest-mock "^26.6.2" - jest-util "^26.6.2" + jest-mock "^29.4.1" + jest-util "^29.4.1" jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-haste-map@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" - integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== - dependencies: - "@jest/types" "^26.6.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^26.0.0" - jest-serializer "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" - micromatch "^4.0.2" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.1.2" +jest-get-type@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" + integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== -jest-haste-map@^27.3.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" - integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== +jest-haste-map@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.1.tgz#b0579dc82d94b40ed9041af56ad25c2f80bedaeb" + integrity sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w== dependencies: - "@jest/types" "^27.5.1" - "@types/graceful-fs" "^4.1.2" + "@jest/types" "^29.4.1" + "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^27.5.1" - jest-serializer "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" + jest-regex-util "^29.2.0" + jest-util "^29.4.1" + jest-worker "^29.4.1" micromatch "^4.0.4" - walker "^1.0.7" + walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz#adc3cf915deacb5212c93b9f3547cd12958f2edd" - integrity sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg== +jest-leak-detector@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.1.tgz#632186c546e084da2b490b7496fee1a1c9929637" + integrity sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^26.6.2" - "@jest/source-map" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^26.6.2" - is-generator-fn "^2.0.0" - jest-each "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-runtime "^26.6.3" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - pretty-format "^26.6.2" - throat "^5.0.0" + jest-get-type "^29.2.0" + pretty-format "^29.4.1" -jest-leak-detector@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af" - integrity sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg== +jest-matcher-utils@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.1.tgz#73d834e305909c3b43285fbc76f78bf0ad7e1954" + integrity sha512-k5h0u8V4nAEy6lSACepxL/rw78FLDkBnXhZVgFneVpnJONhb2DhZj/Gv4eNe+1XqQ5IhgUcqj745UwH0HJmMnA== dependencies: - jest-get-type "^26.3.0" - pretty-format "^26.6.2" + chalk "^4.0.0" + jest-diff "^29.4.1" + jest-get-type "^29.2.0" + pretty-format "^29.4.1" -jest-matcher-utils@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" - integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== +jest-message-util@^29.3.1: + version "29.3.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.3.1.tgz#37bc5c468dfe5120712053dd03faf0f053bd6adb" + integrity sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA== dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.3.1" + "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.3.1" + slash "^3.0.0" + stack-utils "^2.0.3" -jest-message-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" - integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== +jest-message-util@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.1.tgz#522623aa1df9a36ebfdffb06495c7d9d19e8a845" + integrity sha512-H4/I0cXUaLeCw6FM+i4AwCnOwHRgitdaUFOdm49022YD5nfyr8C/DrbXOBEyJaj+w/y0gGJ57klssOaUiLLQGQ== dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/types" "^26.6.2" + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.4.1" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.2" - pretty-format "^26.6.2" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.4.1" slash "^3.0.0" - stack-utils "^2.0.2" + stack-utils "^2.0.3" -jest-mock@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" - integrity sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew== +jest-mock@^29.3.1: + version "29.3.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.3.1.tgz#60287d92e5010979d01f218c6b215b688e0f313e" + integrity sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA== dependencies: - "@jest/types" "^26.6.2" + "@jest/types" "^29.3.1" "@types/node" "*" + jest-util "^29.3.1" + +jest-mock@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.1.tgz#a218a2abf45c99c501d4665207748a6b9e29afbd" + integrity sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ== + dependencies: + "@jest/types" "^29.4.1" + "@types/node" "*" + jest-util "^29.4.1" jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" - integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== - -jest-regex-util@^27.5.1: +jest-regex-util@^27.0.6: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== -jest-resolve-dependencies@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz#6680859ee5d22ee5dcd961fe4871f59f4c784fb6" - integrity sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg== +jest-regex-util@^29.2.0: + version "29.2.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" + integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== + +jest-resolve-dependencies@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.1.tgz#02420a2e055da105e5fca8218c471d8b9553c904" + integrity sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg== dependencies: - "@jest/types" "^26.6.2" - jest-regex-util "^26.0.0" - jest-snapshot "^26.6.2" + jest-regex-util "^29.2.0" + jest-snapshot "^29.4.1" -jest-resolve@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.6.2.tgz#a3ab1517217f469b504f1b56603c5bb541fbb507" - integrity sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ== +jest-resolve@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.1.tgz#4c6bf71a07b8f0b79c5fdf4f2a2cf47317694c5e" + integrity sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ== dependencies: - "@jest/types" "^26.6.2" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" jest-pnp-resolver "^1.2.2" - jest-util "^26.6.2" - read-pkg-up "^7.0.1" - resolve "^1.18.1" + jest-util "^29.4.1" + jest-validate "^29.4.1" + resolve "^1.20.0" + resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.6.3.tgz#2d1fed3d46e10f233fd1dbd3bfaa3fe8924be159" - integrity sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ== +jest-runner@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.1.tgz#57460d9ebb0eea2e27eeddca1816cf8537469661" + integrity sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg== dependencies: - "@jest/console" "^26.6.2" - "@jest/environment" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/console" "^29.4.1" + "@jest/environment" "^29.4.1" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" chalk "^4.0.0" - emittery "^0.7.1" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-config "^26.6.3" - jest-docblock "^26.0.0" - jest-haste-map "^26.6.2" - jest-leak-detector "^26.6.2" - jest-message-util "^26.6.2" - jest-resolve "^26.6.2" - jest-runtime "^26.6.3" - jest-util "^26.6.2" - jest-worker "^26.6.2" - source-map-support "^0.5.6" - throat "^5.0.0" - -jest-runtime@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.6.3.tgz#4f64efbcfac398331b74b4b3c82d27d401b8fa2b" - integrity sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw== - dependencies: - "@jest/console" "^26.6.2" - "@jest/environment" "^26.6.2" - "@jest/fake-timers" "^26.6.2" - "@jest/globals" "^26.6.2" - "@jest/source-map" "^26.6.2" - "@jest/test-result" "^26.6.2" - "@jest/transform" "^26.6.2" - "@jest/types" "^26.6.2" - "@types/yargs" "^15.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.2.0" + jest-environment-node "^29.4.1" + jest-haste-map "^29.4.1" + jest-leak-detector "^29.4.1" + jest-message-util "^29.4.1" + jest-resolve "^29.4.1" + jest-runtime "^29.4.1" + jest-util "^29.4.1" + jest-watcher "^29.4.1" + jest-worker "^29.4.1" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.1.tgz#9a50f9c69d3a391690897c01b0bfa8dc5dd45808" + integrity sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA== + dependencies: + "@jest/environment" "^29.4.1" + "@jest/fake-timers" "^29.4.1" + "@jest/globals" "^29.4.1" + "@jest/source-map" "^29.2.0" + "@jest/test-result" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" + "@types/node" "*" chalk "^4.0.0" - cjs-module-lexer "^0.6.0" + cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" - exit "^0.1.2" glob "^7.1.3" - graceful-fs "^4.2.4" - jest-config "^26.6.3" - jest-haste-map "^26.6.2" - jest-message-util "^26.6.2" - jest-mock "^26.6.2" - jest-regex-util "^26.0.0" - jest-resolve "^26.6.2" - jest-snapshot "^26.6.2" - jest-util "^26.6.2" - jest-validate "^26.6.2" + graceful-fs "^4.2.9" + jest-haste-map "^29.4.1" + jest-message-util "^29.4.1" + jest-mock "^29.4.1" + jest-regex-util "^29.2.0" + jest-resolve "^29.4.1" + jest-snapshot "^29.4.1" + jest-util "^29.4.1" + semver "^7.3.5" slash "^3.0.0" strip-bom "^4.0.0" - yargs "^15.4.1" -jest-serializer@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" - integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - -jest-serializer@^27.5.1: +jest-serializer@^27.0.6: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== @@ -7902,41 +8156,37 @@ jest-serializer@^27.5.1: "@types/node" "*" graceful-fs "^4.2.9" -jest-snapshot@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.6.2.tgz#f3b0af1acb223316850bd14e1beea9837fb39c84" - integrity sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og== +jest-snapshot@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.1.tgz#5692210b3690c94f19317913d4082b123bd83dd9" + integrity sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA== dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^26.6.2" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.0.0" + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.4.1" + "@jest/transform" "^29.4.1" + "@jest/types" "^29.4.1" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^26.6.2" - graceful-fs "^4.2.4" - jest-diff "^26.6.2" - jest-get-type "^26.3.0" - jest-haste-map "^26.6.2" - jest-matcher-utils "^26.6.2" - jest-message-util "^26.6.2" - jest-resolve "^26.6.2" + expect "^29.4.1" + graceful-fs "^4.2.9" + jest-diff "^29.4.1" + jest-get-type "^29.2.0" + jest-haste-map "^29.4.1" + jest-matcher-utils "^29.4.1" + jest-message-util "^29.4.1" + jest-util "^29.4.1" natural-compare "^1.4.0" - pretty-format "^26.6.2" - semver "^7.3.2" - -jest-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" - integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== - dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - micromatch "^4.0.2" + pretty-format "^29.4.1" + semver "^7.3.5" -jest-util@^27.5.1: +jest-util@^27.2.0: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== @@ -7948,7 +8198,31 @@ jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^26.5.2, jest-validate@^26.6.2: +jest-util@^29.3.1: + version "29.3.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.3.1.tgz#1dda51e378bbcb7e3bc9d8ab651445591ed373e1" + integrity sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ== + dependencies: + "@jest/types" "^29.3.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-util@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.1.tgz#2eeed98ff4563b441b5a656ed1a786e3abc3e4c4" + integrity sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ== + dependencies: + "@jest/types" "^29.4.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^26.5.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.6.2.tgz#23d380971587150467342911c3d7b4ac57ab20ec" integrity sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ== @@ -7960,50 +8234,60 @@ jest-validate@^26.5.2, jest-validate@^26.6.2: leven "^3.1.0" pretty-format "^26.6.2" -jest-watcher@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.6.2.tgz#a5b683b8f9d68dbcb1d7dae32172d2cca0592975" - integrity sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ== +jest-validate@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.1.tgz#0d5174510415083ec329d4f981bf6779211f17e9" + integrity sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw== dependencies: - "@jest/test-result" "^26.6.2" - "@jest/types" "^26.6.2" + "@jest/types" "^29.4.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.2.0" + leven "^3.1.0" + pretty-format "^29.4.1" + +jest-watcher@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.1.tgz#6e3e2486918bd778849d4d6e67fd77b814f3e6ed" + integrity sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw== + dependencies: + "@jest/test-result" "^29.4.1" + "@jest/types" "^29.4.1" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^26.6.2" + emittery "^0.13.1" + jest-util "^29.4.1" string-length "^4.0.1" -jest-worker@^26.0.0, jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== +jest-worker@^27.2.0: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: "@types/node" "*" merge-stream "^2.0.0" - supports-color "^7.0.0" + supports-color "^8.0.0" -jest-worker@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== +jest-worker@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.1.tgz#7cb4a99a38975679600305650f86f4807460aab1" + integrity sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ== dependencies: "@types/node" "*" + jest-util "^29.4.1" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^26.6.3: - version "26.6.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-26.6.3.tgz#40e8fdbe48f00dfa1f0ce8121ca74b88ac9148ef" - integrity sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q== +jest@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.1.tgz#bb34baca8e05901b49c02c62f1183a6182ea1785" + integrity sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg== dependencies: - "@jest/core" "^26.6.3" + "@jest/core" "^29.4.1" + "@jest/types" "^29.4.1" import-local "^3.0.2" - jest-cli "^26.6.3" - -jetifier@^1.6.2: - version "1.6.6" - resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.6.tgz#fec8bff76121444c12dc38d2dad6767c421dab68" - integrity sha512-JNAkmPeB/GS2tCRqUzRPsTOHpGDah7xP18vGJfIjZC+W2sxEHbxgJxetIjIqhjQ3yYbYNEELkM/spKLtwoOSUQ== + jest-cli "^29.4.1" jimp@^0.10.0: version "0.10.3" @@ -8072,6 +8356,11 @@ jsc-android@^250230.2.1: resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250230.2.1.tgz#3790313a970586a03ab0ad47defbc84df54f1b83" integrity sha512-KmxeBlRjwoqCnBBKGsihFtvsBHyUFlBxJPK4FzeYcIuBfdjv6jFys44JITAgSTbQD+vIdwMEfyZklsuQX0yI1Q== +jsc-android@^250231.0.0: + version "250231.0.0" + resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250231.0.0.tgz#91720f8df382a108872fa4b3f558f33ba5e95262" + integrity sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw== + jscodeshift@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.13.1.tgz#69bfe51e54c831296380585c6d9e733512aecdef" @@ -8097,39 +8386,6 @@ jscodeshift@^0.13.1: temp "^0.8.4" write-file-atomic "^2.3.0" -jsdom@^16.4.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -8192,19 +8448,10 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - optionalDependencies: - graceful-fs "^4.1.6" +json5@^2.1.2, json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^4.0.0: version "4.0.0" @@ -8213,11 +8460,6 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -8289,13 +8531,6 @@ kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - klaw@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" @@ -8577,6 +8812,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lock-verify@^2.0.2, lock-verify@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/lock-verify/-/lock-verify-2.2.1.tgz#81107948c51ed16f97b96ff8b60675affb243fc1" @@ -8721,7 +8963,7 @@ lodash.zip@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020" integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA= -lodash@^4.0.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.9, lodash@^4.2.1, lodash@^4.6.1, lodash@^4.7.0: +lodash@^4.0.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.9, lodash@^4.2.1, lodash@^4.6.1: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8861,6 +9103,13 @@ make-fetch-happen@^5.0.0: socks-proxy-agent "^4.0.0" ssri "^6.0.0" +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -8963,6 +9212,11 @@ mem@^5.0.0: mimic-fn "^2.1.0" p-is-promise "^2.1.0" +memoize-one@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" + integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + meow@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.0.tgz#50ecbcdafa16f8b58fb7eb9675b933f6473b3a59" @@ -8990,7 +9244,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3, merge2@^1.3.0: +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -9010,79 +9264,160 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -metro-babel-transformer@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.67.0.tgz#42fe82af9953e5c62d9a8d7d544eb7be9020dd18" - integrity sha512-SBqc4nq/dgsPNFm+mpWcQQzJaXnh0nrfz2pSnZC4i6zMtIakrTWb8SQ78jOU1FZVEZ3nu9xCYVHS9Tbr/LoEuw== +metro-babel-transformer@0.73.5: + version "0.73.5" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.5.tgz#e7ebe371cd8bf5df90b0e9153587b4d5089d2ce7" + integrity sha512-G3awAJ9of/R2jEg+MRokYcq/TNvMSxJipwybQ2NfwwSj5iLEmRH2YbwTx5w8f5qKgs2K4SS2pmBIs8qjdV6p3Q== dependencies: "@babel/core" "^7.14.0" - hermes-parser "0.5.0" - metro-source-map "0.67.0" + hermes-parser "0.8.0" + metro-source-map "0.73.5" + nullthrows "^1.1.1" + +metro-babel-transformer@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.7.tgz#561ffa0336eb6d7d112e7128e957114c729fdb71" + integrity sha512-s7UVkwovGTEXYEQrv5hcmSBbFJ9s9lhCRNMScn4Itgj3UMdqRr9lU8DXKEFlJ7osgRxN6n5+eXqcvhE4B1H1VQ== + dependencies: + "@babel/core" "^7.20.0" + hermes-parser "0.8.0" + metro-source-map "0.73.7" nullthrows "^1.1.1" -metro-cache-key@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.67.0.tgz#4df6a73cced199e1bddd0f3454bb931a27141eeb" - integrity sha512-FNJe5Rcb2uzY6G6tsqCf0RV4t2rCeX6vSHBxmP7k+4aI4NqX4evtPI0K82r221nBzm5DqNWCURZ0RYUT6jZMGA== +metro-cache-key@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.73.7.tgz#fa3b4ece5f3191ce238a623051a0d03bada2a153" + integrity sha512-GngYzrHwZU9U0Xl81H4aq9Tn5cjQyU12v9/flB0hzpeiYO5A89TIeilb4Kg8jtfC6JcmmsdK9nxYIGEq7odHhQ== -metro-cache@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.67.0.tgz#928db5742542719677468c4d22ea29b71c7ec8fc" - integrity sha512-IY5dXiR76L75b2ue/mv+9vW8g5hdQJU6YEe81lj6gTSoUrhcONT0rzY+Gh5QOS2Kk6z9utZQMvd9PRKL9/635A== +metro-cache@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.73.7.tgz#dd2b6a791b2754eae9c0a86dcf714b98e025fd95" + integrity sha512-CPPgI+i9yVzOEDCdmEEZ67JgOvZyNDs8kStmGUFgDuLSjj3//HhkqT5XyfWjGeH6KmyGiS8ip3cgLOVn3IsOSA== dependencies: - metro-core "0.67.0" - mkdirp "^0.5.1" - rimraf "^2.5.4" + metro-core "0.73.7" + rimraf "^3.0.2" -metro-config@0.67.0, metro-config@^0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.67.0.tgz#5507d3b295bd10c87bd13dbe5a3033a357418786" - integrity sha512-ThAwUmzZwTbKyyrIn2bKIcJDPDBS0LKAbqJZQioflvBGfcgA21h3fdL3IxRmvCEl6OnkEWI0Tn1Z9w2GLAjf2g== +metro-config@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.73.7.tgz#8935054ece6155d214420c263272cd3a690a82e2" + integrity sha512-pD/F+vK3u37cbj1skYmI6cUsEEscqNRtW2KlDKu1m+n8nooDB2oGTOZatlS5WQa7Ga6jYQRydftlq4CLDexAfA== dependencies: cosmiconfig "^5.0.5" jest-validate "^26.5.2" - metro "0.67.0" - metro-cache "0.67.0" - metro-core "0.67.0" - metro-runtime "0.67.0" + metro "0.73.7" + metro-cache "0.73.7" + metro-core "0.73.7" + metro-runtime "0.73.7" -metro-core@0.67.0, metro-core@^0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.67.0.tgz#75066e11b4df220992abf9cd6200279dd87876c8" - integrity sha512-TOa/ShE1bUq83fGNfV6rFwyfZ288M8ydmWN3g9C2OW8emOHLhJslYD/SIU4DhDkP/99yaJluIALdZ2g0+pCrvQ== +metro-core@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.73.7.tgz#f5abe2448ea72a65f54db9bc90068f3308de1df2" + integrity sha512-H7j1Egj1VnNnsSYf9ZKv0SRwijgtRKIcaGNQq/T+er73vqqb4kR9H+2VIJYPXi6R8lT+QLIMfs6CWSUHAJUgtg== dependencies: - jest-haste-map "^27.3.1" lodash.throttle "^4.1.1" - metro-resolver "0.67.0" + metro-resolver "0.73.7" + +metro-file-map@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.73.7.tgz#709f33ac5ea6f87668d454c77973ab296b7a064b" + integrity sha512-BYaCo2e/4FMN4nOajeN+Za5cPfecfikzUYuFWWMyLAmHU6dj7B+PFkaJ4OEJO3vmRoeq5vMOmhpKXgysYbNXJg== + dependencies: + abort-controller "^3.0.0" + anymatch "^3.0.3" + debug "^2.2.0" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + invariant "^2.2.4" + jest-regex-util "^27.0.6" + jest-serializer "^27.0.6" + jest-util "^27.2.0" + jest-worker "^27.2.0" + micromatch "^4.0.4" + nullthrows "^1.1.1" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" -metro-hermes-compiler@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.67.0.tgz#9c1340f1882fbf535145868d0d28211ca15b0477" - integrity sha512-X5Pr1jC8/kO6d1EBDJ6yhtuc5euHX89UDNv8qdPJHAET03xfFnlojRPwOw6il2udAH20WLBv+F5M9VY+58zspQ== +metro-hermes-compiler@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.73.7.tgz#d1b519c4040423240d89e7816340ca9635deeae8" + integrity sha512-F8PlJ8mWEEumGNH3eMRA3gjgP70ZvH4Ex5F1KY6ofD/gpn7w5HJHSPTeVw8gtUb1pYLN4nevptpyXGg04Jfcog== -metro-inspector-proxy@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.67.0.tgz#22b360a837b07e9e2bc87a71af6154dd8fcc02a5" - integrity sha512-5Ubjk94qpNaU3OT2IZa4/dec09bauic1hzWms4czorBzDenkp4kYXG9/aWTmgQLtCk92H3Q8jKl1PQRxUSkrOQ== +metro-inspector-proxy@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.73.7.tgz#edb966c1581a41a3302860d264f3228e1f57a220" + integrity sha512-TsAtQeKr9X7NaQHlpshu+ZkGWlPi5fFKNqieLkfqvT1oXN4PQF/4q38INyiZtWLPvoUzTR6PRnm4pcUbJ7+Nzg== dependencies: connect "^3.6.5" debug "^2.2.0" ws "^7.5.1" - yargs "^15.3.1" + yargs "^17.5.1" -metro-minify-uglify@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.67.0.tgz#28a77dbd78d9e558dba8c2f31c2b9c6f939df966" - integrity sha512-4CmM5b3MTAmQ/yFEfsHOhD2SuBObB2YF6PKzXZc4agUsQVVtkrrNElaiWa8w26vrTzA9emwcyurxMf4Nl3lYPQ== +metro-minify-terser@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.73.7.tgz#e45fc05eb2e3bc76c9b4fe4abccee0fffeedcf75" + integrity sha512-gbv1fmMOZm6gJ6dQoD+QktlCi2wk6nlTR8j8lQCjeeXGbs6O9e5XLWNPOexHqo7S69bdbohEnfZnLJFcxgHeNw== + dependencies: + terser "^5.15.0" + +metro-minify-uglify@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.73.7.tgz#3dfd397e8202905731e4a519a58fc334d9232a15" + integrity sha512-DmDCzfdbaPExQuQ7NQozCNOSOAgp5Ux9kWzmKAT8seQ38/3NtUepW+PTgxXIHmwNjJV4oHsHwlBlTwJmYihKXg== dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@0.67.0, metro-react-native-babel-preset@^0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.67.0.tgz#53aec093f53a09b56236a9bb534d76658efcbec7" - integrity sha512-tgTG4j0SKwLHbLRELMmgkgkjV1biYkWlGGKOmM484/fJC6bpDikdaFhfjsyE+W+qt7I5szbCPCickMTNQ+zwig== +metro-react-native-babel-preset@0.73.5: + version "0.73.5" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.5.tgz#9b92f1ebc2b3d96f511c45a03f8e35e0fc46cc19" + integrity sha512-Ej6J8ozWSs6nrh0nwX7hgX4oPXUai40ckah37cSLu8qeED2XiEtfLV1YksTLafFE8fX0EieiP97U97dkOGHP4w== + dependencies: + "@babel/core" "^7.14.0" + "@babel/plugin-proposal-async-generator-functions" "^7.0.0" + "@babel/plugin-proposal-class-properties" "^7.0.0" + "@babel/plugin-proposal-export-default-from" "^7.0.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-optional-chaining" "^7.0.0" + "@babel/plugin-syntax-dynamic-import" "^7.0.0" + "@babel/plugin-syntax-export-default-from" "^7.0.0" + "@babel/plugin-syntax-flow" "^7.2.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" + "@babel/plugin-syntax-optional-chaining" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.0.0" + "@babel/plugin-transform-classes" "^7.0.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.0.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-commonjs" "^7.0.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" + "@babel/plugin-transform-parameters" "^7.0.0" + "@babel/plugin-transform-react-display-name" "^7.0.0" + "@babel/plugin-transform-react-jsx" "^7.0.0" + "@babel/plugin-transform-react-jsx-self" "^7.0.0" + "@babel/plugin-transform-react-jsx-source" "^7.0.0" + "@babel/plugin-transform-runtime" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.5.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + "@babel/template" "^7.0.0" + react-refresh "^0.4.0" + +metro-react-native-babel-preset@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz#78e1ce448aa9a5cf3651c0ebe73cb225465211b4" + integrity sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw== dependencies: - "@babel/core" "^7.14.0" + "@babel/core" "^7.20.0" + "@babel/plugin-proposal-async-generator-functions" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" @@ -9091,7 +9426,7 @@ metro-react-native-babel-preset@0.67.0, metro-react-native-babel-preset@^0.67.0: "@babel/plugin-proposal-optional-chaining" "^7.0.0" "@babel/plugin-syntax-dynamic-import" "^7.0.0" "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" + "@babel/plugin-syntax-flow" "^7.18.0" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" "@babel/plugin-syntax-optional-chaining" "^7.0.0" "@babel/plugin-transform-arrow-functions" "^7.0.0" @@ -9100,19 +9435,16 @@ metro-react-native-babel-preset@0.67.0, metro-react-native-babel-preset@^0.67.0: "@babel/plugin-transform-classes" "^7.0.0" "@babel/plugin-transform-computed-properties" "^7.0.0" "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" "@babel/plugin-transform-function-name" "^7.0.0" "@babel/plugin-transform-literals" "^7.0.0" "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.0.0" "@babel/plugin-transform-parameters" "^7.0.0" "@babel/plugin-transform-react-display-name" "^7.0.0" "@babel/plugin-transform-react-jsx" "^7.0.0" "@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" "@babel/plugin-transform-runtime" "^7.0.0" "@babel/plugin-transform-shorthand-properties" "^7.0.0" "@babel/plugin-transform-spread" "^7.0.0" @@ -9123,145 +9455,194 @@ metro-react-native-babel-preset@0.67.0, metro-react-native-babel-preset@^0.67.0: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@0.67.0, metro-react-native-babel-transformer@^0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.67.0.tgz#756d32eb3c05cab3d72fcb1700f8fd09322bb07f" - integrity sha512-P0JT09n7T01epUtgL9mH6BPat3xn4JjBakl4lWHdL61cvEGcrxuIom1eoFFKkgU/K5AVLU4aCAttHS7nSFCcEQ== +metro-react-native-babel-transformer@0.73.5: + version "0.73.5" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.5.tgz#fb1d48cc73ce26371cf2a115f702b7bf3bb5516b" + integrity sha512-CZYgUguqFTzV9vSOZb60p8qlp31aWz8aBB6OqoZ2gJday+n/1k+Y0yy6VPr/tfXJheuQYVIXKvG1gMmUDyxt+Q== dependencies: "@babel/core" "^7.14.0" babel-preset-fbjs "^3.4.0" - hermes-parser "0.5.0" - metro-babel-transformer "0.67.0" - metro-react-native-babel-preset "0.67.0" - metro-source-map "0.67.0" + hermes-parser "0.8.0" + metro-babel-transformer "0.73.5" + metro-react-native-babel-preset "0.73.5" + metro-source-map "0.73.5" + nullthrows "^1.1.1" + +metro-react-native-babel-transformer@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.7.tgz#a92055fd564cd403255cc34f925c5e99ce457565" + integrity sha512-73HW8betjX+VPm3iqsMBe8F/F2Tt+hONO6YJwcF7FonTqQYW1oTz0dOp0dClZGfHUXxpJBz6Vuo7J6TpdzDD+w== + dependencies: + "@babel/core" "^7.20.0" + babel-preset-fbjs "^3.4.0" + hermes-parser "0.8.0" + metro-babel-transformer "0.73.7" + metro-react-native-babel-preset "0.73.7" + metro-source-map "0.73.7" nullthrows "^1.1.1" -metro-resolver@0.67.0, metro-resolver@^0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.67.0.tgz#8143c716f77e468d1d42eca805243706eb349959" - integrity sha512-d2KS/zAyOA/z/q4/ff41rAp+1txF4H6qItwpsls/RHStV2j6PqgRHUzq/3ga+VIeoUJntYJ8nGW3+3qSrhFlig== +metro-resolver@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.73.7.tgz#1e174cf59eac84c0869172764316042b466daaa5" + integrity sha512-mGW3XPeKBCwZnkHcKo1dhFa9olcx7SyNzG1vb5kjzJYe4Qs3yx04r/qFXIJLcIgLItB69TIGvosznUhpeOOXzg== dependencies: absolute-path "^0.0.0" -metro-runtime@0.67.0, metro-runtime@^0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.67.0.tgz#a8888dfd06bcebbac3c99dcac7cd622510dd8ee0" - integrity sha512-IFtSL0JUt1xK3t9IoLflTDft82bjieSzdIJWLzrRzBMlesz8ox5bVmnpQbVQEwfYUpEOxbM3VOZauVbdCmXA7g== +metro-runtime@0.73.5: + version "0.73.5" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.5.tgz#8c92c3947e97a8dede6347ba6a9844bfb8be8258" + integrity sha512-8QJOS7bhJmR6r/Gkki/qY9oX/DdxnLhS8FpdG1Xmm2hDeUVAug12ekWTiCRMu7d1CDVv1F8WvUz09QckZ0dO0g== + dependencies: + "@babel/runtime" "^7.0.0" + react-refresh "^0.4.0" + +metro-runtime@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.7.tgz#9f3a7f3ff668c1a87370650e32b47d8f6329fd1e" + integrity sha512-2fxRGrF8FyrwwHY0TCitdUljzutfW6CWEpdvPilfrs8p0PI5X8xOWg8ficeYtw+DldHtHIAL2phT59PqzHTyVA== + dependencies: + "@babel/runtime" "^7.0.0" + react-refresh "^0.4.0" -metro-source-map@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.67.0.tgz#e28db7253b9ca688e60d5710ebdccba60b45b2df" - integrity sha512-yxypInsRo3SfS00IgTuL6a2W2tfwLY//vA2E+GeqGBF5zTbJZAhwNGIEl8S87XXZhwzJcxf5/8LjJC1YDzabww== +metro-source-map@0.73.5: + version "0.73.5" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.5.tgz#67e14bd1fcc1074b9623640ca311cd99d07426fa" + integrity sha512-58p3zNWgUrqYYjFJb0KkZ+uJurTL4oz7i5T7577b3kvTYuJ0eK4y7rtYf8EwOfMYxRAn/m20aH1Y1fHTsLUwjQ== dependencies: "@babel/traverse" "^7.14.0" - "@babel/types" "^7.0.0" + "@babel/types" "^7.20.0" + invariant "^2.2.4" + metro-symbolicate "0.73.5" + nullthrows "^1.1.1" + ob1 "0.73.5" + source-map "^0.5.6" + vlq "^1.0.0" + +metro-source-map@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.7.tgz#8e9f850a72d60ea7ace05b984f981c8ec843e7a0" + integrity sha512-gbC/lfUN52TtQhEsTTA+987MaFUpQlufuCI05blLGLosDcFCsARikHsxa65Gtslm/rG2MqvFLiPA5hviONNv9g== + dependencies: + "@babel/traverse" "^7.20.0" + "@babel/types" "^7.20.0" invariant "^2.2.4" - metro-symbolicate "0.67.0" + metro-symbolicate "0.73.7" nullthrows "^1.1.1" - ob1 "0.67.0" + ob1 "0.73.7" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.67.0.tgz#16729d05663d28176895244b3d932a898fca2b45" - integrity sha512-ZqVVcfa0xSz40eFzA5P8pCF3V6Tna9RU1prFzAJTa3j9dCGqwh0HTXC8AIkMtgX7hNdZrCJI1YipzUBlwkT0/A== +metro-symbolicate@0.73.5: + version "0.73.5" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.5.tgz#8de118be231decd55c8c70ed54deb308fdffceda" + integrity sha512-aIC8sDlaEdtn0dTt+64IFZFEATatFx3GtzRbJi0+jJx47RjDRiuCt9fzmTMLuadWwnbFK9ZfVMuWEXM9sdtQ7w== dependencies: invariant "^2.2.4" - metro-source-map "0.67.0" + metro-source-map "0.73.5" nullthrows "^1.1.1" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" -metro-transform-plugins@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.67.0.tgz#6122aa4e5e5f9a767cebcc5af6fd1695666683ce" - integrity sha512-DQFoSDIJdTMPDTUlKaCNJjEXiHGwFNneAF9wDSJ3luO5gigM7t7MuSaPzF4hpjmfmcfPnRhP6AEn9jcza2Sh8Q== +metro-symbolicate@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.7.tgz#40e4cda81f8030b86afe391b5e686a0b06822b0a" + integrity sha512-571ThWmX5o8yGNzoXjlcdhmXqpByHU/bSZtWKhtgV2TyIAzYCYt4hawJAS5+/qDazUvjHdm8BbdqFUheM0EKNQ== dependencies: - "@babel/core" "^7.14.0" - "@babel/generator" "^7.14.0" + invariant "^2.2.4" + metro-source-map "0.73.7" + nullthrows "^1.1.1" + source-map "^0.5.6" + through2 "^2.0.1" + vlq "^1.0.0" + +metro-transform-plugins@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.73.7.tgz#49ff2571742d557f20301880f55b00054e468e52" + integrity sha512-M5isiWEau0jMudb5ezaNBZnYqXxcATMqnAYc+Cu25IahT1NHi5aWwLok9EBmBpN5641IZUZXScf+KnS7fPxPCQ== + dependencies: + "@babel/core" "^7.20.0" + "@babel/generator" "^7.20.0" "@babel/template" "^7.0.0" - "@babel/traverse" "^7.14.0" + "@babel/traverse" "^7.20.0" nullthrows "^1.1.1" -metro-transform-worker@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.67.0.tgz#5689553c25b0657aadefdf4ea2cd8dd06e18882a" - integrity sha512-29n+JdTb80ROiv/wDiBVlY/xRAF/nrjhp/Udv/XJl1DZb+x7JEiPxpbpthPhwwl+AYxVrostGB0W06WJ61hfiw== +metro-transform-worker@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.73.7.tgz#be111805e92ea48b7c76dd75830798f318e252e0" + integrity sha512-gZYIu9JAqEI9Rxi0xGMuMW6QsHGbMSptozlTOwOd7T7yXX3WwYS/I3yLPbLhbZTjOhwMHkTt8Nhm2qBo8nh14g== dependencies: - "@babel/core" "^7.14.0" - "@babel/generator" "^7.14.0" - "@babel/parser" "^7.14.0" - "@babel/types" "^7.0.0" + "@babel/core" "^7.20.0" + "@babel/generator" "^7.20.0" + "@babel/parser" "^7.20.0" + "@babel/types" "^7.20.0" babel-preset-fbjs "^3.4.0" - metro "0.67.0" - metro-babel-transformer "0.67.0" - metro-cache "0.67.0" - metro-cache-key "0.67.0" - metro-hermes-compiler "0.67.0" - metro-source-map "0.67.0" - metro-transform-plugins "0.67.0" + metro "0.73.7" + metro-babel-transformer "0.73.7" + metro-cache "0.73.7" + metro-cache-key "0.73.7" + metro-hermes-compiler "0.73.7" + metro-source-map "0.73.7" + metro-transform-plugins "0.73.7" nullthrows "^1.1.1" -metro@0.67.0, metro@^0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.67.0.tgz#8007a041d22de1cdb05184431c67eb7989eef6e0" - integrity sha512-DwuBGAFcAivoac/swz8Lp7Y5Bcge1tzT7T6K0nf1ubqJP8YzBUtyR4pkjEYVUzVu/NZf7O54kHSPVu1ibYzOBQ== +metro@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.73.7.tgz#435081339ac209e4d8802c57ac522638140c802b" + integrity sha512-pkRqFhuGUvkiu8HxKPUQelbCuyy6te6okMssTyLzQwsKilNLK4YMI2uD6PHnypg5SiMJ58lwfqkp/t5w72jEvw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/core" "^7.14.0" - "@babel/generator" "^7.14.0" - "@babel/parser" "^7.14.0" + "@babel/core" "^7.20.0" + "@babel/generator" "^7.20.0" + "@babel/parser" "^7.20.0" "@babel/template" "^7.0.0" - "@babel/traverse" "^7.14.0" - "@babel/types" "^7.0.0" + "@babel/traverse" "^7.20.0" + "@babel/types" "^7.20.0" absolute-path "^0.0.0" accepts "^1.3.7" - async "^2.4.0" + async "^3.2.2" chalk "^4.0.0" ci-info "^2.0.0" connect "^3.6.5" debug "^2.2.0" denodeify "^1.2.1" error-stack-parser "^2.0.6" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - hermes-parser "0.5.0" + graceful-fs "^4.2.4" + hermes-parser "0.8.0" image-size "^0.6.0" invariant "^2.2.4" - jest-haste-map "^27.3.1" - jest-worker "^26.0.0" + jest-worker "^27.2.0" lodash.throttle "^4.1.1" - metro-babel-transformer "0.67.0" - metro-cache "0.67.0" - metro-cache-key "0.67.0" - metro-config "0.67.0" - metro-core "0.67.0" - metro-hermes-compiler "0.67.0" - metro-inspector-proxy "0.67.0" - metro-minify-uglify "0.67.0" - metro-react-native-babel-preset "0.67.0" - metro-resolver "0.67.0" - metro-runtime "0.67.0" - metro-source-map "0.67.0" - metro-symbolicate "0.67.0" - metro-transform-plugins "0.67.0" - metro-transform-worker "0.67.0" + metro-babel-transformer "0.73.7" + metro-cache "0.73.7" + metro-cache-key "0.73.7" + metro-config "0.73.7" + metro-core "0.73.7" + metro-file-map "0.73.7" + metro-hermes-compiler "0.73.7" + metro-inspector-proxy "0.73.7" + metro-minify-terser "0.73.7" + metro-minify-uglify "0.73.7" + metro-react-native-babel-preset "0.73.7" + metro-resolver "0.73.7" + metro-runtime "0.73.7" + metro-source-map "0.73.7" + metro-symbolicate "0.73.7" + metro-transform-plugins "0.73.7" + metro-transform-worker "0.73.7" mime-types "^2.1.27" - mkdirp "^0.5.1" node-fetch "^2.2.0" nullthrows "^1.1.1" - rimraf "^2.5.4" + rimraf "^3.0.2" serialize-error "^2.1.0" source-map "^0.5.6" strip-ansi "^6.0.0" temp "0.8.3" throat "^5.0.0" ws "^7.5.1" - yargs "^15.3.1" + yargs "^17.5.1" -micromatch@^3.1.10, micromatch@^3.1.4: +micromatch@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -9280,7 +9661,7 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.0, micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -9363,7 +9744,7 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -9493,7 +9874,7 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@^2.0.0, ms@^2.1.1: +ms@2.1.2, ms@^2.0.0, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -9539,6 +9920,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -9569,10 +9955,10 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -nocache@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f" - integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q== +nocache@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/nocache/-/nocache-3.0.4.tgz#5b37a56ec6e09fc7d401dceaed2eab40c8bfdf79" + integrity sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw== node-dir@^0.1.17: version "0.1.17" @@ -9631,27 +10017,10 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= -node-machine-id@^1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" - integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== - -node-notifier@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" - integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== - dependencies: - growly "^1.3.0" - is-wsl "^2.2.0" - semver "^7.3.2" - shellwords "^0.1.1" - uuid "^8.3.0" - which "^2.0.2" - -node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== node-simctl@^5.0.2: version "5.3.0" @@ -9707,13 +10076,6 @@ normalize-package-data@^2.0.0, normalize-package-data@^2.3.2, normalize-package- semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - normalize-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -9832,7 +10194,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^4.0.0: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -9985,20 +10347,20 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -ob1@0.67.0: - version "0.67.0" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.67.0.tgz#91f104c90641b1af8c364fc82a4b2c7d0801072d" - integrity sha512-YvZtX8HKYackQ5PwdFIuuNFVsMChRPHvnARRRT0Vk59xsBvL5t9U1Ock3M1sYrKj+Gp73+0q9xcHLAxI+xLi5g== +ob1@0.73.5: + version "0.73.5" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.5.tgz#b80dc4a6f787044e3d8afde3c2d034ae23d05a86" + integrity sha512-MxQH/rCq9/COvgTQbjCldArmesGEidZVVQIn4vDUJvJJ8uMphXOTCBsgWTief2ugvb0WUimIaslKSA+qryFjjQ== + +ob1@0.73.7: + version "0.73.7" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.7.tgz#14c9b6ddc26cf99144f59eb542d7ae956e6b3192" + integrity sha512-DfelfvR843KADhSUATGGhuepVMRcf5VQX+6MQLy5AW0BKDLlO7Usj6YZeAAZP7P86QwsoTxB0RXCFiA7t6S1IQ== object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" @@ -10128,7 +10490,7 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -10152,7 +10514,7 @@ openssl-wrapper@^0.3.4: resolved "https://registry.yarnpkg.com/openssl-wrapper/-/openssl-wrapper-0.3.4.tgz#c01ec98e4dcd2b5dfe0b693f31827200e3b81b07" integrity sha1-wB7Jjk3NK13+C2k/MYJyAOO4Gwc= -optionator@^0.8.1, optionator@^0.8.2: +optionator@^0.8.2: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -10254,11 +10616,6 @@ p-defer@^1.0.0: resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= -p-each-series@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" - integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== - p-filter@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" @@ -10300,6 +10657,13 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" @@ -10321,6 +10685,13 @@ p-locate@^4.0.0, p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -10464,6 +10835,16 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + parse-listing@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/parse-listing/-/parse-listing-1.1.3.tgz#aa546f57fdc129cfbf9945cd4b757b14b06182dd" @@ -10474,11 +10855,6 @@ parse-node-version@^1.0.0: resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== -parse5@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -10578,7 +10954,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -10605,7 +10981,7 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pirates@^4.0.1, pirates@^4.0.5: +pirates@^4.0.4, pirates@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== @@ -10646,7 +11022,7 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -plist@^3.0.1, plist@^3.0.2, plist@^3.0.5: +plist@^3.0.1: version "3.0.5" resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.5.tgz#2cbeb52d10e3cdccccf0c11a63a85d830970a987" integrity sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA== @@ -10701,7 +11077,7 @@ prepend-http@^1.0.1: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= -pretty-format@^26.0.0, pretty-format@^26.5.2, pretty-format@^26.6.2: +pretty-format@^26.5.2, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== @@ -10711,6 +11087,24 @@ pretty-format@^26.0.0, pretty-format@^26.5.2, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +pretty-format@^29.0.0, pretty-format@^29.4.1: + version "29.4.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.1.tgz#0da99b532559097b8254298da7c75a0785b1751c" + integrity sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg== + dependencies: + "@jest/schemas" "^29.4.0" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +pretty-format@^29.3.1: + version "29.3.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.3.1.tgz#1841cac822b02b4da8971dacb03e8a871b4722da" + integrity sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg== + dependencies: + "@jest/schemas" "^29.0.0" + ansi-styles "^5.0.0" + react-is "^18.0.0" + process-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/process-exists/-/process-exists-4.0.0.tgz#dc12d87798c17b3f129f716631e2ccdaf240b4ab" @@ -10751,7 +11145,7 @@ promise-retry@^1.1.1: err-code "^1.0.0" retry "^0.10.0" -promise@^8.0.3, promise@^8.2.0: +promise@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== @@ -10949,110 +11343,53 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-devtools-core@^4.23.0: - version "4.24.3" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.24.3.tgz#371fef3f5c639db0dc59eeef334dd5e10ac61661" - integrity sha512-+htKZxLxDN14jhRG3+IXRiJqNSGHUiPYrMtv9e7qlZxcbKeJjVs+C/hd8kZF5rydp3faBwFN6ZpTaZnLA3/ZGA== +react-devtools-core@^4.26.1: + version "4.27.1" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.27.1.tgz#167aa174383c65786cbb7e965a5b39c702f0a2d3" + integrity sha512-qXhcxxDWiFmFAOq48jts9YQYe1+wVoUXzJTlY4jbaATzyio6dd6CUGu3dXBhREeVgpZ+y4kg6vFJzIOZh6vY2w== dependencies: shell-quote "^1.6.1" ws "^7" -"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-native-codegen@*, react-native-codegen@^0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.0.18.tgz#99d6623d65292e8ce3fdb1d133a358caaa2145e7" - integrity sha512-XPI9aVsFy3dvgDZvyGWrFnknNiyb22kg5nHgxa0vjWTH9ENLBgVRZt9A64xHZ8BYihH+gl0p/1JNOCIEUzRPBg== - dependencies: - "@babel/parser" "^7.14.0" - flow-parser "^0.121.0" - jscodeshift "^0.13.1" - nullthrows "^1.1.1" - -react-native-codegen@^0.0.13: - version "0.0.13" - resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.0.13.tgz#4cc94546fc75a5dbe9350d59c10108f2efe6bc17" - integrity sha512-rCh1P+s0Q4N6vNgS97ckafbhJRztz22+0l0VZoyQC06F07J98kI5cUByH0ATypPRIdpkMbAZc59DoPdDFc01bg== - dependencies: - "@babel/parser" "^7.14.0" - flow-parser "^0.121.0" - jscodeshift "^0.13.1" - nullthrows "^1.1.1" +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-native-codegen@^0.0.17: - version "0.0.17" - resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.0.17.tgz#83fb814d94061cbd46667f510d2ddba35ffb50ac" - integrity sha512-7GIEUmAemH9uWwB6iYXNNsPoPgH06pxzGRmdBzK98TgFBdYJZ7CBuZFPMe4jmHQTPOkQazKZ/w5O6/71JBixmw== +react-native-codegen@^0.71.3, react-native-codegen@^0.71.5: + version "0.71.5" + resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.71.5.tgz#454a42a891cd4ca5fc436440d301044dc1349c14" + integrity sha512-rfsuc0zkuUuMjFnrT55I1mDZ+pBRp2zAiRwxck3m6qeGJBGK5OV5JH66eDQ4aa+3m0of316CqrJDRzVlYufzIg== dependencies: "@babel/parser" "^7.14.0" - flow-parser "^0.121.0" + flow-parser "^0.185.0" jscodeshift "^0.13.1" nullthrows "^1.1.1" -react-native-gradle-plugin@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.5.tgz#1f20d437b140eda65b6e3bdf6eb102bbab1a5a10" - integrity sha512-kGupXo+pD2mB6Z+Oyowor3qlCroiS32FNGoiGQdwU19u8o+NNhEZKwoKfC5Qt03bMZSmFlcAlTyf79vrS2BZKQ== - dependencies: - react-native-codegen "*" +react-native-gradle-plugin@^0.71.12: + version "0.71.13" + resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.13.tgz#6f60ff24ac712554903dfc0ae98475cb280c57a6" + integrity sha512-C66LNZAXbU0YDRkWx8d/8kjesdu7fsUAc/3QPJNftSXKEvEtnFZK2aH/rIgu1s5dbTcE0fjhdVPNJMRIfKo61w== -react-native-gradle-plugin@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.6.tgz#b61a9234ad2f61430937911003cddd7e15c72b45" - integrity sha512-eIlgtsmDp1jLC24dRn43hB3kEcZVqx6DUQbR0N1ABXGnMEafm9I3V3dUUeD1vh+Dy5WqijSoEwLNUPLgu5zDMg== - -react-native-macos@0.68.62: - version "0.68.62" - resolved "https://registry.yarnpkg.com/react-native-macos/-/react-native-macos-0.68.62.tgz#76785f42c1f3d37147c52ecdd1daf04331bab808" - integrity sha512-0IZ0ob8z6TUsENdbgWhKXdgn+HEYVPPPx3QU5WKkdpCoKuHFv9y9F+bPi4uMG36u2khF1eod1hkajXG3tOexDQ== - dependencies: - "@jest/create-cache-key-function" "^27.0.1" - "@react-native-community/cli" "^7.0.3" - "@react-native-community/cli-platform-android" "^7.0.1" - "@react-native-community/cli-platform-ios" "^7.0.1" - "@react-native-community/cli-tools" "^7.0.1" - "@react-native/assets" "1.0.0" - "@react-native/normalize-color" "2.0.0" - "@react-native/polyfills" "2.0.0" - abort-controller "^3.0.0" - anser "^1.4.9" - base64-js "^1.1.2" - deprecated-react-native-prop-types "^2.3.0" - event-target-shim "^5.0.1" - hermes-engine "~0.11.0" - invariant "^2.2.4" - jsc-android "^250230.2.1" - metro-react-native-babel-transformer "0.67.0" - metro-runtime "0.67.0" - metro-source-map "0.67.0" - nullthrows "^1.1.1" - pretty-format "^26.5.2" - promise "^8.0.3" - react-devtools-core "^4.23.0" - react-native-codegen "^0.0.17" - react-native-gradle-plugin "^0.0.6" - react-refresh "^0.4.0" - react-shallow-renderer "16.14.1" - readable-stream "^4.0.0" - regenerator-runtime "^0.13.2" - scheduler "^0.20.2" - stacktrace-parser "^0.1.3" - use-subscription ">=1.0.0 <1.6.0" - whatwg-fetch "^3.0.0" - ws "^6.1.4" +react-native-gradle-plugin@^0.71.15: + version "0.71.15" + resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.15.tgz#9e6b506f30729fe8eb086981702f4e3c891d2b13" + integrity sha512-7S3pAuPaQJlhax6EZ4JMsDNpj05TfuzX9gPgWLrFfAIWIFLuJ6aDQYAZy2TEI9QJALPoWrj8LWaqP/DGYh14pw== -react-native-test-app@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/react-native-test-app/-/react-native-test-app-2.3.2.tgz#4f9b003077f02837817ec86844e9175f0fec2d6a" - integrity sha512-xe9Fb4oHBSbEvzbGmmVxHoSNIXT26gfH1CvGyAiiWq9V485s9duQj72dwZKMQtnZGw3jjahafFhv2D49pzadOg== +react-native-test-app@2.3.12: + version "2.3.12" + resolved "https://registry.yarnpkg.com/react-native-test-app/-/react-native-test-app-2.3.12.tgz#d3a7fd55fdd15a89b7bda1093a5fcbd6a5cb41ef" + integrity sha512-+kVRB5CgB9LSOeCpYD47m18wG2GZSffQ6pafb0/hiVw3DAV2xKcOUJbhkyxggC7RJb3WHgP2uNvEnFgz7/cngw== dependencies: ajv "^8.0.0" chalk "^4.1.0" @@ -11062,106 +11399,108 @@ react-native-test-app@2.3.2: uuid "^8.3.2" yargs "^16.0.0" -react-native-windows@0.68.4: - version "0.68.4" - resolved "https://registry.yarnpkg.com/react-native-windows/-/react-native-windows-0.68.4.tgz#8619b002c05d33e52c3aa0b871ad55789016d8d5" - integrity sha512-i4PMiFbbuKmCcYaMQs0YKpsxl9mn2m8Ij4BnOYtJji4eS108O3/bB/qLd3povWq5qu96D2anpw/KleVozvMBjw== +react-native-windows@0.71.0: + version "0.71.0" + resolved "https://registry.yarnpkg.com/react-native-windows/-/react-native-windows-0.71.0.tgz#d5514f2a85020985851c06f8fa482580c6a80a28" + integrity sha512-k56CKEJpIFA50LAT2JZJxz4EkTx1hkZLcQL/g3aMTAu9hwnKptQVaAMs8okhP1fgMoUbbZ1lQB+deYyHyJAr7Q== dependencies: "@babel/runtime" "^7.0.0" - "@jest/create-cache-key-function" "^27.0.1" - "@react-native-community/cli" "^7.0.3" - "@react-native-community/cli-platform-android" "^7.0.1" - "@react-native-community/cli-platform-ios" "^7.0.1" - "@react-native-windows/cli" "0.68.2" - "@react-native-windows/virtualized-list" "0.68.0" + "@jest/create-cache-key-function" "^29.2.1" + "@react-native-community/cli" "10.0.0" + "@react-native-community/cli-platform-android" "10.0.0" + "@react-native-community/cli-platform-ios" "10.0.0" + "@react-native-windows/cli" "0.71.0" "@react-native/assets" "1.0.0" - "@react-native/normalize-color" "2.0.0" + "@react-native/normalize-color" "2.1.0" "@react-native/polyfills" "2.0.0" abort-controller "^3.0.0" anser "^1.4.9" base64-js "^1.1.2" - deprecated-react-native-prop-types "^2.3.0" + deprecated-react-native-prop-types "^3.0.1" event-target-shim "^5.0.1" - hermes-engine "~0.11.0" invariant "^2.2.4" + jest-environment-node "^29.2.1" jsc-android "^250230.2.1" - metro-react-native-babel-transformer "0.67.0" - metro-runtime "0.67.0" - metro-source-map "0.67.0" + memoize-one "^5.0.0" + metro-react-native-babel-transformer "0.73.5" + metro-runtime "0.73.5" + metro-source-map "0.73.5" + mkdirp "^0.5.1" nullthrows "^1.1.1" pretty-format "^26.5.2" - promise "^8.0.3" - react-devtools-core "^4.23.0" - react-native-codegen "^0.0.13" - react-native-gradle-plugin "^0.0.5" + promise "^8.3.0" + react-devtools-core "^4.26.1" + react-native-codegen "^0.71.3" + react-native-gradle-plugin "^0.71.12" react-refresh "^0.4.0" - react-shallow-renderer "16.14.1" + react-shallow-renderer "^16.15.0" regenerator-runtime "^0.13.2" - scheduler "^0.20.2" + scheduler "^0.23.0" source-map-support "^0.5.19" stacktrace-parser "^0.1.3" - use-subscription "^1.0.0" + use-sync-external-store "^1.0.0" whatwg-fetch "^3.0.0" - ws "^6.1.4" + ws "^6.2.2" -react-native@0.68.5: - version "0.68.5" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.68.5.tgz#8ba7389e00b757c59b6ea23bf38303d52367d155" - integrity sha512-t3kiQ/gumFV+0r/NRSIGtYxanjY4da0utFqHgkMcRPJVwXFWC0Fr8YiOeRGYO1dp8EfrSsOjtfWic/inqVYlbQ== +react-native@0.71.3: + version "0.71.3" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.3.tgz#0faab799c49e61ba12df9e6525c3ac7d595d673c" + integrity sha512-RYJXCcQGa4NTfKiPgl92eRDUuQ6JGDnHqFEzRwJSqEx9lWvlvRRIebstJfurzPDKLQWQrvITR7aI7e09E25mLw== dependencies: - "@jest/create-cache-key-function" "^27.0.1" - "@react-native-community/cli" "^7.0.3" - "@react-native-community/cli-platform-android" "^7.0.1" - "@react-native-community/cli-platform-ios" "^7.0.1" + "@jest/create-cache-key-function" "^29.2.1" + "@react-native-community/cli" "10.1.3" + "@react-native-community/cli-platform-android" "10.1.3" + "@react-native-community/cli-platform-ios" "10.1.1" "@react-native/assets" "1.0.0" - "@react-native/normalize-color" "2.0.0" + "@react-native/normalize-color" "2.1.0" "@react-native/polyfills" "2.0.0" abort-controller "^3.0.0" anser "^1.4.9" base64-js "^1.1.2" - deprecated-react-native-prop-types "^2.3.0" + deprecated-react-native-prop-types "^3.0.1" event-target-shim "^5.0.1" - hermes-engine "~0.11.0" invariant "^2.2.4" - jsc-android "^250230.2.1" - metro-react-native-babel-transformer "0.67.0" - metro-runtime "0.67.0" - metro-source-map "0.67.0" + jest-environment-node "^29.2.1" + jsc-android "^250231.0.0" + memoize-one "^5.0.0" + metro-react-native-babel-transformer "0.73.7" + metro-runtime "0.73.7" + metro-source-map "0.73.7" + mkdirp "^0.5.1" nullthrows "^1.1.1" pretty-format "^26.5.2" - promise "^8.2.0" - react-devtools-core "^4.23.0" - react-native-codegen "^0.0.18" - react-native-gradle-plugin "^0.0.6" + promise "^8.3.0" + react-devtools-core "^4.26.1" + react-native-codegen "^0.71.5" + react-native-gradle-plugin "^0.71.15" react-refresh "^0.4.0" - react-shallow-renderer "16.14.1" + react-shallow-renderer "^16.15.0" regenerator-runtime "^0.13.2" - scheduler "^0.20.2" + scheduler "^0.23.0" stacktrace-parser "^0.1.3" - use-subscription ">=1.0.0 <1.6.0" + use-sync-external-store "^1.0.0" whatwg-fetch "^3.0.0" - ws "^6.1.4" + ws "^6.2.2" react-refresh@^0.4.0: version "0.4.3" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.3.tgz#966f1750c191672e76e16c2efa569150cc73ab53" integrity sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA== -react-shallow-renderer@16.14.1: - version "16.14.1" - resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz#bf0d02df8a519a558fd9b8215442efa5c840e124" - integrity sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg== +react-shallow-renderer@^16.15.0: + version "16.15.0" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" + integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== dependencies: object-assign "^4.1.1" - react-is "^16.12.0 || ^17.0.0" + react-is "^16.12.0 || ^17.0.0 || ^18.0.0" -react@17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== +react@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" read-cmd-shim@^1.0.1, read-cmd-shim@^1.0.5: version "1.0.5" @@ -11287,16 +11626,6 @@ readable-stream@^1.0.31, readable-stream@~1.1.10: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.3.0.tgz#0914d0c72db03b316c9733bb3461d64a3cc50cba" - integrity sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ== - dependencies: - abort-controller "^3.0.0" - buffer "^6.0.3" - events "^3.3.0" - process "^0.11.10" - readdir-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.0.0.tgz#a495436934bbe57be6a68039d16e8946621eb8c5" @@ -11351,17 +11680,17 @@ redeyed@~2.1.0: dependencies: esprima "~4.0.0" -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== dependencies: - regenerate "^1.4.0" + regenerate "^1.4.2" -regenerate@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" - integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.11.0: version "0.11.1" @@ -11373,13 +11702,6 @@ regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.3, regenerator-runtime@^0 resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== -regenerator-transform@^0.14.2: - version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" - integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== - dependencies: - "@babel/runtime" "^7.8.4" - regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -11393,17 +11715,22 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpu-core@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" - integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +regexpu-core@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" + integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" registry-auth-token@^3.0.1: version "3.4.0" @@ -11427,23 +11754,18 @@ registry-url@^3.0.3: dependencies: rc "^1.0.1" -regjsgen@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== -regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== dependencies: jsesc "~0.5.0" -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" @@ -11549,7 +11871,12 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.13.1, resolve@^1.18.1, resolve@^1.8.1: +resolve.exports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e" + integrity sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg== + +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.13.1, resolve@^1.8.1: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== @@ -11558,6 +11885,15 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.13 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.20.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + responselike@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" @@ -11664,11 +12000,6 @@ rpc-websockets@^5.1.1: uuid "^3.4.0" ws "^5.2.2" -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - run-async@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -11725,21 +12056,6 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - sanitize-filename@^1.6.1: version "1.6.3" resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" @@ -11747,25 +12063,17 @@ sanitize-filename@^1.6.1: dependencies: truncate-utf8-bytes "^1.0.0" -sax@>=0.6.0, sax@^1.2.1: +sax@>=0.6.0: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" selenium-appium@1.0.2: version "1.0.2" @@ -11845,10 +12153,10 @@ semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.3.2, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== +semver@^7.0.0, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" @@ -11987,16 +12295,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" - shell-quote@^1.4.3, shell-quote@^1.6.1, shell-quote@^1.7.2, shell-quote@^1.7.3: version "1.7.3" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" @@ -12011,11 +12309,6 @@ shelljs@0.8.x, shelljs@^0.8.4: interpret "^1.0.0" rechoir "^0.6.2" -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - shimmer@^1.1.0, shimmer@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" @@ -12026,6 +12319,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + signale@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/signale/-/signale-1.4.0.tgz#c4be58302fb0262ac00fc3d886a7c113759042f1" @@ -12035,15 +12333,6 @@ signale@^1.2.1: figures "^2.0.0" pkg-conf "^2.1.0" -simple-plist@^1.1.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.3.1.tgz#16e1d8f62c6c9b691b8383127663d834112fb017" - integrity sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw== - dependencies: - bplist-creator "0.1.0" - bplist-parser "0.3.1" - plist "^3.0.5" - simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -12155,7 +12444,7 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -"source-map-support@0.3.2 - 1.0.0", source-map-support@0.x, source-map-support@^0.5.12, source-map-support@^0.5.16, source-map-support@^0.5.19, source-map-support@^0.5.3, source-map-support@^0.5.5, source-map-support@^0.5.6, source-map-support@^0.5.8, source-map-support@^0.5.9: +"source-map-support@0.3.2 - 1.0.0", source-map-support@0.x, source-map-support@^0.5.12, source-map-support@^0.5.16, source-map-support@^0.5.19, source-map-support@^0.5.3, source-map-support@^0.5.5, source-map-support@^0.5.8, source-map-support@^0.5.9, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -12163,12 +12452,20 @@ source-map-resolve@^0.5.0: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= @@ -12284,10 +12581,10 @@ stack-trace@0.0.x: resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= -stack-utils@^2.0.2: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" @@ -12402,14 +12699,14 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" + strip-ansi "^6.0.1" string.prototype.trimend@^1.0.1: version "1.0.1" @@ -12472,12 +12769,12 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^5.0.0" + ansi-regex "^5.0.1" strip-bom@^3.0.0: version "3.0.0" @@ -12506,7 +12803,7 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@^3.0.1: +strip-json-comments@^3.0.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -12533,7 +12830,7 @@ supports-color@^5.0.0, supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -12555,24 +12852,11 @@ supports-hyperlinks@^1.0.1: has-flag "^2.0.0" supports-color "^5.0.0" -supports-hyperlinks@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - table@^5.2.3: version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" @@ -12672,13 +12956,15 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== +terser@^5.15.0: + version "5.16.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.1.tgz#5af3bc3d0f24241c7fb2024199d5c461a1075880" + integrity sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw== dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" test-exclude@^6.0.0: version "6.0.0" @@ -12769,6 +13055,11 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -12833,13 +13124,6 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -12882,10 +13166,10 @@ tslib@^2.0.1, tslib@^2.2.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tsutils@^3.14.0: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== +tsutils@^3.14.0, tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" @@ -12966,13 +13250,6 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -13019,28 +13296,28 @@ unbzip2-stream@^1.3.3: buffer "^5.2.1" through "^2.3.8" -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== -unicode-property-aliases-ecmascript@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" - integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== union-value@^1.0.0: version "1.0.1" @@ -13113,6 +13390,14 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= +update-browserslist-db@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + update-notifier@^2.2.0, update-notifier@^2.3.0, update-notifier@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" @@ -13153,12 +13438,10 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" -"use-subscription@>=1.0.0 <1.6.0", use-subscription@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" - integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA== - dependencies: - object-assign "^4.1.1" +use-sync-external-store@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== use@^3.1.0: version "3.1.1" @@ -13224,11 +13507,6 @@ uuid@^3.3.2, uuid@^3.3.3, uuid@^3.4.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" - integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== - uuid@^8.0.0, uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" @@ -13239,14 +13517,14 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== -v8-to-istanbul@^7.0.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1" - integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow== +v8-to-istanbul@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== dependencies: + "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" - source-map "^0.7.3" validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" @@ -13287,27 +13565,20 @@ vlq@^1.0.0: resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - -walker@^1.0.7, walker@~1.0.5: +walker@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= dependencies: makeerror "1.0.x" +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + wcwidth@^1.0.0, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -13393,33 +13664,11 @@ webidl-conversions@^3.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - whatwg-fetch@^3.0.0: version "3.4.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.0.tgz#e11de14f4878f773fbebcde8871b2c0699af8b30" integrity sha512-rsum2ulz2iuZH08mJkT0Yi6JnKhwdw4oeyMjokgxd+mmqYSd9cPpOQf01TIWgjxG/U4+QR+AwKq6lSbXVxkyoQ== -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" @@ -13428,15 +13677,6 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -13571,15 +13811,13 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.3: imurmurhash "^0.1.4" signal-exit "^3.0.2" -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== +write-file-atomic@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.0.tgz#54303f117e109bf3d540261125c8ea5a7320fab0" + integrity sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w== dependencies: imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" + signal-exit "^3.0.7" write@1.0.3: version "1.0.3" @@ -13595,26 +13833,18 @@ ws@^5.2.2: dependencies: async-limiter "~1.0.0" -ws@^6.1.4: +ws@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== dependencies: async-limiter "~1.0.0" -ws@^7, ws@^7.0.0, ws@^7.2.3, ws@^7.4.6, ws@^7.5.1: +ws@^7, ws@^7.0.0, ws@^7.2.3, ws@^7.5.1: version "7.5.7" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== -xcode@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/xcode/-/xcode-3.0.1.tgz#3efb62aac641ab2c702458f9a0302696146aa53c" - integrity sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA== - dependencies: - simple-plist "^1.1.0" - uuid "^7.0.3" - xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" @@ -13637,11 +13867,6 @@ xml-formatter@^2.4.0: dependencies: xml-parser-xo "^3.2.0" -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - xml-parse-from-string@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" @@ -13677,18 +13902,6 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -xmldoc@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" - integrity sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ== - dependencies: - sax "^1.2.1" - xmldom@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.3.0.tgz#e625457f4300b5df9c2e1ecb776147ece47f3e5a" @@ -13768,6 +13981,11 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + yargs-parser@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" @@ -13810,7 +14028,7 @@ yargs@^14.0.0, yargs@^14.2.3: y18n "^4.0.0" yargs-parser "^15.0.1" -yargs@^15.0.1, yargs@^15.1.0, yargs@^15.3.0, yargs@^15.3.1, yargs@^15.4.1: +yargs@^15.0.1, yargs@^15.1.0, yargs@^15.3.0: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== @@ -13827,7 +14045,7 @@ yargs@^15.0.1, yargs@^15.1.0, yargs@^15.3.0, yargs@^15.3.1, yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.0.0: +yargs@^16.0.0, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -13840,6 +14058,19 @@ yargs@^16.0.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.3.1, yargs@^17.5.1: + version "17.6.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" + integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yargs@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" @@ -13867,6 +14098,11 @@ yauzl@^2.10.0, yauzl@^2.7.0: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zip-stream@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-2.1.3.tgz#26cc4bdb93641a8590dd07112e1f77af1758865b"