@loyalytics/swan-react-native-sdk 2.1.3-beta.1 → 2.1.3-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -107,12 +107,32 @@ const ECOM_EVENTS = exports.ECOM_EVENTS = Object.freeze({
107
107
  SHIPPED: 'shipped',
108
108
  PRODUCT_QUANTITY_SELECTED: 'productQuantitySelected'
109
109
  });
110
+ /** Parse the keyValuePairs JSON string from notification data. Returns empty object on missing/invalid input. */
111
+ function parseKeyValuePairs(data) {
112
+ try {
113
+ const raw = data?.keyValuePairs;
114
+ if (!raw) return {};
115
+ const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
116
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
117
+ return parsed;
118
+ }
119
+ _Logger.default.warn('[SwanSDK] keyValuePairs from notification data is not a valid object');
120
+ return {};
121
+ } catch {
122
+ _Logger.default.warn('[SwanSDK] Failed to parse keyValuePairs from notification data');
123
+ return {};
124
+ }
125
+ }
110
126
 
111
127
  /**
112
128
  * Notification deep link payload
113
129
  * Emitted when user clicks on a push notification
114
130
  */
115
131
 
132
+ /**
133
+ * Deep link payload — unified event for ALL deep link sources (push, email, SMS, etc.)
134
+ */
135
+
116
136
  // Re-export for external use
117
137
 
118
138
  class SwanSDK {
@@ -606,6 +626,19 @@ class SwanSDK {
606
626
  */
607
627
  emitNotificationOpened(payload) {
608
628
  this.emit(SwanSDK.EVENTS.NOTIFICATION_OPENED, payload);
629
+ // Also emit unified deep link event for push source
630
+ this.emitDeepLinkOpened({
631
+ ...payload,
632
+ source: 'push'
633
+ });
634
+ }
635
+
636
+ /**
637
+ * Emit deep link opened event — unified event for all deep link sources
638
+ * @internal
639
+ */
640
+ emitDeepLinkOpened(payload) {
641
+ this.emit(SwanSDK.EVENTS.DEEP_LINK_OPENED, payload);
609
642
  }
610
643
 
611
644
  /**
@@ -741,6 +774,15 @@ class SwanSDK {
741
774
  this.trackEvent('SWAN_NOTIFICATION_ACK', ackData).catch(error => {
742
775
  _Logger.default.error('[SwanSDK] Failed to send deep link click ACK:', error);
743
776
  });
777
+
778
+ // Emit unified deep link event for app navigation
779
+ const nonSwanParams = Object.fromEntries(Object.entries(parsed.params).filter(([key]) => !key.startsWith('swan_')));
780
+ this.emitDeepLinkOpened({
781
+ route: parsed.path,
782
+ source: swanParams.swan_channel || 'deepLink',
783
+ keyValuePairs: nonSwanParams,
784
+ ...swanParams
785
+ });
744
786
  } catch (error) {
745
787
  _Logger.default.error('[SwanSDK] handleDeepLink: unexpected error:', error);
746
788
  }
@@ -2601,6 +2643,7 @@ class SwanSDK {
2601
2643
  static EVENTS = {
2602
2644
  PUSH_NOTIFICATION_RECEIVED: 'swnPushNotificationReceived',
2603
2645
  NOTIFICATION_OPENED: 'swanTapPushNotifiactioncallback',
2646
+ DEEP_LINK_OPENED: 'swanDeepLinkOpened',
2604
2647
  TOKEN_RECEIVED: 'swnTokenReceived',
2605
2648
  TOKEN_REFRESH: 'swnTokenRefresh',
2606
2649
  PERMISSION_CHANGED: 'swnPermissionChanged'
@@ -2658,11 +2701,9 @@ class SwanSDK {
2658
2701
  // For carousel notifications, the default route is in 'defaultRoute' field
2659
2702
  const resolvedRoute = notificationData.route || notificationData.defaultRoute;
2660
2703
  const deepLinkPayload = {
2704
+ ...notificationData,
2661
2705
  route: resolvedRoute,
2662
- data: {
2663
- ...notificationData,
2664
- route: resolvedRoute
2665
- },
2706
+ keyValuePairs: parseKeyValuePairs(notificationData),
2666
2707
  title: initialNotification.notification?.title || notificationData.title,
2667
2708
  body: initialNotification.notification?.body || notificationData.body
2668
2709
  };
@@ -2705,11 +2746,9 @@ class SwanSDK {
2705
2746
  // For carousel notifications, the default route is in 'defaultRoute' field
2706
2747
  const resolvedRoute = notificationData.route || notificationData.defaultRoute;
2707
2748
  const deepLinkPayload = {
2749
+ ...notificationData,
2708
2750
  route: resolvedRoute,
2709
- data: {
2710
- ...notificationData,
2711
- route: resolvedRoute
2712
- },
2751
+ keyValuePairs: parseKeyValuePairs(notificationData),
2713
2752
  title: initialNotification.notification?.title || notificationData.title,
2714
2753
  body: initialNotification.notification?.body || notificationData.body
2715
2754
  };
@@ -3467,11 +3506,9 @@ function createNotificationOpenedHandler() {
3467
3506
  }
3468
3507
  }
3469
3508
  const deepLinkPayload = {
3509
+ ...notificationData,
3470
3510
  route,
3471
- data: {
3472
- ...notificationData,
3473
- route
3474
- },
3511
+ keyValuePairs: parseKeyValuePairs(notificationData),
3475
3512
  title: notificationData.title,
3476
3513
  body: notificationData.body
3477
3514
  };
@@ -3559,11 +3596,9 @@ function createNotifeeForegroundHandler() {
3559
3596
  }
3560
3597
  }
3561
3598
  const deepLinkPayload = {
3599
+ ...notificationData,
3562
3600
  route,
3563
- data: {
3564
- ...notificationData,
3565
- route
3566
- },
3601
+ keyValuePairs: parseKeyValuePairs(notificationData),
3567
3602
  title: event?.detail?.notification?.title,
3568
3603
  body: event?.detail?.notification?.body
3569
3604
  };
@@ -3645,11 +3680,9 @@ function createNotifeeBackgroundHandler() {
3645
3680
  }
3646
3681
  }
3647
3682
  const deepLinkPayload = {
3683
+ ...notificationData,
3648
3684
  route,
3649
- data: {
3650
- ...notificationData,
3651
- route
3652
- },
3685
+ keyValuePairs: parseKeyValuePairs(notificationData),
3653
3686
  title: detail?.notification?.title,
3654
3687
  body: detail?.notification?.body
3655
3688
  };