diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 419f2f952..95a4f7319 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -2,40 +2,38 @@
// https://github.com/microsoft/vscode-dev-containers/tree/v0.163.1/containers/docker-existing-docker-compose
// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml.
{
- "name": "Existing Docker Compose (Extend)",
+ "name": "Existing Docker Compose (Extend)",
- // Update the 'dockerComposeFile' list if you have more compose files or use different names.
- // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
- "dockerComposeFile": [
- "../docker-compose.yml"
- ],
+ // Update the 'dockerComposeFile' list if you have more compose files or use different names.
+ // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
+ "dockerComposeFile": ["../docker-compose.yml"],
- "service": "onesignal-web-sdk-dev",
+ "service": "onesignal-web-sdk-dev",
- // The optional 'workspaceFolder' property is the path VS Code should open by default when
- // connected. This is typically a file mount in .devcontainer/docker-compose.yml
- "workspaceFolder": "/sdk",
+ // The optional 'workspaceFolder' property is the path VS Code should open by default when
+ // connected. This is typically a file mount in .devcontainer/docker-compose.yml
+ "workspaceFolder": "/sdk",
- // Set *default* container specific settings.json values on container create.
- "settings": {
- "terminal.integrated.shell.linux": null
- },
+ // Set *default* container specific settings.json values on container create.
+ "settings": {
+ "terminal.integrated.shell.linux": null
+ },
- // Add the IDs of extensions you want installed when the container is created.
- "extensions": []
+ // Add the IDs of extensions you want installed when the container is created.
+ "extensions": []
- // Use 'forwardPorts' to make a list of ports inside the container available locally.
- // "forwardPorts": [],
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
+ // "forwardPorts": [],
- // Uncomment the next line if you want start specific services in your Docker Compose config.
- // "runServices": [],
+ // Uncomment the next line if you want start specific services in your Docker Compose config.
+ // "runServices": [],
- // Uncomment the next line if you want to keep your containers running after VS Code shuts down.
- // "shutdownAction": "none",
+ // Uncomment the next line if you want to keep your containers running after VS Code shuts down.
+ // "shutdownAction": "none",
- // Uncomment the next line to run commands after the container is created - for example installing curl.
- // "postCreateCommand": "apt-get update && apt-get install -y curl",
+ // Uncomment the next line to run commands after the container is created - for example installing curl.
+ // "postCreateCommand": "apt-get update && apt-get install -y curl",
- // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
- // "remoteUser": "vscode"
+ // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root.
+ // "remoteUser": "vscode"
}
diff --git a/.github/os_probot_metadata.js b/.github/os_probot_metadata.js
deleted file mode 100644
index 6b2b3f92e..000000000
--- a/.github/os_probot_metadata.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Based on probot-metadata - https://github.com/probot/metadata
- */
-const regex = /\n\n/;
-
-const { Octokit } = require('@octokit/action');
-
-const octokit = new Octokit();
-
-module.exports = (context, issue = null) => {
- console.info(context);
- const prefix = 'onesignal-probot';
-
- if (!issue) issue = context.payload.issue;
-
- return {
- async get(key = null) {
- let body = issue.body;
-
- if (!body) {
- body = (await octokit.issues.get(issue)).data.body || '';
- }
-
- const match = body.match(regex);
-
- if (match) {
- const data = JSON.parse(match[1])[prefix];
- return key ? data && data[key] : data;
- }
- },
-
- async set(key, value) {
- let body = issue.body;
- let data = {};
-
- if (!body) body = (await octokit.issues.get(issue)).data.body || '';
-
- body = body.replace(regex, (_, json) => {
- data = JSON.parse(json);
- return '';
- });
-
- if (!data[prefix]) data[prefix] = {};
-
- if (typeof key === 'object') {
- Object.assign(data[prefix], key);
- } else {
- data[prefix][key] = value;
- }
-
- body = `${body}\n\n`;
-
- const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
- const issue_number = context.payload.issue.number;
- return octokit.issues.update({ owner, repo, issue_number, body });
- },
- };
-};
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 4e1566749..c8125664c 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,45 +1,56 @@
# Description
+
## 1 Line Summary
## Details
# Systems Affected
- - [ ] WebSDK
- - [ ] Backend
- - [ ] Dashboard
+
+- [ ] WebSDK
+- [ ] Backend
+- [ ] Dashboard
# Validation
+
## Tests
+
### Info
### Checklist
- - [ ] All the automated tests pass or I explained why that is not possible
- - [ ] I have personally tested this on my machine or explained why that is not possible
- - [ ] I have included test coverage for these changes or explained why they are not needed
+
+- [ ] All the automated tests pass or I explained why that is not possible
+- [ ] I have personally tested this on my machine or explained why that is not possible
+- [ ] I have included test coverage for these changes or explained why they are not needed
**Programming Checklist**
Interfaces:
- - [ ] Don't use default export
- - [ ] New interfaces are in model files
+
+- [ ] Don't use default export
+- [ ] New interfaces are in model files
Functions:
- - [ ] Don't use default export
- - [ ] All function signatures have return types
- - [ ] Helpers should not access any data but rather be given the data to operate on.
+
+- [ ] Don't use default export
+- [ ] All function signatures have return types
+- [ ] Helpers should not access any data but rather be given the data to operate on.
Typescript:
- - [ ] No Typescript warnings
- - [ ] Avoid silencing null/undefined warnings with the exclamation point
+
+- [ ] No Typescript warnings
+- [ ] Avoid silencing null/undefined warnings with the exclamation point
Other:
- - [ ] Iteration: refrain from using `elem of array` syntax. Prefer `forEach` or use `map`
- - [ ] Avoid using global OneSignal accessor for `context` if possible. Instead, we can pass it to function/constructor so that we don't call `OneSignal.context`
+
+- [ ] Iteration: refrain from using `elem of array` syntax. Prefer `forEach` or use `map`
+- [ ] Avoid using global OneSignal accessor for `context` if possible. Instead, we can pass it to function/constructor so that we don't call `OneSignal.context`
## Screenshots
+
### Info
### Checklist
- - [ ] I have included screenshots/recordings of the intended results or explained why they are not needed
+
+- [ ] I have included screenshots/recordings of the intended results or explained why they are not needed
---
diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml
deleted file mode 100644
index a7a42bdef..000000000
--- a/.github/release-drafter.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-name-template: $RESOLVED_VERSION
-tag-template: $RESOLVED_VERSION
-categories:
- - title: ๐ Features
- label: Enhancement / Feature
- - title: ๐ Bug Fixes
- label: Bug
- - title: ๐งฐ Improvements
- label: Improvement
- - title: down arrow Dependency Updates
- label: Dependencies
-change-template: '- $TITLE (#$NUMBER)'
-version-resolver:
- major:
- labels:
- - 'major'
- minor:
- labels:
- - 'minor'
- patch:
- labels:
- - 'patch'
- default: patch
-template: |
- ## Other Changes
-
- $CHANGES
diff --git a/.github/set_response_times.js b/.github/set_response_times.js
deleted file mode 100644
index fb8aa51eb..000000000
--- a/.github/set_response_times.js
+++ /dev/null
@@ -1,63 +0,0 @@
-function calcResponseTimeForIssueCreatedAt(createdAt) {
- const issueOpenedDate = new Date(createdAt);
- const issueTriagedDate = new Date();
- const businessDaysResponseTime = calcBusinessDaysBetweenDates(
- issueOpenedDate,
- issueTriagedDate,
- );
- return businessDaysResponseTime;
-}
-
-function calcBusinessDaysBetweenDates(openedDate, triagedDate) {
- let differenceInWeeks, responseTime;
- if (triagedDate < openedDate) return -1; // error code if dates transposed
- let openedDay = openedDate.getDay(); // day of week
- let triagedDay = triagedDate.getDay();
- openedDay = openedDay == 0 ? 7 : openedDay; // change Sunday from 0 to 7
- triagedDay = triagedDay == 0 ? 7 : triagedDay;
- openedDay = openedDay > 5 ? 5 : openedDay; // only count weekdays
- triagedDay = triagedDay > 5 ? 5 : triagedDay;
- // calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000)
- differenceInWeeks = Math.floor(
- (triagedDate.getTime() - openedDate.getTime()) / 604800000,
- );
- if (openedDay < triagedDay) {
- //Equal to makes it reduce 5 days
- responseTime = differenceInWeeks * 5 + (triagedDay - openedDay);
- } else if (openedDay == triagedDay) {
- responseTime = differenceInWeeks * 5;
- } else {
- responseTime = (differenceInWeeks + 1) * 5 - (openedDay - triagedDay);
- }
- return responseTime;
-}
-
-module.exports = async (context, osmetadata) => {
- const foundResponseTime = await osmetadata(context).get(
- 'response_time_in_business_days',
- );
- if (foundResponseTime) {
- const foundString =
- 'already found response time in business days: ' + foundResponseTime;
- console.info(foundString);
- return foundString;
- }
- if (
- context.payload.comment &&
- context.payload.comment.author_association != 'MEMBER' &&
- context.payload.comment.author_association != 'OWNER' &&
- context.payload.comment.author_association != 'CONTRIBUTOR'
- ) {
- return;
- }
- const businessDaysResponseTime = calcResponseTimeForIssueCreatedAt(
- context.payload.issue.created_at,
- );
- console.info('response time in business days: ' + businessDaysResponseTime);
- const result = osmetadata(context, context.payload.issue).set(
- 'response_time_in_business_days',
- businessDaysResponseTime,
- );
- console.info('osmetadata update result: ' + result);
- return 'set response time in business days: ' + businessDaysResponseTime;
-};
diff --git a/.github/workflows/asana-add-comment.yml b/.github/workflows/asana-add-comment.yml
deleted file mode 100644
index 1235c8f14..000000000
--- a/.github/workflows/asana-add-comment.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-name: Github --> Asana Add Comment Workflow
-
-on:
- issue_comment:
- types: [created]
- workflow_dispatch:
-
-jobs:
- build:
- runs-on: ubuntu-latest
- permissions:
- issues: read
- steps:
- - name: Get Asana Task Corresponding to Issue
- env:
- ISSUE_ID: ${{ github.event.issue.id }}
- REPO_FULL_NAME: ${{ github.event.repository.full_name }}
- WORKSPACE_ID: "780103692902078"
- run: |
- REPO_SCOPED_ISSUE_ID="$REPO_FULL_NAME#$ISSUE_ID"
-
- curl --request GET \
- --url "https://app.asana.com/api/1.0/workspaces/$WORKSPACE_ID/tasks/search?opt_fields=notes&text=$REPO_SCOPED_ISSUE_ID&sort_by=modified_at&sort_ascending=false" \
- --header 'accept: application/json' \
- --header 'authorization: Bearer ${{ secrets.ASANA_PAT }}' \
- --output response.json
- TASK_GID=$(jq -r '.data[0].gid' response.json)
- echo "TASK_GID=$TASK_GID" >> $GITHUB_ENV
- - name: Comment on Asana Task
- env:
- ISSUE_COMMENT: ${{ github.event.comment.body }}
- COMMENTER_NAME: ${{ github.event.comment.user.login }}
- run: |
- BODY_DATA=$(jq -n \
- --arg text "$ISSUE_COMMENT" \
- --arg commenter_name "$COMMENTER_NAME" \
- '{
- "data": {
- "text": "\($commenter_name) left a comment:\n\n\($text)",
- }
- }')
- curl --request POST \
- --url https://app.asana.com/api/1.0/tasks/$TASK_GID/stories \
- --header 'accept: application/json' \
- --header 'authorization: Bearer ${{ secrets.ASANA_PAT }}' \
- --header 'content-type: application/json' \
- --data "$BODY_DATA"
\ No newline at end of file
diff --git a/.github/workflows/asana-create-task.yml b/.github/workflows/asana-create-task.yml
deleted file mode 100644
index f778f2f7a..000000000
--- a/.github/workflows/asana-create-task.yml
+++ /dev/null
@@ -1,119 +0,0 @@
-name: Github --> Asana Create Task Workflow
-
-on:
- issues:
- types: [opened]
- workflow_dispatch:
-
-jobs:
- build:
- runs-on: ubuntu-latest
- permissions:
- issues: read
- steps:
- - name: Create Asana task
- env:
- ISSUE_TITLE: ${{ github.event.issue.title }}
- ISSUE_BODY: ${{ github.event.issue.body }}
- ISSUE_HTML_URL: ${{ github.event.issue.html_url }}
- ISSUE_ID: ${{ github.event.issue.id }}
- ISSUE_NUMBER: ${{ github.event.issue.number }}
- REPO_FULL_NAME: ${{ github.event.repository.full_name }}
- SDK_PLATFORM_GROUP: "1208961704779581"
- SDK_PLATFORM_GROUP_WEB: "1208961704779583"
- SDK_PLATFORM: "1208961704779592"
- SDK_PLATFORM_WEB: "1208961704779597"
- DSA_PRIORITY: "1208779519954980"
- DSA_PRIORITY_NO_PRIORITY: "1208779521616959"
- DSA_STATUS: "1210103546117753"
- DSA_STATUS_TRIAGE: "1210103546117756"
- DSA_REPO_TICKET_URL: "1210347857768758"
- WORKSPACE_ID: "780103692902078"
- PROJECT_ID_GITHUB_AND_IMPORTANT_SDK_ISSUES: "1208970714650308"
- PROJECT_ID_SDK_BACKLOG: "1208777198342772"
- run: |
- DATA_BODY=$(jq -n \
- --arg title "$ISSUE_TITLE" \
- --arg body "$ISSUE_BODY" \
- --arg url "$ISSUE_HTML_URL" \
- --arg id "$ISSUE_ID" \
- --arg number "$ISSUE_NUMBER" \
- --arg repo_full_name "$REPO_FULL_NAME" \
- --arg sdk_platform_group "$SDK_PLATFORM_GROUP" \
- --arg sdk_platform_group_web "$SDK_PLATFORM_GROUP_WEB" \
- --arg sdk_platform "$SDK_PLATFORM" \
- --arg sdk_platform_web "$SDK_PLATFORM_WEB" \
- --arg dsa_priority "$DSA_PRIORITY" \
- --arg dsa_priority_no_priority "$DSA_PRIORITY_NO_PRIORITY" \
- --arg dsa_status "$DSA_STATUS" \
- --arg dsa_status_triage "$DSA_STATUS_TRIAGE" \
- --arg dsa_repo_ticket_url "$DSA_REPO_TICKET_URL" \
- --arg workspace_id "$WORKSPACE_ID" \
- --arg project_id_github_and_important_sdk_issues "$PROJECT_ID_GITHUB_AND_IMPORTANT_SDK_ISSUES" \
- --arg project_id_sdk_backlog "$PROJECT_ID_SDK_BACKLOG" \
- '{
- "data": {
- "custom_fields": {
- $sdk_platform_group: $sdk_platform_group_web,
- $sdk_platform: $sdk_platform_web,
- $dsa_priority: $dsa_priority_no_priority,
- $dsa_status: $dsa_status_triage,
- $dsa_repo_ticket_url: $url
- },
- "name": $title,
- "workspace": $workspace_id,
- "projects": [$project_id_github_and_important_sdk_issues, $project_id_sdk_backlog],
- "notes": "Issue ID: \($repo_full_name)#\($id)\nIssue number: \($number)\nCreated via GitHub Actions\n----\n\n\($body)"
- }
- }')
-
- curl --request POST \
- --url https://app.asana.com/api/1.0/tasks?opt_pretty=true \
- --header 'accept: application/json' \
- --header 'authorization: Bearer ${{ secrets.ASANA_PAT }}' \
- --header 'content-type: application/json' \
- --data "$DATA_BODY" \
- --output response.json
-
- TASK_GID=$(jq -r '.data.gid' response.json)
- echo "TASK_GID=$TASK_GID" >> $GITHUB_ENV
- - name: Move to "0 Unclassified" section in "Github & Important SDK Issues" project
- env:
- SECTION_ID_GITHUB_AND_IMPORTANT_SDK_ISSUES: "1208970755434051"
- run: |
- DATA_BODY=$(jq -n \
- --arg task_gid "$TASK_GID" \
- --arg section_id "$SECTION_ID_GITHUB_AND_IMPORTANT_SDK_ISSUES" \
- '{
- "data": {
- "task": $task_gid,
- "insert_after": "null"
- }
- }')
-
- curl --request POST \
- --url https://app.asana.com/api/1.0/sections/$section_id/addTask \
- --header 'accept: application/json' \
- --header 'authorization: Bearer ${{ secrets.ASANA_PAT }}' \
- --header 'content-type: application/json' \
- --data "$DATA_BODY"
- - name: Move to "Untriaged" section in "SDK / Backlog" project
- env:
- SECTION_ID_SDK_BACKLOG: "1208899729378982"
- run: |
- DATA_BODY=$(jq -n \
- --arg task_gid "$TASK_GID" \
- --arg section_id "$SECTION_ID_SDK_BACKLOG" \
- '{
- "data": {
- "task": $task_gid,
- "insert_after": "null"
- }
- }')
-
- curl --request POST \
- --url https://app.asana.com/api/1.0/sections/$section_id/addTask \
- --header 'accept: application/json' \
- --header 'authorization: Bearer ${{ secrets.ASANA_PAT }}' \
- --header 'content-type: application/json' \
- --data "$DATA_BODY"
\ No newline at end of file
diff --git a/.github/workflows/asana-update-issue.yml b/.github/workflows/asana-update-issue.yml
deleted file mode 100644
index d9dcebe97..000000000
--- a/.github/workflows/asana-update-issue.yml
+++ /dev/null
@@ -1,172 +0,0 @@
-name: Github --> Asana Issue Updates Workflow
-
-on:
- issues:
- types: [edited, deleted, closed, reopened, assigned, unassigned, labeled, unlabeled, milestoned, demilestoned, pinned, unpinned, locked, unlocked, transferred]
- workflow_dispatch:
-
-jobs:
- build:
- runs-on: ubuntu-latest
- permissions:
- issues: read
- steps:
- - name: Get Asana Task Corresponding to Issue
- env:
- ISSUE_ID: ${{ github.event.issue.id }}
- REPO_FULL_NAME: ${{ github.event.repository.full_name }}
- WORKSPACE_ID: "780103692902078"
- run: |
- REPO_SCOPED_ISSUE_ID="$REPO_FULL_NAME#$ISSUE_ID"
-
- curl --request GET \
- --url "https://app.asana.com/api/1.0/workspaces/$WORKSPACE_ID/tasks/search?opt_fields=notes&text=$REPO_SCOPED_ISSUE_ID&sort_by=modified_at&sort_ascending=false" \
- --header 'accept: application/json' \
- --header 'authorization: Bearer ${{ secrets.ASANA_PAT }}' \
- --output response.json
- TASK_GID=$(jq -r '.data[0].gid' response.json)
- echo "TASK_GID=$TASK_GID" >> $GITHUB_ENV
- - name: Determine Action and Post to Asana
- env:
- ACTION_TYPE: ${{ github.event.action }}
- ACTOR_NAME: ${{ github.event.sender.login }}
- ISSUE_TITLE: ${{ github.event.issue.title }}
- ISSUE_NUMBER: ${{ github.event.issue.number }}
- ISSUE_STATE: ${{ github.event.issue.state }}
- run: |
- # Map GitHub action types to human-readable descriptions
- case "$ACTION_TYPE" in
- "edited")
- ACTION_DESC="edited the issue"
- ;;
- "deleted")
- ACTION_DESC="deleted the issue"
- ;;
- "closed")
- ACTION_DESC="closed the issue"
- ;;
- "reopened")
- ACTION_DESC="reopened the issue"
- ;;
- "assigned")
- ACTION_DESC="assigned the issue"
- ;;
- "unassigned")
- ACTION_DESC="unassigned the issue"
- ;;
- "labeled")
- ACTION_DESC="added labels to the issue"
- ;;
- "unlabeled")
- ACTION_DESC="removed labels from the issue"
- ;;
- "milestoned")
- ACTION_DESC="added the issue to a milestone"
- ;;
- "demilestoned")
- ACTION_DESC="removed the issue from a milestone"
- ;;
- "pinned")
- ACTION_DESC="pinned the issue"
- ;;
- "unpinned")
- ACTION_DESC="unpinned the issue"
- ;;
- "locked")
- ACTION_DESC="locked the issue"
- ;;
- "unlocked")
- ACTION_DESC="unlocked the issue"
- ;;
- "transferred")
- ACTION_DESC="transferred the issue"
- ;;
- *)
- ACTION_DESC="performed an action on the issue"
- ;;
- esac
-
- # Add additional context for specific actions based on webhook payload
- if [ "$ACTION_TYPE" = "assigned" ] && [ -n "${{ github.event.assignee.login }}" ]; then
- ACTION_DESC="assigned the issue to ${{ github.event.assignee.login }}"
- fi
-
- if [ "$ACTION_TYPE" = "unassigned" ] && [ -n "${{ github.event.assignee.login }}" ]; then
- ACTION_DESC="unassigned the issue from ${{ github.event.assignee.login }}"
- fi
-
- if [ "$ACTION_TYPE" = "labeled" ] && [ -n "${{ github.event.label.name }}" ]; then
- LABEL_COLOR="${{ github.event.label.color }}"
- ACTION_DESC="added label '${{ github.event.label.name }}' to the issue"
- if [ -n "$LABEL_COLOR" ]; then
- ACTION_DESC="$ACTION_DESC (color: #$LABEL_COLOR)"
- fi
- fi
-
- if [ "$ACTION_TYPE" = "unlabeled" ] && [ -n "${{ github.event.label.name }}" ]; then
- LABEL_COLOR="${{ github.event.label.color }}"
- ACTION_DESC="removed label '${{ github.event.label.name }}' from the issue"
- if [ -n "$LABEL_COLOR" ]; then
- ACTION_DESC="$ACTION_DESC (color: #$LABEL_COLOR)"
- fi
- fi
-
- if [ "$ACTION_TYPE" = "milestoned" ] && [ -n "${{ github.event.milestone.title }}" ]; then
- MILESTONE_DUE_DATE="${{ github.event.milestone.due_on }}"
- ACTION_DESC="added the issue to milestone '${{ github.event.milestone.title }}'"
- if [ -n "$MILESTONE_DUE_DATE" ] && [ "$MILESTONE_DUE_DATE" != "null" ]; then
- ACTION_DESC="$ACTION_DESC (due: $MILESTONE_DUE_DATE)"
- fi
- fi
-
- if [ "$ACTION_TYPE" = "demilestoned" ] && [ -n "${{ github.event.milestone.title }}" ]; then
- ACTION_DESC="removed the issue from milestone '${{ github.event.milestone.title }}'"
- fi
-
- if [ "$ACTION_TYPE" = "transferred" ] && [ -n "${{ github.event.changes.new_repository.full_name }}" ]; then
- ACTION_DESC="transferred the issue to repository ${{ github.event.changes.new_repository.full_name }}"
- fi
-
- if [ "$ACTION_TYPE" = "edited" ] && [ -n "${{ github.event.changes.title.from }}" ]; then
- OLD_TITLE="${{ github.event.changes.title.from }}"
- NEW_TITLE="${{ github.event.issue.title }}"
- ACTION_DESC="edited the issue title from '$OLD_TITLE' to '$NEW_TITLE'"
- fi
-
- echo "ACTION_DESC=$ACTION_DESC" >> $GITHUB_ENV
-
- # Only proceed if we found a task
- if [ "$TASK_GID" != "null" ] && [ -n "$TASK_GID" ]; then
- # Create a more detailed message with additional context
- MESSAGE_TEXT="$ACTOR_NAME performed an action: $ACTION_DESC"
-
- # Add issue state information for state changes
- if [ "$ACTION_TYPE" = "closed" ] || [ "$ACTION_TYPE" = "reopened" ]; then
- MESSAGE_TEXT=$(printf "%s\nIssue state: %s" "$MESSAGE_TEXT" "$ISSUE_STATE")
- fi
-
- # Add repository information for transferred issues
- if [ "$ACTION_TYPE" = "transferred" ]; then
- REPO_NAME="${{ github.event.repository.full_name }}"
- MESSAGE_TEXT=$(printf "%s\nFrom repository: %s" "$MESSAGE_TEXT" "$REPO_NAME")
- fi
-
- MESSAGE_TEXT=$(printf "%s\n\nIssue: #%s - %s" "$MESSAGE_TEXT" "$ISSUE_NUMBER" "$ISSUE_TITLE")
-
- BODY_DATA=$(jq -n \
- --arg text "$MESSAGE_TEXT" \
- '{
- "data": {
- "text": $text
- }
- }')
-
- curl --request POST \
- --url https://app.asana.com/api/1.0/tasks/$TASK_GID/stories \
- --header 'accept: application/json' \
- --header 'authorization: Bearer ${{ secrets.ASANA_PAT }}' \
- --header 'content-type: application/json' \
- --data "$BODY_DATA"
- else
- echo "No corresponding Asana task found for issue ID: $ISSUE_ID"
- fi
\ No newline at end of file
diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml
index b3916e003..5ea455089 100644
--- a/.github/workflows/claude-code-review.yml
+++ b/.github/workflows/claude-code-review.yml
@@ -42,4 +42,3 @@ jobs:
allowed_bots: 'dependabot[bot]'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
-
diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml
index 79fe05647..d1998486a 100644
--- a/.github/workflows/claude.yml
+++ b/.github/workflows/claude.yml
@@ -47,4 +47,3 @@ jobs:
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'
-
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 83d483f02..a924fe82c 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,6 +1,3 @@
{
- "recommendations": [
- "jeff-hykin.macro-commander",
- "void-zero.vite-plus-extension-pack"
- ]
+ "recommendations": ["jeff-hykin.macro-commander", "void-zero.vite-plus-extension-pack"]
}
diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md
index 0b44ef8fa..3922fbcc1 100644
--- a/MIGRATION_GUIDE.md
+++ b/MIGRATION_GUIDE.md
@@ -70,10 +70,7 @@ From:
To:
```html
-
+
```
### Service Worker
diff --git a/TESTS.md b/TESTS.md
index 6a659f7e7..5a9767e6a 100644
--- a/TESTS.md
+++ b/TESTS.md
@@ -70,11 +70,7 @@ server.use(
// or
-server.use(
- http.get('**/v1/notifications', () =>
- HttpResponse.json({ result: {}, status: 200 }),
- ),
-);
+server.use(http.get('**/v1/notifications', () => HttpResponse.json({ result: {}, status: 200 })));
```
## Fake Timers and IndexedDB
diff --git a/__test__/constants/constants.ts b/__test__/constants/constants.ts
index b2e88ebcf..995c2f93a 100644
--- a/__test__/constants/constants.ts
+++ b/__test__/constants/constants.ts
@@ -3,8 +3,7 @@ import { NotificationType } from 'src/shared/subscriptions/constants';
export const APP_ID = '34fcbe85-278d-4fd2-a4ec-0f80e95072c5';
export const PUSH_TOKEN = 'https://fcm.googleapis.com/fcm/send/01010101010101';
-export const PUSH_TOKEN_2 =
- 'https://fcm.googleapis.com/fcm/send/01010101010102';
+export const PUSH_TOKEN_2 = 'https://fcm.googleapis.com/fcm/send/01010101010102';
export const ONESIGNAL_ID = '1111111111-2222222222-3333333333';
export const ONESIGNAL_ID_2 = '2222222222-3333333333-4444444444';
diff --git a/__test__/constants/useragent.ts b/__test__/constants/useragent.ts
index 627368166..6e3056d25 100644
--- a/__test__/constants/useragent.ts
+++ b/__test__/constants/useragent.ts
@@ -21,12 +21,10 @@ export const USER_AGENTS = {
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.1',
FIREFOX_MAC:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 15.6; rv:141.0) Gecko/20100101 Firefox/141.0',
- FIREFOX_LINUX:
- 'Mozilla/5.0 (X11; Linux i686; rv:141.0) Gecko/20100101 Firefox/141.0',
+ FIREFOX_LINUX: 'Mozilla/5.0 (X11; Linux i686; rv:141.0) Gecko/20100101 Firefox/141.0',
FIREFOX_IOS:
'Mozilla/5.0 (iPhone; CPU iPhone OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/141.0 Mobile/15E148 Safari/605.1.15',
- FIREFOX_ANDROID:
- 'Mozilla/5.0 (Android 16; Mobile; rv:141.0) Gecko/141.0 Firefox/141.0',
+ FIREFOX_ANDROID: 'Mozilla/5.0 (Android 16; Mobile; rv:141.0) Gecko/141.0 Firefox/141.0',
SAFARI_MAC:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Safari/605.1.15',
SAFARI_IPHONE:
@@ -53,8 +51,7 @@ export const USER_AGENTS = {
'Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 [FBAN/FBIOS;FBAV/238.0.0.50.115;FBBV/171859800;FBDV/iPhone9,3;FBMD/iPhone;FBSN/iOS;FBSV/12.4.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/172564136;FBCR/AT&T]',
FACEBOOK_APP_ANDROID:
'Mozilla/5.0 (Linux; Android 8.1.0; SM-J410G Build/M1AJB; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.81 Mobile Safari/537.36[FBAN/EMA;FBLC/es_LA;FBAV/457.0.0.12.82;FBCX/modulariab;]',
- SAMSUNG_TABLET:
- 'Dalvik/2.1.0 (Linux; U; Android 14; SM-X306B Build/UP1A.231005.007)',
+ SAMSUNG_TABLET: 'Dalvik/2.1.0 (Linux; U; Android 14; SM-X306B Build/UP1A.231005.007)',
GOOGLE_TABLET:
'Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36',
// AMAZON_FIRE_TV:
diff --git a/__test__/setupTests.ts b/__test__/setupTests.ts
index b9c87e9d5..4c805c9b8 100644
--- a/__test__/setupTests.ts
+++ b/__test__/setupTests.ts
@@ -1,7 +1,8 @@
import * as OneSignalApi from 'src/shared/api/page';
import { ConfigIntegrationKind } from 'src/shared/config/constants';
import { clearAll } from 'src/shared/database/client';
-import type { MockInstance } from 'vite-plus/test';
+import { vi, beforeAll, beforeEach, afterEach, afterAll, type MockInstance } from 'vite-plus/test';
+
import { DEFAULT_USER_AGENT } from './constants';
import TestContext from './support/environment/TestContext';
import { server } from './support/mocks/server';
@@ -52,11 +53,8 @@ Object.defineProperty(navigator, 'userAgent', {
let downloadSpy: MockInstance;
export const mockJsonp = () => {
- const serverConfig = TestContext.getFakeServerAppConfig(
- ConfigIntegrationKind._Custom,
- );
+ const serverConfig = TestContext.getFakeServerAppConfig(ConfigIntegrationKind._Custom);
- if (!downloadSpy)
- downloadSpy = vi.spyOn(OneSignalApi, 'downloadServerAppConfig');
+ if (!downloadSpy) downloadSpy = vi.spyOn(OneSignalApi, 'downloadServerAppConfig');
downloadSpy.mockResolvedValue(serverConfig);
};
diff --git a/__test__/support/environment/TestContext.ts b/__test__/support/environment/TestContext.ts
index 77b31c772..9671eb070 100644
--- a/__test__/support/environment/TestContext.ts
+++ b/__test__/support/environment/TestContext.ts
@@ -13,6 +13,7 @@ import type {
} from 'src/shared/config/types';
import type { RecursivePartial } from 'src/shared/context/types';
import { DelayedPromptType } from 'src/shared/prompts/constants';
+
import { APP_ID } from '../../constants';
import type { TestEnvironmentConfig } from './TestEnvironment';
@@ -113,8 +114,7 @@ export default class TestContext {
message: 'This is an example notification message.',
acceptButton: 'Continue',
cancelButton: 'No Thanks',
- actionMessage:
- "We'd like to send you notifications for the latest news and updates.",
+ actionMessage: "We'd like to send you notifications for the latest news and updates.",
autoAcceptTitle: 'Click Allow',
customizeTextEnabled: true,
},
@@ -256,8 +256,7 @@ export default class TestContext {
message: 'This is an example notification message.',
acceptButton: 'Continue',
cancelButton: 'No Thanks',
- actionMessage:
- "We'd like to send you notifications for the latest news and updates.",
+ actionMessage: "We'd like to send you notifications for the latest news and updates.",
autoAcceptTitle: 'Click Allow',
customizeTextEnabled: true,
},
@@ -272,8 +271,7 @@ export default class TestContext {
text: {
subscribe: 'Subscribe to push notifications',
unsubscribe: 'Unsubscribe from push notifications',
- explanation:
- 'Get updates from all sorts of things that matter to you',
+ explanation: 'Get updates from all sorts of things that matter to you',
},
unsubscribeEnabled: true,
},
@@ -282,8 +280,7 @@ export default class TestContext {
name: 'My Website',
origin: 'https://www.site.com',
proxyOrigin: undefined,
- defaultIconUrl:
- 'https://onesignal.com/images/notification_logo.png',
+ defaultIconUrl: 'https://onesignal.com/images/notification_logo.png',
proxyOriginEnabled: false,
},
webhooks: {
@@ -322,8 +319,7 @@ export default class TestContext {
'BLJozaErc0QXdS7ykMyqniAcvfmdoziwfoSN-Mde_OckAbN_XrOC9Zt2Sfz4pD0UnYT5w3frWjF2iTTtjqEBgbE',
onesignal_vapid_public_key:
'BMzCIzYqtgz2Bx7S6aPVK6lDWets7kGm-pgo2H4RixFikUaNIoPqjPBBOEWMAfeFjuT9mAvbe-lckGi6vvNEiW0',
- safari_web_id:
- 'web.onesignal.auto.017d7a1b-f1ef-4fce-a00c-21a546b5491d',
+ safari_web_id: 'web.onesignal.auto.017d7a1b-f1ef-4fce-a00c-21a546b5491d',
outcomes: {
direct: {
enabled: true,
@@ -447,11 +443,9 @@ export default class TestContext {
persistNotification: false,
webhooks: {
cors: true,
- 'notification.willDisplay':
- 'https://fake-config.com/notification-displayed',
+ 'notification.willDisplay': 'https://fake-config.com/notification-displayed',
'notification.clicked': 'https://fake-config.com/notification-clicked',
- 'notification.dismissed':
- 'https://fake-config.com/notification-dismissed',
+ 'notification.dismissed': 'https://fake-config.com/notification-dismissed',
},
notificationClickHandlerMatch: NotificationClickMatchBehavior._Origin,
notificationClickHandlerAction: NotificationClickActionBehavior._Focus,
diff --git a/__test__/support/environment/TestEnvironment.ts b/__test__/support/environment/TestEnvironment.ts
index c52bc1657..082e807a7 100644
--- a/__test__/support/environment/TestEnvironment.ts
+++ b/__test__/support/environment/TestEnvironment.ts
@@ -6,6 +6,7 @@ import type {
ServerAppConfig,
} from 'src/shared/config/types';
import type { RecursivePartial } from 'src/shared/context/types';
+
import { updateIdentityModel, updatePropertiesModel } from '../helpers/setup';
import { initOSGlobals, stubNotification } from './TestEnvironmentHelpers';
diff --git a/__test__/support/environment/TestEnvironmentHelpers.ts b/__test__/support/environment/TestEnvironmentHelpers.ts
index 043b7e239..4c7ee7086 100644
--- a/__test__/support/environment/TestEnvironmentHelpers.ts
+++ b/__test__/support/environment/TestEnvironmentHelpers.ts
@@ -3,6 +3,7 @@ import { SubscriptionModel } from 'src/core/models/SubscriptionModel';
import { ModelChangeTags } from 'src/core/types/models';
import { setPushToken } from 'src/shared/database/subscription';
import { SubscriptionType } from 'src/shared/subscriptions/constants';
+
import { CoreModuleDirector } from '../../../src/core/CoreModuleDirector';
import NotificationsNamespace from '../../../src/onesignal/NotificationsNamespace';
import OneSignal from '../../../src/onesignal/OneSignal';
@@ -36,9 +37,7 @@ export function initOSGlobals(config: TestEnvironmentConfig = {}) {
const userNamespace = new UserNamespace(!!config.initUserAndPushSubscription); // TO DO: pass in subscription, and permission
global.OneSignal.User = userNamespace;
- global.OneSignal.Notifications = new NotificationsNamespace(
- config.permission,
- );
+ global.OneSignal.Notifications = new NotificationsNamespace(config.permission);
return global.OneSignal;
}
diff --git a/__test__/support/helpers/api.ts b/__test__/support/helpers/api.ts
index 30321f1e8..5b703e99f 100644
--- a/__test__/support/helpers/api.ts
+++ b/__test__/support/helpers/api.ts
@@ -1,22 +1,18 @@
import type { IndexableByString } from 'src/page/slidedown/types';
+import { expect } from 'vite-plus/test';
+
import { ReaderManager } from '../managers/ReaderManager';
export function isAsyncFunction(fn: () => any): boolean {
const fnStr = fn.toString().trim();
- return !!(
- fnStr.startsWith('async ') ||
- fnStr.includes('await') ||
- fn instanceof Promise
- );
+ return !!(fnStr.startsWith('async ') || fnStr.includes('await') || fn instanceof Promise);
}
const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
const ARGUMENT_NAMES = /([^\s,]+)/g;
function getParamNames(func: () => unknown): null | string[] {
const fnStr = func.toString().replace(STRIP_COMMENTS, '');
- return fnStr
- .slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')'))
- .match(ARGUMENT_NAMES);
+ return fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
}
export const matchNestedProperties = (
@@ -33,19 +29,13 @@ export const matchNestedProperties = (
// Check if all properties are present in the SDK
for (const prop of nestedProperties) {
- const propertyDescriptor = Object.getOwnPropertyDescriptor(
- classPrototype,
- prop.name,
- );
+ const propertyDescriptor = Object.getOwnPropertyDescriptor(classPrototype, prop.name);
const isPropertyDefined =
propertyDescriptor &&
- (propertyDescriptor.value !== undefined ||
- propertyDescriptor.get !== undefined);
+ (propertyDescriptor.value !== undefined || propertyDescriptor.get !== undefined);
if (!isPropertyDefined) {
- throw new Error(
- `Property ${prop.name} for namespace ${namespaceName} not found`,
- );
+ throw new Error(`Property ${prop.name} for namespace ${namespaceName} not found`);
}
}
};
@@ -93,9 +83,7 @@ export const matchNestedFunctions = (
};
export const matchApiToSpec = async (parent: object, namespace: string) => {
- const rawJson = await ReaderManager.readFile(
- __dirname + '/../../../api.json',
- );
+ const rawJson = await ReaderManager.readFile(__dirname + '/../../../api.json');
const api = JSON.parse(rawJson);
matchNestedProperties(api, parent, namespace);
matchNestedNamespaces(api, parent, namespace);
diff --git a/__test__/support/helpers/configHelper.ts b/__test__/support/helpers/configHelper.ts
index 093d77ff7..16ccfde6d 100644
--- a/__test__/support/helpers/configHelper.ts
+++ b/__test__/support/helpers/configHelper.ts
@@ -1,6 +1,7 @@
import { getServerAppConfig } from 'src/shared/config/app';
import { ConfigIntegrationKind } from 'src/shared/config/constants';
import type { AppConfig, ServerAppConfig } from 'src/shared/config/types';
+
import TestContext from '../environment/TestContext';
/**
@@ -10,12 +11,8 @@ import TestContext from '../environment/TestContext';
* 2) `convertConfigToVersion2` - the resulting prompt options config should be config schema v2
* @param fakeUserConfig
*/
-export async function getFinalAppConfig(
- fakeUserConfig: any,
-): Promise {
- const fakeServerConfig = TestContext.getFakeServerAppConfig(
- ConfigIntegrationKind._Custom,
- );
+export async function getFinalAppConfig(fakeUserConfig: any): Promise {
+ const fakeServerConfig = TestContext.getFakeServerAppConfig(ConfigIntegrationKind._Custom);
fakeUserConfig.appId = fakeServerConfig.app_id;
const getFakeServerConfig = () =>
new Promise((resolve) => {
diff --git a/__test__/support/helpers/core.ts b/__test__/support/helpers/core.ts
index 019efe63d..59d05a6d7 100644
--- a/__test__/support/helpers/core.ts
+++ b/__test__/support/helpers/core.ts
@@ -1,5 +1,6 @@
import { SubscriptionModel } from 'src/core/models/SubscriptionModel';
import { SubscriptionType } from 'src/shared/subscriptions/constants';
+
import CoreModule from '../../../src/core/CoreModule';
import { CoreModuleDirector } from '../../../src/core/CoreModuleDirector';
diff --git a/__test__/support/helpers/general.ts b/__test__/support/helpers/general.ts
index 2f5e1f913..46874ffee 100644
--- a/__test__/support/helpers/general.ts
+++ b/__test__/support/helpers/general.ts
@@ -1,3 +1,4 @@
+import { vi } from 'vite-plus/test';
/**
* DON'T use with vi.useFakeTimers()
* Flushes promises within some window
diff --git a/__test__/support/helpers/requests.ts b/__test__/support/helpers/requests.ts
index efb254842..7e79b30e5 100644
--- a/__test__/support/helpers/requests.ts
+++ b/__test__/support/helpers/requests.ts
@@ -1,6 +1,8 @@
import { http, HttpResponse } from 'msw';
import type { ISubscription, IUserProperties } from 'src/core/types/api';
import type { NotificationIcons } from 'src/shared/notifications/types';
+import { vi } from 'vite-plus/test';
+
import { APP_ID, ONESIGNAL_ID, SUB_ID } from '../../constants';
import { server } from '../mocks/server';
@@ -8,14 +10,11 @@ import { server } from '../mocks/server';
// configs
export const mockPageStylesCss = () => {
server.use(
- http.get(
- 'https://onesignal.com/sdks/web/v16/OneSignalSDK.page.styles.css',
- () => {
- return new HttpResponse('/* CSS */', {
- headers: { 'Content-Type': 'text/css' },
- });
- },
- ),
+ http.get('https://onesignal.com/sdks/web/v16/OneSignalSDK.page.styles.css', () => {
+ return new HttpResponse('/* CSS */', {
+ headers: { 'Content-Type': 'text/css' },
+ });
+ }),
);
};
@@ -46,9 +45,7 @@ export const getHandler = ({
return HttpResponse.json(response, {
status,
- headers: retryAfter
- ? { 'Retry-After': retryAfter?.toString() }
- : undefined,
+ headers: retryAfter ? { 'Retry-After': retryAfter?.toString() } : undefined,
});
}),
);
@@ -62,9 +59,7 @@ const getDeleteAliasUri = (onesignalId: string = ONESIGNAL_ID) =>
`**/apps/${APP_ID}/users/by/onesignal_id/${onesignalId}/identity/*`;
export const addAliasFn = vi.fn();
-export const setAddAliasResponse = ({
- onesignalId,
-}: { onesignalId?: string } = {}) =>
+export const setAddAliasResponse = ({ onesignalId }: { onesignalId?: string } = {}) =>
getHandler({
uri: getSetAliasUri(onesignalId),
method: 'patch',
@@ -88,9 +83,7 @@ export const setAddAliasError = ({
});
export const deleteAliasFn = vi.fn();
-export const setDeleteAliasResponse = ({
- onesignalId,
-}: { onesignalId?: string } = {}) =>
+export const setDeleteAliasResponse = ({ onesignalId }: { onesignalId?: string } = {}) =>
getHandler({
uri: getDeleteAliasUri(onesignalId),
method: 'delete',
@@ -332,8 +325,7 @@ export const setCreateUserError = ({
}: {
status: number;
retryAfter?: number;
-}) =>
- getHandler({ uri: getCreateUserUri(), method: 'post', status, retryAfter });
+}) => getHandler({ uri: getCreateUserUri(), method: 'post', status, retryAfter });
// update user
export const updateUserFn = vi.fn();
diff --git a/__test__/support/helpers/sdkVersion.ts b/__test__/support/helpers/sdkVersion.ts
index 89a428884..970c07b4c 100644
--- a/__test__/support/helpers/sdkVersion.ts
+++ b/__test__/support/helpers/sdkVersion.ts
@@ -1,11 +1,10 @@
+import { vi, expect } from 'vite-plus/test';
export function expectHeaderToBeSent() {
vi.mocked(window.fetch).mock.calls.forEach((params) => {
expect(typeof params[0]).toBe('string');
const requestInit = params[1] as RequestInit;
const headers = requestInit.headers as Headers;
- expect(headers.get('sdk-version')).toMatch(
- new RegExp(/^onesignal\/web\/[0-9]{6}$/),
- );
+ expect(headers.get('sdk-version')).toMatch(new RegExp(/^onesignal\/web\/[0-9]{6}$/));
});
}
diff --git a/__test__/support/helpers/setup.ts b/__test__/support/helpers/setup.ts
index f030a43bf..e376609d4 100644
--- a/__test__/support/helpers/setup.ts
+++ b/__test__/support/helpers/setup.ts
@@ -11,6 +11,7 @@ import type {
SubscriptionSchema,
} from 'src/shared/database/types';
import { RawPushSubscription } from 'src/shared/models/RawPushSubscription';
+import { vi } from 'vite-plus/test';
export const setIsPushEnabled = async (isPushEnabled: boolean) => {
await db.put('Options', { key: 'isPushEnabled', value: isPushEnabled });
@@ -68,9 +69,7 @@ export const getDbSubscriptions = async (length: number) => {
/**
* Update identity model but not trigger action to trigger api call.
*/
-export const setupIdentityModel = async (
- onesignalID: string = ONESIGNAL_ID,
-) => {
+export const setupIdentityModel = (onesignalID: string = ONESIGNAL_ID) => {
const newIdentityModel = new IdentityModel();
newIdentityModel._onesignalId = onesignalID;
OneSignal._coreDirector._identityModelStore._replace(
@@ -82,9 +81,7 @@ export const setupIdentityModel = async (
/**
* Update properties model but not trigger action to trigger api call.
*/
-export const setupPropertiesModel = async (
- onesignalID: string = ONESIGNAL_ID,
-) => {
+export const setupPropertiesModel = async (onesignalID: string = ONESIGNAL_ID) => {
const newPropertiesModel = new PropertiesModel();
newPropertiesModel._onesignalId = onesignalID;
OneSignal._coreDirector._propertiesModelStore._replace(
@@ -99,9 +96,7 @@ export const setupPropertiesModel = async (
/**
* Update identity model but not trigger action to trigger api call.
*/
-export const updateIdentityModel = async <
- T extends keyof IdentitySchema & string,
->(
+export const updateIdentityModel = (
property: T,
value?: IdentitySchema[T],
) => {
@@ -112,7 +107,7 @@ export const updateIdentityModel = async <
/**
* Update properties model but not trigger action to trigger api call.
*/
-export const updatePropertiesModel = async <
+export const updatePropertiesModel = <
T extends Exclude<
keyof PropertiesSchema,
'modelId' | 'modelName' | 'first_active' | 'last_active'
@@ -128,10 +123,7 @@ export const updatePropertiesModel = async <
/**
* Update subscription model but not trigger action to trigger api call.
*/
-export const setupSubscriptionModel = async (
- id: string | undefined,
- token: string | undefined,
-) => {
+export const setupSubscriptionModel = (id: string | undefined, token: string | undefined) => {
const subscriptionModel = new SubscriptionModel();
subscriptionModel.id = id || '';
subscriptionModel.token = token || '';
@@ -144,11 +136,10 @@ export const setupSubscriptionModel = async (
/**
* In case some action triggers a call to loadSdkStylesheet, we need to mock it.
*/
-export const setupLoadStylesheet = async () => {
- vi.spyOn(
- OneSignal._context._dynamicResourceLoader,
- '_loadSdkStylesheet',
- ).mockResolvedValue(ResourceLoadState._Loaded);
+export const setupLoadStylesheet = () => {
+ vi.spyOn(OneSignal._context._dynamicResourceLoader, '_loadSdkStylesheet').mockResolvedValue(
+ ResourceLoadState._Loaded,
+ );
};
export const getRawPushSubscription = () => {
diff --git a/__test__/support/mocks/MockNotification.ts b/__test__/support/mocks/MockNotification.ts
index 08b26f76d..314759248 100644
--- a/__test__/support/mocks/MockNotification.ts
+++ b/__test__/support/mocks/MockNotification.ts
@@ -93,12 +93,12 @@ export default class MockNotification implements Notification {
_options?: boolean | EventListenerOptions,
): void {}
- static async requestPermission(
- callback?: NotificationPermissionCallback | undefined,
+ static requestPermission(
+ callback?: NotificationPermissionCallback,
): Promise {
if (callback) {
callback(MockNotification.permission);
}
- return MockNotification.permission;
+ return Promise.resolve(MockNotification.permission);
}
}
diff --git a/__test__/support/mocks/MockServiceWorker.ts b/__test__/support/mocks/MockServiceWorker.ts
index 69e91bf09..866cde023 100644
--- a/__test__/support/mocks/MockServiceWorker.ts
+++ b/__test__/support/mocks/MockServiceWorker.ts
@@ -1,3 +1,5 @@
+import { vi } from 'vite-plus/test';
+
import { PUSH_TOKEN } from '../../constants';
export const mockPushSubscription: PushSubscription = {
@@ -15,9 +17,7 @@ export const mockPushSubscription: PushSubscription = {
export const mockPushManager = {
permissionState: vi.fn().mockResolvedValue('granted'),
subscribe: vi.fn().mockResolvedValue(mockPushSubscription),
- getSubscription: vi
- .fn<() => Promise>()
- .mockResolvedValue(mockPushSubscription),
+ getSubscription: vi.fn<() => Promise>().mockResolvedValue(mockPushSubscription),
} satisfies PushManager;
const registration: Partial = {
diff --git a/__test__/support/utils/DispatchEventUtil.ts b/__test__/support/utils/DispatchEventUtil.ts
index 6c5ed17e5..90bfe512f 100644
--- a/__test__/support/utils/DispatchEventUtil.ts
+++ b/__test__/support/utils/DispatchEventUtil.ts
@@ -1,8 +1,7 @@
import type { EventHandler } from '../../../src/shared/libraries/Emitter';
export class DispatchEventUtil {
- private listeners: Map> =
- new Map();
+ private listeners: Map> = new Map();
public addEventListener(
type: string,
@@ -25,9 +24,11 @@ export class DispatchEventUtil {
if (!handlers) return false;
for (const handler of handlers) {
- const eventListenerObj = (handler as EventListenerObject).handleEvent;
- if (eventListenerObj) eventListenerObj(evt);
- else (handler as EventHandler)(evt);
+ if (typeof handler === 'function') {
+ handler(evt);
+ } else {
+ handler.handleEvent(evt);
+ }
}
return true;
}
diff --git a/__test__/support/utils/Random.ts b/__test__/support/utils/Random.ts
deleted file mode 100644
index 08f03c2c6..000000000
--- a/__test__/support/utils/Random.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-export default class Random {
- /**
- * Generates a random string of the specified length with the allowed characters.
- * @param length The length of the random string.
- * @param characterSet A string of characters to allow. Each character of the random string will
- * be one character of this set chosen at random.
- */
- public static getRandomString(
- length: number,
- characterSet = 'abcdefghijklmnopqrstuvwxyz0123456789',
- ) {
- return this.getRandomArray(length, characterSet.length, 0)
- .map((n) => characterSet[n])
- .join('');
- }
-
- public static getRandomNumber(length: number): number {
- return Number(Random.getRandomArray(length, 10, 0).join(''));
- }
-
- public static getRandomUint8Array(length: number) {
- return new Uint8Array(Random.getRandomArray(length, 255, 0));
- }
-
- public static getRandomArray(
- length: number,
- exclusiveMax: number,
- inclusiveMin: number,
- ) {
- return new Array(length)
- .fill(0)
- .map(() =>
- Math.floor(
- Math.random() * (exclusiveMax - inclusiveMin) + inclusiveMin,
- ),
- );
- }
-}
diff --git a/__test__/unit/api/apiJson.test.ts b/__test__/unit/api/apiJson.test.ts
index c420d452b..42cc3249d 100644
--- a/__test__/unit/api/apiJson.test.ts
+++ b/__test__/unit/api/apiJson.test.ts
@@ -1,3 +1,5 @@
+import { describe, test } from 'vite-plus/test';
+
import OneSignal from '../../../src/onesignal/OneSignal';
import { matchApiToSpec } from '../../support/helpers/api';
diff --git a/__test__/unit/core/coreModuleDirector.test.ts b/__test__/unit/core/coreModuleDirector.test.ts
index a7cfdc236..2b5562e48 100644
--- a/__test__/unit/core/coreModuleDirector.test.ts
+++ b/__test__/unit/core/coreModuleDirector.test.ts
@@ -1,9 +1,8 @@
+import { describe, test, expect, beforeEach, vi } from 'vite-plus/test';
+
import { CoreModuleDirector } from '../../../src/core/CoreModuleDirector';
import { TestEnvironment } from '../../support/environment/TestEnvironment';
-import {
- generateNewSubscription,
- getCoreModuleDirector,
-} from '../../support/helpers/core';
+import { generateNewSubscription, getCoreModuleDirector } from '../../support/helpers/core';
describe('CoreModuleDirector tests', () => {
beforeEach(() => {
diff --git a/__test__/unit/events/eventsUnique.test.ts b/__test__/unit/events/eventsUnique.test.ts
index d7dd50845..eed1f1f49 100644
--- a/__test__/unit/events/eventsUnique.test.ts
+++ b/__test__/unit/events/eventsUnique.test.ts
@@ -1,3 +1,5 @@
+import { test, expect } from 'vite-plus/test';
+
import { ONESIGNAL_EVENTS } from '../../../src/onesignal/OneSignalEvents';
test('Test uniqueness of OneSignal event names', () => {
diff --git a/__test__/unit/http/sdkVersion.test.ts b/__test__/unit/http/sdkVersion.test.ts
index ebefea0db..408d75afd 100644
--- a/__test__/unit/http/sdkVersion.test.ts
+++ b/__test__/unit/http/sdkVersion.test.ts
@@ -13,6 +13,8 @@ import {
updateSubscriptionById,
updateUserByAlias,
} from 'src/core/requests/api';
+import { describe, test, beforeAll } from 'vite-plus/test';
+
import { expectHeaderToBeSent } from '../../support/helpers/sdkVersion';
describe('Sdk Version Header Tests', () => {
@@ -20,12 +22,12 @@ describe('Sdk Version Header Tests', () => {
test('POST /users: SDK-Version header is sent', () => {
// @ts-expect-error - partial identity object
- createNewUser({ appId: APP_ID }, {});
+ void createNewUser({ appId: APP_ID }, {});
expectHeaderToBeSent();
});
test('POST /users: header is sent', () => {
- createNewUser(
+ void createNewUser(
{ appId: APP_ID },
// @ts-expect-error - partial identity object
{ refresh_device_metadata: true },
@@ -34,7 +36,7 @@ describe('Sdk Version Header Tests', () => {
});
test('POST /users: header is sent with subscription id', () => {
- createNewUser(
+ void createNewUser(
{ appId: APP_ID, subscriptionId: SUB_ID },
// @ts-expect-error - partial identity object
{},
@@ -43,7 +45,7 @@ describe('Sdk Version Header Tests', () => {
});
test('GET /users/by//: header is sent', () => {
- getUserByAlias(
+ void getUserByAlias(
{ appId: APP_ID },
{
label: IdentityConstants._ExternalID,
@@ -54,7 +56,7 @@ describe('Sdk Version Header Tests', () => {
});
test('PATCH /users/by//: header is sent', () => {
- updateUserByAlias(
+ void updateUserByAlias(
{ appId: APP_ID },
{
label: IdentityConstants._ExternalID,
@@ -66,7 +68,7 @@ describe('Sdk Version Header Tests', () => {
});
test('PATCH /users/by//: header is sent with subscription id', () => {
- updateUserByAlias(
+ void updateUserByAlias(
{ appId: APP_ID, subscriptionId: SUB_ID },
{
label: IdentityConstants._ExternalID,
@@ -78,7 +80,7 @@ describe('Sdk Version Header Tests', () => {
});
test('DELETE /users/by//: header is sent', () => {
- deleteUserByAlias(
+ void deleteUserByAlias(
{ appId: APP_ID },
{
label: IdentityConstants._ExternalID,
@@ -89,7 +91,7 @@ describe('Sdk Version Header Tests', () => {
});
test('POST /users/by///subscription: header is sent', () => {
- createSubscriptionByAlias(
+ void createSubscriptionByAlias(
{ appId: APP_ID },
{
label: IdentityConstants._ExternalID,
@@ -104,7 +106,7 @@ describe('Sdk Version Header Tests', () => {
});
test('GET /users/by///identity: header is sent', () => {
- getUserIdentity(
+ void getUserIdentity(
{ appId: APP_ID },
{
label: IdentityConstants._ExternalID,
@@ -115,7 +117,7 @@ describe('Sdk Version Header Tests', () => {
});
test('DELETE /users/by///identity/: header is sent', () => {
- deleteAlias(
+ void deleteAlias(
{ appId: APP_ID },
{
label: IdentityConstants._ExternalID,
@@ -127,7 +129,7 @@ describe('Sdk Version Header Tests', () => {
});
test('PATCH /subscriptions/: header is sent', () => {
- updateSubscriptionById(
+ void updateSubscriptionById(
{ appId: APP_ID },
EXTERNAL_ID,
// @ts-expect-error - partial identity object
@@ -137,7 +139,7 @@ describe('Sdk Version Header Tests', () => {
});
test('DELETE /subscriptions/: header is sent', () => {
- deleteSubscriptionById({ appId: APP_ID }, EXTERNAL_ID);
+ void deleteSubscriptionById({ appId: APP_ID }, EXTERNAL_ID);
expectHeaderToBeSent();
});
});
diff --git a/__test__/unit/models/path.test.ts b/__test__/unit/models/path.test.ts
index b84c0e36b..5728ed184 100644
--- a/__test__/unit/models/path.test.ts
+++ b/__test__/unit/models/path.test.ts
@@ -1,3 +1,5 @@
+import { describe, test, expect } from 'vite-plus/test';
+
import Path from '../../../src/shared/models/Path';
describe('Path tests', () => {
@@ -10,9 +12,7 @@ describe('Path tests', () => {
test(`should return correct components for a file-based path`, () => {
const path = new Path('file:///c:/web-folder/assets/service-worker.js');
expect(path._getFileName()).toBe('service-worker.js');
- expect(path._getFullPath()).toBe(
- 'file:///c:/web-folder/assets/service-worker.js',
- );
+ expect(path._getFullPath()).toBe('file:///c:/web-folder/assets/service-worker.js');
});
test(`should return case-sensitive correct components for a file-based path`, () => {
@@ -24,9 +24,7 @@ describe('Path tests', () => {
test(`should return correct components for a double-extension path`, () => {
const path = new Path('/web-folder/assets/service-worker.js.php');
expect(path._getFileName()).toBe('service-worker.js.php');
- expect(path._getFullPath()).toBe(
- '/web-folder/assets/service-worker.js.php',
- );
+ expect(path._getFullPath()).toBe('/web-folder/assets/service-worker.js.php');
});
test(`should return correct components for a root-relative path`, () => {
@@ -38,24 +36,16 @@ describe('Path tests', () => {
test(`should return correct components for an absolute web path`, () => {
const path = new Path('https://site.com/web-folder/service-worker.js');
expect(path._getFileName()).toBe('service-worker.js');
- expect(path._getFullPath()).toBe(
- 'https://site.com/web-folder/service-worker.js',
- );
+ expect(path._getFullPath()).toBe('https://site.com/web-folder/service-worker.js');
});
test('should include query string in full path', () => {
- const path = new Path(
- 'https://site.com/web-folder/service-worker.js?appId=12345',
- );
- expect(path._getFullPath()).toBe(
- 'https://site.com/web-folder/service-worker.js?appId=12345',
- );
+ const path = new Path('https://site.com/web-folder/service-worker.js?appId=12345');
+ expect(path._getFullPath()).toBe('https://site.com/web-folder/service-worker.js?appId=12345');
});
test(`should not include query string in path filename`, () => {
- const path = new Path(
- 'https://site.com/web-folder/service-worker.js?appId=12345',
- );
+ const path = new Path('https://site.com/web-folder/service-worker.js?appId=12345');
expect(path._getFileName()).toBe('service-worker.js');
});
});
diff --git a/__test__/unit/push/registerForPush.test.ts b/__test__/unit/push/registerForPush.test.ts
index 68978fcc7..038877a10 100644
--- a/__test__/unit/push/registerForPush.test.ts
+++ b/__test__/unit/push/registerForPush.test.ts
@@ -1,3 +1,5 @@
+import { describe, test, expect, beforeEach, afterEach, vi } from 'vite-plus/test';
+
import * as InitHelper from '../../../src/shared/helpers/init';
import OneSignalEvent from '../../../src/shared/services/OneSignalEvent';
import { TestEnvironment } from '../../support/environment/TestEnvironment';
@@ -43,9 +45,7 @@ describe('Register for push', () => {
global.OneSignal._initialized = true;
global.OneSignal._initCalled = false;
- await expect(InitHelper.registerForPushNotifications()).resolves.toBe(
- false,
- );
+ await expect(InitHelper.registerForPushNotifications()).resolves.toBe(false);
expect(spy).toHaveBeenCalledTimes(1);
});
});
diff --git a/__test__/unit/pushSubscription/nativePermissionChange.test.ts b/__test__/unit/pushSubscription/nativePermissionChange.test.ts
index 4f6de8876..45f047ed1 100644
--- a/__test__/unit/pushSubscription/nativePermissionChange.test.ts
+++ b/__test__/unit/pushSubscription/nativePermissionChange.test.ts
@@ -1,10 +1,4 @@
-import {
- PUSH_TOKEN,
- PUSH_TOKEN_2,
- SUB_ID,
- SUB_ID_2,
- SUB_ID_3,
-} from '__test__/constants';
+import { PUSH_TOKEN, PUSH_TOKEN_2, SUB_ID, SUB_ID_2, SUB_ID_3 } from '__test__/constants';
import { TestEnvironment } from '__test__/support/environment/TestEnvironment';
import { createPushSub } from '__test__/support/environment/TestEnvironmentHelpers';
import { MockServiceWorker } from '__test__/support/mocks/MockServiceWorker';
@@ -15,12 +9,10 @@ import { checkAndTriggerNotificationPermissionChanged } from 'src/shared/helpers
import * as PermissionUtils from 'src/shared/helpers/permissions';
import Emitter from 'src/shared/libraries/Emitter';
import { checkAndTriggerSubscriptionChanged } from 'src/shared/listeners';
+import { describe, test, expect, beforeEach, afterEach, vi } from 'vite-plus/test';
vi.mock('src/shared/libraries/Log');
-const triggerNotificationSpy = vi.spyOn(
- PermissionUtils,
- 'triggerNotificationPermissionChanged',
-);
+const triggerNotificationSpy = vi.spyOn(PermissionUtils, 'triggerNotificationPermissionChanged');
describe('Notification Types are set correctly on subscription change', () => {
beforeEach(() => {
@@ -61,10 +53,7 @@ describe('Notification Types are set correctly on subscription change', () => {
const permChangeStringListener = vi.fn();
const permChangeListener = vi.fn();
- OneSignal.Notifications.addEventListener(
- 'permissionChange',
- permChangeListener,
- );
+ OneSignal.Notifications.addEventListener('permissionChange', permChangeListener);
OneSignal.Notifications.addEventListener(
// @ts-expect-error - we dont expose it in the types
@@ -75,16 +64,14 @@ describe('Notification Types are set correctly on subscription change', () => {
await checkAndTriggerNotificationPermissionChanged();
// should update the db
- const dbPermission = await getOptionsValue(
- 'notificationPermission',
- );
+ const dbPermission = await getOptionsValue('notificationPermission');
expect(dbPermission).toBe('granted');
expect(permChangeListener).toHaveBeenCalledWith(true);
expect(permChangeStringListener).toHaveBeenCalledWith('granted');
});
});
- describe('checkAndTriggerSubscriptionChanged', async () => {
+ describe('checkAndTriggerSubscriptionChanged', () => {
const setAppState = async (appState: Partial) => {
const currentAppState = (await getOptionsValue('appState'))!;
await setDBAppState({
diff --git a/__test__/unit/user/user.test.ts b/__test__/unit/user/user.test.ts
index a0554938b..c52234ef3 100644
--- a/__test__/unit/user/user.test.ts
+++ b/__test__/unit/user/user.test.ts
@@ -1,3 +1,5 @@
+import { describe, test, expect, vi } from 'vite-plus/test';
+
import User from '../../../src/onesignal/User';
import { TestEnvironment } from '../../support/environment/TestEnvironment';
diff --git a/api.json b/api.json
index 6165e07bb..0a1d9cd91 100644
--- a/api.json
+++ b/api.json
@@ -50,7 +50,7 @@
},
{
"name": "setConsentRequired",
- "isAsync": true,
+ "isAsync": false,
"args": [
{
"name": "requiresConsent",
@@ -58,7 +58,7 @@
"optional": false
}
],
- "returnType": "Promise"
+ "returnType": "void"
}
],
"namespaces": ["Slidedown", "Notifications", "Session", "User", "Debug"]
diff --git a/build/scripts/validate.js b/build/scripts/validate.js
index 9256bce7c..7143ea363 100644
--- a/build/scripts/validate.js
+++ b/build/scripts/validate.js
@@ -1,7 +1,8 @@
#!/usr/bin/env node
-import { indexedDB } from 'fake-indexeddb';
-import 'fake-indexeddb/auto';
import { readFileSync } from 'fs';
+
+import 'fake-indexeddb/auto';
+import { indexedDB } from 'fake-indexeddb';
import { JSDOM } from 'jsdom';
const loadJson = (path) => JSON.parse(readFileSync(path, 'utf-8'));
@@ -40,9 +41,7 @@ const validateNamespace = (obj, spec, apiSpec, path = 'OneSignal') => {
});
spec.properties?.forEach(({ name }) => {
- const exists =
- name in obj ||
- Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), name);
+ const exists = name in obj || Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), name);
if (exists) {
if (SHOW_VERBOSE) console.log(`โ ${path}.${name}`);
} else {
@@ -56,12 +55,7 @@ const validateNamespace = (obj, spec, apiSpec, path = 'OneSignal') => {
const nestedSpec = apiSpec[name];
if (nestedSpec) {
- const nestedErrors = validateNamespace(
- obj[name],
- nestedSpec,
- apiSpec,
- `${path}.${name}`,
- );
+ const nestedErrors = validateNamespace(obj[name], nestedSpec, apiSpec, `${path}.${name}`);
errors.push(...nestedErrors);
}
} else {
@@ -76,10 +70,7 @@ const validateBundle = async () => {
console.log('๐ Validating OneSignal bundle...\n');
const apiSpec = loadJson('api.json');
- const bundle = readFileSync(
- 'build/releases/OneSignalSDK.page.es6.js',
- 'utf-8',
- );
+ const bundle = readFileSync('build/releases/OneSignalSDK.page.es6.js', 'utf-8');
const window = setupEnvironment();
const script = window.document.createElement('script');
@@ -90,11 +81,7 @@ const validateBundle = async () => {
if (!window.OneSignal) throw new Error('OneSignal not found');
- const errors = validateNamespace(
- window.OneSignal,
- apiSpec.OneSignal,
- apiSpec,
- );
+ const errors = validateNamespace(window.OneSignal, apiSpec.OneSignal, apiSpec);
if (errors.length > 0) {
console.log('โ Validation failures:');
diff --git a/docker-compose.yml b/docker-compose.yml
index ce1a20a86..363b0cdaa 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,19 +1,19 @@
services:
onesignal-web-sdk-dev:
- image: onesignal/web-sdk-dev
- container_name: web-sdk-dev
- build: .
- volumes:
- - .:/sdk:cached
- - /sdk/node_modules
- - /sdk/preview/node_modules
- - ./build/releases:/sdk/build/releases
- ports:
- - published: 4001
- target: 4001
- - published: 4002
- target: 4002
- command: /bin/sh -c "./docker/docker-entry-point.sh"
+ image: onesignal/web-sdk-dev
+ container_name: web-sdk-dev
+ build: .
+ volumes:
+ - .:/sdk:cached
+ - /sdk/node_modules
+ - /sdk/preview/node_modules
+ - ./build/releases:/sdk/build/releases
+ ports:
+ - published: 4001
+ target: 4001
+ - published: 4002
+ target: 4002
+ command: /bin/sh -c "./docker/docker-entry-point.sh"
# Named volumes that are persisted between docker-compose rebuilds.
# If you need to remove these volumes for some reason, run `docker-compose down -v`
volumes:
diff --git a/index.html b/index.html
index ffe986662..707590647 100644
--- a/index.html
+++ b/index.html
@@ -18,8 +18,7 @@
max-width: 350px;
z-index: 10000;
animation: slideIn 0.3s ease-out;
- font-family:
- -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.in-app-notification h4 {
margin: 0 0 8px 0;
@@ -83,9 +82,7 @@