react-native-nami-sdk 3.4.0-dev.202604020517 → 3.4.0-dev.202605111922

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -85,8 +85,8 @@ dependencies {
85
85
  implementation fileTree(dir: 'libs', include: ['*.jar'])
86
86
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
87
87
 
88
- playImplementation "com.namiml:sdk-android:3.4.0-dev.202604020517"
89
- amazonImplementation "com.namiml:sdk-amazon:3.4.0-dev.202604020517"
88
+ playImplementation "com.namiml:sdk-android:3.4.0-dev.202605111922"
89
+ amazonImplementation "com.namiml:sdk-amazon:3.4.0-dev.202605111922"
90
90
 
91
91
  implementation "com.facebook.react:react-native:+" // From node_modules
92
92
  coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"
@@ -1,19 +1,24 @@
1
1
  package com.namiml.reactnative
2
2
 
3
- import com.facebook.react.bridge.*
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.Arguments
5
+ import com.facebook.react.bridge.Promise
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
8
+ import com.facebook.react.bridge.ReactMethod
9
+ import com.facebook.react.bridge.ReadableMap
4
10
  import com.facebook.react.module.annotations.ReactModule
5
11
  import com.facebook.react.turbomodule.core.interfaces.TurboModule
6
12
  import com.namiml.Nami
7
13
  import com.namiml.NamiConfiguration
8
14
  import com.namiml.NamiLanguageCode
9
15
  import com.namiml.NamiLogLevel
10
- import android.util.Log
11
16
 
12
17
  @ReactModule(name = NamiBridgeModule.NAME)
13
18
  class NamiBridgeModule internal constructor(
14
- private val context: ReactApplicationContext
15
- ) : ReactContextBaseJavaModule(context), TurboModule {
16
-
19
+ private val context: ReactApplicationContext,
20
+ ) : ReactContextBaseJavaModule(context),
21
+ TurboModule {
17
22
  companion object {
18
23
  const val NAME = "RNNami"
19
24
 
@@ -41,7 +46,10 @@ class NamiBridgeModule internal constructor(
41
46
  }
42
47
 
43
48
  @ReactMethod
44
- fun configure(configDict: ReadableMap, promise: Promise) {
49
+ fun configure(
50
+ configDict: ReadableMap,
51
+ promise: Promise,
52
+ ) {
45
53
  logNewArchitectureStatus()
46
54
 
47
55
  val appPlatformID = configDict.getString(CONFIG_MAP_PLATFORM_ID_KEY) ?: PLATFORM_ID_ERROR_VALUE
@@ -55,7 +63,8 @@ class NamiBridgeModule internal constructor(
55
63
  }
56
64
 
57
65
  if (configDict.hasKey(CONFIG_MAP_DEVELOPMENT_MODE_KEY) &&
58
- configDict.getBoolean(CONFIG_MAP_DEVELOPMENT_MODE_KEY)) {
66
+ configDict.getBoolean(CONFIG_MAP_DEVELOPMENT_MODE_KEY)
67
+ ) {
59
68
  builder.developmentMode = true
60
69
  }
61
70
 
@@ -79,9 +88,10 @@ class NamiBridgeModule internal constructor(
79
88
 
80
89
  context.runOnUiQueueThread {
81
90
  Nami.configure(builder.build()) { result ->
82
- val resultMap = Arguments.createMap().apply {
83
- putBoolean("success", result)
84
- }
91
+ val resultMap =
92
+ Arguments.createMap().apply {
93
+ putBoolean("success", result)
94
+ }
85
95
  promise.resolve(resultMap)
86
96
  }
87
97
  }
@@ -92,6 +102,19 @@ class NamiBridgeModule internal constructor(
92
102
  Log.d("RNNami", "New Architecture is ${if (isNewArch) "ENABLED" else "DISABLED"}")
93
103
  }
94
104
 
105
+ @ReactMethod
106
+ fun reset(promise: Promise) {
107
+ context.runOnUiQueueThread {
108
+ try {
109
+ Nami.reset(context.applicationContext)
110
+ promise.resolve(null)
111
+ } catch (e: Throwable) {
112
+ promise.reject("reset_failed", e)
113
+ }
114
+ }
115
+ }
116
+
95
117
  @ReactMethod fun addListener(eventName: String?) {}
118
+
96
119
  @ReactMethod fun removeListeners(count: Int?) {}
97
120
  }
@@ -11,6 +11,7 @@ export interface Spec extends TurboModule {
11
11
  }>;
12
12
  sdkConfigured(): Promise<boolean>;
13
13
  sdkVersion(): Promise<string>;
14
+ reset(): Promise<void>;
14
15
  }
15
16
  declare const _default: Spec;
16
17
  export default _default;
@@ -4,4 +4,5 @@ export declare const Nami: {
4
4
  sdkConfigured: () => Promise<boolean>;
5
5
  sdkVersion: () => Promise<string>;
6
6
  sdkPackageVersion: () => Promise<string>;
7
+ reset: () => Promise<void>;
7
8
  };
@@ -2,4 +2,4 @@
2
2
  * Auto-generated file. Do not edit manually.
3
3
  * React Native Nami SDK version.
4
4
  */
5
- export declare const NAMI_REACT_NATIVE_VERSION = "3.4.0-dev.202604020517";
5
+ export declare const NAMI_REACT_NATIVE_VERSION = "3.4.0-dev.202605111922";
package/ios/Nami.m CHANGED
@@ -17,6 +17,8 @@ RCT_EXTERN_METHOD(sdkConfigured:(RCTPromiseResolveBlock)resolve
17
17
 
18
18
  RCT_EXTERN_METHOD(sdkVersion:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
19
19
 
20
+ RCT_EXTERN_METHOD(reset:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
21
+
20
22
  + (BOOL)requiresMainQueueSetup {
21
23
  return NO;
22
24
  }
package/ios/Nami.swift CHANGED
@@ -92,6 +92,14 @@ class RNNami: NSObject {
92
92
  }
93
93
  }
94
94
 
95
+ @objc(reset:rejecter:)
96
+ func reset(resolve: @escaping RCTPromiseResolveBlock, reject _: @escaping RCTPromiseRejectBlock) {
97
+ Nami.reset()
98
+ DispatchQueue.main.async {
99
+ resolve(nil)
100
+ }
101
+ }
102
+
95
103
  func isNewArchitectureEnabled() -> Bool {
96
104
  #if RCT_NEW_ARCH_ENABLED
97
105
  return true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nami-sdk",
3
- "version": "3.4.0-dev.202604020517",
3
+ "version": "3.4.0-dev.202605111922",
4
4
  "description": "React Native SDK for Nami - No-code paywall and onboarding flows with A/B testing.",
5
5
  "main": "index.ts",
6
6
  "types": "dist/index.d.ts",
@@ -63,9 +63,15 @@
63
63
  ]
64
64
  },
65
65
  "peerDependencies": {
66
+ "@namiml/expo-nami-iap": "3.4.0-dev.202605111922",
66
67
  "react": ">=18",
67
68
  "react-native": ">=0.73"
68
69
  },
70
+ "peerDependenciesMeta": {
71
+ "@namiml/expo-nami-iap": {
72
+ "optional": true
73
+ }
74
+ },
69
75
  "devDependencies": {
70
76
  "@react-native/eslint-config": "^0.80.0",
71
77
  "@types/jest": "^29.5.2",
@@ -21,7 +21,7 @@ Pod::Spec.new do |s|
21
21
  s.requires_arc = true
22
22
  s.swift_version = '5.0' # or your supported version
23
23
 
24
- s.dependency 'Nami', '3.4.0-dev.202604020517'
24
+ s.dependency 'Nami', '3.4.0-dev.202605111922'
25
25
 
26
26
  pod_target_xcconfig = {
27
27
  'DEFINES_MODULE' => 'YES',
@@ -12,6 +12,7 @@ export interface Spec extends TurboModule {
12
12
 
13
13
  sdkConfigured(): Promise<boolean>;
14
14
  sdkVersion(): Promise<string>;
15
+ reset(): Promise<void>;
15
16
  }
16
17
 
17
18
  export default TurboModuleRegistry.getEnforcing<Spec>('RNNami');
package/src/Nami.ts CHANGED
@@ -37,4 +37,7 @@ export const Nami = {
37
37
  sdkPackageVersion: async (): Promise<string> => {
38
38
  return NAMI_REACT_NATIVE_VERSION;
39
39
  },
40
+ reset: async (): Promise<void> => {
41
+ return RNNami.reset();
42
+ },
40
43
  };
package/src/version.ts CHANGED
@@ -2,4 +2,4 @@
2
2
  * Auto-generated file. Do not edit manually.
3
3
  * React Native Nami SDK version.
4
4
  */
5
- export const NAMI_REACT_NATIVE_VERSION = '3.4.0-dev.202604020517';
5
+ export const NAMI_REACT_NATIVE_VERSION = '3.4.0-dev.202605111922';
package/ARCHITECTURE.md DELETED
@@ -1,166 +0,0 @@
1
- # React Native SDK Architecture
2
-
3
- The Nami React Native SDK (`react-native-nami-sdk`) is a TypeScript bridge layer that exposes native Android and iOS SDK functionality to React Native applications via TurboModules.
4
-
5
- ## Build System
6
-
7
- - **Language:** TypeScript 5 (strict mode), Kotlin (Android bridge), Swift (iOS bridge)
8
- - **Package Manager:** npm
9
- - **TypeScript Output:** Declaration files only (`emitDeclarationOnly`)
10
- - **Native Code Generation:** React Native Codegen (TurboModule specs)
11
- - **Linting:** ESLint with @react-native config, Prettier
12
-
13
- ### Native Dependencies
14
-
15
- | Platform | SDK |
16
- |----------|-----|
17
- | Android (Google Play) | `com.namiml:sdk-android` |
18
- | Android (Amazon) | `com.namiml:sdk-amazon` |
19
- | iOS/tvOS | `Nami` CocoaPod |
20
-
21
- ## Directory Structure
22
-
23
- ```
24
- sdk/react-native/
25
- ├── src/ # TypeScript bridge layer
26
- │ ├── index.ts # Main exports
27
- │ ├── types.ts # Type definitions
28
- │ ├── transformers.ts # Data transformation utilities
29
- │ ├── version.ts # Auto-generated version constant
30
- │ ├── Nami.ts # Core SDK initialization
31
- │ ├── NamiPaywallManager.ts # Paywall display/events
32
- │ ├── NamiCampaignManager.ts # Campaign management
33
- │ ├── NamiCustomerManager.ts # Customer identity
34
- │ ├── NamiEntitlementManager.ts # Entitlement access
35
- │ ├── NamiPurchaseManager.ts # Purchase operations
36
- │ ├── NamiFlowManager.ts # Flow management
37
- │ └── NamiOverlayControl.tsx # React component for overlay UI
38
- ├── specs/ # TurboModule native interface specs
39
- ├── android/ # Kotlin native bridge modules
40
- │ └── src/main/java/com/namiml/reactnative/
41
- ├── ios/ # Swift + Objective-C native bridge
42
- ├── dist/ # Built .d.ts type declarations
43
- ├── examples/
44
- │ ├── Basic/ # Full-featured sample (with Detox e2e)
45
- │ └── TestNamiTV/ # tvOS sample
46
- ├── build-utils/ # Version management scripts
47
- └── scripts/ # Version generation
48
- ```
49
-
50
- ## Bridge Architecture
51
-
52
- ```
53
- JavaScript (React Native)
54
- |
55
- TurboModule TypeScript Specs (/specs)
56
- |
57
- Native Bridge Modules (Kotlin + Swift)
58
- |
59
- Native SDKs (com.namiml:sdk-android / Nami CocoaPod)
60
- |
61
- Platform APIs (Google Play Billing / StoreKit)
62
- ```
63
-
64
- The React Native SDK is a **thin bridge** - it does NOT reimplement networking, IAP handling, paywall rendering, entitlement validation, or purchase tracking. All business logic lives in the native SDKs.
65
-
66
- ## Manager Classes
67
-
68
- Each TypeScript manager wraps a corresponding TurboModule:
69
-
70
- | Manager | Key Methods |
71
- |---------|-------------|
72
- | `Nami` | `configure()`, `sdkConfigured()`, `sdkVersion()` |
73
- | `NamiPaywallManager` | `buySkuComplete()`, handler registration (buy, close, sign-in, restore, deeplink) |
74
- | `NamiCampaignManager` | `launch()`, `allCampaigns()`, `isCampaignAvailable()`, `isFlow()`, `refresh()`, `getProductGroups()` |
75
- | `NamiCustomerManager` | `login()`, `logout()`, `journeyState()`, `setCustomerAttribute()`, `setAnonymousMode()`, `deviceId()` |
76
- | `NamiEntitlementManager` | `active()`, `isEntitlementActive()`, `refresh()`, `clearProvisionalEntitlementGrants()` |
77
- | `NamiPurchaseManager` | `allPurchases()`, `skuPurchased()`, `restorePurchases()`, `presentCodeRedemptionSheet()` |
78
- | `NamiFlowManager` | `pause()`, `resume()`, `finish()`, `isFlowOpen()`, `registerStepHandoff()` |
79
- | `NamiOverlayControl` | `presentOverlay()`, `finishOverlay()`, React `NamiOverlayHost` component |
80
-
81
- ## Native Bridge Modules
82
-
83
- ### Android (`android/` - Kotlin)
84
-
85
- - **NamiBridgePackage.java** - TurboReactPackage registering all modules
86
- - **NamiBridgeModule.kt** - `RNNami` core configuration
87
- - **NamiCampaignManagerBridgeModule.kt** - Campaign bridge
88
- - **NamiPaywallManagerBridgeModule.kt** - Paywall bridge
89
- - **NamiPurchaseManagerBridge.kt** - Purchase bridge
90
- - **NamiEntitlementManagerBridge.kt** - Entitlement bridge
91
- - **NamiCustomerManagerBridge.kt** - Customer bridge
92
- - **NamiFlowManagerBridge.kt** - Flow bridge
93
- - **NamiOverlayControlBridge.kt** - Overlay + ReactOverlayActivity
94
- - **NamiUtil.kt** - Data transformation (WritableMap/WritableArray)
95
-
96
- Android supports two product flavors: `play` (Google Play) and `amazon` (Amazon Appstore).
97
-
98
- ### iOS (`ios/` - Swift)
99
-
100
- Parallel Swift implementations for each bridge module, plus Objective-C `.m` files for Codegen/legacy architecture support.
101
-
102
- ## Type System (`src/types.ts`)
103
-
104
- Key types exported to consumers:
105
-
106
- - **NamiConfiguration** - SDK init params (appPlatformID, logLevel, language)
107
- - **NamiSKU** - Product details with platform-specific pricing (Apple, Google, Amazon)
108
- - **NamiPurchase** - Purchase record with timestamps, transaction IDs, source
109
- - **NamiEntitlement** - Entitlement with active purchases and related SKUs
110
- - **NamiCampaign** - Campaign metadata (name, rule type, form factors, segment)
111
- - **CustomerJourneyState** - Subscription lifecycle flags
112
- - **NamiPaywallEvent** - Comprehensive event (30+ actions)
113
- - **NamiPaywallAction** - Enum: BUY_SKU, SELECT_SKU, RESTORE_PURCHASES, VIDEO_STARTED, etc.
114
-
115
- ## Testing
116
-
117
- ### Unit Tests
118
-
119
- TypeScript unit tests using Jest + ts-jest, covering the pure data transformation layer in `src/transformers.ts`:
120
-
121
- - **`parsePurchaseDates`** — converts native timestamp numbers to JS Date objects
122
- - **`coerceSkuType`** — validates raw strings against `NamiSKUType` union, falls back to `'unknown'`
123
- - **`mapToNamiPaywallAction`** — validates raw strings against the `NamiPaywallAction` enum (28 values), falls back to `UNKNOWN`
124
- - **`parseEntitlements`** — transforms raw entitlement arrays, parsing nested purchase dates and defaulting missing SKU arrays
125
-
126
- ```bash
127
- # From monorepo root
128
- make test-react-native
129
-
130
- # Or directly
131
- cd sdk/react-native && npm test
132
- ```
133
-
134
- Test files live in `src/__tests__/` and are excluded from TypeScript compilation output via `tsconfig.json`.
135
-
136
- ### E2E Tests
137
-
138
- - Detox framework in `examples/Basic/e2e/` (iOS simulator + Android emulator)
139
- - CI via GitHub Actions with artifact upload on failure
140
-
141
- #### Local Native SDK Resolution
142
-
143
- In the monorepo, native SDKs may not yet be published when e2e tests run against a PR. The workflow resolves this by building native SDKs locally before the Detox build:
144
-
145
- **iOS** — The `NAMI_SDK_LOCAL_PATH` environment variable points to `sdk/apple/` in the monorepo. When set, each example app's Podfile overrides the published `Nami` CocoaPod with a local `:path` reference. CI builds the XCFramework first (`make build-apple`), then sets the env var so `pod install` picks up the local artifact.
146
-
147
- **Android** — CI publishes the SDK to `mavenLocal` via `./gradlew sdk:publishPublicGooglePublicationToMavenLocal sdk:publishPublicAmazonPublicationToMavenLocal`. The example app's `build.gradle` already includes `mavenLocal()` in its repository list, so Gradle resolves the local artifact without any code changes.
148
-
149
- Both approaches are temporary until dev release publishing is in place, at which point the pre-build steps and env var can be removed.
150
-
151
- ### Code Quality
152
-
153
- - ESLint + TypeScript compilation checks in CI
154
-
155
- ## Peer Dependencies
156
-
157
- - React >= 18
158
- - React Native >= 0.73
159
-
160
- ## Architectural Patterns
161
-
162
- - **Bridge/Adapter** - TypeScript wrappers over native TurboModules
163
- - **Event Emitter** - NativeEventEmitter for real-time native-to-JS events
164
- - **Thin Client** - All business logic delegated to native SDKs
165
- - **Codegen** - TurboModule specs for typed native module generation (New Architecture)
166
- - **Transformer** - Data conversion between native types and JS objects
package/CLAUDE.md DELETED
@@ -1,97 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Repository Overview
6
-
7
- This is the Nami React Native SDK (`react-native-nami-sdk`), a TypeScript bridge layer that exposes native Android and iOS SDK functionality to React Native applications via TurboModules. The SDK is a thin bridge — all business logic lives in the native Android and Apple SDKs.
8
-
9
- ## Development Setup
10
-
11
- ### Prerequisites
12
- - Node.js 20+
13
- - npm
14
- - For iOS bridge work: Xcode + CocoaPods
15
- - For Android bridge work: Android Studio with JDK 17
16
-
17
- ### Install dependencies
18
- ```bash
19
- cd sdk/react-native && npm install
20
- ```
21
-
22
- ## Build Commands
23
-
24
- ```bash
25
- # From monorepo root
26
- make build-react-native # Install npm dependencies
27
- make test-react-native # Run Jest unit tests
28
- make lint-react-native # Run pre-commit + ktlint checks
29
- ```
30
-
31
- ```bash
32
- # Directly
33
- cd sdk/react-native
34
- npm test # Run Jest unit tests
35
- npm run lint # ESLint
36
- ```
37
-
38
- ## Project Structure
39
-
40
- - `src/` — TypeScript bridge layer (managers, types, transformers)
41
- - `specs/` — TurboModule native interface specs (Codegen)
42
- - `android/` — Kotlin native bridge modules
43
- - `ios/` — Swift + Objective-C native bridge
44
- - `dist/` — Built `.d.ts` type declarations (`emitDeclarationOnly`)
45
- - `examples/Basic/` — Full-featured sample app with Detox e2e tests
46
- - `examples/TestNamiTV/` — tvOS sample app
47
- - `build-utils/` — Version management scripts
48
-
49
- ## Architecture
50
-
51
- The SDK is a **thin bridge** — no business logic lives here. TypeScript managers wrap TurboModules; TurboModules call into the native Android/Apple SDKs.
52
-
53
- ```
54
- JavaScript (React Native)
55
-
56
- TypeScript Managers (src/)
57
-
58
- TurboModule Specs (specs/)
59
-
60
- Native Bridge Modules (android/ + ios/)
61
-
62
- Native SDKs (com.namiml:sdk-android / Nami CocoaPod)
63
- ```
64
-
65
- ### Adding or changing bridge methods
66
-
67
- 1. Update the TurboModule spec in `specs/` (TypeScript interface)
68
- 2. Update the TypeScript manager in `src/`
69
- 3. Update the Kotlin bridge module in `android/`
70
- 4. Update the Swift bridge module in `ios/`
71
- 5. Run `npm run lint` and `make test-react-native` before committing
72
-
73
- ## Testing
74
-
75
- ### Unit Tests (Jest + ts-jest)
76
- Tests cover the pure data transformation layer in `src/transformers.ts` and live in `src/__tests__/`.
77
-
78
- ```bash
79
- make test-react-native
80
- # or: cd sdk/react-native && npm test
81
- ```
82
-
83
- ### E2E Tests (Detox)
84
- Located in `examples/Basic/e2e/`. Run via CI. See `ARCHITECTURE.md` for local native SDK resolution setup required before running e2e locally.
85
-
86
- ## Code Quality
87
-
88
- - **ESLint** (`@react-native` config) + **Prettier** for TypeScript
89
- - **ktlint** for Kotlin bridge code — run `ktlint -F` on changed `.kt` files before committing
90
- - Pre-commit hooks via `.pre-commit-config.yaml`
91
-
92
- ## Key Files
93
-
94
- - `src/index.ts` — Main exports
95
- - `src/types.ts` — All public TypeScript types
96
- - `src/transformers.ts` — Data transformation between native and JS types (unit-tested)
97
- - `specs/` — TurboModule specs (source of truth for the native bridge contract)