com-tapp-so-sdk 0.1.0

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.
Files changed (35) hide show
  1. package/ComTappSoSdk.podspec +50 -0
  2. package/LICENSE +20 -0
  3. package/README.md +263 -0
  4. package/android/build.gradle +114 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/com/comtappsosdk/ComTappSoSdkModule.kt +354 -0
  8. package/android/src/main/java/com/comtappsosdk/ComTappSoSdkPackage.kt +45 -0
  9. package/ios/ComTappSoSdk.h +62 -0
  10. package/ios/ComTappSoSdk.mm +343 -0
  11. package/ios/generated/ComTappSoSdkSpec/ComTappSoSdkSpec-generated.mm +81 -0
  12. package/ios/generated/ComTappSoSdkSpec/ComTappSoSdkSpec.h +84 -0
  13. package/ios/generated/ComTappSoSdkSpecJSI-generated.cpp +76 -0
  14. package/ios/generated/ComTappSoSdkSpecJSI.h +125 -0
  15. package/lib/module/NativeComTappSoSdk.js +5 -0
  16. package/lib/module/NativeComTappSoSdk.js.map +1 -0
  17. package/lib/module/Types.js +47 -0
  18. package/lib/module/Types.js.map +1 -0
  19. package/lib/module/events.js +17 -0
  20. package/lib/module/events.js.map +1 -0
  21. package/lib/module/index.js +58 -0
  22. package/lib/module/index.js.map +1 -0
  23. package/lib/typescript/src/NativeComTappSoSdk.d.ts +37 -0
  24. package/lib/typescript/src/NativeComTappSoSdk.d.ts.map +1 -0
  25. package/lib/typescript/src/Types.d.ts +145 -0
  26. package/lib/typescript/src/Types.d.ts.map +1 -0
  27. package/lib/typescript/src/events.d.ts +10 -0
  28. package/lib/typescript/src/events.d.ts.map +1 -0
  29. package/lib/typescript/src/index.d.ts +13 -0
  30. package/lib/typescript/src/index.d.ts.map +1 -0
  31. package/package.json +169 -0
  32. package/src/NativeComTappSoSdk.ts +46 -0
  33. package/src/Types.ts +149 -0
  34. package/src/events.ts +21 -0
  35. package/src/index.tsx +81 -0
@@ -0,0 +1,50 @@
1
+ require "json"
2
+
3
+ # Define the minimum iOS version supported
4
+ min_ios_version_supported = "13.0"
5
+
6
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
7
+ folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
8
+
9
+ Pod::Spec.new do |s|
10
+ s.name = "ComTappSoSdk"
11
+ s.version = package["version"]
12
+ s.summary = package["description"]
13
+ s.homepage = package["homepage"]
14
+ s.license = package["license"]
15
+ s.authors = package["author"]
16
+
17
+ s.platforms = { :ios => min_ios_version_supported }
18
+ s.source = { :git => "https://www.tapp.so/.git", :tag => "#{s.version}" }
19
+
20
+ # Conditionally include source files.
21
+ # In legacy mode (RCT_NEW_ARCH_ENABLED != '1') exclude files in the generated folder.
22
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1'
23
+ s.source_files = "ios/**/*.{h,m,mm,cpp}"
24
+ else
25
+ s.source_files = Dir.glob("ios/**/*.{h,m,mm,cpp}").reject { |path| path.include?("generated") }
26
+ end
27
+
28
+ # Use install_modules_dependencies helper if available (RN >= 0.71.0).
29
+ if respond_to?(:install_modules_dependencies, true)
30
+ install_modules_dependencies(s)
31
+ else
32
+ s.dependency "React-Core"
33
+
34
+ # If the new architecture is enabled, add extra dependencies and flags.
35
+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1'
36
+ s.compiler_flags = "#{folly_compiler_flags} -DRCT_NEW_ARCH_ENABLED=1"
37
+ s.pod_target_xcconfig = {
38
+ "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
39
+ "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
40
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
41
+ }
42
+ s.dependency "React-Codegen"
43
+ s.dependency "RCT-Folly"
44
+ s.dependency "RCTRequired"
45
+ s.dependency "RCTTypeSafety"
46
+ s.dependency "ReactCommon/turbomodule/core"
47
+ end
48
+ end
49
+ s.dependency "Tapp"
50
+ end
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tapp.so
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,263 @@
1
+ # Tapp React Native SDK
2
+
3
+ The official React Native SDK for [Tapp](https://www.tapp.so/) — the growth and attribution platform for modern apps.
4
+
5
+ ![npm version](https://img.shields.io/npm/v/com-tapp-so-sdk)
6
+ ![license](https://img.shields.io/npm/l/com-tapp-so-sdk)
7
+ ![platform](https://img.shields.io/badge/platform-ios%20%7C%20android-lightgrey)
8
+
9
+ ## Overview
10
+
11
+ The Tapp React Native SDK allows you to integrate Tapp's powerful attribution and event tracking into your iOS and Android applications. With this SDK, you can:
12
+
13
+ - **Track Events**: Monitor user actions like purchases, registrations, and custom interactions.
14
+ - **Deep Linking**: Handle deferred deep links to attribute installs and route users to specific content.
15
+ - **Affiliate Integration**: Generate dynamic tracking URLs for influencers and partners.
16
+ - **Cross-Platform Support**: Seamlessly unified API for both iOS and Android.
17
+
18
+ ## Features
19
+
20
+ - 🚀 **Easy Initialization**: Single configuration step for both platforms.
21
+ - 📊 **Event Tracking**: 40+ predefined event types plus support for custom events.
22
+ - 🔗 **Deep Linking**: Robust support for direct and deferred deep linking.
23
+ - 🌐 **Affiliate URL Generation**: Create tracking links programmatically.
24
+ - ⚡ **TurboModules Support**: Ready for React Native's New Architecture.
25
+
26
+ ## Requirements
27
+
28
+ - **React Native**: >= 0.70.0
29
+ - **iOS**: 13.0+
30
+ - **Android**: 5.0+ (API Level 21+)
31
+ - **TypeScript**: 5.0+ (recommended)
32
+
33
+ ## Installation
34
+
35
+ 1. Install the package using `yarn` or `npm`:
36
+
37
+ ```sh
38
+ yarn add com-tapp-so-sdk
39
+ # or
40
+ npm install com-tapp-so-sdk
41
+ ```
42
+
43
+ 2. **iOS Only**: Install CocoaPods dependencies.
44
+
45
+ ```sh
46
+ cd ios && pod install
47
+ ```
48
+
49
+ 3. **Android**: No extra steps required (auto-linked).
50
+
51
+ ## Configuration
52
+
53
+ To start using the SDK, you need to initialize it with your unique **App Token** and **Auth Token** from the [Tapp Dashboard](https://dashboard.tapp.so).
54
+
55
+ It is recommended to initialize the SDK early in your app's lifecycle, such as in your root App component `useEffect`.
56
+
57
+ ```tsx
58
+ import React, { useEffect } from 'react';
59
+ import { start } from 'com-tapp-so-sdk';
60
+
61
+ const App = () => {
62
+ useEffect(() => {
63
+ start({
64
+ authToken: 'YOUR_AUTH_TOKEN',
65
+ tappToken: 'YOUR_TAPP_TOKEN',
66
+ env: 'SANDBOX', // or 'PRODUCTION'
67
+ });
68
+ }, []);
69
+
70
+ return <YourAppContent />;
71
+ };
72
+ ```
73
+
74
+ > **Note**: Use `env: 'SANDBOX'` for development/testing and change to `'PRODUCTION'` for App Store/Play Store builds.
75
+
76
+ ## Usage
77
+
78
+ ### 1. Tracking Events
79
+
80
+ Track standard or custom events to measure user engagement and campaign performance.
81
+
82
+ **Standard Event:**
83
+
84
+ ```tsx
85
+ import { handleTappEvent, EventAction } from 'com-tapp-so-sdk';
86
+
87
+ // Track a "Purchase" event
88
+ await handleTappEvent({
89
+ eventAction: EventAction.TAPP_PURCHASE,
90
+ metadata: {
91
+ price: 29.99,
92
+ currency: 'USD',
93
+ product_id: 'prod_123',
94
+ success: true,
95
+ },
96
+ });
97
+ ```
98
+
99
+ **Custom Event:**
100
+
101
+ ```tsx
102
+ // Track a custom event with a specific name
103
+ await handleTappEvent({
104
+ eventAction: EventAction.CUSTOM,
105
+ customValue: 'my_custom_action',
106
+ metadata: {
107
+ level_achieved: 5,
108
+ score: 1200,
109
+ },
110
+ });
111
+ ```
112
+
113
+ ### 2. Deep Linking & Attribution
114
+
115
+ Retrieve attribution data when your app is opened via a Tapp link.
116
+
117
+ **Fetch Deferred Link Data (First Launch):**
118
+
119
+ ```tsx
120
+ import { fetchOriginLinkData } from 'com-tapp-so-sdk';
121
+
122
+ const checkAttribution = async () => {
123
+ const result = await fetchOriginLinkData();
124
+
125
+ if (!result.error) {
126
+ console.log('Attribution Data:', result.data);
127
+ console.log('Campaign:', result.data?.campaign);
128
+ console.log('Is First Session:', result.isFirstSession);
129
+ } else {
130
+ // Note: This is NOT a fatal error, just means no attribution data was found or config is empty
131
+ console.log('Attribution Info:', result.message);
132
+ }
133
+ };
134
+ ```
135
+
136
+ **Handling Deep Links (Runtime):**
137
+
138
+ ```tsx
139
+ import { Linking } from 'react-native';
140
+ import { fetchLinkData, shouldProcess } from 'com-tapp-so-sdk';
141
+
142
+ // In your deep link handler
143
+ const handleUrl = async (url: string) => {
144
+ // shouldProcess is async to support both architectures safely
145
+ const canProcess = await shouldProcess(url);
146
+
147
+ if (canProcess) {
148
+ const linkData = await fetchLinkData(url);
149
+ if (!linkData.error) {
150
+ console.log('Tapp Deep Link Data:', linkData);
151
+ console.log('Target Content:', linkData.tappUrl);
152
+ }
153
+ } else {
154
+ // Handle standard deep link
155
+ }
156
+ };
157
+
158
+ // Listen for incoming links
159
+ Linking.addEventListener('url', ({ url }) => handleUrl(url));
160
+ ```
161
+
162
+ ### 3. Generate Affiliate URLs
163
+
164
+ Create shareable tracking links for your users (e.g., "Invite a Friend").
165
+
166
+ ```tsx
167
+ import { url } from 'com-tapp-so-sdk';
168
+
169
+ const generateInviteLink = async () => {
170
+ try {
171
+ const inviteLink = await url(
172
+ 'user_123', // Influencer/User ID
173
+ 'summer_promo', // Ad Group (optional)
174
+ 'banner_v1', // Creative (optional)
175
+ { source: 'app_share' } // Custom Data (optional)
176
+ );
177
+ console.log('Share this link:', inviteLink);
178
+ } catch (error) {
179
+ console.error('Failed to generate link:', error);
180
+ }
181
+ };
182
+ ```
183
+
184
+ ## API Reference
185
+
186
+ ### `start(config: InitConfig): void`
187
+
188
+ Initializes the SDK.
189
+
190
+ - `authToken`: Your API authentication token.
191
+ - `tappToken`: Your unique App token.
192
+ - `env`: `'PRODUCTION'` | `'SANDBOX'`.
193
+
194
+ ### `handleTappEvent(event: TappEventType): Promise<string>`
195
+
196
+ Tracks a user event.
197
+
198
+ - `eventAction`: One of `EventAction` enums (e.g., `TAPP_LOGIN`, `TAPP_PURCHASE`).
199
+ - `customValue`: String identifier for `EventAction.CUSTOM`.
200
+ - `metadata`: Object `{ [key: string]: string | number | boolean }`.
201
+
202
+ ### `fetchOriginLinkData(): Promise<TappLinkDataResponse>`
203
+
204
+ Fetches attribution data for the current installation/session (deferred deep linking).
205
+
206
+ **Response (`TappLinkDataResponse`):**
207
+ - `error`: `boolean` — Indicates if the SDK encountered an issue (e.g. network error).
208
+ - `message`: `string | null` — Error description or info message.
209
+ - `tappUrl`: `string | null` — The deep link URL.
210
+ - `attrTappUrl`: `string | null` — The attributed URL.
211
+ - `influencer`: `string | null` — The influencer associated with the link.
212
+ - `data`: `{ [key: string]: string }` — Custom link data (never null, empty object if none).
213
+ - `isFirstSession`: `boolean` — `true` if this is the first app launch.
214
+
215
+ ### `fetchLinkData(deepLink: string): Promise<TappLinkDataResponse>`
216
+
217
+ Resolves link data for a specific URL string (used for direct deep linking).
218
+
219
+ **Returns**: Same response shape as `fetchOriginLinkData`.
220
+
221
+ ### `shouldProcess(deepLink: string): Promise<boolean>`
222
+
223
+ Checks if the provided URL should be processed by the Tapp SDK.
224
+ Returns `true` if it matches Tapp domains/schemes, `false` otherwise.
225
+
226
+ ### `url(influencer: string, adGroup?: string, creative?: string, data?: object): Promise<string>`
227
+
228
+ Generates a tracking URL for the specified parameters.
229
+
230
+ ## SDK Guarantees
231
+
232
+ - **No Throw on Attribution**: `fetchOriginLinkData` and `fetchLinkData` do **not** reject (throw) for standard SDK states (e.g., empty config, no attribution, network error). They resolve an object with `error: true` and a `message`. You should check `response.error` instead of using `try/catch`.
233
+ - **Cross-Platform Consistency**: The response shapes for attribution data are identical on iOS and Android.
234
+ - **Null Safety**: Optional string fields (`tappUrl`, `influencer`) are returned as `null` (not `undefined` or empty strings) when no value is present, allowing for strict type checking.
235
+
236
+ ## Architecture Notes
237
+
238
+ ### React Native New Architecture (Fabric/TurboModules)
239
+
240
+ This SDK is fully compatible with React Native's New Architecture.
241
+ - **Android**: Supports TurboModules via C++ bindings.
242
+ - **iOS**: Fully implemented in Objective-C++ / Swift with TurboModule support enabled.
243
+
244
+ No additional configuration is required; the SDK automatically detects the architecture enabled in your project.
245
+
246
+ ## Troubleshooting
247
+
248
+ **iOS: Build Failures ("Swift compiler error" or "module not found")**
249
+ - Ensure your iOS deployment target is 13.0 or higher.
250
+ - Try cleaning pods: `cd ios && rm -rf Pods Podfile.lock && pod install`.
251
+ - Ensure you open the `.xcworkspace` file, not the `.xcodeproj`.
252
+
253
+ **Android: "SDK not initialized"**
254
+ - Ensure `start()` is called immediately upon app launch.
255
+ - Check that your `tappToken` matches the package name defined in the Tapp Dashboard.
256
+
257
+ **Events not showing in Dashboard**
258
+ - Check if `env` is set to `'SANDBOX'` while looking at live data (or vice versa).
259
+ - Verify internet connectivity on the device/simulator.
260
+
261
+ ## License
262
+
263
+ MIT License. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,114 @@
1
+ // android/build.gradle (library)
2
+
3
+ buildscript {
4
+ // Use project or root ext for Kotlin
5
+ def kotlin_version = rootProject.ext.has("kotlinVersion")
6
+ ? rootProject.ext.get("kotlinVersion")
7
+ : project.properties["ComTappSoSdk_kotlinVersion"]
8
+
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ maven { url 'https://jitpack.io' }
13
+ }
14
+ dependencies {
15
+ classpath "com.android.tools.build:gradle:7.2.1"
16
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
17
+ // React Native Gradle plugin is usually applied via the settings/build of the app;
18
+ // for a library we only need the 'com.facebook.react' plugin below.
19
+ }
20
+ }
21
+
22
+ // --- Helpers (kept from your template) ---
23
+ def getExtOrDefault(name) {
24
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["ComTappSoSdk_" + name]
25
+ }
26
+ def getExtOrIntegerDefault(name) {
27
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["ComTappSoSdk_" + name]).toInteger()
28
+ }
29
+ def supportsNamespace() {
30
+ def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
31
+ def major = parsed[0].toInteger()
32
+ def minor = parsed[1].toInteger()
33
+ // Namespace support added in 7.3.0
34
+ return (major == 7 && minor >= 3) || major >= 8
35
+ }
36
+ def isNewArchitectureEnabled() {
37
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
38
+ }
39
+
40
+ // --- Plugins ---
41
+ apply plugin: "com.android.library"
42
+ apply plugin: "kotlin-android"
43
+ apply plugin: "com.facebook.react" // always apply; don’t gate behind newArch
44
+
45
+ // --- React / Codegen (Android) ---
46
+ // IMPORTANT:
47
+ // - libraryName MUST be the npm package name (from package.json "name")
48
+ // - do NOT set codegenDir (use RN default: android/build/generated/source/codegen)
49
+ react {
50
+ libraryName = "com-tapp-so-sdk"
51
+ codegenJavaPackageName = "com.comtappsosdk"
52
+ // codegenDir = ... <-- DO NOT set; RN expects default path
53
+ }
54
+
55
+ android {
56
+ if (supportsNamespace()) {
57
+ namespace "com.comtappsosdk"
58
+ // If you use a non-standard manifest filename:
59
+ sourceSets {
60
+ main {
61
+ manifest.srcFile "src/main/AndroidManifestNew.xml"
62
+ }
63
+ }
64
+ }
65
+
66
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
67
+
68
+ defaultConfig {
69
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
70
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
71
+
72
+ // Keep New Arch toggle available at runtime/build time
73
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
74
+ // If you need NDK/CMake arch matrix, you can add abiFilters here (optional)
75
+ }
76
+
77
+ buildFeatures {
78
+ buildConfig true
79
+ }
80
+
81
+ buildTypes {
82
+ release {
83
+ minifyEnabled false
84
+ }
85
+ }
86
+
87
+ lintOptions {
88
+ disable "GradleCompatible"
89
+ }
90
+
91
+ compileOptions {
92
+ sourceCompatibility JavaVersion.VERSION_1_8
93
+ targetCompatibility JavaVersion.VERSION_1_8
94
+ }
95
+
96
+ // ❌ DO NOT point to custom generated folders; RN will generate under:
97
+ // android/build/generated/source/codegen/{java|jni}
98
+ // sourceSets { ... } <-- removed on purpose
99
+ }
100
+
101
+ repositories {
102
+ mavenCentral()
103
+ google()
104
+ maven { url 'https://jitpack.io' }
105
+ }
106
+ dependencies {
107
+ implementation "com.facebook.react:react-android"
108
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:${getExtOrDefault('kotlinVersion')}"
109
+
110
+ implementation("com.github.tapp-so.Tapp-Android:Tapp-Native:1.1.3")
111
+ }
112
+
113
+ // namespace "com.comtappsosdk"
114
+ //ComTappSoSdk
@@ -0,0 +1,5 @@
1
+ ComTappSoSdk_kotlinVersion=2.0.21
2
+ ComTappSoSdk_minSdkVersion=24
3
+ ComTappSoSdk_targetSdkVersion=34
4
+ ComTappSoSdk_compileSdkVersion=35
5
+ ComTappSoSdk_ndkVersion=27.1.12297006
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>