mixpanel-react-native 3.1.1 → 3.1.2
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/.vscode/settings.json +3 -0
- package/CHANGELOG.md +11 -0
- package/Samples/MixpanelExample/.bundle/config +2 -0
- package/Samples/MixpanelExample/.eslintrc.js +4 -0
- package/Samples/MixpanelExample/.prettierrc.js +7 -0
- package/Samples/MixpanelExample/.watchmanconfig +1 -0
- package/Samples/MixpanelExample/App.tsx +143 -0
- package/Samples/MixpanelExample/Gemfile +16 -0
- package/Samples/MixpanelExample/README.md +97 -0
- package/Samples/MixpanelExample/__tests__/App.test.tsx +13 -0
- package/Samples/MixpanelExample/android/app/build.gradle +119 -0
- package/Samples/MixpanelExample/android/app/debug.keystore +0 -0
- package/Samples/MixpanelExample/android/app/proguard-rules.pro +10 -0
- package/Samples/MixpanelExample/android/app/src/debug/AndroidManifest.xml +9 -0
- package/Samples/MixpanelExample/android/app/src/main/AndroidManifest.xml +26 -0
- package/Samples/MixpanelExample/android/app/src/main/java/com/mixpanelexample/MainActivity.kt +22 -0
- package/Samples/MixpanelExample/android/app/src/main/java/com/mixpanelexample/MainApplication.kt +44 -0
- package/Samples/MixpanelExample/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/Samples/MixpanelExample/android/app/src/main/res/values/strings.xml +3 -0
- package/Samples/MixpanelExample/android/app/src/main/res/values/styles.xml +9 -0
- package/Samples/MixpanelExample/android/build.gradle +21 -0
- package/Samples/MixpanelExample/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/Samples/MixpanelExample/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/Samples/MixpanelExample/android/gradle.properties +39 -0
- package/Samples/MixpanelExample/android/gradlew +251 -0
- package/Samples/MixpanelExample/android/gradlew.bat +94 -0
- package/Samples/MixpanelExample/android/settings.gradle +6 -0
- package/Samples/MixpanelExample/app.json +4 -0
- package/Samples/MixpanelExample/babel.config.js +3 -0
- package/Samples/MixpanelExample/index.js +9 -0
- package/Samples/MixpanelExample/ios/.xcode.env +11 -0
- package/Samples/MixpanelExample/ios/MixpanelExample/AppDelegate.swift +48 -0
- package/Samples/MixpanelExample/ios/MixpanelExample/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- package/Samples/MixpanelExample/ios/MixpanelExample/Images.xcassets/Contents.json +6 -0
- package/Samples/MixpanelExample/ios/MixpanelExample/Info.plist +52 -0
- package/Samples/MixpanelExample/ios/MixpanelExample/LaunchScreen.storyboard +47 -0
- package/Samples/MixpanelExample/ios/MixpanelExample/PrivacyInfo.xcprivacy +37 -0
- package/Samples/MixpanelExample/ios/MixpanelExample.xcodeproj/project.pbxproj +505 -0
- package/Samples/MixpanelExample/ios/MixpanelExample.xcodeproj/xcshareddata/xcschemes/MixpanelExample.xcscheme +88 -0
- package/Samples/MixpanelExample/ios/Podfile +35 -0
- package/Samples/MixpanelExample/jest.config.js +3 -0
- package/Samples/MixpanelExample/metro.config.js +22 -0
- package/Samples/MixpanelExample/package-lock.json +12456 -0
- package/Samples/MixpanelExample/package.json +42 -0
- package/Samples/MixpanelExample/tsconfig.json +3 -0
- package/__tests__/jest_setup.js +5 -5
- package/__tests__/persistent.test.js +6 -55
- package/javascript/mixpanel-persistent.js +3 -10
- package/package.json +2 -4
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "MixpanelExample",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"android": "react-native run-android",
|
|
7
|
+
"ios": "react-native run-ios",
|
|
8
|
+
"lint": "eslint .",
|
|
9
|
+
"start": "react-native start",
|
|
10
|
+
"test": "jest"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@react-native-async-storage/async-storage": "^1.24.0",
|
|
14
|
+
"mixpanel-react-native": "file:../..",
|
|
15
|
+
"react": "19.0.0",
|
|
16
|
+
"react-native": "0.79.3",
|
|
17
|
+
"uuid": "^3.3.2"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@babel/core": "^7.25.2",
|
|
21
|
+
"@babel/preset-env": "^7.25.3",
|
|
22
|
+
"@babel/runtime": "^7.25.0",
|
|
23
|
+
"@react-native-community/cli": "18.0.0",
|
|
24
|
+
"@react-native-community/cli-platform-android": "18.0.0",
|
|
25
|
+
"@react-native-community/cli-platform-ios": "18.0.0",
|
|
26
|
+
"@react-native/babel-preset": "0.79.3",
|
|
27
|
+
"@react-native/eslint-config": "0.79.3",
|
|
28
|
+
"@react-native/metro-config": "0.79.3",
|
|
29
|
+
"@react-native/typescript-config": "0.79.3",
|
|
30
|
+
"@types/jest": "^29.5.13",
|
|
31
|
+
"@types/react": "^19.0.0",
|
|
32
|
+
"@types/react-test-renderer": "^19.0.0",
|
|
33
|
+
"eslint": "^8.19.0",
|
|
34
|
+
"jest": "^29.6.3",
|
|
35
|
+
"prettier": "2.8.8",
|
|
36
|
+
"react-test-renderer": "19.0.0",
|
|
37
|
+
"typescript": "5.0.4"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/__tests__/jest_setup.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as ReactNative from "react-native";
|
|
2
2
|
import { jest } from "@jest/globals";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
})
|
|
4
|
+
// Mock react-native-get-random-values polyfill
|
|
5
|
+
jest.mock("react-native-get-random-values", () => {
|
|
6
|
+
// Polyfill is imported for side effects, no need to mock specific functions
|
|
7
|
+
return {};
|
|
8
|
+
});
|
|
9
9
|
|
|
10
10
|
jest.mock("mixpanel-react-native/javascript/mixpanel-storage", () => {
|
|
11
11
|
return {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
//
|
|
2
|
-
// So we'll use jest.isolateModules to get a fresh instance
|
|
1
|
+
// Test UUID generation with polyfilled crypto.getRandomValues
|
|
3
2
|
describe("MixpanelPersistent - UUID Generation", () => {
|
|
4
3
|
const token = "test-token";
|
|
5
4
|
|
|
@@ -7,25 +6,17 @@ describe("MixpanelPersistent - UUID Generation", () => {
|
|
|
7
6
|
jest.clearAllMocks();
|
|
8
7
|
});
|
|
9
8
|
|
|
10
|
-
it("should
|
|
9
|
+
it("should generate device ID using uuid.v4() with polyfill", async () => {
|
|
11
10
|
let mixpanelPersistent;
|
|
12
11
|
|
|
13
12
|
await jest.isolateModules(async () => {
|
|
14
|
-
// Mock expo-crypto to throw an error
|
|
15
|
-
jest.doMock("expo-crypto", () => ({
|
|
16
|
-
randomUUID: jest.fn(() => {
|
|
17
|
-
throw new Error("Expo crypto not available");
|
|
18
|
-
}),
|
|
19
|
-
}));
|
|
20
|
-
|
|
21
13
|
// Mock uuid to return a specific value
|
|
22
14
|
jest.doMock("uuid", () => ({
|
|
23
|
-
v4: jest.fn(() => "
|
|
15
|
+
v4: jest.fn(() => "polyfilled-uuid-1234"),
|
|
24
16
|
}));
|
|
25
17
|
|
|
26
18
|
// Now require the modules
|
|
27
19
|
const { MixpanelPersistent } = require("mixpanel-react-native/javascript/mixpanel-persistent");
|
|
28
|
-
const { randomUUID } = require("expo-crypto");
|
|
29
20
|
const uuid = require("uuid");
|
|
30
21
|
|
|
31
22
|
// Create instance
|
|
@@ -35,51 +26,11 @@ describe("MixpanelPersistent - UUID Generation", () => {
|
|
|
35
26
|
// Load device ID (which triggers UUID generation)
|
|
36
27
|
await mixpanelPersistent.loadDeviceId(token);
|
|
37
28
|
|
|
38
|
-
// Verify
|
|
39
|
-
expect(randomUUID).toHaveBeenCalled();
|
|
40
|
-
|
|
41
|
-
// Verify uuid.v4 was called as fallback
|
|
29
|
+
// Verify uuid.v4 was called
|
|
42
30
|
expect(uuid.v4).toHaveBeenCalled();
|
|
43
31
|
|
|
44
|
-
// Verify the device ID was set
|
|
45
|
-
expect(mixpanelPersistent.getDeviceId(token)).toBe("
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("should use expo-crypto randomUUID when available", async () => {
|
|
50
|
-
let mixpanelPersistent;
|
|
51
|
-
|
|
52
|
-
await jest.isolateModules(async () => {
|
|
53
|
-
// Mock expo-crypto to return a specific value
|
|
54
|
-
jest.doMock("expo-crypto", () => ({
|
|
55
|
-
randomUUID: jest.fn(() => "expo-uuid-5678"),
|
|
56
|
-
}));
|
|
57
|
-
|
|
58
|
-
// Mock uuid
|
|
59
|
-
jest.doMock("uuid", () => ({
|
|
60
|
-
v4: jest.fn(() => "should-not-be-called"),
|
|
61
|
-
}));
|
|
62
|
-
|
|
63
|
-
// Now require the modules
|
|
64
|
-
const { MixpanelPersistent } = require("mixpanel-react-native/javascript/mixpanel-persistent");
|
|
65
|
-
const { randomUUID } = require("expo-crypto");
|
|
66
|
-
const uuid = require("uuid");
|
|
67
|
-
|
|
68
|
-
// Create instance
|
|
69
|
-
MixpanelPersistent.instance = null;
|
|
70
|
-
mixpanelPersistent = MixpanelPersistent.getInstance(null, token);
|
|
71
|
-
|
|
72
|
-
// Load device ID
|
|
73
|
-
await mixpanelPersistent.loadDeviceId(token);
|
|
74
|
-
|
|
75
|
-
// Verify randomUUID was called
|
|
76
|
-
expect(randomUUID).toHaveBeenCalled();
|
|
77
|
-
|
|
78
|
-
// Verify uuid.v4 was NOT called
|
|
79
|
-
expect(uuid.v4).not.toHaveBeenCalled();
|
|
80
|
-
|
|
81
|
-
// Verify the device ID was set to the expo value
|
|
82
|
-
expect(mixpanelPersistent.getDeviceId(token)).toBe("expo-uuid-5678");
|
|
32
|
+
// Verify the device ID was set
|
|
33
|
+
expect(mixpanelPersistent.getDeviceId(token)).toBe("polyfilled-uuid-1234");
|
|
83
34
|
});
|
|
84
35
|
});
|
|
85
36
|
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
getAppHasOpenedBeforeKey,
|
|
10
10
|
} from "./mixpanel-constants";
|
|
11
11
|
|
|
12
|
+
import "react-native-get-random-values"; // Polyfill for crypto.getRandomValues
|
|
12
13
|
import { AsyncStorageAdapter } from "./mixpanel-storage";
|
|
13
14
|
import uuid from "uuid";
|
|
14
15
|
import { MixpanelLogger } from "mixpanel-react-native/javascript/mixpanel-logger";
|
|
@@ -66,16 +67,8 @@ export class MixpanelPersistent {
|
|
|
66
67
|
this._identity[token].deviceId = storageToken;
|
|
67
68
|
|
|
68
69
|
if (!this._identity[token].deviceId) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// Try to use expo-crypto if available
|
|
72
|
-
const expoCrypto = require("expo-crypto");
|
|
73
|
-
newDeviceId = expoCrypto.randomUUID();
|
|
74
|
-
} catch (e) {
|
|
75
|
-
// Fallback to uuid.v4() if expo-crypto is not available
|
|
76
|
-
newDeviceId = uuid.v4();
|
|
77
|
-
}
|
|
78
|
-
this._identity[token].deviceId = newDeviceId;
|
|
70
|
+
// Generate device ID using uuid.v4() with polyfilled crypto.getRandomValues
|
|
71
|
+
this._identity[token].deviceId = uuid.v4();
|
|
79
72
|
await this.storageAdapter.setItem(
|
|
80
73
|
getDeviceIdKey(token),
|
|
81
74
|
this._identity[token].deviceId
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mixpanel-react-native",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "Official React Native Tracking Library for Mixpanel Analytics",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -60,9 +60,7 @@
|
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@react-native-async-storage/async-storage": "^1.21.0",
|
|
63
|
+
"react-native-get-random-values": "^1.9.0",
|
|
63
64
|
"uuid": "3.3.2"
|
|
64
|
-
},
|
|
65
|
-
"optionalDependencies": {
|
|
66
|
-
"expo-crypto": "~14.1.4"
|
|
67
65
|
}
|
|
68
66
|
}
|