@snowplow/react-native-tracker 1.3.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/LICENSE +1 -1
- package/README.md +24 -111
- 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 +138 -51
- 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 -1650
- 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
|
@@ -0,0 +1,153 @@
|
|
|
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
|
+
const Micro = require('./microHelpers.js');
|
|
15
|
+
|
|
16
|
+
const microUrl = '0.0.0.0';
|
|
17
|
+
const microPort = '9090';
|
|
18
|
+
const microGood = '/micro/good';
|
|
19
|
+
const microBad = '/micro/bad';
|
|
20
|
+
const microReset = '/micro/reset';
|
|
21
|
+
|
|
22
|
+
async function getMicroGood() {
|
|
23
|
+
const good = await Micro.requestJson(microUrl, microPort, microGood);
|
|
24
|
+
return good;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function getMicroBad() {
|
|
28
|
+
const bad = await Micro.requestJson(microUrl, microPort, microBad);
|
|
29
|
+
return bad;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function resetMicro() {
|
|
33
|
+
await Micro.request(microUrl, microPort, microReset);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* setTimeout promise
|
|
38
|
+
*
|
|
39
|
+
* @param {number} millis The milliseconds to wait
|
|
40
|
+
*/
|
|
41
|
+
function sleep(millis) {
|
|
42
|
+
return new Promise(resolve => {
|
|
43
|
+
setTimeout(() => resolve('done sleeping!'), millis);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Asserts no bad events
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
function assertNoBadEvents() {
|
|
52
|
+
return getMicroBad().then(res => {
|
|
53
|
+
expect(res.length).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Asserts on the number of events having a given schema
|
|
59
|
+
*
|
|
60
|
+
* ```
|
|
61
|
+
* eventsWithSchema("iglu:com.acme/test_event/jsonschema/1-0-0", 2);
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @param {string} schema The event's schema to match
|
|
65
|
+
* @param {number} [n=1] The expected number of matching events
|
|
66
|
+
*/
|
|
67
|
+
function eventsWithSchema(schema, n = 1) {
|
|
68
|
+
n = parseInt(n, 10);
|
|
69
|
+
return getMicroGood().then(arr => {
|
|
70
|
+
const res = Micro.matchBySchema(arr, schema);
|
|
71
|
+
expect(res.length).toBe(n);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Asserts on the number of events having a given type
|
|
77
|
+
*
|
|
78
|
+
* ```
|
|
79
|
+
* eventsWithEventType("struct", 7);
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @param {string} eventType The event's type to match
|
|
83
|
+
* @param {number} [n=1] The expected number of matching events
|
|
84
|
+
*/
|
|
85
|
+
function eventsWithEventType(eventType, n = 1) {
|
|
86
|
+
n = parseInt(n, 10);
|
|
87
|
+
return getMicroGood().then(arr => {
|
|
88
|
+
const res = Micro.matchByEventType(arr, eventType);
|
|
89
|
+
expect(res.length).toBe(n);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Asserts on the number of events having a given set of properties (schema, values, contexts, parameters)
|
|
95
|
+
*
|
|
96
|
+
* ```
|
|
97
|
+
* eventsWithProperties({
|
|
98
|
+
* schema: "iglu:com.acme/test_event/jsonschema/1-0-0",
|
|
99
|
+
* values: {
|
|
100
|
+
* testProperty: true
|
|
101
|
+
* },
|
|
102
|
+
* header: "the: header"
|
|
103
|
+
* contexts: [{
|
|
104
|
+
* schema: "iglu:com.acme/test_context/jsonschema/1-0-0",
|
|
105
|
+
* data: {
|
|
106
|
+
* "testCoProp": 0,
|
|
107
|
+
* }
|
|
108
|
+
* }],
|
|
109
|
+
* parameters: {
|
|
110
|
+
* user_id: "tester",
|
|
111
|
+
* name_tracker: "myTrackerName"
|
|
112
|
+
* }
|
|
113
|
+
* }, 3);
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* @param {Object} eventOptions The options to match against
|
|
117
|
+
* @param {number} [n=1] The expected number of matching events
|
|
118
|
+
*/
|
|
119
|
+
function eventsWithProperties(eventOptions, n = 1) {
|
|
120
|
+
n = parseInt(n, 10);
|
|
121
|
+
return getMicroGood().then(arr => {
|
|
122
|
+
const res = Micro.matchEvents(arr, eventOptions);
|
|
123
|
+
expect(res.length).toBe(n);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Asserts on the number of events having a given HTTP request header
|
|
129
|
+
*
|
|
130
|
+
* ```
|
|
131
|
+
* eventsWithHeader("Connection: keep-alive", 2);
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @param {string} header The request header to match
|
|
135
|
+
* @param {number} [n=1] The expected number of matching events
|
|
136
|
+
*/
|
|
137
|
+
function eventsWithHeader(header, n = 1) {
|
|
138
|
+
n = parseInt(n, 10);
|
|
139
|
+
return getMicroGood().then(arr => {
|
|
140
|
+
const res = Micro.matchByHeader(arr, header);
|
|
141
|
+
expect(res.length).toBe(n);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
module.exports = {
|
|
146
|
+
assertNoBadEvents,
|
|
147
|
+
eventsWithSchema,
|
|
148
|
+
eventsWithEventType,
|
|
149
|
+
eventsWithProperties,
|
|
150
|
+
eventsWithHeader,
|
|
151
|
+
resetMicro,
|
|
152
|
+
sleep,
|
|
153
|
+
};
|
|
@@ -0,0 +1,346 @@
|
|
|
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
|
+
const http = require('http');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Makes an http get request
|
|
18
|
+
*
|
|
19
|
+
* @param {string} url
|
|
20
|
+
* @param {string} port
|
|
21
|
+
* @param {string} path
|
|
22
|
+
*/
|
|
23
|
+
function request(url, port, path) {
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const options = {
|
|
26
|
+
hostname: url,
|
|
27
|
+
port: port,
|
|
28
|
+
path: path,
|
|
29
|
+
};
|
|
30
|
+
try {
|
|
31
|
+
http.get(options, res => {
|
|
32
|
+
let data = '';
|
|
33
|
+
res.on('data', d => (data += d));
|
|
34
|
+
res.on('end', () => resolve(data));
|
|
35
|
+
});
|
|
36
|
+
} catch (e) {
|
|
37
|
+
reject(e);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Returns a JSON parsed response from an http request
|
|
44
|
+
*
|
|
45
|
+
* @param {string} url
|
|
46
|
+
* @param {string} port
|
|
47
|
+
* @param {string} path
|
|
48
|
+
*/
|
|
49
|
+
function requestJson(url, port, path) {
|
|
50
|
+
return request(url, port, path).then(g => JSON.parse(g));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Filters an array of Snowplow events based on eventType
|
|
55
|
+
*
|
|
56
|
+
* ```
|
|
57
|
+
* matchByEventType(goodEventsArray, "page_view");
|
|
58
|
+
*
|
|
59
|
+
* ```
|
|
60
|
+
* @param {Array} eventsArray An array of Snowplow events
|
|
61
|
+
* @param {string} eventType The eventType to match
|
|
62
|
+
* @returns {Array} An array with the matching events
|
|
63
|
+
*/
|
|
64
|
+
function matchByEventType(eventsArray, eventType) {
|
|
65
|
+
return eventsArray.filter(hasEventType(eventType));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Filters an array of Snowplow events based on schema
|
|
70
|
+
*
|
|
71
|
+
* ```
|
|
72
|
+
* matchBySchema(goodEventsArray, "iglu:com.acme/test_event/jsonschema/1-0-0");
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* @param {Array} eventsArray An array of Snowplow events
|
|
76
|
+
* @param {string} schema The schema to match
|
|
77
|
+
* @returns {Array} An array with the matching events
|
|
78
|
+
*/
|
|
79
|
+
function matchBySchema(eventsArray, schema) {
|
|
80
|
+
return eventsArray.filter(hasSchema(schema));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Filters an array of unstructured Snowplow events based on data values
|
|
85
|
+
*
|
|
86
|
+
* ```
|
|
87
|
+
* matchByVals(goodEventsArray, {targetUrl: "https://docs.snowplowanalytics.com/"});
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @param {Array} eventsArray An array of unstructured Snowplow events
|
|
91
|
+
* @param {Object} valsObj The object having as keys the data fields to match
|
|
92
|
+
* @returns {Array} An array with the matching events
|
|
93
|
+
*/
|
|
94
|
+
function matchByVals(eventsArray, valsObj) {
|
|
95
|
+
return eventsArray.filter(hasValues(valsObj));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Filters an array of Snowplow events based on parameter values
|
|
100
|
+
*
|
|
101
|
+
* ```
|
|
102
|
+
* matchByParams(goodEventsArray,
|
|
103
|
+
* {
|
|
104
|
+
* event: "struct",
|
|
105
|
+
* se_category: "Mixes",
|
|
106
|
+
* se_action: "Play",
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @param {Array} eventsArray An array of Snowplow events
|
|
111
|
+
* @param {Object} paramsObj An object having as keys the event parameters to match
|
|
112
|
+
* @returns {Array} An array with the matching events
|
|
113
|
+
*/
|
|
114
|
+
function matchByParams(eventsArray, paramsObj) {
|
|
115
|
+
return eventsArray.filter(hasParams(paramsObj));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Filters an array of Snowplow events based on an array of attached contexts
|
|
120
|
+
*
|
|
121
|
+
* ```
|
|
122
|
+
* matchByContexts(goodEventsArray,
|
|
123
|
+
* [{
|
|
124
|
+
* schema: "iglu:com.acme/a_test_context/jsonschema/1-0-0",
|
|
125
|
+
* data: {"testprop": 0}
|
|
126
|
+
* },{
|
|
127
|
+
* schema: "iglu:com.acme/b_test_context/jsonschema/1-0-0"
|
|
128
|
+
* }]);
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* @param {Array} eventsArray An array of Snowplow events
|
|
132
|
+
* @param {Array} expectedContextsArray An array of contexts
|
|
133
|
+
* @returns {Array} An array with the matching events
|
|
134
|
+
*/
|
|
135
|
+
function matchByContexts(eventsArray, expectedContextsArray) {
|
|
136
|
+
return eventsArray.filter(hasContexts(expectedContextsArray));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Filters an array of Snowplow events based on the request headers
|
|
141
|
+
*
|
|
142
|
+
* ```
|
|
143
|
+
* matchByHeader(goodEventsArray, "Connection: keep-alive");
|
|
144
|
+
*
|
|
145
|
+
* ```
|
|
146
|
+
* @param {Array} eventsArray An array of Snowplow events
|
|
147
|
+
* @param {string} header The HTTP request header to match
|
|
148
|
+
* @returns {Array} An array with the matching events
|
|
149
|
+
*/
|
|
150
|
+
function matchByHeader(eventsArray, header) {
|
|
151
|
+
return eventsArray.filter(hasHeader(header));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Filters an array of Snowplow events based on event's Properties
|
|
156
|
+
*
|
|
157
|
+
* ```
|
|
158
|
+
* matchEvents(goodEventsArray,
|
|
159
|
+
* {
|
|
160
|
+
* schema: "iglu:com.acme/test_event/jsonschema/1-0-0",
|
|
161
|
+
* values: {
|
|
162
|
+
* testProperty: true
|
|
163
|
+
* },
|
|
164
|
+
* contexts: [{
|
|
165
|
+
* schema: "iglu:com.acme/test_context/jsonschema/1-0-0",
|
|
166
|
+
* data: {
|
|
167
|
+
* testCoProp: 0,
|
|
168
|
+
* }
|
|
169
|
+
* }],
|
|
170
|
+
* parameters: {
|
|
171
|
+
* user_id: "tester",
|
|
172
|
+
* name_tracker: "myTrackerName"
|
|
173
|
+
* },
|
|
174
|
+
* header: 'the: header',
|
|
175
|
+
* });
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @param {Array} microEvents An array of Snowplow events
|
|
179
|
+
* @param {Properties} eventProps The event properties to match against
|
|
180
|
+
* @returns {Array} An array with the matching events
|
|
181
|
+
*/
|
|
182
|
+
function matchEvents(microEvents, eventProps) {
|
|
183
|
+
if (Object.prototype.toString.call(microEvents) !== '[object Array]') {
|
|
184
|
+
microEvents = [microEvents];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
let res = microEvents;
|
|
188
|
+
|
|
189
|
+
if (eventProps.eventType) {
|
|
190
|
+
res = matchByEventType(res, eventProps.eventType);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (eventProps.schema) {
|
|
194
|
+
res = matchBySchema(res, eventProps.schema);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (eventProps.values) {
|
|
198
|
+
res = matchByVals(res, eventProps.values);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (eventProps.contexts) {
|
|
202
|
+
res = matchByContexts(res, eventProps.contexts);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (eventProps.parameters) {
|
|
206
|
+
res = matchByParams(res, eventProps.parameters);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (eventProps.header) {
|
|
210
|
+
res = matchByHeader(res, eventProps.header);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return res;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function hasEventType(evType) {
|
|
217
|
+
return function (ev) {
|
|
218
|
+
return ev.eventType === evType;
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function hasSchema(schema) {
|
|
223
|
+
return function (ev) {
|
|
224
|
+
if (ev.eventType === 'unstruct') {
|
|
225
|
+
let unstruct_ev = ev.event.unstruct_event;
|
|
226
|
+
|
|
227
|
+
return unstruct_ev.data.schema === schema;
|
|
228
|
+
} else {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function hasValues(values) {
|
|
235
|
+
return function (ev) {
|
|
236
|
+
if (ev.eventType === 'unstruct') {
|
|
237
|
+
let unstruct_ev = ev.event.unstruct_event;
|
|
238
|
+
let data = unstruct_ev.data.data;
|
|
239
|
+
|
|
240
|
+
return (
|
|
241
|
+
Object.keys(values).every(keyIncludedIn(data)) &&
|
|
242
|
+
Object.keys(values).every(comparesIn(values, data))
|
|
243
|
+
);
|
|
244
|
+
} else {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function hasParams(expectParams) {
|
|
251
|
+
return function (ev) {
|
|
252
|
+
let actualParams = ev.event;
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
Object.keys(expectParams).every(keyIncludedIn(actualParams)) &&
|
|
256
|
+
Object.keys(expectParams).every(comparesIn(expectParams, actualParams))
|
|
257
|
+
);
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function hasContexts(expCoArr) {
|
|
262
|
+
return function (ev) {
|
|
263
|
+
let evCo = ev.event.contexts;
|
|
264
|
+
|
|
265
|
+
if (evCo.hasOwnProperty('data')) {
|
|
266
|
+
let actCoArr = evCo.data;
|
|
267
|
+
|
|
268
|
+
return compare(expCoArr, actCoArr);
|
|
269
|
+
} else {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function hasHeader(header) {
|
|
276
|
+
return function (ev) {
|
|
277
|
+
return ev.rawEvent.context.headers.includes(header);
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function keyIncludedIn(obj) {
|
|
282
|
+
return function (key) {
|
|
283
|
+
return Object.keys(obj).includes(key);
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function comparesIn(expected, actual) {
|
|
288
|
+
return function (key) {
|
|
289
|
+
let expValue = expected[key];
|
|
290
|
+
let actValue = actual[key];
|
|
291
|
+
|
|
292
|
+
return compare(expValue, actValue);
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* A function to deep compare (equality for primitive data types and containership for Objects and Arrays)
|
|
298
|
+
*
|
|
299
|
+
* ```
|
|
300
|
+
* compare(1, 1); // true
|
|
301
|
+
* compare(1, "1"); // false
|
|
302
|
+
* compare([1, 2], [3, 1, 2]); // true
|
|
303
|
+
* compare({a:1, b:2}, {b:2, c:3, a:1}); // true
|
|
304
|
+
* compare([1, [2]], [[3, 2], 1, 4]); // true
|
|
305
|
+
* compare({a: [1, 2], b: {c:3}}, {b: {d:4, c:3}, a:[3, 2, 1]}); // true
|
|
306
|
+
* ```
|
|
307
|
+
*
|
|
308
|
+
* @param {*} expVal The expected value
|
|
309
|
+
* @param {*} actVal The actual value
|
|
310
|
+
* @returns {Boolean} Whether the expVal is equal to or deeply contained in actVal
|
|
311
|
+
*/
|
|
312
|
+
function compare(expVal, actVal) {
|
|
313
|
+
let expType = Object.prototype.toString.call(expVal);
|
|
314
|
+
let actType = Object.prototype.toString.call(actVal);
|
|
315
|
+
|
|
316
|
+
if (expVal === null) {
|
|
317
|
+
return actVal === null;
|
|
318
|
+
} else if (expType !== actType) {
|
|
319
|
+
return false;
|
|
320
|
+
} else if (expType === '[object Array]') {
|
|
321
|
+
return expVal.every(function (e) {
|
|
322
|
+
return actVal.some(function (a) {
|
|
323
|
+
return compare(e, a);
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
} else if (expType === '[object Object]') {
|
|
327
|
+
return Object.keys(expVal).every(function (k) {
|
|
328
|
+
return Object.keys(actVal).includes(k) && compare(expVal[k], actVal[k]);
|
|
329
|
+
});
|
|
330
|
+
} else {
|
|
331
|
+
return expVal === actVal;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
module.exports = {
|
|
336
|
+
matchByEventType,
|
|
337
|
+
matchBySchema,
|
|
338
|
+
matchByVals,
|
|
339
|
+
matchByParams,
|
|
340
|
+
matchByContexts,
|
|
341
|
+
matchByHeader,
|
|
342
|
+
matchEvents,
|
|
343
|
+
compare,
|
|
344
|
+
request,
|
|
345
|
+
requestJson,
|
|
346
|
+
};
|