Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/e2e_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ jobs:
ADYEN_CLIENT_KEY: ${{ secrets.ADYEN_CLIENT_KEY }}
ADYEN_PUBLIC_KEY: ${{ secrets.ADYEN_PUBLIC_KEY }}
ANDROID_API_LEVEL: 35
APPIUM_VERSION: '3.4.2'
APPIUM_UIAUTOMATOR2_VERSION: '7.5.2'

steps:
- name: Download Fixture
Expand All @@ -177,8 +179,8 @@ jobs:

- name: Setup Appium
run: |
npm i -g appium
appium driver install uiautomator2
npm i -g appium@${{ env.APPIUM_VERSION }}
appium driver install uiautomator2@${{ env.APPIUM_UIAUTOMATOR2_VERSION }}

- name: Start Appium
run: bash ./start_appium.sh 4723 30
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v24.13.0
10 changes: 10 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@ ruby ">= 2.6.10"

# Exclude problematic versions of cocoapods and activesupport that causes build failures.
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
gem 'xcodeproj', '< 1.26.0'
gem 'concurrent-ruby', '< 1.3.4'

# Ruby 3.4.0 has removed some libraries from the standard library.
gem 'bigdecimal'
gem 'logger'
gem 'benchmark'
gem 'mutex_m'
gem 'nkf'
6 changes: 3 additions & 3 deletions docs/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ src/
Supported events are read from the native module's `getConstants().supportedEvents` at construction time.

```
NativeModule (react-native)
NativeModule (local interface, extends TurboModule)
EventListenerWrapper<T> # Abstract - manages event subscriptions
Expand Down Expand Up @@ -164,8 +164,8 @@ ActionModuleWrapper # implements Action
SessionWrapper # implements SessionHelperModule
- createSession(session, config) → Promise<SessionContext>
- hide(success, option?)
- onComplete(callback) → EmitterSubscription
- onError(callback) → EmitterSubscription
- assignCompletionHandler(callback) → EventSubscription
- assignErrorHandler(callback) → EventSubscription
- removeAllListeners()

AdyenCSEModuleWrapper # implements AdyenCSEModule
Expand Down
2 changes: 2 additions & 0 deletions e2e-tests/helpers/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ async function createDriver() {
'appium:appPackage': androidAppPackage,
'appium:appActivity': androidAppActivity,
'appium:newCommandTimeout': 120,
'appium:uiautomator2ServerInstallTimeout': 60000,
'appium:uiautomator2ServerLaunchTimeout': 60000,
}
: {
'platformName': 'iOS',
Expand Down
10 changes: 10 additions & 0 deletions e2e-tests/scripts/build-android.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ echo "::group::Launch App [$(date '+%H:%M:%S')]"
adb shell am start -n "$APP_PACKAGE/.MainActivity"
echo "::endgroup::"

echo "::group::Pre-install Appium APKs [$(date '+%H:%M:%S')]"
SETTINGS_APK=$(find ~/.appium -name "settings_apk-debug.apk" 2>/dev/null | head -1)
if [ -n "$SETTINGS_APK" ]; then
echo "Installing io.appium.settings from: $SETTINGS_APK"
adb install -r -t "$SETTINGS_APK" || echo "Warning: settings APK install failed, Appium will retry"
else
echo "Warning: settings_apk-debug.apk not found under ~/.appium"
fi
echo "::endgroup::"

echo "::group::Run Appium Tests [$(date '+%H:%M:%S')]"
export PLATFORM_NAME=android
export APP_PACKAGE
Expand Down
10 changes: 10 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ export default defineConfig([
'prettier/prettier': ['error'],
},
},
{
// Spec files use deep imports intentionally for backward compatibility
// with RN 0.76-0.79, where the top-level import is not supported by
// @react-native/babel-plugin-codegen. The deep path is deprecated but
// functional across the full supported range (>=0.76).
files: ['src/specs/**'],
rules: {
'@react-native/no-deep-imports': 'off',
},
},
{
ignores: ['node_modules/', 'lib/'],
},
Expand Down
8 changes: 4 additions & 4 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
buildscript {
ext {
buildToolsVersion = "35.0.0"
buildToolsVersion = "36.0.0"
minSdkVersion = 24
compileSdkVersion = 35
targetSdkVersion = 34
compileSdkVersion = 36
targetSdkVersion = 36
ndkVersion = "27.1.12297006"
kotlinVersion = "2.0.21"
kotlinVersion = "2.1.20"
}
repositories {
google()
Expand Down
7 changes: 6 additions & 1 deletion example/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,9 @@ newArchEnabled=true

# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
hermesEnabled=true

# Use this property to enable edge-to-edge display support.
# This allows your app to draw behind system bars for an immersive UI.
# Note: Only works with ReactActivity and should not be used with custom Activity.
edgeToEdgeEnabled=false
2 changes: 1 addition & 1 deletion example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
20 changes: 10 additions & 10 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@
"@react-native-async-storage/async-storage": "^2.1.2",
"@react-navigation/native": "^7.0.9",
"@react-navigation/native-stack": "^7.3.3",
"react": "19.0.0",
"react-native": "^0.78.0",
"react": "19.2.3",
"react-native": "0.85.0",
"react-native-safe-area-context": "^5.4.1",
"react-native-screens": "4.11.1"
"react-native-screens": "4.25.2"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "15.0.1",
"@react-native-community/cli-platform-android": "15.0.1",
"@react-native-community/cli-platform-ios": "15.0.1",
"@react-native/babel-preset": "^0.78.2",
"@react-native/metro-config": "^0.78.2",
"@react-native/typescript-config": "^0.78.2",
"@react-native-community/cli": "~20.1.0",
"@react-native-community/cli-platform-android": "~20.1.0",
"@react-native-community/cli-platform-ios": "~20.1.0",
"@react-native/babel-preset": "0.85.0",
"@react-native/metro-config": "0.85.0",
"@react-native/typescript-config": "0.85.0",
"@types/react": "^19.0.0",
"react-native-builder-bob": "^0.40.17"
"react-native-builder-bob": "^0.41.0"
},
"engines": {
"node": ">=18"
Expand Down
16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@
"@eslint/js": "^9.39.2",
"@expo/config-plugins": "^10.0.2",
"@react-native-community/cli": "15.0.1",
"@react-native/babel-preset": "^0.78.2",
"@react-native/eslint-config": "^0.78.0",
"@react-native/babel-preset": "0.85.0",
"@react-native/eslint-config": "0.85.0",
"@react-native/jest-preset": "0.85.0",
"@types/jest": "^29.5.5",
"@types/react": "^19.0.0",
"eslint": "^9.39.2",
Expand All @@ -72,15 +73,16 @@
"husky": "^9.0.11",
"jest": "^29.7.0",
"prettier": "^3.8.1",
"react": "19.0.0",
"react-native": "0.78.3",
"react-native-builder-bob": "^0.40.17",
"typescript": "^5.2.2"
"react": "19.2.3",
"react-native": "0.85.0",
"react-native-builder-bob": "^0.41.0",
"react-test-renderer": "19.2.3",
"typescript": "^6.0.3"
},
"peerDependencies": {
"expo": ">=52",
"react": "*",
"react-native": "*"
"react-native": ">=0.76.0"
},
"peerDependenciesMeta": {
"expo": {
Expand Down
4 changes: 2 additions & 2 deletions src/modules/action/ActionModuleWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { NativeModule } from 'react-native';
import type { TurboModule } from 'react-native';
import type {
BaseConfiguration,
PaymentAction,
Expand All @@ -7,7 +7,7 @@ import type {
import type { ActionModule } from './AdyenAction';

/** Native module interface specific to Action */
interface ActionNativeModule extends NativeModule {
interface ActionNativeModule extends TurboModule {
handle(
action: PaymentAction,
configuration: BaseConfiguration
Expand Down
11 changes: 10 additions & 1 deletion src/modules/base/EventListenerWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import type { NativeModule } from 'react-native';
import type { TurboModule } from 'react-native';
import { Event } from '../../core';

/**
* Minimal interface for native modules used as NativeEventEmitter sources.
* Extends TurboModule (New Architecture) and adds the event emitter contract.
*/
export interface NativeModule extends TurboModule {
addListener: (eventType: string) => void;
removeListeners: (count: number) => void;
}

/** Extended NativeModule interface with optional getConstants */
export interface NativeModuleWithConstants extends NativeModule {
getConstants?: () => { supportedEvents?: string[] };
Expand Down
4 changes: 2 additions & 2 deletions src/modules/cse/AdyenCSEModuleWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { NativeModule } from 'react-native';
import type { TurboModule } from 'react-native';
import type { Card } from './types';
import type { AdyenCSEModule } from './AdyenCSEModule';

/** Native module interface specific to CSE */
interface CSENativeModule extends NativeModule, AdyenCSEModule {}
interface CSENativeModule extends TurboModule, AdyenCSEModule {}

export class AdyenCSEWrapper implements AdyenCSEModule {
private readonly nativeModule: CSENativeModule;
Expand Down
6 changes: 4 additions & 2 deletions src/modules/embedded/EmbeddedComponentProxy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { NativeModule } from 'react-native';
import type {
AdyenActionComponent,
AddressLookup,
Expand All @@ -7,7 +6,10 @@ import type {
PaymentAction,
Event,
} from '../../core';
import type { AdyenEventListener } from '../base/EventListenerWrapper';
import type {
AdyenEventListener,
NativeModule,
} from '../base/EventListenerWrapper';
import type { EmbeddedComponentBusWrapper } from './EmbeddedComponentBusWrapper';

/**
Expand Down
10 changes: 4 additions & 6 deletions src/modules/session/SessionHelperModule.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NativeModules, type EmitterSubscription } from 'react-native';
import { NativeModules, type EventSubscription } from 'react-native';
import type {
AdyenComponent,
AdyenError,
Expand Down Expand Up @@ -29,16 +29,14 @@ export interface SessionHelperModule extends AdyenComponent {
*/
assignCompletionHandler(
callback: (result: SessionsResult) => void
): EmitterSubscription;
): EventSubscription;

/**
* Subscribe to session error events.
* @param callback - Called when the session fails with an error.
* @returns EmitterSubscription that can be used to remove the listener.
* @returns EventSubscription that can be used to remove the listener.
*/
assignErrorHandler(
callback: (error: AdyenError) => void
): EmitterSubscription;
assignErrorHandler(callback: (error: AdyenError) => void): EventSubscription;

/**
* Remove all session event listeners.
Expand Down
24 changes: 10 additions & 14 deletions src/modules/session/SessionWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
type NativeModule,
type EmitterSubscription,
NativeEventEmitter,
} from 'react-native';
import { NativeEventEmitter } from 'react-native';
import type { EventSubscription } from 'react-native';
import type { NativeModule } from '../base/EventListenerWrapper';
import {
Event,
type AdyenComponent,
Expand All @@ -26,7 +24,7 @@ interface SessionNativeModule extends NativeModule, AdyenComponent {
export class SessionWrapper implements SessionHelperModule {
private readonly nativeModule: SessionNativeModule;
private readonly eventEmitter: NativeEventEmitter;
private readonly subscriptions: Map<string, EmitterSubscription> = new Map();
private readonly subscriptions: Map<string, EventSubscription> = new Map();

constructor(nativeModule: SessionNativeModule) {
this.nativeModule = nativeModule;
Expand All @@ -47,15 +45,15 @@ export class SessionWrapper implements SessionHelperModule {
/**
* Subscribe to session completion events.
* @param callback - Called when the session completes successfully.
* @returns EmitterSubscription that can be used to remove the listener.
* @returns EventSubscription that can be used to remove the listener.
*/
assignCompletionHandler(
callback: (result: SessionsResult) => void
): EmitterSubscription {
): EventSubscription {
this.subscriptions.get(Event.onSessionComplete)?.remove();
const subscription = this.eventEmitter.addListener(
Event.onSessionComplete,
callback
(event) => callback(event)
);
Comment thread
descorp marked this conversation as resolved.
this.subscriptions.set(Event.onSessionComplete, subscription);
return subscription;
Expand All @@ -64,15 +62,13 @@ export class SessionWrapper implements SessionHelperModule {
/**
* Subscribe to session error events.
* @param callback - Called when the session fails with an error.
* @returns EmitterSubscription that can be used to remove the listener.
* @returns EventSubscription that can be used to remove the listener.
*/
assignErrorHandler(
callback: (error: AdyenError) => void
): EmitterSubscription {
assignErrorHandler(callback: (error: AdyenError) => void): EventSubscription {
this.subscriptions.get(Event.onSessionError)?.remove();
const subscription = this.eventEmitter.addListener(
Event.onSessionError,
callback
(event) => callback(event)
);
Comment thread
descorp marked this conversation as resolved.
this.subscriptions.set(Event.onSessionError, subscription);
return subscription;
Expand Down
Loading
Loading