react-native-mparticle 2.7.13 → 2.8.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 (172) hide show
  1. package/SECURITY.md +9 -0
  2. package/android/build.gradle +65 -10
  3. package/android/src/main/AndroidManifestNew.xml +3 -0
  4. package/android/src/main/java/com/mparticle/react/MParticleModule.kt +976 -0
  5. package/android/src/main/java/com/mparticle/react/MParticlePackage.kt +68 -0
  6. package/android/src/main/java/com/mparticle/react/rokt/MPRoktModuleImpl.kt +251 -0
  7. package/android/src/main/java/com/mparticle/react/rokt/RoktLayoutViewManagerImpl.kt +79 -0
  8. package/android/src/newarch/java/com/mparticle/react/rokt/MPRoktModule.kt +130 -0
  9. package/android/src/newarch/java/com/mparticle/react/rokt/RoktLayoutViewManager.kt +22 -0
  10. package/android/src/oldarch/java/com/mparticle/react/NativeMPRoktSpec.kt +29 -0
  11. package/android/src/oldarch/java/com/mparticle/react/NativeMParticleSpec.kt +153 -0
  12. package/android/src/oldarch/java/com/mparticle/react/rokt/MPRoktModule.kt +79 -0
  13. package/android/src/oldarch/java/com/mparticle/react/rokt/RoktLayoutViewManager.kt +34 -0
  14. package/ios/RNMParticle/RNMPRokt.h +15 -0
  15. package/ios/RNMParticle/RNMPRokt.mm +247 -0
  16. package/ios/RNMParticle/RNMParticle.h +6 -1
  17. package/ios/RNMParticle/RNMParticle.mm +1199 -0
  18. package/ios/RNMParticle/RoktEventManager.h +16 -0
  19. package/ios/RNMParticle/RoktEventManager.m +174 -0
  20. package/ios/RNMParticle/RoktLayoutManager.m +22 -0
  21. package/ios/RNMParticle/RoktNativeLayoutComponentView.h +18 -0
  22. package/ios/RNMParticle/RoktNativeLayoutComponentView.mm +50 -0
  23. package/ios/RNMParticle.xcodeproj/project.pbxproj +29 -6
  24. package/js/codegenSpecs/NativeMParticle.ts +214 -0
  25. package/js/codegenSpecs/rokt/NativeMPRokt.ts +32 -0
  26. package/js/codegenSpecs/rokt/RoktLayoutNativeComponent.ts +29 -0
  27. package/js/index.tsx +940 -0
  28. package/js/rokt/rokt-layout-view.android.tsx +133 -0
  29. package/js/rokt/rokt-layout-view.ios.tsx +121 -0
  30. package/js/rokt/rokt-layout-view.tsx +15 -0
  31. package/js/rokt/rokt.ts +87 -0
  32. package/js/utils/architecture.ts +22 -0
  33. package/lib/codegenSpecs/NativeMParticle.d.ts +148 -0
  34. package/lib/codegenSpecs/NativeMParticle.js +5 -0
  35. package/lib/codegenSpecs/NativeMParticle.js.map +1 -0
  36. package/lib/codegenSpecs/rokt/NativeMPRokt.d.ts +24 -0
  37. package/lib/codegenSpecs/rokt/NativeMPRokt.js +5 -0
  38. package/lib/codegenSpecs/rokt/NativeMPRokt.js.map +1 -0
  39. package/lib/codegenSpecs/rokt/RoktLayoutNativeComponent.d.ts +18 -0
  40. package/lib/codegenSpecs/rokt/RoktLayoutNativeComponent.js +8 -0
  41. package/lib/codegenSpecs/rokt/RoktLayoutNativeComponent.js.map +1 -0
  42. package/lib/index.d.ts +410 -0
  43. package/lib/index.js +645 -0
  44. package/lib/index.js.map +1 -0
  45. package/lib/rokt/rokt-layout-view.android.d.ts +39 -0
  46. package/lib/rokt/rokt-layout-view.android.js +109 -0
  47. package/lib/rokt/rokt-layout-view.android.js.map +1 -0
  48. package/lib/rokt/rokt-layout-view.d.ts +5 -0
  49. package/lib/rokt/rokt-layout-view.ios.d.ts +32 -0
  50. package/lib/rokt/rokt-layout-view.ios.js +84 -0
  51. package/lib/rokt/rokt-layout-view.ios.js.map +1 -0
  52. package/lib/rokt/rokt-layout-view.js +12 -0
  53. package/lib/rokt/rokt-layout-view.js.map +1 -0
  54. package/lib/rokt/rokt.d.ts +40 -0
  55. package/lib/rokt/rokt.js +54 -0
  56. package/lib/rokt/rokt.js.map +1 -0
  57. package/lib/utils/architecture.d.ts +9 -0
  58. package/lib/utils/architecture.js +19 -0
  59. package/lib/utils/architecture.js.map +1 -0
  60. package/package.json +32 -10
  61. package/react-native-mparticle.podspec +7 -6
  62. package/.github/PULL_REQUEST_TEMPLATE.md +0 -8
  63. package/.github/dependabot.yml +0 -12
  64. package/.github/workflows/daily.yml +0 -19
  65. package/.github/workflows/dependabot-automerge.yml +0 -12
  66. package/.github/workflows/pull-request.yml +0 -60
  67. package/.github/workflows/release.yml +0 -60
  68. package/.github/workflows/sonarcloud.yml +0 -16
  69. package/android/.gradle/7.5.1/checksums/checksums.lock +0 -0
  70. package/android/.gradle/7.5.1/checksums/md5-checksums.bin +0 -0
  71. package/android/.gradle/7.5.1/checksums/sha1-checksums.bin +0 -0
  72. package/android/.gradle/7.5.1/dependencies-accessors/dependencies-accessors.lock +0 -0
  73. package/android/.gradle/7.5.1/dependencies-accessors/gc.properties +0 -0
  74. package/android/.gradle/7.5.1/executionHistory/executionHistory.lock +0 -0
  75. package/android/.gradle/7.5.1/fileChanges/last-build.bin +0 -0
  76. package/android/.gradle/7.5.1/fileHashes/fileHashes.lock +0 -0
  77. package/android/.gradle/7.5.1/gc.properties +0 -0
  78. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  79. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  80. package/android/.gradle/vcs-1/gc.properties +0 -0
  81. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  82. package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
  83. package/android/gradle.properties +0 -53
  84. package/android/gradlew +0 -160
  85. package/android/gradlew.bat +0 -90
  86. package/android/libs/java-json.jar +0 -0
  87. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug-sources.jar +0 -0
  88. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug-sources.jar.md5 +0 -1
  89. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug-sources.jar.sha1 +0 -1
  90. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug-sources.jar.sha256 +0 -1
  91. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug-sources.jar.sha512 +0 -1
  92. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug.aar +0 -0
  93. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug.aar.md5 +0 -1
  94. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug.aar.sha1 +0 -1
  95. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug.aar.sha256 +0 -1
  96. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-debug.aar.sha512 +0 -1
  97. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release-sources.jar +0 -0
  98. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release-sources.jar.md5 +0 -1
  99. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release-sources.jar.sha1 +0 -1
  100. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release-sources.jar.sha256 +0 -1
  101. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release-sources.jar.sha512 +0 -1
  102. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release.aar +0 -0
  103. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release.aar.md5 +0 -1
  104. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release.aar.sha1 +0 -1
  105. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release.aar.sha256 +0 -1
  106. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5-release.aar.sha512 +0 -1
  107. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.module +0 -204
  108. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.module.md5 +0 -1
  109. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.module.sha1 +0 -1
  110. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.module.sha256 +0 -1
  111. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.module.sha512 +0 -1
  112. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.pom +0 -44
  113. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.pom.md5 +0 -1
  114. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.pom.sha1 +0 -1
  115. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.pom.sha256 +0 -1
  116. package/android/libs/react-native-android/com/facebook/react/hermes-engine/0.70.5/hermes-engine-0.70.5.pom.sha512 +0 -1
  117. package/android/libs/react-native-android/com/facebook/react/hermes-engine/maven-metadata.xml +0 -13
  118. package/android/libs/react-native-android/com/facebook/react/hermes-engine/maven-metadata.xml.md5 +0 -1
  119. package/android/libs/react-native-android/com/facebook/react/hermes-engine/maven-metadata.xml.sha1 +0 -1
  120. package/android/libs/react-native-android/com/facebook/react/hermes-engine/maven-metadata.xml.sha256 +0 -1
  121. package/android/libs/react-native-android/com/facebook/react/hermes-engine/maven-metadata.xml.sha512 +0 -1
  122. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug-sources.jar +0 -0
  123. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug-sources.jar.md5 +0 -1
  124. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug-sources.jar.sha1 +0 -1
  125. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug-sources.jar.sha256 +0 -1
  126. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug-sources.jar.sha512 +0 -1
  127. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug.aar +0 -0
  128. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug.aar.md5 +0 -1
  129. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug.aar.sha1 +0 -1
  130. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug.aar.sha256 +0 -1
  131. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-debug.aar.sha512 +0 -1
  132. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release-sources.jar +0 -0
  133. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release-sources.jar.md5 +0 -1
  134. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release-sources.jar.sha1 +0 -1
  135. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release-sources.jar.sha256 +0 -1
  136. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release-sources.jar.sha512 +0 -1
  137. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release.aar +0 -0
  138. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release.aar.md5 +0 -1
  139. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release.aar.sha1 +0 -1
  140. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release.aar.sha256 +0 -1
  141. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5-release.aar.sha512 +0 -1
  142. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.module +0 -628
  143. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.module.md5 +0 -1
  144. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.module.sha1 +0 -1
  145. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.module.sha256 +0 -1
  146. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.module.sha512 +0 -1
  147. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.pom +0 -156
  148. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.pom.md5 +0 -1
  149. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.pom.sha1 +0 -1
  150. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.pom.sha256 +0 -1
  151. package/android/libs/react-native-android/com/facebook/react/react-native/0.70.5/react-native-0.70.5.pom.sha512 +0 -1
  152. package/android/libs/react-native-android/com/facebook/react/react-native/maven-metadata.xml +0 -13
  153. package/android/libs/react-native-android/com/facebook/react/react-native/maven-metadata.xml.md5 +0 -1
  154. package/android/libs/react-native-android/com/facebook/react/react-native/maven-metadata.xml.sha1 +0 -1
  155. package/android/libs/react-native-android/com/facebook/react/react-native/maven-metadata.xml.sha256 +0 -1
  156. package/android/libs/react-native-android/com/facebook/react/react-native/maven-metadata.xml.sha512 +0 -1
  157. package/android/src/main/java/com/mparticle/react/MParticleModule.java +0 -987
  158. package/android/src/main/java/com/mparticle/react/MParticlePackage.java +0 -34
  159. package/android/src/test/java/com/mparticle/react/IdentityApiTest.java +0 -230
  160. package/android/src/test/java/com/mparticle/react/MParticleUserTest.java +0 -233
  161. package/android/src/test/java/com/mparticle/react/testutils/MockMParticleUser.java +0 -103
  162. package/android/src/test/java/com/mparticle/react/testutils/MockMap.java +0 -169
  163. package/android/src/test/java/com/mparticle/react/testutils/MockReadableArray.java +0 -53
  164. package/android/src/test/java/com/mparticle/react/testutils/MockWritableMap.java +0 -4
  165. package/android/src/test/java/com/mparticle/react/testutils/Mutable.java +0 -13
  166. package/ios/RNMParticle/RNMParticle.m +0 -678
  167. package/ios/RNMParticle.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  168. package/ios/RNMParticle.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  169. package/ios/RNMParticle.xcodeproj/project.xcworkspace/xcuserdata/bstalnaker.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  170. package/ios/RNMParticle.xcodeproj/xcuserdata/bstalnaker.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  171. package/js/index.js +0 -697
  172. package/release.sh +0 -6
@@ -0,0 +1,976 @@
1
+ package com.mparticle.react
2
+
3
+ import android.location.Location
4
+ import android.util.Log
5
+ import com.facebook.react.bridge.Arguments
6
+ import com.facebook.react.bridge.Callback
7
+ import com.facebook.react.bridge.ReactApplicationContext
8
+ import com.facebook.react.bridge.ReactMethod
9
+ import com.facebook.react.bridge.ReadableArray
10
+ import com.facebook.react.bridge.ReadableMap
11
+ import com.facebook.react.bridge.ReadableType
12
+ import com.facebook.react.bridge.WritableMap
13
+ import com.facebook.react.bridge.WritableNativeArray
14
+ import com.facebook.react.bridge.WritableNativeMap
15
+ import com.mparticle.MPEvent
16
+ import com.mparticle.MParticle
17
+ import com.mparticle.UserAttributeListener
18
+ import com.mparticle.commerce.CommerceEvent
19
+ import com.mparticle.commerce.Impression
20
+ import com.mparticle.commerce.Product
21
+ import com.mparticle.commerce.Promotion
22
+ import com.mparticle.commerce.TransactionAttributes
23
+ import com.mparticle.consent.CCPAConsent
24
+ import com.mparticle.consent.ConsentState
25
+ import com.mparticle.consent.GDPRConsent
26
+ import com.mparticle.identity.AliasRequest
27
+ import com.mparticle.identity.IdentityApiRequest
28
+ import com.mparticle.identity.IdentityHttpResponse
29
+ import com.mparticle.identity.MParticleUser
30
+ import com.mparticle.internal.Logger
31
+
32
+ class MParticleModule(
33
+ private val reactContext: ReactApplicationContext,
34
+ ) : NativeMParticleSpec(reactContext) {
35
+ companion object {
36
+ const val MODULE_NAME = "RNMParticle"
37
+ private const val LOG_TAG = "MParticleModule"
38
+ }
39
+
40
+ override fun getName(): String = MODULE_NAME
41
+
42
+ @ReactMethod
43
+ override fun upload() {
44
+ MParticle.getInstance()?.upload()
45
+ }
46
+
47
+ @ReactMethod
48
+ override fun setUploadInterval(uploadInterval: Double) {
49
+ MParticle.getInstance()?.setUpdateInterval(uploadInterval.toInt())
50
+ }
51
+
52
+ @ReactMethod
53
+ override fun setLocation(
54
+ latitude: Double,
55
+ longitude: Double,
56
+ ) {
57
+ val newLocation =
58
+ Location("").apply {
59
+ setLatitude(latitude)
60
+ setLongitude(longitude)
61
+ }
62
+ MParticle.getInstance()?.setLocation(newLocation)
63
+ }
64
+
65
+ @ReactMethod
66
+ override fun logEvent(
67
+ eventName: String,
68
+ eventType: Double,
69
+ attributes: ReadableMap?,
70
+ ) {
71
+ val attributes = convertStringMap(attributes)
72
+ val eventType = convertEventType(eventType.toInt())
73
+
74
+ val event =
75
+ MPEvent
76
+ .Builder(name, eventType)
77
+ .customAttributes(attributes)
78
+ .build()
79
+ MParticle.getInstance()?.logEvent(event)
80
+ }
81
+
82
+ @ReactMethod
83
+ override fun logMPEvent(event: ReadableMap?) {
84
+ val convertedEvent = convertMPEvent(event)
85
+ if (convertedEvent != null) {
86
+ MParticle.getInstance()?.logEvent(convertedEvent)
87
+ }
88
+ }
89
+
90
+ @ReactMethod
91
+ override fun logCommerceEvent(commerceEvent: ReadableMap?) {
92
+ commerceEvent?.let {
93
+ val convertedCommerceEvent = convertCommerceEvent(it)
94
+ if (convertedCommerceEvent != null) {
95
+ MParticle.getInstance()?.logEvent(convertedCommerceEvent)
96
+ }
97
+ }
98
+ }
99
+
100
+ @ReactMethod
101
+ override fun logScreenEvent(
102
+ screenName: String,
103
+ attributes: ReadableMap?,
104
+ shouldUploadEvent: Boolean,
105
+ ) {
106
+ val convertedAttributes = convertStringMap(attributes)
107
+ MParticle.getInstance()?.logScreen(screenName, convertedAttributes, shouldUploadEvent)
108
+ }
109
+
110
+ override fun setATTStatus(status: Double) {
111
+ // Not implemented
112
+ }
113
+
114
+ override fun setATTStatusWithCustomTimestamp(
115
+ status: Double,
116
+ timestamp: Double,
117
+ ) {
118
+ // Not implemented
119
+ }
120
+
121
+ @ReactMethod
122
+ override fun setUserAttribute(
123
+ mpid: String,
124
+ key: String,
125
+ value: String,
126
+ ) {
127
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
128
+ selectedUser?.setUserAttribute(key, value)
129
+ }
130
+
131
+ @ReactMethod
132
+ override fun setUserAttributeArray(
133
+ mpid: String,
134
+ key: String,
135
+ value: ReadableArray?,
136
+ ) {
137
+ value?.let {
138
+ val list = mutableListOf<String>()
139
+ for (i in 0 until it.size()) {
140
+ it.getString(i)?.let { element -> list.add(element) }
141
+ }
142
+
143
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
144
+ selectedUser?.setUserAttributeList(key, list)
145
+ }
146
+ }
147
+
148
+ @ReactMethod
149
+ override fun getUserAttributes(
150
+ mpid: String,
151
+ callback: Callback,
152
+ ) {
153
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
154
+ if (selectedUser != null) {
155
+ selectedUser.getUserAttributes(
156
+ object : UserAttributeListener {
157
+ override fun onUserAttributesReceived(
158
+ userAttributes: Map<String, String>?,
159
+ userAttributeLists: Map<String, List<String>>?,
160
+ mpid: Long?,
161
+ ) {
162
+ val resultMap = WritableNativeMap()
163
+ userAttributes?.let { attrs ->
164
+ for ((key, value) in attrs) {
165
+ resultMap.putString(key, value)
166
+ }
167
+ }
168
+ userAttributeLists?.let { attrLists ->
169
+ for ((key, valueList) in attrLists) {
170
+ val resultArray = WritableNativeArray()
171
+ for (arrayVal in valueList) {
172
+ resultArray.pushString(arrayVal)
173
+ }
174
+ resultMap.putArray(key, resultArray)
175
+ }
176
+ }
177
+ callback.invoke(null, resultMap)
178
+ }
179
+ },
180
+ )
181
+ } else {
182
+ callback.invoke()
183
+ }
184
+ }
185
+
186
+ @ReactMethod
187
+ override fun setUserTag(
188
+ mpid: String,
189
+ tag: String,
190
+ ) {
191
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
192
+ selectedUser?.setUserTag(tag)
193
+ }
194
+
195
+ @ReactMethod
196
+ override fun removeUserAttribute(
197
+ mpid: String,
198
+ key: String,
199
+ ) {
200
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
201
+ selectedUser?.removeUserAttribute(key)
202
+ }
203
+
204
+ @ReactMethod
205
+ override fun incrementUserAttribute(
206
+ mpid: String,
207
+ key: String,
208
+ value: Double,
209
+ ) {
210
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
211
+ selectedUser?.incrementUserAttribute(key, value)
212
+ }
213
+
214
+ @ReactMethod
215
+ override fun identify(
216
+ identityRequest: ReadableMap?,
217
+ callback: Callback,
218
+ ) {
219
+ val request = convertIdentityAPIRequest(identityRequest)
220
+
221
+ MParticle
222
+ .getInstance()
223
+ ?.Identity()
224
+ ?.identify(request)
225
+ ?.addFailureListener { identityHttpResponse ->
226
+ callback.invoke(convertIdentityHttpResponse(identityHttpResponse), null)
227
+ }?.addSuccessListener { identityApiResult ->
228
+ val user = identityApiResult.user
229
+ val userID = user.id.toString()
230
+ callback.invoke(null, userID)
231
+ }
232
+ }
233
+
234
+ @ReactMethod
235
+ override fun login(
236
+ identityRequest: ReadableMap?,
237
+ callback: Callback,
238
+ ) {
239
+ val request = convertIdentityAPIRequest(identityRequest)
240
+
241
+ MParticle
242
+ .getInstance()
243
+ ?.Identity()
244
+ ?.login(request)
245
+ ?.addFailureListener { identityHttpResponse ->
246
+ callback.invoke(convertIdentityHttpResponse(identityHttpResponse), null)
247
+ }?.addSuccessListener { identityApiResult ->
248
+ val user = identityApiResult.user
249
+ val userId = user.id.toString()
250
+ val previousUser = identityApiResult.previousUser
251
+ val previousUserId = previousUser?.id?.toString()
252
+ callback.invoke(null, userId, previousUserId)
253
+ }
254
+ }
255
+
256
+ @ReactMethod
257
+ override fun logout(
258
+ identityRequest: ReadableMap?,
259
+ callback: Callback,
260
+ ) {
261
+ val request = convertIdentityAPIRequest(identityRequest)
262
+
263
+ MParticle
264
+ .getInstance()
265
+ ?.Identity()
266
+ ?.logout(request)
267
+ ?.addFailureListener { identityHttpResponse ->
268
+ callback.invoke(convertIdentityHttpResponse(identityHttpResponse), null)
269
+ }?.addSuccessListener { identityApiResult ->
270
+ val user = identityApiResult.user
271
+ val userID = user.id.toString()
272
+ callback.invoke(null, userID)
273
+ }
274
+ }
275
+
276
+ @ReactMethod
277
+ override fun modify(
278
+ identityRequest: ReadableMap?,
279
+ callback: Callback,
280
+ ) {
281
+ val request = convertIdentityAPIRequest(identityRequest)
282
+
283
+ MParticle
284
+ .getInstance()
285
+ ?.Identity()
286
+ ?.modify(request)
287
+ ?.addFailureListener { identityHttpResponse ->
288
+ callback.invoke(convertIdentityHttpResponse(identityHttpResponse), null)
289
+ }?.addSuccessListener { identityApiResult ->
290
+ val user = identityApiResult.user
291
+ val userID = user.id.toString()
292
+ callback.invoke(null, userID)
293
+ }
294
+ }
295
+
296
+ @ReactMethod
297
+ override fun getCurrentUserWithCompletion(callback: Callback) {
298
+ val currentUser = MParticle.getInstance()?.Identity()?.currentUser
299
+ if (currentUser != null) {
300
+ val userID = currentUser.id.toString()
301
+ callback.invoke(null, userID)
302
+ } else {
303
+ callback.invoke(null, null)
304
+ }
305
+ }
306
+
307
+ @ReactMethod
308
+ override fun aliasUsers(
309
+ aliasRequest: ReadableMap?,
310
+ callback: Callback,
311
+ ) {
312
+ val identityApi = MParticle.getInstance()?.Identity()
313
+ if (identityApi == null || aliasRequest == null) {
314
+ callback.invoke(false, "MParticle not initialized")
315
+ return
316
+ }
317
+
318
+ val iterator = aliasRequest.keySetIterator()
319
+ var destinationMpid: Long? = null
320
+ var sourceMpid: Long? = null
321
+ var startTime: Long? = null
322
+ var endTime: Long? = null
323
+
324
+ while (iterator.hasNextKey()) {
325
+ try {
326
+ when (val key = iterator.nextKey()) {
327
+ "destinationMpid" ->
328
+ destinationMpid =
329
+ Utils.getLong(aliasRequest, "destinationMpid", false)
330
+
331
+ "sourceMpid" -> sourceMpid = Utils.getLong(aliasRequest, "sourceMpid", false)
332
+ "startTime" -> startTime = Utils.getLong(aliasRequest, "startTime", true)
333
+ "endTime" -> endTime = Utils.getLong(aliasRequest, "endTime", true)
334
+ }
335
+ } catch (ex: NumberFormatException) {
336
+ Logger.error(ex.message)
337
+ callback.invoke(false, ex.message)
338
+ return
339
+ }
340
+ }
341
+
342
+ if (startTime == null && endTime == null) {
343
+ var sourceUser: MParticleUser? = null
344
+ var destinationUser: MParticleUser? = null
345
+ sourceMpid?.let { sourceUser = identityApi.getUser(it) }
346
+ destinationMpid?.let { destinationUser = identityApi.getUser(it) }
347
+
348
+ if (sourceUser != null && destinationUser != null) {
349
+ val request = AliasRequest.builder(sourceUser!!, destinationUser!!).build()
350
+ val success = MParticle.getInstance()?.Identity()?.aliasUsers(request) ?: false
351
+ callback.invoke(success)
352
+ } else {
353
+ callback.invoke(
354
+ false,
355
+ "MParticleUser could not be found for provided sourceMpid and destinationMpid",
356
+ )
357
+ }
358
+ } else {
359
+ val request =
360
+ AliasRequest
361
+ .builder()
362
+ .destinationMpid(destinationMpid ?: 0)
363
+ .sourceMpid(sourceMpid ?: 0)
364
+ .startTime(startTime ?: 0)
365
+ .endTime(endTime ?: 0)
366
+ .build()
367
+ val success = identityApi.aliasUsers(request)
368
+ callback.invoke(success)
369
+ }
370
+ }
371
+
372
+ @ReactMethod
373
+ override fun getSession(callback: Callback) {
374
+ val session = MParticle.getInstance()?.currentSession
375
+ if (session != null) {
376
+ val sessionId = session.sessionUUID
377
+ callback.invoke(sessionId)
378
+ } else {
379
+ callback.invoke()
380
+ }
381
+ }
382
+
383
+ @ReactMethod
384
+ override fun getUserIdentities(
385
+ mpid: String,
386
+ callback: Callback,
387
+ ) {
388
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
389
+ if (selectedUser != null) {
390
+ callback.invoke(null, convertToUserIdentities(selectedUser.userIdentities))
391
+ } else {
392
+ callback.invoke()
393
+ }
394
+ }
395
+
396
+ @ReactMethod
397
+ override fun getFirstSeen(
398
+ mpid: String,
399
+ callback: Callback,
400
+ ) {
401
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(Utils.parseMpid(mpid))
402
+ if (selectedUser != null) {
403
+ callback.invoke(selectedUser.firstSeenTime.toString())
404
+ } else {
405
+ callback.invoke()
406
+ }
407
+ }
408
+
409
+ @ReactMethod
410
+ override fun getLastSeen(
411
+ mpid: String,
412
+ callback: Callback,
413
+ ) {
414
+ val selectedUser = MParticle.getInstance()?.Identity()?.getUser(Utils.parseMpid(mpid))
415
+ if (selectedUser != null) {
416
+ callback.invoke(selectedUser.lastSeenTime.toString())
417
+ } else {
418
+ callback.invoke()
419
+ }
420
+ }
421
+
422
+ @ReactMethod
423
+ override fun getAttributions(callback: Callback) {
424
+ val attributionResultMap = MParticle.getInstance()?.attributionResults
425
+ val map = Arguments.createMap()
426
+ attributionResultMap?.let { resultMap ->
427
+ for ((key, attribution) in resultMap) {
428
+ val attributeMap = Arguments.createMap()
429
+ attribution?.let { attr ->
430
+ attributeMap.putInt("kitId", attr.serviceProviderId)
431
+ attr.link?.let { attributeMap.putString("link", it) }
432
+ attr.parameters?.let { attributeMap.putString("linkParameters", it.toString()) }
433
+ }
434
+ map.putMap(key.toString(), attributeMap)
435
+ }
436
+ }
437
+ callback.invoke(map)
438
+ }
439
+
440
+ @ReactMethod
441
+ override fun setOptOut(optOut: Boolean) {
442
+ MParticle.getInstance()?.setOptOut(optOut)
443
+ }
444
+
445
+ @ReactMethod
446
+ override fun getOptOut(callback: Callback) {
447
+ val optedOut = MParticle.getInstance()?.optOut ?: false
448
+ callback.invoke(optedOut)
449
+ }
450
+
451
+ @ReactMethod
452
+ override fun isKitActive(
453
+ kitId: Double,
454
+ callback: Callback,
455
+ ) {
456
+ val isActive = MParticle.getInstance()?.isKitActive(kitId.toInt()) ?: false
457
+ callback.invoke(isActive)
458
+ }
459
+
460
+ @ReactMethod
461
+ override fun logPushRegistration(
462
+ token: String?,
463
+ senderId: String?,
464
+ ) {
465
+ if (!token.isNullOrEmpty() && !senderId.isNullOrEmpty()) {
466
+ MParticle.getInstance()?.logPushRegistration(token, senderId)
467
+ }
468
+ }
469
+
470
+ @ReactMethod
471
+ override fun addGDPRConsentState(
472
+ consent: ReadableMap?,
473
+ purpose: String,
474
+ ) {
475
+ val currentUser = MParticle.getInstance()?.Identity()?.currentUser
476
+ if (currentUser != null && consent != null) {
477
+ val gDPRConsent = convertToGDPRConsent(consent)
478
+ if (gDPRConsent != null) {
479
+ val consentState =
480
+ ConsentState
481
+ .withConsentState(currentUser.consentState)
482
+ .addGDPRConsentState(purpose, gDPRConsent)
483
+ .build()
484
+ currentUser.setConsentState(consentState)
485
+ Logger.info("GDPRConsentState added, \n\t\"purpose\": $purpose\n$consentState")
486
+ } else {
487
+ Logger.warning("GDPRConsentState was not able to be deserialized, will not be added")
488
+ }
489
+ }
490
+ }
491
+
492
+ @ReactMethod
493
+ override fun removeGDPRConsentStateWithPurpose(purpose: String) {
494
+ val currentUser = MParticle.getInstance()?.Identity()?.currentUser
495
+ if (currentUser != null) {
496
+ val consentState =
497
+ ConsentState
498
+ .withConsentState(currentUser.consentState)
499
+ .removeGDPRConsentState(purpose)
500
+ .build()
501
+ currentUser.setConsentState(consentState)
502
+ }
503
+ }
504
+
505
+ @ReactMethod
506
+ override fun setCCPAConsentState(consent: ReadableMap?) {
507
+ val currentUser = MParticle.getInstance()?.Identity()?.currentUser
508
+ if (currentUser != null && consent != null) {
509
+ val cCPAConsent = convertToCCPAConsent(consent)
510
+ if (cCPAConsent != null) {
511
+ val consentState =
512
+ ConsentState
513
+ .withConsentState(currentUser.consentState)
514
+ .setCCPAConsentState(cCPAConsent)
515
+ .build()
516
+ currentUser.setConsentState(consentState)
517
+ Logger.info("CCPAConsentState added, \n$consentState")
518
+ } else {
519
+ Logger.warning("CCPAConsentState was not able to be deserialized, will not be added")
520
+ }
521
+ }
522
+ }
523
+
524
+ @ReactMethod
525
+ override fun removeCCPAConsentState() {
526
+ val currentUser = MParticle.getInstance()?.Identity()?.currentUser
527
+ if (currentUser != null) {
528
+ val consentState =
529
+ ConsentState
530
+ .withConsentState(currentUser.consentState)
531
+ .removeCCPAConsentState()
532
+ .build()
533
+ currentUser.setConsentState(consentState)
534
+ }
535
+ }
536
+
537
+ protected fun getWritableMap(): WritableMap = WritableNativeMap()
538
+
539
+ private fun convertIdentityAPIRequest(map: ReadableMap?): IdentityApiRequest {
540
+ val identityRequest = IdentityApiRequest.withEmptyUser()
541
+ val userIdentities = convertUserIdentities(map)
542
+ identityRequest.userIdentities(userIdentities)
543
+ return identityRequest.build()
544
+ }
545
+
546
+ private fun convertMPEvent(map: ReadableMap?): MPEvent? {
547
+ if (map?.hasKey("name") == true && map.hasKey("type")) {
548
+ val name = map.getString("name") ?: return null
549
+ val type = map.getInt("type")
550
+ val builder = MPEvent.Builder(name, convertEventType(type))
551
+
552
+ if (map.hasKey("category")) {
553
+ map.getString("category")?.let { builder.category(it) }
554
+ }
555
+
556
+ if (map.hasKey("duration")) {
557
+ builder.duration(map.getDouble("duration"))
558
+ }
559
+
560
+ if (map.hasKey("info")) {
561
+ val customInfoMap = map.getMap("info")
562
+ val customInfo = convertStringMap(customInfoMap)
563
+ builder.customAttributes(customInfo)
564
+ }
565
+
566
+ if (map.hasKey("customFlags")) {
567
+ val customFlagsMap = map.getMap("customFlags")
568
+ val customFlags = convertStringMap(customFlagsMap)
569
+ if (customFlags != null) {
570
+ for ((key, value) in customFlags) {
571
+ builder.addCustomFlag(key, value)
572
+ }
573
+ }
574
+ }
575
+
576
+ if (map.hasKey("shouldUploadEvent")) {
577
+ builder.shouldUploadEvent(map.getBoolean("shouldUploadEvent"))
578
+ }
579
+
580
+ return builder.build()
581
+ }
582
+ return null
583
+ }
584
+
585
+ private fun convertIdentityHttpResponse(response: IdentityHttpResponse?): ReadableMap {
586
+ val map = Arguments.createMap()
587
+ map.putInt("httpCode", response?.httpCode ?: 0)
588
+ if (response?.mpId != 0L) {
589
+ map.putString("mpid", response?.mpId.toString())
590
+ }
591
+ val stringBuilder = StringBuilder()
592
+ response?.errors?.let { errors ->
593
+ for (error in errors) {
594
+ error?.let {
595
+ stringBuilder.append("Code: ${it.code}\n")
596
+ stringBuilder.append("Message: ${it.message}\n")
597
+ }
598
+ }
599
+ }
600
+ map.putString("errors", stringBuilder.toString())
601
+ return map
602
+ }
603
+
604
+ private fun convertCommerceEvent(map: ReadableMap): CommerceEvent? {
605
+ val isProductAction = map.hasKey("productActionType")
606
+ val isPromotion = map.hasKey("promotionActionType")
607
+ val isImpression = map.hasKey("impressions")
608
+
609
+ if (!isProductAction && !isPromotion && !isImpression) {
610
+ Log.e(LOG_TAG, "Invalid commerce event: $map")
611
+ return null
612
+ }
613
+
614
+ val builder =
615
+ when {
616
+ isProductAction -> {
617
+ val productActionInt = map.getInt("productActionType")
618
+ val productAction = convertProductActionType(productActionInt)
619
+ val productsArray = map.getArray("products") ?: return null
620
+ val productMap = productsArray.getMap(0)
621
+ val product = convertProduct(productMap) ?: return null
622
+ val transactionAttributesMap = map.getMap("transactionAttributes")
623
+ val transactionAttributes = convertTransactionAttributes(transactionAttributesMap)
624
+ val builder =
625
+ transactionAttributes?.let {
626
+ CommerceEvent.Builder(productAction, product).transactionAttributes(it)
627
+ }
628
+
629
+ for (i in 1 until productsArray.size()) {
630
+ val nextProductMap = productsArray.getMap(i)
631
+ val nextProduct = convertProduct(nextProductMap)
632
+ if (nextProduct != null) {
633
+ builder?.addProduct(nextProduct)
634
+ }
635
+ }
636
+ builder
637
+ }
638
+
639
+ isPromotion -> {
640
+ val promotionActionTypeInt = map.getInt("promotionActionType")
641
+ val promotionAction = convertPromotionActionType(promotionActionTypeInt)
642
+ val promotionsReadableArray = map.getArray("promotions") ?: return null
643
+ val promotionMap = promotionsReadableArray.getMap(0)
644
+ val promotion = convertPromotion(promotionMap) ?: return null
645
+ val builder = CommerceEvent.Builder(promotionAction, promotion)
646
+
647
+ for (i in 1 until promotionsReadableArray.size()) {
648
+ val nextPromotionMap = promotionsReadableArray.getMap(i)
649
+ val nextPromotion = convertPromotion(nextPromotionMap)
650
+ if (nextPromotion != null) {
651
+ builder.addPromotion(nextPromotion)
652
+ }
653
+ }
654
+ builder
655
+ }
656
+
657
+ else -> {
658
+ val impressionsArray = map.getArray("impressions") ?: return null
659
+ val impressionMap = impressionsArray.getMap(0)
660
+ val impression = convertImpression(impressionMap) ?: return null
661
+ val builder = CommerceEvent.Builder(impression)
662
+
663
+ for (i in 1 until impressionsArray.size()) {
664
+ val nextImpressionMap = impressionsArray.getMap(i)
665
+ val nextImpression = convertImpression(nextImpressionMap)
666
+ if (nextImpression != null) {
667
+ builder.addImpression(nextImpression)
668
+ }
669
+ }
670
+ builder
671
+ }
672
+ }
673
+
674
+ if (map.hasKey("shouldUploadEvent")) {
675
+ builder?.shouldUploadEvent(map.getBoolean("shouldUploadEvent"))
676
+ }
677
+ if (map.hasKey("customAttributes")) {
678
+ builder?.customAttributes(convertStringMap(map.getMap("customAttributes")))
679
+ }
680
+ if (map.hasKey("currency")) {
681
+ map.getString("currency")?.let { builder?.currency(it) }
682
+ }
683
+ if (map.hasKey("checkoutStep")) {
684
+ builder?.checkoutStep(map.getInt("checkoutStep"))
685
+ }
686
+ if (map.hasKey("checkoutOptions")) {
687
+ map.getString("checkoutOptions")?.let { builder?.checkoutOptions(it) }
688
+ }
689
+
690
+ return builder?.build()
691
+ }
692
+
693
+ private fun convertProduct(map: ReadableMap?): Product? {
694
+ if (map == null) return null
695
+ val name = map.getString("name") ?: return null
696
+ val sku = map.getString("sku") ?: return null
697
+ val unitPrice = map.getDouble("price")
698
+ val builder = Product.Builder(name, sku, unitPrice)
699
+
700
+ if (map.hasKey("brand")) {
701
+ map.getString("brand")?.let { builder.brand(it) }
702
+ }
703
+
704
+ if (map.hasKey("category")) {
705
+ map.getString("category")?.let { builder.category(it) }
706
+ }
707
+
708
+ if (map.hasKey("couponCode")) {
709
+ map.getString("couponCode")?.let { builder.couponCode(it) }
710
+ }
711
+
712
+ if (map.hasKey("customAttributes")) {
713
+ val customAttributesMap = map.getMap("customAttributes")
714
+ val customAttributes = convertStringMap(customAttributesMap)
715
+ builder.customAttributes(customAttributes)
716
+ }
717
+
718
+ if (map.hasKey("position")) {
719
+ builder.position(map.getInt("position"))
720
+ }
721
+
722
+ if (map.hasKey("quantity")) {
723
+ builder.quantity(map.getDouble("quantity"))
724
+ }
725
+
726
+ if (map.hasKey("variant")) {
727
+ map.getString("variant")?.let { builder.variant(it) }
728
+ }
729
+
730
+ return builder.build()
731
+ }
732
+
733
+ private fun convertTransactionAttributes(map: ReadableMap?): TransactionAttributes? {
734
+ if (map?.hasKey("transactionId") != true) {
735
+ return null
736
+ }
737
+
738
+ val transactionId = map.getString("transactionId") ?: return null
739
+ val transactionAttributes = TransactionAttributes(transactionId)
740
+
741
+ if (map.hasKey("affiliation")) {
742
+ map.getString("affiliation")?.let { transactionAttributes.affiliation = it }
743
+ }
744
+
745
+ if (map.hasKey("revenue")) {
746
+ transactionAttributes.revenue = map.getDouble("revenue")
747
+ }
748
+
749
+ if (map.hasKey("shipping")) {
750
+ transactionAttributes.shipping = map.getDouble("shipping")
751
+ }
752
+
753
+ if (map.hasKey("tax")) {
754
+ transactionAttributes.tax = map.getDouble("tax")
755
+ }
756
+
757
+ if (map.hasKey("couponCode")) {
758
+ map.getString("couponCode")?.let { transactionAttributes.couponCode = it }
759
+ }
760
+
761
+ return transactionAttributes
762
+ }
763
+
764
+ private fun convertPromotion(map: ReadableMap?): Promotion? {
765
+ if (map == null) return null
766
+ val promotion = Promotion()
767
+
768
+ if (map.hasKey("id")) {
769
+ map.getString("id")?.let { promotion.id = it }
770
+ }
771
+
772
+ if (map.hasKey("name")) {
773
+ map.getString("name")?.let { promotion.name = it }
774
+ }
775
+
776
+ if (map.hasKey("creative")) {
777
+ map.getString("creative")?.let { promotion.creative = it }
778
+ }
779
+
780
+ if (map.hasKey("position")) {
781
+ map.getString("position")?.let { promotion.position = it }
782
+ }
783
+
784
+ return promotion
785
+ }
786
+
787
+ private fun convertImpression(map: ReadableMap?): Impression? {
788
+ if (map == null) return null
789
+ val listName = map.getString("impressionListName") ?: return null
790
+ val productsArray = map.getArray("products") ?: return null
791
+ val productMap = productsArray.getMap(0)
792
+ val product = convertProduct(productMap) ?: return null
793
+ val impression = Impression(listName, product)
794
+
795
+ for (i in 1 until productsArray.size()) {
796
+ val nextProductMap = productsArray.getMap(i)
797
+ val nextProduct = convertProduct(nextProductMap)
798
+ if (nextProduct != null) {
799
+ impression.addProduct(nextProduct)
800
+ }
801
+ }
802
+
803
+ return impression
804
+ }
805
+
806
+ private fun convertStringMap(readableMap: ReadableMap?): Map<String, String>? {
807
+ if (readableMap == null) return null
808
+
809
+ val map = mutableMapOf<String, String>()
810
+ val iterator = readableMap.keySetIterator()
811
+ while (iterator.hasNextKey()) {
812
+ val key = iterator.nextKey()
813
+ when (readableMap.getType(key)) {
814
+ ReadableType.Null -> map[key] = ""
815
+ ReadableType.Boolean -> map[key] = readableMap.getBoolean(key).toString()
816
+ ReadableType.Number -> {
817
+ try {
818
+ map[key] = readableMap.getInt(key).toString()
819
+ } catch (e: Exception) {
820
+ try {
821
+ map[key] = readableMap.getDouble(key).toString()
822
+ } catch (ex: Exception) {
823
+ Logger.warning("Unable to parse value for \"$key\"")
824
+ }
825
+ }
826
+ }
827
+
828
+ ReadableType.String -> map[key] = readableMap.getString(key) ?: ""
829
+ ReadableType.Map -> Logger.warning("Maps are not supported Attribute value types")
830
+ ReadableType.Array -> Logger.warning("Lists are not supported Attribute value types")
831
+ }
832
+ }
833
+ return map
834
+ }
835
+
836
+ private fun convertUserIdentities(readableMap: ReadableMap?): Map<MParticle.IdentityType, String> {
837
+ val map = mutableMapOf<MParticle.IdentityType, String>()
838
+ if (readableMap != null) {
839
+ val iterator = readableMap.keySetIterator()
840
+ while (iterator.hasNextKey()) {
841
+ val key = iterator.nextKey()
842
+ val identity =
843
+ when (key) {
844
+ "email" -> MParticle.IdentityType.Email
845
+ "customerId" -> MParticle.IdentityType.CustomerId
846
+ else -> MParticle.IdentityType.parseInt(key.toInt())
847
+ }
848
+ identity.let {
849
+ readableMap.getString(key)?.let { value ->
850
+ map[it] = value
851
+ }
852
+ }
853
+ }
854
+ }
855
+ return map
856
+ }
857
+
858
+ private fun convertToUserIdentities(userIdentities: Map<MParticle.IdentityType, String>): WritableMap {
859
+ val nativeMap = getWritableMap()
860
+ for ((identityType, value) in userIdentities) {
861
+ nativeMap.putString(identityType.value.toString(), value)
862
+ }
863
+ return nativeMap
864
+ }
865
+
866
+ private fun convertEventType(eventType: Int): MParticle.EventType =
867
+ when (eventType) {
868
+ 1 -> MParticle.EventType.Navigation
869
+ 2 -> MParticle.EventType.Location
870
+ 3 -> MParticle.EventType.Search
871
+ 4 -> MParticle.EventType.Transaction
872
+ 5 -> MParticle.EventType.UserContent
873
+ 6 -> MParticle.EventType.UserPreference
874
+ 7 -> MParticle.EventType.Social
875
+ 8 -> MParticle.EventType.Other
876
+ 9 -> MParticle.EventType.Media
877
+ else -> MParticle.EventType.Other
878
+ }
879
+
880
+ private fun convertProductActionType(productActionType: Int): String =
881
+ when (productActionType) {
882
+ 1 -> Product.ADD_TO_CART
883
+ 2 -> Product.REMOVE_FROM_CART
884
+ 3 -> Product.CHECKOUT
885
+ 4 -> Product.CHECKOUT_OPTION
886
+ 5 -> Product.CLICK
887
+ 6 -> Product.DETAIL
888
+ 7 -> Product.PURCHASE
889
+ 8 -> Product.REFUND
890
+ 9 -> Product.ADD_TO_WISHLIST
891
+ else -> Product.REMOVE_FROM_WISHLIST
892
+ }
893
+
894
+ private fun convertPromotionActionType(promotionActionType: Int): String =
895
+ when (promotionActionType) {
896
+ 0 -> Promotion.VIEW
897
+ else -> Promotion.CLICK
898
+ }
899
+
900
+ private fun parseMpid(longString: String): Long =
901
+ try {
902
+ longString.toLong()
903
+ } catch (ex: NumberFormatException) {
904
+ 0L
905
+ }
906
+
907
+ private fun convertToGDPRConsent(map: ReadableMap): GDPRConsent? {
908
+ val consented =
909
+ try {
910
+ when (map.getType("consented")) {
911
+ ReadableType.Boolean -> map.getBoolean("consented")
912
+ else -> map.getString("consented")?.toBoolean() ?: false
913
+ }
914
+ } catch (ex: Exception) {
915
+ Logger.error("failed to convert \"consented\" value to a Boolean, unable to process addGDPRConsentState")
916
+ return null
917
+ }
918
+
919
+ val builder = GDPRConsent.builder(consented)
920
+
921
+ if (map.hasKey("document")) {
922
+ map.getString("document")?.let { builder.document(it) }
923
+ }
924
+ if (map.hasKey("hardwareId")) {
925
+ map.getString("hardwareId")?.let { builder.hardwareId(it) }
926
+ }
927
+ if (map.hasKey("location")) {
928
+ map.getString("location")?.let { builder.location(it) }
929
+ }
930
+ if (map.hasKey("timestamp")) {
931
+ try {
932
+ val timestampString = map.getString("timestamp")
933
+ val timestamp = timestampString?.toLong()
934
+ timestamp?.let { builder.timestamp(it) }
935
+ } catch (ex: Exception) {
936
+ Logger.warning("failed to convert \"timestamp\" value to Long")
937
+ }
938
+ }
939
+ return builder.build()
940
+ }
941
+
942
+ private fun convertToCCPAConsent(map: ReadableMap): CCPAConsent? {
943
+ val consented =
944
+ try {
945
+ when (map.getType("consented")) {
946
+ ReadableType.Boolean -> map.getBoolean("consented")
947
+ else -> map.getString("consented")?.toBoolean() ?: false
948
+ }
949
+ } catch (ex: Exception) {
950
+ Logger.error("failed to convert \"consented\" value to a Boolean, unable to process addCCPAConsentState")
951
+ return null
952
+ }
953
+
954
+ val builder = CCPAConsent.builder(consented)
955
+
956
+ if (map.hasKey("document")) {
957
+ map.getString("document")?.let { builder.document(it) }
958
+ }
959
+ if (map.hasKey("hardwareId")) {
960
+ map.getString("hardwareId")?.let { builder.hardwareId(it) }
961
+ }
962
+ if (map.hasKey("location")) {
963
+ map.getString("location")?.let { builder.location(it) }
964
+ }
965
+ if (map.hasKey("timestamp")) {
966
+ try {
967
+ val timestampString = map.getString("timestamp")
968
+ val timestamp = timestampString?.toLong()
969
+ timestamp?.let { builder.timestamp(it) }
970
+ } catch (ex: Exception) {
971
+ Logger.warning("failed to convert \"timestamp\" value to Long")
972
+ }
973
+ }
974
+ return builder.build()
975
+ }
976
+ }