diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..61a74dab
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,15 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+
+indent_style = space
+# indent_size = 2
+
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 00000000..c21695a7
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,21 @@
+module.exports = {
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ project: 'tsconfig.json',
+ tsconfigRootDir: __dirname,
+ sourceType: 'module',
+ },
+ plugins: [
+ '@typescript-eslint/eslint-plugin'
+ ],
+ root: true,
+ env: {
+ jest: true,
+ },
+ ignorePatterns: [
+ '.eslintrc.js',
+ 'lib/**/*',
+ 'TestApp/**/*'
+ ],
+ extends: ['@react-native', 'prettier'],
+};
diff --git a/.github/workflows/android_build.yml b/.github/workflows/android_build.yml
index f8264f50..bd6be040 100644
--- a/.github/workflows/android_build.yml
+++ b/.github/workflows/android_build.yml
@@ -23,7 +23,7 @@ jobs:
- name: Install NodeJS
uses: actions/setup-node@v3
with:
- node-version: '16.17.0'
+ node-version: '18.17.1'
cache: 'yarn'
# install project dependencies
@@ -52,8 +52,8 @@ jobs:
- name: Make Gradlew Executable
run: cd android && chmod +x ./gradlew
- - name: Run Android library unit tests
- run: cd android && ./gradlew clean && ./gradlew testDebugUnitTest && cd ..
+ - name: Run Android unit tests
+ run: cd TestApp/android && ./gradlew clean && ./gradlew testDebugUnitTest && cd ../..
- name: Bundle JS for Android
run: cd TestApp && mkdir android/app/src/main/assets && yarn bundle:android-dev && cd ..
diff --git a/.github/workflows/android_integration_tests.yml b/.github/workflows/android_integration_tests.yml
index de7713de..09b9f911 100644
--- a/.github/workflows/android_integration_tests.yml
+++ b/.github/workflows/android_integration_tests.yml
@@ -31,7 +31,7 @@ jobs:
- name: Install NodeJS
uses: actions/setup-node@v3
with:
- node-version: '16.17.0'
+ node-version: '18.17.1'
cache: 'yarn'
# install project dependencies
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..67076105
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,7 @@
+{
+ "quoteProps": "consistent",
+ "singleQuote": true,
+ "tabWidth": 2,
+ "trailingComma": "es5",
+ "useTabs": false
+}
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..9a88f0ab
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,16 @@
+# Contributing
+
+## Contributing to Code
+Before contributing, please read through the [Klarna Mobile SDK documentation](https://docs.klarna.com/mobile-sdk/).
+
+### Branching
+Prefix the branch you are going to work on depending on what you are working on (bug fix or feature). Use the following prefixes when creating a new branch:
+
+* **feature/** if the branch contains a new feature, for example: `feature/my-shiny-feature`.
+* **bugfix/** if the branch contains a bug fix, for example: `bugfix/my-bug-fix`.
+
+### Pull Requests
+When creating a PR, please include as much information as possible about the type of enhancement, whether if it's a bugfix, new functionality, or any other change. There's [a template](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/pull-request.md) for you to fill out, which will make the review process for the maintainers faster. When creating a PR do it against the `master` branch. The PR should include:
+
+* **A clear and descriptive title**.
+* **Description of the issue** if you are fixing a bug together with a link to the relevant issue or **background for introducing a new feature**.
diff --git a/Gemfile b/Gemfile
index 11f36e3e..f99ba64d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,8 +1,8 @@
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
-ruby '2.7.5'
+ruby '>= 2.7.5'
-gem 'cocoapods', '~> 1.11', '>= 1.11.2'
-gem "fastlane"
-gem "xcode-install"
+gem 'cocoapods', '~> 1.12'
+gem 'fastlane'
+gem 'xcode-install'
diff --git a/Gemfile.lock b/Gemfile.lock
index 479686b6..4490d628 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,15 +1,14 @@
GEM
remote: https://rubygems.org/
specs:
- CFPropertyList (3.0.5)
+ CFPropertyList (3.0.6)
rexml
- activesupport (6.1.7.3)
+ activesupport (7.0.8)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
- zeitwerk (~> 2.3)
- addressable (2.8.1)
+ addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
@@ -17,32 +16,32 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
- aws-partitions (1.626.0)
- aws-sdk-core (3.142.0)
+ aws-partitions (1.824.0)
+ aws-sdk-core (3.181.1)
aws-eventstream (~> 1, >= 1.0.2)
- aws-partitions (~> 1, >= 1.525.0)
- aws-sigv4 (~> 1.1)
+ aws-partitions (~> 1, >= 1.651.0)
+ aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.58.0)
- aws-sdk-core (~> 3, >= 3.127.0)
+ aws-sdk-kms (1.71.0)
+ aws-sdk-core (~> 3, >= 3.177.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.114.0)
- aws-sdk-core (~> 3, >= 3.127.0)
+ aws-sdk-s3 (1.134.0)
+ aws-sdk-core (~> 3, >= 3.181.0)
aws-sdk-kms (~> 1)
- aws-sigv4 (~> 1.4)
- aws-sigv4 (1.5.1)
+ aws-sigv4 (~> 1.6)
+ aws-sigv4 (1.6.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
claide (1.1.0)
- cocoapods (1.11.3)
+ cocoapods (1.12.1)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
- cocoapods-core (= 1.11.3)
+ cocoapods-core (= 1.12.1)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
- cocoapods-downloader (>= 1.4.0, < 2.0)
+ cocoapods-downloader (>= 1.6.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
- cocoapods-trunk (>= 1.4.0, < 2.0)
+ cocoapods-trunk (>= 1.6.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
@@ -50,10 +49,10 @@ GEM
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
nap (~> 1.0)
- ruby-macho (>= 1.0, < 3.0)
+ ruby-macho (>= 2.3.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
- cocoapods-core (1.11.3)
- activesupport (>= 5.0, < 7)
+ cocoapods-core (1.12.1)
+ activesupport (>= 5.0, < 8)
addressable (~> 2.8)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
@@ -77,17 +76,17 @@ GEM
highline (~> 2.0.0)
concurrent-ruby (1.2.2)
declarative (0.0.20)
- digest-crc (0.6.4)
+ digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
escape (0.0.4)
- ethon (0.15.0)
+ ethon (0.16.0)
ffi (>= 1.15.0)
- excon (0.92.4)
- faraday (1.10.2)
+ excon (0.103.0)
+ faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
@@ -115,8 +114,8 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
- fastimage (2.2.6)
- fastlane (2.209.1)
+ fastimage (2.2.7)
+ fastlane (2.215.1)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -137,10 +136,11 @@ GEM
google-apis-playcustomapp_v1 (~> 0.1)
google-cloud-storage (~> 1.31)
highline (~> 2.0)
+ http-cookie (~> 1.0.5)
json (< 3.0.0)
jwt (>= 2.1.0, < 3)
mini_magick (>= 4.9.4, < 5.0.0)
- multipart-post (~> 2.0.0)
+ multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
optparse (~> 0.1.1)
plist (>= 3.1.0, < 4.0.0)
@@ -148,7 +148,7 @@ GEM
security (= 0.1.3)
simctl (~> 1.6.3)
terminal-notifier (>= 2.0.0, < 3.0.0)
- terminal-table (>= 1.4.5, < 2.0.0)
+ terminal-table (~> 3)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
@@ -159,9 +159,9 @@ GEM
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
- google-apis-androidpublisher_v3 (0.25.0)
- google-apis-core (>= 0.7, < 2.a)
- google-apis-core (0.7.0)
+ google-apis-androidpublisher_v3 (0.49.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-core (0.11.1)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -170,30 +170,29 @@ GEM
retriable (>= 2.0, < 4.a)
rexml
webrick
- google-apis-iamcredentials_v1 (0.13.0)
- google-apis-core (>= 0.7, < 2.a)
- google-apis-playcustomapp_v1 (0.10.0)
- google-apis-core (>= 0.7, < 2.a)
- google-apis-storage_v1 (0.17.0)
- google-apis-core (>= 0.7, < 2.a)
+ google-apis-iamcredentials_v1 (0.17.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-playcustomapp_v1 (0.13.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-storage_v1 (0.19.0)
+ google-apis-core (>= 0.9.0, < 2.a)
google-cloud-core (1.6.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
- google-cloud-errors (1.2.0)
- google-cloud-storage (1.39.0)
+ google-cloud-errors (1.3.1)
+ google-cloud-storage (1.44.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
- google-apis-storage_v1 (~> 0.17.0)
+ google-apis-storage_v1 (~> 0.19.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
- googleauth (1.2.0)
+ googleauth (1.8.0)
faraday (>= 0.17.3, < 3.a)
jwt (>= 1.4, < 3.0)
- memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
@@ -201,25 +200,24 @@ GEM
http-cookie (1.0.5)
domain_name (~> 0.5)
httpclient (2.8.3)
- i18n (1.12.0)
+ i18n (1.14.1)
concurrent-ruby (~> 1.0)
- jmespath (1.6.1)
- json (2.6.2)
- jwt (2.5.0)
- memoist (0.16.2)
- mini_magick (4.11.0)
- mini_mime (1.1.2)
- minitest (5.18.0)
+ jmespath (1.6.2)
+ json (2.6.3)
+ jwt (2.7.1)
+ mini_magick (4.12.0)
+ mini_mime (1.1.5)
+ minitest (5.20.0)
molinillo (0.8.0)
multi_json (1.15.0)
- multipart-post (2.0.0)
+ multipart-post (2.3.0)
nanaimo (0.3.0)
nap (1.1.0)
naturally (2.2.1)
netrc (0.11.0)
optparse (0.1.1)
os (1.1.4)
- plist (3.6.0)
+ plist (3.7.0)
public_suffix (4.0.7)
rake (13.0.6)
representable (3.2.0)
@@ -227,23 +225,23 @@ GEM
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
- rexml (3.2.5)
+ rexml (3.2.6)
rouge (2.0.7)
ruby-macho (2.5.1)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
- signet (0.17.0)
+ signet (0.18.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
- simctl (1.6.8)
+ simctl (1.6.10)
CFPropertyList
naturally
terminal-notifier (2.0.0)
- terminal-table (1.8.0)
- unicode-display_width (~> 1.1, >= 1.1.1)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
tty-screen (0.8.1)
@@ -257,8 +255,8 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
- unicode-display_width (1.8.0)
- webrick (1.7.0)
+ unicode-display_width (2.4.2)
+ webrick (1.8.1)
word_wrap (1.0.0)
xcode-install (2.8.1)
claide (>= 0.9.1)
@@ -274,18 +272,17 @@ GEM
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
- zeitwerk (2.6.7)
PLATFORMS
- ruby
+ arm64-darwin-21
DEPENDENCIES
- cocoapods (~> 1.11, >= 1.11.2)
+ cocoapods (~> 1.12)
fastlane
xcode-install
RUBY VERSION
- ruby 2.7.5p203
+ ruby 3.0.0p0
BUNDLED WITH
- 2.1.4
+ 2.2.3
diff --git a/README.md b/README.md
index 24f13670..b3980a65 100644
--- a/README.md
+++ b/README.md
@@ -1,177 +1,133 @@
-# React Native Klarna In-App SDK
+# Klarna Mobile SDK React Native
-![](https://img.shields.io/github/license/klarna/react-native-klarna-inapp-sdk)
-![](https://img.shields.io/npm/v/react-native-klarna-inapp-sdk)
-![](https://img.shields.io/npm/dependency-version/react-native-klarna-inapp-sdk/peer/react-native)
+[![NPM][npm-badge]][npm-url]
+[![React Native][dependency-badge]][dependency-url]
+[![Platforms][platforms-badge]][platforms-url]
+[![License][license-badge]][license-url]
+[![Developed at Klarna][klarna-badge]][klarna-url]
-This library wraps Klarna's In-App SDK and exposes its functionality as React Native components. It
+This library wraps Klarna Mobile SDK and exposes its functionality as React Native components. It
currently supports Klarna Payments via a Payment View component.
This repository also includes a test application that you can use to see how it works.
-**Looking for the pure native Klarna In-App SDK?** Check out the [Klarna In-App SDK](https://github.com/klarna/klarna-inapp-sdk) repo instead.
+### SDK for Other Platforms
+
+* [Android](https://github.com/klarna/klarna-mobile-sdk)
+* [iOS](https://github.com/klarna/klarna-mobile-sdk)
+* [Flutter](https://github.com/klarna/klarna-mobile-sdk-flutter)
## Requirements
* iOS 10 or later.
* Android 4.4 or later.
-### Klarna In-App SDK documentation
-[Overview of the SDK](https://developers.klarna.com/documentation/in-app/)
-
-## What Does React Native Klarna In-App SDK Offer?
-This library allows React Native apps to add views with Klarna content to their app. We currently support Klarna Payments, allowing you to add payment views to your checkout and authorizing a session to create an order natively.
-
-### Why should you use the SDK?
-The SDK removes any possible friction in your app's checkout flow by leveraging native functionality in iOS and Android. Some of the things the SDK does are:
+### Documentations
-* **Plays nicely with 3rd-party apps.** Many customers complete their purchase through their banking application or other 3rd-party apps. We make this experience seamless not just by opening these apps, but returning your users automatically when they’re done.
-* **Safeguards your users' identity.** The SDK adds an extra layer of security lowering the risk of fraudulent purchases. It also insures that your customer doesn’t have to write in any redundant info. (e.g. address or credentials) on successive purchases.
-* **Improves 3D Secure flow.** If certain payment methods require opening banking pages, we’ll display an in-app browser. Your customer can safely authenticate with their bank without ever leaving your app.
-* **Open links without making your customers leave your app.** As with 3D Secure, we open most resources in an in-app browser or a fullscreen overlay. This insures that your customer doesn’t ever have to leave your app.
+* [Overview](https://docs.klarna.com/mobile-sdk/)
+* [Android](https://docs.klarna.com/mobile-sdk/android/)
+* [iOS](https://docs.klarna.com/mobile-sdk/ios/)
+* [React Native](https://docs.klarna.com/mobile-sdk/reactnative/)
## Getting started
-`$ npm install react-native-klarna-inapp-sdk --save`
-
-### Mostly automatic installation
-
-`$ react-native link react-native-klarna-inapp-sdk`
-
-### Manual installation
-
-
-#### iOS
-
-We strongly encourage you to use CocoaPods to manage the library and follow the instructions below to add the SDK as a dependency to the React Native app. If you add the SDK to CocoaPods elsewhere in the application it may cause the SDK to not be visible to the library.
+### Add Dependency
-1. After running `$ npm install react-native-klarna-inapp-sdk --save` go to `[your project]/ios` folder.
-2. Make sure you have a Podfile ready, if not use `pod init`. Check that `platform :ios, ‘10.0’`.
-3. Go to `[your project]/node_modules/react-native-klarna-inapp-sdk/react-native-klarna-inapp-sdk.podspec` and make sure that `s.dependency ‘KlarnaMobileSDK’, ’~> 2.0.12` and `s.platform = :ios, “10.0”`.
-4. Add `react-native-klarna-inapp-sdk` as a dependency to your podfile (`[your project]/ios` folder) `pod ‘react-native-klarna-inapp-sdk’, :podspec => ‘../node_modules/react-native-klarna-inapp-sdk/react-native-klarna-inapp-sdk.podspec’`.
-5. Go back to `[your project]/ios` and run `pod install`.
+#### NPM
-**Note:** If you encounter the build failure error Library not loaded: `@rpath/libswiftCore.dylib`, then you might need to create a `Swift Bridging Header`. to do so, please follow the steps below:
-* In XCode, create a new .swift file in the project.
-* A prompt window would ask you if you want to configure the Bridging Header, choose `yes`.
-* Clean the project and DerivedData.
-* Build the project.
+```shell
+npm install react-native-klarna-inapp-sdk --save
+```
-#### Android
+#### Yarn
-1. Open up `android/app/src/main/java/[...]/MainApplication.java`
- - Add `import com.klarna.inapp.sdk.KlarnaPaymentViewPackage;` to the imports at the top of the file
- - Add `new KlarnaPaymentViewPackage()` to the list returned by the `getPackages()` method
-2. Append the following lines to `android/settings.gradle`:
- ```
- include ':react-native-klarna-inapp-sdk'
- project(':react-native-klarna-inapp-sdk').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-klarna-inapp-sdk/android')
- ```
-3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
- ```
- implementation project(':react-native-klarna-inapp-sdk')
- ```
-
-**Note:** If you encounter any build failure errors regarding the `androidx.annotations` package missing, you should enable `react-native-jetifier` in the `gradle.properties` file inside your project. See how to enable this [here](https://github.com/jumpn/react-native-jetifier).
+```shell
+yarn add react-native-klarna-inapp-sdk
+```
### Warning regarding Android integration
-Both the iOS and Android integrations depend on the native SDK.
+Both the iOS and Android integrations depend on the native SDK.
We've experienced issues with React Native 59 and above where 3rd party Gradle repositories won't
-be recognized in the Android project's `build.gradle`. To address this, you'll need to add a
-reference to the repository in your own app's `build.gradle`.
+be recognized in the Android project's `build.gradle`. To address this, you'll need to add a
+reference to the repository in your own app's `build.gradle`.
-You can do it by adding the lines between the comments below:
+You can do it by adding the lines between the comments below:
-```gradle
+```groovy
allprojects {
repositories {
- mavenLocal()
- maven {
- // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
- url("$rootDir/../node_modules/react-native/android")
- }
- maven {
- // Android JSC is installed from npm
- url("$rootDir/../node_modules/jsc-android/dist")
- }
- google()
- mavenCentral {
- // We don't want to fetch react-native from Maven Central as there are
- // older versions over there.
- content {
- excludeGroup "com.facebook.react"
- }
- }
- // Add the lines below vvv
+ ...
+ // Add the lines below
maven {
url 'https://x.klarnacdn.net/mobile-sdk/'
}
- // Add the lines above ^^^
}
}
-
```
---
## Usage
-You can import the `KlarnaPaymentView` from the library. You'll then be able to add it as a
+You can import the `KlarnaPaymentView` from the library. You'll then be able to add it as a
component to your app. This component exposes callbacks as props and methods you can call via the
-compoent's ref.
+component's ref.
-The view will self-size height-wise and grow it fill it containing view's width.
+The view will self-size height-wise and grow it fill it containing view's width.
### Props
It has the following props:
-| Name | Type | Description |
-| --- | --- | --- |
-| `category` | `String` | The payment method category you want to render in your view.|
-| `onInitialized` | `() => {}` | The initialize call succeeded.|
-| `onLoaded` | `() => {}` | The load call succeeded.|
-| `onLoadedPaymentReview` | `() => {}` | The load payment review call succeeded.|
-| `onAuthorized` | `({}) => {}` | The authorize call succeeded.|
-| `onReauthorized` | `({}) => {}` | The reauthorize call succeeded.|
-| `onFinalized` | `({}) => {}` | The finalize call succeeded.|
-| `onError` | `({}) => {}` | An error occurred.|
+| Name | Type | Description |
+|-------------------------| --- |-------------------------------------------------------------------------------|
+| `category` | `String` | The payment method category you want to render in your view. |
+| `returnUrl` | `String` | An app-defined URL scheme the component uses to return customers to your app. |
+| `onInitialized` | `() => {}` | The initialize call completed. |
+| `onLoaded` | `() => {}` | The load call completed. |
+| `onLoadedPaymentReview` | `() => {}` | The load payment review call completed. |
+| `onAuthorized` | `(approved, authToken, finalizeRequired) => {}` | The authorize call completed. |
+| `onReauthorized` | `(approved, authToken) => {}` | The reauthorize call completed. |
+| `onFinalized` | `(approved, authToken) => {}` | The finalize call completed. |
+| `onError` | `(error) => {}` | An error occurred. |
---
+
+#### Return URL
+
+You can read more about how the return URL works and how to add it tou your iOS application [here](https://developers.klarna.com/documentation/in-app/ios/getting-started/#return-url) and for your Android application [here](https://developers.klarna.com/documentation/in-app/android/getting-started/#return-url).
+
---
### Prop callback parameters
-The `onAuthorized`, `onReauthorized`, `onFinalized` and `onError` will provide an object (via
-`nativeEvent`) with the following parameters:
-
---
-#### authorized: `Boolean`
+#### approved: `boolean`
-Determines whether the previous operation was successful and yielded an authorization token.
+Determines whether the previous operation was successful and yielded an authorization token.
##### Available on:
- `onAuthorized`
-- `onReauthorized`
-- `onFinalized`
+- `onReauthorized`
+- `onFinalized`
---
-#### authToken: `String / undefined`
+#### authToken: `string | null`
If `authorize()`, `reauthorize()` or `finalize()` succeeded, they will return a token you can submit
to your backend.
##### Available on:
- `onAuthorized`
-- `onReauthorized`
-- `onFinalized`
+- `onReauthorized`
+- `onFinalized`
---
-#### finalizeRequired: `Boolean / undefined`
+#### finalizeRequired: `boolean | null`
If `authorize()` requires that you additionally call `finalize()`, .
@@ -180,9 +136,10 @@ If `authorize()` requires that you additionally call `finalize()`, .
---
-#### error: `Object / undefined`
+#### error: `KlarnaPaymentsSDKError`
-If a method failed, `onError()` will let you know via an error object.
+If a method failed, `onError()` will let you know via an error object. Contains `name`, `message`,
+`action`, `isFatal`, `sessionId` properties.
##### Available on:
- `onError`
@@ -198,19 +155,14 @@ below example how these can be called. The methods are the following:
---
#### initialize()
-Initializes the view with a session token. You have to have added the view to your application and
+Initializes the view with a session token. You have to have added the view to your application and
supplied a payment method category.
##### Parameters
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| sessionToken | `String` | The session token you get from Klarna.|
-| returnUrl | `String` | An app-defined URL scheme the component uses to return customers to your app.|
-
-##### Return URL
-
-You can read more about how the return URL works and how to add it tou your iOS application [here](https://developers.klarna.com/documentation/in-app/ios/getting-started/#return-url) and for your Android application [here](https://developers.klarna.com/documentation/in-app/android/getting-started/#return-url).
+| Name | Type | Description |
+|---------|----------|--------------------------------------------------|
+| clientToken | `string` | The client token you get from Klarna Payments API. |
---
@@ -219,16 +171,16 @@ Loads the view. This will render content in the view.
##### Parameters
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| sessionData | `String / undefined` | A JSON object with updated session data serialized into a string.|
+| Name | Type | Description |
+| ---- |-----------------------|------------|
+| sessionData | `string \| undefined` | A JSON object with updated session data serialized into a string.|
---
#### loadPaymentReview()
-Renders a description of the payment terms your customer has agreed to.
+Renders a description of the payment terms your customer has agreed to.
-Once a session is authorized, you can then either render a payment review in the existing
+Once a session is authorized, you can then either render a payment review in the existing
payment view or `initialize()` a new payment view with the same session token and call this method.
##### Note:
@@ -241,10 +193,10 @@ Authorizes the payment session.
##### Parameters
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| autoFinalize | `Boolean / undefined` | A flag used to turn on/off auto-finalization for direct bank transfer.|
-| sessionData | `String / undefined` | A JSON object with updated session data serialized into a string.|
+| Name | Type | Description |
+| ---- |------------------------|----------------------------------------------------------------------|
+| autoFinalize | `boolean \| undefined` | A flag used to turn on/off auto-finalization for direct bank transfer. |
+| sessionData | `string \| undefined` | A JSON object with updated session data serialized into a string.|
---
@@ -254,9 +206,9 @@ the session and get a new authorization token.
##### Parameters
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| sessionData | `String / undefined` | A JSON object with updated session data serialized into a string.|
+| Name | Type | Description |
+| ---- |-----------------------| ----------- |
+| sessionData | `string \| undefined` | A JSON object with updated session data serialized into a string.|
---
@@ -266,155 +218,33 @@ ready.
##### Parameters
-| Name | Type | Description |
-| ---- | ---- | ----------- |
-| sessionData | `String / undefined` | A JSON object with updated session data serialized into a string.|
+| Name | Type | Description |
+| ---- |-----------------------|------------|
+| sessionData | `String \| undefined` | A JSON object with updated session data serialized into a string.|
---
-### More information
-
-You can read more about refs and how they're used [here](https://reactjs.org/docs/refs-and-the-dom.html).
-If you'd like to understand what each method does, you can read about it [on Klarna Developers](https://developers.klarna.com/documentation/in-app/overview/steps-klarna-payments/).
-
-
----
----
-
-## Example
-
-In addition to the test app in [/TestApp](https://github.com/klarna/react-native-klarna-inapp-sdk/tree/master/TestApp), the you can see an abridged version below.
-
-```jsx
-import KlarnaPaymentView from 'react-native-klarna-inapp-sdk';
-
-class MyCheckoutView extends React.Component {
-
- constructor(props) {
- super(props);
- this.state = {
- paymentViewLoaded: false
- };
- }
-
- componentDidMount() {
- // To initialize the component, you'll need call the component's initialize method with your
- // backend's session token and a return URL for your application.
- //
- // This should occur at some point when the payment view is added to your application's view,
- // but it should only be repeated if initialization fails.
- this.refs['my_ref'].initialize('my_session_token', 'my_apps_return_url')
- }
-
- onInitialized = () => {
- // Once the view is initialized, you can render content into it.
- this.refs['my_ref'].load()
- }
-
- onLoaded = () => {
- // Once the view is loaded, the user should be able to see the payment method. They can then
- // choose to use it (it's up to you to determine how that is recognized) and tap a "buy-like"
- // button.
- this.setState({paymentViewLoaded: true})
- }
-
- buyButtonPressed = () => {
- // When the button is tapped, call authorize() on the view.
- this.refs['my_ref'].authorize()
- }
-
- onAuthorized = (event) => {
- // If successfully authorized, the authorization token can be used by your backend to create
- // an order.
- //
- // You can also load a payment review view to allow the user to evaluate their
- // payment choice.
- let params = event.nativeEvent
-
- if (params.authorized) {
- submitAuthToken(params.authToken)
- }
- }
-
- render() {
- return(
- // Other parts of the view
- // ...
- // The payment view
-
- // ...
- // Your buy button
-
- );
- }
-}
-
-```
+## Support
-## Contributing
+If you are having any issues using the SDK in your project or if you think that something is wrong with the SDK itself, please follow our [support guide](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/SUPPORT.md).
-### Support
-
-If you are having any issues using the SDK in your project or if you think that something is wrong with the SDK itself, please create an issue on [Github](https://github.com/klarna/react-native-klarna-inapp-sdk/issues) or report a bug by following the guidelines in the next section.
-
-### How can I contribute?
-
-Thank you for reading this and taking time to contribute to React Native Klarna In-App SDK! Below is a set of guidelines to help you contribute whether you want to report a bug, come with suggestions or modify code.
-
-#### Reporting Bugs
-This section will guide you through submitting a bug report for Klarna In-App SDK.
-
-Before submitting a bug report, please check that the issue hasn't been reported before. If you find a *Closed* issue that seem to describe an issue that is similar to what you want to report, open a new issue and link to the original issue in the new one. When you have checked that the issue hasn't been reported before **fill out [the required template](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)** which will help us resolve the issue faster.
-
-##### Submitting a Bug Report
-Bugs that are submitted are tracked as [GitHub issues](https://guides.github.com/features/issues/). To report a bug, create an issue and use [the template](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/bug_report.md) to provide information about the bug. Explain the problem thoroughly and include any additional information that you think might help the maintainers reproduce the issue. When creating the GitHub issue please make sure that you:
-
-* **Use a clear and descriptive title** for the issue.
-* **Describe the exact steps which reproduce the problem** with as many details as possible. It's generally better to provide too much than too little information.
-* **Describe the behavior you observed after following the steps** and explain exactly what the problem is with that behavior.
-* **Explain which behavior you expected instead** and why.
-* **Provide screenshots and/or screen recordings** that might help explain the issue you are facing. To screen record a phone connected to Android Studio or an emulator follow the steps [here](https://developer.android.com/studio/debug/am-video). To screen record on iOS follow the steps described [here](https://support.apple.com/en-us/HT207935).
-* **Include relevant logs in the bug report** by putting it in a [code block](https://help.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github#multiple-lines), a [file attachment](https://help.github.com/en/github/managing-your-work-on-github/file-attachments-on-issues-and-pull-requests) or in a [gist](https://help.github.com/en/github/writing-on-github/creating-gists) and provide a link to that gist.
-* **Tell how recently you started having the issue.** When was the first time you experienced the issue and was it after updating the SDK version? Or has it always been a problem?
-* If the problem started happening recently, **can you reproduce it in an older version of the SDK?** What's the most recent version in which the problem doesn't happen?
-* **Can you reliably reproduce the issue?** If not, explain how often it occurs and under what conditions it normally happens. For example in what environment you are running.
-
-Include details about the device/emulator/simulator you are experiencing the issue on:
-
-* **Which version of the SDK are you using?**
-* **Which OS is this a problem in, iOS, Android or both?** What version(s)? Also add the appropriate label to the issue.
-* **Did you experience the issue in simulator/emulator or on real device(s)?**
-
-#### Contributing with Code
-Before contributing please read through the [Klarna In-App SDK documentation](https://developers.klarna.com/documentation/in-app/).
-
-##### Branching
-Prefix the branch you are going to work on depending on what you are working on (bug fix or feature). Use the following prefixes when creating a new branch:
-
-* **feature/** if the branch contains a new feature, example: `feature/my-shiny-feature`.
-* **bugfix/** if the branch contains a bug fix, example: `bugfix/my-bug-fix`.
-
-##### Pull Requests
-When creating a PR include as much information as possible about the type of enhancement, whether if it's a bugfix, new functionality or any other change. There's [a template](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/pull-request.md) for you to fill out which will make the review process for the maintainers faster. When creating a PR do it against the `master` branch. The PR should include:
-
-* **A clear and descriptive title**.
-* **Description of the issue** if you are fixing a bug together with a link to the relevant issue or **background for introducing a new feature**.
+## Contribution
+If you want to contribute to this project please follow our [contribution guide](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/CONTRIBUTING.md).
## License
-Copyright 2019 Klarna Bank AB
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+This project is licensed under
+[Apache License, Version 2.0](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/LICENSE).
+
+
+[npm-badge]: https://img.shields.io/npm/v/react-native-klarna-inapp-sdk?style=flat-square
+[npm-url]: https://www.npmjs.com/package/react-native-klarna-inapp-sdk
+[dependency-badge]: https://img.shields.io/npm/dependency-version/react-native-klarna-inapp-sdk/peer/react-native?style=flat-square
+[dependency-url]: https://www.npmjs.com/package/react-native-klarna-inapp-sdk?activeTab=dependencies
+[platforms-badge]: https://img.shields.io/badge/platform-react%20native-lightgrey?style=flat-square
+[platforms-url]: https://reactnative.dev
+[license-badge]: https://img.shields.io/github/license/klarna/react-native-klarna-inapp-sdk?style=flat-square
+[license-url]: https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/LICENSE
+[klarna-badge]: https://img.shields.io/badge/%20-Developed%20at%20Klarna-black?labelColor=ffb3c7&style=flat-square&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAALQAAAAAQAAAtAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABCgAwAEAAAAAQAAAA4AAAAA0LMKiwAAAAlwSFlzAABuugAAbroB1t6xFwAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAAAVBJREFUKBVtkz0vREEUhsdXgo5qJXohkUgQ0fgFNFpR2V5ClP6CQu9PiB6lEL1I7B9A4/treZ47c252s97k2ffMmZkz5869m1JKL/AFbzAHaiRbmsIf4BdaMAZqMFsOXNxXkroKbxCPV5l8yHOJLVipn9/vEreLa7FguSN3S2ynA/ATeQuI8tTY6OOY34DQaQnq9mPCDtxoBwuRxPfAvPMWnARlB12KAi6eLTPruOOP4gcl33O6+Sjgc83DJkRH+h2MgorLzaPy68W48BG2S+xYnmAa1L+nOxEduMH3fgjGFvZeVkANZau68B6CrgJxWosFFpF7iG+h5wKZqwt42qIJtARu/ix+gqsosEq8D35o6R3c7OL4lAnTDljEe9B3Qa2BYzmHemDCt6Diwo6JY7E+A82OnN9HuoBruAQvUQ1nSxP4GVzBDRyBfygf6RW2/gD3NmEv+K/DZgAAAABJRU5ErkJggg==
+[klarna-url]: https://github.com/klarna
diff --git a/SUPPORT.md b/SUPPORT.md
new file mode 100644
index 00000000..f179ab4e
--- /dev/null
+++ b/SUPPORT.md
@@ -0,0 +1,8 @@
+# Support
+
+If you are having any issues using the SDK in your project or if you think that something is wrong with the SDK itself, please create an issue on [Github](https://github.com/klarna/react-native-klarna-inapp-sdk/issues) or report a bug by following the guidelines in the next section.
+
+## Reporting Bugs
+This section will guide you through submitting a bug report for Klarna Mobile SDK.
+
+Before submitting a bug report, please check that the issue hasn't been reported before. If you find a *Closed* issue that seems to describe an issue that is similar to what you want to report, open a new issue and link to the original issue in the new one. When you have checked that the issue hasn't been reported before, please **fill out [the required template](https://github.com/klarna/react-native-klarna-inapp-sdk/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)** which will help us resolve the issue faster.
diff --git a/TestApp/.eslintrc.js b/TestApp/.eslintrc.js
index 0ef09a42..5691b84c 100644
--- a/TestApp/.eslintrc.js
+++ b/TestApp/.eslintrc.js
@@ -1,4 +1,22 @@
module.exports = {
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ project: 'tsconfig.json',
+ tsconfigRootDir: __dirname,
+ sourceType: 'module',
+ },
+ plugins: [
+ '@typescript-eslint/eslint-plugin'
+ ],
root: true,
- extends: "@react-native",
+ env: {
+ jest: true,
+ },
+ ignorePatterns: [
+ '.eslintrc.js'
+ ],
+ extends: [
+ '@react-native',
+ 'prettier',
+ ],
};
diff --git a/TestApp/.gitignore b/TestApp/.gitignore
index 8f8e6b44..0cab2ac6 100644
--- a/TestApp/.gitignore
+++ b/TestApp/.gitignore
@@ -58,7 +58,9 @@ yarn-error.log
# Ruby / CocoaPods
/ios/Pods/
/vendor/bundle/
+
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
+
# testing
/coverage
diff --git a/TestApp/App.tsx b/TestApp/App.tsx
index 89b8fcfa..0ccf24cf 100644
--- a/TestApp/App.tsx
+++ b/TestApp/App.tsx
@@ -11,22 +11,22 @@ import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './src/home/HomeScreen';
import PaymentsScreen from './src/payments/PaymentsScreen';
-function App(): JSX.Element {
- const AppStack = () => {
- const Stack = createNativeStackNavigator();
+const Stack = createNativeStackNavigator();
- return (
-
-
-
-
- );
- };
+const AppStack = () => {
+ return (
+
+
+
+
+ );
+};
+export default function App(): JSX.Element {
return (
@@ -34,4 +34,9 @@ function App(): JSX.Element {
);
}
-export default App;
+type AppStackParamList = {
+ Home: undefined;
+ Payments: undefined;
+};
+
+export type {AppStackParamList};
diff --git a/TestApp/Gemfile b/TestApp/Gemfile
index a543c630..da00b45b 100644
--- a/TestApp/Gemfile
+++ b/TestApp/Gemfile
@@ -1,4 +1,6 @@
source 'https://rubygems.org'
+
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
-ruby ">= 2.6.10"
+ruby '>= 2.7.5'
+
gem 'cocoapods', '~> 1.12'
diff --git a/TestApp/Gemfile.lock b/TestApp/Gemfile.lock
index 5ab2c74c..f77e7818 100644
--- a/TestApp/Gemfile.lock
+++ b/TestApp/Gemfile.lock
@@ -3,7 +3,7 @@ GEM
specs:
CFPropertyList (3.0.6)
rexml
- activesupport (7.0.7.2)
+ activesupport (7.0.8)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -92,7 +92,7 @@ DEPENDENCIES
cocoapods (~> 1.12)
RUBY VERSION
- ruby 2.7.5p203
+ ruby 3.0.0p0
BUNDLED WITH
- 2.1.4
+ 2.2.3
diff --git a/TestApp/android/app/build.gradle b/TestApp/android/app/build.gradle
index 8b910556..d27edff6 100644
--- a/TestApp/android/app/build.gradle
+++ b/TestApp/android/app/build.gradle
@@ -70,13 +70,6 @@ android {
compileSdkVersion rootProject.ext.compileSdkVersion
- // removed in react native 0.65.0
- // https://react-native-community.github.io/upgrade-helper/?from=0.64.4&to=0.65.0#RnDiffApp-android-app-build.gradle
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-
namespace "com.klarna.mobile.sdk.reactnative.testapp"
defaultConfig {
applicationId "com.klarna.mobile.sdk.reactnative.testapp"
diff --git a/TestApp/android/app/src/main/java/com/klarna/mobile/sdk/reactnative/testapp/MainActivity.java b/TestApp/android/app/src/main/java/com/klarna/mobile/sdk/reactnative/testapp/MainActivity.java
index d3773ac1..545101fb 100644
--- a/TestApp/android/app/src/main/java/com/klarna/mobile/sdk/reactnative/testapp/MainActivity.java
+++ b/TestApp/android/app/src/main/java/com/klarna/mobile/sdk/reactnative/testapp/MainActivity.java
@@ -1,5 +1,6 @@
package com.klarna.mobile.sdk.reactnative.testapp;
+import android.os.Bundle;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
@@ -29,4 +30,12 @@ protected ReactActivityDelegate createReactActivityDelegate() {
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
DefaultNewArchitectureEntryPoint.getFabricEnabled());
}
+
+ /**
+ * Added for navigation https://reactnavigation.org/docs/getting-started/
+ */
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(null);
+ }
}
diff --git a/TestApp/android/build.gradle b/TestApp/android/build.gradle
index f9bbd286..33e32be8 100644
--- a/TestApp/android/build.gradle
+++ b/TestApp/android/build.gradle
@@ -8,6 +8,7 @@ buildscript {
targetSdkVersion = 33
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
+ kotlin_version = "1.7.0"
}
repositories {
google()
@@ -16,6 +17,7 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
diff --git a/TestApp/index.js b/TestApp/index.js
index a850d031..7cd584ca 100644
--- a/TestApp/index.js
+++ b/TestApp/index.js
@@ -1,7 +1,3 @@
-/**
- * @format
- */
-
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
diff --git a/TestApp/ios/Podfile b/TestApp/ios/Podfile
index 65fda1b7..65fe3849 100644
--- a/TestApp/ios/Podfile
+++ b/TestApp/ios/Podfile
@@ -26,8 +26,6 @@ if linkage != nil
end
target 'TestApp' do
- pod 'react-native-klarna-inapp-sdk', :path => '../../react-native-klarna-inapp-sdk.podspec'
-
config = use_native_modules!
# Flags change depending on the env values.
diff --git a/TestApp/ios/Podfile.lock b/TestApp/ios/Podfile.lock
index a00fc0f5..d6aa0e3a 100644
--- a/TestApp/ios/Podfile.lock
+++ b/TestApp/ios/Podfile.lock
@@ -378,9 +378,10 @@ PODS:
- React-jsinspector (0.72.4)
- React-logger (0.72.4):
- glog
- - react-native-klarna-inapp-sdk (2.1.12):
+ - react-native-klarna-inapp-sdk (2.1.13):
- KlarnaMobileSDK (= 2.6.10)
- - React
+ - RCT-Folly (= 2021.07.22.00)
+ - React-Core
- react-native-safe-area-context (4.7.2):
- React-Core
- React-NativeModulesApple (0.72.4):
@@ -547,7 +548,7 @@ DEPENDENCIES:
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- - react-native-klarna-inapp-sdk (from `../../react-native-klarna-inapp-sdk.podspec`)
+ - react-native-klarna-inapp-sdk (from `../..`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
@@ -632,7 +633,7 @@ EXTERNAL SOURCES:
React-logger:
:path: "../node_modules/react-native/ReactCommon/logger"
react-native-klarna-inapp-sdk:
- :path: "../../react-native-klarna-inapp-sdk.podspec"
+ :path: "../.."
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
React-NativeModulesApple:
@@ -709,7 +710,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: c7f826e40fa9cab5d37cab6130b1af237332b594
React-jsinspector: aaed4cf551c4a1c98092436518c2d267b13a673f
React-logger: da1ebe05ae06eb6db4b162202faeafac4b435e77
- react-native-klarna-inapp-sdk: 31c6804f74abf0ee7f10fc91147d042f92c8c937
+ react-native-klarna-inapp-sdk: 6f46082682784d325c34c853fe9c42a111c1e31e
react-native-safe-area-context: 7aa8e6d9d0f3100a820efb1a98af68aa747f9284
React-NativeModulesApple: edb5ace14f73f4969df6e7b1f3e41bef0012740f
React-perflogger: 496a1a3dc6737f964107cb3ddae7f9e265ddda58
@@ -733,6 +734,6 @@ SPEC CHECKSUMS:
Yoga: 3efc43e0d48686ce2e8c60f99d4e6bd349aff981
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
-PODFILE CHECKSUM: f99c39854869734a256aad561f5632de91351425
+PODFILE CHECKSUM: 5f146ddb62f4ae63c85ec80898f0a94176f8ed53
COCOAPODS: 1.12.1
diff --git a/TestApp/ios/TestApp.xcodeproj/project.pbxproj b/TestApp/ios/TestApp.xcodeproj/project.pbxproj
index dfd0b003..cbe844b3 100644
--- a/TestApp/ios/TestApp.xcodeproj/project.pbxproj
+++ b/TestApp/ios/TestApp.xcodeproj/project.pbxproj
@@ -611,12 +611,16 @@
);
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
- OTHER_CFLAGS = "$(inherited)";
+ OTHER_CFLAGS = (
+ "$(inherited)",
+ " ",
+ );
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-DFOLLY_NO_CONFIG",
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
+ " ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
@@ -676,12 +680,16 @@
"\"$(inherited)\"",
);
MTL_ENABLE_DEBUG_INFO = NO;
- OTHER_CFLAGS = "$(inherited)";
+ OTHER_CFLAGS = (
+ "$(inherited)",
+ " ",
+ );
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-DFOLLY_NO_CONFIG",
"-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1",
+ " ",
);
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
diff --git a/TestApp/package.json b/TestApp/package.json
index 6fbcd406..f3f5f096 100644
--- a/TestApp/package.json
+++ b/TestApp/package.json
@@ -8,12 +8,11 @@
"start": "react-native start",
"test": "jest",
"lint": "eslint .",
+ "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"",
"bundle:android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res",
"bundle:android-dev": "react-native bundle --platform android --dev true --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res",
"bundle:ios": "react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/main.jsbundle",
"bundle:ios-dev": "react-native bundle --platform ios --dev true --entry-file index.js --bundle-output ios/main.jsbundle",
- "clean:auto": "react-native clean-project-auto",
- "clean": "react-native clean-project",
"pods": "pod-install --quiet"
},
"dependencies": {
@@ -33,15 +32,19 @@
"@tsconfig/react-native": "^3.0.0",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
+ "@typescript-eslint/eslint-plugin": "^6.6.0",
+ "@typescript-eslint/parser": "^6.6.0",
"babel-jest": "^29.2.1",
- "eslint": "^8.19.0",
- "jest": "^29.2.1",
- "metro-react-native-babel-preset": "0.76.8",
"babel-plugin-module-resolver": "^5.0.0",
- "prettier": "^2.4.1",
- "react-test-renderer": "18.2.0",
- "typescript": "4.8.4",
- "react-native-clean-project": "^4.0.1"
+ "eslint": "^8.48.0",
+ "eslint-config-prettier": "^9.0.0",
+ "eslint-plugin-jest": "^27.2.3",
+ "eslint-plugin-prettier": "^5.0.0",
+ "jest": "^29.2.1",
+ "metro-react-native-babel-preset": "^0.77.0",
+ "prettier": "^3.0.3",
+ "react-test-renderer": "^18.2.0",
+ "typescript": "5.2.2"
},
"engines": {
"node": ">=16"
diff --git a/TestApp/src/Styles.js b/TestApp/src/common/ui/Styles.tsx
similarity index 66%
rename from TestApp/src/Styles.js
rename to TestApp/src/common/ui/Styles.tsx
index 42a606a1..424c4dff 100644
--- a/TestApp/src/Styles.js
+++ b/TestApp/src/common/ui/Styles.tsx
@@ -1,10 +1,14 @@
import {StyleSheet} from 'react-native';
-export const backgroundStyle = isDarkMode => {
+export function backgroundStyle(style: any, isDarkMode: boolean) {
+ return [style, background(isDarkMode)];
+}
+
+export function background(isDarkMode: boolean) {
return {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
-};
+}
export const Colors = {
white: '#FFF',
@@ -13,30 +17,37 @@ export const Colors = {
dark: '#444',
darker: '#222',
black: '#000',
-}
+ pink: '#ffc0cb',
+};
const styles = StyleSheet.create({
- outer: {
- flex: 1,
- flexGrow: 1,
- },
scrollView: {
flex: 1,
flexGrow: 1,
},
- scrollViewContentContainer: {
- justifyContent: 'space-between',
+ tokenInput: {
+ flexDirection: 'column',
+ justifyContent: 'space-around',
+ alignItems: 'center',
+ borderColor: 'gray',
+ height: 40,
+ borderWidth: 1,
+ padding: 10,
+ margin: 20,
},
container: {
justifyContent: 'center',
alignItems: 'center',
- backgroundColor: Colors.light,
width: '100%',
},
- header: {
- fontSize: 20,
- textAlign: 'center',
- margin: 10,
+ paymentContainer: {
+ flex: 1,
+ flexDirection: 'column',
+ flexWrap: 'wrap',
+ alignItems: 'center',
+ backgroundColor: Colors.pink,
+ padding: 10,
+ width: '100%',
},
paymentView: {
width: '100%',
@@ -54,35 +65,18 @@ const styles = StyleSheet.create({
alignItems: 'center',
margin: 10,
},
- tokenInput: {
- flexDirection: 'column',
- justifyContent: 'space-around',
- alignItems: 'center',
- borderColor: 'gray',
- height: 40,
- borderWidth: 1,
- padding: 10,
- margin: 20,
- },
button: {
- height: 10,
- margin: 10,
- },
- sectionContainer: {
- marginTop: 32,
- paddingHorizontal: 24,
- },
- sectionTitle: {
- fontSize: 24,
- fontWeight: '600',
- },
- sectionDescription: {
- marginTop: 8,
- fontSize: 18,
- fontWeight: '400',
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingVertical: 7,
+ paddingHorizontal: 10,
+ borderRadius: 4,
+ elevation: 3,
+ backgroundColor: Colors.pink,
},
- highlight: {
- fontWeight: '700',
+ buttonText: {
+ textAlign: 'center',
+ color: Colors.white,
},
navMenuItem: {
fontSize: 20,
diff --git a/TestApp/src/common/ui/view/Button.tsx b/TestApp/src/common/ui/view/Button.tsx
new file mode 100644
index 00000000..150eb712
--- /dev/null
+++ b/TestApp/src/common/ui/view/Button.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import {Text, Pressable} from 'react-native';
+import styles from '../Styles';
+
+type ButtonProps = {
+ onPress: () => void;
+ title: string;
+};
+
+export default function Button(props: ButtonProps) {
+ return (
+
+ {props.title}
+
+ );
+}
diff --git a/TestApp/src/TestProps.js b/TestApp/src/common/util/TestProps.tsx
similarity index 71%
rename from TestApp/src/TestProps.js
rename to TestApp/src/common/util/TestProps.tsx
index 4aaf02f3..1eb13ced 100644
--- a/TestApp/src/TestProps.js
+++ b/TestApp/src/common/util/TestProps.tsx
@@ -1,9 +1,7 @@
import {Platform} from 'react-native';
-const testProps = id => {
+export default function testProps(id: string) {
return Platform.OS === 'android'
? {testID: id, accessibilityLabel: id}
: {testID: id};
-};
-
-export default testProps;
+}
diff --git a/TestApp/src/home/HomeScreen.js b/TestApp/src/home/HomeScreen.js
deleted file mode 100644
index 84f6f6c6..00000000
--- a/TestApp/src/home/HomeScreen.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import {ScrollView, Text, useColorScheme, View} from 'react-native';
-import styles, {backgroundStyle, Colors} from '../Styles';
-import testProps from '../TestProps';
-
-const HomeScreen = ({navigation}) => {
- const isDarkMode = useColorScheme() === 'dark';
-
- return (
-
-
- navigation.navigate('Payments')}>
- Klarna Payments
-
-
-
- );
-};
-
-export default HomeScreen;
diff --git a/TestApp/src/home/HomeScreen.tsx b/TestApp/src/home/HomeScreen.tsx
new file mode 100644
index 00000000..d448dca2
--- /dev/null
+++ b/TestApp/src/home/HomeScreen.tsx
@@ -0,0 +1,35 @@
+import React from 'react';
+import {ScrollView, Text, useColorScheme, View} from 'react-native';
+import type {NativeStackNavigationProp} from '@react-navigation/native-stack';
+import styles, {backgroundStyle, Colors} from '../common/ui/Styles';
+import testProps from '../common/util/TestProps';
+import type {AppStackParamList} from '../../App';
+import {useNavigation} from '@react-navigation/native';
+
+type HomeNavigationProp = NativeStackNavigationProp;
+
+export default function HomeScreen() {
+ const navigation = useNavigation();
+ const isDarkMode = useColorScheme() === 'dark';
+
+ return (
+
+
+ {
+ console.log('Navigating to Payments');
+ navigation.navigate('Payments');
+ }}>
+ Klarna Payments
+
+
+
+ );
+}
diff --git a/TestApp/src/payments/PaymentsContainer.js b/TestApp/src/payments/PaymentsContainer.js
deleted file mode 100644
index 6731ec30..00000000
--- a/TestApp/src/payments/PaymentsContainer.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import React, {useRef, useState} from 'react';
-import {Button, NativeModules, Platform, Text, View} from 'react-native';
-import KlarnaPaymentView from 'react-native-klarna-inapp-sdk';
-import styles from '../Styles';
-import testProps from '../TestProps';
-
-interface PaymentsProps {
- clientToken: string;
- paymentMethodName: string;
-}
-
-const PaymentsContainer = (props: PaymentsProps) => {
- const paymentViewRef = useRef();
- const [eventState, setEventState] = useState();
-
- const onEvent = event => {
- const eventString = JSON.stringify(event.nativeEvent);
- setEventState(eventString);
- window.console.warn(eventString);
- };
-
- const actionButtons = () => {
- return (
-
-
- );
- };
-
- const renderPaymentMethod = () => {
- return (
-
- {props.paymentMethodName}
- {
- onEvent(event);
- }}
- onLoaded={event => {
- onEvent(event);
- }}
- onAuthorized={event => {
- onEvent(event);
- }}
- onReauthorized={event => {
- onEvent(event);
- }}
- onFinalized={event => {
- onEvent(event);
- }}
- onError={event => {
- onEvent(event);
- }}
- />
- {actionButtons()}
-
- {eventState}
-
-
- );
- };
-
- return renderPaymentMethod();
-};
-
-export default PaymentsContainer;
diff --git a/TestApp/src/payments/PaymentsContainer.tsx b/TestApp/src/payments/PaymentsContainer.tsx
new file mode 100644
index 00000000..3ddd73b0
--- /dev/null
+++ b/TestApp/src/payments/PaymentsContainer.tsx
@@ -0,0 +1,120 @@
+import React, {useRef, useState} from 'react';
+import {NativeModules, Platform, Text, View} from 'react-native';
+import {
+ KlarnaPaymentsSDKError,
+ KlarnaPaymentView,
+} from 'react-native-klarna-inapp-sdk';
+import styles from '../common/ui/Styles';
+import testProps from '../common/util/TestProps';
+import Button from '../common/ui/view/Button';
+
+interface PaymentsContainerProps {
+ clientToken: string;
+ paymentMethodName: string;
+}
+
+export default function PaymentsContainer(props: PaymentsContainerProps) {
+ const paymentViewRef = useRef(null);
+ const [eventState, setEventState] = useState();
+
+ const onEvent = (...params: Array) => {
+ console.log('onEvent', params);
+ setEventState(params.join(', '));
+ };
+
+ const actionButtons = () => {
+ return (
+
+ {
+ paymentViewRef.current?.initialize(props.clientToken);
+
+ //You can skip this line, it's for integration testing purposes by Klarna.
+ if (
+ Platform.OS === 'android' &&
+ NativeModules.DebugWebViewModule !== undefined &&
+ NativeModules.DebugWebViewModule !== null
+ ) {
+ NativeModules.DebugWebViewModule.enable();
+ }
+ }}
+ title="Init."
+ {...testProps('initButton_' + props.paymentMethodName)}
+ />
+ {
+ paymentViewRef.current?.load();
+ }}
+ title="Load"
+ {...testProps('loadButton_' + props.paymentMethodName)}
+ />
+ {
+ paymentViewRef.current?.authorize();
+ }}
+ title="Authorize"
+ {...testProps('authorizeButton_' + props.paymentMethodName)}
+ />
+ {
+ paymentViewRef.current?.reauthorize();
+ }}
+ title="Reauthorize"
+ {...testProps('reauthorizeButton_' + props.paymentMethodName)}
+ />
+ {
+ paymentViewRef.current?.finalize();
+ }}
+ title="Finalize"
+ {...testProps('finalizeButton_' + props.paymentMethodName)}
+ />
+
+ );
+ };
+
+ const renderPaymentMethod = () => {
+ return (
+
+ {props.paymentMethodName}
+
+ {
+ onEvent('onInitialized');
+ }}
+ onLoaded={() => {
+ onEvent('onLoaded');
+ }}
+ onLoadedPaymentReview={() => {
+ onEvent('onLoadedPaymentReview');
+ }}
+ onAuthorized={(approved, authToken, finalizeRequired) => {
+ onEvent('onAuthorized', approved, authToken, finalizeRequired);
+ }}
+ onReauthorized={(approved, authToken) => {
+ onEvent('onReauthorized', approved, authToken);
+ }}
+ onFinalized={(approved, authToken) => {
+ onEvent('onFinalized', approved, authToken);
+ }}
+ onError={(error: KlarnaPaymentsSDKError) => {
+ onEvent('onError', JSON.stringify(error));
+ }}
+ />
+
+ {actionButtons()}
+
+ {eventState}
+
+
+ );
+ };
+
+ return renderPaymentMethod();
+}
diff --git a/TestApp/src/payments/PaymentsScreen.js b/TestApp/src/payments/PaymentsScreen.tsx
similarity index 81%
rename from TestApp/src/payments/PaymentsScreen.js
rename to TestApp/src/payments/PaymentsScreen.tsx
index b77d1301..2cbaf93a 100644
--- a/TestApp/src/payments/PaymentsScreen.js
+++ b/TestApp/src/payments/PaymentsScreen.tsx
@@ -1,21 +1,25 @@
import React, {useState} from 'react';
import {ScrollView, TextInput, useColorScheme, View} from 'react-native';
-import styles, {backgroundStyle, Colors} from '../Styles';
-import testProps from '../TestProps';
+import styles, {backgroundStyle, Colors} from '../common/ui/Styles';
+import testProps from '../common/util/TestProps';
import PaymentsContainer from './PaymentsContainer';
let authToken = ''; // set your token here
-const PaymentsScreen = ({navigation}) => {
+export default function PaymentsScreen() {
const isDarkMode = useColorScheme() === 'dark';
const [clientToken, setClientToken] = useState(authToken);
const paymentMethods = [
+ 'klarna',
'pay_now',
'pay_later',
'pay_over_time',
'pay_in_parts',
+ 'direct_debit',
+ 'direct_bank_transfer',
+ 'card',
];
const renderSetTokenInput = () => {
@@ -37,7 +41,7 @@ const PaymentsScreen = ({navigation}) => {
return (
+ style={backgroundStyle(styles.scrollView, isDarkMode)}>
{
);
-};
-
-export default PaymentsScreen;
+}
diff --git a/TestApp/tsconfig.json b/TestApp/tsconfig.json
index 45a6c707..f88ce8f2 100644
--- a/TestApp/tsconfig.json
+++ b/TestApp/tsconfig.json
@@ -1,3 +1,10 @@
{
- "extends": "@tsconfig/react-native/tsconfig.json"
+ "extends": "@tsconfig/react-native/tsconfig.json",
+ "compilerOptions": {
+ "paths": {
+ "react-native-klarna-inapp-sdk": [
+ "../src/index"
+ ]
+ }
+ }
}
diff --git a/TestApp/yarn.lock b/TestApp/yarn.lock
index 1d89d2d4..5d70a881 100644
--- a/TestApp/yarn.lock
+++ b/TestApp/yarn.lock
@@ -29,20 +29,20 @@
integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==
"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.0":
- version "7.22.15"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.15.tgz#15d4fd03f478a459015a4b94cfbb3bd42c48d2f4"
- integrity sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==
+ version "7.22.17"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.17.tgz#2f9b0b395985967203514b24ee50f9fd0639c866"
+ integrity sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==
dependencies:
"@ampproject/remapping" "^2.2.0"
"@babel/code-frame" "^7.22.13"
"@babel/generator" "^7.22.15"
"@babel/helper-compilation-targets" "^7.22.15"
- "@babel/helper-module-transforms" "^7.22.15"
+ "@babel/helper-module-transforms" "^7.22.17"
"@babel/helpers" "^7.22.15"
- "@babel/parser" "^7.22.15"
+ "@babel/parser" "^7.22.16"
"@babel/template" "^7.22.15"
- "@babel/traverse" "^7.22.15"
- "@babel/types" "^7.22.15"
+ "@babel/traverse" "^7.22.17"
+ "@babel/types" "^7.22.17"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
@@ -162,10 +162,10 @@
dependencies:
"@babel/types" "^7.22.15"
-"@babel/helper-module-transforms@^7.22.15", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9":
- version "7.22.15"
- resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz#40ad2f6950f143900e9c1c72363c0b431a606082"
- integrity sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==
+"@babel/helper-module-transforms@^7.22.15", "@babel/helper-module-transforms@^7.22.17", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9":
+ version "7.22.17"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz#7edf129097a51ccc12443adbc6320e90eab76693"
+ integrity sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==
dependencies:
"@babel/helper-environment-visitor" "^7.22.5"
"@babel/helper-module-imports" "^7.22.15"
@@ -186,13 +186,13 @@
integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==
"@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.22.5", "@babel/helper-remap-async-to-generator@^7.22.9":
- version "7.22.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82"
- integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==
+ version "7.22.17"
+ resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.17.tgz#dabaa50622b3b4670bd6546fc8db23eb12d89da0"
+ integrity sha512-bxH77R5gjH3Nkde6/LuncQoLaP16THYPscurp1S8z7S9ZgezCyV3G8Hc+TZiCmY8pz4fp8CvKSgtJMW0FkLAxA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.22.5"
"@babel/helper-environment-visitor" "^7.22.5"
- "@babel/helper-wrap-function" "^7.22.9"
+ "@babel/helper-wrap-function" "^7.22.17"
"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9":
version "7.22.9"
@@ -239,14 +239,14 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040"
integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==
-"@babel/helper-wrap-function@^7.22.9":
- version "7.22.10"
- resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz#d845e043880ed0b8c18bd194a12005cb16d2f614"
- integrity sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==
+"@babel/helper-wrap-function@^7.22.17":
+ version "7.22.17"
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.17.tgz#222ac3ff9cc8f9b617cc1e5db75c0b538e722801"
+ integrity sha512-nAhoheCMlrqU41tAojw9GpVEKDlTS8r3lzFmF0lP52LwblCPbuFSO7nGIZoIcoU5NIm1ABrna0cJExE4Ay6l2Q==
dependencies:
"@babel/helper-function-name" "^7.22.5"
- "@babel/template" "^7.22.5"
- "@babel/types" "^7.22.10"
+ "@babel/template" "^7.22.15"
+ "@babel/types" "^7.22.17"
"@babel/helpers@^7.22.15":
version "7.22.15"
@@ -266,7 +266,7 @@
chalk "^2.4.2"
js-tokens "^4.0.0"
-"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15":
+"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.22.16":
version "7.22.16"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.16.tgz#180aead7f247305cce6551bea2720934e2fa2c95"
integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==
@@ -306,9 +306,9 @@
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-proposal-export-default-from@^7.0.0":
- version "7.22.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.22.5.tgz#825924eda1fad382c3de4db6fe1711b6fa03362f"
- integrity sha512-UCe1X/hplyv6A5g2WnQ90tnHRvYL29dabCWww92lO7VdfMVTVReBTRrhiMrKQejHD9oVkdnRdwYuzUZkBVQisg==
+ version "7.22.17"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.22.17.tgz#91b60cd338f501cccdf549af2308768911ec5fbb"
+ integrity sha512-cop/3quQBVvdz6X5SJC6AhUv3C9DrVTM06LUEXimEdWAhCSyOJIr9NiZDU9leHZ0/aiG0Sh7Zmvaku5TWYNgbA==
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
"@babel/plugin-syntax-export-default-from" "^7.22.5"
@@ -1121,10 +1121,10 @@
"@babel/parser" "^7.22.15"
"@babel/types" "^7.22.15"
-"@babel/traverse@^7.20.0", "@babel/traverse@^7.22.15":
- version "7.22.15"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.15.tgz#75be4d2d6e216e880e93017f4e2389aeb77ef2d9"
- integrity sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==
+"@babel/traverse@^7.20.0", "@babel/traverse@^7.22.15", "@babel/traverse@^7.22.17":
+ version "7.22.17"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.17.tgz#b23c203ab3707e3be816043081b4a994fcacec44"
+ integrity sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==
dependencies:
"@babel/code-frame" "^7.22.13"
"@babel/generator" "^7.22.15"
@@ -1132,15 +1132,15 @@
"@babel/helper-function-name" "^7.22.5"
"@babel/helper-hoist-variables" "^7.22.5"
"@babel/helper-split-export-declaration" "^7.22.6"
- "@babel/parser" "^7.22.15"
- "@babel/types" "^7.22.15"
+ "@babel/parser" "^7.22.16"
+ "@babel/types" "^7.22.17"
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
- version "7.22.15"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.15.tgz#266cb21d2c5fd0b3931e7a91b6dd72d2f617d282"
- integrity sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==
+"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.17", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
+ version "7.22.17"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.17.tgz#f753352c4610ffddf9c8bc6823f9ff03e2303eee"
+ integrity sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==
dependencies:
"@babel/helper-string-parser" "^7.22.5"
"@babel/helper-validator-identifier" "^7.22.15"
@@ -1151,14 +1151,14 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
-"@eslint-community/eslint-utils@^4.2.0":
+"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
version "4.4.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
dependencies:
eslint-visitor-keys "^3.3.0"
-"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1":
+"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1":
version "4.8.0"
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.0.tgz#11195513186f68d42fbf449f9a7136b2c0c92005"
integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==
@@ -1519,6 +1519,18 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
+"@pkgr/utils@^2.3.1":
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc"
+ integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==
+ dependencies:
+ cross-spawn "^7.0.3"
+ fast-glob "^3.3.0"
+ is-glob "^4.0.3"
+ open "^9.1.0"
+ picocolors "^1.0.0"
+ tslib "^2.6.0"
+
"@react-native-community/cli-clean@11.3.6":
version "11.3.6"
resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-11.3.6.tgz#43a06cbee1a5480da804debc4f94662a197720f2"
@@ -1902,7 +1914,7 @@
dependencies:
"@types/istanbul-lib-report" "*"
-"@types/json-schema@^7.0.9":
+"@types/json-schema@^7.0.12", "@types/json-schema@^7.0.9":
version "7.0.12"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb"
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
@@ -1938,7 +1950,7 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5"
integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==
-"@types/semver@^7.3.12":
+"@types/semver@^7.3.12", "@types/semver@^7.5.0":
version "7.5.1"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.1.tgz#0480eeb7221eb9bc398ad7432c9d7e14b1a5a367"
integrity sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==
@@ -1990,6 +2002,23 @@
semver "^7.3.7"
tsutils "^3.21.0"
+"@typescript-eslint/eslint-plugin@^6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.6.0.tgz#19ba09aa34fd504696445100262e5a9e1b1d7024"
+ integrity sha512-CW9YDGTQnNYMIo5lMeuiIG08p4E0cXrXTbcZ2saT/ETE7dWUrNxlijsQeU04qAAKkILiLzdQz+cGFxCJjaZUmA==
+ dependencies:
+ "@eslint-community/regexpp" "^4.5.1"
+ "@typescript-eslint/scope-manager" "6.6.0"
+ "@typescript-eslint/type-utils" "6.6.0"
+ "@typescript-eslint/utils" "6.6.0"
+ "@typescript-eslint/visitor-keys" "6.6.0"
+ debug "^4.3.4"
+ graphemer "^1.4.0"
+ ignore "^5.2.4"
+ natural-compare "^1.4.0"
+ semver "^7.5.4"
+ ts-api-utils "^1.0.1"
+
"@typescript-eslint/parser@^5.30.5":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7"
@@ -2000,6 +2029,17 @@
"@typescript-eslint/typescript-estree" "5.62.0"
debug "^4.3.4"
+"@typescript-eslint/parser@^6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.6.0.tgz#fe323a7b4eafb6d5ea82b96216561810394a739e"
+ integrity sha512-setq5aJgUwtzGrhW177/i+DMLqBaJbdwGj2CPIVFFLE0NCliy5ujIdLHd2D1ysmlmsjdL2GWW+hR85neEfc12w==
+ dependencies:
+ "@typescript-eslint/scope-manager" "6.6.0"
+ "@typescript-eslint/types" "6.6.0"
+ "@typescript-eslint/typescript-estree" "6.6.0"
+ "@typescript-eslint/visitor-keys" "6.6.0"
+ debug "^4.3.4"
+
"@typescript-eslint/scope-manager@5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c"
@@ -2008,6 +2048,14 @@
"@typescript-eslint/types" "5.62.0"
"@typescript-eslint/visitor-keys" "5.62.0"
+"@typescript-eslint/scope-manager@6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.6.0.tgz#57105d4419d6de971f7d2c30a2ff4ac40003f61a"
+ integrity sha512-pT08u5W/GT4KjPUmEtc2kSYvrH8x89cVzkA0Sy2aaOUIw6YxOIjA8ilwLr/1fLjOedX1QAuBpG9XggWqIIfERw==
+ dependencies:
+ "@typescript-eslint/types" "6.6.0"
+ "@typescript-eslint/visitor-keys" "6.6.0"
+
"@typescript-eslint/type-utils@5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a"
@@ -2018,11 +2066,26 @@
debug "^4.3.4"
tsutils "^3.21.0"
+"@typescript-eslint/type-utils@6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.6.0.tgz#14f651d13b884915c4fca0d27adeb652a4499e86"
+ integrity sha512-8m16fwAcEnQc69IpeDyokNO+D5spo0w1jepWWY2Q6y5ZKNuj5EhVQXjtVAeDDqvW6Yg7dhclbsz6rTtOvcwpHg==
+ dependencies:
+ "@typescript-eslint/typescript-estree" "6.6.0"
+ "@typescript-eslint/utils" "6.6.0"
+ debug "^4.3.4"
+ ts-api-utils "^1.0.1"
+
"@typescript-eslint/types@5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f"
integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==
+"@typescript-eslint/types@6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.6.0.tgz#95e7ea650a2b28bc5af5ea8907114a48f54618c2"
+ integrity sha512-CB6QpJQ6BAHlJXdwUmiaXDBmTqIE2bzGTDLADgvqtHWuhfNP3rAOK7kAgRMAET5rDRr9Utt+qAzRBdu3AhR3sg==
+
"@typescript-eslint/typescript-estree@5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b"
@@ -2036,6 +2099,19 @@
semver "^7.3.7"
tsutils "^3.21.0"
+"@typescript-eslint/typescript-estree@6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.6.0.tgz#373c420d2e12c28220f4a83352280a04823a91b7"
+ integrity sha512-hMcTQ6Al8MP2E6JKBAaSxSVw5bDhdmbCEhGW/V8QXkb9oNsFkA4SBuOMYVPxD3jbtQ4R/vSODBsr76R6fP3tbA==
+ dependencies:
+ "@typescript-eslint/types" "6.6.0"
+ "@typescript-eslint/visitor-keys" "6.6.0"
+ debug "^4.3.4"
+ globby "^11.1.0"
+ is-glob "^4.0.3"
+ semver "^7.5.4"
+ ts-api-utils "^1.0.1"
+
"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86"
@@ -2050,6 +2126,19 @@
eslint-scope "^5.1.1"
semver "^7.3.7"
+"@typescript-eslint/utils@6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.6.0.tgz#2d686c0f0786da6362d909e27a9de1c13ba2e7dc"
+ integrity sha512-mPHFoNa2bPIWWglWYdR0QfY9GN0CfvvXX1Sv6DlSTive3jlMTUy+an67//Gysc+0Me9pjitrq0LJp0nGtLgftw==
+ dependencies:
+ "@eslint-community/eslint-utils" "^4.4.0"
+ "@types/json-schema" "^7.0.12"
+ "@types/semver" "^7.5.0"
+ "@typescript-eslint/scope-manager" "6.6.0"
+ "@typescript-eslint/types" "6.6.0"
+ "@typescript-eslint/typescript-estree" "6.6.0"
+ semver "^7.5.4"
+
"@typescript-eslint/visitor-keys@5.62.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e"
@@ -2058,6 +2147,14 @@
"@typescript-eslint/types" "5.62.0"
eslint-visitor-keys "^3.3.0"
+"@typescript-eslint/visitor-keys@6.6.0":
+ version "6.6.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.6.0.tgz#1109088b4346c8b2446f3845db526374d9a3bafc"
+ integrity sha512-L61uJT26cMOfFQ+lMZKoJNbAEckLe539VhTxiGHrWl5XSKQgA0RTBZJW2HFPy5T0ZvPVSD93QsrTKDkfNwJGyQ==
+ dependencies:
+ "@typescript-eslint/types" "6.6.0"
+ eslint-visitor-keys "^3.4.1"
+
abort-controller@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
@@ -2430,6 +2527,11 @@ base64-js@^1.1.2, base64-js@^1.3.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+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==
+
bl@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
@@ -2439,6 +2541,13 @@ bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
+bplist-parser@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e"
+ integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==
+ dependencies:
+ big-integer "^1.6.44"
+
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -2491,6 +2600,13 @@ buffer@^5.5.0:
base64-js "^1.3.1"
ieee754 "^1.1.13"
+bundle-name@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a"
+ integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==
+ dependencies:
+ run-applescript "^5.0.0"
+
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -2813,6 +2929,24 @@ deepmerge@^4.2.2, deepmerge@^4.3.0:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
+default-browser-id@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c"
+ integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==
+ dependencies:
+ bplist-parser "^0.2.0"
+ untildify "^4.0.0"
+
+default-browser@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da"
+ integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==
+ dependencies:
+ bundle-name "^3.0.0"
+ default-browser-id "^3.0.0"
+ execa "^7.1.1"
+ titleize "^3.0.0"
+
defaults@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a"
@@ -2820,6 +2954,11 @@ defaults@^1.0.3:
dependencies:
clone "^1.0.2"
+define-lazy-prop@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f"
+ integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==
+
define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5"
@@ -3055,6 +3194,11 @@ eslint-config-prettier@^8.5.0:
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11"
integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==
+eslint-config-prettier@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f"
+ integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==
+
eslint-plugin-eslint-comments@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa"
@@ -3078,6 +3222,13 @@ eslint-plugin-jest@^26.5.3:
dependencies:
"@typescript-eslint/utils" "^5.10.0"
+eslint-plugin-jest@^27.2.3:
+ version "27.2.3"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.3.tgz#6f8a4bb2ca82c0c5d481d1b3be256ab001f5a3ec"
+ integrity sha512-sRLlSCpICzWuje66Gl9zvdF6mwD5X86I4u55hJyFBsxYOsBCmT5+kSUjf+fkFWVMMgpzNEupjW8WzUqi83hJAQ==
+ dependencies:
+ "@typescript-eslint/utils" "^5.10.0"
+
eslint-plugin-prettier@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b"
@@ -3085,6 +3236,14 @@ eslint-plugin-prettier@^4.2.1:
dependencies:
prettier-linter-helpers "^1.0.0"
+eslint-plugin-prettier@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz#6887780ed95f7708340ec79acfdf60c35b9be57a"
+ integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==
+ dependencies:
+ prettier-linter-helpers "^1.0.0"
+ synckit "^0.8.5"
+
eslint-plugin-react-hooks@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
@@ -3150,7 +3309,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
-eslint@^8.19.0:
+eslint@^8.48.0:
version "8.48.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.48.0.tgz#bf9998ba520063907ba7bfe4c480dc8be03c2155"
integrity sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==
@@ -3261,6 +3420,21 @@ execa@^5.0.0:
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
+execa@^7.1.1:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9"
+ integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.1"
+ human-signals "^4.3.0"
+ is-stream "^3.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^5.1.0"
+ onetime "^6.0.0"
+ signal-exit "^3.0.7"
+ strip-final-newline "^3.0.0"
+
exit@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -3287,7 +3461,7 @@ fast-diff@^1.1.2:
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0"
integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
-fast-glob@^3.2.9:
+fast-glob@^3.2.9, fast-glob@^3.3.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4"
integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==
@@ -3506,7 +3680,7 @@ get-package-type@^0.1.0:
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
-get-stream@^6.0.0:
+get-stream@^6.0.0, get-stream@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
@@ -3690,12 +3864,17 @@ human-signals@^2.1.0:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+human-signals@^4.3.0:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2"
+ integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==
+
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
-ignore@^5.0.5, ignore@^5.2.0:
+ignore@^5.0.5, ignore@^5.2.0, ignore@^5.2.4:
version "5.2.4"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
@@ -3830,6 +4009,16 @@ is-directory@^0.3.1:
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==
+is-docker@^2.0.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
+ integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
+
+is-docker@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200"
+ integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==
+
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@@ -3871,6 +4060,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
dependencies:
is-extglob "^2.1.1"
+is-inside-container@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4"
+ integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==
+ dependencies:
+ is-docker "^3.0.0"
+
is-interactive@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
@@ -3935,6 +4131,11 @@ is-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+is-stream@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac"
+ integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
+
is-string@^1.0.5, is-string@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
@@ -3986,6 +4187,13 @@ is-wsl@^1.1.0:
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==
+is-wsl@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
+ integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
+ dependencies:
+ is-docker "^2.0.0"
+
isarray@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
@@ -4995,6 +5203,51 @@ metro-react-native-babel-preset@0.76.8:
babel-plugin-transform-flow-enums "^0.0.2"
react-refresh "^0.4.0"
+metro-react-native-babel-preset@^0.77.0:
+ version "0.77.0"
+ resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.77.0.tgz#47457eca8e36b77156afbe790247a70dbb40faaa"
+ integrity sha512-HPPD+bTxADtoE4y/4t1txgTQ1LVR6imOBy7RMHUsqMVTbekoi8Ph5YI9vKX2VMPtVWeFt0w9YnCSLPa76GcXsA==
+ dependencies:
+ "@babel/core" "^7.20.0"
+ "@babel/plugin-proposal-async-generator-functions" "^7.0.0"
+ "@babel/plugin-proposal-class-properties" "^7.18.0"
+ "@babel/plugin-proposal-export-default-from" "^7.0.0"
+ "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.0"
+ "@babel/plugin-proposal-numeric-separator" "^7.0.0"
+ "@babel/plugin-proposal-object-rest-spread" "^7.20.0"
+ "@babel/plugin-proposal-optional-catch-binding" "^7.0.0"
+ "@babel/plugin-proposal-optional-chaining" "^7.20.0"
+ "@babel/plugin-syntax-dynamic-import" "^7.8.0"
+ "@babel/plugin-syntax-export-default-from" "^7.0.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"
+ "@babel/plugin-transform-async-to-generator" "^7.20.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.20.0"
+ "@babel/plugin-transform-flow-strip-types" "^7.20.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-typescript" "^7.5.0"
+ "@babel/plugin-transform-unicode-regex" "^7.0.0"
+ "@babel/template" "^7.0.0"
+ babel-plugin-transform-flow-enums "^0.0.2"
+ react-refresh "^0.4.0"
+
metro-react-native-babel-transformer@0.76.7:
version "0.76.7"
resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.76.7.tgz#ccc7c25b49ee8a1860aafdbf48bfa5441d206f8f"
@@ -5296,6 +5549,11 @@ mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+mimic-fn@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc"
+ integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
+
minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@@ -5413,6 +5671,13 @@ npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
+npm-run-path@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00"
+ integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==
+ dependencies:
+ path-key "^4.0.0"
+
nullthrows@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1"
@@ -5521,6 +5786,13 @@ onetime@^5.1.0, onetime@^5.1.2:
dependencies:
mimic-fn "^2.1.0"
+onetime@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4"
+ integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
+ dependencies:
+ mimic-fn "^4.0.0"
+
open@^6.2.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9"
@@ -5528,6 +5800,16 @@ open@^6.2.0:
dependencies:
is-wsl "^1.1.0"
+open@^9.1.0:
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6"
+ integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==
+ dependencies:
+ default-browser "^4.0.0"
+ define-lazy-prop "^3.0.0"
+ is-inside-container "^1.0.0"
+ is-wsl "^2.2.0"
+
optionator@^0.9.3:
version "0.9.3"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64"
@@ -5645,6 +5927,11 @@ path-key@^3.0.0, path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+path-key@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18"
+ integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
+
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
@@ -5708,10 +5995,10 @@ prettier-linter-helpers@^1.0.0:
dependencies:
fast-diff "^1.1.2"
-prettier@^2.4.1:
- version "2.8.8"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
- integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
+prettier@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643"
+ integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==
pretty-format@^26.5.2, pretty-format@^26.6.2:
version "26.6.2"
@@ -5826,11 +6113,6 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
-react-native-clean-project@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/react-native-clean-project/-/react-native-clean-project-4.0.1.tgz#c0e2b17eebf32a683aa67da45fe7932857166da7"
- integrity sha512-B7rXdFC4bfA+Vv7lZ9bKS6cUDgqg04OR5D69sNnhheFBJQ1V04cIfJ1Fu0sbqRsIehqlOcySQRpp8tm7r7PvLQ==
-
react-native-safe-area-context@^4.7.2:
version "4.7.2"
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.7.2.tgz#1673aa99b6a9235e7faaf5a248e69795d6e54e07"
@@ -5899,7 +6181,7 @@ react-shallow-renderer@^16.15.0:
object-assign "^4.1.1"
react-is "^16.12.0 || ^17.0.0 || ^18.0.0"
-react-test-renderer@18.2.0:
+react-test-renderer@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.2.0.tgz#1dd912bd908ff26da5b9fca4fd1c489b9523d37e"
integrity sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==
@@ -6108,6 +6390,13 @@ rimraf@~2.6.2:
dependencies:
glob "^7.1.3"
+run-applescript@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c"
+ integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==
+ dependencies:
+ execa "^5.0.0"
+
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
@@ -6452,6 +6741,11 @@ strip-final-newline@^2.0.0:
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+strip-final-newline@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd"
+ integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
+
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"
@@ -6493,6 +6787,14 @@ supports-preserve-symlinks-flag@^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==
+synckit@^0.8.5:
+ version "0.8.5"
+ resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3"
+ integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==
+ dependencies:
+ "@pkgr/utils" "^2.3.1"
+ tslib "^2.5.0"
+
temp@^0.8.4:
version "0.8.4"
resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.4.tgz#8c97a33a4770072e0a05f919396c7665a7dd59f2"
@@ -6537,6 +6839,11 @@ through2@^2.0.1:
readable-stream "~2.3.6"
xtend "~4.0.1"
+titleize@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53"
+ integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==
+
tmpl@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
@@ -6564,12 +6871,17 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
+ts-api-utils@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331"
+ integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==
+
tslib@^1.8.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-tslib@^2.0.1:
+tslib@^2.0.1, tslib@^2.5.0, tslib@^2.6.0:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
@@ -6647,10 +6959,10 @@ typed-array-length@^1.0.4:
for-each "^0.3.3"
is-typed-array "^1.1.9"
-typescript@4.8.4:
- version "4.8.4"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6"
- integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==
+typescript@5.2.2:
+ version "5.2.2"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
+ integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
uglify-es@^3.1.9:
version "3.3.9"
@@ -6703,6 +7015,11 @@ unpipe@~1.0.0:
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
+untildify@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
+ integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
+
update-browserslist-db@^1.0.11:
version "1.0.11"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940"
diff --git a/android/README.md b/android/README.md
deleted file mode 100644
index c2ccc01e..00000000
--- a/android/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-README
-======
-
-If you want to publish the lib as a maven dependency, follow these steps before publishing a new version to npm:
-
-1. Be sure to have the Android [SDK](https://developer.android.com/studio/index.html) and [NDK](https://developer.android.com/ndk/guides/index.html) installed
-2. Be sure to have a `local.properties` file in this folder that points to the Android SDK and NDK
-```
-ndk.dir=/Users/{username}/Library/Android/sdk/ndk-bundle
-sdk.dir=/Users/{username}/Library/Android/sdk
-```
-3. Delete the `maven` folder
-4. Run `sudo ./gradlew installArchives`
-5. Verify that latest set of generated files is in the maven folder with the correct version number
diff --git a/android/build.gradle b/android/build.gradle
index 1f51b884..f6a359f0 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,51 +1,100 @@
buildscript {
- ext.safeExtGet = {prop, fallback ->
- rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
+ ext.getExtOrFallback = { name, fallback ->
+ rootProject.ext.has(name) ? rootProject.ext.get(name) : fallback
}
+
+ ext.getExtOrDefault = { name ->
+ getExtOrFallback(name, project.properties["lib_" + name])
+ }
+
repositories {
google()
mavenCentral()
}
dependencies {
- // Matches recent template from React Native (0.64)
- // https://github.com/facebook/react-native/blob/0.64-stable/template/android/build.gradle#L16
- classpath("com.android.tools.build:gradle:${safeExtGet('gradlePluginVersion', '4.2.0')}")
+ classpath "com.android.tools.build:gradle:${getExtOrDefault('gradlePluginVersion')}"
}
}
+def isNewArchitectureEnabled() {
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
+}
+
apply plugin: 'com.android.library'
-apply plugin: 'maven-publish'
+apply plugin: 'kotlin-android'
+
+def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
+
+if (isNewArchitectureEnabled()) {
+ apply plugin: "com.facebook.react"
+}
+
+def getExtOrDefault(name) {
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["lib_" + name]
+}
+
+def getExtOrIntegerDefault(name) {
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["lib_" + name]).toInteger()
+}
+
+def supportsNamespace() {
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
+ def major = parsed[0].toInteger()
+ def minor = parsed[1].toInteger()
+
+ // Namespace support was added in 7.3.0
+ if (major == 7 && minor >= 3) {
+ return true
+ }
-// Matches or updates values in template from React Native (0.64)
-// https://github.com/facebook/react-native/blob/0.64-stable/template/android/build.gradle#L5-L9
-def DEFAULT_COMPILE_SDK_VERSION = 30
-def DEFAULT_BUILD_TOOLS_VERSION = "30.0.2"
-def DEFAULT_MIN_SDK_VERSION = 21
-def DEFAULT_TARGET_SDK_VERSION = 30
+ return major >= 8
+}
android {
- compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
- buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION)
+ if (supportsNamespace()) {
+ namespace "com.klarna.mobile.sdk.reactnative"
+
+ sourceSets {
+ main {
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
+ }
+ }
+ }
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
defaultConfig {
- minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION)
- targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION)
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
versionCode 1
versionName "1.0"
}
+ buildTypes {
+ release {
+ minifyEnabled false
+ }
+ }
lintOptions {
abortOnError false
+ disable "GradleCompatible"
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ sourceSets {
+ main {
+ if (isNewArchitectureEnabled()) {
+ java.srcDirs += ["src/newarch/java"]
+ } else {
+ java.srcDirs += ["src/oldarch/java"]
+ }
+ }
}
}
repositories {
- maven {
- // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
- // Matches recent template from React Native (0.59)
- // https://github.com/facebook/react-native/blob/0.59-stable/template/android/build.gradle#L30
- url "$projectDir/../node_modules/react-native/android"
- }
mavenCentral()
google()
maven {
@@ -54,7 +103,11 @@ repositories {
}
dependencies {
- implementation "com.facebook.react:react-native:${safeExtGet('reactnativeVersion', '+')}"
+ // For < 0.71, this will be from the local maven repo
+ // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
+ //noinspection GradleDynamicVersion
+ implementation "com.facebook.react:react-native:${getExtOrFallback('reactnativeVersion', '+')}"
+
implementation 'com.klarna.mobile:sdk:2.6.8'
testImplementation "junit:junit:4.13"
@@ -69,87 +122,12 @@ dependencies {
testImplementation "org.powermock:powermock-classloading-xstream:2.0.7"
}
-def configureReactNativePom(def pom) {
- def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text)
-
- pom.project {
- name packageJson.title
- artifactId packageJson.name
- version = packageJson.version
- group = "com.klarna"
- description packageJson.description
- url packageJson.repository.baseUrl
-
- licenses {
- license {
- name packageJson.license
- url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename
- distribution 'repo'
- }
- }
-
- developers {
- developer {
- id packageJson.author.username
- name packageJson.author.name
- }
- }
- }
-}
-
-afterEvaluate { project ->
-
- task androidJavadocs(type: Javadoc) {
- source = android.sourceSets.main.java.srcDirs
- classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
- android.libraryVariants.all { variant ->
- if (variant.name == 'release') {
- owner.classpath += variant.javaCompileProvider.get().classpath
- }
- }
- }
-
- task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
- archiveClassifier.set('javadoc')
- from androidJavadocs.destinationDir
- }
-
- task androidSourcesJar(type: Jar) {
- archiveClassifier = 'sources'
- from android.sourceSets.main.java.srcDirs
- include '**/*.java'
- }
-
- android.libraryVariants.all { variant ->
- def name = variant.name.capitalize()
- task "jar${name}"(type: Jar, dependsOn: variant.javaCompile) {
- from variant.javaCompile.destinationDir
- }
- }
-
- artifacts {
- archives androidSourcesJar
- archives androidJavadocsJar
- }
-
- publishing {
- publications {
- sdkDefaultRelease(MavenPublication) {
- def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text)
- groupId "com.klarna"
- artifactId packageJson.name
- version packageJson.version
- description packageJson.description
-
- artifact(androidSourcesJar)
- artifact(androidJavadocsJar)
- }
- }
-
- repositories {
- maven {
- url = uri("file://${projectDir}/../android/maven")
- }
- }
- }
+// removed from the docs but we can keep it
+// https://reactnative.dev/docs/0.71/new-architecture-library-intro
+if (isNewArchitectureEnabled()) {
+ react {
+ jsRootDir = file("../src/specs")
+ libraryName = "RNKlarnaMobileSDK"
+ codegenJavaPackageName = "com.klarna.mobile.sdk.reactnative"
+ }
}
diff --git a/android/gradle.properties b/android/gradle.properties
index 3d8ce0ca..8270ac09 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -15,3 +15,10 @@ org.gradle.jvmargs=-Xmx1536m
kotlin.code.style=official
android.useAndroidX=true
android.enableJetifier=true
+
+lib_gradlePluginVersion=7.2.1
+lib_kotlinVersion=1.7.0
+lib_minSdkVersion=21
+lib_targetSdkVersion=31
+lib_compileSdkVersion=31
+lib_ndkVersion=21.4.7075529
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index e9720381..2592ec1f 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -1,4 +1,5 @@
+ package="com.klarna.mobile.sdk.reactnative">
+
diff --git a/android/src/main/AndroidManifestNew.xml b/android/src/main/AndroidManifestNew.xml
new file mode 100644
index 00000000..b5553bc3
--- /dev/null
+++ b/android/src/main/AndroidManifestNew.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/android/src/main/java/com/klarna/inapp/sdk/HeightListener.java b/android/src/main/java/com/klarna/inapp/sdk/HeightListener.java
deleted file mode 100644
index b8b32c40..00000000
--- a/android/src/main/java/com/klarna/inapp/sdk/HeightListener.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package com.klarna.inapp.sdk;
-
-import android.os.Build;
-import android.webkit.JavascriptInterface;
-import android.webkit.ValueCallback;
-import android.webkit.WebView;
-
-import java.lang.ref.WeakReference;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Used by the PaymentViewWrapper class to inject JS and listen to height changes inside the WebView
- */
-public class HeightListener {
- private final String heightScript = "getAndroidHeight()";
- private final AtomicBoolean attachedEventObserver = new AtomicBoolean(false);
- private WeakReference callback;
-
- HeightListener(WebView webView, HeightListenerCallback callback) {
- this.callback = new WeakReference<>(callback);
- webView.addJavascriptInterface(this, "AndroidEventObserver");
- }
-
- /**
- * Injects the script that fetches the height value
- *
- * @param webView The web view instance to inject the script into
- */
- void injectListener(WebView webView) {
- injectScript(webView, getHeightFuncScript());
- }
-
- /**
- * Calls the height function which was injected to the web view and
- * send the value back to the wrapper
- *
- * @param webView The web view to fetch its height value
- */
- void fetchHeight(final WebView webView) {
- if (webView == null) {
- return;
- }
- webView.evaluateJavascript(heightScript, new ValueCallback() {
- @Override
- public void onReceiveValue(String value) {
- if (!attachedEventObserver.get()) {
- attachEventObserver(webView);
- }
- sendHeightValue(value);
- }
- });
- }
-
- /**
- * Attaches 'resize' event listener to the web view's window object and
- * calls the height function when there is a resize event, then send the height value
- * back to the wrapper
- *
- * @param webView The web view to attach the 'resize' listener to
- */
- private void attachEventObserver(WebView webView) {
- String eventListenerScript =
- "try{" +
- "window.addEventListener('resize', function() { AndroidEventObserver.onResized(" + heightScript + "); });" +
- "}catch(error){" +
- "console.log('Failed to attach AndroidEventObserver: ' + error);" +
- "}";
- evaluateJSCompat(webView, eventListenerScript);
- }
-
- /**
- * Injects the given script into the given web view object
- *
- * @param webView The web view to inject the script into
- * @param script The script to inject into the web view
- */
- private void injectScript(WebView webView, String script) {
- try {
- evaluateJSCompat(webView, "(function() {" +
- "var parent = document.getElementsByTagName('head').item(0);" +
- "var script = document.createElement('script');" +
- "script.type = 'text/javascript';" +
- "script.innerHTML = " + script + ";" +
- "parent.appendChild(script)" +
- "})()");
- } catch (Throwable t) {
- }
- }
-
- /**
- * The javascript interface method that is called when there's a
- * 'resize' event
- *
- * @param value The height value which is sent from the 'resize' listener
- */
- @JavascriptInterface
- public void onResized(final String value) {
- attachedEventObserver.set(true);
- sendHeightValue(value);
- }
-
- /**
- * Unwraps and null checks the callback object and sends
- * the height value to wrapper through this callback
- *
- * @param value The updated height value to send to wrapper
- */
- private void sendHeightValue(String value) {
- if (callback != null) {
- HeightListenerCallback callbackInstance = callback.get();
- if (callbackInstance != null) {
- callbackInstance.onNewHeight(value);
- }
- }
- }
-
- /**
- * Returns the height function to be injected as a script into the web view
- *
- * @return The height function in JS
- */
- private String getHeightFuncScript() {
- return
- "function getAndroidHeight(){\n" +
- " var heights = new Array();\n" +
- " var bodyHeight = document.body.scrollHeight;\n" +
- " bodyHeight > 0 && heights.push(bodyHeight);\n" +
- " var docHeight = document.documentElement.scrollHeight;\n" +
- " docHeight > 0 && heights.push(docHeight);\n" +
- " try{\n" +
- " var containerHeight = document.getElementById('payment-container').scrollHeight;\n" +
- " containerHeight > 0 && heights.push(containerHeight);\n" +
- " } catch(error){}\n" +
- " return heights.length > 0 ? Math.min.apply(Math,heights) : 0;\n" +
- "}";
- }
-
- /**
- * Evaluates a script inside a web view in a backward-compatible manner
- *
- * @param webView The web view to evaluate the script
- * @param script The script to be evaluated
- */
- private void evaluateJSCompat(WebView webView, String script) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- webView.evaluateJavascript(script, null);
- } else {
- webView.loadUrl("javascript:" + script);
- }
- }
-
- /**
- * The interface between the wrapper and listener class
- * to send the updated height values
- */
- public interface HeightListenerCallback {
- void onNewHeight(String value);
- }
-}
diff --git a/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentViewManager.java b/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentViewManager.java
deleted file mode 100644
index 60faaedb..00000000
--- a/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentViewManager.java
+++ /dev/null
@@ -1,282 +0,0 @@
-package com.klarna.inapp.sdk;
-
-import android.app.Application;
-
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReadableArray;
-import com.facebook.react.common.MapBuilder;
-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.EventDispatcher;
-import com.klarna.mobile.sdk.api.payments.KlarnaPaymentView;
-import com.klarna.mobile.sdk.api.payments.KlarnaPaymentViewCallback;
-import com.klarna.mobile.sdk.api.payments.KlarnaPaymentsSDKError;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.lang.ref.WeakReference;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-/**
- * Wraps the Payment Views being exposed to JS.
- */
-public class KlarnaPaymentViewManager extends SimpleViewManager implements KlarnaPaymentViewCallback {
-
- // Commands that can be triggered from RN
- public static final int COMMAND_INITIALIZE = 1;
- public static final int COMMAND_LOAD = 2;
- public static final int COMMAND_LOAD_PAYMENT_REVIEW = 3;
- public static final int COMMAND_AUTHORIZE = 4;
- public static final int COMMAND_REAUTHORIZE = 5;
- public static final int COMMAND_FINALIZE = 6;
-
- public static final String REACT_CLASS = "KlarnaPaymentView";
-
- private final ReactApplicationContext reactAppContext;
-
- // Store a list of views to event dispatchers so we send up events via the right views.
- private Map, EventDispatcher> viewToDispatcher;
-
- KlarnaPaymentViewManager(ReactApplicationContext reactApplicationContext, Application app) {
- super();
- this.viewToDispatcher = new HashMap<>();
- this.reactAppContext = reactApplicationContext;
- }
-
- @Override
- public String getName() {
- return REACT_CLASS;
- }
-
- @Override
- public PaymentViewWrapper createViewInstance(ThemedReactContext context) {
- PaymentViewWrapper view = new PaymentViewWrapper(reactAppContext, null);
-
- // Each view has its own event dispatcher.
- EventDispatcher dispatcher = context.getNativeModule(UIManagerModule.class).getEventDispatcher();
- viewToDispatcher.put(new WeakReference<>(view), dispatcher);
-
- return view;
- }
-
- /**
- * Commads are methods that RN will expose on the JS side for a view. They can be called via
- * `UIManager.dispatchViewManagerCommand` from react.
- *
- * @return a map of command names to command IDs
- */
- @Nullable
- @Override
- public Map getCommandsMap() {
- return MapBuilder.of(
- "initialize", COMMAND_INITIALIZE,
- "load", COMMAND_LOAD,
- "loadPaymentReview", COMMAND_LOAD_PAYMENT_REVIEW,
- "authorize", COMMAND_AUTHORIZE,
- "reauthorize", COMMAND_REAUTHORIZE,
- "finalize", COMMAND_FINALIZE
- );
- }
-
- /**
- * Handles commands received from RN to a specific view.
- *
- * @param root
- * @param commandId
- * @param args
- */
- @Override
- public void receiveCommand(@Nonnull PaymentViewWrapper root, int commandId, @Nullable ReadableArray args) {
- String sessionData = null;
-
- switch (commandId) {
- case COMMAND_INITIALIZE:
- if (args != null) {
- final String token = args.getString(0);
- final String returnUrl = args.getString(1);
-
- if (token != null && returnUrl != null) {
- root.paymentView.initialize(token, returnUrl);
- }
- }
- break;
-
- case COMMAND_LOAD:
- if (args != null) {
- sessionData = args.getString(0);
- }
- root.load(sessionData);
- break;
-
- case COMMAND_LOAD_PAYMENT_REVIEW:
- root.paymentView.loadPaymentReview();
- break;
-
- case COMMAND_AUTHORIZE:
- if (args != null) {
- final boolean autoFinalize = args.getBoolean(0);
- sessionData = args.getString(1);
-
- root.paymentView.authorize(autoFinalize, sessionData);
- }
- break;
-
- case COMMAND_REAUTHORIZE:
- if (args != null) {
- sessionData = args.getString(0);
- }
- root.paymentView.reauthorize(sessionData);
- break;
-
- case COMMAND_FINALIZE:
- if (args != null) {
- sessionData = args.getString(0);
- }
- root.paymentView.finalize(sessionData);
- break;
- }
- }
-
- /**
- * Exposes direct event types that will be accessible as prop "callbacks" from RN.
- *
- * Structure must follow:
- * { "": {"registrationName": ""} }
- */
- @Nullable
- @Override
- public Map getExportedCustomDirectEventTypeConstants() {
- return MapBuilder.of(
- KlarnaPaymentEvent.EVENT_NAME_ON_INITIALIZE, MapBuilder.of("registrationName", KlarnaPaymentEvent.EVENT_NAME_ON_INITIALIZE),
- KlarnaPaymentEvent.EVENT_NAME_ON_LOAD, MapBuilder.of("registrationName", KlarnaPaymentEvent.EVENT_NAME_ON_LOAD),
- KlarnaPaymentEvent.EVENT_NAME_ON_LOAD_PAYMENT_REVIEW, MapBuilder.of("registrationName", KlarnaPaymentEvent.EVENT_NAME_ON_LOAD_PAYMENT_REVIEW),
- KlarnaPaymentEvent.EVENT_NAME_ON_AUTHORIZE, MapBuilder.of("registrationName", KlarnaPaymentEvent.EVENT_NAME_ON_AUTHORIZE),
- KlarnaPaymentEvent.EVENT_NAME_ON_REAUTHORIZE, MapBuilder.of("registrationName", KlarnaPaymentEvent.EVENT_NAME_ON_REAUTHORIZE),
- KlarnaPaymentEvent.EVENT_NAME_ON_FINALIZE, MapBuilder.of("registrationName", KlarnaPaymentEvent.EVENT_NAME_ON_FINALIZE),
- KlarnaPaymentEvent.EVENT_NAME_ON_ERROR, MapBuilder.of("registrationName", KlarnaPaymentEvent.EVENT_NAME_ON_ERROR)
- );
- }
-
- /**
- * Payment View's payment method category (e.g: "pay_later", "pay_over_time").
- *
- * @param view
- * @param category
- */
- @ReactProp(name = "category")
- public void setCategory(PaymentViewWrapper view, String category) {
- view.paymentView.registerPaymentViewCallback(this);
- view.paymentView.setCategory(category);
- }
-
- /**
- * Creates an event from event name and a map of params. Sends it via the right dispatcher.
- * @param eventName
- * @param additionalParams
- * @param view
- */
- private void postEventForView(String eventName, Map additionalParams, KlarnaPaymentView view) {
- PaymentViewWrapper wrapper = wrapperForPaymentView(view);
- EventDispatcher foundDispatcher = null;
- for (WeakReference wrapperRef : viewToDispatcher.keySet()) {
- if (wrapperRef.get() == wrapper) {
- foundDispatcher = viewToDispatcher.get(wrapperRef);
- }
- }
-
- KlarnaPaymentEvent event = new KlarnaPaymentEvent(wrapper.getId(), eventName, additionalParams);
- foundDispatcher.dispatchEvent(event);
- }
-
- /**
- * Calls requestLayout on the wrapper to fetch height of the contents.
- * @param view
- */
- private void requestLayout(KlarnaPaymentView view) {
- if (view != null) {
- PaymentViewWrapper wrapper = wrapperForPaymentView(view);
- if (wrapper != null) {
- wrapper.requestLayout();
- }
- }
- }
-
-
- /* -- KlarnaPaymentView callback methods -- */
-
- @Override
- public void onInitialized(@NotNull KlarnaPaymentView paymentView) {
- requestLayout(paymentView);
- postEventForView(KlarnaPaymentEvent.EVENT_NAME_ON_INITIALIZE, null, paymentView);
- }
-
- @Override
- public void onLoaded(@NotNull KlarnaPaymentView paymentView) {
- requestLayout(paymentView);
- postEventForView(KlarnaPaymentEvent.EVENT_NAME_ON_LOAD, null, paymentView);
- }
-
- @Override
- public void onLoadPaymentReview(@NotNull KlarnaPaymentView paymentView, boolean b) {
- requestLayout(paymentView);
- postEventForView(KlarnaPaymentEvent.EVENT_NAME_ON_LOAD_PAYMENT_REVIEW, null, paymentView);
- }
-
- @Override
- public void onAuthorized(@NotNull KlarnaPaymentView paymentView, boolean approved, @org.jetbrains.annotations.Nullable String authToken, @org.jetbrains.annotations.Nullable Boolean finalizeRequired) {
- requestLayout(paymentView);
- postEventForView(KlarnaPaymentEvent.EVENT_NAME_ON_AUTHORIZE,
- MapBuilder.of(
- "approved", approved,
- "authToken", authToken,
- "finalizeRequired", finalizeRequired),
- paymentView);
- }
-
- @Override
- public void onReauthorized(@NotNull KlarnaPaymentView paymentView, boolean approved, @org.jetbrains.annotations.Nullable String authToken) {
- requestLayout(paymentView);
- postEventForView(KlarnaPaymentEvent.EVENT_NAME_ON_REAUTHORIZE,
- MapBuilder.of(
- "approved", approved,
- "authToken", authToken),
- paymentView);
- }
-
- @Override
- public void onFinalized(@NotNull KlarnaPaymentView paymentView, boolean approved, @org.jetbrains.annotations.Nullable String authToken) {
- requestLayout(paymentView);
- postEventForView(KlarnaPaymentEvent.EVENT_NAME_ON_FINALIZE,
- MapBuilder.of(
- "approved", approved,
- "authToken", authToken),
- paymentView);
- }
-
- @Override
- public void onErrorOccurred(@NotNull KlarnaPaymentView klarnaPaymentView, @NotNull KlarnaPaymentsSDKError klarnaPaymentsSDKError) {
- requestLayout(klarnaPaymentView);
- MappableKlarnaPaymentsSDKError sdkError = new MappableKlarnaPaymentsSDKError(klarnaPaymentsSDKError);
- postEventForView(KlarnaPaymentEvent.EVENT_NAME_ON_ERROR,
- MapBuilder.of("error", sdkError.buildMap()),
- klarnaPaymentView);
- }
-
- private PaymentViewWrapper wrapperForPaymentView(KlarnaPaymentView paymentView) {
- for (WeakReference reference : viewToDispatcher.keySet()) {
- PaymentViewWrapper wrapper = reference.get();
-
- if (wrapper != null && wrapper.paymentView == paymentView) {
- return wrapper;
- }
- }
- return null;
- }
-
-}
diff --git a/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentViewPackage.java b/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentViewPackage.java
deleted file mode 100644
index 43274c1c..00000000
--- a/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentViewPackage.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.klarna.inapp.sdk;
-
-import android.app.Application;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import com.facebook.react.ReactPackage;
-import com.facebook.react.bridge.NativeModule;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.uimanager.ViewManager;
-
-public class KlarnaPaymentViewPackage implements ReactPackage {
-
- @Override
- public List createNativeModules(ReactApplicationContext reactContext) {
- return Collections.emptyList();
- }
-
- @Override
- public List createViewManagers(ReactApplicationContext reactContext) {
- return Arrays.asList(new KlarnaPaymentViewManager(reactContext, (Application) reactContext.getApplicationContext()));
- }
-}
diff --git a/android/src/main/java/com/klarna/inapp/sdk/Mappable.java b/android/src/main/java/com/klarna/inapp/sdk/Mappable.java
deleted file mode 100644
index 8139bd55..00000000
--- a/android/src/main/java/com/klarna/inapp/sdk/Mappable.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.klarna.inapp.sdk;
-
-import androidx.annotation.NonNull;
-
-import java.util.Map;
-
-interface Mappable {
- @NonNull
- Map buildMap();
-}
diff --git a/android/src/main/java/com/klarna/inapp/sdk/MappableKlarnaPaymentsSDKError.java b/android/src/main/java/com/klarna/inapp/sdk/MappableKlarnaPaymentsSDKError.java
deleted file mode 100644
index 72b1b0b0..00000000
--- a/android/src/main/java/com/klarna/inapp/sdk/MappableKlarnaPaymentsSDKError.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.klarna.inapp.sdk;
-
-import androidx.annotation.NonNull;
-
-import com.facebook.react.common.MapBuilder;
-import com.klarna.mobile.sdk.api.payments.KlarnaPaymentsSDKError;
-
-import java.util.Map;
-
-class MappableKlarnaPaymentsSDKError implements Mappable {
-
- @NonNull
- private KlarnaPaymentsSDKError klarnaPaymentsSDKError;
-
- MappableKlarnaPaymentsSDKError(@NonNull KlarnaPaymentsSDKError klarnaPaymentsSDKError) {
- this.klarnaPaymentsSDKError = klarnaPaymentsSDKError;
- }
-
- @NonNull
- @Override
- public Map buildMap() {
- return MapBuilder.builder()
- .put("action", klarnaPaymentsSDKError.getAction())
- .put("isFatal", klarnaPaymentsSDKError.isFatal())
- .put("message", klarnaPaymentsSDKError.getMessage())
- .put("name", klarnaPaymentsSDKError.getName())
- .put("invalidFields", klarnaPaymentsSDKError.getInvalidFields())
- .put("sessionId", klarnaPaymentsSDKError.getSessionId())
- .build();
- }
-}
diff --git a/android/src/main/java/com/klarna/inapp/sdk/PaymentViewWrapper.java b/android/src/main/java/com/klarna/inapp/sdk/PaymentViewWrapper.java
deleted file mode 100644
index 48163e84..00000000
--- a/android/src/main/java/com/klarna/inapp/sdk/PaymentViewWrapper.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.klarna.inapp.sdk;
-
-import android.util.AttributeSet;
-import android.view.View;
-import android.webkit.WebView;
-import android.widget.LinearLayout;
-
-import com.facebook.react.bridge.GuardedRunnable;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.uimanager.UIManagerModule;
-import com.klarna.mobile.sdk.api.payments.KlarnaPaymentView;
-
-/***
- * Wraps the KlarnaPaymentView so we can see when a requestLayout() has been triggered.
- */
-public class PaymentViewWrapper extends LinearLayout implements HeightListener.HeightListenerCallback {
- private float displayDensity = 1;
- public KlarnaPaymentView paymentView;
- private boolean loadCalled = false;
- private HeightListener heightListener;
-
- public PaymentViewWrapper(ReactApplicationContext context, AttributeSet attrs) {
- super(context, attrs);
- // Get density for resizing.
- displayDensity = context.getResources().getDisplayMetrics().density;
- // Add KlarnaPaymentView
- LinearLayout.LayoutParams webViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
- paymentView = new KlarnaPaymentView(getReactAppContext().getCurrentActivity(), attrs); // Insure we use activity and not application context for dialogs.
- addView(paymentView, webViewParams);
- heightListener = new HeightListener(getPaymentViewWebView(), this);
- }
-
- public void load(String sessionData) {
- paymentView.load(sessionData);
- loadCalled = true;
- heightListener.injectListener(getPaymentViewWebView());
- }
-
- @Override
- public void requestLayout() {
- super.requestLayout();
- if (isReady() && loadCalled) {
- heightListener.fetchHeight(getPaymentViewWebView());
- }
- }
-
- /**
- * The web view inside the KlarnaPaymentView will trigger requestLayout(), but there is no way
- * to get the KlarnaPaymentView's correct height.
- *
- * Attempts include:
- * - Using Android's measure() and co. methods
- * - Getting the WebView's getContentHeight()
- * - Using a variety of layout listeners.
- *
- * So instead we're:
- * 1. Evaluating some JS (yes, making things even more fragile).
- * 2. Triggering a size change via the UIManagerModule. This will effectively apply a fixed size
- * via width and height style attributes on the React side of things.
- *
- * Note: We can apply style by setting props with uimm.updateView() to just set a height (and
- * no width), but it doesn't update immediately or with the right height.
- *
- * The width will be whatever the parent component's width is.
- */
- private void setHeight(String height) {
- if (height == null || height.equals("null") || height.equals("undefined")) {
- return;
- }
- try {
- final int width = getParentViewWidth();
- final float contentHeight = Float.parseFloat(height);
- final float scaledHeight = contentHeight * displayDensity;
- getReactAppContext().runOnNativeModulesQueueThread(new GuardedRunnable(getReactAppContext()) {
- @Override
- public void runGuarded() {
- UIManagerModule uimm = getReactAppContext().getNativeModule(UIManagerModule.class);
- uimm.updateNodeSize(getId(), width, (int) scaledHeight);
- }
- });
- } catch (Throwable t) {
- }
- }
-
- /**
- * Returns true if the payment view is part of the hierarchy (the first requestLayout() is
- * triggered before) and the whole view is part of the RN hierarchy.
- *
- * @return true if ready
- */
- private boolean isReady() {
- return paymentView != null && getId() != -1;
- }
-
- /**
- * Returns the parent view's width.
- */
- private int getParentViewWidth() {
- View parentReactView = (View) getParent();
- if (parentReactView == null || !(parentReactView instanceof View)) {
- return 0;
- }
- return parentReactView.getWidth();
- }
-
- /**
- * Attempts to retrieve the web view from within the KlarnaPaymentView. This is really fragile.
- */
- private WebView getPaymentViewWebView() {
- for (int i = 0; i < paymentView.getChildCount(); i++) {
- View child = paymentView.getChildAt(i);
-
- if (child instanceof WebView) {
- return (WebView) child;
- }
- }
- return null;
- }
-
- /**
- * Returns the app context the wrapper was initialized with.
- */
- private ReactApplicationContext getReactAppContext() {
- return (ReactApplicationContext) getContext();
- }
-
- @Override
- public void onNewHeight(String value) {
- setHeight(value);
- }
-}
diff --git a/android/src/main/java/com/klarna/mobile/sdk/reactnative/KlarnaPaymentViewPackage.java b/android/src/main/java/com/klarna/mobile/sdk/reactnative/KlarnaPaymentViewPackage.java
new file mode 100644
index 00000000..58c9f13e
--- /dev/null
+++ b/android/src/main/java/com/klarna/mobile/sdk/reactnative/KlarnaPaymentViewPackage.java
@@ -0,0 +1,29 @@
+package com.klarna.mobile.sdk.reactnative;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+
+import com.facebook.react.ReactPackage;
+import com.facebook.react.bridge.NativeModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.uimanager.ViewManager;
+import com.klarna.mobile.sdk.reactnative.payments.KlarnaPaymentViewManager;
+
+import java.util.Collections;
+import java.util.List;
+
+public class KlarnaPaymentViewPackage implements ReactPackage {
+
+ @NonNull
+ @Override
+ public List createNativeModules(@NonNull ReactApplicationContext reactContext) {
+ return Collections.emptyList();
+ }
+
+ @NonNull
+ @Override
+ public List createViewManagers(@NonNull ReactApplicationContext reactContext) {
+ return List.of(new KlarnaPaymentViewManager(reactContext, (Application) reactContext.getApplicationContext()));
+ }
+}
diff --git a/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/ArgumentsUtil.java b/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/ArgumentsUtil.java
new file mode 100644
index 00000000..e4165545
--- /dev/null
+++ b/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/ArgumentsUtil.java
@@ -0,0 +1,62 @@
+package com.klarna.mobile.sdk.reactnative.common;
+
+import com.facebook.react.bridge.Arguments;
+import com.facebook.react.bridge.ReadableArray;
+import com.facebook.react.bridge.ReadableMap;
+import com.facebook.react.bridge.WritableArray;
+import com.facebook.react.bridge.WritableMap;
+
+import java.util.List;
+import java.util.Map;
+
+public class ArgumentsUtil {
+
+ public static WritableMap createMap(Map sourceMap) {
+ WritableMap map = Arguments.createMap();
+ for (Map.Entry entry : sourceMap.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (value == null) {
+ map.putNull(key);
+ } else if (value instanceof Boolean) {
+ map.putBoolean(key, (Boolean) value);
+ } else if (value instanceof String) {
+ map.putString(key, (String) value);
+ } else if (value instanceof Integer) {
+ map.putInt(key, (Integer) value);
+ } else if (value instanceof Double) {
+ map.putDouble(key, (Double) value);
+ } else if (value instanceof ReadableArray) {
+ map.putArray(key, (ReadableArray) value);
+ } else if (value instanceof ReadableMap) {
+ map.putMap(key, (ReadableMap) value);
+ }
+ }
+ return map;
+ }
+
+ public static WritableArray createArray(List> sourceList) {
+ WritableArray array = Arguments.createArray();
+ if (sourceList != null && sourceList.size() > 0) {
+ for (int i = 0; i < sourceList.size(); i++) {
+ Object value = sourceList.get(i);
+ if (value == null) {
+ array.pushNull();
+ } else if (value instanceof Boolean) {
+ array.pushBoolean((Boolean) value);
+ } else if (value instanceof String) {
+ array.pushString((String) value);
+ } else if (value instanceof Integer) {
+ array.pushInt((Integer) value);
+ } else if (value instanceof Double) {
+ array.pushDouble((Double) value);
+ } else if (value instanceof ReadableArray) {
+ array.pushArray((ReadableArray) value);
+ } else if (value instanceof ReadableMap) {
+ array.pushMap((ReadableMap) value);
+ }
+ }
+ }
+ return array;
+ }
+}
diff --git a/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/WebViewResizeObserver.java b/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/WebViewResizeObserver.java
new file mode 100644
index 00000000..f71ce18b
--- /dev/null
+++ b/android/src/main/java/com/klarna/mobile/sdk/reactnative/common/WebViewResizeObserver.java
@@ -0,0 +1,100 @@
+package com.klarna.mobile.sdk.reactnative.common;
+
+import android.os.Build;
+import android.webkit.JavascriptInterface;
+import android.webkit.WebView;
+
+import java.lang.ref.WeakReference;
+
+public class WebViewResizeObserver {
+ /**
+ * The interface between the wrapper and listener class
+ * to send the updated height values
+ */
+ public interface WebViewResizeObserverCallback {
+ void onResized(int value);
+ }
+
+ private static final String JS_INTERFACE_NAME = "NativeResizeObserver";
+ private final WeakReference callback;
+
+ public WebViewResizeObserver(WebViewResizeObserverCallback callback) {
+ this.callback = new WeakReference<>(callback);
+ }
+
+ public void addInterface(WebView webView) {
+ webView.addJavascriptInterface(this, JS_INTERFACE_NAME);
+ }
+
+ public void injectListener(WebView webView) {
+ injectScript(webView, initScript());
+ }
+
+ /**
+ * The javascript interface method that is called when there's a
+ * 'resize' event
+ *
+ * @param value The height value which is sent from the 'resize' listener
+ */
+ @JavascriptInterface
+ public void onResized(int value) {
+ sendHeightValue(value);
+ }
+
+ /**
+ * Unwraps and null checks the callback object and sends
+ * the height value to wrapper through this callback
+ *
+ * @param value The updated height value to send to wrapper
+ */
+ private void sendHeightValue(int value) {
+ WebViewResizeObserverCallback callbackInstance = callback.get();
+ if (callbackInstance != null) {
+ callbackInstance.onResized(value);
+ }
+ }
+
+ private void injectScript(WebView webView, String script) {
+ String tryCatchScript = "try {\n" +
+ " " + script + "\n" +
+ "} catch (error) {\n" +
+ " console.error(\"inject failed\")\n" +
+ "}";
+ evaluateJSCompat(webView, tryCatchScript);
+ }
+
+ /**
+ * Evaluates a script inside a web view in a backward-compatible manner
+ *
+ * @param webView The web view to evaluate the script
+ * @param script The script to be evaluated
+ */
+ private void evaluateJSCompat(WebView webView, String script) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ webView.evaluateJavascript(script, null);
+ } else {
+ webView.loadUrl("javascript:" + script);
+ }
+ }
+
+ private String initScript() {
+ return "const container = document.querySelector('#payment-container');\n" +
+ "const resizeObserver = new ResizeObserver((entries) => {\n" +
+ " for (let entry of entries) {\n" +
+ " console.log('New dimensions found: ', entry);\n" +
+ " if (entry.contentRect) {\n" +
+ " const height = entry.contentRect.height;\n" +
+ " const listener = window.NativeResizeObserver;\n" +
+ " if (listener != null) {\n" +
+ " listener.onResized(height);\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " console.log('Container size changed');\n" +
+ "});\n" +
+ "if (container != null) {\n" +
+ " resizeObserver.observe(container);\n" +
+ "}\n" +
+ "console.log('Resize observer initialized');";
+ }
+}
diff --git a/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentEvent.java b/android/src/main/java/com/klarna/mobile/sdk/reactnative/payments/KlarnaPaymentEvent.java
similarity index 69%
rename from android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentEvent.java
rename to android/src/main/java/com/klarna/mobile/sdk/reactnative/payments/KlarnaPaymentEvent.java
index 3e309503..de04c768 100644
--- a/android/src/main/java/com/klarna/inapp/sdk/KlarnaPaymentEvent.java
+++ b/android/src/main/java/com/klarna/mobile/sdk/reactnative/payments/KlarnaPaymentEvent.java
@@ -1,4 +1,4 @@
-package com.klarna.inapp.sdk;
+package com.klarna.mobile.sdk.reactnative.payments;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
@@ -7,14 +7,10 @@
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.Event;
-import com.facebook.react.uimanager.events.RCTEventEmitter;
-
-import java.util.HashMap;
-import java.util.Map;
/**
* A `KlarnaPaymentEvent` builds the event that will be eventually sent via `on`.
- *
+ *
* It consists of a flat JSON object with a single `name` parameter for the event name as well as
* other, optional parameters depending on the function that was called.
*/
@@ -27,14 +23,15 @@ public class KlarnaPaymentEvent extends Event {
public static final String EVENT_NAME_ON_REAUTHORIZE = "onReauthorized";
public static final String EVENT_NAME_ON_FINALIZE = "onFinalized";
public static final String EVENT_NAME_ON_ERROR = "onError";
+ public static final String EVENT_NAME_ON_RESIZED = "onResized";
@NonNull
private final String eventName;
@Nullable
- private final Map additionalParams;
+ private final WritableMap additionalParams;
- public KlarnaPaymentEvent(@IdRes int viewId, @NonNull String eventName, @Nullable Map additionalParams) {
+ public KlarnaPaymentEvent(@IdRes int viewId, @NonNull String eventName, @Nullable WritableMap additionalParams) {
super(viewId);
this.eventName = eventName;
this.additionalParams = additionalParams;
@@ -45,19 +42,12 @@ public String getEventName() {
return eventName;
}
- /**
- * Composes and sends the event JSON object being sent up to JS.
- * @param rctEventEmitter
- */
+ @Nullable
@Override
- public void dispatch(RCTEventEmitter rctEventEmitter) {
- Map map = new HashMap<>();
-
+ protected WritableMap getEventData() {
if (additionalParams != null) {
- map.putAll(additionalParams);
+ return additionalParams;
}
-
- WritableMap eventData = Arguments.makeNativeMap(map);
- rctEventEmitter.receiveEvent(getViewTag(), getEventName(), eventData);
+ return Arguments.createMap();
}
}
diff --git a/android/src/main/java/com/klarna/mobile/sdk/reactnative/payments/KlarnaPaymentViewManager.java b/android/src/main/java/com/klarna/mobile/sdk/reactnative/payments/KlarnaPaymentViewManager.java
new file mode 100644
index 00000000..95614c58
--- /dev/null
+++ b/android/src/main/java/com/klarna/mobile/sdk/reactnative/payments/KlarnaPaymentViewManager.java
@@ -0,0 +1,346 @@
+package com.klarna.mobile.sdk.reactnative.payments;
+
+import android.app.Application;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactContext;
+import com.facebook.react.bridge.ReadableArray;
+import com.facebook.react.bridge.ReadableMap;
+import com.facebook.react.bridge.WritableMap;
+import com.facebook.react.common.MapBuilder;
+import com.facebook.react.uimanager.ThemedReactContext;
+import com.facebook.react.uimanager.UIManagerHelper;
+import com.facebook.react.uimanager.annotations.ReactProp;
+import com.facebook.react.uimanager.events.EventDispatcher;
+import com.klarna.mobile.sdk.api.payments.KlarnaPaymentView;
+import com.klarna.mobile.sdk.api.payments.KlarnaPaymentViewCallback;
+import com.klarna.mobile.sdk.api.payments.KlarnaPaymentsSDKError;
+import com.klarna.mobile.sdk.reactnative.common.ArgumentsUtil;
+import com.klarna.mobile.sdk.reactnative.common.WebViewResizeObserver;
+import com.klarna.mobile.sdk.reactnative.spec.RNKlarnaPaymentViewSpec;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Wraps the Payment Views being exposed to JS.
+ */
+public class KlarnaPaymentViewManager extends RNKlarnaPaymentViewSpec implements KlarnaPaymentViewCallback, PaymentViewWrapper.OnResizedListener {
+
+ // Commands that can be triggered from RN
+ public static final String COMMAND_INITIALIZE = "initialize";
+ public static final String COMMAND_LOAD = "load";
+ public static final String COMMAND_LOAD_PAYMENT_REVIEW = "loadPaymentReview";
+ public static final String COMMAND_AUTHORIZE = "authorize";
+ public static final String COMMAND_REAUTHORIZE = "reauthorize";
+ public static final String COMMAND_FINALIZE = "finalize";
+
+ public static final String REACT_CLASS = "RNKlarnaPaymentView";
+
+ private final ReactApplicationContext reactAppContext;
+
+ // Store a list of views to event dispatchers so we send up events via the right views.
+ private final Map, EventDispatcher> viewToDispatcher;
+
+ public KlarnaPaymentViewManager(ReactApplicationContext reactApplicationContext, Application app) {
+ super();
+ this.viewToDispatcher = new HashMap<>();
+ this.reactAppContext = reactApplicationContext;
+ }
+
+ @NonNull
+ @Override
+ public String getName() {
+ return REACT_CLASS;
+ }
+
+ @NonNull
+ @Override
+ public PaymentViewWrapper createViewInstance(@NonNull ThemedReactContext context) {
+ PaymentViewWrapper view = new PaymentViewWrapper(reactAppContext, null, this, this);
+
+ // Each view has its own event dispatcher.
+ EventDispatcher dispatcher = UIManagerHelper.getEventDispatcherForReactTag((ReactContext) view.getContext(), view.getId());
+ viewToDispatcher.put(new WeakReference<>(view), dispatcher);
+
+ return view;
+ }
+
+ /**
+ * Handles commands received from RN to a specific view.
+ *
+ * @param root view receiving the command
+ * @param commandId identifier of the command
+ * @param args array of command arguments
+ */
+ @Override
+ public void receiveCommand(@NonNull PaymentViewWrapper root, String commandId, @Nullable ReadableArray args) {
+ String sessionData = null;
+
+ switch (commandId) {
+ case COMMAND_INITIALIZE:
+ if (args != null && args.size() > 0) {
+ final String token = args.getString(0);
+ String returnUrl = null;
+ if (args.size() > 1) {
+ returnUrl = args.getString(1);
+ }
+ initialize(root, token, returnUrl);
+ }
+ break;
+
+ case COMMAND_LOAD:
+ if (args != null && args.size() > 0) {
+ sessionData = args.getString(0);
+ }
+ load(root, sessionData);
+ break;
+
+ case COMMAND_LOAD_PAYMENT_REVIEW:
+ loadPaymentReview(root);
+ break;
+
+ case COMMAND_AUTHORIZE:
+ boolean autoFinalize = true;
+ if (args != null && args.size() > 0) {
+ autoFinalize = args.getBoolean(0);
+ if (args.size() > 1) {
+ sessionData = args.getString(1);
+ }
+ }
+ authorize(root, autoFinalize, sessionData);
+ break;
+
+ case COMMAND_REAUTHORIZE:
+ if (args != null && args.size() > 0) {
+ sessionData = args.getString(0);
+ }
+ reauthorize(root, sessionData);
+ break;
+
+ case COMMAND_FINALIZE:
+ if (args != null && args.size() > 0) {
+ sessionData = args.getString(0);
+ }
+ finalize(root, sessionData);
+ break;
+ }
+ }
+
+ /**
+ * Exposes direct event types that will be accessible as prop "callbacks" from RN.
+ *