diff --git a/.buildkite/basic/browser-pipeline.yml b/.buildkite/basic/browser-pipeline.yml index 9501b414ce..49962e10bc 100644 --- a/.buildkite/basic/browser-pipeline.yml +++ b/.buildkite/basic/browser-pipeline.yml @@ -50,7 +50,7 @@ steps: # - label: ":browserstack: {{matrix}} non-https tests" matrix: - # - ios_11 Skipped pending PLAT-14437 + - ios_11 - safari_16 depends_on: "browser-maze-runner-bs" timeout_in_minutes: 30 @@ -82,7 +82,7 @@ steps: - edge_17 - safari_10 - ios_15 - - android_8 + - android_9 - chrome_43 - chrome_72 - firefox_78 @@ -109,7 +109,6 @@ steps: concurrency_group: "browserstack" concurrency_method: eager - # # BitBar tests # @@ -144,31 +143,31 @@ steps: concurrency_group: "bitbar" concurrency_method: eager - # Uncomment the following block to enable IE11 tests on BitBar - # - label: ":bitbar: ie_11 Browser tests" - # depends_on: "browser-maze-runner-bb" - # timeout_in_minutes: 30 - # plugins: - # docker-compose#v4.12.0: - # pull: browser-maze-runner-bb - # run: browser-maze-runner-bb - # service-ports: true - # use-aliases: true - # command: - # - "--farm=bb" - # - "--browser=ie_11" - # - "--no-tunnel" - # - "--aws-public-ip" - # artifacts#v1.5.0: - # upload: - # - "./test/browser/maze_output/failed/**/*" - # test-collector#v1.10.2: - # files: "reports/TEST-*.xml" - # format: "junit" - # branch: "^main|next$$" - # api-token-env-name: "BROWSER_BUILDKITE_ANALYTICS_TOKEN" - # concurrency: 25 - # concurrency_group: "bitbar" - # concurrency_method: eager - # env: - # HOST: "localhost" # IE11 needs the host set to localhost for some reason + - label: ":bitbar: ie_11 Browser tests" + skip: true # Skipped due to incompatibility + depends_on: "browser-maze-runner-bb" + timeout_in_minutes: 30 + plugins: + docker-compose#v4.12.0: + pull: browser-maze-runner-bb + run: browser-maze-runner-bb + service-ports: true + use-aliases: true + command: + - "--farm=bb" + - "--browser=ie_11" + - "--no-tunnel" + - "--aws-public-ip" + artifacts#v1.5.0: + upload: + - "./test/browser/maze_output/failed/**/*" + test-collector#v1.10.2: + files: "reports/TEST-*.xml" + format: "junit" + branch: "^main|next$$" + api-token-env-name: "BROWSER_BUILDKITE_ANALYTICS_TOKEN" + concurrency: 25 + concurrency_group: "bitbar" + concurrency_method: eager + env: + HOST: "localhost" # IE11 needs the host set to localhost diff --git a/.buildkite/basic/expo-pipeline.yml b/.buildkite/basic/expo-pipeline.yml index 79c1e71b15..80ab7586b8 100644 --- a/.buildkite/basic/expo-pipeline.yml +++ b/.buildkite/basic/expo-pipeline.yml @@ -8,29 +8,29 @@ steps: depends_on: "publish-js" trigger: "bugsnag-expo" build: - branch: "v53/next" + branch: "v54/next" env: BUGSNAG_JS_BRANCH: "${BUILDKITE_BRANCH}" BUGSNAG_JS_COMMIT: "${BUILDKITE_COMMIT}" # a branch name that's safe to use as a docker cache identifier BUGSNAG_JS_CACHE_SAFE_BRANCH_NAME: "${BRANCH_NAME}" - - label: "@bugsnag/expo v52/next" + - label: "@bugsnag/expo v53/next" depends_on: "publish-js" trigger: "bugsnag-expo" build: - branch: "v52/next" + branch: "v53/next" env: BUGSNAG_JS_BRANCH: "${BUILDKITE_BRANCH}" BUGSNAG_JS_COMMIT: "${BUILDKITE_COMMIT}" # a branch name that's safe to use as a docker cache identifier BUGSNAG_JS_CACHE_SAFE_BRANCH_NAME: "${BRANCH_NAME}" - - label: "@bugsnag/expo v51/next" + - label: "@bugsnag/expo v52/next" depends_on: "publish-js" trigger: "bugsnag-expo" build: - branch: "v51/next" + branch: "v52/next" env: BUGSNAG_JS_BRANCH: "${BUILDKITE_BRANCH}" BUGSNAG_JS_COMMIT: "${BUILDKITE_COMMIT}" diff --git a/.buildkite/basic/react-native-android-full-pipeline.yml b/.buildkite/basic/react-native-android-full-pipeline.yml index 2148c45aeb..a46747f7e7 100644 --- a/.buildkite/basic/react-native-android-full-pipeline.yml +++ b/.buildkite/basic/react-native-android-full-pipeline.yml @@ -74,6 +74,7 @@ steps: - "0.79" - label: ':android: Build react-native-navigation {{matrix}} test fixture APK (Old Arch)' + skip: true # Skipped pending PLAT-15027 key: "build-react-native-navigation-android-fixture-old-arch" timeout_in_minutes: 30 agents: @@ -98,6 +99,7 @@ steps: limit: 1 - label: ':android: Build react-native-navigation {{matrix}} test fixture APK (New Arch)' + skip: true # Skipped pending PLAT-15027 key: "build-react-native-navigation-android-fixture-new-arch" timeout_in_minutes: 30 agents: @@ -216,6 +218,7 @@ steps: - "0.79" - label: ":bitbar: :android: react-native-navigation {{matrix}} Android 12 (Old Arch) end-to-end tests" + skip: true # Skipped pending PLAT-15027 depends_on: "build-react-native-navigation-android-fixture-old-arch" timeout_in_minutes: 10 plugins: @@ -257,6 +260,7 @@ steps: - "0.72" - label: ":bitbar: :android: react-native-navigation {{matrix}} Android 12 (New Arch) end-to-end tests" + skip: true # Skipped pending PLAT-15027 depends_on: "build-react-native-navigation-android-fixture-new-arch" timeout_in_minutes: 10 plugins: diff --git a/.github/workflows/aws-lambda.yml b/.github/workflows/aws-lambda.yml index d15a168d1b..1e24dcfc37 100644 --- a/.github/workflows/aws-lambda.yml +++ b/.github/workflows/aws-lambda.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 - name: Install Ruby - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a with: ruby-version: '3.1' diff --git a/.github/workflows/branch-sync.yml b/.github/workflows/branch-sync.yml new file mode 100644 index 0000000000..9971d40edb --- /dev/null +++ b/.github/workflows/branch-sync.yml @@ -0,0 +1,26 @@ +name: Sync main to next +on: + push: + branches: [main] + +jobs: + sync: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Sync main to next + uses: bugsnag/github-action-branch-sync@v1 + with: + source-branch: main + target-branch: next + labels: automation + reviewers: ${{ secrets.AUTOMATION_REVIEWERS }} + team-reviewers: ${{ secrets.AUTOMATION_TEAM_REVIEWERS }} + github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3ad2509a1d..6f71998bd2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -47,7 +47,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3 + uses: github/codeql-action/init@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -61,7 +61,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3 + uses: github/codeql-action/autobuild@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 # â„šī¸ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -74,6 +74,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3 + uses: github/codeql-action/analyze@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c432b30f5f..7d50bbf326 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -68,7 +68,7 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@192325c86100d080feab897ff886c34abd4c83a3 # v3.30.3 + uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 with: sarif_file: results.sarif diff --git a/.github/workflows/test-electron.yml b/.github/workflows/test-electron.yml index d019f04070..b6cbaaefa9 100644 --- a/.github/workflows/test-electron.yml +++ b/.github/workflows/test-electron.yml @@ -30,7 +30,7 @@ jobs: if: ${{ !env.ACT }} run: | echo "::set-output name=dir::$(npm config get cache)" - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 + - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 id: npm-cache if: ${{ !env.ACT }} with: diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index c79454e136..c7b01021f5 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -40,7 +40,7 @@ jobs: - run: git submodule update --init --recursive - name: Install ruby - uses: ruby/setup-ruby@44511735964dcb71245e7e55f72539531f7bc0eb # v1.257.0 + uses: ruby/setup-ruby@0481980f17b760ef6bca5e8c55809102a0af1e5a # v1.263.0 with: ruby-version: 2.7 diff --git a/CHANGELOG.md b/CHANGELOG.md index 032b6f8d31..3fc93a8088 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,37 @@ # Changelog -## [Unreleased] +## [8.7.0] - 2025-10-13 + +### Added + +- (electron) Add `codeBundleId` config option to main process [#2577](https://github.com/bugsnag/bugsnag-js/pull/2577) + +### Changed + +- Update bugsnag-cocoa to [v6.34.0](https//github.com/bugsnag/bugsnag-cocoa/releases/tag/v6.34.0) [#2571](https://github.com/bugsnag/bugsnag-js/pull/2571) + +## [8.6.0] - 2025-09-25 + +### Added + +- Add additional grouping discriminator property to events [#2544](https://github.com/bugsnag/bugsnag-js/pull/2544) +- (react-native) Handle additional grouping discriminator [#2557](https://github.com/bugsnag/bugsnag-js/pull/2557) +- (electron) Handle additional grouping discriminator [#2561](https://github.com/bugsnag/bugsnag-js/pull/2561) ### Changed - Update bugsnag-cocoa to [v6.33.1](https//github.com/bugsnag/bugsnag-cocoa/releases/tag/v6.33.1) [#2552](https://github.com/bugsnag/bugsnag-js/pull/2552) - Update bugsnag-android to [v6.18.0](https//github.com/bugsnag/bugsnag-android/releases/tag/v6.18.0) [#2556](https://github.com/bugsnag/bugsnag-js/pull/2556) +- (core): Change `startsWith()` to `indexOf() === 0` to support older browsers [#2568](https://github.com/bugsnag/bugsnag-js/pull/2568) ### Fixed - (plugin-window-onerror) Guard against errors when trying to call previous handler [#2551](https://github.com/bugsnag/bugsnag-js/pull/2551) +### Dependencies + +Update bugsnag-cocoa to [v6.34.0](https//github.com/bugsnag/bugsnag-cocoa/releases/tag/v6.34.0) [#2571](https://github.com/bugsnag/bugsnag-js/pull/2571) + ## [8.5.0] - 2025-09-01 ### Added diff --git a/docker-compose.yml b/docker-compose.yml index d063053664..32fe9e7099 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -113,7 +113,7 @@ services: - ./reports/:/app/test/node/reports/ react-native-maze-runner: - image: 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v9-cli + image: 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v10-cli environment: <<: *common-environment BITBAR_USERNAME: @@ -137,7 +137,7 @@ services: - ./reports/:/app/reports react-native-cli-maze-runner: - image: 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v9-cli + image: 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v10-cli environment: <<: *common-environment BITBAR_USERNAME: diff --git a/dockerfiles/Dockerfile.browser b/dockerfiles/Dockerfile.browser index cf85642314..a14da2ecdb 100644 --- a/dockerfiles/Dockerfile.browser +++ b/dockerfiles/Dockerfile.browser @@ -64,7 +64,7 @@ RUN find . -name package.json -type f -mindepth 2 -maxdepth 3 ! -path "./node_mo RUN rm -fr **/*/node_modules/ # The maze-runner browser tests (W3C protocol) -FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v9-cli AS browser-maze-runner +FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v10-cli AS browser-maze-runner COPY --from=browser-feature-builder /app/test/browser /app/test/browser/ WORKDIR /app/test/browser diff --git a/dockerfiles/Dockerfile.node b/dockerfiles/Dockerfile.node index fefd5d3f34..757dfdb162 100644 --- a/dockerfiles/Dockerfile.node +++ b/dockerfiles/Dockerfile.node @@ -26,7 +26,7 @@ RUN npm pack --verbose packages/plugin-restify/ RUN npm pack --verbose packages/plugin-hono/ # The maze-runner node tests -FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v9-cli AS node-maze-runner +FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner-releases:latest-v10-cli as node-maze-runner WORKDIR /app/ COPY test/node/features test/node/features COPY --from=node-feature-builder /app/*.tgz ./ diff --git a/lerna.json b/lerna.json index daf0f13606..eac802f781 100644 --- a/lerna.json +++ b/lerna.json @@ -2,6 +2,6 @@ "packages": [ "packages/*" ], - "version": "8.5.0", + "version": "8.7.0", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6488ac64bc..876b3f526c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3955,9 +3955,9 @@ } }, "node_modules/@inquirer/ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.0.tgz", - "integrity": "sha512-JWaTfCxI1eTmJ1BIv86vUfjVatOdxwD0DAVKYevY8SazeUUZtW+tNbsdejVO1GYE0GXJW1N1ahmiC3TFd+7wZA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", + "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", "dev": true, "license": "MIT", "engines": { @@ -3965,15 +3965,15 @@ } }, "node_modules/@inquirer/core": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.2.2.tgz", - "integrity": "sha512-yXq/4QUnk4sHMtmbd7irwiepjB8jXU0kkFRL4nr/aDBA2mDz13cMakEWdDwX3eSCTkk03kwcndD1zfRAIlELxA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", + "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^1.0.0", - "@inquirer/figures": "^1.0.13", - "@inquirer/type": "^3.0.8", + "@inquirer/ansi": "^1.0.1", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", @@ -3993,9 +3993,9 @@ } }, "node_modules/@inquirer/core/node_modules/@inquirer/type": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", - "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", + "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", "dev": true, "license": "MIT", "engines": { @@ -44110,28 +44110,28 @@ }, "packages/browser": { "name": "@bugsnag/browser", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "devDependencies": { - "@bugsnag/delivery-xml-http-request": "^8.4.0", - "@bugsnag/plugin-app-duration": "^8.4.0", - "@bugsnag/plugin-browser-context": "^8.4.0", - "@bugsnag/plugin-browser-device": "^8.4.0", - "@bugsnag/plugin-browser-request": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0", - "@bugsnag/plugin-client-ip": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-inline-script-content": "^8.4.0", - "@bugsnag/plugin-interaction-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-navigation-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-simple-throttle": "^8.4.0", - "@bugsnag/plugin-strip-query-string": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0", + "@bugsnag/delivery-xml-http-request": "^8.6.0", + "@bugsnag/plugin-app-duration": "^8.6.0", + "@bugsnag/plugin-browser-context": "^8.6.0", + "@bugsnag/plugin-browser-device": "^8.6.0", + "@bugsnag/plugin-browser-request": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0", + "@bugsnag/plugin-client-ip": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-inline-script-content": "^8.6.0", + "@bugsnag/plugin-interaction-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-navigation-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-simple-throttle": "^8.6.0", + "@bugsnag/plugin-strip-query-string": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", "@rollup/plugin-node-resolve": "^16.0.0", @@ -44176,7 +44176,7 @@ }, "packages/core": { "name": "@bugsnag/core", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/cuid": "^3.0.0", @@ -44323,15 +44323,15 @@ }, "packages/delivery-electron": { "name": "@bugsnag/delivery-electron", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/json-payload": "^8.4.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-network-status": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-network-status": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0" }, "peerDependencies": { "@bugsnag/electron-network-status": "^8.0.0" @@ -44339,45 +44339,47 @@ }, "packages/delivery-fetch": { "name": "@bugsnag/delivery-fetch", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/json-payload": "^8.4.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" + }, + "peerDependencies": { + "@bugsnag/core": "^8.0.0" } }, "packages/delivery-node": { "name": "@bugsnag/delivery-node", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/json-payload": "^8.4.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "packages/delivery-react-native": { "name": "@bugsnag/delivery-react-native", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", - "devDependencies": { - "@bugsnag/core": "^8.4.0", + "dependencies": { "@bugsnag/derecursify": "^8.4.0" }, - "peerDependencies": { - "@bugsnag/core": "^8.0.0" + "devDependencies": { + "@bugsnag/core": "^8.6.0" } }, "packages/delivery-x-domain-request": { "name": "@bugsnag/delivery-x-domain-request", - "version": "8.4.0", + "version": "8.6.0", "extraneous": true, "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -44385,56 +44387,56 @@ }, "packages/delivery-xml-http-request": { "name": "@bugsnag/delivery-xml-http-request", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/json-payload": "^8.4.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "packages/derecursify": { "name": "@bugsnag/derecursify", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT" }, "packages/electron": { "name": "@bugsnag/electron", - "version": "8.5.0", + "version": "8.7.0", "license": "MIT", "dependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-electron": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-electron": "^8.6.0", "@bugsnag/electron-filestore": "^8.0.0", - "@bugsnag/electron-network-status": "^8.4.0", + "@bugsnag/electron-network-status": "^8.6.0", "@bugsnag/path-normalizer": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-electron-app": "^8.4.0", - "@bugsnag/plugin-electron-app-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0", - "@bugsnag/plugin-electron-client-state-persistence": "^8.4.0", - "@bugsnag/plugin-electron-deliver-minidumps": "^8.5.0", - "@bugsnag/plugin-electron-device": "^8.4.0", - "@bugsnag/plugin-electron-ipc": "^8.5.0", - "@bugsnag/plugin-electron-net-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-electron-network-status": "^8.4.0", - "@bugsnag/plugin-electron-preload-error": "^8.4.0", - "@bugsnag/plugin-electron-process-info": "^8.4.0", - "@bugsnag/plugin-electron-renderer-client-state-updates": "^8.4.0", - "@bugsnag/plugin-electron-renderer-event-data": "^8.4.0", - "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.4.0", - "@bugsnag/plugin-electron-session": "^8.4.0", - "@bugsnag/plugin-interaction-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-internal-callback-marker": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-node-surrounding-code": "^8.4.0", - "@bugsnag/plugin-node-uncaught-exception": "^8.4.0", - "@bugsnag/plugin-node-unhandled-rejection": "^8.4.0", - "@bugsnag/plugin-stackframe-path-normaliser": "^8.4.0", - "@bugsnag/plugin-strip-project-root": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0" + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-electron-app": "^8.7.0", + "@bugsnag/plugin-electron-app-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0", + "@bugsnag/plugin-electron-client-state-persistence": "^8.6.0", + "@bugsnag/plugin-electron-deliver-minidumps": "^8.6.0", + "@bugsnag/plugin-electron-device": "^8.6.0", + "@bugsnag/plugin-electron-ipc": "^8.7.0", + "@bugsnag/plugin-electron-net-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-electron-network-status": "^8.6.0", + "@bugsnag/plugin-electron-preload-error": "^8.6.0", + "@bugsnag/plugin-electron-process-info": "^8.6.0", + "@bugsnag/plugin-electron-renderer-client-state-updates": "^8.6.0", + "@bugsnag/plugin-electron-renderer-event-data": "^8.7.0", + "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.6.0", + "@bugsnag/plugin-electron-session": "^8.6.0", + "@bugsnag/plugin-interaction-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-internal-callback-marker": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-node-surrounding-code": "^8.6.0", + "@bugsnag/plugin-node-uncaught-exception": "^8.6.0", + "@bugsnag/plugin-node-unhandled-rejection": "^8.6.0", + "@bugsnag/plugin-stackframe-path-normaliser": "^8.6.0", + "@bugsnag/plugin-strip-project-root": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0" } }, "packages/electron-filestore": { @@ -44444,11 +44446,11 @@ }, "packages/electron-network-status": { "name": "@bugsnag/electron-network-status", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -44456,21 +44458,21 @@ }, "packages/electron-test-helpers": { "name": "@bugsnag/electron-test-helpers", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "packages/in-flight": { "name": "@bugsnag/in-flight", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/cuid": "^3.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -44478,11 +44480,11 @@ }, "packages/js": { "name": "@bugsnag/js", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { - "@bugsnag/browser": "^8.4.0", - "@bugsnag/node": "^8.4.0" + "@bugsnag/browser": "^8.6.0", + "@bugsnag/node": "^8.6.0" }, "devDependencies": { "@babel/cli": "^7.0.0" @@ -44543,29 +44545,29 @@ }, "packages/node": { "name": "@bugsnag/node", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "byline": "^5.0.0", "error-stack-parser": "^2.0.3", "pump": "^3.0.0", "stack-generator": "^2.0.3" }, "devDependencies": { - "@bugsnag/delivery-node": "^8.4.0", - "@bugsnag/plugin-app-duration": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-contextualize": "^8.4.0", - "@bugsnag/plugin-intercept": "^8.4.0", - "@bugsnag/plugin-node-device": "^8.4.0", - "@bugsnag/plugin-node-in-project": "^8.4.0", - "@bugsnag/plugin-node-surrounding-code": "^8.4.0", - "@bugsnag/plugin-node-uncaught-exception": "^8.4.0", - "@bugsnag/plugin-node-unhandled-rejection": "^8.4.0", - "@bugsnag/plugin-server-session": "^8.4.0", - "@bugsnag/plugin-stackframe-path-normaliser": "^8.4.0", - "@bugsnag/plugin-strip-project-root": "^8.4.0", + "@bugsnag/delivery-node": "^8.6.0", + "@bugsnag/plugin-app-duration": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-contextualize": "^8.6.0", + "@bugsnag/plugin-intercept": "^8.6.0", + "@bugsnag/plugin-node-device": "^8.6.0", + "@bugsnag/plugin-node-in-project": "^8.6.0", + "@bugsnag/plugin-node-surrounding-code": "^8.6.0", + "@bugsnag/plugin-node-uncaught-exception": "^8.6.0", + "@bugsnag/plugin-node-unhandled-rejection": "^8.6.0", + "@bugsnag/plugin-server-session": "^8.6.0", + "@bugsnag/plugin-stackframe-path-normaliser": "^8.6.0", + "@bugsnag/plugin-strip-project-root": "^8.6.0", "@types/node": "^18.19.74" } }, @@ -44618,7 +44620,7 @@ }, "packages/plugin-angular": { "name": "@bugsnag/plugin-angular", - "version": "8.5.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -44631,7 +44633,7 @@ "@angular/compiler": "^19.2.2", "@angular/compiler-cli": "^19.2.2", "@angular/core": "^19.0.0", - "@bugsnag/js": "^8.4.0", + "@bugsnag/js": "^8.6.0", "ng-packagr": "^19.1.0", "rxjs": "~7.8.0", "typescript": "~5.6.2", @@ -47750,10 +47752,10 @@ }, "packages/plugin-app-duration": { "name": "@bugsnag/plugin-app-duration", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47761,14 +47763,14 @@ }, "packages/plugin-aws-lambda": { "name": "@bugsnag/plugin-aws-lambda", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { - "@bugsnag/in-flight": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0" + "@bugsnag/in-flight": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/aws-lambda": "^8.10.76", "@vendia/serverless-express": "^4.10.1", "express": "^4.18.2" @@ -47779,10 +47781,10 @@ }, "packages/plugin-browser-context": { "name": "@bugsnag/plugin-browser-context", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47790,13 +47792,13 @@ }, "packages/plugin-browser-device": { "name": "@bugsnag/plugin-browser-device", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/cuid": "^3.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47804,10 +47806,10 @@ }, "packages/plugin-browser-request": { "name": "@bugsnag/plugin-browser-request", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47815,10 +47817,10 @@ }, "packages/plugin-browser-session": { "name": "@bugsnag/plugin-browser-session", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47826,10 +47828,10 @@ }, "packages/plugin-client-ip": { "name": "@bugsnag/plugin-client-ip", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47837,10 +47839,10 @@ }, "packages/plugin-console-breadcrumbs": { "name": "@bugsnag/plugin-console-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47848,10 +47850,10 @@ }, "packages/plugin-contextualize": { "name": "@bugsnag/plugin-contextualize", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47859,15 +47861,15 @@ }, "packages/plugin-electron-app": { "name": "@bugsnag/plugin-electron-app", - "version": "8.4.0", + "version": "8.7.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "bindings": "^1.5.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47875,14 +47877,14 @@ }, "packages/plugin-electron-app-breadcrumbs": { "name": "@bugsnag/plugin-electron-app-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "lodash.debounce": "^4.0.8" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47890,10 +47892,10 @@ }, "packages/plugin-electron-client-state-manager": { "name": "@bugsnag/plugin-electron-client-state-manager", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47901,16 +47903,16 @@ }, "packages/plugin-electron-client-state-persistence": { "name": "@bugsnag/plugin-electron-client-state-persistence", - "version": "8.4.0", + "version": "8.6.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "bindings": "^1.5.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0", "@types/bindings": "^1.5.0" }, "peerDependencies": { @@ -47919,15 +47921,15 @@ }, "packages/plugin-electron-deliver-minidumps": { "name": "@bugsnag/plugin-electron-deliver-minidumps", - "version": "8.5.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/json-payload": "^8.4.0", "form-data": "^4.0.4" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-network-status": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-network-status": "^8.6.0" }, "peerDependencies": { "@bugsnag/electron-network-status": "^8.0.0" @@ -47935,11 +47937,11 @@ }, "packages/plugin-electron-device": { "name": "@bugsnag/plugin-electron-device", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -47947,13 +47949,13 @@ }, "packages/plugin-electron-ipc": { "name": "@bugsnag/plugin-electron-ipc", - "version": "8.5.0", + "version": "8.7.0", "license": "MIT", "dependencies": { "@bugsnag/safe-json-stringify": "^6.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "browserify": "^17.0.0" }, "peerDependencies": { @@ -48049,11 +48051,11 @@ }, "packages/plugin-electron-net-breadcrumbs": { "name": "@bugsnag/plugin-electron-net-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48061,10 +48063,10 @@ }, "packages/plugin-electron-network-status": { "name": "@bugsnag/plugin-electron-network-status", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48072,11 +48074,11 @@ }, "packages/plugin-electron-power-monitor-breadcrumbs": { "name": "@bugsnag/plugin-electron-power-monitor-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48084,21 +48086,21 @@ }, "packages/plugin-electron-preload-error": { "name": "@bugsnag/plugin-electron-preload-error", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/path-normalizer": "^8.4.0" }, "devDependencies": { - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/electron-test-helpers": "^8.6.0" } }, "packages/plugin-electron-process-info": { "name": "@bugsnag/plugin-electron-process-info", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48106,10 +48108,10 @@ }, "packages/plugin-electron-renderer-client-state-updates": { "name": "@bugsnag/plugin-electron-renderer-client-state-updates", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48117,12 +48119,12 @@ }, "packages/plugin-electron-renderer-event-data": { "name": "@bugsnag/plugin-electron-renderer-event-data", - "version": "8.4.0", + "version": "8.7.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", - "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", + "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0", @@ -48131,20 +48133,20 @@ }, "packages/plugin-electron-renderer-strip-project-root": { "name": "@bugsnag/plugin-electron-renderer-strip-project-root", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" } }, "packages/plugin-electron-screen-breadcrumbs": { "name": "@bugsnag/plugin-electron-screen-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48152,14 +48154,14 @@ }, "packages/plugin-electron-session": { "name": "@bugsnag/plugin-electron-session", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { - "@bugsnag/plugin-browser-session": "^8.4.0" + "@bugsnag/plugin-browser-session": "^8.6.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48167,10 +48169,10 @@ }, "packages/plugin-express": { "name": "@bugsnag/plugin-express", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/express": "4.17.13" }, "peerDependencies": { @@ -48179,10 +48181,10 @@ }, "packages/plugin-hono": { "name": "@bugsnag/plugin-hono", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "hono": "^4.6.3", "typescript": "^5.2.2" }, @@ -48206,10 +48208,10 @@ }, "packages/plugin-inline-script-content": { "name": "@bugsnag/plugin-inline-script-content", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48217,10 +48219,10 @@ }, "packages/plugin-interaction-breadcrumbs": { "name": "@bugsnag/plugin-interaction-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48228,10 +48230,10 @@ }, "packages/plugin-intercept": { "name": "@bugsnag/plugin-intercept", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48239,10 +48241,10 @@ }, "packages/plugin-internal-callback-marker": { "name": "@bugsnag/plugin-internal-callback-marker", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48250,10 +48252,10 @@ }, "packages/plugin-koa": { "name": "@bugsnag/plugin-koa", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/koa": "2.13.4" }, "peerDependencies": { @@ -48262,10 +48264,10 @@ }, "packages/plugin-navigation-breadcrumbs": { "name": "@bugsnag/plugin-navigation-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48273,10 +48275,10 @@ }, "packages/plugin-network-breadcrumbs": { "name": "@bugsnag/plugin-network-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48284,10 +48286,10 @@ }, "packages/plugin-node-device": { "name": "@bugsnag/plugin-node-device", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48295,22 +48297,25 @@ }, "packages/plugin-node-in-project": { "name": "@bugsnag/plugin-node-in-project", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/path-normalizer": "^8.4.0" + }, + "devDependencies": { + "@bugsnag/core": "^8.6.0" } }, "packages/plugin-node-surrounding-code": { "name": "@bugsnag/plugin-node-surrounding-code", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "byline": "^5.0.0", "pump": "^3.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48318,10 +48323,10 @@ }, "packages/plugin-node-uncaught-exception": { "name": "@bugsnag/plugin-node-uncaught-exception", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48329,10 +48334,10 @@ }, "packages/plugin-node-unhandled-rejection": { "name": "@bugsnag/plugin-node-unhandled-rejection", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48340,10 +48345,10 @@ }, "packages/plugin-react": { "name": "@bugsnag/plugin-react", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48356,22 +48361,21 @@ }, "packages/plugin-react-native-client-sync": { "name": "@bugsnag/plugin-react-native-client-sync", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", - "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/derecursify": "^8.4.0" + "dependencies": { + "@bugsnag/derecursify": "^8.6.0" }, - "peerDependencies": { - "@bugsnag/core": "^8.0.0" + "devDependencies": { + "@bugsnag/core": "^8.6.0" } }, "packages/plugin-react-native-event-sync": { "name": "@bugsnag/plugin-react-native-event-sync", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48379,10 +48383,10 @@ }, "packages/plugin-react-native-global-error-handler": { "name": "@bugsnag/plugin-react-native-global-error-handler", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { @@ -48391,10 +48395,10 @@ }, "packages/plugin-react-native-hermes": { "name": "@bugsnag/plugin-react-native-hermes", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { @@ -48403,10 +48407,10 @@ }, "packages/plugin-react-native-navigation": { "name": "@bugsnag/plugin-react-native-navigation", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "react-native-navigation": "^7.0.0" }, "peerDependencies": { @@ -48421,10 +48425,10 @@ }, "packages/plugin-react-native-orientation-breadcrumbs": { "name": "@bugsnag/plugin-react-native-orientation-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { @@ -48433,10 +48437,10 @@ }, "packages/plugin-react-native-session": { "name": "@bugsnag/plugin-react-native-session", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { @@ -48445,10 +48449,10 @@ }, "packages/plugin-react-native-unhandled-rejection": { "name": "@bugsnag/plugin-react-native-unhandled-rejection", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "promise": "^8.0.2" }, "peerDependencies": { @@ -48457,10 +48461,10 @@ }, "packages/plugin-react-navigation": { "name": "@bugsnag/plugin-react-navigation", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@react-navigation/native": "^5.7.3", "@types/react": "^16.9.49", "@types/react-test-renderer": "^16.9.3", @@ -48479,10 +48483,10 @@ }, "packages/plugin-restify": { "name": "@bugsnag/plugin-restify", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/restify": "^8.4.2" }, "peerDependencies": { @@ -48491,13 +48495,13 @@ }, "packages/plugin-server-session": { "name": "@bugsnag/plugin-server-session", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "backo": "^1.1.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48505,10 +48509,10 @@ }, "packages/plugin-simple-throttle": { "name": "@bugsnag/plugin-simple-throttle", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48516,10 +48520,10 @@ }, "packages/plugin-stackframe-path-normaliser": { "name": "@bugsnag/plugin-stackframe-path-normaliser", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48527,18 +48531,21 @@ }, "packages/plugin-strip-project-root": { "name": "@bugsnag/plugin-strip-project-root", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "dependencies": { "@bugsnag/path-normalizer": "^8.4.0" + }, + "devDependencies": { + "@bugsnag/core": "^8.6.0" } }, "packages/plugin-strip-query-string": { "name": "@bugsnag/plugin-strip-query-string", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48546,10 +48553,10 @@ }, "packages/plugin-vue": { "name": "@bugsnag/plugin-vue", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48562,10 +48569,10 @@ }, "packages/plugin-window-onerror": { "name": "@bugsnag/plugin-window-onerror", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48573,10 +48580,10 @@ }, "packages/plugin-window-unhandled-rejection": { "name": "@bugsnag/plugin-window-unhandled-rejection", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" @@ -48584,20 +48591,20 @@ }, "packages/react-native": { "name": "@bugsnag/react-native", - "version": "8.4.0", + "version": "8.7.0", "license": "MIT", "dependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-react-native": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-react": "^8.4.0", - "@bugsnag/plugin-react-native-client-sync": "^8.4.0", - "@bugsnag/plugin-react-native-event-sync": "^8.4.0", - "@bugsnag/plugin-react-native-global-error-handler": "^8.4.0", - "@bugsnag/plugin-react-native-hermes": "^8.4.0", - "@bugsnag/plugin-react-native-session": "^8.4.0", - "@bugsnag/plugin-react-native-unhandled-rejection": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-react-native": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-react": "^8.6.0", + "@bugsnag/plugin-react-native-client-sync": "^8.6.0", + "@bugsnag/plugin-react-native-event-sync": "^8.6.0", + "@bugsnag/plugin-react-native-global-error-handler": "^8.6.0", + "@bugsnag/plugin-react-native-hermes": "^8.6.0", + "@bugsnag/plugin-react-native-session": "^8.6.0", + "@bugsnag/plugin-react-native-unhandled-rejection": "^8.6.0", "iserror": "^0.0.2" }, "devDependencies": { @@ -48695,16 +48702,16 @@ }, "packages/web-worker": { "name": "@bugsnag/web-worker", - "version": "8.4.0", + "version": "8.6.0", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-fetch": "^8.4.0", - "@bugsnag/plugin-browser-device": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0", - "@bugsnag/plugin-client-ip": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-fetch": "^8.6.0", + "@bugsnag/plugin-browser-device": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0", + "@bugsnag/plugin-client-ip": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", "@rollup/plugin-node-resolve": "^16.0.0", @@ -50382,23 +50389,23 @@ "@bugsnag/browser": { "version": "file:packages/browser", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-xml-http-request": "^8.4.0", - "@bugsnag/plugin-app-duration": "^8.4.0", - "@bugsnag/plugin-browser-context": "^8.4.0", - "@bugsnag/plugin-browser-device": "^8.4.0", - "@bugsnag/plugin-browser-request": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0", - "@bugsnag/plugin-client-ip": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-inline-script-content": "^8.4.0", - "@bugsnag/plugin-interaction-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-navigation-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-simple-throttle": "^8.4.0", - "@bugsnag/plugin-strip-query-string": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-xml-http-request": "^8.6.0", + "@bugsnag/plugin-app-duration": "^8.6.0", + "@bugsnag/plugin-browser-context": "^8.6.0", + "@bugsnag/plugin-browser-device": "^8.6.0", + "@bugsnag/plugin-browser-request": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0", + "@bugsnag/plugin-client-ip": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-inline-script-content": "^8.6.0", + "@bugsnag/plugin-interaction-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-navigation-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-simple-throttle": "^8.6.0", + "@bugsnag/plugin-strip-query-string": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", "@rollup/plugin-node-resolve": "^16.0.0", @@ -50531,37 +50538,37 @@ "@bugsnag/delivery-electron": { "version": "file:packages/delivery-electron", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-network-status": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-network-status": "^8.6.0", "@bugsnag/json-payload": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0" + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0" } }, "@bugsnag/delivery-fetch": { "version": "file:packages/delivery-fetch", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@bugsnag/json-payload": "^8.4.0" } }, "@bugsnag/delivery-node": { "version": "file:packages/delivery-node", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@bugsnag/json-payload": "^8.4.0" } }, "@bugsnag/delivery-react-native": { "version": "file:packages/delivery-react-native", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@bugsnag/derecursify": "^8.4.0" } }, "@bugsnag/delivery-xml-http-request": { "version": "file:packages/delivery-xml-http-request", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@bugsnag/json-payload": "^8.4.0" } }, @@ -50571,37 +50578,37 @@ "@bugsnag/electron": { "version": "file:packages/electron", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-electron": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-electron": "^8.6.0", "@bugsnag/electron-filestore": "^8.0.0", - "@bugsnag/electron-network-status": "^8.4.0", + "@bugsnag/electron-network-status": "^8.6.0", "@bugsnag/path-normalizer": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-electron-app": "^8.4.0", - "@bugsnag/plugin-electron-app-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0", - "@bugsnag/plugin-electron-client-state-persistence": "^8.4.0", - "@bugsnag/plugin-electron-deliver-minidumps": "^8.5.0", - "@bugsnag/plugin-electron-device": "^8.4.0", - "@bugsnag/plugin-electron-ipc": "^8.5.0", - "@bugsnag/plugin-electron-net-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-electron-network-status": "^8.4.0", - "@bugsnag/plugin-electron-preload-error": "^8.4.0", - "@bugsnag/plugin-electron-process-info": "^8.4.0", - "@bugsnag/plugin-electron-renderer-client-state-updates": "^8.4.0", - "@bugsnag/plugin-electron-renderer-event-data": "^8.4.0", - "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.4.0", - "@bugsnag/plugin-electron-session": "^8.4.0", - "@bugsnag/plugin-interaction-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-internal-callback-marker": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-node-surrounding-code": "^8.4.0", - "@bugsnag/plugin-node-uncaught-exception": "^8.4.0", - "@bugsnag/plugin-node-unhandled-rejection": "^8.4.0", - "@bugsnag/plugin-stackframe-path-normaliser": "^8.4.0", - "@bugsnag/plugin-strip-project-root": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0" + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-electron-app": "^8.7.0", + "@bugsnag/plugin-electron-app-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0", + "@bugsnag/plugin-electron-client-state-persistence": "^8.6.0", + "@bugsnag/plugin-electron-deliver-minidumps": "^8.6.0", + "@bugsnag/plugin-electron-device": "^8.6.0", + "@bugsnag/plugin-electron-ipc": "^8.7.0", + "@bugsnag/plugin-electron-net-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-electron-network-status": "^8.6.0", + "@bugsnag/plugin-electron-preload-error": "^8.6.0", + "@bugsnag/plugin-electron-process-info": "^8.6.0", + "@bugsnag/plugin-electron-renderer-client-state-updates": "^8.6.0", + "@bugsnag/plugin-electron-renderer-event-data": "^8.7.0", + "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.6.0", + "@bugsnag/plugin-electron-session": "^8.6.0", + "@bugsnag/plugin-interaction-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-internal-callback-marker": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-node-surrounding-code": "^8.6.0", + "@bugsnag/plugin-node-uncaught-exception": "^8.6.0", + "@bugsnag/plugin-node-unhandled-rejection": "^8.6.0", + "@bugsnag/plugin-stackframe-path-normaliser": "^8.6.0", + "@bugsnag/plugin-strip-project-root": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0" } }, "@bugsnag/electron-filestore": { @@ -50610,20 +50617,20 @@ "@bugsnag/electron-network-status": { "version": "file:packages/electron-network-status", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0" } }, "@bugsnag/electron-test-helpers": { "version": "file:packages/electron-test-helpers", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/in-flight": { "version": "file:packages/in-flight", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@bugsnag/cuid": "^3.0.0" } }, @@ -50631,8 +50638,8 @@ "version": "file:packages/js", "requires": { "@babel/cli": "^7.0.0", - "@bugsnag/browser": "^8.4.0", - "@bugsnag/node": "^8.4.0" + "@bugsnag/browser": "^8.6.0", + "@bugsnag/node": "^8.6.0" } }, "@bugsnag/json-payload": { @@ -50673,20 +50680,20 @@ "@bugsnag/node": { "version": "file:packages/node", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-node": "^8.4.0", - "@bugsnag/plugin-app-duration": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-contextualize": "^8.4.0", - "@bugsnag/plugin-intercept": "^8.4.0", - "@bugsnag/plugin-node-device": "^8.4.0", - "@bugsnag/plugin-node-in-project": "^8.4.0", - "@bugsnag/plugin-node-surrounding-code": "^8.4.0", - "@bugsnag/plugin-node-uncaught-exception": "^8.4.0", - "@bugsnag/plugin-node-unhandled-rejection": "^8.4.0", - "@bugsnag/plugin-server-session": "^8.4.0", - "@bugsnag/plugin-stackframe-path-normaliser": "^8.4.0", - "@bugsnag/plugin-strip-project-root": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-node": "^8.6.0", + "@bugsnag/plugin-app-duration": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-contextualize": "^8.6.0", + "@bugsnag/plugin-intercept": "^8.6.0", + "@bugsnag/plugin-node-device": "^8.6.0", + "@bugsnag/plugin-node-in-project": "^8.6.0", + "@bugsnag/plugin-node-surrounding-code": "^8.6.0", + "@bugsnag/plugin-node-uncaught-exception": "^8.6.0", + "@bugsnag/plugin-node-unhandled-rejection": "^8.6.0", + "@bugsnag/plugin-server-session": "^8.6.0", + "@bugsnag/plugin-stackframe-path-normaliser": "^8.6.0", + "@bugsnag/plugin-strip-project-root": "^8.6.0", "@types/node": "^18.19.74", "byline": "^5.0.0", "error-stack-parser": "^2.0.3", @@ -50735,7 +50742,7 @@ "@angular/compiler": "^19.2.2", "@angular/compiler-cli": "^19.2.2", "@angular/core": "^19.0.0", - "@bugsnag/js": "^8.4.0", + "@bugsnag/js": "^8.6.0", "ng-packagr": "^19.1.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", @@ -52632,15 +52639,15 @@ "@bugsnag/plugin-app-duration": { "version": "file:packages/plugin-app-duration", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-aws-lambda": { "version": "file:packages/plugin-aws-lambda", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/in-flight": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/in-flight": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0", "@types/aws-lambda": "^8.10.76", "@vendia/serverless-express": "^4.10.1", "express": "^4.18.2" @@ -52649,74 +52656,74 @@ "@bugsnag/plugin-browser-context": { "version": "file:packages/plugin-browser-context", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-browser-device": { "version": "file:packages/plugin-browser-device", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@bugsnag/cuid": "^3.0.0" } }, "@bugsnag/plugin-browser-request": { "version": "file:packages/plugin-browser-request", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-browser-session": { "version": "file:packages/plugin-browser-session", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-client-ip": { "version": "file:packages/plugin-client-ip", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-console-breadcrumbs": { "version": "file:packages/plugin-console-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-contextualize": { "version": "file:packages/plugin-contextualize", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-electron-app": { "version": "file:packages/plugin-electron-app", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", "bindings": "^1.5.0" } }, "@bugsnag/plugin-electron-app-breadcrumbs": { "version": "file:packages/plugin-electron-app-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", "lodash.debounce": "^4.0.8" } }, "@bugsnag/plugin-electron-client-state-manager": { "version": "file:packages/plugin-electron-client-state-manager", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-electron-client-state-persistence": { "version": "file:packages/plugin-electron-client-state-persistence", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0", "@types/bindings": "^1.5.0", "bindings": "^1.5.0" } @@ -52724,8 +52731,8 @@ "@bugsnag/plugin-electron-deliver-minidumps": { "version": "file:packages/plugin-electron-deliver-minidumps", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-network-status": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-network-status": "^8.6.0", "@bugsnag/json-payload": "^8.4.0", "form-data": "^4.0.4" } @@ -52733,14 +52740,14 @@ "@bugsnag/plugin-electron-device": { "version": "file:packages/plugin-electron-device", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" } }, "@bugsnag/plugin-electron-ipc": { "version": "file:packages/plugin-electron-ipc", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@bugsnag/safe-json-stringify": "^6.0.0", "browserify": "^17.0.0" }, @@ -52831,83 +52838,83 @@ "@bugsnag/plugin-electron-net-breadcrumbs": { "version": "file:packages/plugin-electron-net-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" } }, "@bugsnag/plugin-electron-network-status": { "version": "file:packages/plugin-electron-network-status", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-electron-power-monitor-breadcrumbs": { "version": "file:packages/plugin-electron-power-monitor-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" } }, "@bugsnag/plugin-electron-preload-error": { "version": "file:packages/plugin-electron-preload-error", "requires": { - "@bugsnag/electron-test-helpers": "^8.4.0", + "@bugsnag/electron-test-helpers": "^8.6.0", "@bugsnag/path-normalizer": "^8.4.0" } }, "@bugsnag/plugin-electron-process-info": { "version": "file:packages/plugin-electron-process-info", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-electron-renderer-client-state-updates": { "version": "file:packages/plugin-electron-renderer-client-state-updates", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-electron-renderer-event-data": { "version": "file:packages/plugin-electron-renderer-event-data", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", - "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", + "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.6.0" } }, "@bugsnag/plugin-electron-renderer-strip-project-root": { "version": "file:packages/plugin-electron-renderer-strip-project-root", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" } }, "@bugsnag/plugin-electron-screen-breadcrumbs": { "version": "file:packages/plugin-electron-screen-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" } }, "@bugsnag/plugin-electron-session": { "version": "file:packages/plugin-electron-session", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0" } }, "@bugsnag/plugin-express": { "version": "file:packages/plugin-express", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/express": "4.17.13" } }, "@bugsnag/plugin-hono": { "version": "file:packages/plugin-hono", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "hono": "^4.6.3", "typescript": "^5.2.2" }, @@ -52923,62 +52930,63 @@ "@bugsnag/plugin-inline-script-content": { "version": "file:packages/plugin-inline-script-content", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-interaction-breadcrumbs": { "version": "file:packages/plugin-interaction-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-intercept": { "version": "file:packages/plugin-intercept", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-internal-callback-marker": { "version": "file:packages/plugin-internal-callback-marker", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-koa": { "version": "file:packages/plugin-koa", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/koa": "2.13.4" } }, "@bugsnag/plugin-navigation-breadcrumbs": { "version": "file:packages/plugin-navigation-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-network-breadcrumbs": { "version": "file:packages/plugin-network-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-node-device": { "version": "file:packages/plugin-node-device", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-node-in-project": { "version": "file:packages/plugin-node-in-project", "requires": { + "@bugsnag/core": "^8.6.0", "@bugsnag/path-normalizer": "^8.4.0" } }, "@bugsnag/plugin-node-surrounding-code": { "version": "file:packages/plugin-node-surrounding-code", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "byline": "^5.0.0", "pump": "^3.0.0" } @@ -52986,80 +52994,80 @@ "@bugsnag/plugin-node-uncaught-exception": { "version": "file:packages/plugin-node-uncaught-exception", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-node-unhandled-rejection": { "version": "file:packages/plugin-node-unhandled-rejection", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-react": { "version": "file:packages/plugin-react", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-react-native-client-sync": { "version": "file:packages/plugin-react-native-client-sync", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/derecursify": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/derecursify": "^8.6.0" } }, "@bugsnag/plugin-react-native-event-sync": { "version": "file:packages/plugin-react-native-event-sync", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-react-native-global-error-handler": { "version": "file:packages/plugin-react-native-global-error-handler", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" } }, "@bugsnag/plugin-react-native-hermes": { "version": "file:packages/plugin-react-native-hermes", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" } }, "@bugsnag/plugin-react-native-navigation": { "version": "file:packages/plugin-react-native-navigation", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "react-native-navigation": "^7.0.0" } }, "@bugsnag/plugin-react-native-orientation-breadcrumbs": { "version": "file:packages/plugin-react-native-orientation-breadcrumbs", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" } }, "@bugsnag/plugin-react-native-session": { "version": "file:packages/plugin-react-native-session", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" } }, "@bugsnag/plugin-react-native-unhandled-rejection": { "version": "file:packages/plugin-react-native-unhandled-rejection", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "promise": "^8.0.2" } }, "@bugsnag/plugin-react-navigation": { "version": "file:packages/plugin-react-navigation", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@react-navigation/native": "^5.7.3", "@types/react": "^16.9.49", "@types/react-test-renderer": "^16.9.3", @@ -53070,74 +53078,75 @@ "@bugsnag/plugin-restify": { "version": "file:packages/plugin-restify", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/restify": "^8.4.2" } }, "@bugsnag/plugin-server-session": { "version": "file:packages/plugin-server-session", "requires": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "backo": "^1.1.0" } }, "@bugsnag/plugin-simple-throttle": { "version": "file:packages/plugin-simple-throttle", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-stackframe-path-normaliser": { "version": "file:packages/plugin-stackframe-path-normaliser", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-strip-project-root": { "version": "file:packages/plugin-strip-project-root", "requires": { + "@bugsnag/core": "^8.6.0", "@bugsnag/path-normalizer": "^8.4.0" } }, "@bugsnag/plugin-strip-query-string": { "version": "file:packages/plugin-strip-query-string", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-vue": { "version": "file:packages/plugin-vue", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-window-onerror": { "version": "file:packages/plugin-window-onerror", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/plugin-window-unhandled-rejection": { "version": "file:packages/plugin-window-unhandled-rejection", "requires": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } }, "@bugsnag/react-native": { "version": "file:packages/react-native", "requires": { "@babel/cli": "^7.0.0", - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-react-native": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-react": "^8.4.0", - "@bugsnag/plugin-react-native-client-sync": "^8.4.0", - "@bugsnag/plugin-react-native-event-sync": "^8.4.0", - "@bugsnag/plugin-react-native-global-error-handler": "^8.4.0", - "@bugsnag/plugin-react-native-hermes": "^8.4.0", - "@bugsnag/plugin-react-native-session": "^8.4.0", - "@bugsnag/plugin-react-native-unhandled-rejection": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-react-native": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-react": "^8.6.0", + "@bugsnag/plugin-react-native-client-sync": "^8.6.0", + "@bugsnag/plugin-react-native-event-sync": "^8.6.0", + "@bugsnag/plugin-react-native-global-error-handler": "^8.6.0", + "@bugsnag/plugin-react-native-hermes": "^8.6.0", + "@bugsnag/plugin-react-native-session": "^8.6.0", + "@bugsnag/plugin-react-native-unhandled-rejection": "^8.6.0", "@types/react-native": "0.67.8", "iserror": "^0.0.2", "react-native": "^0.63.4", @@ -53208,13 +53217,13 @@ "@bugsnag/web-worker": { "version": "file:packages/web-worker", "requires": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-fetch": "^8.4.0", - "@bugsnag/plugin-browser-device": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0", - "@bugsnag/plugin-client-ip": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-fetch": "^8.6.0", + "@bugsnag/plugin-browser-device": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0", + "@bugsnag/plugin-client-ip": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", "@rollup/plugin-node-resolve": "^16.0.0", @@ -54016,20 +54025,20 @@ "dev": true }, "@inquirer/ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.0.tgz", - "integrity": "sha512-JWaTfCxI1eTmJ1BIv86vUfjVatOdxwD0DAVKYevY8SazeUUZtW+tNbsdejVO1GYE0GXJW1N1ahmiC3TFd+7wZA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", + "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", "dev": true }, "@inquirer/core": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.2.2.tgz", - "integrity": "sha512-yXq/4QUnk4sHMtmbd7irwiepjB8jXU0kkFRL4nr/aDBA2mDz13cMakEWdDwX3eSCTkk03kwcndD1zfRAIlELxA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", + "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", "dev": true, "requires": { - "@inquirer/ansi": "^1.0.0", - "@inquirer/figures": "^1.0.13", - "@inquirer/type": "^3.0.8", + "@inquirer/ansi": "^1.0.1", + "@inquirer/figures": "1.0.13", + "@inquirer/type": "^3.0.9", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", @@ -54038,9 +54047,9 @@ }, "dependencies": { "@inquirer/type": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", - "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", + "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 50c7967f6a..384485237b 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "test:electron": "xvfb-maybe --auto-servernum -- cucumber-js test/electron/features --retry 3 --retry-tag-filter @flaky" }, "overrides": { + "@inquirer/figures": "1.0.13", "@jest-runner/electron": { "form-data": "^3.0.3" }, diff --git a/packages/browser/package.json b/packages/browser/package.json index 97961ee550..57217c1fed 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/browser", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/index-cjs.cjs", "types": "dist/types/index-es.d.ts", "browser": "./dist/bugsnag.js", @@ -34,29 +34,29 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/delivery-xml-http-request": "^8.4.0", - "@bugsnag/plugin-app-duration": "^8.4.0", - "@bugsnag/plugin-browser-context": "^8.4.0", - "@bugsnag/plugin-browser-device": "^8.4.0", - "@bugsnag/plugin-browser-request": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0", - "@bugsnag/plugin-client-ip": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-inline-script-content": "^8.4.0", - "@bugsnag/plugin-interaction-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-navigation-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-simple-throttle": "^8.4.0", - "@bugsnag/plugin-strip-query-string": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", "@rollup/plugin-node-resolve": "^16.0.0", "@rollup/plugin-replace": "^6.0.2", - "@rollup/plugin-terser": "^0.4.4" + "@rollup/plugin-terser": "^0.4.4", + "@bugsnag/delivery-xml-http-request": "^8.6.0", + "@bugsnag/plugin-app-duration": "^8.6.0", + "@bugsnag/plugin-browser-context": "^8.6.0", + "@bugsnag/plugin-browser-device": "^8.6.0", + "@bugsnag/plugin-browser-request": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0", + "@bugsnag/plugin-client-ip": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-inline-script-content": "^8.6.0", + "@bugsnag/plugin-interaction-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-navigation-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-simple-throttle": "^8.6.0", + "@bugsnag/plugin-strip-query-string": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0" }, "dependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } } diff --git a/packages/core/package.json b/packages/core/package.json index d651c286ab..7f7a60311f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/core", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/index.cjs", "types": "dist/types/index.d.ts", "exports": { diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 1067744179..7d978bb32c 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -26,6 +26,7 @@ export default class Client { public _metadata: { [key: string]: any } public _featuresIndex: { [key: string]: number } public _features: Array + public _groupingDiscriminator?: string | null private _context: string | undefined @@ -71,6 +72,7 @@ export default class Client { this._features = [] this._context = undefined this._user = {} + this._groupingDiscriminator = undefined // callbacks: // e: onError @@ -153,6 +155,17 @@ export default class Client { this._context = c } + getGroupingDiscriminator () { + return this._groupingDiscriminator + } + + setGroupingDiscriminator (value: string | null | undefined) { + const previousValue = this._groupingDiscriminator + if (typeof value === 'string' || value === null || value === undefined) this._groupingDiscriminator = value + return previousValue + } + + _configure (opts: T, internalPlugins: Plugin[]) { const schema = internalPlugins.reduce((schema, plugin) => { if (plugin && plugin.configSchema) return Object.assign({}, schema, plugin.configSchema) @@ -193,7 +206,7 @@ export default class Client { // warn about an apikey that is not of the expected format if (!/^[0-9a-f]{32}$/i.test(config.apiKey)) errors.apiKey = 'should be a string of 32 hexadecimal characters' - if (opts.endpoints === undefined && config.apiKey.startsWith(HUB_PREFIX)) { + if (opts.endpoints === undefined && config.apiKey.indexOf(HUB_PREFIX) === 0) { config.endpoints = { notify: HUB_NOTIFY, sessions: HUB_SESSION @@ -350,6 +363,7 @@ export default class Client { event._user = Object.assign({}, event._user, this._user) event.breadcrumbs = this._breadcrumbs.slice() featureFlagDelegate.merge(event._features, this._features, event._featuresIndex) + event.setGroupingDiscriminator(this._groupingDiscriminator) // exit early if events should not be sent on the current releaseStage if (this._config.enabledReleaseStages !== null && this._config.enabledReleaseStages.indexOf(this._config.releaseStage) === -1) { diff --git a/packages/core/src/event.ts b/packages/core/src/event.ts index d17c12af4e..f4a7b7935a 100644 --- a/packages/core/src/event.ts +++ b/packages/core/src/event.ts @@ -35,6 +35,7 @@ export default class Event { public _metadata: { [key: string]: any } public _features: (FeatureFlag | null)[] public _featuresIndex: { [key: string]: number } + public _groupingDiscriminator: string | null | undefined public _user: User private _correlation?: { spanId?: string, traceId: string } @@ -71,6 +72,7 @@ export default class Event { this._user = {} this._session = undefined this._correlation = undefined + this._groupingDiscriminator = undefined this.errors = [ createBugsnagError(errorClass, errorMessage, Event.__type, stacktrace) @@ -100,6 +102,16 @@ export default class Event { } } + getGroupingDiscriminator () { + return this._groupingDiscriminator + } + + setGroupingDiscriminator (value: string | null | undefined) { + const previousValue = this._groupingDiscriminator + if (typeof value === 'string' || value === null || value === undefined) this._groupingDiscriminator = value + return previousValue + } + getMetadata (section: string, key?: string) { return metadataDelegate.get(this._metadata, section, key) } @@ -150,6 +162,7 @@ export default class Event { breadcrumbs: this.breadcrumbs, context: this.context, groupingHash: this.groupingHash, + groupingDiscriminator: this._groupingDiscriminator, metaData: this._metadata, user: this._user, session: this._session, diff --git a/packages/core/test/event.test.ts b/packages/core/test/event.test.ts index dd3863ed6b..18518d16d7 100644 --- a/packages/core/test/event.test.ts +++ b/packages/core/test/event.test.ts @@ -445,4 +445,28 @@ describe('Event', () => { expect(serialized.correlation).toBeUndefined() }) }) + + describe('Event.getGroupingDiscriminator() / Event.setGroupingDiscriminator', () => { + it('sets and retrieves grouping discriminator on event', () => { + const event = new Event('Error', 'test message', []) + + // Initially should be undefined + expect(event.getGroupingDiscriminator()).toBe(undefined) + + // Set a value and retrieve it + const previousValue = event.setGroupingDiscriminator('event-discriminator') + expect(previousValue).toBe(undefined) + expect(event.getGroupingDiscriminator()).toBe('event-discriminator') + + // Update the value + const previousValue2 = event.setGroupingDiscriminator('updated-discriminator') + expect(previousValue2).toBe('event-discriminator') + expect(event.getGroupingDiscriminator()).toBe('updated-discriminator') + + // Clear the value + const previousValue3 = event.setGroupingDiscriminator(undefined) + expect(previousValue3).toBe('updated-discriminator') + expect(event.getGroupingDiscriminator()).toBe(undefined) + }) + }) }) diff --git a/packages/core/test/grouping-discriminator.test.ts b/packages/core/test/grouping-discriminator.test.ts new file mode 100644 index 0000000000..e53a7463b4 --- /dev/null +++ b/packages/core/test/grouping-discriminator.test.ts @@ -0,0 +1,172 @@ +import Client from '../src/client' + +describe('@bugsnag/core/grouping discriminator', () => { + describe('Client', () => { + describe('getGroupingDiscriminator() / setGroupingDiscriminator()', () => { + it('sets and retrieves grouping discriminator on client', () => { + const client = new Client({ apiKey: 'API_KEY' }) + + // Initially should be undefined + expect(client.getGroupingDiscriminator()).toBe(undefined) + + // Set a value and retrieve it + const previousValue = client.setGroupingDiscriminator('test-discriminator') + expect(previousValue).toBe(undefined) + expect(client.getGroupingDiscriminator()).toBe('test-discriminator') + + // Update the value + const previousValue2 = client.setGroupingDiscriminator('new-discriminator') + expect(previousValue2).toBe('test-discriminator') + expect(client.getGroupingDiscriminator()).toBe('new-discriminator') + + // Clear the value + const previousValue3 = client.setGroupingDiscriminator(undefined) + expect(previousValue3).toBe('new-discriminator') + expect(client.getGroupingDiscriminator()).toBe(undefined) + }) + }) + }) + + describe('Client notify() integration', () => { + it('uses client grouping discriminator when event has none set', (done) => { + const client = new Client({ apiKey: 'API_KEY' }) + client.setGroupingDiscriminator('client-discriminator') + + client._setDelivery(client => ({ + sendEvent: (payload) => { + expect(payload.events).toHaveLength(1) + const event = payload.events[0] + expect(event.getGroupingDiscriminator()).toBe('client-discriminator') + + const eventPayload = event.toJSON() + expect(eventPayload.groupingDiscriminator).toBe('client-discriminator') + done() + }, + sendSession: () => {} + })) + + client.notify(new Error('test error')) + }) + + it('uses event grouping discriminator when set, ignoring client discriminator', (done) => { + const client = new Client({ apiKey: 'API_KEY' }) + client.setGroupingDiscriminator('client-discriminator') + + client._setDelivery(client => ({ + sendEvent: (payload) => { + expect(payload.events).toHaveLength(1) + const event = payload.events[0] + expect(event.getGroupingDiscriminator()).toBe('event-discriminator') + + const eventPayload = event.toJSON() + expect(eventPayload.groupingDiscriminator).toBe('event-discriminator') + done() + }, + sendSession: () => {} + })) + + client.notify(new Error('test error'), (event) => { + event.setGroupingDiscriminator('event-discriminator') + }) + }) + + it('does not set grouping discriminator when neither client nor event has one', (done) => { + const client = new Client({ apiKey: 'API_KEY' }) + + client._setDelivery(client => ({ + sendEvent: (payload) => { + expect(payload.events).toHaveLength(1) + const event = payload.events[0] + expect(event.getGroupingDiscriminator()).toBe(undefined) + + const eventPayload = event.toJSON() + expect(eventPayload.groupingDiscriminator).toBe(undefined) + done() + }, + sendSession: () => {} + })) + + client.notify(new Error('test error')) + }) + + it('handles multiple notify calls with different discriminators', (done) => { + const client = new Client({ apiKey: 'API_KEY' }) + client.setGroupingDiscriminator('client-discriminator') + + let callCount = 0 + const expectedResults = [ + 'client-discriminator', // First call uses client discriminator + 'custom-discriminator', // Second call has event discriminator set + 'client-discriminator', // Third call uses client discriminator again + undefined // Fourth call has the discriminator cleared + ] + + client._setDelivery(client => ({ + sendEvent: (payload) => { + expect(payload.events).toHaveLength(1) + const event = payload.events[0] + expect(event.getGroupingDiscriminator()).toBe(expectedResults[callCount]) + + const eventPayload = event.toJSON() + expect(eventPayload.groupingDiscriminator).toBe(expectedResults[callCount]) + + callCount++ + if (callCount === 4) { + done() + } + }, + sendSession: () => {} + })) + + // First notify - should use client discriminator + client.notify(new Error('test error 1')) + + // Second notify - should use event discriminator + client.notify(new Error('test error 2'), (event) => { + event.setGroupingDiscriminator('custom-discriminator') + }) + + // Third notify - should use client discriminator again + client.notify(new Error('test error 3')) + + // Fourth notify - clear the event discriminator + client.notify(new Error('test error 4'), (event) => { + event.setGroupingDiscriminator(undefined) + }) + }) + + it('allows changing client discriminator between notify calls', (done) => { + const client = new Client({ apiKey: 'API_KEY' }) + client.setGroupingDiscriminator('initial-discriminator') + + let callCount = 0 + const expectedResults = [ + 'initial-discriminator', + 'updated-discriminator' + ] + + client._setDelivery(client => ({ + sendEvent: (payload) => { + expect(payload.events).toHaveLength(1) + const event = payload.events[0] + expect(event.getGroupingDiscriminator()).toBe(expectedResults[callCount]) + + callCount++ + if (callCount === 2) { + done() + } + }, + sendSession: () => {} + })) + + // First notify + client.notify(new Error('test error 1')) + + // Change client discriminator + client.setGroupingDiscriminator('updated-discriminator') + + // Second notify + client.notify(new Error('test error 2')) + }) + }) +}) diff --git a/packages/delivery-electron/package.json b/packages/delivery-electron/package.json index d617d382e6..8ab81e1c68 100644 --- a/packages/delivery-electron/package.json +++ b/packages/delivery-electron/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/delivery-electron", - "version": "8.4.0", + "version": "8.6.0", "main": "delivery.js", "description": "@bugsnag/electron delivery mechanism to send events, sessions, and crash dumps from Electron apps", "homepage": "https://www.bugsnag.com/", @@ -17,9 +17,9 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-network-status": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-network-status": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0" }, "dependencies": { "@bugsnag/json-payload": "^8.4.0" diff --git a/packages/delivery-fetch/package.json b/packages/delivery-fetch/package.json index 77ac54aa2a..5878d09373 100644 --- a/packages/delivery-fetch/package.json +++ b/packages/delivery-fetch/package.json @@ -1,7 +1,7 @@ { "name": "@bugsnag/delivery-fetch", "author": "Bugsnag", - "version": "8.4.0", + "version": "8.6.0", "main": "delivery.js", "description": "@bugsnag/js delivery mechanism using the fetch API", "homepage": "https://www.bugsnag.com/", @@ -17,6 +17,9 @@ "@bugsnag/json-payload": "^8.4.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" + }, + "peerDependencies": { + "@bugsnag/core": "^8.0.0" } } diff --git a/packages/delivery-node/package.json b/packages/delivery-node/package.json index 3c38648429..2884901ce2 100644 --- a/packages/delivery-node/package.json +++ b/packages/delivery-node/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/delivery-node", - "version": "8.4.0", + "version": "8.6.0", "main": "delivery.js", "description": "@bugsnag/node delivery mechanism", "homepage": "https://www.bugsnag.com/", @@ -17,7 +17,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "dependencies": { "@bugsnag/json-payload": "^8.4.0" diff --git a/packages/delivery-react-native/package.json b/packages/delivery-react-native/package.json index e65501c3ec..657577f6c7 100644 --- a/packages/delivery-react-native/package.json +++ b/packages/delivery-react-native/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/delivery-react-native", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/delivery.js", "description": "@bugsnag/js delivery mechanism for React Native", "homepage": "https://www.bugsnag.com/", @@ -19,11 +19,10 @@ }, "author": "Bugsnag", "license": "MIT", - "devDependencies": { - "@bugsnag/core": "^8.4.0", + "dependencies": { "@bugsnag/derecursify": "^8.4.0" }, - "peerDependencies": { - "@bugsnag/core": "^8.0.0" + "devDependencies": { + "@bugsnag/core": "^8.6.0" } } diff --git a/packages/delivery-react-native/src/delivery.js b/packages/delivery-react-native/src/delivery.js index e93a7d7bcd..d6c6791c8f 100644 --- a/packages/delivery-react-native/src/delivery.js +++ b/packages/delivery-react-native/src/delivery.js @@ -27,6 +27,7 @@ module.exports = (client, NativeClient) => ({ user: event._user, metadata: derecursify(event._metadata), groupingHash: event.groupingHash, + groupingDiscriminator: event._groupingDiscriminator, apiKey: event.apiKey, featureFlags: event.toJSON().featureFlags, nativeStack: nativeStack, diff --git a/packages/delivery-react-native/test/delivery.test.ts b/packages/delivery-react-native/test/delivery.test.ts index 8acddd35e9..1d6568933f 100644 --- a/packages/delivery-react-native/test/delivery.test.ts +++ b/packages/delivery-react-native/test/delivery.test.ts @@ -26,6 +26,7 @@ type NativeClientEvent = Pick value === null || stringWithLength(value), message: 'should be string' }, + codeBundleId: { + defaultValue: () => undefined, + message: 'should be a string', + validate: val => (val === undefined || stringWithLength(val)) + }, releaseStage: { ...schema.releaseStage, defaultValue: () => app.isPackaged ? 'production' : 'development' diff --git a/packages/electron/types/notifier.d.ts b/packages/electron/types/notifier.d.ts index bd680fa6d9..aa10630ec0 100644 --- a/packages/electron/types/notifier.d.ts +++ b/packages/electron/types/notifier.d.ts @@ -26,6 +26,7 @@ interface MainConfig extends Config { projectRoot?: string launchDurationMillis?: number sendCode?: boolean + codeBundleId?: string } // a renderer is only allowed a subset of properties from Config diff --git a/packages/in-flight/package.json b/packages/in-flight/package.json index 937d335ea9..24c351f3e1 100644 --- a/packages/in-flight/package.json +++ b/packages/in-flight/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/in-flight", - "version": "8.4.0", + "version": "8.6.0", "main": "src/in-flight.js", "types": "types/bugsnag-in-flight.d.ts", "description": "Internal package to keep track of in-flight requests to Bugsnag", @@ -22,7 +22,7 @@ "@bugsnag/cuid": "^3.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/js/package.json b/packages/js/package.json index 959f7e7d79..6b309fe15f 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/js", - "version": "8.4.0", + "version": "8.6.0", "main": "node/notifier.js", "browser": "browser/notifier.js", "types": "types.d.ts", @@ -36,8 +36,8 @@ "build": "echo 'No build step required for @bugsnag/js'" }, "dependencies": { - "@bugsnag/browser": "^8.4.0", - "@bugsnag/node": "^8.4.0" + "@bugsnag/browser": "^8.6.0", + "@bugsnag/node": "^8.6.0" }, "devDependencies": { "@babel/cli": "^7.0.0" diff --git a/packages/node/package.json b/packages/node/package.json index 2c4bceb32c..0020106fd0 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/node", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/index-cjs.cjs", "types": "dist/types/index-es.d.ts", "exports": { @@ -31,23 +31,23 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/delivery-node": "^8.4.0", - "@bugsnag/plugin-app-duration": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-contextualize": "^8.4.0", - "@bugsnag/plugin-intercept": "^8.4.0", - "@bugsnag/plugin-node-device": "^8.4.0", - "@bugsnag/plugin-node-in-project": "^8.4.0", - "@bugsnag/plugin-node-surrounding-code": "^8.4.0", - "@bugsnag/plugin-node-uncaught-exception": "^8.4.0", - "@bugsnag/plugin-node-unhandled-rejection": "^8.4.0", - "@bugsnag/plugin-server-session": "^8.4.0", - "@bugsnag/plugin-stackframe-path-normaliser": "^8.4.0", - "@bugsnag/plugin-strip-project-root": "^8.4.0", + "@bugsnag/delivery-node": "^8.6.0", + "@bugsnag/plugin-app-duration": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-contextualize": "^8.6.0", + "@bugsnag/plugin-intercept": "^8.6.0", + "@bugsnag/plugin-node-device": "^8.6.0", + "@bugsnag/plugin-node-in-project": "^8.6.0", + "@bugsnag/plugin-node-surrounding-code": "^8.6.0", + "@bugsnag/plugin-node-uncaught-exception": "^8.6.0", + "@bugsnag/plugin-node-unhandled-rejection": "^8.6.0", + "@bugsnag/plugin-server-session": "^8.6.0", + "@bugsnag/plugin-stackframe-path-normaliser": "^8.6.0", + "@bugsnag/plugin-strip-project-root": "^8.6.0", "@types/node": "^18.19.74" }, "dependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "byline": "^5.0.0", "error-stack-parser": "^2.0.3", "pump": "^3.0.0", diff --git a/packages/plugin-angular/package.json b/packages/plugin-angular/package.json index 9bce01b27a..3ee7043ffb 100644 --- a/packages/plugin-angular/package.json +++ b/packages/plugin-angular/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-angular", - "version": "8.5.0", + "version": "8.6.0", "description": "Angular integration for bugsnag-js", "homepage": "https://www.bugsnag.com/", "repository": { @@ -32,7 +32,7 @@ "@angular/compiler": "^19.2.2", "@angular/compiler-cli": "^19.2.2", "@angular/core": "^19.0.0", - "@bugsnag/js": "^8.4.0", + "@bugsnag/js": "^8.6.0", "ng-packagr": "^19.1.0", "rxjs": "~7.8.0", "typescript": "~5.6.2", diff --git a/packages/plugin-app-duration/package.json b/packages/plugin-app-duration/package.json index eefa2d4982..947248b4e7 100644 --- a/packages/plugin-app-duration/package.json +++ b/packages/plugin-app-duration/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-app-duration", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/app-duration.js", "types": "dist/types/app-duration.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-aws-lambda/package.json b/packages/plugin-aws-lambda/package.json index 491164465e..9b5aee3086 100644 --- a/packages/plugin-aws-lambda/package.json +++ b/packages/plugin-aws-lambda/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-aws-lambda", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/index.js", "types": "dist/types/index.d.ts", "exports": { @@ -25,11 +25,11 @@ "author": "Bugsnag", "license": "MIT", "dependencies": { - "@bugsnag/in-flight": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0" + "@bugsnag/in-flight": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/aws-lambda": "^8.10.76", "@vendia/serverless-express": "^4.10.1", "express": "^4.18.2" diff --git a/packages/plugin-browser-context/package.json b/packages/plugin-browser-context/package.json index 56c9fd4827..c92d55a594 100644 --- a/packages/plugin-browser-context/package.json +++ b/packages/plugin-browser-context/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-browser-context", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/context.js", "types": "dist/types/context.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-browser-device/package.json b/packages/plugin-browser-device/package.json index d799c298f9..d23779d601 100644 --- a/packages/plugin-browser-device/package.json +++ b/packages/plugin-browser-device/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-browser-device", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/device.js", "types": "dist/types/device.d.ts", "exports": { @@ -28,7 +28,7 @@ "@bugsnag/cuid": "^3.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-browser-request/package.json b/packages/plugin-browser-request/package.json index 2b0e19b35d..0c501ff3b7 100644 --- a/packages/plugin-browser-request/package.json +++ b/packages/plugin-browser-request/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-browser-request", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/request.js", "types": "dist/types/request.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-browser-session/package.json b/packages/plugin-browser-session/package.json index d851b02568..b93027542c 100644 --- a/packages/plugin-browser-session/package.json +++ b/packages/plugin-browser-session/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-browser-session", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/session.js", "types": "dist/types/session.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-client-ip/package.json b/packages/plugin-client-ip/package.json index 07a63cfb2c..e707927203 100644 --- a/packages/plugin-client-ip/package.json +++ b/packages/plugin-client-ip/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-client-ip", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/client-ip.js", "types": "dist/types/client-ip.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-console-breadcrumbs/package.json b/packages/plugin-console-breadcrumbs/package.json index 0f70f1bd28..3f23975b32 100644 --- a/packages/plugin-console-breadcrumbs/package.json +++ b/packages/plugin-console-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-console-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/console-breadcrumbs.js", "types": "dist/types/console-breadcrumbs.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-contextualize/package.json b/packages/plugin-contextualize/package.json index 757af50bf0..d66c3de30f 100644 --- a/packages/plugin-contextualize/package.json +++ b/packages/plugin-contextualize/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-contextualize", - "version": "8.4.0", + "version": "8.6.0", "main": "contextualize.js", "description": "@bugsnag/js plugin to add context to unhandled events", "homepage": "https://www.bugsnag.com/", @@ -17,7 +17,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-app-breadcrumbs/package.json b/packages/plugin-electron-app-breadcrumbs/package.json index 17efbb2b3a..4792d058d0 100644 --- a/packages/plugin-electron-app-breadcrumbs/package.json +++ b/packages/plugin-electron-app-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-app-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "app-breadcrumbs.js", "description": "@bugsnag/electron plugin to collect breadcrumbs for app lifecycle events", "repository": { @@ -17,8 +17,8 @@ "lodash.debounce": "^4.0.8" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-app/app.js b/packages/plugin-electron-app/app.js index 8abfd773e9..2d065c66f1 100644 --- a/packages/plugin-electron-app/app.js +++ b/packages/plugin-electron-app/app.js @@ -105,7 +105,8 @@ module.exports = (NativeClient, process, electronApp, BrowserWindow, filestore, isLaunching: true, releaseStage: client._config.releaseStage, type: client._config.appType || osToAppType.get(process.platform), - version: client._config.appVersion + version: client._config.appVersion, + codeBundleId: client._config.codeBundleId }) client.addMetadata('app', { diff --git a/packages/plugin-electron-app/package.json b/packages/plugin-electron-app/package.json index ebf389d105..66e46415e0 100644 --- a/packages/plugin-electron-app/package.json +++ b/packages/plugin-electron-app/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-app", - "version": "8.4.0", + "version": "8.7.0", "main": "app.js", "description": "@bugsnag/electron plugin to collect app information", "repository": { @@ -25,8 +25,8 @@ "generate-compile-commands": "node-gyp configure --release -- -f gyp.generator.compile_commands_json.py; mv Release/compile_commands.json .; rm -rf Debug Release" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "dependencies": { "bindings": "^1.5.0" diff --git a/packages/plugin-electron-app/test/app.test.ts b/packages/plugin-electron-app/test/app.test.ts index 3ca4e56633..d5b995b5ef 100644 --- a/packages/plugin-electron-app/test/app.test.ts +++ b/packages/plugin-electron-app/test/app.test.ts @@ -13,6 +13,7 @@ const makeExpectedSessionApp = (customisations = {}) => ({ releaseStage: 'production', type: undefined, version: '1.2.3', + codeBundleId: undefined, ...customisations }) @@ -181,6 +182,19 @@ describe('plugin: electron app info', () => { expect(session.app).toEqual(makeExpectedSessionApp()) }) + it('reports app.codeBundleId when configured', async () => { + const config = { codeBundleId: 'test-bundle-123' } + + const { sendEvent, sendSession } = makeClient({ config }) + + const event = await sendEvent() + expect(event.app).toEqual(makeExpectedEventApp({ codeBundleId: 'test-bundle-123' })) + expect(event.getMetadata('app')).toEqual(makeExpectedMetadataApp()) + + const session = await sendSession() + expect(session.app).toEqual(makeExpectedSessionApp({ codeBundleId: 'test-bundle-123' })) + }) + it('tracks focus and blur events for inForeground', async () => { const BrowserWindow = makeBrowserWindow() const electronApp = makeElectronApp({ BrowserWindow }) @@ -801,6 +815,11 @@ const schema = { }), allowPartialObject: true, validate: value => true + }, + codeBundleId: { + defaultValue: () => undefined, + message: 'should be a string', + validate: val => (val === undefined || typeof val === 'string') } } diff --git a/packages/plugin-electron-client-state-manager/client-state-manager.js b/packages/plugin-electron-client-state-manager/client-state-manager.js index ac0e56dfca..fe8f0077bb 100644 --- a/packages/plugin-electron-client-state-manager/client-state-manager.js +++ b/packages/plugin-electron-client-state-manager/client-state-manager.js @@ -22,6 +22,13 @@ module.exports = { return ret } + const origSetGroupingDiscriminator = client.setGroupingDiscriminator + client.setGroupingDiscriminator = (...args) => { + const ret = origSetGroupingDiscriminator.call(client, ...args) + emitter.emit('GroupingDiscriminatorUpdate', client.getGroupingDiscriminator()) + return ret + } + const origAddMetadata = client.addMetadata client.addMetadata = (...args) => { const ret = origAddMetadata.call(client, ...args) @@ -73,13 +80,16 @@ module.exports = { } // handle a bulk update of initial values from a new renderer - const bulkUpdate = ({ user, context, metadata, features }) => { + const bulkUpdate = ({ user, context, metadata, features, groupingDiscriminator }) => { if (user) { client.setUser(user.id, user.email, user.name) } if (context) { client.setContext(context) } + if (groupingDiscriminator) { + client.setGroupingDiscriminator(groupingDiscriminator) + } if (metadata) { for (const section in metadata) { origAddMetadata.call(client, section, metadata[section]) diff --git a/packages/plugin-electron-client-state-manager/package.json b/packages/plugin-electron-client-state-manager/package.json index c7c01c3756..659c35008a 100644 --- a/packages/plugin-electron-client-state-manager/package.json +++ b/packages/plugin-electron-client-state-manager/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-client-state-manager", - "version": "8.4.0", + "version": "8.6.0", "main": "client-state-manager.js", "description": "@bugsnag/electron plugin to sync state between various processes", "homepage": "https://www.bugsnag.com/", @@ -19,7 +19,7 @@ "client-state-manager.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-client-state-manager/test/client-state-manager.test.ts b/packages/plugin-electron-client-state-manager/test/client-state-manager.test.ts index a8f7e276f2..dd070cc68b 100644 --- a/packages/plugin-electron-client-state-manager/test/client-state-manager.test.ts +++ b/packages/plugin-electron-client-state-manager/test/client-state-manager.test.ts @@ -29,6 +29,16 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { client.setContext('ctx') }) + it('should emit events when grouping discriminator changes', done => { + const client = new Client({ apiKey: '123' }, {}, [stateManager], Notifier) + const { emitter } = client.getPlugin('clientStateManager') + emitter.on('GroupingDiscriminatorUpdate', (groupingDiscriminator: string) => { + expect(groupingDiscriminator).toBe('discriminator') + done() + }) + client.setGroupingDiscriminator('discriminator') + }) + interface MetadataUpdatePayload { section: string values?: Record @@ -137,11 +147,13 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { const featuresCb = jest.fn() const contextCb = jest.fn() const userCb = jest.fn() + const groupingDiscriminatorCb = jest.fn() emitter.on('FeatureFlagUpdate', featuresCb) emitter.on('MetadataReplace', metadataCb) emitter.on('ContextUpdate', contextCb) emitter.on('UserUpdate', userCb) + emitter.on('GroupingDiscriminatorUpdate', groupingDiscriminatorCb) // update everything bulkUpdate({ @@ -155,7 +167,8 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { features: [ { name: 'flag name 1', variant: 'variant name 1' }, { name: 'flag name 2', variant: 'variant name 2' } - ] + ], + groupingDiscriminator: 'discriminator' }) expect(featuresCb).toHaveBeenCalledWith([ @@ -166,6 +179,7 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { expect(metadataCb).toHaveBeenCalledWith({ section: { key: 'value' } }) expect(contextCb).toHaveBeenCalledWith('ctx') expect(userCb).toHaveBeenCalledWith({ id: '123', name: 'Jim', email: 'jim@jim.com' }) + expect(groupingDiscriminatorCb).toHaveBeenCalledWith('discriminator') }) it('should support bulk updates (only context)', () => { @@ -175,10 +189,14 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { const metadataCb = jest.fn() const contextCb = jest.fn() const userCb = jest.fn() + const featuresCb = jest.fn() + const groupingDiscriminatorCb = jest.fn() emitter.on('MetadataReplace', metadataCb) emitter.on('ContextUpdate', contextCb) emitter.on('UserUpdate', userCb) + emitter.on('FeatureFlagUpdate', featuresCb) + emitter.on('GroupingDiscriminatorUpdate', groupingDiscriminatorCb) // update just context bulkUpdate({ @@ -188,6 +206,8 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { expect(metadataCb).not.toHaveBeenCalled() expect(contextCb).toHaveBeenCalledWith('ctx') expect(userCb).not.toHaveBeenCalled() + expect(featuresCb).not.toHaveBeenCalled() + expect(groupingDiscriminatorCb).not.toHaveBeenCalled() }) it('should support bulk updates (only user)', () => { @@ -197,10 +217,14 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { const metadataCb = jest.fn() const contextCb = jest.fn() const userCb = jest.fn() + const featuresCb = jest.fn() + const groupingDiscriminatorCb = jest.fn() emitter.on('MetadataReplace', metadataCb) emitter.on('ContextUpdate', contextCb) emitter.on('UserUpdate', userCb) + emitter.on('FeatureFlagUpdate', featuresCb) + emitter.on('GroupingDiscriminatorUpdate', groupingDiscriminatorCb) // update just user bulkUpdate({ @@ -210,6 +234,8 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { expect(metadataCb).not.toHaveBeenCalled() expect(contextCb).not.toHaveBeenCalledWith() expect(userCb).toHaveBeenCalledWith({ id: '123', name: 'Jim', email: 'jim@jim.com' }) + expect(featuresCb).not.toHaveBeenCalledWith() + expect(groupingDiscriminatorCb).not.toHaveBeenCalledWith() }) it('should support bulk updates (only metadata)', () => { @@ -219,10 +245,14 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { const metadataCb = jest.fn() const contextCb = jest.fn() const userCb = jest.fn() + const featuresCb = jest.fn() + const groupingDiscriminatorCb = jest.fn() emitter.on('MetadataReplace', metadataCb) emitter.on('ContextUpdate', contextCb) emitter.on('UserUpdate', userCb) + emitter.on('FeatureFlagUpdate', featuresCb) + emitter.on('GroupingDiscriminatorUpdate', groupingDiscriminatorCb) // update just metadata bulkUpdate({ @@ -234,5 +264,35 @@ describe('@bugsnag/plugin-electron-client-state-manager', () => { expect(metadataCb).toHaveBeenCalledWith({ section: { key: 'value' } }) expect(contextCb).not.toHaveBeenCalled() expect(userCb).not.toHaveBeenCalled() + expect(featuresCb).not.toHaveBeenCalledWith() + expect(groupingDiscriminatorCb).not.toHaveBeenCalledWith() + }) + + it('should support bulk updates (only grouping discriminator)', () => { + const client = new Client({ apiKey: '123' }, {}, [stateManager], Notifier) + const { emitter, bulkUpdate } = client.getPlugin('clientStateManager') + + const metadataCb = jest.fn() + const featuresCb = jest.fn() + const contextCb = jest.fn() + const groupingDiscriminatorCb = jest.fn() + const userCb = jest.fn() + + emitter.on('MetadataReplace', metadataCb) + emitter.on('ContextUpdate', contextCb) + emitter.on('UserUpdate', userCb) + emitter.on('FeatureFlagUpdate', featuresCb) + emitter.on('GroupingDiscriminatorUpdate', groupingDiscriminatorCb) + + // update just grouping discriminator + bulkUpdate({ + groupingDiscriminator: 'discriminator' + }) + + expect(metadataCb).not.toHaveBeenCalled() + expect(contextCb).not.toHaveBeenCalled() + expect(userCb).not.toHaveBeenCalled() + expect(featuresCb).not.toHaveBeenCalled() + expect(groupingDiscriminatorCb).toHaveBeenCalledWith('discriminator') }) }) diff --git a/packages/plugin-electron-client-state-persistence/client-state-persistence.js b/packages/plugin-electron-client-state-persistence/client-state-persistence.js index 49d557dc21..46279dd904 100644 --- a/packages/plugin-electron-client-state-persistence/client-state-persistence.js +++ b/packages/plugin-electron-client-state-persistence/client-state-persistence.js @@ -36,6 +36,14 @@ module.exports = { } }) + clientStateManager.emitter.on('GroupingDiscriminatorUpdate', groupingDiscriminator => { + try { + NativeClient.updateGroupingDiscriminator(groupingDiscriminator) + } catch (e) { + client._logger.error(e) + } + }) + clientStateManager.emitter.on('MetadataUpdate', ({ section, values }) => { try { NativeClient.updateMetadata(section, values) diff --git a/packages/plugin-electron-client-state-persistence/package.json b/packages/plugin-electron-client-state-persistence/package.json index 34b53a5605..d378d018ed 100644 --- a/packages/plugin-electron-client-state-persistence/package.json +++ b/packages/plugin-electron-client-state-persistence/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-client-state-persistence", - "version": "8.4.0", + "version": "8.6.0", "main": "client-state-persistence.js", "description": "@bugsnag/electron plugin to sync information between JS and native layer", "homepage": "https://www.bugsnag.com/", @@ -39,9 +39,9 @@ "bindings": "^1.5.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", - "@bugsnag/plugin-electron-client-state-manager": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", + "@bugsnag/plugin-electron-client-state-manager": "^8.6.0", "@types/bindings": "^1.5.0" }, "peerDependencies": { diff --git a/packages/plugin-electron-client-state-persistence/src/api.c b/packages/plugin-electron-client-state-persistence/src/api.c index c6b4299b81..5d6f1fbe72 100644 --- a/packages/plugin-electron-client-state-persistence/src/api.c +++ b/packages/plugin-electron-client-state-persistence/src/api.c @@ -233,6 +233,35 @@ static napi_value UpdateContext(napi_env env, napi_callback_info info) { return NULL; } +static napi_value UpdateGroupingDiscriminator(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1]; + napi_status status = napi_get_cb_info(env, info, &argc, args, NULL, NULL); + assert(status == napi_ok); + + if (argc < 1) { + napi_throw_type_error(env, NULL, "Wrong number of arguments, expected 1"); + return NULL; + } + + napi_valuetype valuetype0; + status = napi_typeof(env, args[0], &valuetype0); + assert(status == napi_ok); + + if (valuetype0 == napi_string) { + char *grouping_discriminator = read_string_value(env, args[0], false); + throw_error_from_status(env, becsp_set_grouping_discriminator(grouping_discriminator)); + free(grouping_discriminator); + } else if (valuetype0 == napi_null) { + becsp_set_grouping_discriminator(NULL); + } else { + napi_throw_type_error(env, NULL, + "Wrong argument type, expected string or null"); + } + + return NULL; +} + static napi_value UpdateUser(napi_env env, napi_callback_info info) { size_t argc = 3; napi_value args[3]; @@ -475,6 +504,10 @@ napi_value Init(napi_env env, napi_value exports) { status = napi_define_properties(env, exports, 1, &desc); assert(status == napi_ok); + desc = DECLARE_NAPI_METHOD("updateGroupingDiscriminator", UpdateGroupingDiscriminator); + status = napi_define_properties(env, exports, 1, &desc); + assert(status == napi_ok); + desc = DECLARE_NAPI_METHOD("updateUser", UpdateUser); status = napi_define_properties(env, exports, 1, &desc); assert(status == napi_ok); diff --git a/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.c b/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.c index f489ae9655..f286365d33 100644 --- a/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.c +++ b/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.c @@ -43,6 +43,7 @@ static const char *const key_app = "app"; static const char *const key_breadcrumbs = "breadcrumbs"; static const char *const key_context = "context"; static const char *const key_device = "device"; +static const char *const key_grouping_discriminator = "groupingDiscriminator"; static const char *const key_metadata = "metadata"; static const char *const key_feature_flags = "featureFlags"; static const char *const key_session = "session"; @@ -220,6 +221,24 @@ BECSP_STATUS becsp_set_context(const char *context) { return BECSP_STATUS_SUCCESS; } +BECSP_STATUS becsp_set_grouping_discriminator(const char *grouping_discriminator) { + if (!g_context.data) { + return BECSP_STATUS_NOT_INSTALLED; + } + context_lock(); + + JSON_Object *obj = json_value_get_object(g_context.data); + if (grouping_discriminator) { + json_object_set_string(obj, key_grouping_discriminator, grouping_discriminator); + } else { + json_object_remove(obj, key_grouping_discriminator); + } + + serialize_data(); + context_unlock(); + return BECSP_STATUS_SUCCESS; +} + BECSP_STATUS becsp_set_metadata(const char *values) { if (!g_context.data) { return BECSP_STATUS_NOT_INSTALLED; diff --git a/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.h b/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.h index f4b49be445..7019c3dd57 100644 --- a/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.h +++ b/packages/plugin-electron-client-state-persistence/src/bugsnag_electron_client_state_persistence.h @@ -68,6 +68,13 @@ BECSP_STATUS becsp_add_breadcrumb(const char *val); */ BECSP_STATUS becsp_set_context(const char *context); +/** + * Set the grouping discriminator + * + * @param grouping_discriminator the new grouping discriminator value or NULL to unset + */ +BECSP_STATUS becsp_set_grouping_discriminator(const char *grouping_discriminator); + /** * Set event user * diff --git a/packages/plugin-electron-deliver-minidumps/deliver-minidumps.js b/packages/plugin-electron-deliver-minidumps/deliver-minidumps.js index e2f60c88eb..39b3e8972d 100644 --- a/packages/plugin-electron-deliver-minidumps/deliver-minidumps.js +++ b/packages/plugin-electron-deliver-minidumps/deliver-minidumps.js @@ -94,6 +94,7 @@ const takeEventSnapshot = (client) => ({ app: { ...client._app }, breadcrumbs: client._breadcrumbs.slice(), context: client._context, + groupingDiscriminator: client._groupingDiscriminator, device: { ...client._device }, metadata: { ...client._metadata }, featureFlags: featureFlagDelegate.toEventApi(client._features), diff --git a/packages/plugin-electron-deliver-minidumps/event-serialisation.js b/packages/plugin-electron-deliver-minidumps/event-serialisation.js index e0ea83e5fa..d838bfcba6 100644 --- a/packages/plugin-electron-deliver-minidumps/event-serialisation.js +++ b/packages/plugin-electron-deliver-minidumps/event-serialisation.js @@ -7,6 +7,7 @@ const supportedProperties = [ 'device', 'featureFlags', 'groupingHash', + 'groupingDiscriminator', 'metaData', 'request', 'session', @@ -96,6 +97,10 @@ function deserialiseEvent (json, minidumpPath) { event.context = json.context } + if (hasValueForProperty(json, 'groupingDiscriminator')) { + event.groupingDiscriminator = json.groupingDiscriminator + } + if (hasValueForProperty(json, 'device')) { event.device = json.device } diff --git a/packages/plugin-electron-deliver-minidumps/package.json b/packages/plugin-electron-deliver-minidumps/package.json index c25170b296..17c39881c5 100644 --- a/packages/plugin-electron-deliver-minidumps/package.json +++ b/packages/plugin-electron-deliver-minidumps/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-deliver-minidumps", - "version": "8.5.0", + "version": "8.6.0", "main": "deliver-minidumps.js", "description": "@bugsnag/electron plugin to deliver minidumps to Bugsnag", "homepage": "https://www.bugsnag.com/", @@ -23,8 +23,8 @@ "form-data": "^4.0.4" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-network-status": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-network-status": "^8.6.0" }, "peerDependencies": { "@bugsnag/electron-network-status": "^8.0.0" diff --git a/packages/plugin-electron-device/package.json b/packages/plugin-electron-device/package.json index da75b9b668..1a39b1ad21 100644 --- a/packages/plugin-electron-device/package.json +++ b/packages/plugin-electron-device/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-device", - "version": "8.4.0", + "version": "8.6.0", "main": "device.js", "description": "@bugsnag/electron plugin to collect device information", "repository": { @@ -14,8 +14,8 @@ "device.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-ipc/bugsnag-ipc-main.js b/packages/plugin-electron-ipc/bugsnag-ipc-main.js index 3f01d05cec..68c08f66fd 100644 --- a/packages/plugin-electron-ipc/bugsnag-ipc-main.js +++ b/packages/plugin-electron-ipc/bugsnag-ipc-main.js @@ -97,9 +97,11 @@ module.exports = class BugsnagIpcMain { ...event.app, releaseStage: this.client._config.releaseStage, version: this.client._config.appVersion, - type: this.client._config.appType + type: this.client._config.appType, + codeBundleId: this.client._config.codeBundleId } event.context = event.context || this.client._context + event.groupingDiscriminator = event.groupingDiscriminator || this.client._groupingDiscriminator event._metadata = { ...event._metadata, ...this.client._metadata } featureFlagDelegate.merge(event._features, this.client._features, event._featuresIndex) event._user = { ...event._user, ...this.client._user } @@ -112,8 +114,8 @@ module.exports = class BugsnagIpcMain { if (!shouldSend) return resolve({ shouldSend: false }) // extract just the properties we want from the event - const { app, breadcrumbs, context, device, _metadata, _features, _user } = event - resolve({ app, breadcrumbs, context, device, metadata: _metadata, features: _features, user: _user }) + const { app, breadcrumbs, context, device, _metadata, _features, _user, groupingDiscriminator } = event + resolve({ app, breadcrumbs, context, device, metadata: _metadata, features: _features, user: _user, groupingDiscriminator }) }) }) } @@ -156,6 +158,8 @@ module.exports = class BugsnagIpcMain { ['update', this.update.bind(this)], ['getContext', this.client.getContext.bind(this.client)], ['setContext', this.client.setContext.bind(this.client)], + ['getGroupingDiscriminator', this.client.getGroupingDiscriminator.bind(this.client)], + ['setGroupingDiscriminator', this.client.setGroupingDiscriminator.bind(this.client)], ['addMetadata', this.client.addMetadata.bind(this.client)], ['clearMetadata', this.client.clearMetadata.bind(this.client)], ['getMetadata', this.client.getMetadata.bind(this.client)], diff --git a/packages/plugin-electron-ipc/bugsnag-ipc-renderer.js b/packages/plugin-electron-ipc/bugsnag-ipc-renderer.js index febc07885f..b2d112293d 100644 --- a/packages/plugin-electron-ipc/bugsnag-ipc-renderer.js +++ b/packages/plugin-electron-ipc/bugsnag-ipc-renderer.js @@ -25,6 +25,14 @@ const BugsnagIpcRenderer = { return safeInvoke(false, 'setContext', context) }, + getGroupingDiscriminator () { + return safeInvoke(true, 'getGroupingDiscriminator') + }, + + setGroupingDiscriminator (groupingDiscriminator) { + return safeInvoke(false, 'setGroupingDiscriminator', groupingDiscriminator) + }, + addMetadata (...args) { return safeInvoke(false, 'addMetadata', ...args) }, diff --git a/packages/plugin-electron-ipc/package.json b/packages/plugin-electron-ipc/package.json index 1234b8e0c7..63e1dc09a8 100644 --- a/packages/plugin-electron-ipc/package.json +++ b/packages/plugin-electron-ipc/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-ipc", - "version": "8.5.0", + "version": "8.7.0", "main": "electron-ipc.js", "description": "@bugsnag/electron plugin to create the IPC layer between main and renderer processes", "repository": { @@ -22,7 +22,7 @@ "@bugsnag/core": "^8.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "browserify": "^17.0.0" }, "dependencies": { diff --git a/packages/plugin-electron-ipc/test/bugsnag-ipc-main.test.ts b/packages/plugin-electron-ipc/test/bugsnag-ipc-main.test.ts index 44f88679c2..add67209dc 100644 --- a/packages/plugin-electron-ipc/test/bugsnag-ipc-main.test.ts +++ b/packages/plugin-electron-ipc/test/bugsnag-ipc-main.test.ts @@ -54,6 +54,23 @@ describe('BugsnagIpcMain', () => { expect(event.returnValue).toEqual('today') }) + it('works for updating grouping discriminator', () => { + const client = new Client({ apiKey: '123' }, {}, [mockClientStateManagerPlugin], Notifier) + client.setGroupingDiscriminator = jest.fn() + const bugsnagIpcMain = new BugsnagIpcMain(client) + bugsnagIpcMain.handle({}, 'setGroupingDiscriminator', JSON.stringify('grouping-discriminator')) + expect(client.setGroupingDiscriminator).toHaveBeenCalledWith('grouping-discriminator') + }) + + it('returns the current grouping discriminator', () => { + const client = new Client({ apiKey: '123' }, {}, [mockClientStateManagerPlugin], Notifier) + client.setGroupingDiscriminator('current-grouping-discriminator') + const bugsnagIpcMain = new BugsnagIpcMain(client) + const event = { returnValue: undefined } + bugsnagIpcMain.handleSync(event, 'getGroupingDiscriminator') + expect(event.returnValue).toEqual('current-grouping-discriminator') + }) + it('works for updating user', () => { const client = new Client({ apiKey: '123' }, testSchema, [mockClientStateManagerPlugin], Notifier) client.setUser = jest.fn() @@ -274,6 +291,7 @@ describe('BugsnagIpcMain', () => { client.leaveBreadcrumb('hi') client.setContext('ctx') + client.setGroupingDiscriminator('grouping-discriminator') client.setUser('123', 'jim@jim.com', 'Jim') client.addFeatureFlags([ { name: 'flag1' }, @@ -295,10 +313,12 @@ describe('BugsnagIpcMain', () => { releaseStage: 'production', name: 'testApp', type: 'test', - version: undefined + version: undefined, + codeBundleId: undefined }, breadcrumbs: client._breadcrumbs, context: 'ctx', + groupingDiscriminator: 'grouping-discriminator', device: { id: '123' }, metadata: { app: { testingMode: 'unit' }, @@ -318,6 +338,35 @@ describe('BugsnagIpcMain', () => { }) }) + it('should include codeBundleId in app object when configured', async () => { + const schema = { + codeBundleId: { + defaultValue: () => undefined, + message: 'should be a string', + validate: (val: unknown) => (val === undefined || typeof val === 'string') + }, + releaseStage: { + defaultValue: () => 'production', + message: 'should be a string', + validate: (val: unknown) => typeof val === 'string' + } + } + const client = new Client({ + apiKey: '123', + codeBundleId: 'test-bundle-456' + }, schema, [mockClientStateManagerPlugin], Notifier) + + const bugsnagIpcMain = new BugsnagIpcMain(client) + const payloadInfo = await bugsnagIpcMain.getPayloadInfo() + + expect(payloadInfo.app).toEqual({ + releaseStage: 'production', + version: undefined, + type: undefined, + codeBundleId: 'test-bundle-456' + }) + }) + it('should return shouldSend=false when a callback returns false', async () => { const cb = jest.fn(() => false) // @ts-expect-error _internal is not a property of jest mocks but if we diff --git a/packages/plugin-electron-ipc/test/bugsnag-ipc-renderer.test.ts b/packages/plugin-electron-ipc/test/bugsnag-ipc-renderer.test.ts index c18d71eec5..b230c28e5e 100644 --- a/packages/plugin-electron-ipc/test/bugsnag-ipc-renderer.test.ts +++ b/packages/plugin-electron-ipc/test/bugsnag-ipc-renderer.test.ts @@ -36,6 +36,16 @@ describe('BugsnagIpcRenderer', () => { expect(electron.ipcRenderer.invoke).toHaveBeenCalledWith(CHANNEL_RENDERER_TO_MAIN, 'setContext', JSON.stringify('ctx')) }) + it('should call ipcRenderer correctly for getGroupingDiscriminator', () => { + BugsnagIpcRenderer.getGroupingDiscriminator() + expect(electron.ipcRenderer.sendSync).toHaveBeenCalledWith(CHANNEL_RENDERER_TO_MAIN_SYNC, 'getGroupingDiscriminator') + }) + + it('should call ipcRenderer correctly for setGroupingDiscriminator', async () => { + await BugsnagIpcRenderer.setGroupingDiscriminator('ctx') + expect(electron.ipcRenderer.invoke).toHaveBeenCalledWith(CHANNEL_RENDERER_TO_MAIN, 'setGroupingDiscriminator', JSON.stringify('ctx')) + }) + it('should call ipcRenderer correctly for getUser', () => { BugsnagIpcRenderer.getUser() expect(electron.ipcRenderer.sendSync).toHaveBeenCalledWith( @@ -146,4 +156,36 @@ describe('BugsnagIpcRenderer', () => { await BugsnagIpcRenderer.dispatch(event) expect(electron.ipcRenderer.invoke).toHaveBeenCalledWith(CHANNEL_RENDERER_TO_MAIN, 'dispatch', JSON.stringify(event)) }) + + it('should receive main process codeBundleId via getPayloadInfo but not use it when renderer has no codeBundleId', async () => { + // Mock the electron.ipcRenderer.invoke to return payload info with main's codeBundleId + const mockPayloadInfo = { + app: { + releaseStage: 'production', + version: '1.0.0', + type: 'electron', + codeBundleId: 'main-bundle-abc123' + }, + breadcrumbs: [], + context: null, + device: {}, + metadata: {}, + features: [], + user: {}, + groupingDiscriminator: null + }; + + (electron.ipcRenderer.invoke as jest.Mock).mockResolvedValueOnce(mockPayloadInfo) + + // Verify that getPayloadInfo returns the main's codeBundleId + const result = await BugsnagIpcRenderer.getPayloadInfo() + + expect(electron.ipcRenderer.invoke).toHaveBeenCalledWith(CHANNEL_RENDERER_TO_MAIN, 'getPayloadInfo') + expect(result.app.codeBundleId).toBe('main-bundle-abc123') + + // Note: This test verifies the IPC transport mechanism works correctly. + // The actual isolation behavior (preventing main's codeBundleId from being used + // when renderer has no codeBundleId) is enforced by the renderer-event-data plugin + // which explicitly sets codeBundleId from the renderer's own config. + }) }) diff --git a/packages/plugin-electron-net-breadcrumbs/package.json b/packages/plugin-electron-net-breadcrumbs/package.json index acb43c50a2..b48c8c8064 100644 --- a/packages/plugin-electron-net-breadcrumbs/package.json +++ b/packages/plugin-electron-net-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-net-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "net-breadcrumbs.js", "description": "@bugsnag/electron plugin to collect breadcrumbs from requests made with the net module", "repository": { @@ -14,8 +14,8 @@ "net-breadcrumbs.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-network-status/package.json b/packages/plugin-electron-network-status/package.json index 1b77a9003c..80b2656af6 100644 --- a/packages/plugin-electron-network-status/package.json +++ b/packages/plugin-electron-network-status/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-network-status", - "version": "8.4.0", + "version": "8.6.0", "main": "network-status.js", "description": "@bugsnag/electron plugin to monitor the network status", "repository": { @@ -14,7 +14,7 @@ "network-status.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-power-monitor-breadcrumbs/package.json b/packages/plugin-electron-power-monitor-breadcrumbs/package.json index eda595dea2..881f316a7b 100644 --- a/packages/plugin-electron-power-monitor-breadcrumbs/package.json +++ b/packages/plugin-electron-power-monitor-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-power-monitor-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "power-monitor-breadcrumbs.js", "description": "@bugsnag/electron plugin to collect power state breadcrumbs", "repository": { @@ -14,8 +14,8 @@ "power-monitor-breadcrumbs.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-preload-error/package.json b/packages/plugin-electron-preload-error/package.json index ef8a2501f0..faea0497ba 100644 --- a/packages/plugin-electron-preload-error/package.json +++ b/packages/plugin-electron-preload-error/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-preload-error", - "version": "8.4.0", + "version": "8.6.0", "main": "preload-error.js", "description": "@bugsnag/electron plugin to handle errors in preload scripts", "repository": { @@ -15,7 +15,7 @@ "preload-error.js" ], "devDependencies": { - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/electron-test-helpers": "^8.6.0" }, "dependencies": { "@bugsnag/path-normalizer": "^8.4.0" diff --git a/packages/plugin-electron-process-info/package.json b/packages/plugin-electron-process-info/package.json index f84add65e6..bbde8ac55a 100644 --- a/packages/plugin-electron-process-info/package.json +++ b/packages/plugin-electron-process-info/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-process-info", - "version": "8.4.0", + "version": "8.6.0", "main": "procinfo.js", "description": "@bugsnag/electron plugin to collect process information for errors", "repository": { @@ -14,7 +14,7 @@ "procinfo.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-renderer-client-state-updates/client-state-updates.js b/packages/plugin-electron-renderer-client-state-updates/client-state-updates.js index 00523bda64..9361b79a55 100644 --- a/packages/plugin-electron-renderer-client-state-updates/client-state-updates.js +++ b/packages/plugin-electron-renderer-client-state-updates/client-state-updates.js @@ -24,6 +24,7 @@ module.exports = (BugsnagIpcRenderer = window.__bugsnag_ipc__) => ({ client.addFeatureFlags = safeExec(client, BugsnagIpcRenderer, 'addFeatureFlags') client.clearFeatureFlag = safeExec(client, BugsnagIpcRenderer, 'clearFeatureFlag') client.clearFeatureFlags = safeExec(client, BugsnagIpcRenderer, 'clearFeatureFlags') + client.setGroupingDiscriminator = safeExec(client, BugsnagIpcRenderer, 'setGroupingDiscriminator') client.startSession = () => { safeExec(client, BugsnagIpcRenderer, 'startSession')() @@ -41,9 +42,13 @@ module.exports = (BugsnagIpcRenderer = window.__bugsnag_ipc__) => ({ const updates = { metadata: client._metadata, features: client._features } const user = client.getUser() const context = client.getContext() + const groupingDiscriminator = client.getGroupingDiscriminator() if (context && context.length > 0) { updates.context = context } + if (groupingDiscriminator) { + updates.groupingDiscriminator = groupingDiscriminator + } if (Object.keys(user).length > 0) { updates.user = user } @@ -57,6 +62,7 @@ module.exports = (BugsnagIpcRenderer = window.__bugsnag_ipc__) => ({ client._featuresIndex = {} client._features = [] client._context = undefined + client._groupingDiscriminator = undefined client._user = {} // use main process state once configured properties are synched @@ -64,5 +70,6 @@ module.exports = (BugsnagIpcRenderer = window.__bugsnag_ipc__) => ({ client.getContext = safeExec(client, BugsnagIpcRenderer, 'getContext') client.getUser = safeExec(client, BugsnagIpcRenderer, 'getUser') client.getMetadata = safeExec(client, BugsnagIpcRenderer, 'getMetadata') + client.getGroupingDiscriminator = safeExec(client, BugsnagIpcRenderer, 'getGroupingDiscriminator') } }) diff --git a/packages/plugin-electron-renderer-client-state-updates/package.json b/packages/plugin-electron-renderer-client-state-updates/package.json index 728c2137a7..8db2795c4b 100644 --- a/packages/plugin-electron-renderer-client-state-updates/package.json +++ b/packages/plugin-electron-renderer-client-state-updates/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-renderer-client-state-updates", - "version": "8.4.0", + "version": "8.6.0", "main": "client-state-updates.js", "description": "@bugsnag/electron plugin to sync information between JS renderers", "homepage": "https://www.bugsnag.com/", @@ -19,7 +19,7 @@ "client-state-updates.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-renderer-client-state-updates/test/client-state-updates.test.ts b/packages/plugin-electron-renderer-client-state-updates/test/client-state-updates.test.ts index a74e6c0635..4b51c6af1b 100644 --- a/packages/plugin-electron-renderer-client-state-updates/test/client-state-updates.test.ts +++ b/packages/plugin-electron-renderer-client-state-updates/test/client-state-updates.test.ts @@ -27,6 +27,24 @@ describe('clientStateUpdatesPlugin', () => { expect(client.getContext()).toBe('ctx') }) + it('propagates grouping discriminator changes', () => { + const mockBugsnagIpcRenderer = { + setGroupingDiscriminator: jest.fn() + } + const client = new Client({ apiKey: '123' }, {}, [clientStateUpdatesPlugin(mockBugsnagIpcRenderer)], Notifier) + + client.setGroupingDiscriminator('discriminator') + expect(mockBugsnagIpcRenderer.setGroupingDiscriminator).toHaveBeenCalledWith('discriminator') + }) + + it('forwards upstream changes to grouping discriminator', () => { + const mockBugsnagIpcRenderer = { + getGroupingDiscriminator: () => 'discriminator' + } + const client = new Client({ apiKey: '123' }, {}, [clientStateUpdatesPlugin(mockBugsnagIpcRenderer)], Notifier) + expect(client.getGroupingDiscriminator()).toBe('discriminator') + }) + it('propagates user changes', () => { const mockBugsnagIpcRenderer = { setUser: jest.fn() diff --git a/packages/plugin-electron-renderer-event-data/package.json b/packages/plugin-electron-renderer-event-data/package.json index 47cc3cc176..98a516a58d 100644 --- a/packages/plugin-electron-renderer-event-data/package.json +++ b/packages/plugin-electron-renderer-event-data/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-renderer-event-data", - "version": "8.4.0", + "version": "8.7.0", "main": "renderer-event-data.js", "description": "@bugsnag/electron plugin to get fully populated event data in renderer callbacks", "homepage": "https://www.bugsnag.com/", @@ -19,9 +19,9 @@ "renderer-event-data.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0", - "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0", + "@bugsnag/plugin-electron-renderer-strip-project-root": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0", diff --git a/packages/plugin-electron-renderer-event-data/renderer-event-data.js b/packages/plugin-electron-renderer-event-data/renderer-event-data.js index e20b03dfd9..452f82154a 100644 --- a/packages/plugin-electron-renderer-event-data/renderer-event-data.js +++ b/packages/plugin-electron-renderer-event-data/renderer-event-data.js @@ -8,6 +8,7 @@ module.exports = (BugsnagIpcRenderer = window.__bugsnag_ipc__) => ({ app, breadcrumbs, context, + groupingDiscriminator, device, metadata, features, @@ -18,6 +19,7 @@ module.exports = (BugsnagIpcRenderer = window.__bugsnag_ipc__) => ({ if (shouldSend === false) return false event.context = event.context || context || getDefaultContext() + event._groupingDiscriminator = event._groupingDiscriminator || groupingDiscriminator event.breadcrumbs = breadcrumbs event.app = { ...event.app, ...app, codeBundleId: client._config.codeBundleId } event.device = { ...event.device, ...device } diff --git a/packages/plugin-electron-renderer-event-data/test/renderer-event-data.test.ts b/packages/plugin-electron-renderer-event-data/test/renderer-event-data.test.ts index d33e00431c..75e8cb9584 100644 --- a/packages/plugin-electron-renderer-event-data/test/renderer-event-data.test.ts +++ b/packages/plugin-electron-renderer-event-data/test/renderer-event-data.test.ts @@ -13,7 +13,7 @@ describe('plugin: electron renderer event data', () => { expect(onError).not.toHaveBeenCalled() }) - it('sets context, breadcrumbs, app, device, user, feature flags and metadata from the main process', async () => { + it('sets context, groupingDiscriminator, breadcrumbs, app, device, user, feature flags and metadata from the main process', async () => { const context = 'abc context xyz' const breadcrumbs = [new Breadcrumb('message', { metadata: true }, 'manual')] const app = { abc: 123 } @@ -21,8 +21,10 @@ describe('plugin: electron renderer event data', () => { const user = { id: '10293847' } const features = [{ name: 'flag1', variant: 'variant1' }] const metadata = { meta: { data: true } } + const groupingDiscriminator = 'test-discriminator' + const codeBundleId = 'main-bundle-123' - const { sendEvent } = makeClient({ context, breadcrumbs, app, device, user, features, metadata }) + const { sendEvent } = makeClient({ context, breadcrumbs, app, device, user, features, metadata, groupingDiscriminator, codeBundleId }) const event = await sendEvent() @@ -33,6 +35,7 @@ describe('plugin: electron renderer event data', () => { expect(event.getUser()).toStrictEqual(user) expect(event._features).toStrictEqual(features) expect(event.getMetadata('meta')).toStrictEqual(metadata.meta) + expect(event.getGroupingDiscriminator()).toStrictEqual(groupingDiscriminator) }) it('prefers pre-existing context from the event', async () => { @@ -45,6 +48,16 @@ describe('plugin: electron renderer event data', () => { expect(event.context).toBe('hello') }) + it('prefers pre-existing groupingDiscriminator from the event', async () => { + const { client, sendEvent } = makeClient({ groupingDiscriminator: 'goodbye' }) + + client.addOnError(event => { event.setGroupingDiscriminator('hello') }, true) + + const event = await sendEvent() + + expect(event.getGroupingDiscriminator()).toBe('hello') + }) + it('prefers pre-existing user from the event', async () => { const { client, sendEvent } = makeClient({ user: { id: 123 } }) @@ -54,7 +67,44 @@ describe('plugin: electron renderer event data', () => { expect(event.getUser()).toStrictEqual({ id: 456, email: 'abc@example.com', name: 'abc' }) }) + + it('does not use main process codeBundleId when renderer has no codeBundleId set', async () => { + // Simulate main process having a codeBundleId but renderer config having undefined + const mainProcessPayload = { + app: { + releaseStage: 'production', + version: '1.0.0', + type: 'electron', + codeBundleId: 'main-bundle-abc123' // This should NOT be used by renderer + }, + breadcrumbs: [], + context: null, + device: {}, + metadata: {}, + features: [], + user: {}, + groupingDiscriminator: null + } + + // Create client with no codeBundleId in renderer config (undefined) + const { sendEvent } = makeClientForPlugin({ + plugins: [plugin(makeIpcRenderer(mainProcessPayload))], + config: { + // Explicitly omit codeBundleId to simulate renderer with no codeBundleId config + } + }) + + const event = await sendEvent() + + // The renderer should use its own config value (undefined), not the main process value + expect(event.app.codeBundleId).toBeUndefined() + + // Verify other app properties from main process are still applied + expect(event.app.releaseStage).toBe('production') + expect(event.app.version).toBe('1.0.0') + expect(event.app.type).toBe('electron') + }) }) -const makeClient = payloadInfo => makeClientForPlugin({ plugins: [plugin(makeIpcRenderer(payloadInfo))] }) -const makeIpcRenderer = payloadInfo => ({ getPayloadInfo: async () => payloadInfo }) +const makeClient = (payloadInfo: any) => makeClientForPlugin({ plugins: [plugin(makeIpcRenderer(payloadInfo))] }) +const makeIpcRenderer = (payloadInfo: any) => ({ getPayloadInfo: async () => payloadInfo }) diff --git a/packages/plugin-electron-renderer-strip-project-root/package.json b/packages/plugin-electron-renderer-strip-project-root/package.json index 96e1a56451..9260ee0c47 100644 --- a/packages/plugin-electron-renderer-strip-project-root/package.json +++ b/packages/plugin-electron-renderer-strip-project-root/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-renderer-strip-project-root", - "version": "8.4.0", + "version": "8.6.0", "main": "strip-project-root.js", "description": "@bugsnag/electron plugin to strip the project root from stack traces", "homepage": "https://www.bugsnag.com/", @@ -15,8 +15,8 @@ "*.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "author": "Bugsnag", "license": "MIT" diff --git a/packages/plugin-electron-screen-breadcrumbs/package.json b/packages/plugin-electron-screen-breadcrumbs/package.json index 548b9dc236..a30f2989c7 100644 --- a/packages/plugin-electron-screen-breadcrumbs/package.json +++ b/packages/plugin-electron-screen-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-screen-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "screen-breadcrumbs.js", "description": "@bugsnag/electron plugin to collect screen breadcrumbs", "repository": { @@ -14,8 +14,8 @@ "screen-breadcrumbs.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-electron-session/package.json b/packages/plugin-electron-session/package.json index 5c8d9d7c8f..cdc7a03286 100644 --- a/packages/plugin-electron-session/package.json +++ b/packages/plugin-electron-session/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-electron-session", - "version": "8.4.0", + "version": "8.6.0", "main": "session.js", "description": "@bugsnag/electron plugin for sessions", "repository": { @@ -14,11 +14,11 @@ "session.js" ], "dependencies": { - "@bugsnag/plugin-browser-session": "^8.4.0" + "@bugsnag/plugin-browser-session": "^8.6.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/electron-test-helpers": "^8.4.0" + "@bugsnag/core": "^8.6.0", + "@bugsnag/electron-test-helpers": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-express/package.json b/packages/plugin-express/package.json index 747566e850..a240e5368f 100644 --- a/packages/plugin-express/package.json +++ b/packages/plugin-express/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-express", - "version": "8.4.0", + "version": "8.6.0", "main": "src/express.js", "types": "types/bugsnag-express.d.ts", "description": "@bugsnag/js error handling middleware for Express (and Connect) web servers", @@ -22,7 +22,7 @@ "@bugsnag/core": "^8.2.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/express": "4.17.13" } } diff --git a/packages/plugin-hono/package.json b/packages/plugin-hono/package.json index 689fac1837..344c386363 100644 --- a/packages/plugin-hono/package.json +++ b/packages/plugin-hono/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-hono", - "version": "8.4.0", + "version": "8.6.0", "main": "src/hono.js", "types": "types/bugsnag-hono.d.ts", "description": "@bugsnag/js error handling middleware for Hono web servers", @@ -22,7 +22,7 @@ "@bugsnag/core": "^8.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "hono": "^4.6.3", "typescript": "^5.2.2" }, diff --git a/packages/plugin-inline-script-content/package.json b/packages/plugin-inline-script-content/package.json index 14c5e8d170..24fb29208a 100644 --- a/packages/plugin-inline-script-content/package.json +++ b/packages/plugin-inline-script-content/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-inline-script-content", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/inline-script-content.js", "types": "dist/types/inline-script-content.d.ts", "exports": { @@ -30,7 +30,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-interaction-breadcrumbs/package.json b/packages/plugin-interaction-breadcrumbs/package.json index 4e842012c5..3955ce69a7 100644 --- a/packages/plugin-interaction-breadcrumbs/package.json +++ b/packages/plugin-interaction-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-interaction-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/interaction-breadcrumbs.js", "types": "dist/types/interaction-breadcrumbs.d.ts", "exports": { @@ -30,7 +30,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-intercept/package.json b/packages/plugin-intercept/package.json index d7a790b9f5..347fbe2e2f 100644 --- a/packages/plugin-intercept/package.json +++ b/packages/plugin-intercept/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-intercept", - "version": "8.4.0", + "version": "8.6.0", "main": "intercept.js", "description": "@bugsnag/js plugin providing convenience functions for intercepting asynchronous errors", "homepage": "https://www.bugsnag.com/", @@ -18,7 +18,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-internal-callback-marker/package.json b/packages/plugin-internal-callback-marker/package.json index e0a3552d7d..f32d42160f 100644 --- a/packages/plugin-internal-callback-marker/package.json +++ b/packages/plugin-internal-callback-marker/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-internal-callback-marker", - "version": "8.4.0", + "version": "8.6.0", "main": "internal-callback-marker.js", "description": "@bugsnag/js plugin to annotate all OnError callbacks added by internal plugins", "homepage": "https://www.bugsnag.com/", @@ -18,7 +18,7 @@ "internal-callback-marker.js" ], "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-koa/package.json b/packages/plugin-koa/package.json index 5f033053fe..d6f6e582ce 100644 --- a/packages/plugin-koa/package.json +++ b/packages/plugin-koa/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-koa", - "version": "8.4.0", + "version": "8.6.0", "main": "src/koa.js", "types": "types/bugsnag-koa.d.ts", "description": "@bugsnag/js error handling middleware for Koa web servers", @@ -22,7 +22,7 @@ "@bugsnag/core": "^8.2.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/koa": "2.13.4" } } diff --git a/packages/plugin-navigation-breadcrumbs/package.json b/packages/plugin-navigation-breadcrumbs/package.json index 8f02d5dc63..a295a68683 100644 --- a/packages/plugin-navigation-breadcrumbs/package.json +++ b/packages/plugin-navigation-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-navigation-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/navigation-breadcrumbs.js", "types": "dist/types/navigation-breadcrumbs.d.ts", "exports": { @@ -30,7 +30,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-network-breadcrumbs/package.json b/packages/plugin-network-breadcrumbs/package.json index 026524a00f..bebb2cd681 100644 --- a/packages/plugin-network-breadcrumbs/package.json +++ b/packages/plugin-network-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-network-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/network-breadcrumbs.js", "types": "dist/types/network-breadcrumbs.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-node-device/package.json b/packages/plugin-node-device/package.json index 57b2746eb3..10b537d82a 100644 --- a/packages/plugin-node-device/package.json +++ b/packages/plugin-node-device/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-node-device", - "version": "8.4.0", + "version": "8.6.0", "main": "device.js", "description": "@bugsnag/js plugin to set device info in node", "homepage": "https://www.bugsnag.com/", @@ -18,7 +18,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-node-in-project/package.json b/packages/plugin-node-in-project/package.json index 717c9de9a9..67a672ada4 100644 --- a/packages/plugin-node-in-project/package.json +++ b/packages/plugin-node-in-project/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-node-in-project", - "version": "8.4.0", + "version": "8.6.0", "main": "in-project.js", "description": "@bugsnag/js plugin to mark whether stackframes are 'in-project'", "homepage": "https://www.bugsnag.com/", @@ -19,5 +19,8 @@ "license": "MIT", "dependencies": { "@bugsnag/path-normalizer": "^8.4.0" + }, + "devDependencies": { + "@bugsnag/core": "^8.6.0" } } diff --git a/packages/plugin-node-surrounding-code/package.json b/packages/plugin-node-surrounding-code/package.json index 2f0af18f91..363f07532c 100644 --- a/packages/plugin-node-surrounding-code/package.json +++ b/packages/plugin-node-surrounding-code/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-node-surrounding-code", - "version": "8.4.0", + "version": "8.6.0", "main": "surrounding-code.js", "description": "@bugsnag/js plugin to load surrounding code in Node stacktraces", "homepage": "https://www.bugsnag.com/", @@ -22,7 +22,7 @@ "pump": "^3.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-node-uncaught-exception/package.json b/packages/plugin-node-uncaught-exception/package.json index 7df190b307..021e0dc266 100644 --- a/packages/plugin-node-uncaught-exception/package.json +++ b/packages/plugin-node-uncaught-exception/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-node-uncaught-exception", - "version": "8.4.0", + "version": "8.6.0", "main": "uncaught-exception.js", "description": "@bugsnag/js plugin to capture and report uncaught exceptions", "homepage": "https://www.bugsnag.com/", @@ -18,7 +18,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-node-unhandled-rejection/package.json b/packages/plugin-node-unhandled-rejection/package.json index 55582d19eb..48686f3479 100644 --- a/packages/plugin-node-unhandled-rejection/package.json +++ b/packages/plugin-node-unhandled-rejection/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-node-unhandled-rejection", - "version": "8.4.0", + "version": "8.6.0", "main": "unhandled-rejection.js", "description": "@bugsnag/js plugin to capture and report unhandled rejections", "homepage": "https://www.bugsnag.com/", @@ -18,7 +18,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-react-native-client-sync/package.json b/packages/plugin-react-native-client-sync/package.json index 747381ad56..b75de10f8f 100644 --- a/packages/plugin-react-native-client-sync/package.json +++ b/packages/plugin-react-native-client-sync/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-client-sync", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/client-sync.js", "description": "@bugsnag/react-native plugin to sync information between JS and native layer", "homepage": "https://www.bugsnag.com/", @@ -16,12 +16,11 @@ ], "author": "Bugsnag", "license": "MIT", - "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/derecursify": "^8.4.0" + "dependencies": { + "@bugsnag/derecursify": "^8.6.0" }, - "peerDependencies": { - "@bugsnag/core": "^8.0.0" + "devDependencies": { + "@bugsnag/core": "^8.6.0" }, "scripts": { "build": "rollup --config rollup.config.js", diff --git a/packages/plugin-react-native-client-sync/src/client-sync.js b/packages/plugin-react-native-client-sync/src/client-sync.js index ca95b53ce0..0300b0c2e1 100644 --- a/packages/plugin-react-native-client-sync/src/client-sync.js +++ b/packages/plugin-react-native-client-sync/src/client-sync.js @@ -25,6 +25,13 @@ module.exports = (NativeClient) => ({ return ret } + const origSetGroupingDiscriminator = client.setGroupingDiscriminator + client.setGroupingDiscriminator = function () { + const ret = origSetGroupingDiscriminator.apply(this, arguments) + NativeClient.updateGroupingDiscriminator(this._groupingDiscriminator) + return ret + } + const origAddMetadata = client.addMetadata client.addMetadata = function (section, key, value) { const ret = origAddMetadata.apply(this, arguments) @@ -99,6 +106,9 @@ module.exports = (NativeClient) => ({ case 'ContextUpdate': origSetContext.call(client, event.data) break + case 'GroupingDiscriminatorUpdate': + origSetGroupingDiscriminator.call(client, event.data) + break case 'AddFeatureFlag': origAddFeatureFlag.call(client, event.data.name, event.data.variant) break diff --git a/packages/plugin-react-native-client-sync/test/client-sync.test.ts b/packages/plugin-react-native-client-sync/test/client-sync.test.ts index 4c4c7e5406..8a85dff866 100644 --- a/packages/plugin-react-native-client-sync/test/client-sync.test.ts +++ b/packages/plugin-react-native-client-sync/test/client-sync.test.ts @@ -31,6 +31,21 @@ describe('plugin: react native client sync', () => { c.setContext('1234') }) + it('updates grouping discriminator', done => { + const c = new Client({ + apiKey: 'api_key', + plugins: [ + plugin({ + updateGroupingDiscriminator: (update: any) => { + expect(update).toBe('test-discriminator') + done() + } + }) + ] + }) + c.setGroupingDiscriminator('test-discriminator') + }) + it('updates metadata', done => { const c = new Client({ apiKey: 'api_key', @@ -186,6 +201,19 @@ describe('plugin: react native client sync', () => { }, 1) }) + it('silently updates grouping discriminator when an update is received', () => { + MockAddListener.mockImplementation((event: any, listener: (payload: any) => void) => { + setTimeout(() => listener({ type: 'GroupingDiscriminatorUpdate', data: 'new-discriminator' }), 0) + }) + const c = new Client({ apiKey: 'api_key', plugins: [plugin()] }) + expect(MockAddListener).toHaveBeenCalledWith('bugsnag::sync', expect.any(Function)) + expect(c.getGroupingDiscriminator()).toBe(undefined) + + setTimeout(() => { + expect(c.getGroupingDiscriminator()).toBe('new-discriminator') + }, 1) + }) + it('silently updates user when an update is received', () => { MockAddListener.mockImplementation((event: any, listener: (payload: any) => void) => { setTimeout(() => listener({ type: 'UserUpdate', data: { id: '1234', name: 'Ben', email: 'ben@bensnag.be' } }), 0) diff --git a/packages/plugin-react-native-event-sync/package.json b/packages/plugin-react-native-event-sync/package.json index 539405c906..4c1527ebdc 100644 --- a/packages/plugin-react-native-event-sync/package.json +++ b/packages/plugin-react-native-event-sync/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-event-sync", - "version": "8.4.0", + "version": "8.6.0", "main": "event-sync.js", "description": "@bugsnag/react-native plugin to sync native event information in an onError callbacks", "homepage": "https://www.bugsnag.com/", @@ -17,7 +17,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-react-native-global-error-handler/package.json b/packages/plugin-react-native-global-error-handler/package.json index b15aea033e..a5a8173ff7 100644 --- a/packages/plugin-react-native-global-error-handler/package.json +++ b/packages/plugin-react-native-global-error-handler/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-global-error-handler", - "version": "8.4.0", + "version": "8.6.0", "main": "error-handler.js", "description": "@bugsnag/js plugin to report unhandled exceptions in React Native", "homepage": "https://www.bugsnag.com/", @@ -17,7 +17,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { diff --git a/packages/plugin-react-native-hermes/package.json b/packages/plugin-react-native-hermes/package.json index f254e8f978..fa1efc591f 100644 --- a/packages/plugin-react-native-hermes/package.json +++ b/packages/plugin-react-native-hermes/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-hermes", - "version": "8.4.0", + "version": "8.6.0", "main": "hermes.js", "description": "@bugsnag/react-native plugin to support Hermes", "homepage": "https://www.bugsnag.com/", @@ -20,7 +20,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { diff --git a/packages/plugin-react-native-navigation/package.json b/packages/plugin-react-native-navigation/package.json index e9070bbbc8..2946b81789 100644 --- a/packages/plugin-react-native-navigation/package.json +++ b/packages/plugin-react-native-navigation/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-navigation", - "version": "8.4.0", + "version": "8.6.0", "main": "react-native-navigation.js", "types": "types/react-native-navigation.d.ts", "description": "@bugsnag/react-native plugin for integration with react-native-navigation", @@ -19,7 +19,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "react-native-navigation": "^7.0.0" }, "peerDependencies": { diff --git a/packages/plugin-react-native-orientation-breadcrumbs/package.json b/packages/plugin-react-native-orientation-breadcrumbs/package.json index c142c6557f..e4468f106e 100644 --- a/packages/plugin-react-native-orientation-breadcrumbs/package.json +++ b/packages/plugin-react-native-orientation-breadcrumbs/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-orientation-breadcrumbs", - "version": "8.4.0", + "version": "8.6.0", "main": "orientation.js", "description": "@bugsnag/js plugin to create breadcrumbs when the device orientation changes in a React Native app", "homepage": "https://www.bugsnag.com/", @@ -17,7 +17,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { diff --git a/packages/plugin-react-native-session/package.json b/packages/plugin-react-native-session/package.json index 3c347141a9..9988f81e8d 100644 --- a/packages/plugin-react-native-session/package.json +++ b/packages/plugin-react-native-session/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-session", - "version": "8.4.0", + "version": "8.6.0", "main": "session.js", "description": "@bugsnag/react-native session implementation (which delegates all functionality to the native client)", "homepage": "https://www.bugsnag.com/", @@ -17,7 +17,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/react-native": "0.67.8" }, "peerDependencies": { diff --git a/packages/plugin-react-native-unhandled-rejection/package.json b/packages/plugin-react-native-unhandled-rejection/package.json index c287029735..0f9d7d1036 100644 --- a/packages/plugin-react-native-unhandled-rejection/package.json +++ b/packages/plugin-react-native-unhandled-rejection/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-native-unhandled-rejection", - "version": "8.4.0", + "version": "8.6.0", "main": "rejection-handler.js", "description": "@bugsnag/js plugin to report unhandled promise rejections in React Native", "homepage": "https://www.bugsnag.com/", @@ -17,7 +17,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "promise": "^8.0.2" }, "peerDependencies": { diff --git a/packages/plugin-react-navigation/package.json b/packages/plugin-react-navigation/package.json index a3cda353ec..1f9dd15b2b 100644 --- a/packages/plugin-react-navigation/package.json +++ b/packages/plugin-react-navigation/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-react-navigation", - "version": "8.4.0", + "version": "8.6.0", "main": "react-navigation.js", "description": "@bugsnag/react-native plugin to update context and leave breadcrumb when the screen changes", "homepage": "https://www.bugsnag.com/", @@ -22,7 +22,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@react-navigation/native": "^5.7.3", "@types/react": "^16.9.49", "@types/react-test-renderer": "^16.9.3", diff --git a/packages/plugin-react/package.json b/packages/plugin-react/package.json index 4285647f9f..66a3bcd098 100644 --- a/packages/plugin-react/package.json +++ b/packages/plugin-react/package.json @@ -1,7 +1,7 @@ { "name": "@bugsnag/plugin-react", "description": "React integration for @bugsnag/js", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/index-cjs.cjs", "types": "dist/types/index-es.d.ts", "browser": "dist/bugsnag-react.js", @@ -31,7 +31,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-restify/package.json b/packages/plugin-restify/package.json index 19f22ad447..8ec2e3a633 100644 --- a/packages/plugin-restify/package.json +++ b/packages/plugin-restify/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-restify", - "version": "8.4.0", + "version": "8.6.0", "main": "src/restify.js", "types": "types/bugsnag-restify.d.ts", "description": "@bugsnag/js error handling middleware for Restify web servers", @@ -22,7 +22,7 @@ "@bugsnag/core": "^8.2.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0", + "@bugsnag/core": "^8.6.0", "@types/restify": "^8.4.2" } } diff --git a/packages/plugin-server-session/package.json b/packages/plugin-server-session/package.json index 1903c6ee77..b1f097480a 100644 --- a/packages/plugin-server-session/package.json +++ b/packages/plugin-server-session/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-server-session", - "version": "8.4.0", + "version": "8.6.0", "main": "session.js", "description": "@bugsnag/js plugin to enable session tracking in server applications", "homepage": "https://www.bugsnag.com/", @@ -20,7 +20,7 @@ "backo": "^1.1.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-simple-throttle/package.json b/packages/plugin-simple-throttle/package.json index 87195b99e0..5680d3c880 100644 --- a/packages/plugin-simple-throttle/package.json +++ b/packages/plugin-simple-throttle/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-simple-throttle", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/throttle.js", "types": "dist/types/throttle.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-stackframe-path-normaliser/package.json b/packages/plugin-stackframe-path-normaliser/package.json index 1b607806ee..e8dafa5ebd 100644 --- a/packages/plugin-stackframe-path-normaliser/package.json +++ b/packages/plugin-stackframe-path-normaliser/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-stackframe-path-normaliser", - "version": "8.4.0", + "version": "8.6.0", "main": "path-normaliser.js", "description": "@bugsnag/js plugin to normalise file paths in stackframes", "homepage": "https://www.bugsnag.com/", @@ -17,6 +17,6 @@ "@bugsnag/core": "^8.0.0" }, "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" } } diff --git a/packages/plugin-strip-project-root/package.json b/packages/plugin-strip-project-root/package.json index 4c8b68b64c..3e1446f9ad 100644 --- a/packages/plugin-strip-project-root/package.json +++ b/packages/plugin-strip-project-root/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-strip-project-root", - "version": "8.4.0", + "version": "8.6.0", "main": "strip-project-root.js", "description": "@bugsnag/js plugin to remove common project root paths from stacktraces", "homepage": "https://www.bugsnag.com/", @@ -18,5 +18,8 @@ "license": "MIT", "dependencies": { "@bugsnag/path-normalizer": "^8.4.0" + }, + "devDependencies": { + "@bugsnag/core": "^8.6.0" } } diff --git a/packages/plugin-strip-query-string/package.json b/packages/plugin-strip-query-string/package.json index 286bee8a03..40ee0ce0f7 100644 --- a/packages/plugin-strip-query-string/package.json +++ b/packages/plugin-strip-query-string/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-strip-query-string", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/strip-query-string.js", "types": "dist/types/strip-query-string.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-vue/package.json b/packages/plugin-vue/package.json index e54a1f28e2..3d4889f9eb 100644 --- a/packages/plugin-vue/package.json +++ b/packages/plugin-vue/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-vue", - "version": "8.4.0", + "version": "8.6.0", "description": "Vue.js integration for bugsnag-js", "main": "dist/index.cjs", "types": "dist/types/index.d.ts", @@ -31,7 +31,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-window-onerror/package.json b/packages/plugin-window-onerror/package.json index 00d7d37fab..2c0f1eb244 100644 --- a/packages/plugin-window-onerror/package.json +++ b/packages/plugin-window-onerror/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-window-onerror", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/onerror.js", "types": "dist/types/onerror.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/plugin-window-unhandled-rejection/package.json b/packages/plugin-window-unhandled-rejection/package.json index c9b1ec7a70..c5074dc140 100644 --- a/packages/plugin-window-unhandled-rejection/package.json +++ b/packages/plugin-window-unhandled-rejection/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/plugin-window-unhandled-rejection", - "version": "8.4.0", + "version": "8.6.0", "main": "dist/unhandled-rejection.js", "types": "dist/types/unhandled-rejection.d.ts", "exports": { @@ -25,7 +25,7 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0" + "@bugsnag/core": "^8.6.0" }, "peerDependencies": { "@bugsnag/core": "^8.0.0" diff --git a/packages/react-native/android/src/main/java/com/bugsnag/android/BugsnagReactNativeImpl.java b/packages/react-native/android/src/main/java/com/bugsnag/android/BugsnagReactNativeImpl.java index 83d59938b5..91fdab2040 100644 --- a/packages/react-native/android/src/main/java/com/bugsnag/android/BugsnagReactNativeImpl.java +++ b/packages/react-native/android/src/main/java/com/bugsnag/android/BugsnagReactNativeImpl.java @@ -23,6 +23,7 @@ class BugsnagReactNativeImpl { static final String MODULE_NAME = "BugsnagReactNative"; private static final String UPDATE_CONTEXT = "ContextUpdate"; + private static final String UPDATE_GROUPING_DISCRIMINATOR = "GroupingDiscriminatorUpdate"; private static final String UPDATE_USER = "UserUpdate"; private static final String UPDATE_METADATA = "MetadataUpdate"; private static final String ADD_FEATURE_FLAG = "AddFeatureFlag"; @@ -85,6 +86,7 @@ void emitEvent(MessageEvent event) { switch (event.getType()) { case UPDATE_CONTEXT: + case UPDATE_GROUPING_DISCRIMINATOR: map.putString(DATA_KEY, (String) event.getData()); break; case UPDATE_USER: @@ -161,6 +163,14 @@ void updateContext(@Nullable String context) { } } + void updateGroupingDiscriminator(@Nullable String groupingDiscriminator) { + try { + plugin.updateGroupingDiscriminator(groupingDiscriminator); + } catch (Throwable exc) { + logFailure("updateGroupingDiscriminator", exc); + } + } + void addMetadata(@NonNull String section, @Nullable ReadableMap data) { try { plugin.addMetadata(section, data != null ? data.toHashMap() : null); diff --git a/packages/react-native/android/src/newarch/java/com/bugsnag/android/NativeBugsnagImpl.java b/packages/react-native/android/src/newarch/java/com/bugsnag/android/NativeBugsnagImpl.java index 30ba97a0e8..c876390ef6 100644 --- a/packages/react-native/android/src/newarch/java/com/bugsnag/android/NativeBugsnagImpl.java +++ b/packages/react-native/android/src/newarch/java/com/bugsnag/android/NativeBugsnagImpl.java @@ -71,6 +71,11 @@ public void updateContext(@Nullable String context) { impl.updateContext(context); } + @Override + public void updateGroupingDiscriminator(@Nullable String groupingDiscriminator) { + impl.updateGroupingDiscriminator(groupingDiscriminator); + } + @Override public void addMetadata(String section, ReadableMap metadata) { impl.addMetadata(section, metadata); diff --git a/packages/react-native/android/src/oldarch/java/com/bugsnag/android/BugsnagReactNative.java b/packages/react-native/android/src/oldarch/java/com/bugsnag/android/BugsnagReactNative.java index 58acaad285..c1358177b8 100644 --- a/packages/react-native/android/src/oldarch/java/com/bugsnag/android/BugsnagReactNative.java +++ b/packages/react-native/android/src/oldarch/java/com/bugsnag/android/BugsnagReactNative.java @@ -77,6 +77,11 @@ void updateContext(@Nullable String context) { impl.updateContext(context); } + @ReactMethod + void updateGroupingDiscriminator(@Nullable String groupingDiscriminator) { + impl.updateGroupingDiscriminator(groupingDiscriminator); + } + @ReactMethod void addMetadata(@NonNull String section, @Nullable ReadableMap data) { impl.addMetadata(section, data); diff --git a/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m b/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m index b781b7e87c..38547b6f4e 100644 --- a/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m +++ b/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m @@ -30,6 +30,7 @@ - (BugsnagEvent *)deserializeEvent:(NSDictionary *)payload { session:nil /* set by -[BugsnagClient notifyInternal:block:] */]; event.context = payload[@"context"]; event.groupingHash = payload[@"groupingHash"]; + event.groupingDiscriminator = payload[@"groupingDiscriminator"]; [event setCorrelationTraceId:correlation[@"traceId"] spanId:correlation[@"spanId"]]; diff --git a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.mm b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.mm index f0732c3186..6a5faa90a1 100644 --- a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.mm +++ b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.mm @@ -73,6 +73,11 @@ @implementation BugsnagReactNative BSG_EXPORT_RETURN } +BSG_EXPORT_METHOD(updateGroupingDiscriminator:(NSString *)groupingDiscriminator) { + [Bugsnag setGroupingDiscriminator:groupingDiscriminator]; + BSG_EXPORT_RETURN +} + BSG_EXPORT_METHOD(updateCodeBundleId:(NSString *)codeBundleId) { Bugsnag.client.codeBundleId = codeBundleId; BSG_EXPORT_RETURN diff --git a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m index bbc933ceef..e41b2e961a 100644 --- a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m +++ b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m @@ -77,6 +77,15 @@ - (NSDictionary *)serializeClientObserverEvent:(BSGClientObserverEvent)event wit }; } break; + + case BSGClientObserverUpdateGroupingDiscriminator: + if ([value isKindOfClass:[NSString class]] || !value) { + return @{ + @"type": @"GroupingDiscriminatorUpdate", + @"data": value ?: [NSNull null] + }; + } + break; } return nil; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa b/packages/react-native/ios/vendor/bugsnag-cocoa index 8dcc68b843..1f991e92a6 160000 --- a/packages/react-native/ios/vendor/bugsnag-cocoa +++ b/packages/react-native/ios/vendor/bugsnag-cocoa @@ -1 +1 @@ -Subproject commit 8dcc68b843fe38c67075d32e9532be76ee388ed9 +Subproject commit 1f991e92a6e3993c2763d071781d895ca4075a90 diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 4082758a57..d5bdd195b7 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/react-native", - "version": "8.4.0", + "version": "8.7.0", "main": "src/notifier.js", "types": "types/bugsnag.d.ts", "description": "Bugsnag error reporter for React Native applications", @@ -54,17 +54,17 @@ "typescript": "^3.3.3" }, "dependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-react-native": "^8.4.0", - "@bugsnag/plugin-console-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-network-breadcrumbs": "^8.4.0", - "@bugsnag/plugin-react": "^8.4.0", - "@bugsnag/plugin-react-native-client-sync": "^8.4.0", - "@bugsnag/plugin-react-native-event-sync": "^8.4.0", - "@bugsnag/plugin-react-native-global-error-handler": "^8.4.0", - "@bugsnag/plugin-react-native-hermes": "^8.4.0", - "@bugsnag/plugin-react-native-session": "^8.4.0", - "@bugsnag/plugin-react-native-unhandled-rejection": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-react-native": "^8.6.0", + "@bugsnag/plugin-console-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-network-breadcrumbs": "^8.6.0", + "@bugsnag/plugin-react": "^8.6.0", + "@bugsnag/plugin-react-native-client-sync": "^8.6.0", + "@bugsnag/plugin-react-native-event-sync": "^8.6.0", + "@bugsnag/plugin-react-native-global-error-handler": "^8.6.0", + "@bugsnag/plugin-react-native-hermes": "^8.6.0", + "@bugsnag/plugin-react-native-session": "^8.6.0", + "@bugsnag/plugin-react-native-unhandled-rejection": "^8.6.0", "iserror": "^0.0.2" }, "scripts": { diff --git a/packages/react-native/src/NativeBugsnag.ts b/packages/react-native/src/NativeBugsnag.ts index 118b024ee9..dd50022156 100644 --- a/packages/react-native/src/NativeBugsnag.ts +++ b/packages/react-native/src/NativeBugsnag.ts @@ -42,6 +42,8 @@ export interface Spec extends TurboModule { clearFeatureFlag(name: string): void clearFeatureFlags(): void + + updateGroupingDiscriminator(groupingDiscriminator: string | undefined | null): void } diff --git a/packages/web-worker/package.json b/packages/web-worker/package.json index 045a7ad629..78a247ee10 100644 --- a/packages/web-worker/package.json +++ b/packages/web-worker/package.json @@ -1,6 +1,6 @@ { "name": "@bugsnag/web-worker", - "version": "8.4.0", + "version": "8.6.0", "description": "BugSnag error reporter for JavaScript web workers and service workers", "homepage": "https://www.bugsnag.com/", "main": "dist/index.js", @@ -42,13 +42,13 @@ "author": "Bugsnag", "license": "MIT", "devDependencies": { - "@bugsnag/core": "^8.4.0", - "@bugsnag/delivery-fetch": "^8.4.0", - "@bugsnag/plugin-browser-device": "^8.4.0", - "@bugsnag/plugin-browser-session": "^8.4.0", - "@bugsnag/plugin-client-ip": "^8.4.0", - "@bugsnag/plugin-window-onerror": "^8.4.0", - "@bugsnag/plugin-window-unhandled-rejection": "^8.4.0", + "@bugsnag/core": "^8.6.0", + "@bugsnag/delivery-fetch": "^8.6.0", + "@bugsnag/plugin-browser-device": "^8.6.0", + "@bugsnag/plugin-browser-session": "^8.6.0", + "@bugsnag/plugin-client-ip": "^8.6.0", + "@bugsnag/plugin-window-onerror": "^8.6.0", + "@bugsnag/plugin-window-unhandled-rejection": "^8.6.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", "@rollup/plugin-node-resolve": "^16.0.0", diff --git a/scripts/generate-react-native-cli-fixture.js b/scripts/generate-react-native-cli-fixture.js index 90983cba43..010acd2520 100644 --- a/scripts/generate-react-native-cli-fixture.js +++ b/scripts/generate-react-native-cli-fixture.js @@ -22,7 +22,7 @@ if (!process.env.RCT_NEW_ARCH_ENABLED || (process.env.RCT_NEW_ARCH_ENABLED !== ' process.exit(1) } -const notifierVersion = process.env.NOTIFIER_VERSION || common.getCommitId() +const notifierVersion = process.env.NOTIFIER_VERSION || common.determineVersion() const reactNativeVersion = process.env.RN_VERSION const ROOT_DIR = resolve(__dirname, '../') diff --git a/scripts/generate-react-native-fixture.js b/scripts/generate-react-native-fixture.js index de9feaa11a..597fe32d53 100644 --- a/scripts/generate-react-native-fixture.js +++ b/scripts/generate-react-native-fixture.js @@ -40,6 +40,7 @@ const replacementFilesDir = resolve(ROOT_DIR, 'test/react-native/features/fixtur const INTERNAL_DEPENDENCIES = [ '@bugsnag/react-native', + '@bugsnag/derecursify', '@bugsnag/plugin-react-navigation', '@bugsnag/plugin-react-native-navigation' ] diff --git a/test/aws-lambda/Gemfile b/test/aws-lambda/Gemfile index 2c6a8f9ddf..3be2e6f61c 100644 --- a/test/aws-lambda/Gemfile +++ b/test/aws-lambda/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'bugsnag-maze-runner', '~>9.0' +gem 'bugsnag-maze-runner', '~>10.0' # Use a branch of Maze Runner # gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner', branch: 'tms/use-maze-check' diff --git a/test/browser/Gemfile b/test/browser/Gemfile index c1ff00ee7b..5066a995c9 100644 --- a/test/browser/Gemfile +++ b/test/browser/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'bugsnag-maze-runner', '~> 9.0' +gem 'bugsnag-maze-runner', '~> 10.0' # Use a branch of Maze Runner #gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner', branch: 'tms/use-maze-check' diff --git a/test/browser/features/fixtures/browser_errors.yml b/test/browser/features/fixtures/browser_errors.yml index 610b2d2227..77a30e4cc0 100644 --- a/test/browser/features/fixtures/browser_errors.yml +++ b/test/browser/features/fixtures/browser_errors.yml @@ -103,7 +103,7 @@ safari_16: lineNumber: 18 columnNumber: 25 -ios_10: +ios_11: handled: errorClass: 'ReferenceError' errorMessage: "Can't find variable: foo" @@ -129,7 +129,7 @@ ios_10: lineNumber: 18 columnNumber: 25 -ios_11: +ios_15: handled: errorClass: 'ReferenceError' errorMessage: "Can't find variable: foo" @@ -155,33 +155,33 @@ ios_11: lineNumber: 18 columnNumber: 25 -ios_15: +android_4: handled: errorClass: 'ReferenceError' - errorMessage: "Can't find variable: foo" + errorMessage: 'foo is not defined' unhandled_syntax: errorClass: 'SyntaxError' - errorMessage: "Unexpected token '!'. Parse error." + errorMessage: "Unexpected token '!'" lineNumber: 18 - columnNumber: 0 + columnNumber: 13 file: '/unhandled/script/a.html' unhandled_thrown: errorClass: 'Error' errorMessage: "bad things" lineNumber: 18 - columnNumber: 22 + columnNumber: 13 unhandled_undefined_function: errorClass: 'ReferenceError' - errorMessage: "Can't find variable: nevergoingtoexist_notinamillionyears" + errorMessage: nevergoingtoexist_notinamillionyears is not defined lineNumber: 18 - columnNumber: 43 + columnNumber: 7 unhandled_malformed_uri: errorClass: 'URIError' - errorMessage: URI error + errorMessage: URI malformed lineNumber: 18 - columnNumber: 25 + columnNumber: 7 -android_4: +android_6: handled: errorClass: 'ReferenceError' errorMessage: 'foo is not defined' @@ -207,7 +207,7 @@ android_4: lineNumber: 18 columnNumber: 7 -android_6: +android_7: handled: errorClass: 'ReferenceError' errorMessage: 'foo is not defined' @@ -233,7 +233,7 @@ android_6: lineNumber: 18 columnNumber: 7 -android_7: +android_8: handled: errorClass: 'ReferenceError' errorMessage: 'foo is not defined' @@ -259,7 +259,7 @@ android_7: lineNumber: 18 columnNumber: 7 -android_8: +android_9: handled: errorClass: 'ReferenceError' errorMessage: 'foo is not defined' diff --git a/test/browser/features/fixtures/grouping_discriminator/script/index.html b/test/browser/features/fixtures/grouping_discriminator/script/index.html new file mode 100644 index 0000000000..525a9dde50 --- /dev/null +++ b/test/browser/features/fixtures/grouping_discriminator/script/index.html @@ -0,0 +1,44 @@ + + + + + + + + + + + diff --git a/test/browser/features/fixtures/strict_mode/script/a.html b/test/browser/features/fixtures/strict_mode/script/a.html deleted file mode 100644 index df14a60d5e..0000000000 --- a/test/browser/features/fixtures/strict_mode/script/a.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - -
PENDING
- - - - - diff --git a/test/browser/features/fixtures/strict_mode/script/notifier-does-not-error.html b/test/browser/features/fixtures/strict_mode/script/notifier-does-not-error.html new file mode 100644 index 0000000000..8a5e2333d3 --- /dev/null +++ b/test/browser/features/fixtures/strict_mode/script/notifier-does-not-error.html @@ -0,0 +1,50 @@ + + + + + + + + + diff --git a/test/browser/features/grouping_discriminator.feature b/test/browser/features/grouping_discriminator.feature new file mode 100644 index 0000000000..b4b42922c2 --- /dev/null +++ b/test/browser/features/grouping_discriminator.feature @@ -0,0 +1,15 @@ +@grouping_discriminator +Feature: Grouping discriminator functionality + +Scenario: multiple notify() calls with different grouping discriminators + When I navigate to the test URL "/grouping_discriminator/script/index.html" + Then I wait to receive 6 errors + And the error is a valid browser payload for the error reporting API + And the following sets are present in the current error payloads: + | events.0.exceptions.0.message | events.0.groupingDiscriminator | + | no-discriminator | nil | + | client-discriminator | client-discriminator | + | event-discriminator | event-discriminator | + | null-discriminator | nil | + | undefined-discriminator | nil | + | no-discriminator-2 | nil | diff --git a/test/browser/features/integrity.feature b/test/browser/features/integrity.feature index 1e5eba9994..009fa26811 100644 --- a/test/browser/features/integrity.feature +++ b/test/browser/features/integrity.feature @@ -1,4 +1,4 @@ -@skip_ie_11 @skip_ios_10 @skip_safari_10 @skip_safari_16 @skip_edge_17 @skip_chrome_43 @skip_http +@skip_ie_11 @skip_safari_10 @skip_safari_16 @skip_edge_17 @skip_chrome_43 @skip_http Feature: Bugsnag-Integrity header Scenario: Integrity headers are set when setPayloadChecksums is true diff --git a/test/browser/features/steps/browser_steps.rb b/test/browser/features/steps/browser_steps.rb index a339db8526..ed0ae21324 100644 --- a/test/browser/features/steps/browser_steps.rb +++ b/test/browser/features/steps/browser_steps.rb @@ -44,3 +44,24 @@ txt = Maze.driver.find_element(id: 'bugsnag-test-state').text Maze.check.equal('DONE', txt, "Expected #bugsnag-test-state text to be 'DONE'. It was '#{txt}'.") end + +When('the following sets are present in the current {word} payloads:') do |request_type, data_table| + expected_values = data_table.hashes + requests = Maze::Server.list_for(request_type) + Maze.check.equal(expected_values.length, requests.size_all) + payload_values = requests.all.map do |request| + payload_hash = {} + data_table.headers.each_with_object(payload_hash) do |field_path, payload_hash| + payload_hash[field_path] = Maze::Helper.read_key_path(request[:body], field_path) + end + payload_hash + end + expected_values.each do |expected_data| + # if value is 'nil' then the field should not be present in the payload + expected_data.each do |field_path, expected_value| + expected_data[field_path] = nil if expected_value == 'nil' + end + Maze.check.true(payload_values.include?(expected_data), + "#{expected_data} was not found in any of the current payloads") + end +end diff --git a/test/browser/features/strict_mode.feature b/test/browser/features/strict_mode.feature index 6907eabe8f..e4f63a6643 100644 --- a/test/browser/features/strict_mode.feature +++ b/test/browser/features/strict_mode.feature @@ -2,8 +2,7 @@ Feature: Compatibility with strict mode Scenario: notifier does not error in strict mode - When I navigate to the test URL "/strict_mode/script/a.html" - And the test should run in this browser + When I navigate to the test URL "/strict_mode/script/notifier-does-not-error.html" Then I wait to receive an error And the error is a valid browser payload for the error reporting API And the exception "errorClass" equals "InvalidError" diff --git a/test/browser/features/web_worker.feature b/test/browser/features/web_worker.feature index d1d4ad9538..857d6ee542 100644 --- a/test/browser/features/web_worker.feature +++ b/test/browser/features/web_worker.feature @@ -44,7 +44,8 @@ Feature: worker notifier And I wait to receive a session Then the session is a valid browser payload for the session tracking API - @skip_safari_16 + # Not supported on Safari https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Integrity-Policy#browser_compatibility + @skip_safari_16 @skip_ios_12 Scenario: Integrity headers are set when setPayloadChecksums is true When I navigate to the test URL "/web_worker/integrity" And I wait to receive an error diff --git a/test/electron/features/error-handling.feature b/test/electron/features/error-handling.feature index eb7a7065f9..9a1008913a 100644 --- a/test/electron/features/error-handling.feature +++ b/test/electron/features/error-handling.feature @@ -105,3 +105,15 @@ Feature: Detecting and reporting errors | config | | default | | complex-config | + + Scenario: Main process uses main codeBundleId when different from renderer + Given I launch an app with configuration: + | bugsnag | mixed-codebundleid | + When I click "main-notify" + Then the total requests received by the server matches: + | events | 1 | + Then the headers of every event request contains: + | Bugsnag-API-Key | 6425093c6530f554a9897d2d7d38e248 | + | Content-Type | application/json | + | Bugsnag-Integrity | {BODY_SHA1} | + Then the contents of an event request matches "main/handled-error/mixed-codebundleid.json" diff --git a/test/electron/features/grouping-discriminator.feature b/test/electron/features/grouping-discriminator.feature new file mode 100644 index 0000000000..2415f038b0 --- /dev/null +++ b/test/electron/features/grouping-discriminator.feature @@ -0,0 +1,39 @@ +Feature: Additional grouping discriminator + Grouping discriminator field is included in electron events + and can be passed between renderer and main processes. + + Scenario: Main process grouping discriminator is sent with main errors + Given I launch an app with configuration: + | bugsnag | default | + When I click "main-process-set-grouping-discriminator" + And I click "main-notify" + Then the total requests received by the server matches: + | events | 1 | + And the event "groupingDiscriminator" equals "main-process-discriminator" + + Scenario: Renderer process grouping discriminator is sent with renderer errors + Given I launch an app with configuration: + | bugsnag | default | + When I click "renderer-set-grouping-discriminator" + And I click "renderer-notify" + Then the total requests received by the server matches: + | events | 1 | + And the event "groupingDiscriminator" equals "renderer-process-discriminator" + + Scenario: Main process grouping discriminator persists across renderer errors + Given I launch an app with configuration: + | bugsnag | default | + When I click "main-process-set-grouping-discriminator" + And I click "renderer-notify" + Then the total requests received by the server matches: + | events | 1 | + And the event "groupingDiscriminator" equals "main-process-discriminator" + + Scenario: Renderer process grouping discriminator persists across main errors + Given I launch an app with configuration: + | bugsnag | default | + When I click "renderer-set-grouping-discriminator" + And I click "main-notify" + Then the total requests received by the server matches: + | events | 1 | + And the event "groupingDiscriminator" equals "renderer-process-discriminator" diff --git a/test/electron/features/renderer-config.feature b/test/electron/features/renderer-config.feature index d8ede118ca..3c6553bc93 100644 --- a/test/electron/features/renderer-config.feature +++ b/test/electron/features/renderer-config.feature @@ -37,4 +37,16 @@ Feature: Setting config options in renderers | property | config | | clear-user | { "user": { "id": "3", "name": "Bugs Nag", "email": "bugs.nag@bugsnag.com" } } | | clear-context | { "context": "renderer context" } | - | clear-metadata | { "metadata": { "renderer": { "key": "value" } } } | \ No newline at end of file + | clear-metadata | { "metadata": { "renderer": { "key": "value" } } } | + + Scenario: Different codeBundleId values in main and renderer processes + Given I launch an app with configuration: + | bugsnag | mixed-codebundleid | + And I click "renderer-notify" + Then the total requests received by the server matches: + | events | 1 | + Then the headers of every event request contains: + | Bugsnag-API-Key | 6425093c6530f554a9897d2d7d38e248 | + | Content-Type | application/json | + | Bugsnag-Integrity | {BODY_SHA1} | + Then the contents of an event request matches "renderer/config/mixed-codebundleid.json" \ No newline at end of file diff --git a/test/electron/features/support/steps/request-steps.js b/test/electron/features/support/steps/request-steps.js index c35ea8166e..ffaeab856e 100644 --- a/test/electron/features/support/steps/request-steps.js +++ b/test/electron/features/support/steps/request-steps.js @@ -41,6 +41,18 @@ Given('I launch an app with configuration:', launchConfig, (data) => { setup[key] = config }) + // If no explicit renderer_config was provided, check if the bugsnag config file has a renderer export + if (setup.renderer_config === '{}' && setup.bugsnag !== 'default') { + try { + const configModule = require(`../../../fixtures/app/src/configs/${setup.bugsnag}.js`) + if (typeof configModule.renderer === 'function') { + setup.renderer_config = JSON.stringify(configModule.renderer()) + } + } catch (e) { + // If the config file doesn't exist or doesn't have a renderer export, use the default + } + } + return global.automator.start({ BUGSNAG_CONFIG: setup.bugsnag, BUGSNAG_PRELOAD: setup.preload, @@ -252,3 +264,11 @@ Then('the event has no feature flags', async () => { expect(payloads[0].events).toHaveLength(1) expect(payloads[0].events[0]).toHaveProperty('featureFlags', []) }) + +Then('the event {string} equals {string}', async (field, expected) => { + const payloads = readPayloads(global.server.uploadsForType('event')) + + expect(payloads).toHaveLength(1) + expect(payloads[0].events).toHaveLength(1) + expect(payloads[0].events[0]).toHaveProperty(field, expected) +}) diff --git a/test/electron/fixtures/app/src/configs/complex-config.js b/test/electron/fixtures/app/src/configs/complex-config.js index 540a85f7af..c49cc3b6b9 100644 --- a/test/electron/fixtures/app/src/configs/complex-config.js +++ b/test/electron/fixtures/app/src/configs/complex-config.js @@ -2,6 +2,7 @@ module.exports = () => { return { appType: 'complicated', appVersion: '2.0.83-beta3', + codeBundleId: '2.0.83-beta3-r456', context: 'shopping cart', user: { id: '3', diff --git a/test/electron/fixtures/app/src/configs/mixed-codebundleid.js b/test/electron/fixtures/app/src/configs/mixed-codebundleid.js new file mode 100644 index 0000000000..399b68f084 --- /dev/null +++ b/test/electron/fixtures/app/src/configs/mixed-codebundleid.js @@ -0,0 +1,14 @@ +module.exports = () => { + return { + appType: 'mixed-bundle', + appVersion: '1.0.0', + codeBundleId: 'main-bundle-abc123', + releaseStage: 'test' + } +} + +module.exports.renderer = () => { + return { + codeBundleId: 'renderer-bundle-xyz789' + } +} diff --git a/test/electron/fixtures/app/src/index.html b/test/electron/fixtures/app/src/index.html index 2f3e196380..b522b5293f 100644 --- a/test/electron/fixtures/app/src/index.html +++ b/test/electron/fixtures/app/src/index.html @@ -69,5 +69,9 @@

Actions

  • Make a failed GET request
  • Trigger a network request error
  • + diff --git a/test/electron/fixtures/app/src/main.js b/test/electron/fixtures/app/src/main.js index d7fb23b3ad..6669d4811a 100644 --- a/test/electron/fixtures/app/src/main.js +++ b/test/electron/fixtures/app/src/main.js @@ -148,3 +148,7 @@ ipcMain.on('main-process-get-request', (_event, fail) => { ipcMain.on('main-process-request-error', () => { networkRequestError() }) + +ipcMain.on('main-process-set-grouping-discriminator', (_event, discriminator) => { + Bugsnag.setGroupingDiscriminator(discriminator) +}) diff --git a/test/electron/fixtures/app/src/preload.js b/test/electron/fixtures/app/src/preload.js index fdb79653b5..54f788c07b 100644 --- a/test/electron/fixtures/app/src/preload.js +++ b/test/electron/fixtures/app/src/preload.js @@ -48,5 +48,8 @@ contextBridge.exposeInMainWorld('RunnerAPI', { mainProcessRequestError: () => { ipcRenderer.send('main-process-request-error') }, + mainProcessSetGroupingDiscriminator: (discriminator) => { + ipcRenderer.send('main-process-set-grouping-discriminator', discriminator) + }, preloadStart: Date.now() }) diff --git a/test/electron/fixtures/app/src/renderer.js b/test/electron/fixtures/app/src/renderer.js index 7394fe253e..6b0cfd7a0c 100644 --- a/test/electron/fixtures/app/src/renderer.js +++ b/test/electron/fixtures/app/src/renderer.js @@ -95,3 +95,11 @@ document.getElementById('renderer-clear-context').onclick = () => { document.getElementById('renderer-clear-metadata').onclick = () => { Bugsnag.clearMetadata('renderer') } + +document.getElementById('main-process-set-grouping-discriminator').onclick = () => { + window.RunnerAPI.mainProcessSetGroupingDiscriminator('main-process-discriminator') +} + +document.getElementById('renderer-set-grouping-discriminator').onclick = () => { + Bugsnag.setGroupingDiscriminator('renderer-process-discriminator') +} diff --git a/test/electron/fixtures/events/app-launch/complex-config.json b/test/electron/fixtures/events/app-launch/complex-config.json index 8911ca9a67..d893ba84f2 100644 --- a/test/electron/fixtures/events/app-launch/complex-config.json +++ b/test/electron/fixtures/events/app-launch/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/main/breadcrumbs/complex-config.json b/test/electron/fixtures/events/main/breadcrumbs/complex-config.json index 48b6d860b5..55c605e331 100644 --- a/test/electron/fixtures/events/main/breadcrumbs/complex-config.json +++ b/test/electron/fixtures/events/main/breadcrumbs/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/main/handled-error/complex-config.json b/test/electron/fixtures/events/main/handled-error/complex-config.json index d3606af6cb..3b8acdcb17 100644 --- a/test/electron/fixtures/events/main/handled-error/complex-config.json +++ b/test/electron/fixtures/events/main/handled-error/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/main/handled-error/mixed-codebundleid.json b/test/electron/fixtures/events/main/handled-error/mixed-codebundleid.json new file mode 100644 index 0000000000..48d219fc55 --- /dev/null +++ b/test/electron/fixtures/events/main/handled-error/mixed-codebundleid.json @@ -0,0 +1,101 @@ +{ + "apiKey": "6425093c6530f554a9897d2d7d38e248", + "notifier": { + "name": "Bugsnag Electron", + "url": "https://github.com/bugsnag/bugsnag-electron", + "version": "{REGEX:^200\\.1\\.0-canary\\.[0-9a-f]{24}$}" + }, + "events": [ + { + "payloadVersion": "4", + "app": { + "codeBundleId": "main-bundle-abc123", + "duration": "{TYPE:number}", + "releaseStage": "test", + "inForeground": "{TYPE:boolean}", + "isLaunching": "{TYPE:boolean}", + "type": "mixed-bundle", + "version": "1.0.0" + }, + "device": { + "runtimeVersions": { + "node": "{TYPE:string}", + "chrome": "{TYPE:string}", + "electron": "{TYPE:string}" + }, + "id": "{REGEX:[0-9a-f]{64}}", + "freeMemory": "{TYPE:number}", + "time": "{TIMESTAMP}", + "totalMemory": "{TYPE:number}", + "osVersion": "{REGEX:\\d+\\.\\d+}" + }, + "metaData": { + "app": { + "name": "Runner", + "CFBundleVersion": "{PLATFORM_MACOS:1.0.2}" + }, + "device": { + "online": "{TYPE:boolean}", + "idleTime": "{TYPE:number}", + "screenResolution": { + "width": "{TYPE:number}", + "height": "{TYPE:number}" + } + }, + "process": { + "type": "browser", + "heapStatistics": {} + } + }, + "severity": "warning", + "unhandled": false, + "severityReason": { + "type": "handledException" + }, + "breadcrumbs": [ + { + "type": "state", + "name": "Bugsnag loaded", + "timestamp": "{TIMESTAMP}", + "metaData": {} + }, + { + "type": "state", + "name": "App became ready", + "timestamp": "{TIMESTAMP}" + }, + { + "type": "state", + "name": "Browser window 1 created", + "timestamp": "{TIMESTAMP}", + "metaData": { + "id": 1 + } + }, + { + "type": "state", + "name": "Browser window 1 was shown", + "timestamp": "{TIMESTAMP}", + "metaData": { + "id": 1, + "title": "Runner" + } + } + ], + "exceptions": [ + { + "errorMessage": "something bad", + "errorClass": "ReferenceError", + "stacktrace": [{ + "file": ".webpack/main/index.js", + "lineNumber": 2, + "code": { + "1": "{TYPE:string}" + } + }], + "type": "electronnodejs" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/electron/fixtures/events/main/uncaught-exception/complex-config.json b/test/electron/fixtures/events/main/uncaught-exception/complex-config.json index 20f1f34d64..5b4fbd9134 100644 --- a/test/electron/fixtures/events/main/uncaught-exception/complex-config.json +++ b/test/electron/fixtures/events/main/uncaught-exception/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/main/unhandled-rejection/complex-config.json b/test/electron/fixtures/events/main/unhandled-rejection/complex-config.json index b1dc77bc44..2cd2f0d531 100644 --- a/test/electron/fixtures/events/main/unhandled-rejection/complex-config.json +++ b/test/electron/fixtures/events/main/unhandled-rejection/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/on-error/complex-config.json b/test/electron/fixtures/events/on-error/complex-config.json index 1af891d6b2..cf06bbf866 100644 --- a/test/electron/fixtures/events/on-error/complex-config.json +++ b/test/electron/fixtures/events/on-error/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/renderer/config/mixed-codebundleid.json b/test/electron/fixtures/events/renderer/config/mixed-codebundleid.json new file mode 100644 index 0000000000..e6226bf41d --- /dev/null +++ b/test/electron/fixtures/events/renderer/config/mixed-codebundleid.json @@ -0,0 +1,105 @@ +{ + "apiKey": "6425093c6530f554a9897d2d7d38e248", + "notifier": { + "name": "Bugsnag Electron", + "url": "https://github.com/bugsnag/bugsnag-electron", + "version": "{REGEX:^200\\.1\\.0-canary\\.[0-9a-f]{24}$}" + }, + "events": [ + { + "payloadVersion": "4", + "app": { + "codeBundleId": "renderer-bundle-xyz789", + "duration": "{TYPE:number}", + "releaseStage": "test", + "inForeground": "{TYPE:boolean}", + "isLaunching": "{TYPE:boolean}", + "type": "mixed-bundle", + "version": "1.0.0" + }, + "device": { + "runtimeVersions": { + "node": "{TYPE:string}", + "chrome": "{TYPE:string}", + "electron": "{TYPE:string}" + }, + "id": "{REGEX:[0-9a-f]{64}}", + "freeMemory": "{TYPE:number}", + "time": "{TIMESTAMP}", + "totalMemory": "{TYPE:number}", + "osVersion": "{REGEX:\\d+\\.\\d+}" + }, + "metaData": { + "app": { + "name": "Runner", + "CFBundleVersion": "{PLATFORM_MACOS:1.0.2}" + }, + "device": { + "online": "{TYPE:boolean}", + "idleTime": "{TYPE:number}", + "screenResolution": { + "width": "{TYPE:number}", + "height": "{TYPE:number}" + } + }, + "process": { + "type": "renderer", + "sandboxed": true, + "isMainFrame": true, + "heapStatistics": {} + } + }, + "severity": "warning", + "unhandled": false, + "severityReason": { + "type": "handledException" + }, + "breadcrumbs": [ + { + "type": "state", + "name": "Bugsnag loaded", + "timestamp": "{TIMESTAMP}", + "metaData": {} + }, + { + "type": "state", + "name": "App became ready", + "timestamp": "{TIMESTAMP}" + }, + { + "type": "state", + "name": "Browser window 1 created", + "timestamp": "{TIMESTAMP}", + "metaData": { + "id": 1 + } + }, + { + "type": "state", + "name": "Browser window 1 was shown", + "timestamp": "{TIMESTAMP}", + "metaData": { + "id": 1, + "title": "Runner" + } + } + ], + "exceptions": [ + { + "errorMessage": "{REGEX:ALERT!$}", + "errorClass": "Error", + "stacktrace": [ + { + "lineNumber": 1, + "file": ".webpack/renderer/main_window/index.js", + "code": { + "1": "{TYPE:string}" + } + } + ], + "type": "electronrendererjs" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/electron/fixtures/events/renderer/context/page-title-clear-complex-config.json b/test/electron/fixtures/events/renderer/context/page-title-clear-complex-config.json index 7b9ba19a1d..2a0919a77e 100644 --- a/test/electron/fixtures/events/renderer/context/page-title-clear-complex-config.json +++ b/test/electron/fixtures/events/renderer/context/page-title-clear-complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/renderer/context/page-title-update-complex-config.json b/test/electron/fixtures/events/renderer/context/page-title-update-complex-config.json index 7b9ba19a1d..2a0919a77e 100644 --- a/test/electron/fixtures/events/renderer/context/page-title-update-complex-config.json +++ b/test/electron/fixtures/events/renderer/context/page-title-update-complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/renderer/handled-error/complex-config.json b/test/electron/fixtures/events/renderer/handled-error/complex-config.json index bb1cc772ef..645e2f3260 100644 --- a/test/electron/fixtures/events/renderer/handled-error/complex-config.json +++ b/test/electron/fixtures/events/renderer/handled-error/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/renderer/uncaught-exception/complex-config.json b/test/electron/fixtures/events/renderer/uncaught-exception/complex-config.json index b8f43f2427..52e6ff0544 100644 --- a/test/electron/fixtures/events/renderer/uncaught-exception/complex-config.json +++ b/test/electron/fixtures/events/renderer/uncaught-exception/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/renderer/unhandled-rejection/complex-config.json b/test/electron/fixtures/events/renderer/unhandled-rejection/complex-config.json index 3fc34940a4..48405c43f2 100644 --- a/test/electron/fixtures/events/renderer/unhandled-rejection/complex-config.json +++ b/test/electron/fixtures/events/renderer/unhandled-rejection/complex-config.json @@ -9,6 +9,7 @@ { "payloadVersion": "4", "app": { + "codeBundleId": "2.0.83-beta3-r456", "duration": "{TYPE:number}", "releaseStage": "beta", "inForeground": "{TYPE:boolean}", diff --git a/test/electron/fixtures/events/sessions/complex-config.json b/test/electron/fixtures/events/sessions/complex-config.json index 0a2328a0c7..6dc4ef5759 100644 --- a/test/electron/fixtures/events/sessions/complex-config.json +++ b/test/electron/fixtures/events/sessions/complex-config.json @@ -17,6 +17,7 @@ } }, "app": { + "codeBundleId": "2.0.83-beta3-r456", "releaseStage": "beta", "version": "2.0.83-beta3", "type": "complicated" diff --git a/test/node/Gemfile b/test/node/Gemfile index 29d3f3cccb..a911459674 100644 --- a/test/node/Gemfile +++ b/test/node/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'bugsnag-maze-runner', '~>8.0' +gem 'bugsnag-maze-runner', '~>10.0' # Use a branch of Maze Runner #gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner', branch: 'tms/use-maze-check' diff --git a/test/react-native-cli/Gemfile b/test/react-native-cli/Gemfile index 9eb0d7678d..44c25e95eb 100644 --- a/test/react-native-cli/Gemfile +++ b/test/react-native-cli/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' gem 'cocoapods' gem 'xcodeproj', '< 1.26.0' -gem 'bugsnag-maze-runner', '~>9.0' +gem 'bugsnag-maze-runner', '~>10.0' # Use a branch of Maze Runner #gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner', branch: 'tms/use-maze-check' diff --git a/test/react-native/Gemfile b/test/react-native/Gemfile index 206ecd5fde..2c9de72294 100644 --- a/test/react-native/Gemfile +++ b/test/react-native/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' gem 'cocoapods' gem 'xcodeproj', '< 1.26.0' -gem 'bugsnag-maze-runner', '~>9.0' +gem 'bugsnag-maze-runner', '~>10.0' # Use a branch of Maze Runner #gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner', branch: 'tms/use-maze-check' diff --git a/test/react-native/features/fixtures/scenario-launcher/android/src/main/java/com/bugsnag/reactnative/test/scenarios/GroupingDiscriminatorNativeScenario.kt b/test/react-native/features/fixtures/scenario-launcher/android/src/main/java/com/bugsnag/reactnative/test/scenarios/GroupingDiscriminatorNativeScenario.kt new file mode 100644 index 0000000000..fed3214bc6 --- /dev/null +++ b/test/react-native/features/fixtures/scenario-launcher/android/src/main/java/com/bugsnag/reactnative/test/scenarios/GroupingDiscriminatorNativeScenario.kt @@ -0,0 +1,25 @@ +package com.reactnative.scenarios + +import android.content.Context +import com.bugsnag.android.Bugsnag +import com.facebook.react.bridge.Promise + +class GroupingDiscriminatorNativeScenario(context: Context): Scenario(context) { + + override fun run(promise: Promise) { + val exception = RuntimeException("GroupingDiscriminatorScenarioNative") + Bugsnag.notify(exception) + Thread.sleep(500) + Bugsnag.setGroupingDiscriminator("grouping-discriminator-from-native") + // JS layer will be automatically notified via the BugsnagReactNativeEmitter + // when setGroupingDiscriminator is called, which triggers the client observer + } + + override fun runSync(): Boolean { + val exception = RuntimeException("GroupingDiscriminatorScenarioNative") + Bugsnag.notify(exception) + Thread.sleep(500) + Bugsnag.setGroupingDiscriminator("grouping-discriminator-from-native") + return true + } +} diff --git a/test/react-native/features/fixtures/scenario-launcher/ios/BugsnagTestInterface.xcodeproj/project.pbxproj b/test/react-native/features/fixtures/scenario-launcher/ios/BugsnagTestInterface.xcodeproj/project.pbxproj index ce31311634..d762a1a2d2 100644 --- a/test/react-native/features/fixtures/scenario-launcher/ios/BugsnagTestInterface.xcodeproj/project.pbxproj +++ b/test/react-native/features/fixtures/scenario-launcher/ios/BugsnagTestInterface.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ DA2260AC2E58AD79008384E6 /* BugsnagTestInterface.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA2260AB2E58AD79008384E6 /* BugsnagTestInterface.mm */; }; DA2260D42E58AD99008384E6 /* ContextNativeCustomScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2260B42E58AD99008384E6 /* ContextNativeCustomScenario.m */; }; + DA2260FB2E58AD99008384E6 /* GroupingDiscriminatorNativeScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = DA3371AC2F69BE8A009495D7 /* GroupingDiscriminatorNativeScenario.m */; }; DA2260D52E58AD99008384E6 /* MetadataNativeUnhandledScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2260C02E58AD99008384E6 /* MetadataNativeUnhandledScenario.m */; }; DA2260D62E58AD99008384E6 /* UserNativeClientScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2260D32E58AD99008384E6 /* UserNativeClientScenario.m */; }; DA2260D72E58AD99008384E6 /* StartSessionScenario.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2260CF2E58AD99008384E6 /* StartSessionScenario.m */; }; @@ -54,6 +55,8 @@ DA2260B22E58AD99008384E6 /* BreadcrumbsNativeManualScenario.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = BreadcrumbsNativeManualScenario.m; path = Scenarios/BreadcrumbsNativeManualScenario.m; sourceTree = ""; }; DA2260B32E58AD99008384E6 /* ContextNativeCustomScenario.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ContextNativeCustomScenario.h; path = Scenarios/ContextNativeCustomScenario.h; sourceTree = ""; }; DA2260B42E58AD99008384E6 /* ContextNativeCustomScenario.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ContextNativeCustomScenario.m; path = Scenarios/ContextNativeCustomScenario.m; sourceTree = ""; }; + DA3371AD2F69BE8B009495D8 /* GroupingDiscriminatorNativeScenario.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = GroupingDiscriminatorNativeScenario.h; path = Scenarios/GroupingDiscriminatorNativeScenario.h; sourceTree = ""; }; + DA3371AC2F69BE8A009495D7 /* GroupingDiscriminatorNativeScenario.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = GroupingDiscriminatorNativeScenario.m; path = Scenarios/GroupingDiscriminatorNativeScenario.m; sourceTree = ""; }; DA2260B52E58AD99008384E6 /* DeviceNativeHandledScenario.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DeviceNativeHandledScenario.h; path = Scenarios/DeviceNativeHandledScenario.h; sourceTree = ""; }; DA2260B62E58AD99008384E6 /* DeviceNativeHandledScenario.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = DeviceNativeHandledScenario.m; path = Scenarios/DeviceNativeHandledScenario.m; sourceTree = ""; }; DA2260B72E58AD99008384E6 /* DeviceNativeUnhandledScenario.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DeviceNativeUnhandledScenario.h; path = Scenarios/DeviceNativeUnhandledScenario.h; sourceTree = ""; }; @@ -109,6 +112,8 @@ DA2260B22E58AD99008384E6 /* BreadcrumbsNativeManualScenario.m */, DA2260B32E58AD99008384E6 /* ContextNativeCustomScenario.h */, DA2260B42E58AD99008384E6 /* ContextNativeCustomScenario.m */, + DA3371AD2F69BE8B009495D8 /* GroupingDiscriminatorNativeScenario.h */, + DA3371AC2F69BE8A009495D7 /* GroupingDiscriminatorNativeScenario.m */, DA2260B52E58AD99008384E6 /* DeviceNativeHandledScenario.h */, DA2260B62E58AD99008384E6 /* DeviceNativeHandledScenario.m */, DA2260B72E58AD99008384E6 /* DeviceNativeUnhandledScenario.h */, @@ -215,6 +220,7 @@ buildActionMask = 2147483647; files = ( DA2260D42E58AD99008384E6 /* ContextNativeCustomScenario.m in Sources */, + DA2260FB2E58AD99008384E6 /* GroupingDiscriminatorNativeScenario.m in Sources */, DA2260D52E58AD99008384E6 /* MetadataNativeUnhandledScenario.m in Sources */, DA2260D62E58AD99008384E6 /* UserNativeClientScenario.m in Sources */, DA2260D72E58AD99008384E6 /* StartSessionScenario.m in Sources */, diff --git a/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorNativeScenario.h b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorNativeScenario.h new file mode 100644 index 0000000000..73d11746ae --- /dev/null +++ b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorNativeScenario.h @@ -0,0 +1,6 @@ +#import +#import "Scenario.h" + +@interface GroupingDiscriminatorNativeScenario : Scenario + +@end diff --git a/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorNativeScenario.m b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorNativeScenario.m new file mode 100644 index 0000000000..91b0e83311 --- /dev/null +++ b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorNativeScenario.m @@ -0,0 +1,15 @@ +#import "GroupingDiscriminatorNativeScenario.h" + +@implementation GroupingDiscriminatorNativeScenario + +- (void)run: (RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject { + NSException *exception = [[NSException alloc] initWithName:@"NSException" reason:@"GroupingDiscriminatorScenarioNative" userInfo:nil]; + [Bugsnag notify:exception]; + [NSThread sleepForTimeInterval:0.5]; + [Bugsnag setGroupingDiscriminator:@"grouping-discriminator-from-native"]; + // JS layer will be automatically notified via the BugsnagReactNativeEmitter + // when setGroupingDiscriminator is called, which triggers BSGClientObserverUpdateGroupingDiscriminator +} + +@end diff --git a/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorScenario.h b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorScenario.h new file mode 100644 index 0000000000..46151229c6 --- /dev/null +++ b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorScenario.h @@ -0,0 +1,6 @@ +#import +#import "Scenario.h" + +@interface GroupingDiscriminatorScenario : Scenario + +@end diff --git a/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorScenario.m b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorScenario.m new file mode 100644 index 0000000000..30c23f3925 --- /dev/null +++ b/test/react-native/features/fixtures/scenario-launcher/ios/Scenarios/GroupingDiscriminatorScenario.m @@ -0,0 +1,11 @@ +#import "GroupingDiscriminatorScenario.h" + +@implementation GroupingDiscriminatorScenario + +- (void)run: (RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject { + // This scenario is driven from the JS side + // The native part doesn't need to do anything specific +} + +@end diff --git a/test/react-native/features/fixtures/scenario-launcher/src/scenarios/GroupingDiscriminatorNativeScenario.js b/test/react-native/features/fixtures/scenario-launcher/src/scenarios/GroupingDiscriminatorNativeScenario.js new file mode 100644 index 0000000000..c3792de4ff --- /dev/null +++ b/test/react-native/features/fixtures/scenario-launcher/src/scenarios/GroupingDiscriminatorNativeScenario.js @@ -0,0 +1,18 @@ +import Scenario from './Scenario' +import Bugsnag from '@bugsnag/react-native' +import { NativeInterface } from '../lib/native' + +export class GroupingDiscriminatorNativeScenario extends Scenario { + run () { + // Set initial grouping discriminator in JavaScript + Bugsnag.setGroupingDiscriminator('grouping-discriminator-from-js') + + // Trigger the native scenario which will set the grouping discriminator + setTimeout(async () => { + await NativeInterface.runScenario('GroupingDiscriminatorNativeScenario') + setTimeout(() => { + Bugsnag.notify(new Error('GroupingDiscriminatorScenarioJS')) + }, 100) + }, 100) + } +} diff --git a/test/react-native/features/fixtures/scenario-launcher/src/scenarios/GroupingDiscriminatorScenario.js b/test/react-native/features/fixtures/scenario-launcher/src/scenarios/GroupingDiscriminatorScenario.js new file mode 100644 index 0000000000..cbd0864ef8 --- /dev/null +++ b/test/react-native/features/fixtures/scenario-launcher/src/scenarios/GroupingDiscriminatorScenario.js @@ -0,0 +1,32 @@ +import Scenario from './Scenario' +import Bugsnag from '@bugsnag/react-native' + +export class GroupingDiscriminatorScenario extends Scenario { + run () { + // 1. Notify with error that has no discriminator + Bugsnag.notify(new Error('no-discriminator')) + + // 2. Notify with error that should use client discriminator + Bugsnag.setGroupingDiscriminator('client-discriminator') + Bugsnag.notify(new Error('client-discriminator')) + + // 3. Notify with error and set event discriminator + Bugsnag.notify(new Error('event-discriminator'), event => { + event.setGroupingDiscriminator('event-discriminator') + }) + + // 4. Notify with error and explicitly set event discriminator to null + Bugsnag.notify(new Error('null-discriminator'), event => { + event.setGroupingDiscriminator(null) + }) + + // 5. Notify with error and explicitly set event discriminator to undefined + Bugsnag.notify(new Error('undefined-discriminator'), event => { + event.setGroupingDiscriminator(undefined) + }) + + // 6. Clear client grouping discriminator and notify + Bugsnag.setGroupingDiscriminator(undefined) + Bugsnag.notify(new Error('no-discriminator-2')) + } +} diff --git a/test/react-native/features/fixtures/scenario-launcher/src/scenarios/index.js b/test/react-native/features/fixtures/scenario-launcher/src/scenarios/index.js index f9401b51d2..1c0c937efa 100644 --- a/test/react-native/features/fixtures/scenario-launcher/src/scenarios/index.js +++ b/test/react-native/features/fixtures/scenario-launcher/src/scenarios/index.js @@ -81,3 +81,7 @@ export { ReactNavigationBreadcrumbsDisabledScenario } from './ReactNavigationBre // react-native-navigation.feature export { ReactNativeNavigationBreadcrumbsEnabledScenario } from './ReactNativeNavigationBreadcrumbsEnabledScenario' export { ReactNativeNavigationBreadcrumbsDisabledScenario } from './ReactNativeNavigationBreadcrumbsDisabledScenario' + +// grouping-discriminator.feature +export { GroupingDiscriminatorScenario } from './GroupingDiscriminatorScenario' +export { GroupingDiscriminatorNativeScenario } from './GroupingDiscriminatorNativeScenario' diff --git a/test/react-native/features/grouping-discriminator.feature b/test/react-native/features/grouping-discriminator.feature new file mode 100644 index 0000000000..715c58090c --- /dev/null +++ b/test/react-native/features/grouping-discriminator.feature @@ -0,0 +1,23 @@ +@grouping_discriminator +Feature: Grouping discriminator functionality + +Scenario: multiple notify() calls with different grouping discriminators + When I run "GroupingDiscriminatorScenario" + And I wait to receive 6 errors + Then the following sets are present in the current error payloads: + | events.0.exceptions.0.message | events.0.groupingDiscriminator | + | no-discriminator | nil | + | client-discriminator | client-discriminator | + | event-discriminator | event-discriminator | + | null-discriminator | nil | + | undefined-discriminator | nil | + | no-discriminator-2 | nil | + +Scenario: Grouping discriminator set in JavaScript is reflected in native + When I run "GroupingDiscriminatorNativeScenario" + And I wait to receive 2 errors + Then the following sets are present in the current error payloads: + | events.0.exceptions.0.message | events.0.groupingDiscriminator | + | GroupingDiscriminatorScenarioNative | grouping-discriminator-from-js | + | GroupingDiscriminatorScenarioJS | grouping-discriminator-from-native | + \ No newline at end of file diff --git a/test/react-native/features/steps/react-native-steps.rb b/test/react-native/features/steps/react-native-steps.rb index 7eb162318c..656bd3ffd4 100644 --- a/test/react-native/features/steps/react-native-steps.rb +++ b/test/react-native/features/steps/react-native-steps.rb @@ -129,6 +129,10 @@ def wait_for_app_state(expected_state) payload_hash end expected_values.each do |expected_data| + # For test data, if the value is the string 'nil', it represents an absent field. + expected_data.each do |field_path, expected_value| + expected_data[field_path] = nil if expected_value == 'nil' + end Maze.check.true(payload_values.include?(expected_data), "#{expected_data} was not found in any of the current payloads") end