@metamask-previews/notification-services-controller 24.1.2-preview-e4acb70 → 24.1.2-preview-5620ede0b

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 (104) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/NotificationServicesController/NotificationServicesController.cjs +4 -2
  3. package/dist/NotificationServicesController/NotificationServicesController.cjs.map +1 -1
  4. package/dist/NotificationServicesController/NotificationServicesController.d.cts.map +1 -1
  5. package/dist/NotificationServicesController/NotificationServicesController.d.mts.map +1 -1
  6. package/dist/NotificationServicesController/NotificationServicesController.mjs +4 -2
  7. package/dist/NotificationServicesController/NotificationServicesController.mjs.map +1 -1
  8. package/dist/NotificationServicesController/index.cjs +3 -1
  9. package/dist/NotificationServicesController/index.cjs.map +1 -1
  10. package/dist/NotificationServicesController/index.d.cts +1 -0
  11. package/dist/NotificationServicesController/index.d.cts.map +1 -1
  12. package/dist/NotificationServicesController/index.d.mts +1 -0
  13. package/dist/NotificationServicesController/index.d.mts.map +1 -1
  14. package/dist/NotificationServicesController/index.mjs +1 -0
  15. package/dist/NotificationServicesController/index.mjs.map +1 -1
  16. package/dist/NotificationServicesController/mocks/mock-raw-notifications.cjs +1 -0
  17. package/dist/NotificationServicesController/mocks/mock-raw-notifications.cjs.map +1 -1
  18. package/dist/NotificationServicesController/mocks/mock-raw-notifications.d.cts.map +1 -1
  19. package/dist/NotificationServicesController/mocks/mock-raw-notifications.d.mts.map +1 -1
  20. package/dist/NotificationServicesController/mocks/mock-raw-notifications.mjs +1 -0
  21. package/dist/NotificationServicesController/mocks/mock-raw-notifications.mjs.map +1 -1
  22. package/dist/NotificationServicesController/processors/process-api-notifications.cjs +2 -0
  23. package/dist/NotificationServicesController/processors/process-api-notifications.cjs.map +1 -1
  24. package/dist/NotificationServicesController/processors/process-api-notifications.d.cts.map +1 -1
  25. package/dist/NotificationServicesController/processors/process-api-notifications.d.mts.map +1 -1
  26. package/dist/NotificationServicesController/processors/process-api-notifications.mjs +2 -0
  27. package/dist/NotificationServicesController/processors/process-api-notifications.mjs.map +1 -1
  28. package/dist/NotificationServicesController/processors/process-feature-announcement.cjs +2 -0
  29. package/dist/NotificationServicesController/processors/process-feature-announcement.cjs.map +1 -1
  30. package/dist/NotificationServicesController/processors/process-feature-announcement.d.cts.map +1 -1
  31. package/dist/NotificationServicesController/processors/process-feature-announcement.d.mts.map +1 -1
  32. package/dist/NotificationServicesController/processors/process-feature-announcement.mjs +2 -0
  33. package/dist/NotificationServicesController/processors/process-feature-announcement.mjs.map +1 -1
  34. package/dist/NotificationServicesController/processors/process-snap-notifications.cjs +2 -0
  35. package/dist/NotificationServicesController/processors/process-snap-notifications.cjs.map +1 -1
  36. package/dist/NotificationServicesController/processors/process-snap-notifications.d.cts.map +1 -1
  37. package/dist/NotificationServicesController/processors/process-snap-notifications.d.mts.map +1 -1
  38. package/dist/NotificationServicesController/processors/process-snap-notifications.mjs +2 -0
  39. package/dist/NotificationServicesController/processors/process-snap-notifications.mjs.map +1 -1
  40. package/dist/NotificationServicesController/types/notification/notification.cjs.map +1 -1
  41. package/dist/NotificationServicesController/types/notification/notification.d.cts +1 -0
  42. package/dist/NotificationServicesController/types/notification/notification.d.cts.map +1 -1
  43. package/dist/NotificationServicesController/types/notification/notification.d.mts +1 -0
  44. package/dist/NotificationServicesController/types/notification/notification.d.mts.map +1 -1
  45. package/dist/NotificationServicesController/types/notification/notification.mjs.map +1 -1
  46. package/dist/NotificationServicesController/types/notification-api/schema.cjs.map +1 -1
  47. package/dist/NotificationServicesController/types/notification-api/schema.d.cts +8 -1
  48. package/dist/NotificationServicesController/types/notification-api/schema.d.cts.map +1 -1
  49. package/dist/NotificationServicesController/types/notification-api/schema.d.mts +8 -1
  50. package/dist/NotificationServicesController/types/notification-api/schema.d.mts.map +1 -1
  51. package/dist/NotificationServicesController/types/notification-api/schema.mjs.map +1 -1
  52. package/dist/NotificationServicesController/utils/get-notification-subtype.cjs +33 -0
  53. package/dist/NotificationServicesController/utils/get-notification-subtype.cjs.map +1 -0
  54. package/dist/NotificationServicesController/utils/get-notification-subtype.d.cts +17 -0
  55. package/dist/NotificationServicesController/utils/get-notification-subtype.d.cts.map +1 -0
  56. package/dist/NotificationServicesController/utils/get-notification-subtype.d.mts +17 -0
  57. package/dist/NotificationServicesController/utils/get-notification-subtype.d.mts.map +1 -0
  58. package/dist/NotificationServicesController/utils/get-notification-subtype.mjs +29 -0
  59. package/dist/NotificationServicesController/utils/get-notification-subtype.mjs.map +1 -0
  60. package/dist/NotificationServicesPushController/NotificationServicesPushController.cjs.map +1 -1
  61. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.cts +3 -4
  62. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.cts.map +1 -1
  63. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.mts +3 -4
  64. package/dist/NotificationServicesPushController/NotificationServicesPushController.d.mts.map +1 -1
  65. package/dist/NotificationServicesPushController/NotificationServicesPushController.mjs.map +1 -1
  66. package/dist/NotificationServicesPushController/types/index.cjs.map +1 -1
  67. package/dist/NotificationServicesPushController/types/index.d.cts +1 -0
  68. package/dist/NotificationServicesPushController/types/index.d.cts.map +1 -1
  69. package/dist/NotificationServicesPushController/types/index.d.mts +1 -0
  70. package/dist/NotificationServicesPushController/types/index.d.mts.map +1 -1
  71. package/dist/NotificationServicesPushController/types/index.mjs.map +1 -1
  72. package/dist/NotificationServicesPushController/types/push-analytics.cjs +5 -0
  73. package/dist/NotificationServicesPushController/types/push-analytics.cjs.map +1 -0
  74. package/dist/NotificationServicesPushController/types/push-analytics.d.cts +20 -0
  75. package/dist/NotificationServicesPushController/types/push-analytics.d.cts.map +1 -0
  76. package/dist/NotificationServicesPushController/types/push-analytics.d.mts +20 -0
  77. package/dist/NotificationServicesPushController/types/push-analytics.d.mts.map +1 -0
  78. package/dist/NotificationServicesPushController/types/push-analytics.mjs +4 -0
  79. package/dist/NotificationServicesPushController/types/push-analytics.mjs.map +1 -0
  80. package/dist/NotificationServicesPushController/utils/index.cjs +1 -0
  81. package/dist/NotificationServicesPushController/utils/index.cjs.map +1 -1
  82. package/dist/NotificationServicesPushController/utils/index.d.cts +1 -0
  83. package/dist/NotificationServicesPushController/utils/index.d.cts.map +1 -1
  84. package/dist/NotificationServicesPushController/utils/index.d.mts +1 -0
  85. package/dist/NotificationServicesPushController/utils/index.d.mts.map +1 -1
  86. package/dist/NotificationServicesPushController/utils/index.mjs +1 -0
  87. package/dist/NotificationServicesPushController/utils/index.mjs.map +1 -1
  88. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.cjs +27 -0
  89. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.cjs.map +1 -0
  90. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.d.cts +12 -0
  91. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.d.cts.map +1 -0
  92. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.d.mts +12 -0
  93. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.d.mts.map +1 -0
  94. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.mjs +23 -0
  95. package/dist/NotificationServicesPushController/utils/to-push-analytics-payload.mjs.map +1 -0
  96. package/dist/NotificationServicesPushController/web/push-utils.cjs +13 -25
  97. package/dist/NotificationServicesPushController/web/push-utils.cjs.map +1 -1
  98. package/dist/NotificationServicesPushController/web/push-utils.d.cts +3 -3
  99. package/dist/NotificationServicesPushController/web/push-utils.d.cts.map +1 -1
  100. package/dist/NotificationServicesPushController/web/push-utils.d.mts +3 -3
  101. package/dist/NotificationServicesPushController/web/push-utils.d.mts.map +1 -1
  102. package/dist/NotificationServicesPushController/web/push-utils.mjs +13 -25
  103. package/dist/NotificationServicesPushController/web/push-utils.mjs.map +1 -1
  104. package/package.json +1 -1
@@ -8,8 +8,7 @@ const app_1 = require("firebase/app");
8
8
  const messaging_1 = require("firebase/messaging");
9
9
  const sw_1 = require("firebase/messaging/sw");
10
10
  const loglevel_1 = __importDefault(require("loglevel"));
11
- const NotificationServicesController_1 = require("../../NotificationServicesController/index.cjs");
12
- const to_raw_notification_1 = require("../../shared/to-raw-notification.cjs");
11
+ const to_push_analytics_payload_1 = require("../utils/to-push-analytics-payload.cjs");
13
12
  // Exported to help testing
14
13
  // eslint-disable-next-line import-x/no-mutable-exports
15
14
  exports.supportedCache = null;
@@ -104,27 +103,16 @@ async function listenToPushNotificationsReceived(env, handler) {
104
103
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
105
104
  async (payload) => {
106
105
  try {
107
- // MessagePayload shapes are not known
108
- // TODO - provide open-api unfied backend/frontend types
109
- // TODO - we will replace the underlying Data payload with the same Notification payload used by mobile
110
- const data = JSON.parse(payload?.data?.data ?? 'null');
111
- if (!data) {
106
+ const analyticsPayload = (0, to_push_analytics_payload_1.toPushAnalyticsPayload)(payload?.data);
107
+ if (!analyticsPayload) {
112
108
  return;
113
109
  }
114
- if (!(0, NotificationServicesController_1.isOnChainRawNotification)(data)) {
115
- return;
116
- }
117
- const notificationData = (0, to_raw_notification_1.toRawAPINotification)(data);
118
- const notification = (0, NotificationServicesController_1.safeProcessNotification)(notificationData);
119
- if (!notification) {
120
- return;
121
- }
122
- await handler?.(notification);
110
+ await handler?.(analyticsPayload);
123
111
  }
124
112
  catch (error) {
125
- // Do Nothing, cannot parse a bad notification
126
- loglevel_1.default.error('Unable to send push notification:', {
127
- notification: payload?.data?.data,
113
+ // Do Nothing, cannot handle a bad notification
114
+ loglevel_1.default.error('Unable to handle push notification:', {
115
+ notification: payload?.data,
128
116
  error,
129
117
  });
130
118
  }
@@ -162,13 +150,13 @@ function listenToPushNotificationsClicked(handler) {
162
150
  */
163
151
  function createSubscribeToPushNotifications(props) {
164
152
  return async function (env) {
165
- const onBackgroundMessageSub = await listenToPushNotificationsReceived(env, async (notification) => {
166
- props.messenger.publish('NotificationServicesPushController:onNewNotifications', notification);
167
- await props.onReceivedHandler(notification);
153
+ const onBackgroundMessageSub = await listenToPushNotificationsReceived(env, async (analyticsPayload) => {
154
+ props.messenger.publish('NotificationServicesPushController:onNewNotifications', analyticsPayload);
155
+ await props.onReceivedHandler(analyticsPayload);
168
156
  });
169
- const onClickSub = listenToPushNotificationsClicked((event, notification) => {
170
- props.messenger.publish('NotificationServicesPushController:pushNotificationClicked', notification);
171
- props.onClickHandler(event, notification);
157
+ const onClickSub = listenToPushNotificationsClicked((event, analyticsPayload) => {
158
+ props.messenger.publish('NotificationServicesPushController:pushNotificationClicked', analyticsPayload);
159
+ props.onClickHandler(event, analyticsPayload);
172
160
  });
173
161
  const unsubscribe = () => {
174
162
  onBackgroundMessageSub?.();
@@ -1 +1 @@
1
- {"version":3,"file":"push-utils.cjs","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// We are defining that this file uses a webworker global scope.\n// eslint-disable-next-line spaced-comment\n/// <reference lib=\"webworker\" />\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApp, initializeApp } from 'firebase/app';\nimport { getToken, deleteToken } from 'firebase/messaging';\nimport {\n getMessaging,\n onBackgroundMessage,\n isSupported,\n} from 'firebase/messaging/sw';\nimport type { Messaging, MessagePayload } from 'firebase/messaging/sw';\nimport log from 'loglevel';\n\nimport type { Types } from '../../NotificationServicesController';\nimport {\n isOnChainRawNotification,\n safeProcessNotification,\n} from '../../NotificationServicesController';\nimport { toRawAPINotification } from '../../shared/to-raw-notification';\nimport type { NotificationServicesPushControllerMessenger } from '../NotificationServicesPushController';\nimport type { PushNotificationEnv } from '../types/firebase';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\n// Exported to help testing\n// eslint-disable-next-line import-x/no-mutable-exports\nexport let supportedCache: boolean | null = null;\n\nconst getPushAvailability = async (): Promise<boolean> => {\n // Race condition is acceptable here - worst case is isSupported() is called\n // multiple times during initialization, which is harmless for caching a boolean\n // eslint-disable-next-line require-atomic-updates\n supportedCache ??= await isSupported();\n return supportedCache;\n};\n\nconst createFirebaseApp = async (\n env: PushNotificationEnv,\n): Promise<FirebaseApp> => {\n try {\n return getApp();\n } catch {\n const firebaseConfig = {\n apiKey: env.apiKey,\n authDomain: env.authDomain,\n storageBucket: env.storageBucket,\n projectId: env.projectId,\n messagingSenderId: env.messagingSenderId,\n appId: env.appId,\n measurementId: env.measurementId,\n };\n return initializeApp(firebaseConfig);\n }\n};\n\nconst getFirebaseMessaging = async (\n env: PushNotificationEnv,\n): Promise<Messaging | null> => {\n const supported = await getPushAvailability();\n if (!supported) {\n return null;\n }\n\n const app = await createFirebaseApp(env);\n return getMessaging(app);\n};\n\n/**\n * Creates a registration token for Firebase Cloud Messaging.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with the registration token or null if an error occurs.\n */\nexport async function createRegToken(\n env: PushNotificationEnv,\n): Promise<string | null> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const token = await getToken(messaging, {\n serviceWorkerRegistration: self.registration,\n vapidKey: env.vapidKey,\n });\n return token;\n } catch {\n return null;\n }\n}\n\n/**\n * Deletes the Firebase Cloud Messaging registration token.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with true if the token was successfully deleted, false otherwise.\n */\nexport async function deleteRegToken(\n env: PushNotificationEnv,\n): Promise<boolean> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return true;\n }\n\n await deleteToken(messaging);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Service Worker Listener for when push notifications are received.\n *\n * @param env - push notification environment\n * @param handler - handler to actually showing notification, MUST BE PROVIDED\n * @returns unsubscribe handler\n */\nasync function listenToPushNotificationsReceived(\n env: PushNotificationEnv,\n handler?: (notification: Types.INotification) => void | Promise<void>,\n): Promise<(() => void) | null> {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const unsubscribePushNotifications = onBackgroundMessage(\n messaging,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (payload: MessagePayload): Promise<void> => {\n try {\n // MessagePayload shapes are not known\n // TODO - provide open-api unfied backend/frontend types\n // TODO - we will replace the underlying Data payload with the same Notification payload used by mobile\n const data: unknown | null = JSON.parse(payload?.data?.data ?? 'null');\n\n if (!data) {\n return;\n }\n\n if (!isOnChainRawNotification(data)) {\n return;\n }\n\n const notificationData = toRawAPINotification(data);\n const notification = safeProcessNotification(notificationData);\n\n if (!notification) {\n return;\n }\n\n await handler?.(notification);\n } catch (error) {\n // Do Nothing, cannot parse a bad notification\n log.error('Unable to send push notification:', {\n notification: payload?.data?.data,\n error,\n });\n }\n },\n );\n\n const unsubscribe = (): void => unsubscribePushNotifications();\n return unsubscribe;\n}\n\n/**\n * Service Worker Listener for when a notification is clicked\n *\n * @param handler - listen to NotificationEvent from the service worker\n * @returns unsubscribe handler\n */\nfunction listenToPushNotificationsClicked(\n handler: (e: NotificationEvent, notification: Types.INotification) => void,\n): () => void {\n const clickHandler = (event: NotificationEvent): void => {\n // Get Data\n const data: Types.INotification = event?.notification?.data;\n handler(event, data);\n };\n\n self.addEventListener('notificationclick', clickHandler);\n const unsubscribe = (): void =>\n self.removeEventListener('notificationclick', clickHandler);\n return unsubscribe;\n}\n\n/**\n * A creator function that assists creating web-specific push notification subscription:\n * 1. Creates subscriptions for receiving and clicking notifications\n * 2. Creates click events when a notification is clicked\n * 3. Publishes controller messenger events\n *\n * @param props - props for this creator function.\n * @param props.onReceivedHandler - allows the developer to handle showing a notification\n * @param props.onClickHandler - allows the developer to handle clicking the notification\n * @param props.messenger - the controller messenger to publish the `onNewNotifications` and `pushNotificationsClicked` events\n * @returns a function that can be used by the controller\n */\nexport function createSubscribeToPushNotifications(props: {\n onReceivedHandler: (\n notification: Types.INotification,\n ) => void | Promise<void>;\n onClickHandler: (\n e: NotificationEvent,\n notification: Types.INotification,\n ) => void;\n messenger: NotificationServicesPushControllerMessenger;\n}): (env: PushNotificationEnv) => Promise<() => void> {\n return async function (env: PushNotificationEnv): Promise<() => void> {\n const onBackgroundMessageSub = await listenToPushNotificationsReceived(\n env,\n async (notification): Promise<void> => {\n props.messenger.publish(\n 'NotificationServicesPushController:onNewNotifications',\n notification,\n );\n await props.onReceivedHandler(notification);\n },\n );\n const onClickSub = listenToPushNotificationsClicked(\n (event, notification): void => {\n props.messenger.publish(\n 'NotificationServicesPushController:pushNotificationClicked',\n notification,\n );\n props.onClickHandler(event, notification);\n },\n );\n\n const unsubscribe = (): void => {\n onBackgroundMessageSub?.();\n onClickSub();\n };\n\n return unsubscribe;\n };\n}\n"]}
1
+ {"version":3,"file":"push-utils.cjs","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// We are defining that this file uses a webworker global scope.\n// eslint-disable-next-line spaced-comment\n/// <reference lib=\"webworker\" />\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApp, initializeApp } from 'firebase/app';\nimport { getToken, deleteToken } from 'firebase/messaging';\nimport {\n getMessaging,\n onBackgroundMessage,\n isSupported,\n} from 'firebase/messaging/sw';\nimport type { Messaging, MessagePayload } from 'firebase/messaging/sw';\nimport log from 'loglevel';\n\nimport type { NotificationServicesPushControllerMessenger } from '../NotificationServicesPushController';\nimport type { PushAnalyticsPayload } from '../types';\nimport type { PushNotificationEnv } from '../types/firebase';\nimport { toPushAnalyticsPayload } from '../utils/to-push-analytics-payload';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\n// Exported to help testing\n// eslint-disable-next-line import-x/no-mutable-exports\nexport let supportedCache: boolean | null = null;\n\nconst getPushAvailability = async (): Promise<boolean> => {\n // Race condition is acceptable here - worst case is isSupported() is called\n // multiple times during initialization, which is harmless for caching a boolean\n // eslint-disable-next-line require-atomic-updates\n supportedCache ??= await isSupported();\n return supportedCache;\n};\n\nconst createFirebaseApp = async (\n env: PushNotificationEnv,\n): Promise<FirebaseApp> => {\n try {\n return getApp();\n } catch {\n const firebaseConfig = {\n apiKey: env.apiKey,\n authDomain: env.authDomain,\n storageBucket: env.storageBucket,\n projectId: env.projectId,\n messagingSenderId: env.messagingSenderId,\n appId: env.appId,\n measurementId: env.measurementId,\n };\n return initializeApp(firebaseConfig);\n }\n};\n\nconst getFirebaseMessaging = async (\n env: PushNotificationEnv,\n): Promise<Messaging | null> => {\n const supported = await getPushAvailability();\n if (!supported) {\n return null;\n }\n\n const app = await createFirebaseApp(env);\n return getMessaging(app);\n};\n\n/**\n * Creates a registration token for Firebase Cloud Messaging.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with the registration token or null if an error occurs.\n */\nexport async function createRegToken(\n env: PushNotificationEnv,\n): Promise<string | null> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const token = await getToken(messaging, {\n serviceWorkerRegistration: self.registration,\n vapidKey: env.vapidKey,\n });\n return token;\n } catch {\n return null;\n }\n}\n\n/**\n * Deletes the Firebase Cloud Messaging registration token.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with true if the token was successfully deleted, false otherwise.\n */\nexport async function deleteRegToken(\n env: PushNotificationEnv,\n): Promise<boolean> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return true;\n }\n\n await deleteToken(messaging);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Service Worker Listener for when push notifications are received.\n *\n * @param env - push notification environment\n * @param handler - handler to actually showing notification, MUST BE PROVIDED\n * @returns unsubscribe handler\n */\nasync function listenToPushNotificationsReceived(\n env: PushNotificationEnv,\n handler?: (payload: PushAnalyticsPayload) => void | Promise<void>,\n): Promise<(() => void) | null> {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const unsubscribePushNotifications = onBackgroundMessage(\n messaging,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (payload: MessagePayload): Promise<void> => {\n try {\n const analyticsPayload = toPushAnalyticsPayload(payload?.data);\n\n if (!analyticsPayload) {\n return;\n }\n\n await handler?.(analyticsPayload);\n } catch (error) {\n // Do Nothing, cannot handle a bad notification\n log.error('Unable to handle push notification:', {\n notification: payload?.data,\n error,\n });\n }\n },\n );\n\n const unsubscribe = (): void => unsubscribePushNotifications();\n return unsubscribe;\n}\n\n/**\n * Service Worker Listener for when a notification is clicked\n *\n * @param handler - listen to NotificationEvent from the service worker\n * @returns unsubscribe handler\n */\nfunction listenToPushNotificationsClicked(\n handler: (e: NotificationEvent, payload: PushAnalyticsPayload) => void,\n): () => void {\n const clickHandler = (event: NotificationEvent): void => {\n // Get Data\n const data: PushAnalyticsPayload = event?.notification?.data;\n handler(event, data);\n };\n\n self.addEventListener('notificationclick', clickHandler);\n const unsubscribe = (): void =>\n self.removeEventListener('notificationclick', clickHandler);\n return unsubscribe;\n}\n\n/**\n * A creator function that assists creating web-specific push notification subscription:\n * 1. Creates subscriptions for receiving and clicking notifications\n * 2. Creates click events when a notification is clicked\n * 3. Publishes controller messenger events\n *\n * @param props - props for this creator function.\n * @param props.onReceivedHandler - allows the developer to handle showing a notification\n * @param props.onClickHandler - allows the developer to handle clicking the notification\n * @param props.messenger - the controller messenger to publish the `onNewNotifications` and `pushNotificationsClicked` events\n * @returns a function that can be used by the controller\n */\nexport function createSubscribeToPushNotifications(props: {\n onReceivedHandler: (payload: PushAnalyticsPayload) => void | Promise<void>;\n onClickHandler: (e: NotificationEvent, payload: PushAnalyticsPayload) => void;\n messenger: NotificationServicesPushControllerMessenger;\n}): (env: PushNotificationEnv) => Promise<() => void> {\n return async function (env: PushNotificationEnv): Promise<() => void> {\n const onBackgroundMessageSub = await listenToPushNotificationsReceived(\n env,\n async (analyticsPayload): Promise<void> => {\n props.messenger.publish(\n 'NotificationServicesPushController:onNewNotifications',\n analyticsPayload,\n );\n await props.onReceivedHandler(analyticsPayload);\n },\n );\n const onClickSub = listenToPushNotificationsClicked(\n (event, analyticsPayload): void => {\n props.messenger.publish(\n 'NotificationServicesPushController:pushNotificationClicked',\n analyticsPayload,\n );\n props.onClickHandler(event, analyticsPayload);\n },\n );\n\n const unsubscribe = (): void => {\n onBackgroundMessageSub?.();\n onClickSub();\n };\n\n return unsubscribe;\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  /// <reference lib="webworker" />
2
- import type { Types } from "../../NotificationServicesController/index.cjs";
3
2
  import type { NotificationServicesPushControllerMessenger } from "../NotificationServicesPushController.cjs";
3
+ import type { PushAnalyticsPayload } from "../types/index.cjs";
4
4
  import type { PushNotificationEnv } from "../types/firebase.cjs";
5
5
  export declare let supportedCache: boolean | null;
6
6
  /**
@@ -30,8 +30,8 @@ export declare function deleteRegToken(env: PushNotificationEnv): Promise<boolea
30
30
  * @returns a function that can be used by the controller
31
31
  */
32
32
  export declare function createSubscribeToPushNotifications(props: {
33
- onReceivedHandler: (notification: Types.INotification) => void | Promise<void>;
34
- onClickHandler: (e: NotificationEvent, notification: Types.INotification) => void;
33
+ onReceivedHandler: (payload: PushAnalyticsPayload) => void | Promise<void>;
34
+ onClickHandler: (e: NotificationEvent, payload: PushAnalyticsPayload) => void;
35
35
  messenger: NotificationServicesPushControllerMessenger;
36
36
  }): (env: PushNotificationEnv) => Promise<() => void>;
37
37
  //# sourceMappingURL=push-utils.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"push-utils.d.cts","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":";AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,uDAA6C;AAMlE,OAAO,KAAK,EAAE,2CAA2C,EAAE,kDAA8C;AACzG,OAAO,KAAK,EAAE,mBAAmB,EAAE,8BAA0B;AAM7D,eAAO,IAAI,cAAc,EAAE,OAAO,GAAG,IAAW,CAAC;AAyCjD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,OAAO,CAAC,CAYlB;AA+ED;;;;;;;;;;;GAWG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE;IACxD,iBAAiB,EAAE,CACjB,YAAY,EAAE,KAAK,CAAC,aAAa,KAC9B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,cAAc,EAAE,CACd,CAAC,EAAE,iBAAiB,EACpB,YAAY,EAAE,KAAK,CAAC,aAAa,KAC9B,IAAI,CAAC;IACV,SAAS,EAAE,2CAA2C,CAAC;CACxD,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CA6BpD"}
1
+ {"version":3,"file":"push-utils.d.cts","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":";AAcA,OAAO,KAAK,EAAE,2CAA2C,EAAE,kDAA8C;AACzG,OAAO,KAAK,EAAE,oBAAoB,EAAE,2BAAiB;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,8BAA0B;AAO7D,eAAO,IAAI,cAAc,EAAE,OAAO,GAAG,IAAW,CAAC;AAyCjD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAiED;;;;;;;;;;;GAWG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE;IACxD,iBAAiB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,cAAc,EAAE,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC9E,SAAS,EAAE,2CAA2C,CAAC;CACxD,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CA6BpD"}
@@ -1,6 +1,6 @@
1
1
  /// <reference lib="webworker" />
2
- import type { Types } from "../../NotificationServicesController/index.mjs";
3
2
  import type { NotificationServicesPushControllerMessenger } from "../NotificationServicesPushController.mjs";
3
+ import type { PushAnalyticsPayload } from "../types/index.mjs";
4
4
  import type { PushNotificationEnv } from "../types/firebase.mjs";
5
5
  export declare let supportedCache: boolean | null;
6
6
  /**
@@ -30,8 +30,8 @@ export declare function deleteRegToken(env: PushNotificationEnv): Promise<boolea
30
30
  * @returns a function that can be used by the controller
31
31
  */
32
32
  export declare function createSubscribeToPushNotifications(props: {
33
- onReceivedHandler: (notification: Types.INotification) => void | Promise<void>;
34
- onClickHandler: (e: NotificationEvent, notification: Types.INotification) => void;
33
+ onReceivedHandler: (payload: PushAnalyticsPayload) => void | Promise<void>;
34
+ onClickHandler: (e: NotificationEvent, payload: PushAnalyticsPayload) => void;
35
35
  messenger: NotificationServicesPushControllerMessenger;
36
36
  }): (env: PushNotificationEnv) => Promise<() => void>;
37
37
  //# sourceMappingURL=push-utils.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"push-utils.d.mts","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":";AAcA,OAAO,KAAK,EAAE,KAAK,EAAE,uDAA6C;AAMlE,OAAO,KAAK,EAAE,2CAA2C,EAAE,kDAA8C;AACzG,OAAO,KAAK,EAAE,mBAAmB,EAAE,8BAA0B;AAM7D,eAAO,IAAI,cAAc,EAAE,OAAO,GAAG,IAAW,CAAC;AAyCjD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,OAAO,CAAC,CAYlB;AA+ED;;;;;;;;;;;GAWG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE;IACxD,iBAAiB,EAAE,CACjB,YAAY,EAAE,KAAK,CAAC,aAAa,KAC9B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,cAAc,EAAE,CACd,CAAC,EAAE,iBAAiB,EACpB,YAAY,EAAE,KAAK,CAAC,aAAa,KAC9B,IAAI,CAAC;IACV,SAAS,EAAE,2CAA2C,CAAC;CACxD,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CA6BpD"}
1
+ {"version":3,"file":"push-utils.d.mts","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":";AAcA,OAAO,KAAK,EAAE,2CAA2C,EAAE,kDAA8C;AACzG,OAAO,KAAK,EAAE,oBAAoB,EAAE,2BAAiB;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,8BAA0B;AAO7D,eAAO,IAAI,cAAc,EAAE,OAAO,GAAG,IAAW,CAAC;AAyCjD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,OAAO,CAAC,CAYlB;AAiED;;;;;;;;;;;GAWG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE;IACxD,iBAAiB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,cAAc,EAAE,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC9E,SAAS,EAAE,2CAA2C,CAAC;CACxD,GAAG,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CA6BpD"}
@@ -9,8 +9,7 @@ import { getToken, deleteToken } from "firebase/messaging";
9
9
  import { getMessaging, onBackgroundMessage, isSupported } from "firebase/messaging/sw";
10
10
  import $log from "loglevel";
11
11
  const log = $importDefault($log);
12
- import { isOnChainRawNotification, safeProcessNotification } from "../../NotificationServicesController/index.mjs";
13
- import { toRawAPINotification } from "../../shared/to-raw-notification.mjs";
12
+ import { toPushAnalyticsPayload } from "../utils/to-push-analytics-payload.mjs";
14
13
  // Exported to help testing
15
14
  // eslint-disable-next-line import-x/no-mutable-exports
16
15
  export let supportedCache = null;
@@ -103,27 +102,16 @@ async function listenToPushNotificationsReceived(env, handler) {
103
102
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
104
103
  async (payload) => {
105
104
  try {
106
- // MessagePayload shapes are not known
107
- // TODO - provide open-api unfied backend/frontend types
108
- // TODO - we will replace the underlying Data payload with the same Notification payload used by mobile
109
- const data = JSON.parse(payload?.data?.data ?? 'null');
110
- if (!data) {
105
+ const analyticsPayload = toPushAnalyticsPayload(payload?.data);
106
+ if (!analyticsPayload) {
111
107
  return;
112
108
  }
113
- if (!isOnChainRawNotification(data)) {
114
- return;
115
- }
116
- const notificationData = toRawAPINotification(data);
117
- const notification = safeProcessNotification(notificationData);
118
- if (!notification) {
119
- return;
120
- }
121
- await handler?.(notification);
109
+ await handler?.(analyticsPayload);
122
110
  }
123
111
  catch (error) {
124
- // Do Nothing, cannot parse a bad notification
125
- log.error('Unable to send push notification:', {
126
- notification: payload?.data?.data,
112
+ // Do Nothing, cannot handle a bad notification
113
+ log.error('Unable to handle push notification:', {
114
+ notification: payload?.data,
127
115
  error,
128
116
  });
129
117
  }
@@ -161,13 +149,13 @@ function listenToPushNotificationsClicked(handler) {
161
149
  */
162
150
  export function createSubscribeToPushNotifications(props) {
163
151
  return async function (env) {
164
- const onBackgroundMessageSub = await listenToPushNotificationsReceived(env, async (notification) => {
165
- props.messenger.publish('NotificationServicesPushController:onNewNotifications', notification);
166
- await props.onReceivedHandler(notification);
152
+ const onBackgroundMessageSub = await listenToPushNotificationsReceived(env, async (analyticsPayload) => {
153
+ props.messenger.publish('NotificationServicesPushController:onNewNotifications', analyticsPayload);
154
+ await props.onReceivedHandler(analyticsPayload);
167
155
  });
168
- const onClickSub = listenToPushNotificationsClicked((event, notification) => {
169
- props.messenger.publish('NotificationServicesPushController:pushNotificationClicked', notification);
170
- props.onClickHandler(event, notification);
156
+ const onClickSub = listenToPushNotificationsClicked((event, analyticsPayload) => {
157
+ props.messenger.publish('NotificationServicesPushController:pushNotificationClicked', analyticsPayload);
158
+ props.onClickHandler(event, analyticsPayload);
171
159
  });
172
160
  const unsubscribe = () => {
173
161
  onBackgroundMessageSub?.();
@@ -1 +1 @@
1
- {"version":3,"file":"push-utils.mjs","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// We are defining that this file uses a webworker global scope.\n// eslint-disable-next-line spaced-comment\n/// <reference lib=\"webworker\" />\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApp, initializeApp } from 'firebase/app';\nimport { getToken, deleteToken } from 'firebase/messaging';\nimport {\n getMessaging,\n onBackgroundMessage,\n isSupported,\n} from 'firebase/messaging/sw';\nimport type { Messaging, MessagePayload } from 'firebase/messaging/sw';\nimport log from 'loglevel';\n\nimport type { Types } from '../../NotificationServicesController';\nimport {\n isOnChainRawNotification,\n safeProcessNotification,\n} from '../../NotificationServicesController';\nimport { toRawAPINotification } from '../../shared/to-raw-notification';\nimport type { NotificationServicesPushControllerMessenger } from '../NotificationServicesPushController';\nimport type { PushNotificationEnv } from '../types/firebase';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\n// Exported to help testing\n// eslint-disable-next-line import-x/no-mutable-exports\nexport let supportedCache: boolean | null = null;\n\nconst getPushAvailability = async (): Promise<boolean> => {\n // Race condition is acceptable here - worst case is isSupported() is called\n // multiple times during initialization, which is harmless for caching a boolean\n // eslint-disable-next-line require-atomic-updates\n supportedCache ??= await isSupported();\n return supportedCache;\n};\n\nconst createFirebaseApp = async (\n env: PushNotificationEnv,\n): Promise<FirebaseApp> => {\n try {\n return getApp();\n } catch {\n const firebaseConfig = {\n apiKey: env.apiKey,\n authDomain: env.authDomain,\n storageBucket: env.storageBucket,\n projectId: env.projectId,\n messagingSenderId: env.messagingSenderId,\n appId: env.appId,\n measurementId: env.measurementId,\n };\n return initializeApp(firebaseConfig);\n }\n};\n\nconst getFirebaseMessaging = async (\n env: PushNotificationEnv,\n): Promise<Messaging | null> => {\n const supported = await getPushAvailability();\n if (!supported) {\n return null;\n }\n\n const app = await createFirebaseApp(env);\n return getMessaging(app);\n};\n\n/**\n * Creates a registration token for Firebase Cloud Messaging.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with the registration token or null if an error occurs.\n */\nexport async function createRegToken(\n env: PushNotificationEnv,\n): Promise<string | null> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const token = await getToken(messaging, {\n serviceWorkerRegistration: self.registration,\n vapidKey: env.vapidKey,\n });\n return token;\n } catch {\n return null;\n }\n}\n\n/**\n * Deletes the Firebase Cloud Messaging registration token.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with true if the token was successfully deleted, false otherwise.\n */\nexport async function deleteRegToken(\n env: PushNotificationEnv,\n): Promise<boolean> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return true;\n }\n\n await deleteToken(messaging);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Service Worker Listener for when push notifications are received.\n *\n * @param env - push notification environment\n * @param handler - handler to actually showing notification, MUST BE PROVIDED\n * @returns unsubscribe handler\n */\nasync function listenToPushNotificationsReceived(\n env: PushNotificationEnv,\n handler?: (notification: Types.INotification) => void | Promise<void>,\n): Promise<(() => void) | null> {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const unsubscribePushNotifications = onBackgroundMessage(\n messaging,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (payload: MessagePayload): Promise<void> => {\n try {\n // MessagePayload shapes are not known\n // TODO - provide open-api unfied backend/frontend types\n // TODO - we will replace the underlying Data payload with the same Notification payload used by mobile\n const data: unknown | null = JSON.parse(payload?.data?.data ?? 'null');\n\n if (!data) {\n return;\n }\n\n if (!isOnChainRawNotification(data)) {\n return;\n }\n\n const notificationData = toRawAPINotification(data);\n const notification = safeProcessNotification(notificationData);\n\n if (!notification) {\n return;\n }\n\n await handler?.(notification);\n } catch (error) {\n // Do Nothing, cannot parse a bad notification\n log.error('Unable to send push notification:', {\n notification: payload?.data?.data,\n error,\n });\n }\n },\n );\n\n const unsubscribe = (): void => unsubscribePushNotifications();\n return unsubscribe;\n}\n\n/**\n * Service Worker Listener for when a notification is clicked\n *\n * @param handler - listen to NotificationEvent from the service worker\n * @returns unsubscribe handler\n */\nfunction listenToPushNotificationsClicked(\n handler: (e: NotificationEvent, notification: Types.INotification) => void,\n): () => void {\n const clickHandler = (event: NotificationEvent): void => {\n // Get Data\n const data: Types.INotification = event?.notification?.data;\n handler(event, data);\n };\n\n self.addEventListener('notificationclick', clickHandler);\n const unsubscribe = (): void =>\n self.removeEventListener('notificationclick', clickHandler);\n return unsubscribe;\n}\n\n/**\n * A creator function that assists creating web-specific push notification subscription:\n * 1. Creates subscriptions for receiving and clicking notifications\n * 2. Creates click events when a notification is clicked\n * 3. Publishes controller messenger events\n *\n * @param props - props for this creator function.\n * @param props.onReceivedHandler - allows the developer to handle showing a notification\n * @param props.onClickHandler - allows the developer to handle clicking the notification\n * @param props.messenger - the controller messenger to publish the `onNewNotifications` and `pushNotificationsClicked` events\n * @returns a function that can be used by the controller\n */\nexport function createSubscribeToPushNotifications(props: {\n onReceivedHandler: (\n notification: Types.INotification,\n ) => void | Promise<void>;\n onClickHandler: (\n e: NotificationEvent,\n notification: Types.INotification,\n ) => void;\n messenger: NotificationServicesPushControllerMessenger;\n}): (env: PushNotificationEnv) => Promise<() => void> {\n return async function (env: PushNotificationEnv): Promise<() => void> {\n const onBackgroundMessageSub = await listenToPushNotificationsReceived(\n env,\n async (notification): Promise<void> => {\n props.messenger.publish(\n 'NotificationServicesPushController:onNewNotifications',\n notification,\n );\n await props.onReceivedHandler(notification);\n },\n );\n const onClickSub = listenToPushNotificationsClicked(\n (event, notification): void => {\n props.messenger.publish(\n 'NotificationServicesPushController:pushNotificationClicked',\n notification,\n );\n props.onClickHandler(event, notification);\n },\n );\n\n const unsubscribe = (): void => {\n onBackgroundMessageSub?.();\n onClickSub();\n };\n\n return unsubscribe;\n };\n}\n"]}
1
+ {"version":3,"file":"push-utils.mjs","sourceRoot":"","sources":["../../../src/NotificationServicesPushController/web/push-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// We are defining that this file uses a webworker global scope.\n// eslint-disable-next-line spaced-comment\n/// <reference lib=\"webworker\" />\nimport type { FirebaseApp } from 'firebase/app';\nimport { getApp, initializeApp } from 'firebase/app';\nimport { getToken, deleteToken } from 'firebase/messaging';\nimport {\n getMessaging,\n onBackgroundMessage,\n isSupported,\n} from 'firebase/messaging/sw';\nimport type { Messaging, MessagePayload } from 'firebase/messaging/sw';\nimport log from 'loglevel';\n\nimport type { NotificationServicesPushControllerMessenger } from '../NotificationServicesPushController';\nimport type { PushAnalyticsPayload } from '../types';\nimport type { PushNotificationEnv } from '../types/firebase';\nimport { toPushAnalyticsPayload } from '../utils/to-push-analytics-payload';\n\ndeclare const self: ServiceWorkerGlobalScope;\n\n// Exported to help testing\n// eslint-disable-next-line import-x/no-mutable-exports\nexport let supportedCache: boolean | null = null;\n\nconst getPushAvailability = async (): Promise<boolean> => {\n // Race condition is acceptable here - worst case is isSupported() is called\n // multiple times during initialization, which is harmless for caching a boolean\n // eslint-disable-next-line require-atomic-updates\n supportedCache ??= await isSupported();\n return supportedCache;\n};\n\nconst createFirebaseApp = async (\n env: PushNotificationEnv,\n): Promise<FirebaseApp> => {\n try {\n return getApp();\n } catch {\n const firebaseConfig = {\n apiKey: env.apiKey,\n authDomain: env.authDomain,\n storageBucket: env.storageBucket,\n projectId: env.projectId,\n messagingSenderId: env.messagingSenderId,\n appId: env.appId,\n measurementId: env.measurementId,\n };\n return initializeApp(firebaseConfig);\n }\n};\n\nconst getFirebaseMessaging = async (\n env: PushNotificationEnv,\n): Promise<Messaging | null> => {\n const supported = await getPushAvailability();\n if (!supported) {\n return null;\n }\n\n const app = await createFirebaseApp(env);\n return getMessaging(app);\n};\n\n/**\n * Creates a registration token for Firebase Cloud Messaging.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with the registration token or null if an error occurs.\n */\nexport async function createRegToken(\n env: PushNotificationEnv,\n): Promise<string | null> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const token = await getToken(messaging, {\n serviceWorkerRegistration: self.registration,\n vapidKey: env.vapidKey,\n });\n return token;\n } catch {\n return null;\n }\n}\n\n/**\n * Deletes the Firebase Cloud Messaging registration token.\n *\n * @param env - env to configure push notifications\n * @returns A promise that resolves with true if the token was successfully deleted, false otherwise.\n */\nexport async function deleteRegToken(\n env: PushNotificationEnv,\n): Promise<boolean> {\n try {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return true;\n }\n\n await deleteToken(messaging);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Service Worker Listener for when push notifications are received.\n *\n * @param env - push notification environment\n * @param handler - handler to actually showing notification, MUST BE PROVIDED\n * @returns unsubscribe handler\n */\nasync function listenToPushNotificationsReceived(\n env: PushNotificationEnv,\n handler?: (payload: PushAnalyticsPayload) => void | Promise<void>,\n): Promise<(() => void) | null> {\n const messaging = await getFirebaseMessaging(env);\n if (!messaging) {\n return null;\n }\n\n const unsubscribePushNotifications = onBackgroundMessage(\n messaging,\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async (payload: MessagePayload): Promise<void> => {\n try {\n const analyticsPayload = toPushAnalyticsPayload(payload?.data);\n\n if (!analyticsPayload) {\n return;\n }\n\n await handler?.(analyticsPayload);\n } catch (error) {\n // Do Nothing, cannot handle a bad notification\n log.error('Unable to handle push notification:', {\n notification: payload?.data,\n error,\n });\n }\n },\n );\n\n const unsubscribe = (): void => unsubscribePushNotifications();\n return unsubscribe;\n}\n\n/**\n * Service Worker Listener for when a notification is clicked\n *\n * @param handler - listen to NotificationEvent from the service worker\n * @returns unsubscribe handler\n */\nfunction listenToPushNotificationsClicked(\n handler: (e: NotificationEvent, payload: PushAnalyticsPayload) => void,\n): () => void {\n const clickHandler = (event: NotificationEvent): void => {\n // Get Data\n const data: PushAnalyticsPayload = event?.notification?.data;\n handler(event, data);\n };\n\n self.addEventListener('notificationclick', clickHandler);\n const unsubscribe = (): void =>\n self.removeEventListener('notificationclick', clickHandler);\n return unsubscribe;\n}\n\n/**\n * A creator function that assists creating web-specific push notification subscription:\n * 1. Creates subscriptions for receiving and clicking notifications\n * 2. Creates click events when a notification is clicked\n * 3. Publishes controller messenger events\n *\n * @param props - props for this creator function.\n * @param props.onReceivedHandler - allows the developer to handle showing a notification\n * @param props.onClickHandler - allows the developer to handle clicking the notification\n * @param props.messenger - the controller messenger to publish the `onNewNotifications` and `pushNotificationsClicked` events\n * @returns a function that can be used by the controller\n */\nexport function createSubscribeToPushNotifications(props: {\n onReceivedHandler: (payload: PushAnalyticsPayload) => void | Promise<void>;\n onClickHandler: (e: NotificationEvent, payload: PushAnalyticsPayload) => void;\n messenger: NotificationServicesPushControllerMessenger;\n}): (env: PushNotificationEnv) => Promise<() => void> {\n return async function (env: PushNotificationEnv): Promise<() => void> {\n const onBackgroundMessageSub = await listenToPushNotificationsReceived(\n env,\n async (analyticsPayload): Promise<void> => {\n props.messenger.publish(\n 'NotificationServicesPushController:onNewNotifications',\n analyticsPayload,\n );\n await props.onReceivedHandler(analyticsPayload);\n },\n );\n const onClickSub = listenToPushNotificationsClicked(\n (event, analyticsPayload): void => {\n props.messenger.publish(\n 'NotificationServicesPushController:pushNotificationClicked',\n analyticsPayload,\n );\n props.onClickHandler(event, analyticsPayload);\n },\n );\n\n const unsubscribe = (): void => {\n onBackgroundMessageSub?.();\n onClickSub();\n };\n\n return unsubscribe;\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/notification-services-controller",
3
- "version": "24.1.2-preview-e4acb70",
3
+ "version": "24.1.2-preview-5620ede0b",
4
4
  "description": "Manages New MetaMask decentralized Notification system",
5
5
  "keywords": [
6
6
  "Ethereum",