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
6 changes: 0 additions & 6 deletions .cursor/rules/conventions.md

This file was deleted.

32 changes: 32 additions & 0 deletions .cursor/rules/pr-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
description: Conventions for pull request titles and body content
alwaysApply: true
---

# Pull Request Conventions

## PR Title

Use semantic/conventional commit prefixes in PR titles:

- `fix:` for bug fixes
- `feat:` for new features
- `chore:` for maintenance tasks (deps, CI, tooling)
- `refactor:` for code restructuring without behavior changes
- `docs:` for documentation-only changes
- `test:` for test-only changes

Example: `fix: resolve notification grouping on Android 14`

## PR Body

Follow the repo's PR template at `.github/pull_request_template.md`. Every PR body must include:

1. **One Line Summary** (required)
2. **Motivation** (required) explaining why the change is being made
3. **Scope** (recommended) describing what is and isn't affected
4. **Testing** section with manual and/or unit testing details
5. **Affected code checklist** with relevant items checked
6. **Checklist** sections confirmed

Remove the instructional header block (between `<!-- START -->` and `<!-- END -->`) before submitting.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@
},
{
"path": "./build/releases/OneSignalSDK.page.es6.js",
"limit": "43.69 kB",
"limit": "41.94 kB",
"gzip": true
},
{
"path": "./build/releases/OneSignalSDK.sw.js",
"limit": "12.701 kB",
"limit": "12.272 kB",
"gzip": true
},
{
Expand Down
6 changes: 1 addition & 5 deletions src/core/executors/CustomEventOperationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ export class CustomEventsOperationExecutor implements IOperationExecutor {
}

async _execute(operations: Operation[]): Promise<ExecutionResponse> {
Log._debug(
`CustomEventsOperationExecutor(operations: ${JSON.stringify(
operations,
)})`,
);
Log._debug(`CustomEventOpExec(${JSON.stringify(operations)})`);

// TODO: each trackEvent is sent individually right now; may need to batch in the future
const operation = operations[0];
Expand Down
4 changes: 1 addition & 3 deletions src/core/executors/IdentityOperationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ export class IdentityOperationExecutor implements IOperationExecutor {
}

async _execute(operations: Operation[]): Promise<ExecutionResponse> {
Log._debug(
`IdentityOperationExecutor(operations: ${JSON.stringify(operations)})`,
);
Log._debug(`IdentityOpExec(${JSON.stringify(operations)})`);

const invalidOps = operations.filter(
(op) =>
Expand Down
10 changes: 3 additions & 7 deletions src/core/executors/LoginUserOperationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ export class LoginUserOperationExecutor implements IOperationExecutor {
}

async _execute(operations: Operation[]): Promise<ExecutionResponse> {
Log._debug(
`LoginUserOperationExecutor(operation: ${JSON.stringify(operations)})`,
);
Log._debug(`LoginUserOpExec(${JSON.stringify(operations)})`);
const startingOp = operations[0];

if (startingOp instanceof LoginUserOperation)
Expand Down Expand Up @@ -121,13 +119,11 @@ export class LoginUserOperationExecutor implements IOperationExecutor {
}

case ExecutionResult._FailConflict:
Log._debug(`Handling 409 for externalId: ${loginUserOp._externalId}`);
Log._debug(`409 conflict: ${loginUserOp._externalId}`);
return this._createUser(loginUserOp, operations);

case ExecutionResult._FailNoretry:
Log._error(
`Recovering from SetAlias failure for externalId: ${loginUserOp._externalId}`,
);
Log._error(`SetAlias failed: ${loginUserOp._externalId}`);
return this._createUser(loginUserOp, operations);

default:
Expand Down
4 changes: 1 addition & 3 deletions src/core/executors/RefreshUserOperationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ export class RefreshUserOperationExecutor implements IOperationExecutor {
}

async _execute(operations: Operation[]): Promise<ExecutionResponse> {
Log._debug(
`RefreshUserOperationExecutor(operation: ${JSON.stringify(operations)})`,
);
Log._debug(`RefreshUserOpExec(${JSON.stringify(operations)})`);

if (operations.some((op) => !(op instanceof RefreshUserOperation)))
throw new Error(
Expand Down
2 changes: 1 addition & 1 deletion src/core/executors/SubscriptionOperationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class SubscriptionOperationExecutor implements IOperationExecutor {
}

async _execute(operations: Operation[]): Promise<ExecutionResponse> {
Log._debug(`SubscriptionOperationExecutor(operations: ${operations})`);
Log._debug(`SubOpExec(${operations})`);

const startingOp = operations[0];
if (startingOp instanceof CreateSubscriptionOperation)
Expand Down
2 changes: 1 addition & 1 deletion src/core/executors/UpdateUserOperationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class UpdateUserOperationExecutor implements IOperationExecutor {
}

async _execute(operations: Operation[]): Promise<ExecutionResponse> {
Log._debug(`UpdateUserOperationExecutor(operation: ${operations})`);
Log._debug(`UpdateUserOpExec(${operations})`);

const { appId, onesignalId, propertiesObject, refreshDeviceMetadata } =
this._processOperations(operations);
Expand Down
4 changes: 2 additions & 2 deletions src/core/modelRepo/OperationModelStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class OperationModelStore extends ModelStore<Operation> {

_create(jsonObject?: { name?: string } | null): Operation | null {
if (jsonObject === null) {
Log._error('null jsonObject sent to OperationModelStore.create');
Log._error('null jsonObject in OpModelStore.create');
return null;
}

Expand Down Expand Up @@ -96,7 +96,7 @@ export class OperationModelStore extends ModelStore<Operation> {
} {
const operationName = object?.name;
if (!operationName) {
Log._error("jsonObject must have 'name' attribute");
Log._error("Missing 'name' attribute");
return false;
}

Expand Down
24 changes: 11 additions & 13 deletions src/core/operationRepo/OperationRepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ export class OperationRepo implements IOperationRepo, IStartableService {
public _pause(): void {
clearInterval(this._timerID);
this._timerID = undefined;
Log._debug('OperationRepo: Paused');
Log._debug('OpRepo: Paused');
}

public _enqueue(operation: Operation): void {
Log._debug(`OperationRepo.enqueue(operation: ${operation})`);
Log._debug(`OpRepo.enqueue: ${operation}`);

this._internalEnqueue(
{
Expand All @@ -97,7 +97,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
}

public async _enqueueAndWait(operation: Operation): Promise<void> {
Log._debug(`OperationRepo.enqueueAndWaitoperation: ${operation})`);
Log._debug(`OpRepo.enqueueAndWait: ${operation}`);

await new Promise<void>((resolve, reject) => {
this._internalEnqueue(
Expand All @@ -121,9 +121,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
(item) => item.operation._modelId === queueItem.operation._modelId,
);
if (hasExisting) {
Log._debug(
`OperationRepo: internalEnqueue - operation.modelId: ${queueItem.operation._modelId} already exists in the queue.`,
);
Log._debug(`OpRepo: duplicate modelId: ${queueItem.operation._modelId}`);
return;
}

Expand All @@ -143,7 +141,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
let runningOps = false;

this._timerID = setInterval(async () => {
if (runningOps) return Log._debug('Operations in progress');
if (runningOps) return Log._debug('Ops in progress');

const ops = this._getNextOps(this._executeBucket);

Expand Down Expand Up @@ -172,7 +170,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
const response = await executor._execute(operations);
const idTranslations = response._idTranslations;

Log._debug(`OperationRepo: execute response = ${response._result}`);
Log._debug(`OpRepo: result = ${response._result}`);

// Handle ID translations
if (idTranslations) {
Expand All @@ -199,7 +197,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
case ExecutionResult._FailUnauthorized:
case ExecutionResult._FailNoretry:
case ExecutionResult._FailConflict:
Log._error(`Operation execution failed without retry: ${operations}`);
Log._error(`Op failed (no retry): ${operations}`);
ops.forEach((op) => {
this._operationModelStore._remove(op.operation._modelId);
});
Expand All @@ -218,7 +216,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
break;

case ExecutionResult._FailRetry:
Log._error(`Operation execution failed, retrying: ${operations}`);
Log._error(`Op failed, retrying: ${operations}`);
// Add back all operations to front of queue
[...ops].reverse().forEach((op) => {
removeOpFromDB(op.operation);
Expand All @@ -231,7 +229,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
break;

case ExecutionResult._FailPauseOpRepo:
Log._error(`Operation failed, pausing ops:${operations}`);
Log._error(`Op failed, pausing: ${operations}`);
this._pause();
ops.forEach((op) => op.resolver?.(false));
[...ops].reverse().forEach((op) => {
Expand Down Expand Up @@ -263,7 +261,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {
await delay(OP_REPO_POST_CREATE_DELAY);
}
} catch (e) {
Log._error(`Error attempting to execute operation: ${ops}`, e);
Log._error(`Op execute error: ${ops}`, e);

// On failure remove operations from store
ops.forEach((op) => {
Expand All @@ -284,7 +282,7 @@ export class OperationRepo implements IOperationRepo, IStartableService {

if (delayFor < 1) return;

Log._error(`Operations being delay for: ${delayFor} ms`);
Log._error(`Ops delayed: ${delayFor}ms`);
await delay(delayFor);
}

Expand Down
10 changes: 2 additions & 8 deletions src/entries/pageSdkInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,8 @@ async function processOneSignalDeferredArray(
function onesignalSdkInit() {
incrementSdkLoadCount();
if (getSdkLoadCount() > 1) {
Log._warn(
`OneSignal: The web push SDK is included more than once. For optimal performance, please include our ` +
`SDK only once on your page.`,
);
Log._debug(
`OneSignal: Exiting from SDK initialization to prevent double-initialization errors. ` +
`Occurred ${getSdkLoadCount()} times.`,
);
Log._warn('SDK included more than once');
Log._debug(`Skipping duplicate init (${getSdkLoadCount()})`);
return;
}

Expand Down
4 changes: 1 addition & 3 deletions src/onesignal/NotificationsNamespace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@ describe('requestPermission', () => {
// in flight error
notifications.requestPermission();
await expect(notifications.requestPermission()).resolves.toBe(false);
expect(debugSpy).toHaveBeenCalledWith(
'Already showing autoprompt. Abort showing a native prompt.',
);
expect(debugSpy).toHaveBeenCalledWith('Autoprompt already showing');

// permission is denied
await expect(notifications.requestPermission()).resolves.toBe(false);
Expand Down
6 changes: 2 additions & 4 deletions src/onesignal/OneSignal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ describe('OneSignal - No Consent Required', () => {

expect(addAliasFn).toHaveBeenCalledTimes(1);
expect(debugSpy).toHaveBeenCalledWith(
'Login: External ID already set, skipping login',
'Login: externalId already set',
);
await vi.waitUntil(
() => transferSubscriptionFn.mock.calls.length === 1,
Expand Down Expand Up @@ -844,9 +844,7 @@ describe('OneSignal - No Consent Required', () => {
expect(identityModel._externalId).toBeUndefined();

OneSignal.logout();
expect(debugSpy).toHaveBeenCalledWith(
'Logout: User is not logged in, skipping logout',
);
expect(debugSpy).toHaveBeenCalledWith('Logout: not logged in');
});

test('can logout the user with existing external id and subscription', async () => {
Expand Down
11 changes: 3 additions & 8 deletions src/onesignal/OneSignal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default class OneSignal {
private static async _initializeConfig(options: AppUserConfig) {
const appConfig = await getAppConfig(options);

Log._debug('OneSignal: Final web app config:', appConfig);
Log._debug('Final web app config:', appConfig);

// Workaround to temp assign config so that it can be used in context.
OneSignal.config = appConfig;
Expand Down Expand Up @@ -154,7 +154,7 @@ export default class OneSignal {

const idb = await dbPromise.catch((e) => {
Log._error(
'OneSignal: IndexedDB unavailable, close & reopen the page to retry init',
'IndexedDB unavailable, close & reopen the page to retry init',
e,
);
});
Expand Down Expand Up @@ -210,10 +210,6 @@ export default class OneSignal {
)
await __init();
else {
Log._debug(
'OneSignal: Waiting for DOMContentLoaded or readyStateChange event before continuing' +
' initialization...',
);
window.addEventListener('DOMContentLoaded', () => {
__init();
});
Expand Down Expand Up @@ -312,8 +308,7 @@ function processItem(
}

Log._info(
`OneSignal Web SDK loaded (version ${VERSION},
${windowEnvString} environment).`,
`Web SDK loaded (version ${VERSION}, ${windowEnvString} environment).`,
);
Log._debug(
`Current Page URL: ${
Expand Down
12 changes: 5 additions & 7 deletions src/onesignal/SessionNamespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class SessionNamespace {
): Promise<void> {
const config = OneSignal.config?.userConfig.outcomes;
if (!config) {
Log._error(`Could not send ${outcomeName}. No outcomes config found.`);
Log._error(`No outcomes config for ${outcomeName}`);
return;
}

Expand All @@ -23,7 +23,7 @@ export class SessionNamespace {
typeof outcomeWeight !== 'undefined' &&
typeof outcomeWeight !== 'number'
) {
Log._error('Outcome weight can only be a number if present.');
Log._error('Outcome weight must be a number');
return;
}

Expand All @@ -43,7 +43,7 @@ export class SessionNamespace {
async sendUniqueOutcome(outcomeName: string): Promise<void> {
const config = OneSignal.config?.userConfig.outcomes;
if (!config) {
Log._error(`Could not send ${outcomeName}. No outcomes config found.`);
Log._error(`No outcomes config for ${outcomeName}`);
return;
}

Expand All @@ -60,9 +60,7 @@ export class SessionNamespace {
const outcomeAttribution = await outcomesHelper._getAttribution();

if (outcomeAttribution.type === OutcomeAttributionType._NotSupported) {
Log._warn(
'You are on a free plan. Please upgrade to use this functionality.',
);
Log._warn('Upgrade required for this feature');
return;
}

Expand All @@ -80,7 +78,7 @@ export class SessionNamespace {
newNotifsToAttributeWithOutcome,
)
) {
Log._warn(`'${outcomeName}' was already reported for all notifications.`);
Log._warn(`'${outcomeName}' already reported`);
return;
}

Expand Down
4 changes: 2 additions & 2 deletions src/onesignal/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,12 @@ export default class User {
const onesignalId =
OneSignal._coreDirector._getIdentityModel()._onesignalId;
if (IDManager._isLocalId(onesignalId) && !hasLoginOp(onesignalId)) {
Log._error('User must be logged in first.');
Log._error('User not logged in');
return;
}

if (!isObjectSerializable(properties)) {
Log._error('Properties must be JSON-serializable');
Log._error('Properties not serializable');
return;
}
logMethodCall('trackEvent', { name, properties });
Expand Down
Loading
Loading