diff --git a/MIGRATION_0.1.9-0.2.0.md b/MIGRATION_0.1.9-0.2.0.md new file mode 100644 index 0000000..bf78553 --- /dev/null +++ b/MIGRATION_0.1.9-0.2.0.md @@ -0,0 +1,55 @@ +# Migration Guide: v0.1.9 → v0.2.0 + +## Breaking Changes + +### Import Syntax Changes + +**Before (v0.1.9):** +```js +import TSAccountProtectionSDKModule, { TSAccountProtectionSDK } from 'react-native-ts-accountprotection'; +``` + +**After (v0.2.0):** +```js +import { + initializeSDKIOS, + setUserId, + triggerAction, + clearUser, + setLogLevel, + TSAction, + type TSActionEventOptions +} from 'react-native-ts-accountprotection'; +``` + +### API Usage Changes + +| Function | Before | After | +|----------|--------|-------| +| Initialize iOS | `TSAccountProtectionSDKModule.initializeSDKIOS()` | `initializeSDKIOS()` | +| Set User ID | `TSAccountProtectionSDKModule.setUserId(id)` | `setUserId(id)` | +| Trigger Action | `TSAccountProtectionSDKModule.triggerAction(...)` | `triggerAction(...)` | +| Clear User | `TSAccountProtectionSDKModule.clearUser()` | `clearUser()` | +| Set Log Level | `TSAccountProtectionSDKModule.setLogLevel(...)` | `setLogLevel(...)` | + +### Type Reference Changes + +| Type | Before | After | +|------|--------|-------| +| Actions | `TSAccountProtectionSDK.TSAction.login` | `TSAction.login` | +| Event Options | `TSAccountProtectionSDK.TSActionEventOptions` | `TSActionEventOptions` | +| Response | `TSAccountProtectionSDK.TSSetActionResponse` | `TSSetActionResponse` | + +## Quick Migration Steps + +1. **Update imports** - Replace the old import with individual named imports +2. **Remove module prefix** - Remove `TSAccountProtectionSDKModule.` from all function calls +3. **Update type references** - Remove `TSAccountProtectionSDK.` namespace from type references +4. **Add type imports** - Import types with `type` keyword for TypeScript projects + +## Benefits + +- ✅ Tree-shaking support for smaller bundle sizes +- ✅ Cleaner, more intuitive API +- ✅ Better TypeScript intellisense +- ✅ Follows React Native community standards diff --git a/README.md b/README.md index af6caea..5fc5906 100644 --- a/README.md +++ b/README.md @@ -91,11 +91,11 @@ First, [Create](https://developer.transmitsecurity.com/guides/risk/quick_start_i Next initialize the SDK when your app component is ready ```js -import TSAccountProtectionSDKModule, { TSAccountProtectionSDK } from 'react-native-ts-accountprotection'; +import { initializeSDKIOS } from 'react-native-ts-accountprotection'; componentDidMount(): void { // Setup the module as soon your component is ready - await TSAccountProtectionSDKModule.initializeSDKIOS(); + await initializeSDKIOS(); } ``` @@ -103,14 +103,18 @@ componentDidMount(): void { #### Set UserID after authentication ```js -await TSAccountProtectionSDKModule.setUserId(username); +import { setUserId } from 'react-native-ts-accountprotection'; + +await setUserId(username); ``` #### Trigger Action ```js +import { triggerAction, TSAction } from 'react-native-ts-accountprotection'; + private handleTriggerActionLoginExample = async () => { - const triggerActionResponse = await TSAccountProtectionSDKModule.triggerAction( - TSAccountProtectionSDK.TSAction.login, + const triggerActionResponse = await triggerAction( + TSAction.login, { correlationId: "CORRELATION_ID", claimUserId: "CLAIM_USER_ID", @@ -125,14 +129,18 @@ private handleTriggerActionLoginExample = async () => { #### Clear User ID ```js -await TSAccountProtectionSDKModule.clearUser(); +import { clearUser } from 'react-native-ts-accountprotection'; + +await clearUser(); ``` #### Set Log Level (Optional) Enable or disable SDK debug logging: ```js -await TSAccountProtectionSDKModule.setLogLevel(true); // Enable debug logging -await TSAccountProtectionSDKModule.setLogLevel(false); // Disable debug logging +import { setLogLevel } from 'react-native-ts-accountprotection'; + +await setLogLevel(true); // Enable debug logging +await setLogLevel(false); // Disable debug logging ``` ## Important diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6faa9f6..234eb17 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,50 @@ # Release Notes +## Version 0.2.0 + +### 🚀 Major API Refactor - Breaking Changes + +This release introduces a significant improvement to the module's API design, transitioning from a mixed export pattern to clean named exports. This change aligns with modern React Native best practices and provides a better developer experience. + +### Breaking Changes +- **Removed default export**: The module no longer exports a default class instance +- **Eliminated namespace**: All types previously under `TSAccountProtectionSDK` namespace are now direct exports +- **Updated import syntax**: Imports now use named imports instead of mixed default + named imports +- **Simplified type references**: Types no longer require namespace prefixes + +### API Changes + +**Before:** +```js +import TSAccountProtectionSDKModule, { TSAccountProtectionSDK } from 'react-native-ts-accountprotection'; + +await TSAccountProtectionSDKModule.initializeIOS(clientId); +await TSAccountProtectionSDKModule.triggerAction(TSAccountProtectionSDK.TSAction.login, options); +``` + +**After:** +```js +import { initializeIOS, triggerAction, TSAction } from 'react-native-ts-accountprotection'; + +await initializeIOS(clientId); +await triggerAction(TSAction.login, options); +``` + +### Benefits +- **Tree-shaking support**: Enables better bundle optimization and smaller app sizes +- **Cleaner imports**: More intuitive and concise import statements +- **Better IntelliSense**: Improved TypeScript auto-completion and code navigation +- **Modern standards**: Follows current React Native community best practices +- **Simplified usage**: No more verbose namespace references + +### Migration +A complete migration guide is available in `MIGRATION_0.1.9-0.2.0.md` with step-by-step instructions for updating your existing code. + +### Technical Details +- Removed wrapper class layer for direct native module access +- Streamlined type definitions without nested namespaces +- Maintained full API functionality while improving ergonomics + ## Version 0.1.9 ### Breaking Changes (iOS only) diff --git a/android/build.gradle b/android/build.gradle index e10dc2d..55c0353 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -92,7 +92,7 @@ dependencies { // 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.ts.sdk:accountprotection:2.2.4") + implementation("com.ts.sdk:accountprotection:2.2.5") implementation "com.facebook.react:react-native:+" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" } diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index f9cf7c5..970d624 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,6 +1,6 @@ PODS: - - AccountProtection (0.0.8006): - - TSCoreSDK (~> 0.2.8000) + - AccountProtection (2.2.0): + - TSCoreSDK (~> 1.1.0) - boost (1.83.0) - DoubleConversion (1.1.6) - FBLazyVector (0.73.5) @@ -889,7 +889,7 @@ PODS: - glog - React-debug - react-native-ts-accountprotection (0.1.9): - - AccountProtection (= 0.0.8006) + - AccountProtection (= 2.2.0) - glog - RCT-Folly (= 2022.05.16.00) - React-Core @@ -1061,7 +1061,7 @@ PODS: - React-logger (= 0.73.5) - React-perflogger (= 0.73.5) - SocketRocket (0.6.1) - - TSCoreSDK (0.2.8000) + - TSCoreSDK (1.1.2) - Yoga (1.14.0) DEPENDENCIES: @@ -1228,7 +1228,7 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/yoga" SPEC CHECKSUMS: - AccountProtection: 9e330dd72fe0eb1c0854d496994944cfdbca1251 + AccountProtection: 32e1d95047bd7a183c6877a21b91dff2ed9223cb boost: d3f49c53809116a5d38da093a8aa78bf551aed09 DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953 FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d @@ -1258,7 +1258,7 @@ SPEC CHECKSUMS: React-jsinspector: 32db5e364bcae8fca8cdf8891830636275add0c5 React-logger: 4136cd22748f4275b04bf82f7b6853ba93b5e0e3 React-Mapbuffer: ee9b45b26e759a099a3e024df50b25af390ee998 - react-native-ts-accountprotection: c8de4b1d1821ddc843b940fe96df4f8104fe9e52 + react-native-ts-accountprotection: 5e32039e0dfe0d7c1f39ac4d398a9b6ad47d9b9d React-nativeconfig: 1166714a4f7ea57a0df5c2cb44fbc70f98d580f9 React-NativeModulesApple: d4a50e6739e201716bc90178c143d019c8e09c36 React-perflogger: 0dd9f1725d55f8264b81efadd373fe1d9cca7dc2 @@ -1280,7 +1280,7 @@ SPEC CHECKSUMS: React-utils: c89ba7cfbcc24a54c229928aa971a2539f5bdc21 ReactCommon: 878d3e9687f81294648a1d025b91ecde7e22179e SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - TSCoreSDK: 62d65a01ebde7c0bfe889582cbc6edffa3f09568 + TSCoreSDK: 4f470f7de900589db07d9ff2967b5d733fe1be1d Yoga: a716eea57d0d3430219c0a5a233e1e93ee931eb7 PODFILE CHECKSUM: f4bf8cd8d354e08c7c833a720648a16bd26f7e54 diff --git a/example/src/App.tsx b/example/src/App.tsx index 23771cb..473fb83 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -2,7 +2,15 @@ import * as React from 'react'; import { SafeAreaView, Keyboard, Alert, Platform } from 'react-native'; -import TSAccountProtectionSDKModule, { TSAccountProtectionSDK } from 'react-native-ts-accountprotection'; +import { + initializeIOS, + setUserId, + setLogLevel, + clearUser, + triggerAction, + TSAction, + type TSActionEventOptions +} from 'react-native-ts-accountprotection'; import MockServer from './mock-server'; import Login from './screens/login'; @@ -72,11 +80,11 @@ export default class App extends React.Component { private onAppReady = async (): Promise => { // this is for iOS only, Android TSAccountProtectionSDK is initialized from application onCreate. if (Platform.OS === 'ios') { - await TSAccountProtectionSDKModule.initializeIOS(config.clientId, null); + await initializeIOS(config.clientId, null); } const isLogEnabled = true; - await TSAccountProtectionSDKModule.setLogLevel(isLogEnabled); + await setLogLevel(isLogEnabled); } // Authentication @@ -84,7 +92,7 @@ export default class App extends React.Component { private handleLogin = async (username: string, password: string) => { Keyboard.dismiss() this.setState({ isLoading: true }); - await TSAccountProtectionSDKModule.setUserId(username); + await setUserId(username); setTimeout(async () => { this.navigateToAuthenticatedUserScreen(); @@ -103,7 +111,7 @@ export default class App extends React.Component { private onLogout = async () => { Keyboard.dismiss() this.setState({ isLoading: true }); - await TSAccountProtectionSDKModule.clearUser(); + await clearUser(); this.setState({ isLoading: false, currentScreen: AppScreen.Login @@ -117,8 +125,8 @@ export default class App extends React.Component { this.setState({ isLoading: true }); try { - const triggerActionResponse = await TSAccountProtectionSDKModule.triggerAction( - `${TSAccountProtectionSDK.TSAction.transaction}`, + const triggerActionResponse = await triggerAction( + `${TSAction.transaction}`, this.convertMoneyTransferDTOToEventOptions(requestDTO) ); @@ -141,8 +149,8 @@ export default class App extends React.Component { } private handleTriggerActionLoginExample = async () => { - const triggerActionResponse = await TSAccountProtectionSDKModule.triggerAction( - TSAccountProtectionSDK.TSAction.login, + const triggerActionResponse = await triggerAction( + TSAction.login, { correlationId: "CORRELATION_ID", claimUserId: "CLAIM_USER_ID", @@ -154,8 +162,8 @@ export default class App extends React.Component { console.log("Action Token: ", actionToken); } - private convertMoneyTransferDTOToEventOptions = (requestDTO: MoneyTransferDTO): TSAccountProtectionSDK.TSActionEventOptions => { - const options: TSAccountProtectionSDK.TSActionEventOptions = { + private convertMoneyTransferDTOToEventOptions = (requestDTO: MoneyTransferDTO): TSActionEventOptions => { + const options: TSActionEventOptions = { transactionData: { amount: parseFloat(requestDTO.amount), currency: 'USD', diff --git a/example/src/screens/authenticated-user.tsx b/example/src/screens/authenticated-user.tsx index 590eea2..b4857b7 100644 --- a/example/src/screens/authenticated-user.tsx +++ b/example/src/screens/authenticated-user.tsx @@ -1,5 +1,5 @@ import React, { type ReactElement } from 'react'; -import { Text, TextInput, Button, StyleSheet, View } from 'react-native'; +import { Text, TextInput, TouchableOpacity, StyleSheet, View, ScrollView, StatusBar } from 'react-native'; import type { MoneyTransferDTO } from '../App'; interface AuthenticatedUserProps { @@ -29,69 +29,122 @@ export class AuthenticatedUser extends React.Component - - {"DRS Example"} - {this.renderHeading()} - {this.renderInputFields()} - {this.renderSubmitButton()} - {this.renderLogoutButton()} - - ); - } + + + {/* Header */} + + + + Welcome back + {this.props.userId} + + this.props.onLogout()} + activeOpacity={0.8} + > + Sign Out + + + - private renderSubmitButton(): ReactElement { - return ( - -