@dashx/react-native 1.1.1 → 1.1.3

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 (132) hide show
  1. package/.DS_Store +0 -0
  2. package/.claude/settings.local.json +14 -0
  3. package/.github/workflows/ci.yml +28 -0
  4. package/CONTRIBUTING.md +153 -0
  5. package/DashXReactNative.podspec +6 -2
  6. package/README.md +259 -97
  7. package/__tests__/index.test.js +363 -0
  8. package/android/.gitignore +10 -0
  9. package/android/.gradle/7.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  10. package/android/.gradle/7.2/dependencies-accessors/gc.properties +0 -0
  11. package/android/.gradle/7.2/fileChanges/last-build.bin +0 -0
  12. package/android/.gradle/7.2/fileHashes/fileHashes.lock +0 -0
  13. package/android/.gradle/7.2/gc.properties +0 -0
  14. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  15. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  16. package/android/.gradle/checksums/checksums.lock +0 -0
  17. package/android/.gradle/checksums/md5-checksums.bin +0 -0
  18. package/android/.gradle/checksums/sha1-checksums.bin +0 -0
  19. package/android/.gradle/vcs-1/gc.properties +0 -0
  20. package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.dex +0 -0
  21. package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/DashXReactNativeModule.dex +0 -0
  22. package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/MessageReceivedEventHolder.dex +0 -0
  23. package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/util/Utils$WhenMappings.dex +0 -0
  24. package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/dashx/rn/sdk/util/Utils.dex +0 -0
  25. package/android/build/.transforms/9dceace6c3787533d2dbb1a387e9284c/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  26. package/android/build/.transforms/f3c6049e7ab4bb564c79f3a246b8575e/transformed/classes/classes_dex/classes.dex +0 -0
  27. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +16 -0
  28. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  29. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +31 -5
  30. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +16 -0
  31. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.class +0 -0
  32. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/DashXReactNativeModule.class +0 -0
  33. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/MessageReceivedEventHolder.class +0 -0
  34. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/util/Utils$WhenMappings.class +0 -0
  35. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/dashx/rn/sdk/util/Utils.class +0 -0
  36. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  37. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  38. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  39. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  40. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  41. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  42. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  43. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  44. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  45. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  46. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  47. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  48. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  49. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  50. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  51. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  52. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  53. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  54. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  55. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  56. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  57. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  58. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  59. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  60. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  61. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +0 -0
  62. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +0 -0
  63. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  64. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  65. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  66. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  67. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  68. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  69. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  70. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  71. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  72. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  73. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  74. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  75. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  76. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  77. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  78. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  79. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  80. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  81. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  82. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  83. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  84. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  85. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  86. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  87. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +1 -1
  88. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  89. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  90. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  91. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  92. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  93. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  94. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  95. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  96. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  97. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  98. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  99. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  100. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  101. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  102. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  103. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  104. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  105. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  106. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  107. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  108. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  109. package/android/build/outputs/logs/manifest-merger-debug-report.txt +25 -3
  110. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  111. package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.class +0 -0
  112. package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/DashXReactNativeModule.class +0 -0
  113. package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/MessageReceivedEventHolder.class +0 -0
  114. package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/util/Utils$WhenMappings.class +0 -0
  115. package/android/build/tmp/kotlin-classes/debug/com/dashx/rn/sdk/util/Utils.class +0 -0
  116. package/android/build.gradle +4 -1
  117. package/android/src/main/AndroidManifest.xml +15 -3
  118. package/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeFirebaseMessagingService.kt +72 -0
  119. package/android/src/main/java/com/dashx/rn/sdk/DashXReactNativeModule.kt +84 -15
  120. package/android/src/main/java/com/dashx/rn/sdk/MessageReceivedEventHolder.kt +14 -0
  121. package/android/src/main/java/com/dashx/rn/sdk/util/Utils.kt +14 -0
  122. package/babel.config.js +1 -1
  123. package/index.d.ts +107 -0
  124. package/index.js +81 -4
  125. package/ios/.DS_Store +0 -0
  126. package/ios/DashXEventEmitter.swift +3 -2
  127. package/ios/DashXRCTAppDelegate.swift +110 -44
  128. package/ios/DashXReactNative-Bridging-Header.h +2 -0
  129. package/ios/DashXReactNative.h +1 -0
  130. package/ios/DashXReactNative.mm +16 -0
  131. package/ios/DashXReactNative.swift +118 -28
  132. package/package.json +18 -5
@@ -1,11 +1,33 @@
1
1
  -- Merging decision tree log ---
2
2
  manifest
3
- ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:2:1-4:12
4
- INJECTED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:2:1-4:12
3
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:1:1-16:12
4
+ INJECTED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:1:1-16:12
5
5
  package
6
6
  INJECTED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml
7
+ xmlns:tools
8
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:2:5-51
7
9
  xmlns:android
8
- ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:2:11-69
10
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:1:11-69
11
+ application
12
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:3:5-15:19
13
+ service#com.dashx.android.DashXFirebaseMessagingService
14
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:5:9-7:35
15
+ tools:node
16
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:7:13-32
17
+ android:name
18
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:6:13-75
19
+ service#com.dashx.rn.sdk.DashXReactNativeFirebaseMessagingService
20
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:8:9-14:19
21
+ android:exported
22
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:10:13-37
23
+ android:name
24
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:9:13-85
25
+ intent-filter#action:name:com.google.firebase.MESSAGING_EVENT
26
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:11:13-13:29
27
+ action#com.google.firebase.MESSAGING_EVENT
28
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:12:17-78
29
+ android:name
30
+ ADDED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml:12:25-75
9
31
  uses-sdk
10
32
  INJECTED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml reason: use-sdk injection requested
11
33
  INJECTED from /Users/gulshan/Work/dashx-demo-rn/node_modules/@dashx/react-native/android/src/main/AndroidManifest.xml
@@ -52,5 +52,8 @@ dependencies {
52
52
  implementation 'com.google.code.gson:gson:2.9.0'
53
53
  implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0'
54
54
 
55
- implementation "com.dashx:dashx-android:1.1.3"
55
+ // Ensure Firebase Messaging types are available for FCM service subclass
56
+ implementation 'com.google.firebase:firebase-messaging-ktx:23.1.2'
57
+
58
+ implementation "com.dashx:dashx-android:1.1.5"
56
59
  }
@@ -1,4 +1,16 @@
1
-
2
- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
-
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ xmlns:tools="http://schemas.android.com/tools">
3
+ <application>
4
+ <!-- Replace dashx-android's FCM service with our subclass that also emits to JS. -->
5
+ <service
6
+ android:name="com.dashx.android.DashXFirebaseMessagingService"
7
+ tools:node="remove" />
8
+ <service
9
+ android:name="com.dashx.rn.sdk.DashXReactNativeFirebaseMessagingService"
10
+ android:exported="false">
11
+ <intent-filter>
12
+ <action android:name="com.google.firebase.MESSAGING_EVENT" />
13
+ </intent-filter>
14
+ </service>
15
+ </application>
4
16
  </manifest>
@@ -0,0 +1,72 @@
1
+ package com.dashx.rn.sdk
2
+
3
+ import com.dashx.android.DashXFirebaseMessagingService
4
+ import com.dashx.android.DashXLog
5
+ import com.facebook.react.bridge.Arguments
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.WritableMap
8
+ import com.facebook.react.modules.core.DeviceEventManagerModule
9
+ import com.google.firebase.messaging.RemoteMessage
10
+
11
+ /**
12
+ * Extends dashx-android's FCM service to also emit "messageReceived" to the React Native JS layer
13
+ * so that DashX.onMessageReceived() callbacks receive push notifications.
14
+ */
15
+ class DashXReactNativeFirebaseMessagingService : DashXFirebaseMessagingService() {
16
+
17
+ private val tag = DashXReactNativeFirebaseMessagingService::class.java.simpleName
18
+
19
+ override fun onMessageReceived(remoteMessage: RemoteMessage) {
20
+ // Preserve dashx-android behavior (notification display + tracking)
21
+ super.onMessageReceived(remoteMessage)
22
+
23
+ val context = MessageReceivedEventHolder.reactContext ?: run {
24
+ DashXLog.d(tag, "React context not available, skipping JS emit")
25
+ return
26
+ }
27
+
28
+ if (!context.hasActiveReactInstance()) {
29
+ DashXLog.d(tag, "No active React instance, skipping JS emit")
30
+ return
31
+ }
32
+
33
+ val payload = remoteMessageToWritableMap(remoteMessage)
34
+ context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
35
+ .emit("messageReceived", payload)
36
+ }
37
+
38
+ private fun remoteMessageToWritableMap(remoteMessage: RemoteMessage): WritableMap {
39
+ val map = Arguments.createMap()
40
+
41
+ // Data payload (always present as Map<String, String>)
42
+ remoteMessage.data.let { data ->
43
+ if (!data.isNullOrEmpty()) {
44
+ val dataMap = Arguments.createMap()
45
+ for ((key, value) in data) {
46
+ dataMap.putString(key, value)
47
+ }
48
+ map.putMap("data", dataMap)
49
+ }
50
+ }
51
+
52
+ // Notification payload (if present)
53
+ remoteMessage.notification?.let { notification ->
54
+ val notifMap = Arguments.createMap()
55
+ notification.title?.let { notifMap.putString("title", it) }
56
+ notification.body?.let { notifMap.putString("body", it) }
57
+ notification.bodyLocalizationKey?.let { notifMap.putString("bodyLocalizationKey", it) }
58
+ notification.titleLocalizationKey?.let { notifMap.putString("titleLocalizationKey", it) }
59
+ notification.channelId?.let { notifMap.putString("channelId", it) }
60
+ notification.clickAction?.let { notifMap.putString("clickAction", it) }
61
+ notification.tag?.let { notifMap.putString("tag", it) }
62
+ notification.imageUrl?.toString()?.let { notifMap.putString("imageUrl", it) }
63
+ map.putMap("notification", notifMap)
64
+ }
65
+
66
+ remoteMessage.messageId?.let { map.putString("messageId", it) }
67
+ remoteMessage.senderId?.let { map.putString("senderId", it) }
68
+ remoteMessage.from?.let { map.putString("from", it) }
69
+
70
+ return map
71
+ }
72
+ }
@@ -13,6 +13,16 @@ import kotlinx.serialization.json.JsonObject
13
13
  class DashXReactNativeModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
14
14
  private val tag = DashXReactNativeModule::class.java.simpleName
15
15
 
16
+ override fun initialize() {
17
+ super.initialize()
18
+ MessageReceivedEventHolder.reactContext = reactContext
19
+ }
20
+
21
+ override fun invalidate() {
22
+ MessageReceivedEventHolder.reactContext = null
23
+ super.invalidate()
24
+ }
25
+
16
26
  override fun getName(): String {
17
27
  return "DashXReactNative"
18
28
  }
@@ -77,11 +87,38 @@ class DashXReactNativeModule(private val reactContext: ReactApplicationContext)
77
87
  }
78
88
 
79
89
  @ReactMethod
80
- fun fetchContent(urn: String, options: ReadableMap?, promise: Promise) {
90
+ fun fetchRecord(urn: String, options: ReadableMap?, promise: Promise) {
91
+ val preview = options?.getBooleanIfPresent("preview")
92
+ val language = options?.getStringIfPresent("language")
93
+ val fields = try {
94
+ convertReadableArrayToKJsonList(options?.getArray("fields"))
95
+ } catch (e: Exception) {
96
+ DashXLog.d(tag, e.message)
97
+ promise.reject("EUNSPECIFIED", "Error parsing fields: ${e.message}")
98
+ return
99
+ }
100
+ val include = try {
101
+ convertReadableArrayToKJsonList(options?.getArray("include"))
102
+ } catch (e: Exception) {
103
+ DashXLog.d(tag, e.message)
104
+ promise.reject("EUNSPECIFIED", "Error parsing include: ${e.message}")
105
+ return
106
+ }
107
+ val exclude = try {
108
+ convertReadableArrayToKJsonList(options?.getArray("exclude"))
109
+ } catch (e: Exception) {
110
+ DashXLog.d(tag, e.message)
111
+ promise.reject("EUNSPECIFIED", "Error parsing exclude: ${e.message}")
112
+ return
113
+ }
114
+
81
115
  DashX.fetchRecord(
82
- urn,
83
- options?.getBooleanIfPresent("preview"),
84
- options?.getStringIfPresent("language"),
116
+ urn = urn,
117
+ preview = preview,
118
+ language = language,
119
+ fields = fields,
120
+ include = include,
121
+ exclude = exclude,
85
122
  onError = {
86
123
  promise.reject("EUNSPECIFIED", it.message)
87
124
  },
@@ -92,30 +129,62 @@ class DashXReactNativeModule(private val reactContext: ReactApplicationContext)
92
129
  }
93
130
 
94
131
  @ReactMethod
95
- fun searchContent(contentType: String, options: ReadableMap?, promise: Promise) {
132
+ fun searchRecords(resource: String, options: ReadableMap?, promise: Promise) {
96
133
  val jsonFilter = try {
97
- convertMapToJson(options?.getMap("filter"))
134
+ convertMapToJson(options?.getMap("filter"))?.let { convertJsonToKJson(it) }
98
135
  } catch (e: Exception) {
99
136
  DashXLog.d(tag, e.message)
100
- throw Exception("Encountered an error while parsing filter")
137
+ promise.reject("EUNSPECIFIED", "Error parsing filter: ${e.message}")
138
+ return
101
139
  }
102
-
103
- val jsonOrder = try {
104
- convertMapToJson(options?.getMap("order"))
140
+ val order = try {
141
+ convertReadableArrayToKJsonList(options?.getArray("order"))
142
+ } catch (e: Exception) {
143
+ DashXLog.d(tag, e.message)
144
+ promise.reject("EUNSPECIFIED", "Error parsing order: ${e.message}")
145
+ return
146
+ }
147
+ val limit = options?.getIntIfPresent("limit")
148
+ val preview = options?.getBooleanIfPresent("preview")
149
+ val language = options?.getStringIfPresent("language")
150
+ val fields = try {
151
+ convertReadableArrayToKJsonList(options?.getArray("fields"))
152
+ } catch (e: Exception) {
153
+ DashXLog.d(tag, e.message)
154
+ promise.reject("EUNSPECIFIED", "Error parsing fields: ${e.message}")
155
+ return
156
+ }
157
+ val include = try {
158
+ convertReadableArrayToKJsonList(options?.getArray("include"))
159
+ } catch (e: Exception) {
160
+ DashXLog.d(tag, e.message)
161
+ promise.reject("EUNSPECIFIED", "Error parsing include: ${e.message}")
162
+ return
163
+ }
164
+ val exclude = try {
165
+ convertReadableArrayToKJsonList(options?.getArray("exclude"))
105
166
  } catch (e: Exception) {
106
167
  DashXLog.d(tag, e.message)
107
- throw Exception("Encountered an error while parsing order")
168
+ promise.reject("EUNSPECIFIED", "Error parsing exclude: ${e.message}")
169
+ return
108
170
  }
109
171
 
110
172
  DashX.searchRecords(
111
- contentType,
112
- convertJsonToKJson(jsonFilter),
173
+ resource = resource,
174
+ filter = jsonFilter,
175
+ order = order,
176
+ limit = limit,
177
+ preview = preview,
178
+ language = language,
179
+ fields = fields,
180
+ include = include,
181
+ exclude = exclude,
113
182
  onError = {
114
183
  promise.reject("EUNSPECIFIED", it.message)
115
184
  },
116
- onSuccess = { content ->
185
+ onSuccess = { records ->
117
186
  val readableArray = Arguments.createArray()
118
- content.forEach {
187
+ records.forEach {
119
188
  readableArray.pushMap(convertJsonToMap(convertKJsonToJson(it)))
120
189
  }
121
190
  promise.resolve(readableArray)
@@ -0,0 +1,14 @@
1
+ package com.dashx.rn.sdk
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+
5
+ /**
6
+ * Holds a reference to the React context so that [DashXReactNativeFirebaseMessagingService]
7
+ * can emit "messageReceived" events to JS when FCM messages arrive.
8
+ * Set by [DashXReactNativeModule], cleared when the module is invalidated.
9
+ */
10
+ object MessageReceivedEventHolder {
11
+ @Volatile
12
+ var reactContext: ReactApplicationContext? = null
13
+ internal set
14
+ }
@@ -26,6 +26,20 @@ fun convertJsonToKJson(jsonObject: JsonObject?): KJsonObject? {
26
26
  return Json.decodeFromString(jsonString)
27
27
  }
28
28
 
29
+ /**
30
+ * Converts a ReadableArray of maps to a list of kotlinx JsonObjects for DashX.searchRecords options (order, fields, include, exclude).
31
+ */
32
+ @Throws(JSONException::class)
33
+ fun convertReadableArrayToKJsonList(readableArray: ReadableArray?): List<KJsonObject>? {
34
+ if (readableArray == null || readableArray.size() == 0) return null
35
+ return (0 until readableArray.size()).mapNotNull { i ->
36
+ when (readableArray.getType(i)) {
37
+ ReadableType.Map -> readableArray.getMap(i)?.let { convertMapToJson(it)?.let { gson -> convertJsonToKJson(gson) } }
38
+ else -> null
39
+ }
40
+ }.ifEmpty { null }
41
+ }
42
+
29
43
  @Throws(JSONException::class)
30
44
  fun convertMapToJson(readableMap: ReadableMap?): JsonObject? {
31
45
  val iterator = readableMap?.keySetIterator() ?: return null
package/babel.config.js CHANGED
@@ -1,3 +1,3 @@
1
1
  module.exports = {
2
- presets: ['module:metro-react-native-babel-preset'],
2
+ presets: ['module:@react-native/babel-preset'],
3
3
  };
package/index.d.ts CHANGED
@@ -1,5 +1,14 @@
1
1
  import { EmitterSubscription } from 'react-native';
2
2
 
3
+ /**
4
+ * Error codes returned by native SDKs in promise rejections.
5
+ * Consistent across iOS and Android.
6
+ */
7
+ export enum DashXErrorCode {
8
+ /** An unspecified error occurred. */
9
+ EUNSPECIFIED = 'EUNSPECIFIED',
10
+ }
11
+
3
12
  export interface ConfigureOptions {
4
13
  publicKey: string;
5
14
  baseURI?: string;
@@ -16,6 +25,43 @@ export interface IdentifyOptions {
16
25
 
17
26
  export type LogLevel = 0 | 1 | 2;
18
27
 
28
+ export interface FetchRecordOptions {
29
+ preview?: boolean;
30
+ language?: string;
31
+ fields?: Record<string, unknown>[];
32
+ include?: Record<string, unknown>[];
33
+ exclude?: Record<string, unknown>[];
34
+ }
35
+
36
+ export interface SearchRecordsOptions {
37
+ filter?: Record<string, unknown>;
38
+ order?: Record<string, unknown>[];
39
+ limit?: number;
40
+ page?: number;
41
+ preview?: boolean;
42
+ language?: string;
43
+ fields?: Record<string, unknown>[];
44
+ include?: Record<string, unknown>[];
45
+ exclude?: Record<string, unknown>[];
46
+ }
47
+
48
+ export interface AssetData {
49
+ status?: string;
50
+ url?: string;
51
+ playbackIds?: { id?: string; policy?: string }[];
52
+ }
53
+
54
+ export interface AssetResponse {
55
+ status?: string;
56
+ data?: { asset?: AssetData };
57
+ }
58
+
59
+ /**
60
+ * Mirrors UNAuthorizationStatus integer values:
61
+ * 0 = notDetermined, 1 = denied, 2 = authorized, 3 = provisional, 4 = ephemeral
62
+ */
63
+ export type NotificationPermissionStatus = 0 | 1 | 2 | 3 | 4;
64
+
19
65
  export interface NotificationMessage {
20
66
  [key: string]: unknown;
21
67
  }
@@ -52,6 +98,24 @@ export interface DashXInstance {
52
98
  */
53
99
  screen(screenName: string, data?: Record<string, unknown>): void;
54
100
 
101
+ /**
102
+ * Fetch a single record by URN (e.g. "article/123") with optional preview, language, fields, include, exclude.
103
+ * Returns a promise resolving to the record object.
104
+ */
105
+ fetchRecord(
106
+ urn: string,
107
+ options?: FetchRecordOptions
108
+ ): Promise<Record<string, unknown>>;
109
+
110
+ /**
111
+ * Search records by resource with optional filter, order, limit, preview, language, fields, include, exclude.
112
+ * Returns a promise resolving to an array of record objects.
113
+ */
114
+ searchRecords(
115
+ resource: string,
116
+ options?: SearchRecordsOptions
117
+ ): Promise<Record<string, unknown>[]>;
118
+
55
119
  /**
56
120
  * Subscribe the current device to push notifications.
57
121
  */
@@ -86,6 +150,49 @@ export interface DashXInstance {
86
150
  onMessageReceived(
87
151
  callback: (message: NotificationMessage) => void
88
152
  ): EmitterSubscription;
153
+
154
+ /**
155
+ * Upload a local file to DashX. Returns an AssetResponse with the asset status and URL.
156
+ * @param filePath Absolute path to the local file.
157
+ */
158
+ uploadAsset(
159
+ filePath: string,
160
+ resource: string,
161
+ attribute: string
162
+ ): Promise<AssetResponse>;
163
+
164
+ /**
165
+ * Fetch details of a previously uploaded asset by its ID.
166
+ */
167
+ fetchAsset(assetId: string): Promise<AssetResponse>;
168
+
169
+ /**
170
+ * Enable automatic app lifecycle event tracking (iOS only).
171
+ */
172
+ enableLifecycleTracking(): void;
173
+
174
+ /**
175
+ * Enable IDFA/ATT ad tracking and request the App Tracking Transparency permission (iOS only).
176
+ */
177
+ enableAdTracking(): void;
178
+
179
+ /**
180
+ * Request push notification permission from the user.
181
+ * Resolves with a NotificationPermissionStatus integer.
182
+ */
183
+ requestNotificationPermission(): Promise<NotificationPermissionStatus>;
184
+
185
+ /**
186
+ * Get the current push notification permission status without prompting.
187
+ * Resolves with a NotificationPermissionStatus integer.
188
+ */
189
+ getNotificationPermissionStatus(): Promise<NotificationPermissionStatus>;
190
+
191
+ /**
192
+ * Register a listener for deep link / universal link events dispatched by the SDK.
193
+ * Returns a subscription that can be removed via `.remove()`.
194
+ */
195
+ onLinkReceived(callback: (url: string) => void): EmitterSubscription;
89
196
  }
90
197
 
91
198
  declare const DashX: DashXInstance;
package/index.js CHANGED
@@ -40,7 +40,9 @@ const DashX = {
40
40
  throw new Error('DashX.configure: options must be an object');
41
41
  }
42
42
  if (!options.publicKey || typeof options.publicKey !== 'string') {
43
- throw new Error('DashX.configure: publicKey is required and must be a string');
43
+ throw new Error(
44
+ 'DashX.configure: publicKey is required and must be a string'
45
+ );
44
46
  }
45
47
  return getNativeDashX().configure(options);
46
48
  },
@@ -54,10 +56,14 @@ const DashX = {
54
56
 
55
57
  setIdentity(uid, token) {
56
58
  if (!uid || typeof uid !== 'string') {
57
- throw new Error('DashX.setIdentity: uid is required and must be a string');
59
+ throw new Error(
60
+ 'DashX.setIdentity: uid is required and must be a string'
61
+ );
58
62
  }
59
63
  if (!token || typeof token !== 'string') {
60
- throw new Error('DashX.setIdentity: token is required and must be a string');
64
+ throw new Error(
65
+ 'DashX.setIdentity: token is required and must be a string'
66
+ );
61
67
  }
62
68
  return getNativeDashX().setIdentity(uid, token);
63
69
  },
@@ -75,11 +81,37 @@ const DashX = {
75
81
 
76
82
  screen(screenName, data) {
77
83
  if (!screenName || typeof screenName !== 'string') {
78
- throw new Error('DashX.screen: screenName is required and must be a string');
84
+ throw new Error(
85
+ 'DashX.screen: screenName is required and must be a string'
86
+ );
79
87
  }
80
88
  return getNativeDashX().screen(screenName, data || null);
81
89
  },
82
90
 
91
+ fetchRecord(urn, options = {}) {
92
+ if (!urn || typeof urn !== 'string') {
93
+ throw new Error(
94
+ 'DashX.fetchRecord: urn is required and must be a string (e.g. "article/123")'
95
+ );
96
+ }
97
+ if (options !== null && typeof options !== 'object') {
98
+ throw new Error('DashX.fetchRecord: options must be an object');
99
+ }
100
+ return getNativeDashX().fetchRecord(urn, options || null);
101
+ },
102
+
103
+ searchRecords(resource, options = {}) {
104
+ if (!resource || typeof resource !== 'string') {
105
+ throw new Error(
106
+ 'DashX.searchRecords: resource is required and must be a string'
107
+ );
108
+ }
109
+ if (options !== null && typeof options !== 'object') {
110
+ throw new Error('DashX.searchRecords: options must be an object');
111
+ }
112
+ return getNativeDashX().searchRecords(resource, options || null);
113
+ },
114
+
83
115
  fetchStoredPreferences() {
84
116
  return getNativeDashX().fetchStoredPreferences();
85
117
  },
@@ -114,6 +146,51 @@ const DashX = {
114
146
  }
115
147
  return getEventEmitter().addListener('messageReceived', callback);
116
148
  },
149
+
150
+ uploadAsset(filePath, resource, attribute) {
151
+ if (!filePath || typeof filePath !== 'string') {
152
+ throw new Error('DashX.uploadAsset: filePath must be a string');
153
+ }
154
+ if (!resource || typeof resource !== 'string') {
155
+ throw new Error('DashX.uploadAsset: resource must be a string');
156
+ }
157
+ if (!attribute || typeof attribute !== 'string') {
158
+ throw new Error('DashX.uploadAsset: attribute must be a string');
159
+ }
160
+ return getNativeDashX().uploadAsset(filePath, resource, attribute);
161
+ },
162
+
163
+ fetchAsset(assetId) {
164
+ if (!assetId || typeof assetId !== 'string') {
165
+ throw new Error('DashX.fetchAsset: assetId must be a string');
166
+ }
167
+ return getNativeDashX().fetchAsset(assetId);
168
+ },
169
+
170
+ enableLifecycleTracking() {
171
+ if (Platform.OS !== 'ios') return;
172
+ return getNativeDashX().enableLifecycleTracking();
173
+ },
174
+
175
+ enableAdTracking() {
176
+ if (Platform.OS !== 'ios') return;
177
+ return getNativeDashX().enableAdTracking();
178
+ },
179
+
180
+ requestNotificationPermission() {
181
+ return getNativeDashX().requestNotificationPermission();
182
+ },
183
+
184
+ getNotificationPermissionStatus() {
185
+ return getNativeDashX().getNotificationPermissionStatus();
186
+ },
187
+
188
+ onLinkReceived(callback) {
189
+ if (typeof callback !== 'function') {
190
+ throw new Error('DashX.onLinkReceived: callback must be a function');
191
+ }
192
+ return getEventEmitter().addListener('linkReceived', callback);
193
+ },
117
194
  };
118
195
 
119
196
  export default DashX;
package/ios/.DS_Store ADDED
Binary file