Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,077 changes: 951 additions & 1,126 deletions outputs/onesignal-ngx/bundles/onesignal-ngx.umd.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion outputs/onesignal-ngx/bundles/onesignal-ngx.umd.js.map

Large diffs are not rendered by default.

19 changes: 17 additions & 2 deletions outputs/onesignal-ngx/esm2015/lib/onesignal-ngx.service.js

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion outputs/onesignal-ngx/fesm2015/onesignal-ngx.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion outputs/onesignal-ngx/fesm2015/onesignal-ngx.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion outputs/onesignal-ngx/onesignal-ngx.metadata.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"__symbolic":"module","version":4,"metadata":{"AutoPromptOptions":{"__symbolic":"interface"},"IOneSignalAutoPromptOptions":{"__symbolic":"interface"},"IOneSignalCategories":{"__symbolic":"interface"},"IOneSignalTagCategory":{"__symbolic":"interface"},"PushSubscriptionNamespaceProperties":{"__symbolic":"interface"},"SubscriptionChangeEvent":{"__symbolic":"interface"},"NotificationEventName":{"__symbolic":"interface"},"SlidedownEventName":{"__symbolic":"interface"},"OneSignalDeferredLoadedCallback":{"__symbolic":"interface"},"IOSNotification":{"__symbolic":"interface"},"IOSNotificationActionButton":{"__symbolic":"interface"},"IDisplayableOSNotification":{"__symbolic":"interface"},"NotificationClickResult":{"__symbolic":"interface"},"NotificationEventTypeMap":{"__symbolic":"interface"},"NotificationForegroundWillDisplayEvent":{"__symbolic":"interface"},"NotificationDismissEvent":{"__symbolic":"interface"},"NotificationClickEvent":{"__symbolic":"interface"},"UserChangeEvent":{"__symbolic":"interface"},"UserNamespaceProperties":{"__symbolic":"interface"},"IInitObject":{"__symbolic":"interface"},"IOneSignalOneSignal":{"__symbolic":"interface"},"IOneSignalNotifications":{"__symbolic":"interface"},"IOneSignalSlidedown":{"__symbolic":"interface"},"IOneSignalDebug":{"__symbolic":"interface"},"IOneSignalSession":{"__symbolic":"interface"},"IOneSignalUser":{"__symbolic":"interface"},"IOneSignalPushSubscription":{"__symbolic":"interface"},"OneSignal":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":956,"character":1},"arguments":[{"providedIn":"root"}]}],"members":{"__ctor__":[{"__symbolic":"constructor"}],"init":[{"__symbolic":"method"}]},"statics":{"ɵprov":{}}},"OnesignalNgxComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":2,"character":1},"arguments":[{"selector":"onesignal-onesignal-ngx","template":"\n <p>\n onesignal-ngx works!\n </p>\n ","styles":[]}]}],"members":{"__ctor__":[{"__symbolic":"constructor"}],"ngOnInit":[{"__symbolic":"method"}]}},"OnesignalNgxModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule","line":5,"character":1},"arguments":[{"declarations":[{"__symbolic":"reference","name":"OnesignalNgxComponent"}],"imports":[],"exports":[{"__symbolic":"reference","name":"OnesignalNgxComponent"}]}]}],"members":{}}},"origins":{"AutoPromptOptions":"./lib/onesignal-ngx.service","IOneSignalAutoPromptOptions":"./lib/onesignal-ngx.service","IOneSignalCategories":"./lib/onesignal-ngx.service","IOneSignalTagCategory":"./lib/onesignal-ngx.service","PushSubscriptionNamespaceProperties":"./lib/onesignal-ngx.service","SubscriptionChangeEvent":"./lib/onesignal-ngx.service","NotificationEventName":"./lib/onesignal-ngx.service","SlidedownEventName":"./lib/onesignal-ngx.service","OneSignalDeferredLoadedCallback":"./lib/onesignal-ngx.service","IOSNotification":"./lib/onesignal-ngx.service","IOSNotificationActionButton":"./lib/onesignal-ngx.service","IDisplayableOSNotification":"./lib/onesignal-ngx.service","NotificationClickResult":"./lib/onesignal-ngx.service","NotificationEventTypeMap":"./lib/onesignal-ngx.service","NotificationForegroundWillDisplayEvent":"./lib/onesignal-ngx.service","NotificationDismissEvent":"./lib/onesignal-ngx.service","NotificationClickEvent":"./lib/onesignal-ngx.service","UserChangeEvent":"./lib/onesignal-ngx.service","UserNamespaceProperties":"./lib/onesignal-ngx.service","IInitObject":"./lib/onesignal-ngx.service","IOneSignalOneSignal":"./lib/onesignal-ngx.service","IOneSignalNotifications":"./lib/onesignal-ngx.service","IOneSignalSlidedown":"./lib/onesignal-ngx.service","IOneSignalDebug":"./lib/onesignal-ngx.service","IOneSignalSession":"./lib/onesignal-ngx.service","IOneSignalUser":"./lib/onesignal-ngx.service","IOneSignalPushSubscription":"./lib/onesignal-ngx.service","OneSignal":"./lib/onesignal-ngx.service","OnesignalNgxComponent":"./lib/onesignal-ngx.component","OnesignalNgxModule":"./lib/onesignal-ngx.module"},"importAs":"onesignal-ngx"}
{"__symbolic":"module","version":4,"metadata":{"AutoPromptOptions":{"__symbolic":"interface"},"IOneSignalAutoPromptOptions":{"__symbolic":"interface"},"IOneSignalCategories":{"__symbolic":"interface"},"IOneSignalTagCategory":{"__symbolic":"interface"},"PushSubscriptionNamespaceProperties":{"__symbolic":"interface"},"SubscriptionChangeEvent":{"__symbolic":"interface"},"NotificationEventName":{"__symbolic":"interface"},"SlidedownEventName":{"__symbolic":"interface"},"OneSignalDeferredLoadedCallback":{"__symbolic":"interface"},"IOSNotification":{"__symbolic":"interface"},"IOSNotificationActionButton":{"__symbolic":"interface"},"IDisplayableOSNotification":{"__symbolic":"interface"},"NotificationClickResult":{"__symbolic":"interface"},"NotificationEventTypeMap":{"__symbolic":"interface"},"NotificationForegroundWillDisplayEvent":{"__symbolic":"interface"},"NotificationDismissEvent":{"__symbolic":"interface"},"NotificationClickEvent":{"__symbolic":"interface"},"UserChangeEvent":{"__symbolic":"interface"},"UserNamespaceProperties":{"__symbolic":"interface"},"IInitObject":{"__symbolic":"interface"},"IOneSignalOneSignal":{"__symbolic":"interface"},"IOneSignalNotifications":{"__symbolic":"interface"},"IOneSignalSlidedown":{"__symbolic":"interface"},"IOneSignalDebug":{"__symbolic":"interface"},"IOneSignalSession":{"__symbolic":"interface"},"IOneSignalUser":{"__symbolic":"interface"},"IOneSignalPushSubscription":{"__symbolic":"interface"},"OneSignal":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":961,"character":1},"arguments":[{"providedIn":"root"}]}],"members":{"__ctor__":[{"__symbolic":"constructor"}],"init":[{"__symbolic":"method"}]},"statics":{"ɵprov":{}}},"OnesignalNgxComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":2,"character":1},"arguments":[{"selector":"onesignal-onesignal-ngx","template":"\n <p>\n onesignal-ngx works!\n </p>\n ","styles":[]}]}],"members":{"__ctor__":[{"__symbolic":"constructor"}],"ngOnInit":[{"__symbolic":"method"}]}},"OnesignalNgxModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule","line":5,"character":1},"arguments":[{"declarations":[{"__symbolic":"reference","name":"OnesignalNgxComponent"}],"imports":[],"exports":[{"__symbolic":"reference","name":"OnesignalNgxComponent"}]}]}],"members":{}}},"origins":{"AutoPromptOptions":"./lib/onesignal-ngx.service","IOneSignalAutoPromptOptions":"./lib/onesignal-ngx.service","IOneSignalCategories":"./lib/onesignal-ngx.service","IOneSignalTagCategory":"./lib/onesignal-ngx.service","PushSubscriptionNamespaceProperties":"./lib/onesignal-ngx.service","SubscriptionChangeEvent":"./lib/onesignal-ngx.service","NotificationEventName":"./lib/onesignal-ngx.service","SlidedownEventName":"./lib/onesignal-ngx.service","OneSignalDeferredLoadedCallback":"./lib/onesignal-ngx.service","IOSNotification":"./lib/onesignal-ngx.service","IOSNotificationActionButton":"./lib/onesignal-ngx.service","IDisplayableOSNotification":"./lib/onesignal-ngx.service","NotificationClickResult":"./lib/onesignal-ngx.service","NotificationEventTypeMap":"./lib/onesignal-ngx.service","NotificationForegroundWillDisplayEvent":"./lib/onesignal-ngx.service","NotificationDismissEvent":"./lib/onesignal-ngx.service","NotificationClickEvent":"./lib/onesignal-ngx.service","UserChangeEvent":"./lib/onesignal-ngx.service","UserNamespaceProperties":"./lib/onesignal-ngx.service","IInitObject":"./lib/onesignal-ngx.service","IOneSignalOneSignal":"./lib/onesignal-ngx.service","IOneSignalNotifications":"./lib/onesignal-ngx.service","IOneSignalSlidedown":"./lib/onesignal-ngx.service","IOneSignalDebug":"./lib/onesignal-ngx.service","IOneSignalSession":"./lib/onesignal-ngx.service","IOneSignalUser":"./lib/onesignal-ngx.service","IOneSignalPushSubscription":"./lib/onesignal-ngx.service","OneSignal":"./lib/onesignal-ngx.service","OnesignalNgxComponent":"./lib/onesignal-ngx.component","OnesignalNgxModule":"./lib/onesignal-ngx.module"},"importAs":"onesignal-ngx"}
57 changes: 55 additions & 2 deletions outputs/react/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { describe, expect, test, vi } from 'vitest';
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';

import OneSignal from './index';

const APP_ID = '123456';

const originalDocument = window.document;
const documentSpy = vi.spyOn(window, 'document', 'get');

const APP_ID = '123456';
beforeAll(() => {
// jsdom lacks PushSubscriptionOptions; stub it so init()'s push-support check passes.
function PushSubscriptionOptionsStub() {}
PushSubscriptionOptionsStub.prototype = { applicationServerKey: undefined };
(globalThis as unknown as { PushSubscriptionOptions: unknown }).PushSubscriptionOptions =
PushSubscriptionOptionsStub;
});

const init = vi.fn();
// @ts-expect-error - mocking OneSignal class that comes from the cdn
Expand Down Expand Up @@ -50,3 +59,47 @@ describe('React OneSignal', () => {
);
});
});

describe('init() rejects instead of hanging', () => {
let OneSignalModule: typeof import('./index').default;

beforeEach(async () => {
vi.resetModules();
window.OneSignalDeferred = [];
// addSDKScript() short-circuits if #onesignal-sdk already exists in the DOM.
document.querySelectorAll('script#onesignal-sdk').forEach((el) => el.remove());
OneSignalModule = (await import('./index')).default;
});

afterEach(() => {
vi.restoreAllMocks();
});

test('rejects when the browser does not support Web Push', async () => {
const originalPushSubscriptionOptions = (
globalThis as unknown as { PushSubscriptionOptions: unknown }
).PushSubscriptionOptions;
(globalThis as unknown as { PushSubscriptionOptions: unknown }).PushSubscriptionOptions =
undefined;
window.safari = undefined;

try {
await expect(OneSignalModule.init({ appId: APP_ID })).rejects.toThrow(
'This browser does not support Web Push notifications.',
);
} finally {
(globalThis as unknown as { PushSubscriptionOptions: unknown }).PushSubscriptionOptions =
originalPushSubscriptionOptions;
}
});

test('rejects when the SDK script fails to load', async () => {
const initPromise = OneSignalModule.init({ appId: APP_ID });

const scriptElement = document.getElementById('onesignal-sdk') as HTMLScriptElement | null;
expect(scriptElement).not.toBeNull();
scriptElement?.onerror?.(new Event('error'));

await expect(initPromise).rejects.toThrow('OneSignal script failed to load.');
});
});
18 changes: 17 additions & 1 deletion outputs/react/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const DEFAULT_SCRIPT_SRC =

let isOneSignalInitialized = false;
let isOneSignalScriptFailed = false;
let pendingInitReject: ((reason?: unknown) => void) | undefined;

if (typeof window !== 'undefined') {
window.OneSignalDeferred = window.OneSignalDeferred || [];
Expand All @@ -23,6 +24,8 @@ declare global {

function handleOnError() {
isOneSignalScriptFailed = true;
pendingInitReject?.(new Error('OneSignal script failed to load.'));
pendingInitReject = undefined;
}

function addSDKScript(scriptSrc?: string) {
Expand Down Expand Up @@ -106,6 +109,14 @@ const init = (options: IInitObject): Promise<void> => {
return Promise.reject(`Document is not defined.`);
}

// Required: the CDN script silently exits on unsupported browsers without
// draining OneSignalDeferred, so init() would hang forever otherwise.
if (!isPushNotificationsSupported()) {
return Promise.reject(
new Error('This browser does not support Web Push notifications.'),
);
}

// Handle both disabled and disable keys for welcome notification
if (options.welcomeNotification?.disabled !== undefined) {
options.welcomeNotification.disable = options.welcomeNotification.disabled;
Expand All @@ -114,13 +125,18 @@ const init = (options: IInitObject): Promise<void> => {
addSDKScript(options.scriptSrc);

return new Promise<void>((resolve, reject) => {
pendingInitReject = reject;
window.OneSignalDeferred?.push((OneSignal) => {
OneSignal.init(options)
.then(() => {
isOneSignalInitialized = true;
pendingInitReject = undefined;
resolve();
})
.catch(reject);
.catch((err) => {
pendingInitReject = undefined;
reject(err);
});
});
});
};
Expand Down
18 changes: 17 additions & 1 deletion outputs/vue/v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const DEFAULT_SCRIPT_SRC =

let isOneSignalInitialized = false;
let isOneSignalScriptFailed = false;
let pendingInitReject: ((reason?: unknown) => void) | undefined;

const VueApp: any = Vue;

Expand All @@ -17,6 +18,8 @@ if (typeof window !== 'undefined') {

function handleOnError() {
isOneSignalScriptFailed = true;
pendingInitReject?.(new Error('OneSignal script failed to load.'));
pendingInitReject = undefined;
}

function addSDKScript(scriptSrc?: string) {
Expand Down Expand Up @@ -72,6 +75,14 @@ const init = (options: IInitObject): Promise<void> => {
return Promise.reject(`Document is not defined.`);
}

// Required: the CDN script silently exits on unsupported browsers without
// draining OneSignalDeferred, so init() would hang forever otherwise.
if (!isPushNotificationsSupported()) {
return Promise.reject(
new Error('This browser does not support Web Push notifications.'),
);
}

// Handle both disabled and disable keys for welcome notification
if (options.welcomeNotification?.disabled !== undefined) {
options.welcomeNotification.disable = options.welcomeNotification.disabled;
Expand All @@ -80,13 +91,18 @@ const init = (options: IInitObject): Promise<void> => {
addSDKScript(options.scriptSrc);

return new Promise<void>((resolve, reject) => {
pendingInitReject = reject;
window.OneSignalDeferred?.push((OneSignal) => {
OneSignal.init(options)
.then(() => {
isOneSignalInitialized = true;
pendingInitReject = undefined;
resolve();
})
.catch(reject);
.catch((err) => {
pendingInitReject = undefined;
reject(err);
});
});
});
};
Expand Down
18 changes: 17 additions & 1 deletion outputs/vue/v3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const DEFAULT_SCRIPT_SRC =

let isOneSignalInitialized = false;
let isOneSignalScriptFailed = false;
let pendingInitReject: ((reason?: unknown) => void) | undefined;

if (typeof window !== 'undefined') {
window.OneSignalDeferred = window.OneSignalDeferred || [];
Expand All @@ -15,6 +16,8 @@ if (typeof window !== 'undefined') {

function handleOnError() {
isOneSignalScriptFailed = true;
pendingInitReject?.(new Error('OneSignal script failed to load.'));
pendingInitReject = undefined;
}

function addSDKScript(scriptSrc?: string) {
Expand Down Expand Up @@ -71,6 +74,14 @@ const init = (options: IInitObject): Promise<void> => {
return Promise.reject(`Document is not defined.`);
}

// Required: the CDN script silently exits on unsupported browsers without
// draining OneSignalDeferred, so init() would hang forever otherwise.
if (!isPushNotificationsSupported()) {
return Promise.reject(
new Error('This browser does not support Web Push notifications.'),
);
}

// Handle both disabled and disable keys for welcome notification
if (options.welcomeNotification?.disabled !== undefined) {
options.welcomeNotification.disable = options.welcomeNotification.disabled;
Expand All @@ -79,13 +90,18 @@ const init = (options: IInitObject): Promise<void> => {
addSDKScript(options.scriptSrc);

return new Promise<void>((resolve, reject) => {
pendingInitReject = reject;
window.OneSignalDeferred?.push((OneSignal) => {
OneSignal.init(options)
.then(() => {
isOneSignalInitialized = true;
pendingInitReject = undefined;
resolve();
})
.catch(reject);
.catch((err) => {
pendingInitReject = undefined;
reject(err);
});
});
});
};
Expand Down
Loading