react-native-mparticle 2.8.0 → 2.9.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 (37) hide show
  1. package/README.md +252 -94
  2. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  3. package/android/gradle/wrapper/gradle-wrapper.properties +6 -0
  4. package/android/gradle.properties +26 -0
  5. package/android/gradlew +160 -0
  6. package/android/gradlew.bat +90 -0
  7. package/android/libs/java-json.jar +0 -0
  8. package/android/src/main/java/com/mparticle/react/MParticleModule.kt +2 -2
  9. package/android/src/test/java/com/mparticle/react/IdentityApiTest.java +230 -0
  10. package/android/src/test/java/com/mparticle/react/MParticleUserTest.java +173 -0
  11. package/android/src/test/java/com/mparticle/react/testutils/MockMParticleUser.java +109 -0
  12. package/android/src/test/java/com/mparticle/react/testutils/MockMap.java +203 -0
  13. package/android/src/test/java/com/mparticle/react/testutils/MockReadableArray.java +68 -0
  14. package/android/src/test/java/com/mparticle/react/testutils/MockWritableMap.java +4 -0
  15. package/android/src/test/java/com/mparticle/react/testutils/Mutable.java +13 -0
  16. package/app.plugin.js +1 -0
  17. package/ios/RNMParticle/RNMPRokt.mm +25 -11
  18. package/ios/RNMParticle/RNMParticle.mm +38 -28
  19. package/js/codegenSpecs/NativeMParticle.ts +3 -4
  20. package/js/rokt/rokt-layout-view.android.tsx +2 -1
  21. package/lib/codegenSpecs/NativeMParticle.d.ts +3 -4
  22. package/lib/codegenSpecs/NativeMParticle.js.map +1 -1
  23. package/lib/rokt/rokt-layout-view.android.js +1 -0
  24. package/lib/rokt/rokt-layout-view.android.js.map +1 -1
  25. package/package.json +28 -4
  26. package/plugin/build/withMParticle.d.ts +60 -0
  27. package/plugin/build/withMParticle.js +30 -0
  28. package/plugin/build/withMParticleAndroid.d.ts +6 -0
  29. package/plugin/build/withMParticleAndroid.js +266 -0
  30. package/plugin/build/withMParticleIOS.d.ts +6 -0
  31. package/plugin/build/withMParticleIOS.js +362 -0
  32. package/plugin/src/withMParticle.ts +106 -0
  33. package/plugin/src/withMParticleAndroid.ts +359 -0
  34. package/plugin/src/withMParticleIOS.ts +459 -0
  35. package/plugin/tsconfig.json +8 -0
  36. package/react-native-mparticle.podspec +11 -0
  37. package/SECURITY.md +0 -9
package/package.json CHANGED
@@ -4,31 +4,55 @@
4
4
  "homepage": "https://www.mparticle.com",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "mParticle/react-native-mparticle",
7
- "version": "2.8.0",
7
+ "version": "2.9.0",
8
8
  "main": "lib/index.js",
9
9
  "types": "lib/index.d.ts",
10
10
  "react-native": "js/index",
11
11
  "scripts": {
12
12
  "build": "tsc",
13
+ "build:plugin": "tsc --build plugin",
13
14
  "clean": "rm -rf lib",
14
- "prepare": "yarn clean && yarn build",
15
- "dev:pack": "yarn build && yarn pack --filename react-native-mparticle-latest.tgz",
15
+ "clean:plugin": "rm -rf plugin/build",
16
+ "prepare": "yarn clean && yarn build && yarn build:plugin",
17
+ "dev:pack": "yarn build && yarn build:plugin && yarn pack --filename react-native-mparticle-latest.tgz",
16
18
  "dev:link": "./dev-link.sh",
17
19
  "lint": "eslint '{js,lib}/**/*.{ts,tsx}' --fix",
18
20
  "format": "prettier --write '{js,lib}/**/*.{ts,tsx}'",
19
21
  "test": "npm run lint"
20
22
  },
23
+ "files": [
24
+ "android",
25
+ "ios",
26
+ "js",
27
+ "lib",
28
+ "react-native-mparticle.podspec",
29
+ "app.plugin.js",
30
+ "plugin"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public",
34
+ "provenance": true,
35
+ "registry": "https://registry.npmjs.org"
36
+ },
21
37
  "dependencies": {},
22
38
  "peerDependencies": {
23
39
  "react": ">= 16.0.0-alpha.12",
24
- "react-native": ">= 0.45.0"
40
+ "react-native": ">= 0.45.0",
41
+ "@expo/config-plugins": ">=7.0.0"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "@expo/config-plugins": {
45
+ "optional": true
46
+ }
25
47
  },
26
48
  "devDependencies": {
49
+ "@expo/config-plugins": "^7.2.5",
27
50
  "@typescript-eslint/eslint-plugin": "^5.62.0",
28
51
  "@typescript-eslint/parser": "^5.62.0",
29
52
  "eslint": "^8.45.0",
30
53
  "eslint-config-prettier": "^8.10.0",
31
54
  "eslint-plugin-prettier": "^4.2.1",
55
+ "expo-module-scripts": "^3.0.0",
32
56
  "prettier": "^2.8.8",
33
57
  "@types/react": "^18.0.0",
34
58
  "@types/react-native": "^0.70.0",
@@ -0,0 +1,60 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ /**
3
+ * mParticle plugin configuration options
4
+ */
5
+ export interface MParticlePluginProps {
6
+ /**
7
+ * iOS API key from mParticle dashboard
8
+ */
9
+ iosApiKey: string;
10
+ /**
11
+ * iOS API secret from mParticle dashboard
12
+ */
13
+ iosApiSecret: string;
14
+ /**
15
+ * Android API key from mParticle dashboard
16
+ */
17
+ androidApiKey: string;
18
+ /**
19
+ * Android API secret from mParticle dashboard
20
+ */
21
+ androidApiSecret: string;
22
+ /**
23
+ * Log level for debugging
24
+ * @default 'none'
25
+ */
26
+ logLevel?: 'none' | 'error' | 'warning' | 'debug' | 'verbose';
27
+ /**
28
+ * mParticle environment
29
+ * @default 'autoDetect'
30
+ */
31
+ environment?: 'development' | 'production' | 'autoDetect';
32
+ /**
33
+ * Data plan ID for validation
34
+ */
35
+ dataPlanId?: string;
36
+ /**
37
+ * Data plan version for validation
38
+ */
39
+ dataPlanVersion?: number;
40
+ /**
41
+ * iOS kit pod names to include
42
+ * @example ['mParticle-Rokt', 'mParticle-Amplitude']
43
+ */
44
+ iosKits?: string[];
45
+ /**
46
+ * Android kit artifact names to include (version auto-detected from core SDK)
47
+ * @example ['android-rokt-kit', 'android-amplitude-kit']
48
+ */
49
+ androidKits?: string[];
50
+ /**
51
+ * Whether to use an empty identify request at initialization
52
+ * If true or omitted, uses requestWithEmptyUser/withEmptyUser()
53
+ * If false, no identify request is made at initialization
54
+ * Identity should be updated from React Native code after initialization
55
+ * @default true
56
+ */
57
+ useEmptyIdentifyRequest?: boolean;
58
+ }
59
+ declare const _default: ConfigPlugin<MParticlePluginProps>;
60
+ export default _default;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_plugins_1 = require("@expo/config-plugins");
4
+ const withMParticleIOS_1 = require("./withMParticleIOS");
5
+ const withMParticleAndroid_1 = require("./withMParticleAndroid");
6
+ const pkg = require('../../package.json');
7
+ /**
8
+ * Expo Config Plugin for mParticle React Native SDK
9
+ *
10
+ * This plugin configures your Expo project to use the mParticle SDK by:
11
+ * - Adding mParticle SDK initialization to iOS AppDelegate
12
+ * - Adding mParticle SDK initialization to Android MainApplication
13
+ * - Adding kit dependencies to iOS Podfile
14
+ * - Adding kit dependencies to Android build.gradle
15
+ */
16
+ const withMParticle = (config, props) => {
17
+ // Validate required props
18
+ if (!props.iosApiKey || !props.iosApiSecret) {
19
+ throw new Error('react-native-mparticle plugin requires iosApiKey and iosApiSecret');
20
+ }
21
+ if (!props.androidApiKey || !props.androidApiSecret) {
22
+ throw new Error('react-native-mparticle plugin requires androidApiKey and androidApiSecret');
23
+ }
24
+ // Apply iOS modifications
25
+ config = (0, withMParticleIOS_1.withMParticleIOS)(config, props);
26
+ // Apply Android modifications
27
+ config = (0, withMParticleAndroid_1.withMParticleAndroid)(config, props);
28
+ return config;
29
+ };
30
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withMParticle, pkg.name, pkg.version);
@@ -0,0 +1,6 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ import { MParticlePluginProps } from './withMParticle';
3
+ /**
4
+ * Apply all Android-specific mParticle configurations
5
+ */
6
+ export declare const withMParticleAndroid: ConfigPlugin<MParticlePluginProps>;
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withMParticleAndroid = void 0;
4
+ const config_plugins_1 = require("@expo/config-plugins");
5
+ const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
6
+ // Tag used for mergeContents to identify code blocks added by this plugin
7
+ const MPARTICLE_TAG = 'react-native-mparticle';
8
+ /**
9
+ * Get the mParticle log level string for Android
10
+ */
11
+ function getAndroidLogLevel(logLevel) {
12
+ switch (logLevel) {
13
+ case 'none':
14
+ return 'MParticle.LogLevel.NONE';
15
+ case 'error':
16
+ return 'MParticle.LogLevel.ERROR';
17
+ case 'warning':
18
+ return 'MParticle.LogLevel.WARNING';
19
+ case 'debug':
20
+ return 'MParticle.LogLevel.DEBUG';
21
+ case 'verbose':
22
+ return 'MParticle.LogLevel.VERBOSE';
23
+ default:
24
+ return null;
25
+ }
26
+ }
27
+ /**
28
+ * Get the mParticle environment string for Android
29
+ */
30
+ function getAndroidEnvironment(environment) {
31
+ switch (environment) {
32
+ case 'development':
33
+ return 'MParticle.Environment.Development';
34
+ case 'production':
35
+ return 'MParticle.Environment.Production';
36
+ case 'autoDetect':
37
+ return 'MParticle.Environment.AutoDetect';
38
+ default:
39
+ return null;
40
+ }
41
+ }
42
+ /**
43
+ * Generate mParticle initialization code for Kotlin MainApplication
44
+ */
45
+ function generateKotlinInitCode(props) {
46
+ const { androidApiKey, androidApiSecret, logLevel, environment, useEmptyIdentifyRequest = true, dataPlanId, dataPlanVersion, } = props;
47
+ const lines = [
48
+ '// mParticle SDK initialization',
49
+ 'val mParticleOptions = MParticleOptions.builder(this)',
50
+ ` .credentials("${androidApiKey}", "${androidApiSecret}")`,
51
+ ];
52
+ const androidLogLevel = getAndroidLogLevel(logLevel);
53
+ if (androidLogLevel) {
54
+ lines.push(` .logLevel(${androidLogLevel})`);
55
+ }
56
+ const androidEnvironment = getAndroidEnvironment(environment);
57
+ if (androidEnvironment) {
58
+ lines.push(` .environment(${androidEnvironment})`);
59
+ }
60
+ if (dataPlanId) {
61
+ const versionParam = dataPlanVersion ? `, ${dataPlanVersion}` : '';
62
+ lines.push(` .dataplan("${dataPlanId}"${versionParam})`);
63
+ }
64
+ if (useEmptyIdentifyRequest) {
65
+ lines.push(' .identify(IdentityApiRequest.withEmptyUser().build())');
66
+ }
67
+ lines.push(' .build()');
68
+ lines.push('MParticle.start(mParticleOptions)');
69
+ return lines.join('\n ');
70
+ }
71
+ /**
72
+ * Generate mParticle initialization code for Java MainApplication
73
+ */
74
+ function generateJavaInitCode(props) {
75
+ const { androidApiKey, androidApiSecret, logLevel, environment, useEmptyIdentifyRequest = true, dataPlanId, dataPlanVersion, } = props;
76
+ const lines = [
77
+ '// mParticle SDK initialization',
78
+ 'MParticleOptions.Builder optionsBuilder = MParticleOptions.builder(this)',
79
+ ` .credentials("${androidApiKey}", "${androidApiSecret}")`,
80
+ ];
81
+ const androidLogLevel = getAndroidLogLevel(logLevel);
82
+ if (androidLogLevel) {
83
+ lines.push(` .logLevel(${androidLogLevel})`);
84
+ }
85
+ const androidEnvironment = getAndroidEnvironment(environment);
86
+ if (androidEnvironment) {
87
+ lines.push(` .environment(${androidEnvironment})`);
88
+ }
89
+ if (dataPlanId) {
90
+ const versionParam = dataPlanVersion ? `, ${dataPlanVersion}` : '';
91
+ lines.push(` .dataplan("${dataPlanId}"${versionParam})`);
92
+ }
93
+ if (useEmptyIdentifyRequest) {
94
+ lines.push(' .identify(IdentityApiRequest.withEmptyUser().build())');
95
+ }
96
+ // Java needs semicolons
97
+ lines.push(';');
98
+ lines.push('MParticle.start(optionsBuilder.build());');
99
+ return lines.join('\n ');
100
+ }
101
+ /**
102
+ * Generate mParticle import statements for Kotlin
103
+ */
104
+ function getKotlinImports() {
105
+ return `import com.mparticle.MParticle
106
+ import com.mparticle.MParticleOptions
107
+ import com.mparticle.identity.IdentityApiRequest`;
108
+ }
109
+ /**
110
+ * Generate mParticle import statements for Java
111
+ */
112
+ function getJavaImports() {
113
+ return `import com.mparticle.MParticle;
114
+ import com.mparticle.MParticleOptions;
115
+ import com.mparticle.identity.IdentityApiRequest;`;
116
+ }
117
+ /**
118
+ * Add mParticle configuration to MainApplication
119
+ * Handles both Kotlin and Java
120
+ */
121
+ const withMParticleMainApplication = (config, props) => {
122
+ return (0, config_plugins_1.withMainApplication)(config, config => {
123
+ const { contents, language } = config.modResults;
124
+ // Check if mParticle is already initialized
125
+ if (contents.includes('MParticleOptions') ||
126
+ contents.includes('mParticleOptions')) {
127
+ return config;
128
+ }
129
+ const isKotlin = language === 'kt';
130
+ if (isKotlin) {
131
+ config.modResults.contents = addMParticleToKotlinMainApplication(contents, props);
132
+ }
133
+ else if (language === 'java') {
134
+ config.modResults.contents = addMParticleToJavaMainApplication(contents, props);
135
+ }
136
+ else {
137
+ console.warn(`[react-native-mparticle] Unsupported MainApplication language: ${language}. ` +
138
+ 'mParticle initialization must be added manually.');
139
+ }
140
+ return config;
141
+ });
142
+ };
143
+ /**
144
+ * Add mParticle import and initialization to Kotlin MainApplication
145
+ */
146
+ function addMParticleToKotlinMainApplication(contents, props) {
147
+ // Add import statements using mergeContents
148
+ const withImports = (0, generateCode_1.mergeContents)({
149
+ src: contents,
150
+ newSrc: getKotlinImports(),
151
+ anchor: /^package .+$/m,
152
+ offset: 1,
153
+ tag: `${MPARTICLE_TAG}-import`,
154
+ comment: '//',
155
+ });
156
+ // Generate initialization code
157
+ const initCode = generateKotlinInitCode(props);
158
+ // Find the right place to add initialization code
159
+ // Try ApplicationLifecycleDispatcher first (Expo pattern), then super.onCreate()
160
+ let result = withImports.contents;
161
+ if (result.includes('ApplicationLifecycleDispatcher.onApplicationCreate(this)')) {
162
+ const withInit = (0, generateCode_1.mergeContents)({
163
+ src: result,
164
+ newSrc: `\n ${initCode}\n`,
165
+ anchor: /ApplicationLifecycleDispatcher\.onApplicationCreate\(this\)/,
166
+ offset: 1,
167
+ tag: `${MPARTICLE_TAG}-init`,
168
+ comment: '//',
169
+ });
170
+ result = withInit.contents;
171
+ }
172
+ else if (result.includes('super.onCreate()')) {
173
+ const withInit = (0, generateCode_1.mergeContents)({
174
+ src: result,
175
+ newSrc: `\n ${initCode}\n`,
176
+ anchor: /super\.onCreate\(\)/,
177
+ offset: 1,
178
+ tag: `${MPARTICLE_TAG}-init`,
179
+ comment: '//',
180
+ });
181
+ result = withInit.contents;
182
+ }
183
+ return result;
184
+ }
185
+ /**
186
+ * Add mParticle import and initialization to Java MainApplication
187
+ */
188
+ function addMParticleToJavaMainApplication(contents, props) {
189
+ // Add import statements using mergeContents
190
+ const withImports = (0, generateCode_1.mergeContents)({
191
+ src: contents,
192
+ newSrc: getJavaImports(),
193
+ anchor: /^package .+;$/m,
194
+ offset: 1,
195
+ tag: `${MPARTICLE_TAG}-import`,
196
+ comment: '//',
197
+ });
198
+ // Generate initialization code
199
+ const initCode = generateJavaInitCode(props);
200
+ // Find the right place to add initialization code
201
+ let result = withImports.contents;
202
+ if (result.includes('ApplicationLifecycleDispatcher.onApplicationCreate(this);')) {
203
+ const withInit = (0, generateCode_1.mergeContents)({
204
+ src: result,
205
+ newSrc: `\n ${initCode}\n`,
206
+ anchor: /ApplicationLifecycleDispatcher\.onApplicationCreate\(this\);/,
207
+ offset: 1,
208
+ tag: `${MPARTICLE_TAG}-init`,
209
+ comment: '//',
210
+ });
211
+ result = withInit.contents;
212
+ }
213
+ else if (result.includes('super.onCreate();')) {
214
+ const withInit = (0, generateCode_1.mergeContents)({
215
+ src: result,
216
+ newSrc: `\n ${initCode}\n`,
217
+ anchor: /super\.onCreate\(\);/,
218
+ offset: 1,
219
+ tag: `${MPARTICLE_TAG}-init`,
220
+ comment: '//',
221
+ });
222
+ result = withInit.contents;
223
+ }
224
+ return result;
225
+ }
226
+ /**
227
+ * Add kit dependencies to app/build.gradle
228
+ */
229
+ const withMParticleAppBuildGradle = (config, props) => {
230
+ return (0, config_plugins_1.withAppBuildGradle)(config, config => {
231
+ const { contents } = config.modResults;
232
+ if (!props.androidKits || props.androidKits.length === 0) {
233
+ return config;
234
+ }
235
+ // Check if kits are already added
236
+ const kitsAlreadyAdded = props.androidKits.every(kit => contents.includes(`com.mparticle:${kit}`));
237
+ if (kitsAlreadyAdded) {
238
+ return config;
239
+ }
240
+ // Generate kit dependency lines
241
+ // Use + for version to auto-match core SDK version
242
+ const kitDependencies = props.androidKits
243
+ .map(kit => ` implementation "com.mparticle:${kit}:+"`)
244
+ .join('\n');
245
+ // Use mergeContents for idempotent injection
246
+ const withKits = (0, generateCode_1.mergeContents)({
247
+ src: contents,
248
+ newSrc: `\n // mParticle kits\n${kitDependencies}`,
249
+ anchor: /dependencies\s*\{/,
250
+ offset: 1,
251
+ tag: `${MPARTICLE_TAG}-kits`,
252
+ comment: '//',
253
+ });
254
+ config.modResults.contents = withKits.contents;
255
+ return config;
256
+ });
257
+ };
258
+ /**
259
+ * Apply all Android-specific mParticle configurations
260
+ */
261
+ const withMParticleAndroid = (config, props) => {
262
+ config = withMParticleMainApplication(config, props);
263
+ config = withMParticleAppBuildGradle(config, props);
264
+ return config;
265
+ };
266
+ exports.withMParticleAndroid = withMParticleAndroid;
@@ -0,0 +1,6 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ import { MParticlePluginProps } from './withMParticle';
3
+ /**
4
+ * Apply all iOS-specific mParticle configurations
5
+ */
6
+ export declare const withMParticleIOS: ConfigPlugin<MParticlePluginProps>;