@snowplow/react-native-tracker 1.4.0 → 2.0.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.
- package/.editorconfig +15 -0
- package/.eslintignore +6 -0
- package/.gitattributes +3 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/actions/setup/action.yml +28 -0
- package/.github/workflows/build.yml +150 -0
- package/.github/workflows/deploy.yml +98 -0
- package/.github/workflows/e2e-android.yml +121 -0
- package/.github/workflows/e2e-ios.yml +90 -0
- package/.github/workflows/snyk.yml +21 -0
- package/.gitignore +70 -0
- package/.npmignore +60 -0
- package/.nvmrc +1 -0
- package/.watchmanconfig +1 -0
- package/.yarnrc +3 -0
- package/CHANGELOG +166 -0
- package/CONTRIBUTING.md +80 -0
- package/README.md +23 -110
- package/android/build.gradle +93 -37
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +1 -2
- package/android/gradle.properties +5 -2
- package/android/gradlew +172 -110
- package/android/gradlew.bat +24 -19
- package/android/src/main/AndroidManifest.xml +1 -3
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/snowplow/reactnativetracker/ReactNativeTrackerModule.kt +704 -0
- package/android/src/main/java/com/snowplow/reactnativetracker/ReactNativeTrackerPackage.kt +17 -0
- package/android/src/main/java/com/snowplow/reactnativetracker/util/ConfigUtil.kt +271 -0
- package/android/src/main/java/com/snowplow/reactnativetracker/util/EventUtil.kt +213 -0
- package/android/src/main/java/com/snowplow/reactnativetracker/util/TrackerVersion.kt +5 -0
- package/babel.config.js +3 -0
- package/example/.watchmanconfig +1 -0
- package/example/Gemfile +6 -0
- package/example/android/app/build.gradle +129 -0
- package/example/android/app/debug.keystore +0 -0
- package/example/android/app/proguard-rules.pro +10 -0
- package/example/android/app/src/androidTest/java/com/reactnativetrackerexample/DetoxTest.java +36 -0
- package/example/android/app/src/androidTest/java/com/reactnativetrackerexample/DetoxTestAppJUnitRunner.java +21 -0
- package/example/android/app/src/debug/AndroidManifest.xml +13 -0
- package/example/android/app/src/debug/java/com/reactnativetrackerexample/ReactNativeFlipper.java +75 -0
- package/example/android/app/src/main/AndroidManifest.xml +26 -0
- package/example/android/app/src/main/java/com/reactnativetrackerexample/MainActivity.java +32 -0
- package/example/android/app/src/main/java/com/reactnativetrackerexample/MainApplication.java +62 -0
- package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +36 -0
- package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/values/strings.xml +3 -0
- package/example/android/app/src/main/res/values/styles.xml +9 -0
- package/example/android/app/src/release/java/com/reactnativetrackerexample/ReactNativeFlipper.java +20 -0
- package/example/android/build.gradle +31 -0
- package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/example/android/gradle/wrapper/gradle-wrapper.properties +6 -0
- package/example/android/gradle.properties +44 -0
- package/example/android/gradlew +244 -0
- package/example/android/gradlew.bat +92 -0
- package/example/android/settings.gradle +4 -0
- package/example/app.json +4 -0
- package/example/babel.config.js +17 -0
- package/example/detox.config.js +92 -0
- package/example/e2e/config.json +10 -0
- package/example/e2e/emitEvents.e2e.detox.js +108 -0
- package/example/e2e/environment.js +23 -0
- package/example/e2e/helpers/microCommands.js +153 -0
- package/example/e2e/helpers/microHelpers.js +346 -0
- package/example/e2e/helpers/microHelpers.test.js +308 -0
- package/example/e2e/helpers/schemas.js +62 -0
- package/example/e2e/jest.config.js +16 -0
- package/example/e2e/setup.js +4 -0
- package/example/e2e/testEvents.micro.test.js +300 -0
- package/example/index.js +5 -0
- package/example/ios/.xcode.env +11 -0
- package/example/ios/Podfile +64 -0
- package/example/ios/Podfile.lock +737 -0
- package/example/ios/ReactNativeTrackerExample/AppDelegate.h +6 -0
- package/example/ios/ReactNativeTrackerExample/AppDelegate.mm +26 -0
- package/example/ios/ReactNativeTrackerExample/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- package/example/ios/ReactNativeTrackerExample/Images.xcassets/Contents.json +6 -0
- package/example/ios/ReactNativeTrackerExample/Info.plist +55 -0
- package/example/ios/ReactNativeTrackerExample/LaunchScreen.storyboard +47 -0
- package/example/ios/ReactNativeTrackerExample/main.m +10 -0
- package/example/ios/ReactNativeTrackerExample-Bridging-Header.h +3 -0
- package/example/ios/ReactNativeTrackerExample.xcodeproj/project.pbxproj +722 -0
- package/{ios/RNSnowplowTracker.xcodeproj/xcshareddata/xcschemes/RNSnowplowTracker.xcscheme → example/ios/ReactNativeTrackerExample.xcodeproj/xcshareddata/xcschemes/ReactNativeTrackerExample.xcscheme} +29 -21
- package/example/ios/ReactNativeTrackerExample.xcworkspace/contents.xcworkspacedata +10 -0
- package/example/ios/ReactNativeTrackerExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/example/ios/ReactNativeTrackerExampleTests/Info.plist +24 -0
- package/example/ios/ReactNativeTrackerExampleTests/ReactNativeTrackerExampleTests.m +66 -0
- package/example/metro.config.js +45 -0
- package/example/package.json +54 -0
- package/example/react-native.config.js +10 -0
- package/example/src/App.js +557 -0
- package/example/tsconfig.json +5 -0
- package/example/yarn.lock +7379 -0
- package/ios/ReactNativeTracker-Bridging-Header.h +2 -0
- package/ios/ReactNativeTracker.mm +165 -0
- package/ios/ReactNativeTracker.swift +757 -0
- package/ios/{RNSnowplowTracker.xcodeproj → ReactNativeTracker.xcodeproj}/project.pbxproj +55 -79
- package/ios/Util/ConfigUtils.swift +206 -0
- package/ios/Util/TrackerVersion.swift +3 -0
- package/ios/Util/Utilities.swift +37 -0
- package/lefthook.yml +11 -0
- package/lib/commonjs/api.js +475 -0
- package/lib/commonjs/api.js.map +1 -0
- package/lib/commonjs/configurations.js +209 -0
- package/lib/commonjs/configurations.js.map +1 -0
- package/lib/commonjs/constants.js +85 -0
- package/lib/commonjs/constants.js.map +1 -0
- package/lib/commonjs/events.js +256 -0
- package/lib/commonjs/events.js.map +1 -0
- package/lib/commonjs/index.js +141 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/jsCore.js +393 -0
- package/lib/commonjs/jsCore.js.map +1 -0
- package/lib/commonjs/native.js +29 -0
- package/lib/commonjs/native.js.map +1 -0
- package/lib/commonjs/subject.js +248 -0
- package/lib/commonjs/subject.js.map +1 -0
- package/lib/commonjs/tracker.js +221 -0
- package/lib/commonjs/tracker.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/commonjs/utils.js +85 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/commonjs/webViewInterface.js +79 -0
- package/lib/commonjs/webViewInterface.js.map +1 -0
- package/lib/module/api.js +439 -0
- package/lib/module/api.js.map +1 -0
- package/lib/module/configurations.js +197 -0
- package/lib/module/configurations.js.map +1 -0
- package/lib/module/constants.js +80 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/events.js +240 -0
- package/lib/module/events.js.map +1 -0
- package/lib/module/index.js +129 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/jsCore.js +390 -0
- package/lib/module/jsCore.js.map +1 -0
- package/lib/module/native.js +25 -0
- package/lib/module/native.js.map +1 -0
- package/lib/module/subject.js +235 -0
- package/lib/module/subject.js.map +1 -0
- package/lib/module/tracker.js +209 -0
- package/lib/module/tracker.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/module/utils.js +79 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/module/webViewInterface.js +75 -0
- package/lib/module/webViewInterface.js.map +1 -0
- package/lib/typescript/__tests__/api.test.d.ts +2 -0
- package/lib/typescript/__tests__/api.test.d.ts.map +1 -0
- package/lib/typescript/__tests__/configurations.test.d.ts +2 -0
- package/lib/typescript/__tests__/configurations.test.d.ts.map +1 -0
- package/lib/typescript/__tests__/events.test.d.ts +2 -0
- package/lib/typescript/__tests__/events.test.d.ts.map +1 -0
- package/lib/typescript/__tests__/index.test.d.ts +2 -0
- package/lib/typescript/__tests__/index.test.d.ts.map +1 -0
- package/lib/typescript/__tests__/jsCore.test.d.ts +2 -0
- package/lib/typescript/__tests__/jsCore.test.d.ts.map +1 -0
- package/lib/typescript/__tests__/utils.test.d.ts +2 -0
- package/lib/typescript/__tests__/utils.test.d.ts.map +1 -0
- package/lib/typescript/api.d.ts +226 -0
- package/lib/typescript/api.d.ts.map +1 -0
- package/lib/typescript/configurations.d.ts +73 -0
- package/lib/typescript/configurations.d.ts.map +1 -0
- package/lib/typescript/constants.d.ts +59 -0
- package/lib/typescript/constants.d.ts.map +1 -0
- package/lib/typescript/events.d.ts +101 -0
- package/lib/typescript/events.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +27 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/jsCore.d.ts +140 -0
- package/lib/typescript/jsCore.d.ts.map +1 -0
- package/lib/typescript/native.d.ts +4 -0
- package/lib/typescript/native.d.ts.map +1 -0
- package/lib/typescript/subject.d.ts +91 -0
- package/lib/typescript/subject.d.ts.map +1 -0
- package/lib/typescript/tracker.d.ts +93 -0
- package/lib/typescript/tracker.d.ts.map +1 -0
- package/{dist/index.d.ts → lib/typescript/types.d.ts} +188 -75
- package/lib/typescript/types.d.ts.map +1 -0
- package/lib/typescript/utils.d.ts +35 -0
- package/lib/typescript/utils.d.ts.map +1 -0
- package/lib/typescript/webViewInterface.d.ts +15 -0
- package/lib/typescript/webViewInterface.d.ts.map +1 -0
- package/package.json +134 -52
- package/scripts/bootstrap.js +29 -0
- package/snowplow-react-native-tracker.podspec +42 -0
- package/src/__mocks__/react-native.js +7 -0
- package/src/__tests__/api.test.ts +34 -0
- package/src/__tests__/configurations.test.ts +620 -0
- package/src/__tests__/events.test.ts +749 -0
- package/src/__tests__/index.test.ts +27 -0
- package/src/__tests__/jsCore.test.ts +169 -0
- package/src/__tests__/utils.test.ts +23 -0
- package/src/api.ts +535 -0
- package/src/configurations.ts +337 -0
- package/src/constants.ts +102 -0
- package/src/events.ts +330 -0
- package/src/index.ts +189 -0
- package/src/jsCore.ts +553 -0
- package/src/native.ts +34 -0
- package/src/subject.ts +315 -0
- package/src/tracker.ts +330 -0
- package/src/types.ts +1087 -0
- package/src/utils.ts +78 -0
- package/src/webViewInterface.ts +105 -0
- package/tsconfig.build.json +5 -0
- package/tsconfig.json +28 -0
- package/turbo.json +34 -0
- package/yarn.lock +9333 -0
- package/RNSnowplowTracker.podspec +0 -24
- package/android/src/main/java/com/snowplowanalytics/react/tracker/RNSnowplowTrackerModule.java +0 -750
- package/android/src/main/java/com/snowplowanalytics/react/tracker/RNSnowplowTrackerPackage.java +0 -29
- package/android/src/main/java/com/snowplowanalytics/react/util/ConfigUtil.java +0 -351
- package/android/src/main/java/com/snowplowanalytics/react/util/EventUtil.java +0 -339
- package/android/src/main/java/com/snowplowanalytics/react/util/TrackerVersion.java +0 -7
- package/dist/index.js +0 -2026
- package/dist/index.js.map +0 -1
- package/ios/RNSnowplowTracker.h +0 -34
- package/ios/RNSnowplowTracker.m +0 -911
- package/ios/Util/NSDictionary+RNSP_TypeMethods.h +0 -33
- package/ios/Util/NSDictionary+RNSP_TypeMethods.m +0 -40
- package/ios/Util/RNConfigUtils.h +0 -44
- package/ios/Util/RNConfigUtils.m +0 -209
- package/ios/Util/RNTrackerVersion.h +0 -27
- package/ios/Util/RNTrackerVersion.m +0 -27
- package/ios/Util/RNUtilities.h +0 -32
- package/ios/Util/RNUtilities.m +0 -68
package/src/jsCore.ts
ADDED
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2020-2023 Snowplow Analytics Ltd. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* This program is licensed to you under the Apache License Version 2.0,
|
|
5
|
+
* and you may not use this file except in compliance with the Apache License Version 2.0.
|
|
6
|
+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing,
|
|
9
|
+
* software distributed under the Apache License Version 2.0 is distributed on an
|
|
10
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
InitTrackerConfiguration,
|
|
18
|
+
SelfDescribing,
|
|
19
|
+
EventContext,
|
|
20
|
+
StructuredProps,
|
|
21
|
+
ScreenViewProps,
|
|
22
|
+
ScreenSize,
|
|
23
|
+
PageViewProps,
|
|
24
|
+
TimingProps,
|
|
25
|
+
ConsentGrantedProps,
|
|
26
|
+
ConsentWithdrawnProps,
|
|
27
|
+
EcommerceTransactionProps,
|
|
28
|
+
DeepLinkReceivedProps,
|
|
29
|
+
MessageNotificationProps,
|
|
30
|
+
NetworkConfiguration,
|
|
31
|
+
} from './types';
|
|
32
|
+
|
|
33
|
+
import {
|
|
34
|
+
type Payload,
|
|
35
|
+
trackerCore,
|
|
36
|
+
type PayloadBuilder,
|
|
37
|
+
buildSelfDescribingEvent,
|
|
38
|
+
buildStructEvent,
|
|
39
|
+
buildPageView,
|
|
40
|
+
buildConsentGranted,
|
|
41
|
+
buildConsentWithdrawn,
|
|
42
|
+
buildEcommerceTransaction,
|
|
43
|
+
buildEcommerceTransactionItem,
|
|
44
|
+
} from '@snowplow/tracker-core';
|
|
45
|
+
import type { TrackerCore } from '@snowplow/tracker-core';
|
|
46
|
+
import { errorHandler } from './utils';
|
|
47
|
+
import { schemas } from './constants';
|
|
48
|
+
import { v4 as uuid } from 'uuid';
|
|
49
|
+
|
|
50
|
+
// Tracker version added to the events
|
|
51
|
+
const trackerVersion = 'rn-2.0.0';
|
|
52
|
+
|
|
53
|
+
interface Tracker extends TrackerCore {
|
|
54
|
+
setDomainUserId: (duid: string | undefined) => void;
|
|
55
|
+
setNetworkUserId: (nuid: string | undefined) => void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let trackers: { [namespace: string]: Tracker } = {};
|
|
59
|
+
|
|
60
|
+
function preparePayload(payload: Payload): Record<string, string> {
|
|
61
|
+
const stringifiedPayload: Record<string, string> = {};
|
|
62
|
+
|
|
63
|
+
payload['stm'] = new Date().getTime().toString();
|
|
64
|
+
|
|
65
|
+
for (const key in payload) {
|
|
66
|
+
if (Object.prototype.hasOwnProperty.call(payload, key)) {
|
|
67
|
+
stringifiedPayload[key] = String(payload[key]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return stringifiedPayload;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function createEmitCallback(
|
|
74
|
+
networkConfig: NetworkConfiguration
|
|
75
|
+
): (e: Payload) => void {
|
|
76
|
+
return (e: Payload) => {
|
|
77
|
+
const postJson = {
|
|
78
|
+
schema: schemas.payloadData,
|
|
79
|
+
data: [preparePayload(e)],
|
|
80
|
+
};
|
|
81
|
+
const endpoint = networkConfig.endpoint;
|
|
82
|
+
const postPath =
|
|
83
|
+
networkConfig.customPostPath ?? '/com.snowplowanalytics.snowplow/tp2';
|
|
84
|
+
const headers = networkConfig.requestHeaders ?? {};
|
|
85
|
+
fetch(endpoint + postPath, {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
body: JSON.stringify(postJson),
|
|
88
|
+
headers: {
|
|
89
|
+
'Content-Type': 'application/json',
|
|
90
|
+
...headers,
|
|
91
|
+
},
|
|
92
|
+
}).catch(errorHandler);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function updateTrackerProperties(
|
|
97
|
+
tracker: Tracker,
|
|
98
|
+
configuration: InitTrackerConfiguration
|
|
99
|
+
): void {
|
|
100
|
+
tracker.setPlatform(configuration.trackerConfig?.devicePlatform ?? 'mob');
|
|
101
|
+
tracker.setTrackerVersion(trackerVersion);
|
|
102
|
+
tracker.setTrackerNamespace(configuration.namespace);
|
|
103
|
+
if (configuration.trackerConfig?.appId != null) {
|
|
104
|
+
tracker.setAppId(configuration.trackerConfig.appId);
|
|
105
|
+
}
|
|
106
|
+
if (configuration.subjectConfig?.colorDepth != null) {
|
|
107
|
+
tracker.setColorDepth(String(configuration.subjectConfig.colorDepth));
|
|
108
|
+
}
|
|
109
|
+
if (configuration.subjectConfig?.domainUserId != null) {
|
|
110
|
+
tracker.setDomainUserId(configuration.subjectConfig.domainUserId);
|
|
111
|
+
}
|
|
112
|
+
if (configuration.subjectConfig?.ipAddress != null) {
|
|
113
|
+
tracker.setIpAddress(configuration.subjectConfig.ipAddress);
|
|
114
|
+
}
|
|
115
|
+
if (configuration.subjectConfig?.language != null) {
|
|
116
|
+
tracker.setLang(configuration.subjectConfig.language);
|
|
117
|
+
}
|
|
118
|
+
if (configuration.subjectConfig?.screenResolution != null) {
|
|
119
|
+
tracker.setScreenResolution(
|
|
120
|
+
String(configuration.subjectConfig.screenResolution[0]),
|
|
121
|
+
String(configuration.subjectConfig.screenResolution[1])
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
if (configuration.subjectConfig?.screenViewport != null) {
|
|
125
|
+
tracker.setViewport(
|
|
126
|
+
String(configuration.subjectConfig.screenViewport[0]),
|
|
127
|
+
String(configuration.subjectConfig.screenViewport[1])
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
if (configuration.subjectConfig?.timezone != null) {
|
|
131
|
+
tracker.setTimezone(configuration.subjectConfig.timezone);
|
|
132
|
+
}
|
|
133
|
+
if (configuration.subjectConfig?.userId != null) {
|
|
134
|
+
tracker.setUserId(configuration.subjectConfig.userId);
|
|
135
|
+
}
|
|
136
|
+
if (configuration.subjectConfig?.useragent != null) {
|
|
137
|
+
tracker.setUseragent(configuration.subjectConfig.useragent);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function createTracker(
|
|
142
|
+
configuration: InitTrackerConfiguration,
|
|
143
|
+
emitCallback?: (e: Payload) => void
|
|
144
|
+
): Promise<void> {
|
|
145
|
+
// create an emit callback if not given
|
|
146
|
+
const emitter =
|
|
147
|
+
emitCallback ?? createEmitCallback(configuration.networkConfig);
|
|
148
|
+
|
|
149
|
+
// the tracker core does not provide an option to set the duid, so we need to add custom
|
|
150
|
+
let domainUserId: string | undefined;
|
|
151
|
+
const setDomainUserId = (userId: string | undefined): void => {
|
|
152
|
+
domainUserId = userId;
|
|
153
|
+
};
|
|
154
|
+
let networkUserId: string | undefined;
|
|
155
|
+
const setNetworkUserId = (userId: string | undefined): void => {
|
|
156
|
+
networkUserId = userId;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// initialize the tracker core
|
|
160
|
+
const core = trackerCore({
|
|
161
|
+
base64: configuration.trackerConfig?.base64Encoding ?? true,
|
|
162
|
+
callback: (payload: PayloadBuilder) => {
|
|
163
|
+
if (domainUserId != null) {
|
|
164
|
+
payload.add('duid', domainUserId);
|
|
165
|
+
}
|
|
166
|
+
if (networkUserId != null) {
|
|
167
|
+
payload.add('tnuid', networkUserId);
|
|
168
|
+
}
|
|
169
|
+
const builtPayload = payload.build();
|
|
170
|
+
emitter(builtPayload);
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
const tracker = { ...core, setDomainUserId, setNetworkUserId };
|
|
174
|
+
trackers[configuration.namespace] = tracker;
|
|
175
|
+
|
|
176
|
+
// update tracker properties to reflect subject and tracker info
|
|
177
|
+
updateTrackerProperties(tracker, configuration);
|
|
178
|
+
|
|
179
|
+
return <Promise<void>>Promise.resolve();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function removeTracker(details: { tracker: string }): Promise<boolean> {
|
|
183
|
+
delete trackers[details.tracker];
|
|
184
|
+
return <Promise<boolean>>Promise.resolve(true);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function removeAllTrackers(): Promise<boolean> {
|
|
188
|
+
trackers = {};
|
|
189
|
+
return <Promise<boolean>>Promise.resolve(true);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function forTracker(
|
|
193
|
+
namespace: string | null,
|
|
194
|
+
callback: (tracker: Tracker) => void
|
|
195
|
+
): void {
|
|
196
|
+
const tracker =
|
|
197
|
+
namespace != null ? trackers[namespace] : Object.values(trackers)[0];
|
|
198
|
+
|
|
199
|
+
if (tracker) {
|
|
200
|
+
callback(tracker);
|
|
201
|
+
} else {
|
|
202
|
+
errorHandler(new Error('No such tracker found.'));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function trackSelfDescribingEvent(details: {
|
|
207
|
+
tracker: string | null;
|
|
208
|
+
eventData: SelfDescribing;
|
|
209
|
+
contexts: EventContext[];
|
|
210
|
+
}): Promise<void> {
|
|
211
|
+
forTracker(details.tracker, (tracker) => {
|
|
212
|
+
tracker.track(
|
|
213
|
+
buildSelfDescribingEvent({
|
|
214
|
+
event: details.eventData,
|
|
215
|
+
}),
|
|
216
|
+
details.contexts
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
return <Promise<void>>Promise.resolve();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function trackStructuredEvent(details: {
|
|
223
|
+
tracker: string | null;
|
|
224
|
+
eventData: StructuredProps;
|
|
225
|
+
contexts: EventContext[];
|
|
226
|
+
}): Promise<void> {
|
|
227
|
+
forTracker(details.tracker, (tracker) => {
|
|
228
|
+
tracker.track(buildStructEvent(details.eventData), details.contexts);
|
|
229
|
+
});
|
|
230
|
+
return <Promise<void>>Promise.resolve();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function trackScreenViewEvent(details: {
|
|
234
|
+
tracker: string | null;
|
|
235
|
+
eventData: ScreenViewProps;
|
|
236
|
+
contexts: EventContext[];
|
|
237
|
+
}): Promise<void> {
|
|
238
|
+
const data: ScreenViewProps = {
|
|
239
|
+
name: details.eventData.name,
|
|
240
|
+
id: details.eventData.id ?? uuid(),
|
|
241
|
+
};
|
|
242
|
+
if (details.eventData.type != null) {
|
|
243
|
+
data.type = details.eventData.type;
|
|
244
|
+
}
|
|
245
|
+
if (details.eventData.previousName != null) {
|
|
246
|
+
data.previousName = details.eventData.previousName;
|
|
247
|
+
}
|
|
248
|
+
if (details.eventData.previousId != null) {
|
|
249
|
+
data.previousId = details.eventData.previousId;
|
|
250
|
+
}
|
|
251
|
+
if (details.eventData.previousType != null) {
|
|
252
|
+
data.previousType = details.eventData.previousType;
|
|
253
|
+
}
|
|
254
|
+
if (details.eventData.transitionType != null) {
|
|
255
|
+
data.transitionType = details.eventData.transitionType;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return trackSelfDescribingEvent({
|
|
259
|
+
tracker: details.tracker,
|
|
260
|
+
eventData: {
|
|
261
|
+
schema: schemas.screenViewSchema,
|
|
262
|
+
data: data,
|
|
263
|
+
},
|
|
264
|
+
contexts: details.contexts,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function trackPageViewEvent(details: {
|
|
269
|
+
tracker: string | null;
|
|
270
|
+
eventData: PageViewProps;
|
|
271
|
+
contexts: EventContext[];
|
|
272
|
+
}): Promise<void> {
|
|
273
|
+
forTracker(details.tracker, (tracker) => {
|
|
274
|
+
tracker.track(buildPageView(details.eventData), details.contexts);
|
|
275
|
+
});
|
|
276
|
+
return <Promise<void>>Promise.resolve();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function trackTimingEvent(details: {
|
|
280
|
+
tracker: string | null;
|
|
281
|
+
eventData: TimingProps;
|
|
282
|
+
contexts: EventContext[];
|
|
283
|
+
}): Promise<void> {
|
|
284
|
+
return trackSelfDescribingEvent({
|
|
285
|
+
tracker: details.tracker,
|
|
286
|
+
eventData: {
|
|
287
|
+
schema: schemas.timingSchema,
|
|
288
|
+
data: details.eventData,
|
|
289
|
+
},
|
|
290
|
+
contexts: details.contexts,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function trackConsentGrantedEvent(details: {
|
|
295
|
+
tracker: string | null;
|
|
296
|
+
eventData: ConsentGrantedProps;
|
|
297
|
+
contexts: EventContext[];
|
|
298
|
+
}): Promise<void> {
|
|
299
|
+
forTracker(details.tracker, (tracker) => {
|
|
300
|
+
const built = buildConsentGranted({
|
|
301
|
+
id: details.eventData.documentId,
|
|
302
|
+
version: details.eventData.version,
|
|
303
|
+
name: details.eventData.name,
|
|
304
|
+
description: details.eventData.documentDescription,
|
|
305
|
+
expiry: details.eventData.expiry,
|
|
306
|
+
});
|
|
307
|
+
tracker.track(built.event, details.contexts.concat(built.context));
|
|
308
|
+
});
|
|
309
|
+
return <Promise<void>>Promise.resolve();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function trackConsentWithdrawnEvent(details: {
|
|
313
|
+
tracker: string | null;
|
|
314
|
+
eventData: ConsentWithdrawnProps;
|
|
315
|
+
contexts: EventContext[];
|
|
316
|
+
}): Promise<void> {
|
|
317
|
+
forTracker(details.tracker, (tracker) => {
|
|
318
|
+
const built = buildConsentWithdrawn({
|
|
319
|
+
all: details.eventData.all,
|
|
320
|
+
id: details.eventData.documentId,
|
|
321
|
+
version: details.eventData.version,
|
|
322
|
+
name: details.eventData.name,
|
|
323
|
+
description: details.eventData.documentDescription,
|
|
324
|
+
});
|
|
325
|
+
tracker.track(built.event, details.contexts.concat(built.context));
|
|
326
|
+
});
|
|
327
|
+
return <Promise<void>>Promise.resolve();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function trackEcommerceTransactionEvent(details: {
|
|
331
|
+
tracker: string | null;
|
|
332
|
+
eventData: EcommerceTransactionProps;
|
|
333
|
+
contexts: EventContext[];
|
|
334
|
+
}): Promise<void> {
|
|
335
|
+
forTracker(details.tracker, (tracker) => {
|
|
336
|
+
details.eventData.items.forEach((item) => {
|
|
337
|
+
tracker.track(
|
|
338
|
+
buildEcommerceTransactionItem({
|
|
339
|
+
...item,
|
|
340
|
+
orderId: details.eventData.orderId,
|
|
341
|
+
}),
|
|
342
|
+
details.contexts
|
|
343
|
+
);
|
|
344
|
+
});
|
|
345
|
+
tracker.track(
|
|
346
|
+
buildEcommerceTransaction({
|
|
347
|
+
orderId: details.eventData.orderId,
|
|
348
|
+
total: details.eventData.totalValue,
|
|
349
|
+
affiliation: details.eventData.affiliation,
|
|
350
|
+
tax: details.eventData.taxValue,
|
|
351
|
+
shipping: details.eventData.shipping,
|
|
352
|
+
city: details.eventData.city,
|
|
353
|
+
state: details.eventData.state,
|
|
354
|
+
country: details.eventData.country,
|
|
355
|
+
currency: details.eventData.currency,
|
|
356
|
+
}),
|
|
357
|
+
details.contexts
|
|
358
|
+
);
|
|
359
|
+
});
|
|
360
|
+
return <Promise<void>>Promise.resolve();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function trackDeepLinkReceivedEvent(details: {
|
|
364
|
+
tracker: string | null;
|
|
365
|
+
eventData: DeepLinkReceivedProps;
|
|
366
|
+
contexts: EventContext[];
|
|
367
|
+
}): Promise<void> {
|
|
368
|
+
return trackSelfDescribingEvent({
|
|
369
|
+
tracker: details.tracker,
|
|
370
|
+
eventData: {
|
|
371
|
+
schema: schemas.deepLinkReceivedSchema,
|
|
372
|
+
data: details.eventData,
|
|
373
|
+
},
|
|
374
|
+
contexts: details.contexts,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function trackMessageNotificationEvent(details: {
|
|
379
|
+
tracker: string | null;
|
|
380
|
+
eventData: MessageNotificationProps;
|
|
381
|
+
contexts: EventContext[];
|
|
382
|
+
}): Promise<void> {
|
|
383
|
+
return trackSelfDescribingEvent({
|
|
384
|
+
tracker: details.tracker,
|
|
385
|
+
eventData: {
|
|
386
|
+
schema: schemas.messageNotificationSchema,
|
|
387
|
+
data: details.eventData,
|
|
388
|
+
},
|
|
389
|
+
contexts: details.contexts,
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function removeGlobalContexts(): Promise<void> {
|
|
394
|
+
return <Promise<void>>Promise.reject(new Error('Not implemented'));
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function addGlobalContexts(): Promise<void> {
|
|
398
|
+
return <Promise<void>>Promise.reject(new Error('Not implemented'));
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function setUserId(details: {
|
|
402
|
+
tracker: string;
|
|
403
|
+
userId: string | null;
|
|
404
|
+
}): Promise<void> {
|
|
405
|
+
trackers[details.tracker]?.setUserId(details.userId ?? '');
|
|
406
|
+
return <Promise<void>>Promise.resolve();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function setNetworkUserId(details: {
|
|
410
|
+
tracker: string;
|
|
411
|
+
networkUserId: string | null;
|
|
412
|
+
}): Promise<void> {
|
|
413
|
+
trackers[details.tracker]?.setNetworkUserId(details.networkUserId ?? '');
|
|
414
|
+
return <Promise<void>>Promise.resolve();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function setDomainUserId(details: {
|
|
418
|
+
tracker: string;
|
|
419
|
+
domainUserId: string | null;
|
|
420
|
+
}): Promise<void> {
|
|
421
|
+
trackers[details.tracker]?.setDomainUserId(details.domainUserId ?? '');
|
|
422
|
+
return <Promise<void>>Promise.resolve();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function setIpAddress(details: {
|
|
426
|
+
tracker: string;
|
|
427
|
+
ipAddress: string | null;
|
|
428
|
+
}): Promise<void> {
|
|
429
|
+
trackers[details.tracker]?.setIpAddress(details.ipAddress ?? '');
|
|
430
|
+
return <Promise<void>>Promise.resolve();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function setUseragent(details: {
|
|
434
|
+
tracker: string;
|
|
435
|
+
useragent: string | null;
|
|
436
|
+
}): Promise<void> {
|
|
437
|
+
trackers[details.tracker]?.setUseragent(details.useragent ?? '');
|
|
438
|
+
return <Promise<void>>Promise.resolve();
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function setTimezone(details: {
|
|
442
|
+
tracker: string;
|
|
443
|
+
timezone: string | null;
|
|
444
|
+
}): Promise<void> {
|
|
445
|
+
trackers[details.tracker]?.setTimezone(details.timezone ?? '');
|
|
446
|
+
return <Promise<void>>Promise.resolve();
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function setLanguage(details: {
|
|
450
|
+
tracker: string;
|
|
451
|
+
language: string | null;
|
|
452
|
+
}): Promise<void> {
|
|
453
|
+
trackers[details.tracker]?.setLang(details.language ?? '');
|
|
454
|
+
return <Promise<void>>Promise.resolve();
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function setScreenResolution(details: {
|
|
458
|
+
tracker: string;
|
|
459
|
+
screenResolution: ScreenSize | null;
|
|
460
|
+
}): Promise<void> {
|
|
461
|
+
if (details.screenResolution) {
|
|
462
|
+
trackers[details.tracker]?.setScreenResolution(
|
|
463
|
+
String(details.screenResolution[0]),
|
|
464
|
+
String(details.screenResolution[1])
|
|
465
|
+
);
|
|
466
|
+
} else {
|
|
467
|
+
trackers[details.tracker]?.addPayloadPair('res', '');
|
|
468
|
+
}
|
|
469
|
+
return <Promise<void>>Promise.resolve();
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function setScreenViewport(details: {
|
|
473
|
+
tracker: string;
|
|
474
|
+
screenViewport: ScreenSize | null;
|
|
475
|
+
}): Promise<void> {
|
|
476
|
+
if (details.screenViewport) {
|
|
477
|
+
trackers[details.tracker]?.setViewport(
|
|
478
|
+
String(details.screenViewport[0]),
|
|
479
|
+
String(details.screenViewport[1])
|
|
480
|
+
);
|
|
481
|
+
} else {
|
|
482
|
+
trackers[details.tracker]?.addPayloadPair('vp', '');
|
|
483
|
+
}
|
|
484
|
+
return <Promise<void>>Promise.resolve();
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function setColorDepth(details: {
|
|
488
|
+
tracker: string;
|
|
489
|
+
colorDepth: number | null;
|
|
490
|
+
}): Promise<void> {
|
|
491
|
+
trackers[details.tracker]?.setColorDepth(String(details.colorDepth ?? ''));
|
|
492
|
+
return <Promise<void>>Promise.resolve();
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function getSessionUserId(): Promise<string> {
|
|
496
|
+
return <Promise<string>>Promise.reject(new Error('Not implemented'));
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function getSessionId(): Promise<string> {
|
|
500
|
+
return <Promise<string>>Promise.reject(new Error('Not implemented'));
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function getSessionIndex(): Promise<number> {
|
|
504
|
+
return <Promise<number>>Promise.reject(new Error('Not implemented'));
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function getIsInBackground(): Promise<boolean> {
|
|
508
|
+
return <Promise<boolean>>Promise.reject(new Error('Not implemented'));
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
function getBackgroundIndex(): Promise<number> {
|
|
512
|
+
return <Promise<number>>Promise.reject(new Error('Not implemented'));
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function getForegroundIndex(): Promise<number> {
|
|
516
|
+
return <Promise<number>>Promise.reject(new Error('Not implemented'));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const JSSnowplowTracker = Object.freeze({
|
|
520
|
+
createTracker,
|
|
521
|
+
removeTracker,
|
|
522
|
+
removeAllTrackers,
|
|
523
|
+
trackSelfDescribingEvent,
|
|
524
|
+
trackStructuredEvent,
|
|
525
|
+
trackScreenViewEvent,
|
|
526
|
+
trackPageViewEvent,
|
|
527
|
+
trackTimingEvent,
|
|
528
|
+
trackConsentGrantedEvent,
|
|
529
|
+
trackConsentWithdrawnEvent,
|
|
530
|
+
trackEcommerceTransactionEvent,
|
|
531
|
+
trackDeepLinkReceivedEvent,
|
|
532
|
+
trackMessageNotificationEvent,
|
|
533
|
+
removeGlobalContexts,
|
|
534
|
+
addGlobalContexts,
|
|
535
|
+
setUserId,
|
|
536
|
+
setNetworkUserId,
|
|
537
|
+
setDomainUserId,
|
|
538
|
+
setIpAddress,
|
|
539
|
+
setUseragent,
|
|
540
|
+
setTimezone,
|
|
541
|
+
setLanguage,
|
|
542
|
+
setScreenResolution,
|
|
543
|
+
setScreenViewport,
|
|
544
|
+
setColorDepth,
|
|
545
|
+
getSessionUserId,
|
|
546
|
+
getSessionId,
|
|
547
|
+
getSessionIndex,
|
|
548
|
+
getIsInBackground,
|
|
549
|
+
getBackgroundIndex,
|
|
550
|
+
getForegroundIndex,
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
export { JSSnowplowTracker };
|
package/src/native.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2020-2023 Snowplow Analytics Ltd. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* This program is licensed to you under the Apache License Version 2.0,
|
|
5
|
+
* and you may not use this file except in compliance with the Apache License Version 2.0.
|
|
6
|
+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing,
|
|
9
|
+
* software distributed under the Apache License Version 2.0 is distributed on an
|
|
10
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
import { NativeModules } from 'react-native';
|
|
17
|
+
import { JSSnowplowTracker } from './jsCore';
|
|
18
|
+
import type { Native } from './types';
|
|
19
|
+
import { errorHandler } from './utils';
|
|
20
|
+
|
|
21
|
+
const isAvailable = NativeModules.ReactNativeTracker != null;
|
|
22
|
+
if (!isAvailable) {
|
|
23
|
+
errorHandler(
|
|
24
|
+
new Error(
|
|
25
|
+
'Unable to access the native iOS/Android Snowplow tracker, a tracker implementation with very limited functionality is used.'
|
|
26
|
+
)
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const RNSnowplowTracker: Native = isAvailable
|
|
31
|
+
? (NativeModules.ReactNativeTracker as Native)
|
|
32
|
+
: JSSnowplowTracker;
|
|
33
|
+
|
|
34
|
+
export { RNSnowplowTracker };
|