1import Constants from 'expo-constants';
2import { CodedError, Platform, SyntheticPlatformEmitter } from 'expo-modules-core';
3export default async function getDevicePushTokenAsync() {
4    const data = await _subscribeDeviceToPushNotificationsAsync();
5    SyntheticPlatformEmitter.emit('onDevicePushToken', { devicePushToken: data });
6    return { type: Platform.OS, data };
7}
8function guardPermission() {
9    if (!('Notification' in window)) {
10        throw new CodedError('ERR_UNAVAILABLE', 'The Web Notifications API is not available on this device.');
11    }
12    if (!navigator.serviceWorker) {
13        throw new CodedError('ERR_UNAVAILABLE', 'Notifications cannot be used because the service worker API is not supported on this device. This might also happen because your web page does not support HTTPS.');
14    }
15    if (Notification.permission !== 'granted') {
16        throw new CodedError('ERR_NOTIFICATIONS_PERMISSION_DENIED', `Cannot use web notifications without permissions granted. Request permissions with "expo-permissions".`);
17    }
18}
19async function _subscribeDeviceToPushNotificationsAsync() {
20    // @ts-expect-error: TODO: not on the schema
21    const vapidPublicKey = Constants.expoConfig?.notification?.vapidPublicKey;
22    if (!vapidPublicKey) {
23        throw new CodedError('ERR_NOTIFICATIONS_PUSH_WEB_MISSING_CONFIG', 'You must provide `notification.vapidPublicKey` in `app.json` to use push notifications on web. Learn more: https://docs.expo.dev/versions/latest/guides/using-vapid/.');
24    }
25    // @ts-expect-error: TODO: not on the schema
26    const serviceWorkerPath = Constants.expoConfig?.notification?.serviceWorkerPath;
27    if (!serviceWorkerPath) {
28        throw new CodedError('ERR_NOTIFICATIONS_PUSH_MISSING_CONFIGURATION', 'You must specify `notification.serviceWorkerPath` in `app.json` to use push notifications on the web. Please provide the path to the service worker that will handle notifications.');
29    }
30    guardPermission();
31    let registration = null;
32    try {
33        registration = await navigator.serviceWorker.register(serviceWorkerPath);
34    }
35    catch (error) {
36        throw new CodedError('ERR_NOTIFICATIONS_PUSH_REGISTRATION_FAILED', `Could not register this device for push notifications because the service worker (${serviceWorkerPath}) could not be registered: ${error}`);
37    }
38    await navigator.serviceWorker.ready;
39    if (!registration.active) {
40        throw new CodedError('ERR_NOTIFICATIONS_PUSH_REGISTRATION_FAILED', 'Could not register this device for push notifications because the service worker is not active.');
41    }
42    const subscribeOptions = {
43        userVisibleOnly: true,
44        applicationServerKey: _urlBase64ToUint8Array(vapidPublicKey),
45    };
46    let pushSubscription = null;
47    try {
48        pushSubscription = await registration.pushManager.subscribe(subscribeOptions);
49    }
50    catch (error) {
51        throw new CodedError('ERR_NOTIFICATIONS_PUSH_REGISTRATION_FAILED', 'The device was unable to register for remote notifications with the browser endpoint. (' +
52            error +
53            ')');
54    }
55    const pushSubscriptionJson = pushSubscription.toJSON();
56    const subscriptionObject = {
57        endpoint: pushSubscriptionJson.endpoint,
58        keys: {
59            p256dh: pushSubscriptionJson.keys.p256dh,
60            auth: pushSubscriptionJson.keys.auth,
61        },
62    };
63    // Store notification icon string in service worker.
64    // This message is received by `/expo-service-worker.js`.
65    // We wrap it with `fromExpoWebClient` to make sure other message
66    // will not override content such as `notificationIcon`.
67    // https://stackoverflow.com/a/35729334/2603230
68    const notificationIcon = (Constants.expoConfig?.notification ?? {}).icon;
69    await registration.active.postMessage(JSON.stringify({ fromExpoWebClient: { notificationIcon } }));
70    return subscriptionObject;
71}
72// https://github.com/web-push-libs/web-push#using-vapid-key-for-applicationserverkey
73function _urlBase64ToUint8Array(base64String) {
74    const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
75    const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
76    const rawData = window.atob(base64);
77    const outputArray = new Uint8Array(rawData.length);
78    for (let i = 0; i < rawData.length; ++i) {
79        outputArray[i] = rawData.charCodeAt(i);
80    }
81    return outputArray;
82}
83//# sourceMappingURL=getDevicePushTokenAsync.web.js.map