= ({
Push ID
- {maskValue(pushSubscriptionId ?? '—')}
+ {pushSubscriptionId ?? '—'}
diff --git a/examples/demo/src/components/sections/UserSection.tsx b/examples/demo/src/components/sections/UserSection.tsx
index ddaee1f..56ea78a 100644
--- a/examples/demo/src/components/sections/UserSection.tsx
+++ b/examples/demo/src/components/sections/UserSection.tsx
@@ -25,7 +25,7 @@ const UserSection: FC = ({ externalUserId, onLogin, onLogout }
External ID
- {externalUserId ?? '–'}
+ {externalUserId ?? '—'}
diff --git a/examples/demo/src/hooks/useOneSignal.ts b/examples/demo/src/hooks/useOneSignal.ts
index ad3e5bd..953af0d 100644
--- a/examples/demo/src/hooks/useOneSignal.ts
+++ b/examples/demo/src/hooks/useOneSignal.ts
@@ -18,6 +18,18 @@ const RESOLVED_APP_ID = APP_ID?.trim() || DEFAULT_APP_ID;
const apiService = OneSignalApiService.getInstance();
const preferences = PreferencesService.getInstance();
+// uncomment to debug ios logs in safari web inspector
+// const buf: string[] = [];
+// (['log', 'warn', 'error'] as const).forEach((level) => {
+// const orig = console[level].bind(console);
+// console[level] = (...args) => {
+// buf.push(`[${level}] ${args.map(String).join(' ')}`);
+// localStorage.setItem('__logs', JSON.stringify(buf.slice(-500)));
+// orig(...args);
+// };
+// });
+// then later call JSON.parse(localStorage.getItem('__logs')).forEach(l => console.log(l))
+
// One-shot SDK initialization at module-eval time. Capacitor's bridge queues
// calls until native is ready, so no `deviceready` gating is required. The
// downstream `OneSignal.initialize` short-circuits on the native side, but
@@ -47,8 +59,6 @@ function initOneSignal(): void {
if (storedExternalUserId) {
void OneSignal.login(storedExternalUserId);
}
-
- console.log(`OneSignal initialized with app ID: ${RESOLVED_APP_ID}`);
}
initOneSignal();
@@ -79,6 +89,7 @@ export type UseOneSignalReturn = {
consentRequired: boolean;
privacyConsentGiven: boolean;
externalUserId: string | undefined;
+ oneSignalId: string | undefined;
pushSubscriptionId: string | undefined;
isPushEnabled: boolean;
hasNotificationPermission: boolean;
@@ -139,6 +150,7 @@ export function useOneSignal(): UseOneSignalReturn {
preferences.getConsentGiven(),
);
const [externalUserId, setExternalUserId] = useState(undefined);
+ const [oneSignalId, setOneSignalId] = useState(undefined);
const [pushSubscriptionId, setPushSubscriptionId] = useState(undefined);
const [isPushEnabled, setIsPushEnabled] = useState(false);
const [hasNotificationPermission, setHasNotificationPermission] = useState(false);
@@ -196,22 +208,6 @@ export function useOneSignal(): UseOneSignalReturn {
const handleNotificationClick = (e: NotificationClickEvent) => {
console.log(`Notification click: ${e.notification.title ?? ''}`);
- // Persist to localStorage so cold-start clicks are still inspectable
- // after the Safari Web Inspector reattaches to the WKWebView.
- try {
- const existing = JSON.parse(localStorage.getItem('lastNotificationClicks') ?? '[]');
- existing.push({
- notificationId: e.notification.notificationId,
- title: e.notification.title ?? null,
- body: e.notification.body ?? null,
- actionId: e.result.actionId ?? null,
- url: e.result.url ?? null,
- receivedAt: new Date().toISOString(),
- });
- localStorage.setItem('lastNotificationClicks', JSON.stringify(existing.slice(-20)));
- } catch (err) {
- console.warn('Failed to persist notification click to localStorage', err);
- }
};
const handleForegroundWillDisplay = (e: NotificationWillDisplayEvent) => {
@@ -245,6 +241,8 @@ export function useOneSignal(): UseOneSignalReturn {
`User changed: onesignalId=${nextOnesignalId ?? 'null'}, externalId=${event.current.externalId ?? 'null'}`,
);
+ setOneSignalId(nextOnesignalId ?? undefined);
+
if (nextOnesignalId === null) return;
void fetchUserDataFromApi();
};
@@ -261,11 +259,6 @@ export function useOneSignal(): UseOneSignalReturn {
OneSignal.User.addEventListener('change', userChangeHandler);
const load = async () => {
- // Uncomment if you want so you have time to see logs while trying to open
- // safari web inspector. Not an issue for chrome web inspector.
- // await new Promise((resolve) => setTimeout(resolve, 10_000));
- // if (cancelled) return;
-
const [externalId, pushId, pushOptedIn, hasPerm, initialOnesignalId] = await Promise.all([
OneSignal.User.getExternalId(),
OneSignal.User.pushSubscription.getIdAsync(),
@@ -276,6 +269,7 @@ export function useOneSignal(): UseOneSignalReturn {
if (cancelled) return;
setExternalUserId(externalId ?? preferences.getExternalUserId() ?? undefined);
+ setOneSignalId(initialOnesignalId ?? undefined);
setPushSubscriptionId(pushId ?? undefined);
setIsPushEnabled(pushOptedIn);
setHasNotificationPermission(hasPerm);
@@ -543,6 +537,7 @@ export function useOneSignal(): UseOneSignalReturn {
consentRequired,
privacyConsentGiven,
externalUserId,
+ oneSignalId,
pushSubscriptionId,
isPushEnabled,
hasNotificationPermission,
diff --git a/examples/demo/src/pages/HomeScreen.css b/examples/demo/src/pages/HomeScreen.css
index 11e0f47..01bd9ce 100644
--- a/examples/demo/src/pages/HomeScreen.css
+++ b/examples/demo/src/pages/HomeScreen.css
@@ -41,7 +41,7 @@
.brand-header {
background: var(--os-primary);
- border-bottom: 1px solid #fff;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
color: #fff;
min-height: var(--demo-header-height);
padding-top: var(--ion-safe-area-top);
@@ -150,6 +150,8 @@
.kv-card .kv-row .id-value {
font-size: var(--font-size-body-small);
font-family: monospace;
+ user-select: all;
+ -webkit-user-select: all;
}
.divider {
diff --git a/examples/demo/src/services/OneSignalApiService.ts b/examples/demo/src/services/OneSignalApiService.ts
index 3baa348..0b515e6 100644
--- a/examples/demo/src/services/OneSignalApiService.ts
+++ b/examples/demo/src/services/OneSignalApiService.ts
@@ -74,34 +74,56 @@ class OneSignalApiService {
subscriptionId: string,
extra: Record,
): Promise {
- try {
- const body = {
- app_id: this.appId,
- include_subscription_ids: [subscriptionId],
- headings,
- contents,
- ...extra,
- };
-
- const response = await CapacitorHttp.post({
- url: 'https://onesignal.com/api/v1/notifications',
- headers: {
- Accept: 'application/vnd.onesignal.v1+json',
- 'Content-Type': 'application/json',
- },
- data: body,
- });
-
- if (response.status < 200 || response.status >= 300) {
- console.error(`Send notification failed: ${JSON.stringify(response.data)}`);
+ const body = {
+ app_id: this.appId,
+ include_subscription_ids: [subscriptionId],
+ headings,
+ contents,
+ ...extra,
+ };
+
+ const maxAttempts = 5;
+ const backoffMs = (n: number) => 2_000 * 2 ** (n - 1);
+
+ // Retry on `invalid_player_ids` to absorb the brief race where the
+ // subscription has been created locally but is not yet visible to the
+ // /notifications endpoint.
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
+ try {
+ const response = await CapacitorHttp.post({
+ url: 'https://onesignal.com/api/v1/notifications',
+ headers: {
+ Accept: 'application/vnd.onesignal.v1+json',
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ });
+
+ if (response.status < 200 || response.status >= 300) {
+ console.error(`Send notification failed: ${JSON.stringify(response.data)}`);
+ return false;
+ }
+
+ const invalidIds = response.data?.errors?.invalid_player_ids;
+ if (Array.isArray(invalidIds) && invalidIds.length > 0) {
+ if (attempt < maxAttempts) {
+ await new Promise((resolve) => setTimeout(resolve, backoffMs(attempt)));
+ continue;
+ }
+ console.error(
+ `Send notification failed: invalid_player_ids ${JSON.stringify(invalidIds)}`,
+ );
+ return false;
+ }
+
+ return true;
+ } catch (err) {
+ console.error(`Send notification error: ${String(err)}`);
return false;
}
-
- return true;
- } catch (err) {
- console.error(`Send notification error: ${String(err)}`);
- return false;
}
+
+ return false;
}
async updateLiveActivity(
diff --git a/examples/demo/src/utils/maskValue.ts b/examples/demo/src/utils/maskValue.ts
deleted file mode 100644
index 12d1582..0000000
--- a/examples/demo/src/utils/maskValue.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-// Mirrors the trim/strict-equals check used elsewhere so a stray newline
-// or whitespace in `.env` doesn't accidentally enable masking.
-const E2E_MODE = (import.meta.env.VITE_E2E_MODE ?? '').trim() === 'true';
-const MASK_CHAR = '•';
-
-export function maskValue(value: string): string {
- if (E2E_MODE) {
- return MASK_CHAR.repeat(value.length);
- }
- return value;
-}
diff --git a/examples/demo_cap7/src/app/app.component.ts b/examples/demo_cap7/src/app/app.component.ts
index e6ce849..d32ae82 100644
--- a/examples/demo_cap7/src/app/app.component.ts
+++ b/examples/demo_cap7/src/app/app.component.ts
@@ -90,26 +90,42 @@ export class AppComponent {
return;
}
- const response = await CapacitorHttp.post({
- url: 'https://onesignal.com/api/v1/notifications',
- headers: {
- Accept: 'application/vnd.onesignal.v1+json',
- 'Content-Type': 'application/json',
- },
- data: {
- app_id: ONESIGNAL_APP_ID,
- include_subscription_ids: [subscriptionId],
- headings: { en: 'Simple Notification' },
- contents: { en: 'This is a simple push notification' },
- },
- });
-
- if (response.status < 200 || response.status >= 300) {
- this.log(`Send failed (${response.status}): ${JSON.stringify(response.data)}`);
+ const body = {
+ app_id: ONESIGNAL_APP_ID,
+ include_subscription_ids: [subscriptionId],
+ headings: { en: 'Simple Notification' },
+ contents: { en: 'This is a simple push notification' },
+ };
+ const maxAttempts = 3;
+
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
+ const response = await CapacitorHttp.post({
+ url: 'https://onesignal.com/api/v1/notifications',
+ headers: {
+ Accept: 'application/vnd.onesignal.v1+json',
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ });
+
+ if (response.status < 200 || response.status >= 300) {
+ this.log(`Send failed (${response.status}): ${JSON.stringify(response.data)}`);
+ return;
+ }
+
+ const invalidIds = response.data?.errors?.invalid_player_ids;
+ if (Array.isArray(invalidIds) && invalidIds.length > 0) {
+ if (attempt < maxAttempts) {
+ await new Promise((resolve) => setTimeout(resolve, 3_000 * attempt));
+ continue;
+ }
+ this.log(`Send failed: invalid_player_ids ${JSON.stringify(invalidIds)}`);
+ return;
+ }
+
+ this.log(`Sent. response: ${JSON.stringify(response.data)}`);
return;
}
-
- this.log(`Sent. response: ${JSON.stringify(response.data)}`);
} catch (err) {
this.log(`sendTestNotification error: ${String(err)}`);
} finally {
diff --git a/examples/demo_pods/.env.example b/examples/demo_pods/.env.example
index a9c529a..b15cf8d 100644
--- a/examples/demo_pods/.env.example
+++ b/examples/demo_pods/.env.example
@@ -1,4 +1,3 @@
VITE_ONESIGNAL_APP_ID=your_onesignal_app_id
VITE_ONESIGNAL_API_KEY=your_rest_api_key
VITE_ONESIGNAL_ANDROID_CHANNEL_ID=
-VITE_E2E_MODE=false
diff --git a/examples/demo_pods/android/app/src/main/res/values/styles.xml b/examples/demo_pods/android/app/src/main/res/values/styles.xml
index be874e5..59cf157 100644
--- a/examples/demo_pods/android/app/src/main/res/values/styles.xml
+++ b/examples/demo_pods/android/app/src/main/res/values/styles.xml
@@ -17,6 +17,8 @@
\ No newline at end of file
diff --git a/examples/demo_pods/capacitor.config.ts b/examples/demo_pods/capacitor.config.ts
index 07dfa5f..3b26df2 100644
--- a/examples/demo_pods/capacitor.config.ts
+++ b/examples/demo_pods/capacitor.config.ts
@@ -13,6 +13,11 @@ const config: CapacitorConfig = {
// the WebView. Test-only convenience for the demo app.
webContentsDebuggingEnabled: true,
},
+ plugins: {
+ SplashScreen: {
+ backgroundColor: '#ffffff',
+ },
+ },
};
export default config;
diff --git a/examples/demo_pods/src/components/sections/AppSection.tsx b/examples/demo_pods/src/components/sections/AppSection.tsx
index cb04999..72f2fe5 100644
--- a/examples/demo_pods/src/components/sections/AppSection.tsx
+++ b/examples/demo_pods/src/components/sections/AppSection.tsx
@@ -1,7 +1,6 @@
import { IonToggle } from '@ionic/react';
import type { FC } from 'react';
-import { maskValue } from '../../utils/maskValue';
import SectionCard from '../SectionCard';
interface AppSectionProps {
@@ -24,7 +23,7 @@ const AppSection: FC = ({
App ID
- {maskValue(appId)}
+ {appId}
diff --git a/examples/demo_pods/src/components/sections/PushSection.tsx b/examples/demo_pods/src/components/sections/PushSection.tsx
index 540d1c5..c43545d 100644
--- a/examples/demo_pods/src/components/sections/PushSection.tsx
+++ b/examples/demo_pods/src/components/sections/PushSection.tsx
@@ -1,7 +1,6 @@
import { IonToggle } from '@ionic/react';
import type { FC } from 'react';
-import { maskValue } from '../../utils/maskValue';
import ActionButton from '../ActionButton';
import SectionCard from '../SectionCard';
@@ -27,7 +26,7 @@ const PushSection: FC = ({
Push ID
- {maskValue(pushSubscriptionId ?? '—')}
+ {pushSubscriptionId ?? '—'}
diff --git a/examples/demo_pods/src/components/sections/UserSection.tsx b/examples/demo_pods/src/components/sections/UserSection.tsx
index ddaee1f..56ea78a 100644
--- a/examples/demo_pods/src/components/sections/UserSection.tsx
+++ b/examples/demo_pods/src/components/sections/UserSection.tsx
@@ -25,7 +25,7 @@ const UserSection: FC = ({ externalUserId, onLogin, onLogout }
External ID
- {externalUserId ?? '–'}
+ {externalUserId ?? '—'}
diff --git a/examples/demo_pods/src/hooks/useOneSignal.ts b/examples/demo_pods/src/hooks/useOneSignal.ts
index f06e897..953af0d 100644
--- a/examples/demo_pods/src/hooks/useOneSignal.ts
+++ b/examples/demo_pods/src/hooks/useOneSignal.ts
@@ -18,6 +18,18 @@ const RESOLVED_APP_ID = APP_ID?.trim() || DEFAULT_APP_ID;
const apiService = OneSignalApiService.getInstance();
const preferences = PreferencesService.getInstance();
+// uncomment to debug ios logs in safari web inspector
+// const buf: string[] = [];
+// (['log', 'warn', 'error'] as const).forEach((level) => {
+// const orig = console[level].bind(console);
+// console[level] = (...args) => {
+// buf.push(`[${level}] ${args.map(String).join(' ')}`);
+// localStorage.setItem('__logs', JSON.stringify(buf.slice(-500)));
+// orig(...args);
+// };
+// });
+// then later call JSON.parse(localStorage.getItem('__logs')).forEach(l => console.log(l))
+
// One-shot SDK initialization at module-eval time. Capacitor's bridge queues
// calls until native is ready, so no `deviceready` gating is required. The
// downstream `OneSignal.initialize` short-circuits on the native side, but
@@ -47,8 +59,6 @@ function initOneSignal(): void {
if (storedExternalUserId) {
void OneSignal.login(storedExternalUserId);
}
-
- console.log(`OneSignal initialized with app ID: ${RESOLVED_APP_ID}`);
}
initOneSignal();
@@ -79,6 +89,7 @@ export type UseOneSignalReturn = {
consentRequired: boolean;
privacyConsentGiven: boolean;
externalUserId: string | undefined;
+ oneSignalId: string | undefined;
pushSubscriptionId: string | undefined;
isPushEnabled: boolean;
hasNotificationPermission: boolean;
@@ -139,6 +150,7 @@ export function useOneSignal(): UseOneSignalReturn {
preferences.getConsentGiven(),
);
const [externalUserId, setExternalUserId] = useState(undefined);
+ const [oneSignalId, setOneSignalId] = useState(undefined);
const [pushSubscriptionId, setPushSubscriptionId] = useState(undefined);
const [isPushEnabled, setIsPushEnabled] = useState(false);
const [hasNotificationPermission, setHasNotificationPermission] = useState(false);
@@ -196,27 +208,16 @@ export function useOneSignal(): UseOneSignalReturn {
const handleNotificationClick = (e: NotificationClickEvent) => {
console.log(`Notification click: ${e.notification.title ?? ''}`);
- // Persist to localStorage so cold-start clicks are still inspectable
- // after the Safari Web Inspector reattaches to the WKWebView.
- try {
- const existing = JSON.parse(localStorage.getItem('lastNotificationClicks') ?? '[]');
- existing.push({
- notificationId: e.notification.notificationId,
- title: e.notification.title ?? null,
- body: e.notification.body ?? null,
- actionId: e.result.actionId ?? null,
- url: e.result.url ?? null,
- receivedAt: new Date().toISOString(),
- });
- localStorage.setItem('lastNotificationClicks', JSON.stringify(existing.slice(-20)));
- } catch (err) {
- console.warn('Failed to persist notification click to localStorage', err);
- }
};
const handleForegroundWillDisplay = (e: NotificationWillDisplayEvent) => {
console.log(`Notification foregroundWillDisplay: ${e.getNotification().title ?? ''}`);
- e.getNotification().display();
+
+ // uncomment to test preventing the default display behavior
+ // e.preventDefault();
+
+ // can call this after preventDefault to force display of notification
+ // e.getNotification().display();
};
const pushSubHandler = (event: PushSubscriptionChangedState) => {
@@ -230,6 +231,7 @@ export function useOneSignal(): UseOneSignalReturn {
};
const permissionHandler = (granted: boolean) => {
+ console.log(`Permission changed: ${granted}`);
setHasNotificationPermission(granted);
};
@@ -239,6 +241,8 @@ export function useOneSignal(): UseOneSignalReturn {
`User changed: onesignalId=${nextOnesignalId ?? 'null'}, externalId=${event.current.externalId ?? 'null'}`,
);
+ setOneSignalId(nextOnesignalId ?? undefined);
+
if (nextOnesignalId === null) return;
void fetchUserDataFromApi();
};
@@ -255,11 +259,6 @@ export function useOneSignal(): UseOneSignalReturn {
OneSignal.User.addEventListener('change', userChangeHandler);
const load = async () => {
- // Uncomment if you want so you have time to see logs while trying to open
- // safari web inspector. Not an issue for chrome web inspector.
- // await new Promise((resolve) => setTimeout(resolve, 10_000));
- // if (cancelled) return;
-
const [externalId, pushId, pushOptedIn, hasPerm, initialOnesignalId] = await Promise.all([
OneSignal.User.getExternalId(),
OneSignal.User.pushSubscription.getIdAsync(),
@@ -270,6 +269,7 @@ export function useOneSignal(): UseOneSignalReturn {
if (cancelled) return;
setExternalUserId(externalId ?? preferences.getExternalUserId() ?? undefined);
+ setOneSignalId(initialOnesignalId ?? undefined);
setPushSubscriptionId(pushId ?? undefined);
setIsPushEnabled(pushOptedIn);
setHasNotificationPermission(hasPerm);
@@ -537,6 +537,7 @@ export function useOneSignal(): UseOneSignalReturn {
consentRequired,
privacyConsentGiven,
externalUserId,
+ oneSignalId,
pushSubscriptionId,
isPushEnabled,
hasNotificationPermission,
diff --git a/examples/demo_pods/src/pages/HomeScreen.css b/examples/demo_pods/src/pages/HomeScreen.css
index 11e0f47..27485e5 100644
--- a/examples/demo_pods/src/pages/HomeScreen.css
+++ b/examples/demo_pods/src/pages/HomeScreen.css
@@ -41,7 +41,7 @@
.brand-header {
background: var(--os-primary);
- border-bottom: 1px solid #fff;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
color: #fff;
min-height: var(--demo-header-height);
padding-top: var(--ion-safe-area-top);
diff --git a/examples/demo_pods/src/services/OneSignalApiService.ts b/examples/demo_pods/src/services/OneSignalApiService.ts
index 3baa348..0b515e6 100644
--- a/examples/demo_pods/src/services/OneSignalApiService.ts
+++ b/examples/demo_pods/src/services/OneSignalApiService.ts
@@ -74,34 +74,56 @@ class OneSignalApiService {
subscriptionId: string,
extra: Record,
): Promise {
- try {
- const body = {
- app_id: this.appId,
- include_subscription_ids: [subscriptionId],
- headings,
- contents,
- ...extra,
- };
-
- const response = await CapacitorHttp.post({
- url: 'https://onesignal.com/api/v1/notifications',
- headers: {
- Accept: 'application/vnd.onesignal.v1+json',
- 'Content-Type': 'application/json',
- },
- data: body,
- });
-
- if (response.status < 200 || response.status >= 300) {
- console.error(`Send notification failed: ${JSON.stringify(response.data)}`);
+ const body = {
+ app_id: this.appId,
+ include_subscription_ids: [subscriptionId],
+ headings,
+ contents,
+ ...extra,
+ };
+
+ const maxAttempts = 5;
+ const backoffMs = (n: number) => 2_000 * 2 ** (n - 1);
+
+ // Retry on `invalid_player_ids` to absorb the brief race where the
+ // subscription has been created locally but is not yet visible to the
+ // /notifications endpoint.
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
+ try {
+ const response = await CapacitorHttp.post({
+ url: 'https://onesignal.com/api/v1/notifications',
+ headers: {
+ Accept: 'application/vnd.onesignal.v1+json',
+ 'Content-Type': 'application/json',
+ },
+ data: body,
+ });
+
+ if (response.status < 200 || response.status >= 300) {
+ console.error(`Send notification failed: ${JSON.stringify(response.data)}`);
+ return false;
+ }
+
+ const invalidIds = response.data?.errors?.invalid_player_ids;
+ if (Array.isArray(invalidIds) && invalidIds.length > 0) {
+ if (attempt < maxAttempts) {
+ await new Promise((resolve) => setTimeout(resolve, backoffMs(attempt)));
+ continue;
+ }
+ console.error(
+ `Send notification failed: invalid_player_ids ${JSON.stringify(invalidIds)}`,
+ );
+ return false;
+ }
+
+ return true;
+ } catch (err) {
+ console.error(`Send notification error: ${String(err)}`);
return false;
}
-
- return true;
- } catch (err) {
- console.error(`Send notification error: ${String(err)}`);
- return false;
}
+
+ return false;
}
async updateLiveActivity(
diff --git a/examples/demo_pods/src/utils/maskValue.ts b/examples/demo_pods/src/utils/maskValue.ts
deleted file mode 100644
index 12d1582..0000000
--- a/examples/demo_pods/src/utils/maskValue.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-// Mirrors the trim/strict-equals check used elsewhere so a stray newline
-// or whitespace in `.env` doesn't accidentally enable masking.
-const E2E_MODE = (import.meta.env.VITE_E2E_MODE ?? '').trim() === 'true';
-const MASK_CHAR = '•';
-
-export function maskValue(value: string): string {
- if (E2E_MODE) {
- return MASK_CHAR.repeat(value.length);
- }
- return value;
-}
diff --git a/ios/Sources/OneSignalCapacitorPlugin/OneSignalCapacitorPlugin.swift b/ios/Sources/OneSignalCapacitorPlugin/OneSignalCapacitorPlugin.swift
index d11e855..c4f21ea 100644
--- a/ios/Sources/OneSignalCapacitorPlugin/OneSignalCapacitorPlugin.swift
+++ b/ios/Sources/OneSignalCapacitorPlugin/OneSignalCapacitorPlugin.swift
@@ -110,7 +110,7 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin {
initialized = true
OneSignalWrapper.sdkType = "capacitor"
- OneSignalWrapper.sdkVersion = "010004"
+ OneSignalWrapper.sdkVersion = "010005"
// OSCapacitorLaunchOptions's +load captures the dictionary from
// UIApplicationDidFinishLaunchingNotification at process start (before
// main()), so cold-start notification taps that arrive via launchOptions
diff --git a/package.json b/package.json
index cc663bf..992fb7b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@onesignal/capacitor-plugin",
- "version": "1.0.4",
+ "version": "1.0.5",
"description": "OneSignal is a high volume Push Notification service for mobile apps. This is the pure Capacitor plugin for OneSignal, providing push notifications, in-app messaging, and more.",
"keywords": [
"apns",
@@ -60,7 +60,6 @@
"@capacitor/docgen": "^0.2.2",
"@types/bun": "latest",
"@vitest/coverage-v8": "^4.1.2",
- "happy-dom": "^20.9.0",
"typescript": "^5.9.3",
"vite-plus": "0.1.20"
},
diff --git a/vite.config.ts b/vite.config.ts
index 5a580bf..593cb3f 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -32,7 +32,7 @@ export default defineConfig({
},
test: {
clearMocks: true,
- environment: 'happy-dom',
+ environment: 'node',
include: ['**/*.test.ts', '**/*.test.tsx'],
coverage: {
exclude: ['mocks/**', 'src/helpers.ts'],