diff --git a/.craft.yml b/.craft.yml index f08ee2832d25..d9be4d4b3fa4 100644 --- a/.craft.yml +++ b/.craft.yml @@ -5,10 +5,12 @@ targets: # NPM Targets ## 1. Base Packages, node or browser SDKs depend on ## 1.1 Types + # TODO(v9): Remove - name: npm id: '@sentry/types' includeNames: /^sentry-types-\d.*\.tgz$/ ## 1.2 Utils + # TODO(v9): Remove - name: npm id: '@sentry/utils' includeNames: /^sentry-utils-\d.*\.tgz$/ diff --git a/.github/dependency-review-config.yml b/.github/dependency-review-config.yml index 99deb0e2677c..3becba39719e 100644 --- a/.github/dependency-review-config.yml +++ b/.github/dependency-review-config.yml @@ -1,7 +1,9 @@ fail-on-severity: 'high' allow-ghsas: # dependency review does not allow specific file exclusions - # we use an older version of NextJS in our tests and thus need to + # we use an older version of NextJS in our tests and thus need to # exclude this # once our minimum supported version is over 14.1.1 this can be removed - GHSA-fr5h-rqp8-mj6g + # we need this for an E2E test for the minimum required version of Nuxt 3.7.0 + - GHSA-v784-fjjh-f8r4 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d903d4913cd4..5df700a2947e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -387,7 +387,7 @@ jobs: if: github.event_name != 'pull_request' - name: Compute test coverage - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -491,7 +491,7 @@ jobs: NODE_VERSION: ${{ matrix.node }} - name: Compute test coverage - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} @@ -1408,6 +1408,10 @@ jobs: key: ${{ needs.job_build.outputs.dependency_cache_key }} enableCrossOsArchive: true + - name: Increase yarn network timeout on Windows + if: contains(matrix.os, 'windows') + run: yarn config set network-timeout 600000 -g + - name: Install dependencies env: SKIP_PLAYWRIGHT_BROWSER_INSTALL: "1" @@ -1418,10 +1422,6 @@ jobs: run: | git config --global --add safe.directory "*" - - name: Increase yarn network timeout on Windows - if: contains(matrix.os, 'windows') - run: yarn config set network-timeout 600000 -g - - name: Setup python uses: actions/setup-python@v5 if: ${{ !contains(matrix.container, 'alpine') }} diff --git a/.size-limit.js b/.size-limit.js index e97e15f6cd4e..dc2b7af8128f 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -40,7 +40,7 @@ module.exports = [ path: 'packages/browser/build/npm/esm/index.js', import: createImport('init', 'browserTracingIntegration'), gzip: true, - limit: '36.5 KB', + limit: '37.5 KB', }, { name: '@sentry/browser (incl. Tracing, Replay)', @@ -124,7 +124,7 @@ module.exports = [ import: createImport('init', 'ErrorBoundary', 'reactRouterV6BrowserTracingIntegration'), ignore: ['react/jsx-runtime'], gzip: true, - limit: '39.5 KB', + limit: '40.5 KB', }, // Vue SDK (ESM) { @@ -132,14 +132,14 @@ module.exports = [ path: 'packages/vue/build/esm/index.js', import: createImport('init'), gzip: true, - limit: '28 KB', + limit: '29 KB', }, { name: '@sentry/vue (incl. Tracing)', path: 'packages/vue/build/esm/index.js', import: createImport('init', 'browserTracingIntegration'), gzip: true, - limit: '38.5 KB', + limit: '39.5 KB', }, // Svelte SDK (ESM) { @@ -219,7 +219,7 @@ module.exports = [ import: createImport('init'), ignore: ['$app/stores'], gzip: true, - limit: '37 KB', + limit: '38 KB', }, // Node SDK (ESM) { diff --git a/CHANGELOG.md b/CHANGELOG.md index bfacfe82c2a4..08ae2d6bca2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,150 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott -Work in this release was contributed by @NEKOYASAN. Thank you for your contribution! +## 8.42.0 + +### Important Changes + +- **feat(react): React Router v7 support (library) ([#14513](https://github.com/getsentry/sentry-javascript/pull/14513))** + + This release adds support for [React Router v7 (library mode)](https://reactrouter.com/home#react-router-as-a-library). + Check out the docs on how to set up the integration: [Sentry React Router v7 Integration Docs](https://docs.sentry.io/platforms/javascript/guides/react/features/react-router/v7/) + +### Deprecations + +- **feat: Warn about source-map generation ([#14533](https://github.com/getsentry/sentry-javascript/pull/14533))** + + In the next major version of the SDK we will change how source maps are generated when the SDK is added to an application. + Currently, the implementation varies a lot between different SDKs and can be difficult to understand. + Moving forward, our goal is to turn on source maps for every framework, unless we detect that they are explicitly turned off. + Additionally, if we end up enabling source maps, we will emit a log message that we did so. + + With this particular release, we are emitting warnings that source map generation will change in the future and we print instructions on how to prepare for the next major. + +- **feat(nuxt): Deprecate `tracingOptions` in favor of `vueIntegration` ([#14530](https://github.com/getsentry/sentry-javascript/pull/14530))** + + Currently it is possible to configure tracing options in two places in the Sentry Nuxt SDK: + + - In `Sentry.init()` + - Inside `tracingOptions` in `Sentry.init()` + + For tree-shaking purposes and alignment with the Vue SDK, it is now recommended to instead use the newly exported `vueIntegration()` and its `tracingOptions` option to configure tracing options in the Nuxt SDK: + + ```ts + // sentry.client.config.ts + import * as Sentry from '@sentry/nuxt'; + + Sentry.init({ + // ... + integrations: [ + Sentry.vueIntegration({ + tracingOptions: { + trackComponents: true, + }, + }), + ], + }); + ``` + +### Other Changes + +- feat(browser-utils): Update `web-vitals` to v4.2.4 ([#14439](https://github.com/getsentry/sentry-javascript/pull/14439)) +- feat(nuxt): Expose `vueIntegration` ([#14526](https://github.com/getsentry/sentry-javascript/pull/14526)) +- fix(feedback): Handle css correctly in screenshot mode ([#14535](https://github.com/getsentry/sentry-javascript/pull/14535)) + +## 8.41.0 + +### Important Changes + +- **meta(nuxt): Require minimum Nuxt v3.7.0 ([#14473](https://github.com/getsentry/sentry-javascript/pull/14473))** + + We formalized that the Nuxt SDK is at minimum compatible with Nuxt version 3.7.0 and above. + Additionally, the SDK requires the implicit `nitropack` dependency to satisfy version `^2.10.0` and `ofetch` to satisfy `^1.4.0`. + It is recommended to check your lock-files and manually upgrade these dependencies if they don't match the version ranges. + +### Deprecations + +We are deprecating a few APIs which will be removed in the next major. + +The following deprecations will _potentially_ affect you: + +- **feat(core): Update & deprecate `undefined` option handling ([#14450](https://github.com/getsentry/sentry-javascript/pull/14450))** + + In the next major version we will change how passing `undefined` to `tracesSampleRate` / `tracesSampler` / `enableTracing` will behave. + + Currently, doing the following: + + ```ts + Sentry.init({ + tracesSampleRate: undefined, + }); + ``` + + Will result in tracing being _enabled_ (although no spans will be generated) because the `tracesSampleRate` key is present in the options object. + In the next major version, this behavior will be changed so that passing `undefined` (or rather having a `tracesSampleRate` key) will result in tracing being disabled, the same as not passing the option at all. + If you are currently relying on `undefined` being passed, and and thus have tracing enabled, it is recommended to update your config to set e.g. `tracesSampleRate: 0` instead, which will also enable tracing in v9. + + The same applies to `tracesSampler` and `enableTracing`. + +- **feat(core): Log warnings when returning `null` in `beforeSendSpan` ([#14433](https://github.com/getsentry/sentry-javascript/pull/14433))** + + Currently, the `beforeSendSpan` option in `Sentry.init()` allows you to drop individual spans from a trace by returning `null` from the hook. + Since this API lends itself to creating "gaps" inside traces, we decided to change how this API will work in the next major version. + + With the next major version the `beforeSendSpan` API can only be used to mutate spans, but no longer to drop them. + With this release the SDK will warn you if you are using this API to drop spans. + Instead, it is recommended to configure instrumentation (i.e. integrations) directly to control what spans are created. + + Additionally, with the next major version, root spans will also be passed to `beforeSendSpan`. + +- **feat(utils): Deprecate `@sentry/utils` ([#14431](https://github.com/getsentry/sentry-javascript/pull/14431))** + + With the next major version the `@sentry/utils` package will be merged into the `@sentry/core` package. + It is therefore no longer recommended to use the `@sentry/utils` package. + +- **feat(vue): Deprecate configuring Vue tracing options anywhere else other than through the `vueIntegration`'s `tracingOptions` option ([#14385](https://github.com/getsentry/sentry-javascript/pull/14385))** + + Currently it is possible to configure tracing options in various places in the Sentry Vue SDK: + + - In `Sentry.init()` + - Inside `tracingOptions` in `Sentry.init()` + - In the `vueIntegration()` options + - Inside `tracingOptions` in the `vueIntegration()` options + + Because this is a bit messy and confusing to document, the only recommended way to configure tracing options going forward is through the `tracingOptions` in the `vueIntegration()`. + The other means of configuration will be removed in the next major version of the SDK. + +- **feat: Deprecate `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude` ([#14486](https://github.com/getsentry/sentry-javascript/pull/14486))** + + Currently it is possible to define `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude` options in `Sentry.init()` to only apply ESM loader hooks to a subset of modules. + This API served as an escape hatch in case certain modules are incompatible with ESM loader hooks. + + Since this API was introduced, a way was found to only wrap modules that there exists instrumentation for (meaning a vetted list). + To only wrap modules that have instrumentation, it is recommended to instead set `registerEsmLoaderHooks.onlyIncludeInstrumentedModules` to `true`. + + Note that `onlyIncludeInstrumentedModules: true` will become the default behavior in the next major version and the `registerEsmLoaderHooks` will no longer accept fine-grained options. + +The following deprecations will _most likely_ not affect you unless you are building an SDK yourself: + +- feat(core): Deprecate `arrayify` ([#14405](https://github.com/getsentry/sentry-javascript/pull/14405)) +- feat(core): Deprecate `flatten` ([#14454](https://github.com/getsentry/sentry-javascript/pull/14454)) +- feat(core): Deprecate `urlEncode` ([#14406](https://github.com/getsentry/sentry-javascript/pull/14406)) +- feat(core): Deprecate `validSeverityLevels` ([#14407](https://github.com/getsentry/sentry-javascript/pull/14407)) +- feat(core/utils): Deprecate `getNumberOfUrlSegments` ([#14458](https://github.com/getsentry/sentry-javascript/pull/14458)) +- feat(utils): Deprecate `memoBuilder`, `BAGGAGE_HEADER_NAME`, and `makeFifoCache` ([#14434](https://github.com/getsentry/sentry-javascript/pull/14434)) +- feat(utils/core): Deprecate `addRequestDataToEvent` and `extractRequestData` ([#14430](https://github.com/getsentry/sentry-javascript/pull/14430)) + +### Other Changes + +- feat: Streamline `sentry-trace`, `baggage` and DSC handling ([#14364](https://github.com/getsentry/sentry-javascript/pull/14364)) +- feat(core): Further optimize debug ID parsing ([#14365](https://github.com/getsentry/sentry-javascript/pull/14365)) +- feat(node): Add `openTelemetryInstrumentations` option ([#14484](https://github.com/getsentry/sentry-javascript/pull/14484)) +- feat(nuxt): Add filter for not found source maps (devtools) ([#14437](https://github.com/getsentry/sentry-javascript/pull/14437)) +- feat(nuxt): Only delete public source maps ([#14438](https://github.com/getsentry/sentry-javascript/pull/14438)) +- fix(nextjs): Don't report `NEXT_REDIRECT` from browser ([#14440](https://github.com/getsentry/sentry-javascript/pull/14440)) +- perf(opentelemetry): Bucket spans for cleanup ([#14154](https://github.com/getsentry/sentry-javascript/pull/14154)) + +Work in this release was contributed by @NEKOYASAN and @fmorett. Thank you for your contributions! ## 8.40.0 diff --git a/README.md b/README.md index 44b10aa4d5b0..db7000a9d51f 100644 --- a/README.md +++ b/README.md @@ -111,10 +111,6 @@ below: Provides the integration for Session Replay. - [`@sentry/core`](https://github.com/getsentry/sentry-javascript/tree/master/packages/core): The base for all JavaScript SDKs with interfaces, type definitions and base classes. -- [`@sentry/utils`](https://github.com/getsentry/sentry-javascript/tree/master/packages/utils): A set of helpers and - utility functions useful for various SDKs. -- [`@sentry/types`](https://github.com/getsentry/sentry-javascript/tree/master/packages/types): Types used in all - packages. ## Bug Bounty Program diff --git a/biome.json b/biome.json index cee069ac3127..49b865345e39 100644 --- a/biome.json +++ b/biome.json @@ -44,6 +44,9 @@ "angular.json", "ember/instance-initializers/**", "ember/types.d.ts", + "solidstart/*.d.ts", + "solidstart/client/", + "solidstart/server/", ".output", ".vinxi" ] diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json index cd52a3eaecc1..ee0d598fa960 100644 --- a/dev-packages/browser-integration-tests/package.json +++ b/dev-packages/browser-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-integration-tests", - "version": "8.40.0", + "version": "8.42.0", "main": "index.js", "license": "MIT", "engines": { @@ -43,7 +43,7 @@ "@babel/preset-typescript": "^7.16.7", "@playwright/test": "^1.44.1", "@sentry-internal/rrweb": "2.29.0", - "@sentry/browser": "8.40.0", + "@sentry/browser": "8.42.0", "axios": "1.7.7", "babel-loader": "^8.2.2", "html-webpack-plugin": "^5.5.0", diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/click/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/click/test.ts index d6dd646b9965..b76c6f2d85f9 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/click/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/click/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/customEvent/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/customEvent/test.ts index 83cd53f8acba..d56ca8a8cc00 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/customEvent/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/customEvent/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/textInput/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/textInput/test.ts index d7544fbf891e..f7d1a32c4497 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/textInput/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/dom/textInput/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/get/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/get/test.ts index 9ecf29c31014..7daa0b43cb6a 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/get/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/get/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/getWithRequestObj/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/getWithRequestObj/test.ts index 8d545ea6f566..c778276fae90 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/getWithRequestObj/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/getWithRequestObj/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/post/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/post/test.ts index fd27c71e6ad7..a2ef7e478c2e 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/post/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/post/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/statusCode/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/statusCode/test.ts index 70cd868ccfe1..60892609c5b1 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/statusCode/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/fetch/statusCode/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/get/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/get/test.ts index 9c4b14e89033..abcc012bc46d 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/get/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/get/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/post/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/post/test.ts index 985e7e316244..cb259b1a547c 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/post/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/post/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/statusCode/test.ts b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/statusCode/test.ts index eb7014df5890..1fbf688f16d8 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/statusCode/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/Breadcrumbs/xhr/statusCode/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/ContextLines/noAddedLines/test.ts b/dev-packages/browser-integration-tests/suites/integrations/ContextLines/noAddedLines/test.ts index 8fa8ec16cddd..a3c8614bfb2b 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/ContextLines/noAddedLines/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/ContextLines/noAddedLines/test.ts @@ -7,6 +7,7 @@ sentryTest('should not add source context lines to errors from script files', as const url = await getLocalTestUrl({ testDir: __dirname }); const eventReqPromise = waitForErrorRequestOnUrl(page, url); + await page.waitForFunction('window.Sentry'); const clickPromise = page.locator('#script-error-btn').click(); diff --git a/dev-packages/browser-integration-tests/suites/integrations/captureConsole/test.ts b/dev-packages/browser-integration-tests/suites/integrations/captureConsole/test.ts index 606ef8925afd..7630d2a7824f 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/captureConsole/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/captureConsole/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/globalHandlers/fetchStackTrace/test.ts b/dev-packages/browser-integration-tests/suites/integrations/globalHandlers/fetchStackTrace/test.ts index 3d6790a36230..15dacad349b7 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/globalHandlers/fetchStackTrace/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/globalHandlers/fetchStackTrace/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpContext/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpContext/test.ts index f85aa63473d5..190aae12ce18 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpContext/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpContext/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/axios/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/axios/test.ts index 8b4267c217e6..d4e7ba222b30 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpclient/axios/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/axios/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/simple/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/simple/test.ts index d490f98426cd..09390fffd573 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/simple/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/simple/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/test.ts index 0bf34e61b95a..fbd30098773a 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event as SentryEvent } from '@sentry/types'; +import type { Event as SentryEvent } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequest/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequest/test.ts index 9fb6add1a2d5..f1e23bbd080b 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequest/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequest/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndBodyAndOptions/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndBodyAndOptions/test.ts index 485a52ed3fd4..ba34c4fdfa0f 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndBodyAndOptions/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndBodyAndOptions/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndOptions/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndOptions/test.ts index d78860f7b1a6..0ea8fc7bc0cb 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndOptions/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withRequestAndOptions/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/xhr/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/xhr/test.ts index 9953de1c860e..d342e9abf748 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/httpclient/xhr/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/xhr/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadata/test.ts b/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadata/test.ts index 8e9401e67be1..271314220f7a 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadata/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadata/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadataWithRewriteFrames/test.ts b/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadataWithRewriteFrames/test.ts index 04e8f24adfaf..bdabe0d63680 100644 --- a/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadataWithRewriteFrames/test.ts +++ b/dev-packages/browser-integration-tests/suites/integrations/moduleMetadata/appliesMetadataWithRewriteFrames/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts b/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts index 2901c482e2d2..642006f4c2fc 100644 --- a/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts +++ b/dev-packages/browser-integration-tests/suites/manual-client/browser-context/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; @@ -43,6 +43,8 @@ sentryTest('allows to setup a client manually & capture exceptions', async ({ ge version: expect.any(String), packages: [{ name: expect.any(String), version: expect.any(String) }], }, - contexts: { trace: { trace_id: expect.any(String), span_id: expect.any(String) } }, + contexts: { + trace: { trace_id: expect.stringMatching(/[a-f0-9]{32}/), span_id: expect.stringMatching(/[a-f0-9]{16}/) }, + }, }); }); diff --git a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts index 32f3e0758de2..37de3ad11082 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/empty_obj/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts index 43fd59b5b1dc..765c59678d49 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/multiple_breadcrumbs/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts index 3eba0e1ecc48..d99ec82d88d7 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/simple_breadcrumb/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts index 3837262b69a9..b18b57f27c20 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/addBreadcrumb/undefined_arg/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/beforeSendTransaction/init.js b/dev-packages/browser-integration-tests/suites/public-api/beforeSendTransaction/init.js new file mode 100644 index 000000000000..e94e2bd42ab2 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/beforeSendTransaction/init.js @@ -0,0 +1,23 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [Sentry.browserTracingIntegration()], + beforeSendTransaction: transactionEvent => { + const op = transactionEvent.contexts.trace.op; + if (op === 'pageload' || op === 'navigation') { + // use whatever logic you want to set the name + transactionEvent.transaction = 'customName'; + + transactionEvent.transaction_info.source = 'route'; + transactionEvent.contexts.trace.data = { + ...transactionEvent.contexts.trace.data, + [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', + }; + } + return transactionEvent; + }, + tracesSampleRate: 1, +}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/beforeSendTransaction/test.ts b/dev-packages/browser-integration-tests/suites/public-api/beforeSendTransaction/test.ts new file mode 100644 index 000000000000..92e34c398b27 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/beforeSendTransaction/test.ts @@ -0,0 +1,32 @@ +import { expect } from '@playwright/test'; +import type { Event } from '@sentry/core'; + +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/browser'; +import { sentryTest } from '../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../utils/helpers'; + +sentryTest( + 'allows modification of the transaction name and source but overwrites source to custom', + async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestUrl({ testDir: __dirname }); + + const eventData = await getFirstSentryEnvelopeRequest(page, url); + + expect(eventData.type).toBe('transaction'); + + // user-changed name + expect(eventData.transaction).toBe('customName'); + + // Despite the user setting the source to 'route', the SDK detects that the txn name was changed + // and therefore sets the transaction_info.source to 'custom'. This is not ideal but also not easily changeable. + // Given that Relay doesn't differentiate between 'source' and 'route', we'll keep this as-is for now. + expect(eventData.transaction_info?.source).toBe('custom'); + + // This stays the same but it has no effect on Relay. + expect(eventData.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('route'); + }, +); diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/classInstance/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/classInstance/test.ts index 0c0a35859dd0..04527d822407 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/classInstance/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/classInstance/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/emptyObj/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/emptyObj/test.ts index 712f599f30d5..79f5af014476 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/emptyObj/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/emptyObj/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/errorEvent/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/errorEvent/test.ts index 5e8cbc0dd9c1..db68fb7790b5 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/errorEvent/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/errorEvent/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/event/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/event/test.ts index d212a027ec53..b6d68e0da3f0 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/event/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/event/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/eventBreadcrumbs/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/eventBreadcrumbs/test.ts index 4dc6bd0c7311..887c63d896bc 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/eventBreadcrumbs/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/eventBreadcrumbs/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/linkedErrors/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/linkedErrors/test.ts index 9136f11ceae0..61dc0e3418f6 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/linkedErrors/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/linkedErrors/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsDifferentStacktrace/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsDifferentStacktrace/test.ts index 103c0c1d1dc5..05283130a679 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsDifferentStacktrace/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsDifferentStacktrace/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsSameStacktrace/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsSameStacktrace/test.ts index 7ef825b0b147..fadcc4a72899 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsSameStacktrace/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/multipleErrorsSameStacktrace/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/plainObject/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/plainObject/test.ts index 1f31b1738bb4..8bf55ef1eca6 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/plainObject/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/plainObject/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/transactionBreadcrumbs/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/transactionBreadcrumbs/test.ts index 4383d92a6f73..0599d275b065 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/transactionBreadcrumbs/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/transactionBreadcrumbs/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureException/undefinedArg/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureException/undefinedArg/test.ts index a7e8dfc93116..87611a523b7c 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureException/undefinedArg/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureException/undefinedArg/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/multipleMessageAttachStacktrace/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/multipleMessageAttachStacktrace/test.ts index a16afd870fd9..487b0e1c62c4 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/multipleMessageAttachStacktrace/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/multipleMessageAttachStacktrace/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/parameterized_message/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/parameterized_message/test.ts index c507f8a7d8c6..79f097d60a6b 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/parameterized_message/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/parameterized_message/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/simple_message/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/simple_message/test.ts index 50df0b1c38df..fdd9cba22b37 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/simple_message/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/simple_message/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/with_level/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/with_level/test.ts index 96b3a98276df..2a9ab70d0622 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureMessage/with_level/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureMessage/with_level/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/simple_feedback/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/simple_feedback/test.ts index 6c3ffdbc969f..3d1253910e3d 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/simple_feedback/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/simple_feedback/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { UserFeedback } from '@sentry/types'; +import type { UserFeedback } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureException/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureException/test.ts index 800489456525..aa7bc8f7aa17 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureException/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureException/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event, UserFeedback } from '@sentry/types'; +import type { Event, UserFeedback } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureMessage/test.ts b/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureMessage/test.ts index 7b0b5ad2f2ed..019a5d4a0326 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureMessage/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/captureUserFeedback/withCaptureMessage/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event, UserFeedback } from '@sentry/types'; +import type { Event, UserFeedback } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/denyUrls/test.ts b/dev-packages/browser-integration-tests/suites/public-api/denyUrls/test.ts index c562b0fb9c09..b6eda2f9cad0 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/denyUrls/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/denyUrls/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/ignoreErrors/test.ts b/dev-packages/browser-integration-tests/suites/public-api/ignoreErrors/test.ts index 809e47e66a8b..3101cc500cde 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/ignoreErrors/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/ignoreErrors/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/subject.js b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/subject.js new file mode 100644 index 000000000000..1f28a4f125e0 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/subject.js @@ -0,0 +1,11 @@ +const btn = document.createElement('button'); +btn.id = 'btn'; +document.body.appendChild(btn); + +const functionListener = function () { + throw new Error('event_listener_error'); +}; + +btn.addEventListener('click', functionListener); + +btn.click(); diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/test.ts new file mode 100644 index 000000000000..513b3911422a --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/test.ts @@ -0,0 +1,29 @@ +import { expect } from '@playwright/test'; +import type { Event } from '@sentry/core'; + +import { sentryTest } from '../../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; + +sentryTest('should capture target name in mechanism data', async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + + const eventData = await getFirstSentryEnvelopeRequest(page, url); + + expect(eventData.exception?.values).toHaveLength(1); + expect(eventData.exception?.values?.[0]).toMatchObject({ + type: 'Error', + value: 'event_listener_error', + mechanism: { + type: 'instrument', + handled: false, + data: { + function: 'addEventListener', + handler: 'functionListener', + target: 'EventTarget', + }, + }, + stacktrace: { + frames: expect.any(Array), + }, + }); +}); diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/named-function/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/named-function/test.ts index 9ab0c5030bab..aa215deb3141 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/named-function/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/named-function/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/remove/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/remove/test.ts index d8047a044646..8958c4ce71b8 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/remove/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/remove/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/thrown-error/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/thrown-error/test.ts index 3a4313ae044e..276c77d9d04a 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/thrown-error/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/thrown-error/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/non-string-arg/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/non-string-arg/test.ts index a9002579e912..14d42a242cf3 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/non-string-arg/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/non-string-arg/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, runScriptInSandbox } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/rethrown/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/rethrown/test.ts index 53c16ad46e23..4a4cd9e0137f 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/rethrown/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/rethrown/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, runScriptInSandbox } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/syntax-errors/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/syntax-errors/test.ts index cd08b56ccee5..c11d1897e1c2 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/syntax-errors/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/syntax-errors/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, runScriptInSandbox } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-errors/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-errors/test.ts index 27dbcc771431..683d99b72e23 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-errors/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-errors/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, runScriptInSandbox } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-objects/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-objects/test.ts index 37a70678a2de..c2d174b1cd33 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-objects/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-objects/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, runScriptInSandbox } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-strings/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-strings/test.ts index 1245feb862e5..ff4eb3dd0002 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-strings/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onError/thrown-strings/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, runScriptInSandbox } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/custom-event/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/custom-event/test.ts index 0f0bc09ed6d7..639229c2dc7b 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/custom-event/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/custom-event/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/event/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/event/test.ts index 167cdc48870f..80fc86abd9cf 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/event/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/event/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-errors/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-errors/test.ts index 2d18376174c7..b895470d64f4 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-errors/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-errors/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-null/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-null/test.ts index f350ed0de639..88105df9a6c9 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-null/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-null/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-number/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-number/test.ts index 7fefb9037427..f9fa303d2774 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-number/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-number/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-object-complex/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-object-complex/test.ts index 80a23927d9b5..01b77e1a62a4 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-object-complex/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-object-complex/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-objects/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-objects/test.ts index e4e5fcfa2248..4b4a1d683caf 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-objects/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-objects/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-string-large/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-string-large/test.ts index 1bec29f18f6d..e198d6f944f0 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-string-large/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-string-large/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-strings/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-strings/test.ts index 91faa5536079..220cdcf77cbd 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-strings/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-strings/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-undefined/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-undefined/test.ts index 2195725a6599..d7dad5318e73 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-undefined/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/onUnhandledRejection/thrown-undefined/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/requestAnimationFrame/thrown-errors/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/requestAnimationFrame/thrown-errors/test.ts index e39e4c20a27b..c9eb70150f0c 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/requestAnimationFrame/thrown-errors/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/requestAnimationFrame/thrown-errors/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setInterval/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setInterval/test.ts index cdf8a4be9eb2..f8061c6ed4c1 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setInterval/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setInterval/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeout/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeout/test.ts index be46196aa754..c63f71650e8f 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeout/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeout/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeoutFrozen/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeoutFrozen/test.ts index 1fdee574b3f2..3ae6049d8c33 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeoutFrozen/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/setTimeoutFrozen/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/xhr/thrown-error/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/xhr/thrown-error/test.ts index 0a2114232e48..2e9f97915276 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/xhr/thrown-error/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/xhr/thrown-error/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setContext/multiple_contexts/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setContext/multiple_contexts/test.ts index 8e11f0cfde64..dfaab3d05b1e 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setContext/multiple_contexts/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setContext/multiple_contexts/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setContext/non_serializable_context/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setContext/non_serializable_context/test.ts index a54080159c2b..349ad39a3b57 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setContext/non_serializable_context/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setContext/non_serializable_context/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setContext/simple_context/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setContext/simple_context/test.ts index 1697d8735ede..beccf31ec42b 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setContext/simple_context/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setContext/simple_context/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setExtra/multiple_extras/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setExtra/multiple_extras/test.ts index e6d0b0a63f9e..6ba6202f2c4f 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setExtra/multiple_extras/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setExtra/multiple_extras/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts index 3a107189fc16..742c0e19f070 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setExtra/non_serializable_extra/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setExtra/simple_extra/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setExtra/simple_extra/test.ts index 8c3557d9f047..6d235e6b752b 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setExtra/simple_extra/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setExtra/simple_extra/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts index 64f9101b7057..c7b9e6a283b9 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setExtras/consecutive_calls/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setExtras/multiple_extras/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setExtras/multiple_extras/test.ts index b57f70b80c2b..0e388d77b3ba 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setExtras/multiple_extras/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setExtras/multiple_extras/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setTag/with_non_primitives/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setTag/with_non_primitives/test.ts index 2cbe0683e434..b270d7216d7a 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setTag/with_non_primitives/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setTag/with_non_primitives/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setTag/with_primitives/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setTag/with_primitives/test.ts index 3eb7567247c7..04725491b24c 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setTag/with_primitives/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setTag/with_primitives/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setTags/with_non_primitives/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setTags/with_non_primitives/test.ts index 2cbe0683e434..b270d7216d7a 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setTags/with_non_primitives/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setTags/with_non_primitives/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setTags/with_primitives/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setTags/with_primitives/test.ts index 3eb7567247c7..04725491b24c 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setTags/with_primitives/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setTags/with_primitives/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts index dbf5943c7814..ac3c06311bf9 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setUser/unset_user/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/setUser/update_user/test.ts b/dev-packages/browser-integration-tests/suites/public-api/setUser/update_user/test.ts index 915265a9a030..38a18daf2c2f 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/setUser/update_user/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/setUser/update_user/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/test.ts index bb125b5f5448..e78d377ebdff 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/circular_data/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-reject/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-reject/test.ts index 62beb28adcbe..b92de394703b 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-reject/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-reject/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw-not-awaited/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw-not-awaited/test.ts index 0bfb51c8863d..581e0bd61f9c 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw-not-awaited/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw-not-awaited/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw/test.ts index 9d966312973f..bb9db67db038 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-async-throw/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-sync/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-sync/test.ts index 1894cac93ec9..1930695c8f3e 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-sync/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/error-sync/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-in-scope/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-in-scope/test.ts index 8ad6e31eccce..6f46367a325f 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-in-scope/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-in-scope/test.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; -import type { TransactionEvent } from '@sentry/types'; +import type { TransactionEvent } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/test.ts index 212e4808f3e7..2cc4381c8307 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans-with-parentSpanId/test.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; -import type { TransactionEvent } from '@sentry/types'; +import type { TransactionEvent } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans/test.ts index 47e8e9fa3ac5..df60c3ee1aa3 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/parallel-root-spans/test.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; -import type { TransactionEvent } from '@sentry/types'; +import type { TransactionEvent } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/test.ts index 535d2dd7fc70..a5f55babd291 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/setMeasurement/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts index 7f3d21d22602..af87e11df37e 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone-mixed-transaction/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Envelope, EventEnvelope, SpanEnvelope, TransactionEvent } from '@sentry/types'; +import type { Envelope, EventEnvelope, SpanEnvelope, TransactionEvent } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone/test.ts index d871ead881a9..a37a50f28e04 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/standalone/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { SpanEnvelope } from '@sentry/types'; +import type { SpanEnvelope } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts b/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts index 07708d3f6df9..be81e06a6e40 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/withScope/nested_scopes/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/public-api/withScope/throwError/test.ts b/dev-packages/browser-integration-tests/suites/public-api/withScope/throwError/test.ts index 589b1e5c6f45..540cc36b2d10 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/withScope/throwError/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/withScope/throwError/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts b/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts index e95653f3cadc..384ee0071f64 100644 --- a/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts +++ b/dev-packages/browser-integration-tests/suites/replay/dsc/test.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; import type * as Sentry from '@sentry/browser'; -import type { EventEnvelopeHeaders } from '@sentry/types'; +import type { EventEnvelopeHeaders } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { @@ -58,7 +58,7 @@ sentryTest( expect(envHeader.trace).toEqual({ environment: 'production', sample_rate: '1', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', replay_id: replay.session?.id, sampled: 'true', @@ -105,7 +105,7 @@ sentryTest( expect(envHeader.trace).toEqual({ environment: 'production', sample_rate: '1', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', sampled: 'true', }); @@ -157,7 +157,7 @@ sentryTest( expect(envHeader.trace).toEqual({ environment: 'production', sample_rate: '1', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', replay_id: replay.session?.id, sampled: 'true', @@ -199,7 +199,7 @@ sentryTest( expect(envHeader.trace).toEqual({ environment: 'production', sample_rate: '1', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', sampled: 'true', }); @@ -240,7 +240,7 @@ sentryTest('should add replay_id to error DSC while replay is active', async ({ expect(error1Header.trace).toBeDefined(); expect(error1Header.trace).toEqual({ environment: 'production', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', replay_id: replay.session?.id, ...(hasTracing @@ -261,7 +261,7 @@ sentryTest('should add replay_id to error DSC while replay is active', async ({ expect(error2Header.trace).toBeDefined(); expect(error2Header.trace).toEqual({ environment: 'production', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', ...(hasTracing ? { diff --git a/dev-packages/browser-integration-tests/suites/sessions/initial-scope/test.ts b/dev-packages/browser-integration-tests/suites/sessions/initial-scope/test.ts index 985977a3f0a5..b3faacc6f88d 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/initial-scope/test.ts +++ b/dev-packages/browser-integration-tests/suites/sessions/initial-scope/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { SessionContext } from '@sentry/types'; +import type { SessionContext } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/sessions/start-session/test.ts b/dev-packages/browser-integration-tests/suites/sessions/start-session/test.ts index 8a8243d81257..0dd12d17fe95 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/start-session/test.ts +++ b/dev-packages/browser-integration-tests/suites/sessions/start-session/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { SessionContext } from '@sentry/types'; +import type { SessionContext } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/sessions/update-session/test.ts b/dev-packages/browser-integration-tests/suites/sessions/update-session/test.ts index 966b133dded1..3f1419d1615d 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/update-session/test.ts +++ b/dev-packages/browser-integration-tests/suites/sessions/update-session/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { SessionContext } from '@sentry/types'; +import type { SessionContext } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/test.ts b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/test.ts index 8a8243d81257..0dd12d17fe95 100644 --- a/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/test.ts +++ b/dev-packages/browser-integration-tests/suites/sessions/v7-hub-start-session/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { SessionContext } from '@sentry/types'; +import type { SessionContext } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/stacktraces/protocol_containing_fn_identifiers/test.ts b/dev-packages/browser-integration-tests/suites/stacktraces/protocol_containing_fn_identifiers/test.ts index 884dea9c618c..1767e2b1c5b5 100644 --- a/dev-packages/browser-integration-tests/suites/stacktraces/protocol_containing_fn_identifiers/test.ts +++ b/dev-packages/browser-integration-tests/suites/stacktraces/protocol_containing_fn_identifiers/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/stacktraces/protocol_fn_identifiers/test.ts b/dev-packages/browser-integration-tests/suites/stacktraces/protocol_fn_identifiers/test.ts index a78c15963814..1179080c1770 100644 --- a/dev-packages/browser-integration-tests/suites/stacktraces/protocol_fn_identifiers/test.ts +++ b/dev-packages/browser-integration-tests/suites/stacktraces/protocol_fn_identifiers/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/stacktraces/regular_fn_identifiers/test.ts b/dev-packages/browser-integration-tests/suites/stacktraces/regular_fn_identifiers/test.ts index 7585a21521e0..62f84db7ea9e 100644 --- a/dev-packages/browser-integration-tests/suites/stacktraces/regular_fn_identifiers/test.ts +++ b/dev-packages/browser-integration-tests/suites/stacktraces/regular_fn_identifiers/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/async-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/async-spans/test.ts index c9ffb2580615..eaf14c124260 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/async-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/async-spans/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-custom/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-custom/test.ts index 2997f614aa26..3047f40e67e6 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-custom/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-custom/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { SpanJSON } from '@sentry/types'; +import type { SpanJSON } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-pageload/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-pageload/test.ts index 0dcd11ee0159..564138235bb3 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-pageload/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/backgroundtab-pageload/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/error/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/error/test.ts index 3dbc9a90307c..fe48966ddd6e 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/error/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/error/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/http-timings/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/http-timings/test.ts index 8d6e9124a86e..e23ba53e3817 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/http-timings/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/http-timings/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -35,7 +35,7 @@ sentryTest('should create fetch spans with http timing @firefox', async ({ brows expect(span).toMatchObject({ description: `GET http://example.com/${index}`, parent_span_id: tracingEvent.contexts?.trace?.span_id, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: tracingEvent.contexts?.trace?.trace_id, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions/test.ts index 0bf03d3576ff..e8fa473e1a60 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/interactions/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event as SentryEvent } from '@sentry/types'; +import type { Event as SentryEvent } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-before-navigation/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-before-navigation/test.ts index a4804d0ff309..a9c63508faa0 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-before-navigation/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-before-navigation/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-disabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-disabled/test.ts index a0a263762186..a024358259c5 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-disabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-disabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-enabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-enabled/test.ts index b2729a70f4cf..b127a1f674a1 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-enabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-enabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/browser'; import { sentryTest } from '../../../../utils/fixtures'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-non-chromium/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-non-chromium/test.ts index 56d0456e9a2a..e59e9c96168b 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-non-chromium/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-animation-frame-non-chromium/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts index a3ad1e98a069..51447ee84586 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-and-animation-frame-enabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/browser'; import { sentryTest } from '../../../../utils/fixtures'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-before-navigation/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-before-navigation/test.ts index a2ac2817b853..2250fa234faf 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-before-navigation/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-before-navigation/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts index 47d212e44119..23b2d31b415e 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts index e0c655836561..c9c1a42ddb1a 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-no-animation-frame/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-no-animation-frame/test.ts index e0c655836561..c9c1a42ddb1a 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-no-animation-frame/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-no-animation-frame/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/meta/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/meta/test.ts index b33ea0cc444c..39cad4b8f7d0 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/meta/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/meta/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event, EventEnvelopeHeaders } from '@sentry/types'; +import type { Event, EventEnvelopeHeaders } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation/test.ts index 59939b0a6973..5e22d9a8d502 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/navigation/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts index 14a95ed9e29e..6226ff75dbb9 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload/test.ts index 6f855168ebce..6be7a5cbb9a4 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageloadDelayed/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageloadDelayed/test.ts index e0adc33e6271..cf14c46d47a7 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageloadDelayed/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageloadDelayed/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts b/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts index 41003a133b34..7ce5f7195a5b 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test'; import type { Page } from '@playwright/test'; -import type { DynamicSamplingContext } from '@sentry/types'; +import type { DynamicSamplingContext } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import type { EventAndTraceHeader } from '../../../utils/helpers'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts b/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts index f2f4b10ede46..db658c53d973 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { EventEnvelopeHeaders } from '@sentry/types'; +import type { EventEnvelopeHeaders } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { @@ -24,7 +24,7 @@ sentryTest( environment: 'production', sample_rate: '1', transaction: expect.stringContaining('/index.html'), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', sampled: 'true', }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/envelope-header/test.ts b/dev-packages/browser-integration-tests/suites/tracing/envelope-header/test.ts index fdfbac823166..0f2c08ff1781 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/envelope-header/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/envelope-header/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { EventEnvelopeHeaders } from '@sentry/types'; +import type { EventEnvelopeHeaders } from '@sentry/core'; import { sentryTest } from '../../../utils/fixtures'; import { @@ -27,7 +27,7 @@ sentryTest( expect(envHeader.trace).toEqual({ environment: 'production', sample_rate: '1', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', sampled: 'true', }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/connection-rtt/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/connection-rtt/test.ts index 145c718dd151..a3ec0c93bce8 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/connection-rtt/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/connection-rtt/test.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/handlers-lcp/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/handlers-lcp/test.ts index 78b48dc5a7f5..625c2a8f6d9a 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/handlers-lcp/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/handlers-lcp/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts index 3fb942f4aa67..4e840fd96cae 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-measure-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-measure-spans/test.ts index 7f2e2fae9021..acc50d68a070 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-measure-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-measure-spans/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts index 152cadf80418..2343d77f55c7 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts index b27d747df649..d227c0aaf575 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts @@ -1,6 +1,6 @@ import type { Page } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event as SentryEvent, EventEnvelope, SpanEnvelope } from '@sentry/types'; +import type { Event as SentryEvent, EventEnvelope, SpanEnvelope } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls/test.ts index 64ccba5d9b35..61c0a20e1506 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts index 469660563a4e..663774a23920 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fid/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fp-fcp/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fp-fcp/test.ts index bcdf9e232329..176d81edd930 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fp-fcp/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-fp-fcp/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts index 438c9c5f6ecd..61962bd40593 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-late/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event as SentryEvent, SpanEnvelope } from '@sentry/types'; +import type { Event as SentryEvent, SpanEnvelope } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts index c68903f23e71..788c168067bd 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized-late/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event as SentryEvent, SpanEnvelope } from '@sentry/types'; +import type { Event as SentryEvent, SpanEnvelope } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts index 4f3c262d780d..5da11a8caae3 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp-parametrized/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { SpanEnvelope } from '@sentry/types'; +import type { SpanEnvelope } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts index ab2146185b72..0a159db4dc31 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-inp/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event as SentryEvent, SpanEnvelope, SpanJSON } from '@sentry/types'; +import type { Event as SentryEvent, SpanEnvelope, SpanJSON } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts index 84e93b54ac9b..1cfee3b670a7 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-lcp/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-ttfb/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-ttfb/test.ts index e135601f7ddf..602b4671f342 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-ttfb/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-ttfb/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals/test.ts index c41efad620ac..3f29c0614f14 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts index d4a6065a177b..623a27299077 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch-relative-url/test.ts @@ -24,7 +24,7 @@ sentryTest('should create spans for fetch requests', async ({ getLocalTestUrl, p expect(span).toMatchObject({ description: `GET /test-req/${index}`, parent_span_id: tracingEvent.contexts?.trace?.span_id, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: tracingEvent.contexts?.trace?.trace_id, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts index 53ff985a3f1b..bcbfa1890cdd 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -28,7 +28,7 @@ sentryTest('should create spans for fetch requests', async ({ getLocalTestUrl, p expect(span).toMatchObject({ description: `GET http://example.com/${index}`, parent_span_id: tracingEvent.contexts?.trace?.span_id, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: tracingEvent.contexts?.trace?.trace_id, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts index f3dca9359b8b..7baedcae7a02 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr-relative-url/test.ts @@ -24,7 +24,7 @@ sentryTest('should create spans for xhr requests', async ({ getLocalTestUrl, pag expect(span).toMatchObject({ description: `GET /test-req/${index}`, parent_span_id: tracingEvent.contexts?.trace?.span_id, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: tracingEvent.contexts?.trace?.trace_id, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts index 5cc65c872c08..4288c6727ab7 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -20,7 +20,7 @@ sentryTest('should create spans for XHR requests', async ({ getLocalTestUrl, pag expect(span).toMatchObject({ description: `GET http://example.com/${index}`, parent_span_id: eventData.contexts?.trace?.span_id, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: eventData.contexts?.trace?.trace_id, diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts index f6cb0a413878..cd1e79c211aa 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/navigation/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import type { EventAndTraceHeader } from '../../../../utils/helpers'; import { shouldSkipFeedbackTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts index bdfe0521c433..d102ad4c128e 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload-meta/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import type { EventAndTraceHeader } from '../../../../utils/helpers'; import { shouldSkipFeedbackTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts index c9e07869a237..00bbb26740de 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/trace-lifetime/pageload/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import type { EventAndTraceHeader } from '../../../../utils/helpers'; import { shouldSkipFeedbackTest } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/suites/transport/offline/queued/test.ts b/dev-packages/browser-integration-tests/suites/transport/offline/queued/test.ts index 4cd9b1e8fdff..9b6eb36fd0ea 100644 --- a/dev-packages/browser-integration-tests/suites/transport/offline/queued/test.ts +++ b/dev-packages/browser-integration-tests/suites/transport/offline/queued/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers'; diff --git a/dev-packages/browser-integration-tests/utils/generatePlugin.ts b/dev-packages/browser-integration-tests/utils/generatePlugin.ts index 26a086bf2a77..c3b515ada32d 100644 --- a/dev-packages/browser-integration-tests/utils/generatePlugin.ts +++ b/dev-packages/browser-integration-tests/utils/generatePlugin.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import path from 'path'; -import type { Package } from '@sentry/types'; +import type { Package } from '@sentry/core'; import HtmlWebpackPlugin, { createHtmlTagObject } from 'html-webpack-plugin'; import type { Compiler } from 'webpack'; diff --git a/dev-packages/browser-integration-tests/utils/helpers.ts b/dev-packages/browser-integration-tests/utils/helpers.ts index 34e591cad0dc..df60adfcaabb 100644 --- a/dev-packages/browser-integration-tests/utils/helpers.ts +++ b/dev-packages/browser-integration-tests/utils/helpers.ts @@ -8,7 +8,7 @@ import type { EventEnvelope, EventEnvelopeHeaders, TransactionEvent, -} from '@sentry/types'; +} from '@sentry/core'; export const envelopeUrlRegex = /\.sentry\.io\/api\/\d+\/envelope\//; diff --git a/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts b/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts index 40e303e9b0cb..63152d54870b 100644 --- a/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts +++ b/dev-packages/browser-integration-tests/utils/replayEventTemplates.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { expect } from '@playwright/test'; import { SDK_VERSION } from '@sentry/browser'; -import type { ReplayEvent } from '@sentry/types'; +import type { ReplayEvent } from '@sentry/core'; const DEFAULT_REPLAY_EVENT = { type: 'replay_event', diff --git a/dev-packages/browser-integration-tests/utils/replayHelpers.ts b/dev-packages/browser-integration-tests/utils/replayHelpers.ts index 36727664dce3..e090eba48200 100644 --- a/dev-packages/browser-integration-tests/utils/replayHelpers.ts +++ b/dev-packages/browser-integration-tests/utils/replayHelpers.ts @@ -11,7 +11,7 @@ import type { import type { fullSnapshotEvent, incrementalSnapshotEvent } from '@sentry-internal/rrweb'; import { EventType } from '@sentry-internal/rrweb'; import type { ReplayEventWithTime } from '@sentry/browser'; -import type { Breadcrumb, Event, ReplayEvent, ReplayRecordingMode } from '@sentry/types'; +import type { Breadcrumb, Event, ReplayEvent, ReplayRecordingMode } from '@sentry/core'; import pako from 'pako'; import { envelopeRequestParser } from './helpers'; diff --git a/dev-packages/bundle-analyzer-scenarios/package.json b/dev-packages/bundle-analyzer-scenarios/package.json index 59cae79dd9e5..3ec7ca42becb 100644 --- a/dev-packages/bundle-analyzer-scenarios/package.json +++ b/dev-packages/bundle-analyzer-scenarios/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/bundle-analyzer-scenarios", - "version": "8.40.0", + "version": "8.42.0", "description": "Scenarios to test bundle analysis with", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/dev-packages/bundle-analyzer-scenarios", diff --git a/dev-packages/clear-cache-gh-action/package.json b/dev-packages/clear-cache-gh-action/package.json index fb5a67883575..1ed18e1a8997 100644 --- a/dev-packages/clear-cache-gh-action/package.json +++ b/dev-packages/clear-cache-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/clear-cache-gh-action", "description": "An internal Github Action to clear GitHub caches.", - "version": "8.40.0", + "version": "8.42.0", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json index 579a22f41d31..3a929c871068 100644 --- a/dev-packages/e2e-tests/package.json +++ b/dev-packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/e2e-tests", - "version": "8.40.0", + "version": "8.42.0", "license": "MIT", "private": true, "scripts": { @@ -13,10 +13,11 @@ "test:validate-test-app-setups": "ts-node validate-test-app-setups.ts", "test:prepare": "ts-node prepare.ts", "test:validate": "run-s test:validate-configuration test:validate-test-app-setups", - "clean": "rimraf tmp node_modules pnpm-lock.yaml && yarn clean:test-applications", + "clean": "rimraf tmp node_modules && yarn clean:test-applications && yarn clean:pnpm", "ci:build-matrix": "ts-node ./lib/getTestMatrix.ts", "ci:build-matrix-optional": "ts-node ./lib/getTestMatrix.ts --optional=true", - "clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml,.last-run.json,test-results} && pnpm store prune" + "clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml,.last-run.json,test-results}", + "clean:pnpm": "pnpm store prune" }, "devDependencies": { "@types/glob": "8.0.0", @@ -24,12 +25,11 @@ "dotenv": "16.0.3", "esbuild": "0.20.0", "glob": "8.0.3", - "rimraf": "^5.0.0", + "rimraf": "^5.0.10", "ts-node": "10.9.1", "yaml": "2.2.2" }, "volta": { - "extends": "../../package.json", - "pnpm": "9.4.0" + "extends": "../../package.json" } } diff --git a/dev-packages/e2e-tests/test-applications/astro-4/tests/errors.server.test.ts b/dev-packages/e2e-tests/test-applications/astro-4/tests/errors.server.test.ts index d5f07ebe239a..3faacdb30090 100644 --- a/dev-packages/e2e-tests/test-applications/astro-4/tests/errors.server.test.ts +++ b/dev-packages/e2e-tests/test-applications/astro-4/tests/errors.server.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { waitForError } from '@sentry-internal/test-utils'; +import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; test.describe('server-side errors', () => { test('captures SSR error', async ({ page }) => { @@ -7,9 +7,26 @@ test.describe('server-side errors', () => { return errorEvent?.exception?.values?.[0]?.value === "Cannot read properties of undefined (reading 'x')"; }); + const transactionEventPromise = waitForTransaction('astro-4', transactionEvent => { + return transactionEvent.transaction === 'GET /ssr-error'; + }); + await page.goto('/ssr-error'); const errorEvent = await errorEventPromise; + const transactionEvent = await transactionEventPromise; + + expect(transactionEvent).toMatchObject({ + transaction: 'GET /ssr-error', + spans: [], + }); + + const traceId = transactionEvent.contexts?.trace?.trace_id; + const spanId = transactionEvent.contexts?.trace?.span_id; + + expect(traceId).toMatch(/[a-f0-9]{32}/); + expect(spanId).toMatch(/[a-f0-9]{16}/); + expect(transactionEvent.contexts?.trace?.parent_span_id).toBeUndefined(); expect(errorEvent).toMatchObject({ contexts: { @@ -20,8 +37,8 @@ test.describe('server-side errors', () => { os: expect.any(Object), runtime: expect.any(Object), trace: { - span_id: '', //TODO: This is a bug! We should expect.stringMatching(/[a-f0-9]{16}/) instead of '' - trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: spanId, + trace_id: traceId, }, }, environment: 'qa', @@ -69,18 +86,50 @@ test.describe('server-side errors', () => { const errorEventPromise = waitForError('astro-4', errorEvent => { return errorEvent?.exception?.values?.[0]?.value === 'Endpoint Error'; }); + const transactionEventApiPromise = waitForTransaction('astro-4', transactionEvent => { + return transactionEvent.transaction === 'GET /endpoint-error/api'; + }); + const transactionEventEndpointPromise = waitForTransaction('astro-4', transactionEvent => { + return transactionEvent.transaction === 'GET /endpoint-error'; + }); await page.goto('/endpoint-error'); await page.getByText('Get Data').click(); const errorEvent = await errorEventPromise; + const transactionEventApi = await transactionEventApiPromise; + const transactionEventEndpoint = await transactionEventEndpointPromise; + + expect(transactionEventEndpoint).toMatchObject({ + transaction: 'GET /endpoint-error', + spans: [], + }); + + const traceId = transactionEventEndpoint.contexts?.trace?.trace_id; + const endpointSpanId = transactionEventApi.contexts?.trace?.span_id; + + expect(traceId).toMatch(/[a-f0-9]{32}/); + expect(endpointSpanId).toMatch(/[a-f0-9]{16}/); + + expect(transactionEventApi).toMatchObject({ + transaction: 'GET /endpoint-error/api', + spans: [], + }); + + const spanId = transactionEventApi.contexts?.trace?.span_id; + const parentSpanId = transactionEventApi.contexts?.trace?.parent_span_id; + + expect(spanId).toMatch(/[a-f0-9]{16}/); + // TODO: This is incorrect, for whatever reason, it should be the endpointSpanId ideally + expect(parentSpanId).toMatch(/[a-f0-9]{16}/); + expect(parentSpanId).not.toEqual(endpointSpanId); expect(errorEvent).toMatchObject({ contexts: { trace: { - parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), - span_id: expect.stringMatching(/[a-f0-9]{16}/), - trace_id: expect.stringMatching(/[a-f0-9]{32}/), + parent_span_id: parentSpanId, + span_id: spanId, + trace_id: traceId, }, }, exception: { diff --git a/dev-packages/e2e-tests/test-applications/aws-lambda-layer-cjs/tests/basic.test.ts b/dev-packages/e2e-tests/test-applications/aws-lambda-layer-cjs/tests/basic.test.ts index 53a44c424cf4..babd00bd4d7c 100644 --- a/dev-packages/e2e-tests/test-applications/aws-lambda-layer-cjs/tests/basic.test.ts +++ b/dev-packages/e2e-tests/test-applications/aws-lambda-layer-cjs/tests/basic.test.ts @@ -37,9 +37,9 @@ test('Lambda layer SDK bundle sends events', async ({ request }) => { }, op: 'function.aws.lambda', origin: 'auto.otel.aws-lambda', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(transactionEvent.spans).toHaveLength(2); diff --git a/dev-packages/e2e-tests/test-applications/aws-serverless-esm/tests/basic.test.ts b/dev-packages/e2e-tests/test-applications/aws-serverless-esm/tests/basic.test.ts index f6e57655ad08..62190c78f4a3 100644 --- a/dev-packages/e2e-tests/test-applications/aws-serverless-esm/tests/basic.test.ts +++ b/dev-packages/e2e-tests/test-applications/aws-serverless-esm/tests/basic.test.ts @@ -34,9 +34,9 @@ test('AWS Serverless SDK sends events in ESM mode', async ({ request }) => { }, op: 'function.aws.lambda', origin: 'auto.function.serverless', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(transactionEvent.spans).toHaveLength(2); diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-errors.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-errors.test.ts index 5e06086f1a29..e0effa285b9f 100644 --- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-errors.test.ts @@ -24,7 +24,7 @@ test('Sends a client-side exception to Sentry', async ({ page }) => { expect(errorEvent.transaction).toEqual('/'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-transactions.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-transactions.test.ts index d46191a77c03..8721a4d086bb 100644 --- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/create-next-app/tests/client-transactions.test.ts @@ -20,8 +20,8 @@ test('Sends a pageload transaction to Sentry', async ({ page }) => { version: '18.2.0', }, trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), op: 'pageload', origin: 'auto.pageload.nextjs.pages_router_instrumentation', data: expect.objectContaining({ @@ -65,8 +65,8 @@ test('captures a navigation transcation to Sentry', async ({ page }) => { version: '18.2.0', }, trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), op: 'navigation', origin: 'auto.navigation.nextjs.pages_router_instrumentation', data: expect.objectContaining({ diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-errors.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-errors.test.ts index ed3263f5eb8b..08a47ace671f 100644 --- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-errors.test.ts @@ -25,7 +25,7 @@ test('Sends a server-side exception to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /api/error'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-transactions.test.ts b/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-transactions.test.ts index db5aec11ced0..731d1820ee61 100644 --- a/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/create-next-app/tests/server-transactions.test.ts @@ -19,8 +19,8 @@ test('Sends server-side transactions to Sentry', async ({ baseURL }) => { type: 'transaction', contexts: expect.objectContaining({ trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), op: 'http.server', origin: 'auto.http.nextjs', data: expect.objectContaining({ @@ -41,7 +41,7 @@ test('Sends server-side transactions to Sentry', async ({ baseURL }) => { description: 'test-span', origin: 'manual', parent_span_id: transactionEvent.contexts?.trace?.span_id, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express-legacy/package.json b/dev-packages/e2e-tests/test-applications/create-remix-app-express-legacy/package.json index 1b9747d95bdf..047218b29e3f 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express-legacy/package.json +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-express-legacy/package.json @@ -31,7 +31,6 @@ "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", "@remix-run/dev": "^2.7.2", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@types/compression": "^1.7.2", "@types/express": "^4.17.17", diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/package.json b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/package.json index 534078696906..6e9f884bedde 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/package.json +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/package.json @@ -28,7 +28,6 @@ "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", "@remix-run/dev": "^2.7.2", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@types/compression": "^1.7.5", "@types/express": "^4.17.20", diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express/package.json b/dev-packages/e2e-tests/test-applications/create-remix-app-express/package.json index 1b9747d95bdf..047218b29e3f 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express/package.json +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-express/package.json @@ -31,7 +31,6 @@ "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", "@remix-run/dev": "^2.7.2", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@types/compression": "^1.7.2", "@types/express": "^4.17.17", diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/package.json b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/package.json index 1bd69b66ff67..1d99cf43d3b6 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/package.json +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-legacy/package.json @@ -29,7 +29,6 @@ "@remix-run/eslint-config": "^1.19.3", "@types/react": "^18.0.35", "@types/react-dom": "^18.0.11", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "eslint": "^8.38.0", "typescript": "^5.0.4" diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-v2-legacy/package.json b/dev-packages/e2e-tests/test-applications/create-remix-app-v2-legacy/package.json index 93938b75c6a1..3772ea5c76f6 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-v2-legacy/package.json +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-v2-legacy/package.json @@ -25,7 +25,6 @@ "@sentry-internal/test-utils": "link:../../../test-utils", "@remix-run/dev": "2.7.2", "@remix-run/eslint-config": "2.7.2", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@types/react": "^18.0.35", "@types/react-dom": "^18.0.11", diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/package.json b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/package.json index 17adb9ace8ae..d1600004d97f 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/package.json +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/package.json @@ -25,7 +25,6 @@ "@sentry-internal/test-utils": "link:../../../test-utils", "@remix-run/dev": "2.7.2", "@remix-run/eslint-config": "2.7.2", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@types/react": "^18.0.35", "@types/react-dom": "^18.0.11", diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app/package.json b/dev-packages/e2e-tests/test-applications/create-remix-app/package.json index a3210d7c3187..34ec42143c9e 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app/package.json +++ b/dev-packages/e2e-tests/test-applications/create-remix-app/package.json @@ -29,7 +29,6 @@ "@remix-run/eslint-config": "^1.19.3", "@types/react": "^18.0.35", "@types/react-dom": "^18.0.11", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "eslint": "^8.38.0", "typescript": "^5.0.4" diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts b/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts index 8fe1993db3f8..7e9a4fe96972 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts +++ b/dev-packages/e2e-tests/test-applications/create-remix-app/tests/client-inp.test.ts @@ -34,12 +34,12 @@ test('sends an INP span during pageload', async ({ page }) => { }, description: 'body > div > input#exception-button[type="button"]', op: 'ui.interaction.click', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), is_segment: true, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.browser.inp', exclusive_time: expect.any(Number), measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } }, @@ -86,12 +86,12 @@ test('sends an INP span after pageload', async ({ page }) => { }, description: 'body > div > input#exception-button[type="button"]', op: 'ui.interaction.click', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), is_segment: true, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.browser.inp', exclusive_time: expect.any(Number), measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } }, @@ -131,11 +131,11 @@ test('sends an INP span during navigation', async ({ page }) => { }, description: '', op: 'ui.interaction.click', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.browser.inp', exclusive_time: expect.any(Number), measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } }, @@ -186,10 +186,10 @@ test('sends an INP span after navigation', async ({ page }) => { description: '', op: 'ui.interaction.click', is_segment: true, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.browser.inp', exclusive_time: expect.any(Number), measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } }, diff --git a/dev-packages/e2e-tests/test-applications/default-browser/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/default-browser/tests/errors.test.ts index e4f2eda9a579..a84bfe6d4788 100644 --- a/dev-packages/e2e-tests/test-applications/default-browser/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/default-browser/tests/errors.test.ts @@ -24,8 +24,8 @@ test('captures an error', async ({ page }) => { }); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/ember-classic/package.json b/dev-packages/e2e-tests/test-applications/ember-classic/package.json index 2de3891d90af..681f9fabb919 100644 --- a/dev-packages/e2e-tests/test-applications/ember-classic/package.json +++ b/dev-packages/e2e-tests/test-applications/ember-classic/package.json @@ -18,7 +18,7 @@ "test:build": "pnpm install && npx playwright install && pnpm build", "test:build-latest": "pnpm install && pnpm add ember-source@latest && npx playwright install && pnpm build", "test:assert": "playwright test", - "clean": "npx rimraf node_modules,pnpm-lock.yaml,dist" + "clean": "npx rimraf node_modules pnpm-lock.yaml dist" }, "devDependencies": { "@ember/optional-features": "^2.0.0", diff --git a/dev-packages/e2e-tests/test-applications/ember-classic/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/ember-classic/tests/performance.test.ts index 47f3cdb0a6b4..e6aa4747bf92 100644 --- a/dev-packages/e2e-tests/test-applications/ember-classic/tests/performance.test.ts +++ b/dev-packages/e2e-tests/test-applications/ember-classic/tests/performance.test.ts @@ -157,7 +157,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.transition', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -174,7 +174,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.before_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -189,7 +189,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.before_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -207,7 +207,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -222,7 +222,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -240,7 +240,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.after_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -255,7 +255,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.after_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -271,7 +271,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.runloop.render', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, diff --git a/dev-packages/e2e-tests/test-applications/ember-embroider/package.json b/dev-packages/e2e-tests/test-applications/ember-embroider/package.json index 1512a07d122c..bc312e034a22 100644 --- a/dev-packages/e2e-tests/test-applications/ember-embroider/package.json +++ b/dev-packages/e2e-tests/test-applications/ember-embroider/package.json @@ -18,7 +18,7 @@ "test:build": "pnpm install && npx playwright install && pnpm build", "test:build-latest": "pnpm install && pnpm add ember-source@latest && npx playwright install && pnpm build", "test:assert": "playwright test", - "clean": "npx rimraf node_modules,pnpm-lock.yaml,dist" + "clean": "npx rimraf node_modules pnpm-lock.yaml dist" }, "devDependencies": { "@babel/core": "^7.24.4", @@ -68,5 +68,8 @@ }, "volta": { "extends": "../../package.json" + }, + "sentryTest": { + "skip": true } } diff --git a/dev-packages/e2e-tests/test-applications/ember-embroider/tests/performance.test.ts b/dev-packages/e2e-tests/test-applications/ember-embroider/tests/performance.test.ts index a26bec292650..a82964b46a92 100644 --- a/dev-packages/e2e-tests/test-applications/ember-embroider/tests/performance.test.ts +++ b/dev-packages/e2e-tests/test-applications/ember-embroider/tests/performance.test.ts @@ -157,7 +157,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.transition', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -174,7 +174,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.before_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -189,7 +189,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.before_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -207,7 +207,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -222,7 +222,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -240,7 +240,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.after_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -255,7 +255,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.route.after_model', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, @@ -271,7 +271,7 @@ test('captures correct spans for navigation', async ({ page }) => { op: 'ui.ember.runloop.render', origin: 'auto.ui.ember', parent_span_id: spanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), trace_id: traceId, diff --git a/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts b/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts index 0a78073e88ae..03cebd495539 100644 --- a/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts +++ b/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts @@ -7,8 +7,4 @@ import * as _SentryCore from '@sentry/core'; // biome-ignore lint/nursery/noUnusedImports: import * as _SentryNode from '@sentry/node'; // biome-ignore lint/nursery/noUnusedImports: -import * as _SentryTypes from '@sentry/types'; -// biome-ignore lint/nursery/noUnusedImports: -import * as _SentryUtils from '@sentry/utils'; -// biome-ignore lint/nursery/noUnusedImports: import * as _SentryWasm from '@sentry/wasm'; diff --git a/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json b/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json index eda13af9e170..77bebc280ea4 100644 --- a/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json +++ b/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json @@ -18,8 +18,6 @@ "@sentry/core": "latest || *", "@sentry/node": "latest || *", "@sentry-internal/replay": "latest || *", - "@sentry/types": "latest || *", - "@sentry/core": "latest || *", "@sentry/wasm": "latest || *" } } diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/package.json b/dev-packages/e2e-tests/test-applications/nestjs-8/package.json index 9cf681c33ef5..20724e8d3b78 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/package.json +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/package.json @@ -21,7 +21,6 @@ "@nestjs/schedule": "^4.1.0", "@nestjs/platform-express": "^8.0.0", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/src/app.service.ts b/dev-packages/e2e-tests/test-applications/nestjs-8/src/app.service.ts index 72aef6947a6c..6b6b01411c0c 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/src/app.service.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/src/app.service.ts @@ -1,9 +1,9 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { RpcException } from '@nestjs/microservices'; import { Cron, SchedulerRegistry } from '@nestjs/schedule'; +import type { MonitorConfig } from '@sentry/core'; import * as Sentry from '@sentry/nestjs'; import { SentryCron, SentryTraced } from '@sentry/nestjs'; -import type { MonitorConfig } from '@sentry/types'; const monitorConfig: MonitorConfig = { schedule: { diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/cron-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/cron-decorator.test.ts index dee95c1f1b01..d5d0cc44a418 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/cron-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/cron-decorator.test.ts @@ -27,8 +27,8 @@ test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { }, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, }), @@ -43,8 +43,8 @@ test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { duration: expect.any(Number), contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, }), diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/errors.test.ts index 72570f43efc4..e60e94691210 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/errors.test.ts @@ -24,8 +24,9 @@ test('Sends exception to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/span-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/span-decorator.test.ts index 2aa097d5262c..57eca5bc9dfe 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/span-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/span-decorator.test.ts @@ -19,14 +19,14 @@ test('Transaction includes span and correct value for decorated async function', expect(transactionEvent.spans).toEqual( expect.arrayContaining([ expect.objectContaining({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'manual', 'sentry.op': 'wait and return a string', }, description: 'wait', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', op: 'wait and return a string', @@ -54,14 +54,14 @@ test('Transaction includes span and correct value for decorated sync function', expect(transactionEvent.spans).toEqual( expect.arrayContaining([ expect.objectContaining({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'manual', 'sentry.op': 'return a string', }, description: 'getString', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', op: 'return a string', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts index dc72d6c639e8..cab90847df50 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -59,12 +59,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, op: 'request_handler.express', description: '/test-transaction', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.express', }, { @@ -72,12 +72,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { @@ -85,17 +85,17 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.nestjs', 'sentry.op': 'handler.nestjs', @@ -105,7 +105,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'nestjs.callback': 'testTransaction', }, description: 'testTransaction', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -141,14 +141,14 @@ test('API route transaction includes nest middleware span. Spans created in and expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleMiddleware', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -166,22 +166,22 @@ test('API route transaction includes nest middleware span. Spans created in and expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-middleware-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -221,14 +221,14 @@ test('API route transaction includes nest guard span and span started in guard i expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleGuard', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -246,11 +246,11 @@ test('API route transaction includes nest guard span and span started in guard i expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-guard-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -285,14 +285,14 @@ test('API route transaction includes nest pipe span for valid request', async ({ expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ParseIntPipe', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -322,14 +322,14 @@ test('API route transaction includes nest pipe span for invalid request', async expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ParseIntPipe', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'unknown_error', @@ -361,14 +361,14 @@ test('API route transaction includes nest interceptor spans before route executi expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleInterceptor1', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -376,14 +376,14 @@ test('API route transaction includes nest interceptor spans before route executi origin: 'auto.middleware.nestjs', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleInterceptor2', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -405,33 +405,33 @@ test('API route transaction includes nest interceptor spans before route executi expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-1', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-2', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -479,14 +479,14 @@ test('API route transaction includes exactly one nest interceptor span after rou expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'Interceptors - After Route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -514,11 +514,11 @@ test('API route transaction includes exactly one nest interceptor span after rou expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-after-route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -561,14 +561,14 @@ test('API route transaction includes nest async interceptor spans before route e expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'AsyncInterceptor', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -588,22 +588,22 @@ test('API route transaction includes nest async interceptor spans before route e expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-async-interceptor-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -646,14 +646,14 @@ test('API route transaction includes exactly one nest async interceptor span aft expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'Interceptors - After Route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -681,11 +681,11 @@ test('API route transaction includes exactly one nest async interceptor span aft expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-async-interceptor-span-after-route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic-with-graphql/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic-with-graphql/tests/errors.test.ts index 2071e436e133..62103cfafbd9 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic-with-graphql/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic-with-graphql/tests/errors.test.ts @@ -24,8 +24,9 @@ test('Sends exception to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); @@ -112,7 +113,8 @@ test('Sends graphql exception to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('POST /graphql'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/package.json b/dev-packages/e2e-tests/test-applications/nestjs-basic/package.json index f7a0da2fc403..44dcda348383 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/package.json +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/package.json @@ -21,7 +21,6 @@ "@nestjs/schedule": "^4.1.0", "@nestjs/platform-express": "^10.0.0", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/src/app.service.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/src/app.service.ts index 067282dd1ee2..242b4c778a0e 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/src/app.service.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/src/app.service.ts @@ -1,9 +1,9 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { RpcException } from '@nestjs/microservices'; import { Cron, SchedulerRegistry } from '@nestjs/schedule'; +import type { MonitorConfig } from '@sentry/core'; import * as Sentry from '@sentry/nestjs'; import { SentryCron, SentryTraced } from '@sentry/nestjs'; -import type { MonitorConfig } from '@sentry/types'; const monitorConfig: MonitorConfig = { schedule: { diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts index 03ae6011d2b4..7896603b3bd9 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/cron-decorator.test.ts @@ -35,8 +35,8 @@ test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { }, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, }), @@ -51,8 +51,8 @@ test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { duration: expect.any(Number), contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, }), @@ -72,8 +72,8 @@ test('Sends exceptions to Sentry on error in cron job', async ({ baseURL }) => { expect(errorEvent.exception?.values).toHaveLength(1); expect(errorEvent.exception?.values?.[0]?.value).toBe('Test error from cron job'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); // kill cron so tests don't get stuck diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts index ee7d12dd22ca..748730985cf6 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/errors.test.ts @@ -24,8 +24,9 @@ test('Sends exception to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts index ee7666a50f18..b82213e6157a 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/span-decorator.test.ts @@ -19,14 +19,14 @@ test('Transaction includes span and correct value for decorated async function', expect(transactionEvent.spans).toEqual( expect.arrayContaining([ expect.objectContaining({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'manual', 'sentry.op': 'wait and return a string', }, description: 'wait', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', op: 'wait and return a string', @@ -54,14 +54,14 @@ test('Transaction includes span and correct value for decorated sync function', expect(transactionEvent.spans).toEqual( expect.arrayContaining([ expect.objectContaining({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'manual', 'sentry.op': 'return a string', }, description: 'getString', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', op: 'return a string', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts index a9c8ffea9117..c37eb8da7cc1 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -59,12 +59,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, op: 'request_handler.express', description: '/test-transaction', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.express', }, { @@ -72,12 +72,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { @@ -85,17 +85,17 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.nestjs', 'sentry.op': 'handler.nestjs', @@ -105,7 +105,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'nestjs.callback': 'testTransaction', }, description: 'testTransaction', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -141,14 +141,14 @@ test('API route transaction includes nest middleware span. Spans created in and expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleMiddleware', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -166,22 +166,22 @@ test('API route transaction includes nest middleware span. Spans created in and expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-middleware-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -221,14 +221,14 @@ test('API route transaction includes nest guard span and span started in guard i expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleGuard', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -246,11 +246,11 @@ test('API route transaction includes nest guard span and span started in guard i expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-guard-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -285,14 +285,14 @@ test('API route transaction includes nest pipe span for valid request', async ({ expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ParseIntPipe', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -322,14 +322,14 @@ test('API route transaction includes nest pipe span for invalid request', async expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ParseIntPipe', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'unknown_error', @@ -361,14 +361,14 @@ test('API route transaction includes nest interceptor spans before route executi expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleInterceptor1', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -376,14 +376,14 @@ test('API route transaction includes nest interceptor spans before route executi origin: 'auto.middleware.nestjs', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleInterceptor2', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -405,33 +405,33 @@ test('API route transaction includes nest interceptor spans before route executi expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-1', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-2', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -479,14 +479,14 @@ test('API route transaction includes exactly one nest interceptor span after rou expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'Interceptors - After Route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -514,11 +514,11 @@ test('API route transaction includes exactly one nest interceptor span after rou expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-after-route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -561,14 +561,14 @@ test('API route transaction includes nest async interceptor spans before route e expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'AsyncInterceptor', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -588,22 +588,22 @@ test('API route transaction includes nest async interceptor spans before route e expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-async-interceptor-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -646,14 +646,14 @@ test('API route transaction includes exactly one nest async interceptor span aft expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'Interceptors - After Route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -681,11 +681,11 @@ test('API route transaction includes exactly one nest async interceptor span aft expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-async-interceptor-span-after-route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/package.json b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/package.json index efc52a8a4db9..6efae6b1c0d5 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/package.json +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/package.json @@ -20,7 +20,6 @@ "@nestjs/platform-express": "^10.0.0", "@nestjs/event-emitter": "^2.0.0", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/events.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/events.test.ts index b09eabb38980..227851d458cf 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/events.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/events.test.ts @@ -27,9 +27,9 @@ test('Event emitter', async () => { }); expect(successEventTransaction.contexts.trace).toEqual({ - parent_span_id: expect.any(String), - span_id: expect.any(String), - trace_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.source': 'custom', 'sentry.sample_rate': 1, diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts index d928deac08fd..ecc67e26ab16 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts @@ -1,7 +1,7 @@ import crypto from 'crypto'; import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -import { SpanJSON } from '@sentry/types'; +import { SpanJSON } from '@sentry/core'; test('Propagates trace for outgoing http requests', async ({ baseURL }) => { const id = crypto.randomUUID(); @@ -78,7 +78,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-http/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -111,7 +111,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { }, op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -193,7 +193,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-fetch/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -226,7 +226,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { }), op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-graphql/package.json b/dev-packages/e2e-tests/test-applications/nestjs-graphql/package.json index 91f495776575..2463d24df940 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-graphql/package.json +++ b/dev-packages/e2e-tests/test-applications/nestjs-graphql/package.json @@ -22,7 +22,6 @@ "@nestjs/graphql": "^12.2.0", "@nestjs/platform-express": "^10.3.10", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "graphql": "^16.9.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1" diff --git a/dev-packages/e2e-tests/test-applications/nestjs-graphql/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-graphql/tests/errors.test.ts index 48e0ef8c2c9f..9f9e7cdc0d17 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-graphql/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-graphql/tests/errors.test.ts @@ -43,7 +43,8 @@ test('Sends exception to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('POST /graphql'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/package.json b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/package.json index 9cc3641d2322..0b03e38ccbdb 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/package.json +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/package.json @@ -19,7 +19,6 @@ "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/errors.test.ts index 94c742dd210a..fc7520fbcb7b 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/errors.test.ts @@ -32,8 +32,9 @@ test('Sends unexpected exception to Sentry if thrown in module with global filte expect(errorEvent.transaction).toEqual('GET /example-module/unexpected-exception'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); @@ -68,8 +69,9 @@ test('Sends unexpected exception to Sentry if thrown in module with local filter expect(errorEvent.transaction).toEqual('GET /example-module-local-filter/unexpected-exception'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); @@ -106,8 +108,9 @@ test('Sends unexpected exception to Sentry if thrown in module that was register expect(errorEvent.transaction).toEqual('GET /example-module-registered-first/unexpected-exception'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts index 740ab6f5650c..5fb9c98ffc66 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'http.route': '/example-module/transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -59,12 +59,12 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { }, op: 'request_handler.express', description: '/example-module/transaction', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.express', }, { @@ -72,12 +72,12 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { @@ -85,17 +85,17 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.nestjs', 'sentry.op': 'handler.nestjs', @@ -105,7 +105,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'nestjs.callback': 'testTransaction', }, description: 'testTransaction', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -142,14 +142,14 @@ test('API route transaction includes exception filter span for global filter in expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleExceptionFilter', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -181,14 +181,14 @@ test('API route transaction includes exception filter span for local filter in m expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'LocalExampleExceptionFilter', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -220,14 +220,14 @@ test('API route transaction includes exception filter span for global filter in expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleExceptionFilterRegisteredFirst', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/package.json b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/package.json index dfbe5e83e640..8f90e1582598 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/package.json +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/package.json @@ -19,7 +19,6 @@ "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts index 03d4679fa3c0..e29d4677397f 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/errors.test.ts @@ -24,8 +24,9 @@ test('Sends unexpected exception to Sentry if thrown in module with global filte expect(errorEvent.transaction).toEqual('GET /example-module/unexpected-exception'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); @@ -52,8 +53,9 @@ test('Sends unexpected exception to Sentry if thrown in module with local filter expect(errorEvent.transaction).toEqual('GET /example-module-local-filter/unexpected-exception'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); @@ -82,8 +84,9 @@ test('Sends unexpected exception to Sentry if thrown in module that was register expect(errorEvent.transaction).toEqual('GET /example-module-registered-first/unexpected-exception'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts index a2ea1db9c506..b95aa1fe4406 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'http.route': '/example-module/transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -59,12 +59,12 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { }, op: 'request_handler.express', description: '/example-module/transaction', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.express', }, { @@ -72,12 +72,12 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { @@ -85,17 +85,17 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.nestjs', 'sentry.op': 'handler.nestjs', @@ -105,7 +105,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'nestjs.callback': 'testTransaction', }, description: 'testTransaction', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -142,14 +142,14 @@ test('API route transaction includes exception filter span for global filter in expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleExceptionFilter', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -181,14 +181,14 @@ test('API route transaction includes exception filter span for local filter in m expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'LocalExampleExceptionFilter', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -220,14 +220,14 @@ test('API route transaction includes exception filter span for global filter in expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleExceptionFilterRegisteredFirst', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/package.json b/dev-packages/e2e-tests/test-applications/nextjs-13/package.json index 51eaf9bf9fb4..81e4b844d072 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/package.json +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/package.json @@ -35,7 +35,6 @@ "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", "@sentry/react": "latest || *", - "@sentry/types": "latest || *", "@sentry/vercel-edge": "latest || *" }, "volta": { diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/app-dir-pageloads.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/app-dir-pageloads.test.ts index d7d08eb22773..c656ade91202 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/app-dir-pageloads.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/app-dir-pageloads.test.ts @@ -30,8 +30,8 @@ test('should create a pageload transaction when the `app` directory is used', as }, op: 'pageload', origin: 'auto.pageload.nextjs.app_router_instrumentation', - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, environment: 'qa', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/fetch.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/fetch.test.ts index 5b42e14269bc..a4608b2abab5 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/fetch.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/fetch.test.ts @@ -45,11 +45,11 @@ test('should correctly instrument `fetch` for performance tracing', async ({ pag }, description: 'GET http://example.com', op: 'http.client', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), status: expect.any(String), origin: 'auto.http.browser', }), diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-navigation.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-navigation.test.ts index 8bd128896b6c..1969429f3103 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-navigation.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-navigation.test.ts @@ -37,8 +37,8 @@ test('should report a navigation transaction for pages router navigations', asyn }, op: 'navigation', origin: 'auto.navigation.nextjs.pages_router_instrumentation', - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, platform: 'javascript', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-pageload.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-pageload.test.ts index af59b41c2908..295fa762f636 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-pageload.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/client/pages-dir-pageload.test.ts @@ -30,8 +30,8 @@ test('should create a pageload transaction when the `pages` directory is used', }, op: 'pageload', origin: 'auto.pageload.nextjs.pages_router_instrumentation', - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, environment: 'qa', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts index 8ef79f8cf146..42b2e3727bd6 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/cjs-api-endpoints.test.ts @@ -44,9 +44,9 @@ test('should create a transaction for a CJS pages router API endpoint', async ({ }, op: 'http.server', origin: 'auto.http.nextjs', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, environment: 'qa', @@ -106,9 +106,9 @@ test('should not mess up require statements in CJS API endpoints', async ({ requ }, op: 'http.server', origin: 'auto.http.nextjs', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, environment: 'qa', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/getServerSideProps.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/getServerSideProps.test.ts index 9ae79d7bd4b0..60f9842ca20e 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/getServerSideProps.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/getServerSideProps.test.ts @@ -17,7 +17,7 @@ test('Should report an error event for errors thrown in getServerSideProps', asy expect(await errorEventPromise).toMatchObject({ contexts: { - trace: { span_id: expect.any(String), trace_id: expect.any(String) }, + trace: { span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: expect.stringMatching(/[a-f0-9]{32}/) }, }, event_id: expect.any(String), exception: { @@ -65,9 +65,9 @@ test('Should report an error event for errors thrown in getServerSideProps', asy }, op: 'http.server', origin: 'auto', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'internal_error', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, event_id: expect.any(String), @@ -104,7 +104,7 @@ test('Should report an error event for errors thrown in getServerSideProps in pa expect(await errorEventPromise).toMatchObject({ contexts: { - trace: { span_id: expect.any(String), trace_id: expect.any(String) }, + trace: { span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: expect.stringMatching(/[a-f0-9]{32}/) }, }, event_id: expect.any(String), exception: { @@ -152,9 +152,9 @@ test('Should report an error event for errors thrown in getServerSideProps in pa }, op: 'http.server', origin: 'auto', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'internal_error', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, event_id: expect.any(String), diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/pages-router-api-endpoints.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/pages-router-api-endpoints.test.ts index 12196c08fcc1..36592b56fb94 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/pages-router-api-endpoints.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/pages-router-api-endpoints.test.ts @@ -20,7 +20,7 @@ test('Should report an error event for errors thrown in pages router api routes' expect(await errorEventPromise).toMatchObject({ contexts: { runtime: { name: 'node', version: expect.any(String) }, - trace: { span_id: expect.any(String), trace_id: expect.any(String) }, + trace: { span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: expect.stringMatching(/[a-f0-9]{32}/) }, }, exception: { values: [ @@ -60,7 +60,7 @@ test('Should report an error event for errors thrown in pages router api routes' }, op: 'http.server', origin: 'auto.http.nextjs', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'internal_error', trace_id: (await errorEventPromise).contexts?.trace?.trace_id, }, @@ -103,9 +103,9 @@ test('Should report a transaction event for a successful pages router api route' }, op: 'http.server', origin: 'auto.http.nextjs', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, platform: 'node', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts index 0303fe6e583f..937d7c8da6c0 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/server-component-error.test.ts @@ -12,8 +12,8 @@ test('Should capture an error thrown in a server component', async ({ page }) => contexts: { runtime: { name: 'node', version: expect.any(String) }, trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, event_id: expect.any(String), diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts index 6b25cb6f74f7..3bcc1bbbea92 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/server/wrapApiHandlerWithSentry.test.ts @@ -40,9 +40,9 @@ cases.forEach(({ name, url, transactionName }) => { }, op: 'http.server', origin: 'auto.http.nextjs', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, platform: 'node', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-14/package.json b/dev-packages/e2e-tests/test-applications/nextjs-14/package.json index f4569e1f6ceb..b03722a5dccc 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-14/package.json +++ b/dev-packages/e2e-tests/test-applications/nextjs-14/package.json @@ -35,7 +35,6 @@ "@sentry/opentelemetry": "latest || *", "@sentry/react": "latest || *", "@sentry-internal/replay": "latest || *", - "@sentry/types": "latest || *", "@sentry/vercel-edge": "latest || *" }, "volta": { diff --git a/dev-packages/e2e-tests/test-applications/nextjs-14/tests/generation-functions.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-14/tests/generation-functions.test.ts index 28b9d8cab43f..346928c44ebc 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-14/tests/generation-functions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-14/tests/generation-functions.test.ts @@ -18,10 +18,10 @@ test('Should emit a span for a generateMetadata() function invocation', async ({ expect.objectContaining({ description: 'generateMetadata /generation-functions/page', origin: 'auto', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }), ); @@ -75,10 +75,10 @@ test('Should send a transaction event for a generateViewport() function invocati expect.objectContaining({ description: 'generateViewport /generation-functions/page', origin: 'auto', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }), ); }); diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/package.json b/dev-packages/e2e-tests/test-applications/nextjs-15/package.json index 6e9fb6af5b07..19638112649e 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/package.json +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/package.json @@ -36,7 +36,6 @@ "@sentry/opentelemetry": "latest || *", "@sentry/react": "latest || *", "@sentry-internal/replay": "latest || *", - "@sentry/types": "latest || *", "@sentry/vercel-edge": "latest || *" }, "volta": { diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/components/span-context.tsx b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/components/span-context.tsx index 81a6f404d0f4..1375b7e9cd4c 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/components/span-context.tsx +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/components/span-context.tsx @@ -1,7 +1,7 @@ 'use client'; +import { Span } from '@sentry/core'; import { startInactiveSpan } from '@sentry/nextjs'; -import { Span } from '@sentry/types'; import { PropsWithChildren, createContext, useState } from 'react'; export const SpanContext = createContext< diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/package.json b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/package.json index 91791b89be75..dd145692aa23 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/package.json +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/package.json @@ -37,7 +37,6 @@ "@sentry/opentelemetry": "latest || *", "@sentry/react": "latest || *", "@sentry-internal/replay": "latest || *", - "@sentry/types": "latest || *", "@sentry/vercel-edge": "latest || *", "ts-node": "10.9.1" }, diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/client-errors.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/client-errors.test.ts index d1ea09ac2c76..091c8fc1e46c 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/client-errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/client-errors.test.ts @@ -32,7 +32,7 @@ test('Sends a client-side exception to Sentry', async ({ page }) => { // Next.js >= 15 propagates a trace ID to the client via a meta tag. Also, only dev mode emits a meta tag because // the requested page is static and only in dev mode SSR is kicked off. parent_span_id: nextjsMajor >= 15 && isDevMode ? expect.any(String) : undefined, - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/middleware.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/middleware.test.ts index a00a29672ed6..14eb40f2d2dd 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/middleware.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/middleware.test.ts @@ -82,12 +82,12 @@ test('Should trace outgoing fetch requests inside middleware and create breadcru description: 'GET http://localhost:3030/', op: 'http.client', origin: 'auto.http.wintercg_fetch', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, ]), ); diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts index ff61cb3bd682..f2e73c892a9b 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts @@ -28,9 +28,9 @@ test('Sends a transaction for a request to app router', async ({ page }) => { }), op: 'http.server', origin: 'auto', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(transactionEvent.request).toEqual({ diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/transactions.test.ts index cc22b9da1a40..fa5cd062d862 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/transactions.test.ts @@ -29,8 +29,8 @@ test('Sends a pageload transaction', async ({ page }) => { // Next.js >= 15 propagates a trace ID to the client via a meta tag. Also, only dev mode emits a meta tag because // the requested page is static and only in dev mode SSR is kicked off. parent_span_id: nextjsMajor >= 15 && isDevMode ? expect.any(String) : undefined, - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), op: 'pageload', origin: 'auto.pageload.nextjs.app_router_instrumentation', data: expect.objectContaining({ diff --git a/dev-packages/e2e-tests/test-applications/nextjs-turbo/package.json b/dev-packages/e2e-tests/test-applications/nextjs-turbo/package.json index 03d8a71dbcae..4ca726c474b8 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-turbo/package.json +++ b/dev-packages/e2e-tests/test-applications/nextjs-turbo/package.json @@ -35,7 +35,6 @@ "@sentry/opentelemetry": "latest || *", "@sentry/react": "latest || *", "@sentry-internal/replay": "latest || *", - "@sentry/types": "latest || *", "@sentry/vercel-edge": "latest || *", "import-in-the-middle": "1.11.2" }, diff --git a/dev-packages/e2e-tests/test-applications/node-connect/package.json b/dev-packages/e2e-tests/test-applications/node-connect/package.json index bf2ec590b285..276e8654f8f4 100644 --- a/dev-packages/e2e-tests/test-applications/node-connect/package.json +++ b/dev-packages/e2e-tests/test-applications/node-connect/package.json @@ -12,7 +12,6 @@ }, "dependencies": { "@sentry/node": "latest || *", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sentry/opentelemetry": "latest || *", "@types/node": "18.15.1", diff --git a/dev-packages/e2e-tests/test-applications/node-connect/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-connect/tests/errors.test.ts index e0b39ed16bc5..2aa569915eb4 100644 --- a/dev-packages/e2e-tests/test-applications/node-connect/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-connect/tests/errors.test.ts @@ -23,7 +23,7 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-connect/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-connect/tests/transactions.test.ts index f0da250d8be9..ec02acca77d6 100644 --- a/dev-packages/e2e-tests/test-applications/node-connect/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-connect/tests/transactions.test.ts @@ -41,9 +41,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -55,12 +55,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { @@ -73,12 +73,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, op: 'request_handler.connect', description: '/test-transaction', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.connect', }, ], diff --git a/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json b/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json index 574371f84c15..5be4d29bbb38 100644 --- a/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json +++ b/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json @@ -20,7 +20,6 @@ "@sentry/aws-serverless": "latest || *", "@sentry/google-cloud-serverless": "latest || *", "@sentry/bun": "latest || *", - "@sentry/types": "latest || *", "@types/node": "18.15.1", "typescript": "4.9.5" }, diff --git a/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts index 5316cc377358..75e718016a90 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts @@ -72,12 +72,12 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'middleware.express', description: 'query', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -91,12 +91,12 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'middleware.express', description: 'expressInit', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -110,11 +110,11 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'request_handler.express', description: '/test-transaction/:param', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts index 06e2c2e09434..a1b596072a6a 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts @@ -72,12 +72,12 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'middleware.express', description: 'query', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -91,12 +91,12 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'middleware.express', description: 'expressInit', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -110,11 +110,11 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'request_handler.express', description: '/test-transaction/:param', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts index 9d6b10a3dd74..2f3208a33bbb 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts @@ -72,12 +72,12 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'middleware.express', description: 'query', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -91,12 +91,12 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'middleware.express', description: 'expressInit', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -110,12 +110,12 @@ test('Should record a transaction for route with parameters', async ({ request } op: 'request_handler.express', description: '/test-transaction/:param', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -133,8 +133,8 @@ test.skip('Should record spans from http instrumentation', async ({ request }) = const httpClientSpan = transactionEvent.spans?.find(span => span.op === 'http.client'); expect(httpClientSpan).toEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'http.flavor': '1.1', 'http.host': 'example.com:80', @@ -155,7 +155,7 @@ test.skip('Should record spans from http instrumentation', async ({ request }) = url: 'http://example.com/', }, description: 'GET http://example.com/', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', diff --git a/dev-packages/e2e-tests/test-applications/node-express-incorrect-instrumentation/package.json b/dev-packages/e2e-tests/test-applications/node-express-incorrect-instrumentation/package.json index a8b325bc075d..391514a2c1dd 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-incorrect-instrumentation/package.json +++ b/dev-packages/e2e-tests/test-applications/node-express-incorrect-instrumentation/package.json @@ -13,7 +13,6 @@ "dependencies": { "@sentry/core": "latest || *", "@sentry/node": "latest || *", - "@sentry/types": "latest || *", "@trpc/server": "10.45.2", "@trpc/client": "10.45.2", "@types/express": "4.17.17", diff --git a/dev-packages/e2e-tests/test-applications/node-express-send-to-sentry/package.json b/dev-packages/e2e-tests/test-applications/node-express-send-to-sentry/package.json index 5a1b9b7d8300..49e98e2c49ad 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-send-to-sentry/package.json +++ b/dev-packages/e2e-tests/test-applications/node-express-send-to-sentry/package.json @@ -13,7 +13,6 @@ "dependencies": { "@sentry/core": "latest || *", "@sentry/node": "latest || *", - "@sentry/types": "latest || *", "@types/express": "4.17.17", "@types/node": "18.15.1", "express": "4.19.2", diff --git a/dev-packages/e2e-tests/test-applications/node-express/package.json b/dev-packages/e2e-tests/test-applications/node-express/package.json index 97947e70d06e..bc0b9b4dead7 100644 --- a/dev-packages/e2e-tests/test-applications/node-express/package.json +++ b/dev-packages/e2e-tests/test-applications/node-express/package.json @@ -13,7 +13,6 @@ "dependencies": { "@sentry/core": "latest || *", "@sentry/node": "latest || *", - "@sentry/types": "latest || *", "@trpc/server": "10.45.2", "@trpc/client": "10.45.2", "@types/express": "4.17.17", diff --git a/dev-packages/e2e-tests/test-applications/node-express/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-express/tests/errors.test.ts index 0a61c8665e30..bf0c5c5fb6b2 100644 --- a/dev-packages/e2e-tests/test-applications/node-express/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express/tests/errors.test.ts @@ -23,8 +23,8 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts index fede408d258e..3b51ae415b03 100644 --- a/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -69,12 +69,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { description: 'query', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -88,12 +88,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { description: 'expressInit', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -107,12 +107,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { description: '/test-transaction', op: 'request_handler.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -147,12 +147,12 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) description: 'query', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -166,12 +166,12 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) description: 'expressInit', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -185,11 +185,11 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) description: '/test-exception/:id', op: 'request_handler.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/package.json b/dev-packages/e2e-tests/test-applications/node-fastify-5/package.json index c60d9a3dae51..e0a000572a25 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/package.json +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/package.json @@ -12,7 +12,6 @@ }, "dependencies": { "@sentry/node": "latest || *", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sentry/opentelemetry": "latest || *", "@types/node": "22.7.5", diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/errors.test.ts index 67b27a6c0e5e..f79eb30e9b4c 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/errors.test.ts @@ -23,7 +23,8 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts index 050ce19c6a3c..7e059b99354b 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts @@ -1,7 +1,7 @@ import crypto from 'crypto'; import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -import { SpanJSON } from '@sentry/types'; +import { SpanJSON } from '@sentry/core'; test('Propagates trace for outgoing http requests', async ({ baseURL }) => { const id = crypto.randomUUID(); @@ -78,7 +78,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-http/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -111,7 +111,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { }, op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -193,7 +193,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-fetch/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -226,7 +226,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { }), op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts index 6ca2d19f3b32..d226009dcc1f 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -68,12 +68,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, description: 'sentry-fastify-error-handler', op: 'middleware.fastify', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.fastify', }); @@ -87,12 +87,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, description: 'sentry-fastify-error-handler', op: 'request_handler.fastify', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.fastify', }); @@ -101,12 +101,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }); @@ -115,12 +115,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-fastify/package.json b/dev-packages/e2e-tests/test-applications/node-fastify/package.json index 0478786cd499..b657eddd1de1 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify/package.json +++ b/dev-packages/e2e-tests/test-applications/node-fastify/package.json @@ -12,7 +12,6 @@ }, "dependencies": { "@sentry/node": "latest || *", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sentry/opentelemetry": "latest || *", "@types/node": "18.15.1", diff --git a/dev-packages/e2e-tests/test-applications/node-fastify/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify/tests/errors.test.ts index 3ef2bba479db..1b63fe0e0c55 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify/tests/errors.test.ts @@ -23,7 +23,8 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-fastify/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify/tests/propagation.test.ts index d2e9a188da9f..7e4aeee0f220 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify/tests/propagation.test.ts @@ -1,7 +1,7 @@ import crypto from 'crypto'; import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -import { SpanJSON } from '@sentry/types'; +import { SpanJSON } from '@sentry/core'; test('Propagates trace for outgoing http requests', async ({ baseURL }) => { const id = crypto.randomUUID(); @@ -78,7 +78,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-http/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -111,7 +111,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { }, op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -193,7 +193,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-fetch/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -226,7 +226,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { }), op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify/tests/transactions.test.ts index c9cb53afb94c..01e07538dc72 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -68,12 +68,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, description: 'sentry-fastify-error-handler', op: 'middleware.fastify', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.fastify', }); @@ -87,12 +87,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, description: 'sentry-fastify-error-handler', op: 'request_handler.fastify', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.fastify', }); @@ -101,12 +101,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }); @@ -115,12 +115,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-hapi/package.json b/dev-packages/e2e-tests/test-applications/node-hapi/package.json index 47db96a4a666..2eda8acc7589 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi/package.json +++ b/dev-packages/e2e-tests/test-applications/node-hapi/package.json @@ -13,8 +13,7 @@ "dependencies": { "@hapi/boom": "10.0.1", "@hapi/hapi": "21.3.10", - "@sentry/node": "latest || *", - "@sentry/types": "latest || *" + "@sentry/node": "latest || *" }, "devDependencies": { "@playwright/test": "^1.44.1", diff --git a/dev-packages/e2e-tests/test-applications/node-hapi/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-hapi/tests/errors.test.ts index f28250f26f3c..6531b83baa8e 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-hapi/tests/errors.test.ts @@ -17,8 +17,8 @@ test('Sends thrown error to Sentry', async ({ baseURL }) => { expect(transactionEvent.transaction).toBe('GET /test-failure'); expect(transactionEvent.contexts?.trace).toMatchObject({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); expect(errorEvent.exception?.values).toHaveLength(1); @@ -34,8 +34,8 @@ test('Sends thrown error to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-failure'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); expect(errorEvent.contexts?.trace?.trace_id).toBe(transactionEvent.contexts?.trace?.trace_id); diff --git a/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts index c3237de74a5a..3f332992d0e7 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts @@ -39,9 +39,9 @@ test('Sends successful transaction', async ({ baseURL }) => { 'http.route': '/test-success', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -69,12 +69,12 @@ test('Sends successful transaction', async ({ baseURL }) => { description: 'GET /test-success', op: 'router.hapi', origin: 'auto.http.otel.hapi', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, { // this comes from "onPreResponse" @@ -87,12 +87,12 @@ test('Sends successful transaction', async ({ baseURL }) => { description: 'ext - onPreResponse', op: 'server.ext.hapi', origin: 'auto.http.otel.hapi', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, ]); }); diff --git a/dev-packages/e2e-tests/test-applications/node-koa/package.json b/dev-packages/e2e-tests/test-applications/node-koa/package.json index dd8a17d0f4b5..0f6ed61216db 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/package.json +++ b/dev-packages/e2e-tests/test-applications/node-koa/package.json @@ -13,7 +13,6 @@ "@koa/bodyparser": "^5.1.1", "@koa/router": "^12.0.1", "@sentry/node": "latest || *", - "@sentry/types": "latest || *", "@types/node": "18.15.1", "koa": "^2.15.2", "typescript": "4.9.5" diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/assert.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/assert.test.ts index 0f9f724ef237..e274f451b959 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/assert.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/assert.test.ts @@ -24,8 +24,9 @@ test('Returns 400 from failed assert', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-assert/:condition'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/errors.test.ts index 1fbb1fd42613..cadf29fbda90 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/errors.test.ts @@ -23,7 +23,8 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts index 1f5413af0cbe..0ff946d07d3d 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts @@ -1,7 +1,7 @@ import crypto from 'crypto'; import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -import { SpanJSON } from '@sentry/types'; +import { SpanJSON } from '@sentry/core'; test('Propagates trace for outgoing http requests', async ({ baseURL }) => { const id = crypto.randomUUID(); @@ -78,7 +78,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-http/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -111,7 +111,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { }, op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -193,7 +193,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-fetch/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -226,7 +226,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { }), op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts index 1197575d1a96..966dbc5937e3 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -65,12 +65,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { description: 'bodyParser', op: 'middleware.koa', origin: 'auto.http.otel.koa', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, { data: { @@ -82,12 +82,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { op: 'middleware.koa', origin: 'auto.http.otel.koa', description: '< unknown >', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, { data: { @@ -99,12 +99,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, op: 'router.koa', description: '/test-transaction', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.koa', }, { @@ -112,12 +112,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { @@ -125,12 +125,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, ]); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/package.json b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/package.json index b7334026d18f..ed286d4c6886 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/package.json +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/package.json @@ -21,7 +21,6 @@ "@nestjs/schedule": "^4.1.0", "@nestjs/platform-express": "^10.0.0", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/app.service.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/app.service.ts index 3e4639040a7e..3241e05768ec 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/app.service.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/src/app.service.ts @@ -1,9 +1,9 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { RpcException } from '@nestjs/microservices'; import { Cron, SchedulerRegistry } from '@nestjs/schedule'; +import type { MonitorConfig } from '@sentry/core'; import * as Sentry from '@sentry/nestjs'; import { SentryCron, SentryTraced } from '@sentry/nestjs'; -import type { MonitorConfig } from '@sentry/types'; const monitorConfig: MonitorConfig = { schedule: { diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts index 1475a1449f44..dc4c98aebf40 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/cron-decorator.test.ts @@ -27,8 +27,8 @@ test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { }, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, }), @@ -43,8 +43,8 @@ test('Cron job triggers send of in_progress envelope', async ({ baseURL }) => { duration: expect.any(Number), contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, }), diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts index 0155c3887805..491a64e7166c 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/errors.test.ts @@ -24,8 +24,8 @@ test('Sends exception to Sentry', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts index 831dfd4400dc..fa155b6dd674 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/span-decorator.test.ts @@ -19,14 +19,14 @@ test('Transaction includes span and correct value for decorated async function', expect(transactionEvent.spans).toEqual( expect.arrayContaining([ expect.objectContaining({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'manual', 'sentry.op': 'wait and return a string', }, description: 'wait', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', op: 'wait and return a string', @@ -54,14 +54,14 @@ test('Transaction includes span and correct value for decorated sync function', expect(transactionEvent.spans).toEqual( expect.arrayContaining([ expect.objectContaining({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'manual', 'sentry.op': 'return a string', }, description: 'getString', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', op: 'return a string', diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts index 23855d1f55b8..0245b7fdb7b3 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-basic/tests/transactions.test.ts @@ -40,9 +40,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -59,12 +59,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, op: 'request_handler.express', description: '/test-transaction', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.express', }, { @@ -72,12 +72,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { @@ -85,17 +85,17 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.origin': 'manual', }, description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.nestjs', 'sentry.op': 'handler.nestjs', @@ -105,7 +105,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'nestjs.callback': 'testTransaction', }, description: 'testTransaction', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -141,14 +141,14 @@ test('API route transaction includes nest middleware span. Spans created in and expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleMiddleware', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -166,22 +166,22 @@ test('API route transaction includes nest middleware span. Spans created in and expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-middleware-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -221,14 +221,14 @@ test('API route transaction includes nest guard span and span started in guard i expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleGuard', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -246,11 +246,11 @@ test('API route transaction includes nest guard span and span started in guard i expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-guard-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -284,14 +284,14 @@ test('API route transaction includes nest pipe span for valid request', async ({ expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ParseIntPipe', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -320,14 +320,14 @@ test('API route transaction includes nest pipe span for invalid request', async expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ParseIntPipe', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'unknown_error', @@ -359,14 +359,14 @@ test('API route transaction includes nest interceptor spans before route executi expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleInterceptor1', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -374,14 +374,14 @@ test('API route transaction includes nest interceptor spans before route executi origin: 'auto.middleware.nestjs', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'ExampleInterceptor2', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -403,33 +403,33 @@ test('API route transaction includes nest interceptor spans before route executi expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-1', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-2', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -477,14 +477,14 @@ test('API route transaction includes exactly one nest interceptor span after rou expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'Interceptors - After Route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -512,11 +512,11 @@ test('API route transaction includes exactly one nest interceptor span after rou expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-interceptor-span-after-route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -559,14 +559,14 @@ test('API route transaction includes nest async interceptor spans before route e expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'AsyncInterceptor', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -586,22 +586,22 @@ test('API route transaction includes nest async interceptor spans before route e expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-controller-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', origin: 'manual', }, { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-async-interceptor-span', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -644,14 +644,14 @@ test('API route transaction includes exactly one nest async interceptor span aft expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.op': 'middleware.nestjs', 'sentry.origin': 'auto.middleware.nestjs', }, description: 'Interceptors - After Route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -679,11 +679,11 @@ test('API route transaction includes exactly one nest async interceptor span aft expect.objectContaining({ spans: expect.arrayContaining([ { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: expect.any(Object), description: 'test-async-interceptor-span-after-route', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/package.json b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/package.json index ad61f9a77ad4..f6fbc916ad68 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/package.json +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/package.json @@ -19,7 +19,6 @@ "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@sentry/nestjs": "latest || *", - "@sentry/types": "latest || *", "reflect-metadata": "^0.2.0", "rxjs": "^7.8.1" }, diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts index 49b827ca7e27..d252cdad5fa3 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs-distributed-tracing/tests/propagation.test.ts @@ -1,7 +1,7 @@ import crypto from 'crypto'; import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -import { SpanJSON } from '@sentry/types'; +import { SpanJSON } from '@sentry/core'; test('Propagates trace for outgoing http requests', async ({ baseURL }) => { const id = crypto.randomUUID(); @@ -78,7 +78,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-http/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -111,7 +111,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { }, op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -193,7 +193,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'http.route': '/test-outgoing-fetch/:id', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', @@ -226,7 +226,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { }), op: 'http.server', parent_span_id: outgoingHttpSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', trace_id: traceId, origin: 'auto.http.otel.http', diff --git a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json index 3507981ff013..30cd21643eb8 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/package.json @@ -15,7 +15,6 @@ "@opentelemetry/sdk-trace-node": "^1.25.1", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", - "@sentry/types": "latest || *", "@types/express": "4.17.17", "@types/node": "18.15.1", "express": "4.19.2", diff --git a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/errors.test.ts index 18d14cd12080..4627c86bf03f 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/errors.test.ts @@ -23,7 +23,7 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts index cb374ec8d440..c3e40d06d6b0 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts @@ -11,8 +11,8 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { const transactionEvent = await transactionEventPromise; expect(transactionEvent.contexts?.trace).toEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.source': 'route', 'sentry.op': 'http.server', @@ -45,8 +45,8 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { expect(transactionEvent.spans?.length).toBe(4); expect(transactionEvent.spans).toContainEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.express', 'sentry.op': 'middleware.express', @@ -55,7 +55,7 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { 'express.type': 'middleware', }, description: 'query', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -64,8 +64,8 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { }); expect(transactionEvent.spans).toContainEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.express', 'sentry.op': 'middleware.express', @@ -74,7 +74,7 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { 'express.type': 'middleware', }, description: 'expressInit', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -83,8 +83,8 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { }); expect(transactionEvent.spans).toContainEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'auto.http.otel.express', 'sentry.op': 'request_handler.express', @@ -93,7 +93,7 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { 'express.type': 'request_handler', }, description: '/task', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', @@ -102,14 +102,14 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { }); expect(transactionEvent.spans).toContainEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { 'sentry.origin': 'manual', 'sentry.op': 'custom.op', }, description: 'Long task', - parent_span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', diff --git a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json index b02788c4761f..fd2b9bf4aafe 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/package.json @@ -16,7 +16,6 @@ "@sentry/core": "latest || *", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", - "@sentry/types": "latest || *", "@types/express": "4.17.17", "@types/node": "18.15.1", "express": "4.19.2", diff --git a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/errors.test.ts index 7dbb66a4119d..bb3c8c70b629 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/errors.test.ts @@ -23,7 +23,7 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/:id'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts index ebf500ffb09c..0f978f72cf57 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts @@ -52,9 +52,9 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', }, op: 'http.server', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.otel.http', }); @@ -81,12 +81,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { description: 'query', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -100,12 +100,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { description: 'expressInit', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -119,12 +119,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { description: '/test-transaction', op: 'request_handler.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -159,12 +159,12 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) description: 'query', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -178,12 +178,12 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) description: 'expressInit', op: 'middleware.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spans).toContainEqual({ @@ -197,11 +197,11 @@ test('Sends an API route transaction for an errored route', async ({ baseURL }) description: '/test-exception/:id', op: 'request_handler.express', origin: 'auto.http.otel.express', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json index ed01eff7dce2..efe84d86604e 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json +++ b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/package.json @@ -19,7 +19,6 @@ "@sentry/core": "latest || *", "@sentry/node": "latest || *", "@sentry/opentelemetry": "latest || *", - "@sentry/types": "latest || *", "@types/express": "4.17.17", "@types/node": "18.15.1", "express": "4.19.2", diff --git a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/errors.test.ts index 36231f87a464..5e44ed93fa6c 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/errors.test.ts @@ -24,8 +24,8 @@ test('Sends correct error event', async ({ baseURL }) => { expect(errorEvent.transaction).toEqual('GET /test-exception/123'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/transactions.test.ts index bb069b7e3e11..678841bdb249 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-without-tracing/tests/transactions.test.ts @@ -34,17 +34,55 @@ test('Sends an API route transaction to OTLP', async ({ baseURL }) => { const scopeSpans = json.resourceSpans?.[0]?.scopeSpans; expect(scopeSpans).toBeDefined(); - // Http server span & undici client spans are emitted + // Http server span & undici client spans are emitted, + // as well as the spans emitted via `Sentry.startSpan()` // But our default node-fetch spans are not emitted - expect(scopeSpans.length).toEqual(2); + expect(scopeSpans.length).toEqual(3); const httpScopes = scopeSpans?.filter(scopeSpan => scopeSpan.scope.name === '@opentelemetry/instrumentation-http'); const undiciScopes = scopeSpans?.filter( scopeSpan => scopeSpan.scope.name === '@opentelemetry/instrumentation-undici', ); + const startSpanScopes = scopeSpans?.filter(scopeSpan => scopeSpan.scope.name === '@sentry/node'); expect(httpScopes.length).toBe(1); + expect(startSpanScopes.length).toBe(1); + expect(startSpanScopes[0].spans.length).toBe(2); + expect(startSpanScopes[0].spans).toEqual([ + { + traceId: expect.any(String), + spanId: expect.any(String), + parentSpanId: expect.any(String), + name: 'test-span', + kind: 1, + startTimeUnixNano: expect.any(String), + endTimeUnixNano: expect.any(String), + attributes: [], + droppedAttributesCount: 0, + events: [], + droppedEventsCount: 0, + status: { code: 0 }, + links: [], + droppedLinksCount: 0, + }, + { + traceId: expect.any(String), + spanId: expect.any(String), + name: 'test-transaction', + kind: 1, + startTimeUnixNano: expect.any(String), + endTimeUnixNano: expect.any(String), + attributes: [{ key: 'sentry.op', value: { stringValue: 'e2e-test' } }], + droppedAttributesCount: 0, + events: [], + droppedEventsCount: 0, + status: { code: 0 }, + links: [], + droppedLinksCount: 0, + }, + ]); + // Undici spans are emitted correctly expect(undiciScopes.length).toBe(1); expect(undiciScopes[0].spans.length).toBe(1); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-min/package.json b/dev-packages/e2e-tests/test-applications/nuxt-3-min/package.json index 18f798f89246..34180346b252 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-min/package.json +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-min/package.json @@ -1,6 +1,6 @@ { "name": "nuxt-3-min", - "description": "E2E test app for the minimum nuxt 3 version our nuxt SDK supports.", + "description": "E2E test app for the minimum Nuxt 3 version our Nuxt SDK supports.", "private": true, "type": "module", "scripts": { @@ -16,7 +16,7 @@ }, "dependencies": { "@sentry/nuxt": "latest || *", - "nuxt": "3.13.2" + "nuxt": "3.7.0" }, "devDependencies": { "@nuxt/test-utils": "^3.14.1", @@ -24,7 +24,7 @@ "@sentry-internal/test-utils": "link:../../../test-utils" }, "overrides": { - "nitropack": "2.9.7", - "@vercel/nft": "^0.27.4" + "nitropack": "2.10.0", + "ofetch": "1.4.0" } } diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-min/sentry.client.config.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-min/sentry.client.config.ts index 7547bafa6618..9a9566051452 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-min/sentry.client.config.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-min/sentry.client.config.ts @@ -6,5 +6,11 @@ Sentry.init({ dsn: useRuntimeConfig().public.sentry.dsn, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1.0, - trackComponents: true, + integrations: [ + Sentry.vueIntegration({ + tracingOptions: { + trackComponents: true, + }, + }), + ], }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.client.test.ts index 9d0b3c694a1c..b726636974c9 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3-min/tests/tracing.client.test.ts @@ -45,11 +45,11 @@ test('sends component tracking spans when `trackComponents` is enabled', async ( data: { 'sentry.origin': 'auto.ui.vue', 'sentry.op': 'ui.vue.mount' }, description: 'Vue ', op: 'ui.vue.mount', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.ui.vue', }; diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/package.json b/dev-packages/e2e-tests/test-applications/nuxt-3/package.json index 0b9654108d48..8cc66d2d408e 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3/package.json +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/package.json @@ -15,14 +15,11 @@ }, "dependencies": { "@sentry/nuxt": "latest || *", - "nuxt": "^3.13.1" + "nuxt": "^3.14.0" }, "devDependencies": { "@nuxt/test-utils": "^3.14.1", "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils" - }, - "overrides": { - "@vercel/nft": "0.27.4" } } diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/sentry.client.config.ts b/dev-packages/e2e-tests/test-applications/nuxt-3/sentry.client.config.ts index 7547bafa6618..9a9566051452 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3/sentry.client.config.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/sentry.client.config.ts @@ -6,5 +6,11 @@ Sentry.init({ dsn: useRuntimeConfig().public.sentry.dsn, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1.0, - trackComponents: true, + integrations: [ + Sentry.vueIntegration({ + tracingOptions: { + trackComponents: true, + }, + }), + ], }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.client.test.ts index 76b2a9094531..f779bbcee69f 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-3/tests/tracing.client.test.ts @@ -45,11 +45,11 @@ test('sends component tracking spans when `trackComponents` is enabled', async ( data: { 'sentry.origin': 'auto.ui.vue', 'sentry.op': 'ui.vue.mount' }, description: 'Vue ', op: 'ui.vue.mount', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.ui.vue', }; diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts index dd2183162db9..e8b628595975 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/sentry.client.config.ts @@ -6,7 +6,6 @@ Sentry.init({ dsn: useRuntimeConfig().public.sentry.dsn, tunnel: `http://localhost:3031/`, // proxy server tracesSampleRate: 1.0, - trackComponents: true, integrations: [ Sentry.piniaIntegration(usePinia(), { actionTransformer: action => `Transformed: ${action}`, @@ -15,5 +14,10 @@ Sentry.init({ ...state, }), }), + Sentry.vueIntegration({ + tracingOptions: { + trackComponents: true, + }, + }), ], }); diff --git a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.client.test.ts b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.client.test.ts index 9119e279e491..d1f2b4fdea47 100644 --- a/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.client.test.ts +++ b/dev-packages/e2e-tests/test-applications/nuxt-4/tests/tracing.client.test.ts @@ -45,11 +45,11 @@ test('sends component tracking spans when `trackComponents` is enabled', async ( data: { 'sentry.origin': 'auto.ui.vue', 'sentry.op': 'ui.vue.mount' }, description: 'Vue ', op: 'ui.vue.mount', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.ui.vue', }; diff --git a/dev-packages/e2e-tests/test-applications/react-17/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/react-17/tests/errors.test.ts index 444e30fc0067..7088cd12e3bf 100644 --- a/dev-packages/e2e-tests/test-applications/react-17/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-17/tests/errors.test.ts @@ -24,8 +24,8 @@ test('Sends correct error event', async ({ page }) => { expect(errorEvent.transaction).toEqual('/'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts index 3b9c5ab1fdaf..58e3df1ee8d6 100644 --- a/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-17/tests/transactions.test.ts @@ -86,11 +86,11 @@ test('sends an INP span', async ({ page }) => { }, description: 'body > div#root > input#exception-button[type="button"]', op: 'ui.interaction.click', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.browser.inp', exclusive_time: expect.any(Number), measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } }, diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/errors.test.ts index 1602f10c3e3e..9a5675b8698a 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/errors.test.ts @@ -24,7 +24,7 @@ test('Captures exception correctly', async ({ page }) => { expect(errorEvent.transaction).toEqual('/'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts index 7fd15646dff2..7abb269d15b0 100644 --- a/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-create-hash-router/tests/transactions.test.ts @@ -28,8 +28,8 @@ test('Captures a pageload transaction', async ({ page }) => { 'lcp.loadTime': expect.any(Number), }, op: 'pageload', - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.pageload.react.reactrouter_v6', }); @@ -50,11 +50,11 @@ test('Captures a pageload transaction', async ({ page }) => { }, description: page.url(), op: 'browser.domContentLoadedEvent', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.ui.browser.metrics', }); expect(transactionEvent.spans).toContainEqual({ @@ -64,11 +64,11 @@ test('Captures a pageload transaction', async ({ page }) => { }, description: page.url(), op: 'browser.connect', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.ui.browser.metrics', }); expect(transactionEvent.spans).toContainEqual({ @@ -78,11 +78,11 @@ test('Captures a pageload transaction', async ({ page }) => { }, description: page.url(), op: 'browser.request', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.ui.browser.metrics', }); expect(transactionEvent.spans).toContainEqual({ @@ -92,11 +92,11 @@ test('Captures a pageload transaction', async ({ page }) => { }, description: page.url(), op: 'browser.response', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.ui.browser.metrics', }); }); @@ -123,8 +123,8 @@ test('Captures a navigation transaction', async ({ page }) => { 'sentry.source': 'route', }), op: 'navigation', - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.navigation.react.reactrouter_v6', }); diff --git a/dev-packages/e2e-tests/test-applications/react-router-5/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/react-router-5/tests/errors.test.ts index 11ba3f8df5d5..96b4a042c08b 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-5/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-5/tests/errors.test.ts @@ -24,8 +24,8 @@ test('Sends correct error event', async ({ page }) => { expect(errorEvent.transaction).toEqual('/'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/react-router-6-use-routes/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/react-router-6-use-routes/tests/errors.test.ts index 10fea8625a51..272025d95877 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-6-use-routes/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-6-use-routes/tests/errors.test.ts @@ -24,8 +24,8 @@ test('Sends correct error event', async ({ page }) => { expect(errorEvent.transaction).toEqual('/'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/react-router-6/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/react-router-6/tests/errors.test.ts index 8ffbfcae282a..e34699420ccf 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-6/tests/errors.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-6/tests/errors.test.ts @@ -24,8 +24,8 @@ test('Sends correct error event', async ({ page }) => { expect(errorEvent.transaction).toEqual('/'); expect(errorEvent.contexts?.trace).toEqual({ - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }); }); diff --git a/dev-packages/e2e-tests/test-applications/react-router-6/tests/sse.test.ts b/dev-packages/e2e-tests/test-applications/react-router-6/tests/sse.test.ts index b34fc8123899..b6146838b0de 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-6/tests/sse.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-6/tests/sse.test.ts @@ -1,6 +1,6 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; -import { SpanJSON } from '@sentry/types'; +import { SpanJSON } from '@sentry/core'; test('Waits for sse streaming when creating spans', async ({ page }) => { await page.goto('/sse'); diff --git a/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts index 3f108931b00e..555e0655c52e 100644 --- a/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/react-router-6/tests/transactions.test.ts @@ -86,11 +86,11 @@ test('sends an INP span', async ({ page }) => { }, description: 'body > div#root > input#exception-button[type="button"]', op: 'ui.interaction.click', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.http.browser.inp', exclusive_time: expect.any(Number), measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } }, diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/.gitignore b/dev-packages/e2e-tests/test-applications/react-router-7-spa/.gitignore new file mode 100644 index 000000000000..84634c973eeb --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/.gitignore @@ -0,0 +1,29 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +/test-results/ +/playwright-report/ +/playwright/.cache/ + +!*.d.ts diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/.npmrc b/dev-packages/e2e-tests/test-applications/react-router-7-spa/.npmrc new file mode 100644 index 000000000000..070f80f05092 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/.npmrc @@ -0,0 +1,2 @@ +@sentry:registry=http://127.0.0.1:4873 +@sentry-internal:registry=http://127.0.0.1:4873 diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/index.html b/dev-packages/e2e-tests/test-applications/react-router-7-spa/index.html new file mode 100644 index 000000000000..e4b78eae1230 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/package.json b/dev-packages/e2e-tests/test-applications/react-router-7-spa/package.json new file mode 100644 index 000000000000..e9009b1c2aa3 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/package.json @@ -0,0 +1,60 @@ +{ + "name": "react-router-7-spa", + "version": "0.1.0", + "private": true, + "dependencies": { + "@sentry/react": "latest || *", + "@types/react": "18.3.1", + "@types/react-dom": "18.3.1", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-router": "^7.0.1" + }, + "devDependencies": { + "@playwright/test": "^1.44.1", + "@sentry-internal/test-utils": "link:../../../test-utils", + "vite": "^6.0.1", + "@vitejs/plugin-react": "^4.3.4", + "typescript": "4.9.5" + }, + "scripts": { + "build": "vite build", + "dev": "vite", + "preview": "vite preview", + "test": "playwright test", + "clean": "npx rimraf node_modules pnpm-lock.yaml", + "test:build": "pnpm install && npx playwright install && pnpm build", + "test:build-ts3.8": "pnpm install && pnpm add typescript@3.8 && npx playwright install && pnpm build", + "test:build-canary": "pnpm install && pnpm add react@canary react-dom@canary && npx playwright install && pnpm build", + "test:assert": "pnpm test" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "volta": { + "extends": "../../package.json" + }, + "sentryTest": { + "variants": [ + { + "build-command": "test:build-ts3.8", + "label": "react-router-7-spa (TS 3.8)" + } + ] + } +} diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/playwright.config.mjs b/dev-packages/e2e-tests/test-applications/react-router-7-spa/playwright.config.mjs new file mode 100644 index 000000000000..7fda76df18ae --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/playwright.config.mjs @@ -0,0 +1,8 @@ +import { getPlaywrightConfig } from '@sentry-internal/test-utils'; + +const config = getPlaywrightConfig({ + startCommand: `pnpm preview --port 3030`, + port: 3030, +}); + +export default config; diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/globals.d.ts b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/globals.d.ts new file mode 100644 index 000000000000..ffa61ca49acc --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/globals.d.ts @@ -0,0 +1,5 @@ +interface Window { + recordedTransactions?: string[]; + capturedExceptionId?: string; + sentryReplayId?: string; +} diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/main.tsx b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/main.tsx new file mode 100644 index 000000000000..a49c2c35de9d --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/main.tsx @@ -0,0 +1,55 @@ +import * as Sentry from '@sentry/react'; +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { + BrowserRouter, + Route, + Routes, + createRoutesFromChildren, + matchRoutes, + useLocation, + useNavigationType, +} from 'react-router'; +import Index from './pages/Index'; +import SSE from './pages/SSE'; +import User from './pages/User'; + +const replay = Sentry.replayIntegration(); + +Sentry.init({ + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: import.meta.env.PUBLIC_E2E_TEST_DSN, + integrations: [ + Sentry.reactRouterV7BrowserTracingIntegration({ + useEffect: React.useEffect, + useLocation, + useNavigationType, + createRoutesFromChildren, + matchRoutes, + trackFetchStreamPerformance: true, + }), + replay, + ], + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 1.0, + release: 'e2e-test', + + // Always capture replays, so we can test this properly + replaysSessionSampleRate: 1.0, + replaysOnErrorSampleRate: 0.0, + tunnel: 'http://localhost:3031', +}); + +const SentryRoutes = Sentry.withSentryReactRouterV7Routing(Routes); + +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); +root.render( + + + } /> + } /> + } /> + + , +); diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/Index.tsx b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/Index.tsx new file mode 100644 index 000000000000..3f660ed4f4f7 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/Index.tsx @@ -0,0 +1,23 @@ +// biome-ignore lint/nursery/noUnusedImports: Need React import for JSX +import * as React from 'react'; +import { Link } from 'react-router'; + +const Index = () => { + return ( + <> + { + throw new Error('I am an error!'); + }} + /> + + navigate + + + ); +}; + +export default Index; diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/SSE.tsx b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/SSE.tsx new file mode 100644 index 000000000000..64a9f5717114 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/SSE.tsx @@ -0,0 +1,59 @@ +import * as Sentry from '@sentry/react'; +// biome-ignore lint/nursery/noUnusedImports: Need React import for JSX +import * as React from 'react'; + +const fetchSSE = async ({ timeout, abort = false }: { timeout: boolean; abort?: boolean }) => { + Sentry.startSpanManual({ name: 'sse stream using fetch' }, async span => { + const controller = new AbortController(); + + const res = await Sentry.startSpan({ name: 'sse fetch call' }, async () => { + const endpoint = `http://localhost:8080/${timeout ? 'sse-timeout' : 'sse'}`; + + const signal = controller.signal; + return await fetch(endpoint, { signal }); + }); + + const stream = res.body; + const reader = stream?.getReader(); + + const readChunk = async () => { + if (abort) { + controller.abort(); + } + const readRes = await reader?.read(); + if (readRes?.done) { + return; + } + + new TextDecoder().decode(readRes?.value); + + await readChunk(); + }; + + try { + await readChunk(); + } catch (error) { + console.error('Could not fetch sse', error); + } + + span.end(); + }); +}; + +const SSE = () => { + return ( + <> + + + + + ); +}; + +export default SSE; diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/User.tsx b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/User.tsx new file mode 100644 index 000000000000..62f0c2d17533 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/src/pages/User.tsx @@ -0,0 +1,8 @@ +// biome-ignore lint/nursery/noUnusedImports: Need React import for JSX +import * as React from 'react'; + +const User = () => { + return

I am a blank page :)

; +}; + +export default User; diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/react-router-7-spa/start-event-proxy.mjs new file mode 100644 index 000000000000..cd75ae3ae830 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/start-event-proxy.mjs @@ -0,0 +1,6 @@ +import { startEventProxyServer } from '@sentry-internal/test-utils'; + +startEventProxyServer({ + port: 3031, + proxyServerName: 'react-router-7-spa', +}); diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/react-router-7-spa/tests/errors.test.ts new file mode 100644 index 000000000000..e31d3c4066d4 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/tests/errors.test.ts @@ -0,0 +1,59 @@ +import { expect, test } from '@playwright/test'; +import { waitForError, waitForTransaction } from '@sentry-internal/test-utils'; + +test('Sends correct error event', async ({ page, baseURL }) => { + const errorEventPromise = waitForError('react-router-7-spa', event => { + return !event.type && event.exception?.values?.[0]?.value === 'I am an error!'; + }); + + await page.goto('/'); + + const exceptionButton = page.locator('id=exception-button'); + await exceptionButton.click(); + + const errorEvent = await errorEventPromise; + + expect(errorEvent.exception?.values).toHaveLength(1); + expect(errorEvent.exception?.values?.[0]?.value).toBe('I am an error!'); + + expect(errorEvent.request).toEqual({ + headers: expect.any(Object), + url: 'http://localhost:3030/', + }); + + expect(errorEvent.transaction).toEqual('/'); + + expect(errorEvent.contexts?.trace).toEqual({ + trace_id: expect.any(String), + span_id: expect.any(String), + }); +}); + +test('Sets correct transactionName', async ({ page }) => { + const transactionPromise = waitForTransaction('react-router-7-spa', async transactionEvent => { + return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload'; + }); + + const errorEventPromise = waitForError('react-router-7-spa', event => { + return !event.type && event.exception?.values?.[0]?.value === 'I am an error!'; + }); + + await page.goto('/'); + const transactionEvent = await transactionPromise; + + // Only capture error once transaction was sent + const exceptionButton = page.locator('id=exception-button'); + await exceptionButton.click(); + + const errorEvent = await errorEventPromise; + + expect(errorEvent.exception?.values).toHaveLength(1); + expect(errorEvent.exception?.values?.[0]?.value).toBe('I am an error!'); + + expect(errorEvent.transaction).toEqual('/'); + + expect(errorEvent.contexts?.trace).toEqual({ + trace_id: transactionEvent.contexts?.trace?.trace_id, + span_id: expect.not.stringContaining(transactionEvent.contexts?.trace?.span_id || ''), + }); +}); diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/react-router-7-spa/tests/transactions.test.ts new file mode 100644 index 000000000000..c915d3694742 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/tests/transactions.test.ts @@ -0,0 +1,99 @@ +import { expect, test } from '@playwright/test'; +import { waitForEnvelopeItem, waitForTransaction } from '@sentry-internal/test-utils'; + +test('sends a pageload transaction with a parameterized URL', async ({ page }) => { + const transactionPromise = waitForTransaction('react-router-7-spa', async transactionEvent => { + return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload'; + }); + + await page.goto(`/`); + + const rootSpan = await transactionPromise; + + expect(rootSpan).toMatchObject({ + contexts: { + trace: { + op: 'pageload', + origin: 'auto.pageload.react.reactrouter_v7', + }, + }, + transaction: '/', + transaction_info: { + source: 'route', + }, + }); +}); + +test('sends a navigation transaction with a parameterized URL', async ({ page }) => { + page.on('console', msg => console.log(msg.text())); + const pageloadTxnPromise = waitForTransaction('react-router-7-spa', async transactionEvent => { + return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'pageload'; + }); + + const navigationTxnPromise = waitForTransaction('react-router-7-spa', async transactionEvent => { + return !!transactionEvent?.transaction && transactionEvent.contexts?.trace?.op === 'navigation'; + }); + + await page.goto(`/`); + await pageloadTxnPromise; + + const linkElement = page.locator('id=navigation'); + + const [_, navigationTxn] = await Promise.all([linkElement.click(), navigationTxnPromise]); + + expect(navigationTxn).toMatchObject({ + contexts: { + trace: { + op: 'navigation', + origin: 'auto.navigation.react.reactrouter_v7', + }, + }, + transaction: '/user/:id', + transaction_info: { + source: 'route', + }, + }); +}); + +test('sends an INP span', async ({ page }) => { + const inpSpanPromise = waitForEnvelopeItem('react-router-7-spa', item => { + return item[0].type === 'span'; + }); + + await page.goto(`/`); + + await page.click('#exception-button'); + + await page.waitForTimeout(500); + + // Page hide to trigger INP + await page.evaluate(() => { + window.dispatchEvent(new Event('pagehide')); + }); + + const inpSpan = await inpSpanPromise; + + expect(inpSpan[1]).toEqual({ + data: { + 'sentry.origin': 'auto.http.browser.inp', + 'sentry.op': 'ui.interaction.click', + release: 'e2e-test', + environment: 'qa', + transaction: '/', + 'sentry.exclusive_time': expect.any(Number), + replay_id: expect.any(String), + 'user_agent.original': expect.stringContaining('Chrome'), + }, + description: 'body > div#root > input#exception-button[type="button"]', + op: 'ui.interaction.click', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + timestamp: expect.any(Number), + trace_id: expect.any(String), + origin: 'auto.http.browser.inp', + exclusive_time: expect.any(Number), + measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } }, + segment_id: expect.any(String), + }); +}); diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/tsconfig.json b/dev-packages/e2e-tests/test-applications/react-router-7-spa/tsconfig.json new file mode 100644 index 000000000000..60051df13cbf --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es2018", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react", + "types": ["vite/client"], + }, + "include": ["src", "tests"] +} diff --git a/dev-packages/e2e-tests/test-applications/react-router-7-spa/vite.config.ts b/dev-packages/e2e-tests/test-applications/react-router-7-spa/vite.config.ts new file mode 100644 index 000000000000..63c2c4317df7 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/react-router-7-spa/vite.config.ts @@ -0,0 +1,8 @@ +import react from '@vitejs/plugin-react'; +import { defineConfig } from 'vite'; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], + envPrefix: 'PUBLIC_', +}); diff --git a/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json b/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json index 55d4c5743e0a..62050fc0d10c 100644 --- a/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json +++ b/dev-packages/e2e-tests/test-applications/solid-solidrouter/package.json @@ -16,7 +16,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "autoprefixer": "^10.4.17", "postcss": "^8.4.33", diff --git a/dev-packages/e2e-tests/test-applications/solid/package.json b/dev-packages/e2e-tests/test-applications/solid/package.json index 51eccbae8a31..5196494cca78 100644 --- a/dev-packages/e2e-tests/test-applications/solid/package.json +++ b/dev-packages/e2e-tests/test-applications/solid/package.json @@ -16,7 +16,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "autoprefixer": "^10.4.17", "postcss": "^8.4.33", diff --git a/dev-packages/e2e-tests/test-applications/svelte-5/package.json b/dev-packages/e2e-tests/test-applications/svelte-5/package.json index 0eb3d4154d40..d1230c56ef40 100644 --- a/dev-packages/e2e-tests/test-applications/svelte-5/package.json +++ b/dev-packages/e2e-tests/test-applications/svelte-5/package.json @@ -15,7 +15,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sveltejs/vite-plugin-svelte": "^3.0.2", "@tsconfig/svelte": "^5.0.2", diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/package.json b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/package.json index 192b56a98fe9..7aee187f4469 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2-svelte-5/package.json @@ -21,7 +21,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/kit": "^2.0.0", diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2-twp/package.json b/dev-packages/e2e-tests/test-applications/sveltekit-2-twp/package.json index 56daf84e58b5..4738b14b39aa 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2-twp/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2-twp/package.json @@ -20,7 +20,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/kit": "^2.0.0", diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json b/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json index 080a23ebcfe8..75b5aa195356 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json @@ -20,7 +20,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-node": "^2.0.0", diff --git a/dev-packages/e2e-tests/test-applications/sveltekit/package.json b/dev-packages/e2e-tests/test-applications/sveltekit/package.json index c7e9aa022d1e..546fec8b9cf5 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit/package.json @@ -19,7 +19,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/adapter-node": "^1.2.4", diff --git a/dev-packages/e2e-tests/test-applications/vue-3/package.json b/dev-packages/e2e-tests/test-applications/vue-3/package.json index 4f3125b81eb2..364c67996c76 100644 --- a/dev-packages/e2e-tests/test-applications/vue-3/package.json +++ b/dev-packages/e2e-tests/test-applications/vue-3/package.json @@ -23,7 +23,6 @@ "devDependencies": { "@playwright/test": "^1.44.1", "@sentry-internal/test-utils": "link:../../../test-utils", - "@sentry/types": "latest || *", "@sentry/core": "latest || *", "@tsconfig/node20": "^20.1.2", "@types/node": "^20.11.10", diff --git a/dev-packages/e2e-tests/verdaccio-config/config.yaml b/dev-packages/e2e-tests/verdaccio-config/config.yaml index 67ee55a9d9ce..585cbbfa10a5 100644 --- a/dev-packages/e2e-tests/verdaccio-config/config.yaml +++ b/dev-packages/e2e-tests/verdaccio-config/config.yaml @@ -164,12 +164,14 @@ packages: unpublish: $all # proxy: npmjs # Don't proxy for E2E tests! + # TODO(v9): Remove '@sentry/types': access: $all publish: $all unpublish: $all # proxy: npmjs # Don't proxy for E2E tests! + # TODO(v9): Remove '@sentry/utils': access: $all publish: $all diff --git a/dev-packages/external-contributor-gh-action/package.json b/dev-packages/external-contributor-gh-action/package.json index 1ab5c0fd0dc4..d2b79213ea66 100644 --- a/dev-packages/external-contributor-gh-action/package.json +++ b/dev-packages/external-contributor-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/external-contributor-gh-action", "description": "An internal Github Action to add external contributors to the CHANGELOG.md file.", - "version": "8.40.0", + "version": "8.42.0", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/node-integration-tests/package.json b/dev-packages/node-integration-tests/package.json index f58bef2a0e45..3159dc8cb9b3 100644 --- a/dev-packages/node-integration-tests/package.json +++ b/dev-packages/node-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/node-integration-tests", - "version": "8.40.0", + "version": "8.42.0", "license": "MIT", "engines": { "node": ">=14.18" @@ -31,10 +31,9 @@ "@nestjs/core": "10.4.6", "@nestjs/platform-express": "10.4.6", "@prisma/client": "5.9.1", - "@sentry/aws-serverless": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/aws-serverless": "8.42.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", "@types/mongodb": "^3.6.20", "@types/mysql": "^2.15.21", "@types/pg": "^8.6.5", diff --git a/dev-packages/node-integration-tests/scripts/clean.js b/dev-packages/node-integration-tests/scripts/clean.js index b7ae8505e916..0610e39f92d4 100644 --- a/dev-packages/node-integration-tests/scripts/clean.js +++ b/dev-packages/node-integration-tests/scripts/clean.js @@ -17,12 +17,3 @@ for (const path of paths) { // } } - -// eslint-disable-next-line no-console -console.log('Cleaning up watchman...'); - -try { - execSync('watchman watch-del "./../.."; watchman watch-project "./../.."', { stdio: 'inherit' }); -} catch (_) { - // -} diff --git a/dev-packages/node-integration-tests/src/index.ts b/dev-packages/node-integration-tests/src/index.ts index 4bd0a9ccce25..18c443203926 100644 --- a/dev-packages/node-integration-tests/src/index.ts +++ b/dev-packages/node-integration-tests/src/index.ts @@ -1,5 +1,5 @@ import type { AddressInfo } from 'net'; -import type { BaseTransportOptions, Envelope, Transport, TransportMakeRequestResponse } from '@sentry/types'; +import type { BaseTransportOptions, Envelope, Transport, TransportMakeRequestResponse } from '@sentry/core'; import type { Express } from 'express'; /** diff --git a/dev-packages/node-integration-tests/suites/anr/test.ts b/dev-packages/node-integration-tests/suites/anr/test.ts index 0352212a8293..fd15df4bd0b8 100644 --- a/dev-packages/node-integration-tests/suites/anr/test.ts +++ b/dev-packages/node-integration-tests/suites/anr/test.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { conditionalTest } from '../../utils'; import { cleanupChildProcesses, createRunner } from '../../utils/runner'; @@ -6,8 +6,8 @@ const ANR_EVENT = { // Ensure we have context contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, device: { arch: expect.any(String), diff --git a/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/s3/test.ts b/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/s3/test.ts index 6ffc6f6303fa..10d3f4bdd005 100644 --- a/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/s3/test.ts +++ b/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/s3/test.ts @@ -26,6 +26,6 @@ describe('awsIntegration', () => { }); test('should auto-instrument aws-sdk v2 package.', done => { - createRunner(__dirname, 'scenario.js').expect({ transaction: EXPECTED_TRANSCATION }).start(done); + createRunner(__dirname, 'scenario.js').ignore('event').expect({ transaction: EXPECTED_TRANSCATION }).start(done); }); }); diff --git a/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts b/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts index f675ca4250dd..632568fa85d1 100644 --- a/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts +++ b/dev-packages/node-integration-tests/suites/breadcrumbs/process-thread/test.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { conditionalTest } from '../../../utils'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; diff --git a/dev-packages/node-integration-tests/suites/cron/cron/test.ts b/dev-packages/node-integration-tests/suites/cron/cron/test.ts index ee83f4dc1226..acd7815aebe1 100644 --- a/dev-packages/node-integration-tests/suites/cron/cron/test.ts +++ b/dev-packages/node-integration-tests/suites/cron/cron/test.ts @@ -15,8 +15,8 @@ test('cron instrumentation', done => { monitor_config: { schedule: { type: 'crontab', value: '* * * * * *' } }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -30,8 +30,8 @@ test('cron instrumentation', done => { duration: expect.any(Number), contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -45,8 +45,8 @@ test('cron instrumentation', done => { monitor_config: { schedule: { type: 'crontab', value: '* * * * * *' } }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -60,8 +60,8 @@ test('cron instrumentation', done => { duration: expect.any(Number), contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, diff --git a/dev-packages/node-integration-tests/suites/cron/node-cron/test.ts b/dev-packages/node-integration-tests/suites/cron/node-cron/test.ts index 2c3be50907a3..904da8180087 100644 --- a/dev-packages/node-integration-tests/suites/cron/node-cron/test.ts +++ b/dev-packages/node-integration-tests/suites/cron/node-cron/test.ts @@ -15,8 +15,8 @@ test('node-cron instrumentation', done => { monitor_config: { schedule: { type: 'crontab', value: '* * * * * *' } }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -30,8 +30,8 @@ test('node-cron instrumentation', done => { duration: expect.any(Number), contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -45,8 +45,8 @@ test('node-cron instrumentation', done => { monitor_config: { schedule: { type: 'crontab', value: '* * * * * *' } }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -60,8 +60,8 @@ test('node-cron instrumentation', done => { duration: expect.any(Number), contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, diff --git a/dev-packages/node-integration-tests/suites/cron/node-schedule/test.ts b/dev-packages/node-integration-tests/suites/cron/node-schedule/test.ts index 84d94c54ad8d..74d815e56c88 100644 --- a/dev-packages/node-integration-tests/suites/cron/node-schedule/test.ts +++ b/dev-packages/node-integration-tests/suites/cron/node-schedule/test.ts @@ -15,8 +15,8 @@ test('node-schedule instrumentation', done => { monitor_config: { schedule: { type: 'crontab', value: '* * * * * *' } }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -30,8 +30,8 @@ test('node-schedule instrumentation', done => { duration: expect.any(Number), contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -45,8 +45,8 @@ test('node-schedule instrumentation', done => { monitor_config: { schedule: { type: 'crontab', value: '* * * * * *' } }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, @@ -60,8 +60,8 @@ test('node-schedule instrumentation', done => { duration: expect.any(Number), contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), }, }, }, diff --git a/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts b/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts index 25f90460e2b9..f8d752497d46 100644 --- a/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts +++ b/dev-packages/node-integration-tests/suites/esm/warn-esm/test.ts @@ -5,7 +5,7 @@ afterAll(() => { }); const esmWarning = - '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or use version 7.x of the Sentry Node.js SDK.'; + '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.'; test("warns if using ESM on Node.js versions that don't support `register()`", async () => { const nodeMajorVersion = Number(process.versions.node.split('.')[0]); diff --git a/dev-packages/node-integration-tests/suites/express/tracing/test.ts b/dev-packages/node-integration-tests/suites/express/tracing/test.ts index 0b56d354759c..1c1d8439822d 100644 --- a/dev-packages/node-integration-tests/suites/express/tracing/test.ts +++ b/dev-packages/node-integration-tests/suites/express/tracing/test.ts @@ -12,8 +12,8 @@ describe('express tracing', () => { transaction: { contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { url: expect.stringMatching(/\/test\/express$/), 'http.response.status_code': 200, @@ -58,8 +58,8 @@ describe('express tracing', () => { }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), data: { url: expect.stringMatching(/\/test\/regex$/), 'http.response.status_code': 200, @@ -86,8 +86,8 @@ describe('express tracing', () => { }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), data: { url: expect.stringMatching(`/test/${segment}$`), 'http.response.status_code': 200, @@ -122,8 +122,8 @@ describe('express tracing', () => { }, contexts: { trace: { - trace_id: expect.any(String), - span_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), data: { url: expect.stringMatching(`/test/${segment}$`), 'http.response.status_code': 200, diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts index ec761a7d591d..7c4f702f5df8 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/scenario.ts @@ -15,6 +15,18 @@ Sentry.withScope(scope => { traceId: '12345678901234567890123456789012', }); - Sentry.startSpan({ name: 'test_span_1' }, () => undefined); - Sentry.startSpan({ name: 'test_span_2' }, () => undefined); + const spanIdTraceId = Sentry.startSpan( + { + name: 'test_span_1', + }, + span1 => span1.spanContext().traceId, + ); + + Sentry.startSpan( + { + name: 'test_span_2', + attributes: { spanIdTraceId }, + }, + () => undefined, + ); }); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/test.ts index 9a561ffd391a..ecc45e46b4a0 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope-with-parentSpanId/test.ts @@ -6,28 +6,19 @@ afterAll(() => { test('should send manually started parallel root spans outside of root context with parentSpanId', done => { createRunner(__dirname, 'scenario.ts') + .expect({ transaction: { transaction: 'test_span_1' } }) .expect({ - transaction: { - transaction: 'test_span_1', - contexts: { - trace: { - span_id: expect.any(String), - parent_span_id: '1234567890123456', - trace_id: '12345678901234567890123456789012', - }, - }, - }, - }) - .expect({ - transaction: { - transaction: 'test_span_2', - contexts: { - trace: { - span_id: expect.any(String), - parent_span_id: '1234567890123456', - trace_id: '12345678901234567890123456789012', - }, - }, + transaction: transaction => { + expect(transaction).toBeDefined(); + const traceId = transaction.contexts?.trace?.trace_id; + expect(traceId).toBeDefined(); + expect(transaction.contexts?.trace?.parent_span_id).toBeUndefined(); + + const trace1Id = transaction.contexts?.trace?.data?.spanIdTraceId; + expect(trace1Id).toBeDefined(); + + // Different trace ID as the first span + expect(trace1Id).not.toBe(traceId); }, }) .start(done); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope/test.ts index 97ceaa1e382c..58cf67c7c69a 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/parallel-spans-in-scope/test.ts @@ -19,8 +19,8 @@ test('should send manually started parallel root spans outside of root context', const trace1Id = transaction.contexts?.trace?.data?.spanIdTraceId; expect(trace1Id).toBeDefined(); - // Same trace ID as the first span - expect(trace1Id).toBe(traceId); + // Different trace ID as the first span + expect(trace1Id).not.toBe(traceId); }, }) .start(done); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/with-nested-spans/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/with-nested-spans/test.ts index 5cf4dc8c8c40..ffa693c4752d 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/with-nested-spans/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/with-nested-spans/test.ts @@ -1,4 +1,4 @@ -import type { SpanJSON } from '@sentry/types'; +import type { SpanJSON } from '@sentry/core'; import { assertSentryTransaction } from '../../../../utils/assertions'; import { cleanupChildProcesses, createRunner } from '../../../../utils/runner'; diff --git a/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts b/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts index 38b3c26dd95e..7a3eb6414237 100644 --- a/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts @@ -1,4 +1,4 @@ -import type { TransactionEvent } from '@sentry/types'; +import type { TransactionEvent } from '@sentry/core'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; // When running docker compose, we need a larger timeout, as this takes some time. diff --git a/dev-packages/node-integration-tests/suites/tracing/dsc-txn-name-update/test.ts b/dev-packages/node-integration-tests/suites/tracing/dsc-txn-name-update/test.ts index cefaba1ad97f..82f86baa835f 100644 --- a/dev-packages/node-integration-tests/suites/tracing/dsc-txn-name-update/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/dsc-txn-name-update/test.ts @@ -67,7 +67,7 @@ test('adds current transaction name to trace envelope header when the txn name i release: '1.0', sample_rate: '1', sampled: 'true', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, }) @@ -79,7 +79,7 @@ test('adds current transaction name to trace envelope header when the txn name i release: '1.0', sample_rate: '1', sampled: 'true', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), transaction: 'updated-name-1', }, }, @@ -92,7 +92,7 @@ test('adds current transaction name to trace envelope header when the txn name i release: '1.0', sample_rate: '1', sampled: 'true', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), transaction: 'updated-name-2', }, }, @@ -105,7 +105,7 @@ test('adds current transaction name to trace envelope header when the txn name i release: '1.0', sample_rate: '1', sampled: 'true', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), transaction: 'updated-name-2', }, }, diff --git a/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span-unsampled/test.ts b/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span-unsampled/test.ts index c962bc36800d..8ac2dd53a089 100644 --- a/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span-unsampled/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span-unsampled/test.ts @@ -6,7 +6,7 @@ test('envelope header for error event during active unsampled span is correct', .expectHeader({ event: { trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', environment: 'production', release: '1.0', diff --git a/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span/test.ts b/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span/test.ts index f81364dec824..6749f275035b 100644 --- a/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/envelope-header/error-active-span/test.ts @@ -6,7 +6,7 @@ test('envelope header for error event during active span is correct', done => { .expectHeader({ event: { trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', environment: 'production', release: '1.0', diff --git a/dev-packages/node-integration-tests/suites/tracing/envelope-header/error/test.ts b/dev-packages/node-integration-tests/suites/tracing/envelope-header/error/test.ts index 87229650bfb4..efb1ce409efd 100644 --- a/dev-packages/node-integration-tests/suites/tracing/envelope-header/error/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/envelope-header/error/test.ts @@ -5,7 +5,7 @@ test('envelope header for error events is correct', done => { .expectHeader({ event: { trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), environment: 'production', public_key: 'public', release: '1.0', diff --git a/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-route/test.ts b/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-route/test.ts index a9d7a3ac04e8..592d75f30ae6 100644 --- a/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-route/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-route/test.ts @@ -5,7 +5,7 @@ test('envelope header for transaction event of route correct', done => { .expectHeader({ transaction: { trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', transaction: 'GET /route', environment: 'production', diff --git a/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-url/test.ts b/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-url/test.ts index 2656835cd98d..a7de2f95c965 100644 --- a/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-url/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction-url/test.ts @@ -5,7 +5,7 @@ test('envelope header for transaction event with source=url correct', done => { .expectHeader({ transaction: { trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', environment: 'production', release: '1.0', diff --git a/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction/test.ts b/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction/test.ts index 436c7d7adf2e..3d4ff2d8d96a 100644 --- a/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/envelope-header/transaction/test.ts @@ -5,7 +5,7 @@ test('envelope header for transaction event is correct', done => { .expectHeader({ transaction: { trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), public_key: 'public', environment: 'production', release: '1.0', diff --git a/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts b/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts index 016ad078d34e..7fc6a5f05efa 100644 --- a/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts @@ -18,8 +18,8 @@ describe('httpIntegration', () => { transaction: { contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { url: expect.stringMatching(/\/test$/), 'http.response.status_code': 200, @@ -59,8 +59,8 @@ describe('httpIntegration', () => { transaction: { contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { url: expect.stringMatching(/\/test$/), 'http.response.status_code': 200, @@ -83,8 +83,8 @@ describe('httpIntegration', () => { transaction: { contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { url: expect.stringMatching(/\/test$/), 'http.response.status_code': 200, @@ -108,8 +108,8 @@ describe('httpIntegration', () => { transaction: { contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), data: { url: expect.stringMatching(/\/test$/), 'http.response.status_code': 200, diff --git a/dev-packages/node-integration-tests/suites/tracing/maxSpans/test.ts b/dev-packages/node-integration-tests/suites/tracing/maxSpans/test.ts index 2554a9b790b6..b705bfc71ea4 100644 --- a/dev-packages/node-integration-tests/suites/tracing/maxSpans/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/maxSpans/test.ts @@ -1,4 +1,4 @@ -import type { SpanJSON } from '@sentry/types'; +import type { SpanJSON } from '@sentry/core'; import { createRunner } from '../../../utils/runner'; test('it limits spans to 1000', done => { diff --git a/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/instrument.mjs b/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/instrument.mjs new file mode 100644 index 000000000000..d843ca07fce8 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/instrument.mjs @@ -0,0 +1,11 @@ +import { loggingTransport } from '@sentry-internal/node-integration-tests'; +import * as Sentry from '@sentry/node'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + release: '1.0', + tracesSampleRate: 1.0, + tracePropagationTargets: [/\/v0/, 'v1'], + integrations: [], + transport: loggingTransport, +}); diff --git a/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/scenario.mjs b/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/scenario.mjs new file mode 100644 index 000000000000..07e234983b4d --- /dev/null +++ b/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/scenario.mjs @@ -0,0 +1,25 @@ +import * as http from 'http'; +import * as Sentry from '@sentry/node'; + +// eslint-disable-next-line @typescript-eslint/no-floating-promises +Sentry.startSpan({ name: 'test_span' }, async () => { + await makeHttpRequest(`${process.env.SERVER_URL}/api/v0`); + await makeHttpRequest(`${process.env.SERVER_URL}/api/v1`); + await makeHttpRequest(`${process.env.SERVER_URL}/api/v2`); + await makeHttpRequest(`${process.env.SERVER_URL}/api/v3`); +}); + +function makeHttpRequest(url) { + return new Promise(resolve => { + http + .request(url, httpRes => { + httpRes.on('data', () => { + // we don't care about data + }); + httpRes.on('end', () => { + resolve(); + }); + }) + .end(); + }); +} diff --git a/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/test.ts b/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/test.ts new file mode 100644 index 000000000000..b69354ae00c4 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/tracing/requests/http-sampled-esm/test.ts @@ -0,0 +1,43 @@ +import { join } from 'path'; +import { conditionalTest } from '../../../../utils'; +import { createRunner } from '../../../../utils/runner'; +import { createTestServer } from '../../../../utils/server'; + +conditionalTest({ min: 18 })('outgoing sampled http requests are correctly instrumented in ESM', () => { + test('outgoing sampled http requests are correctly instrumented in ESM', done => { + expect.assertions(11); + + createTestServer(done) + .get('/api/v0', headers => { + expect(headers['baggage']).toEqual(expect.any(String)); + expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})-1$/)); + expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000-1'); + }) + .get('/api/v1', headers => { + expect(headers['baggage']).toEqual(expect.any(String)); + expect(headers['sentry-trace']).toEqual(expect.stringMatching(/^([a-f0-9]{32})-([a-f0-9]{16})-1$/)); + expect(headers['sentry-trace']).not.toEqual('00000000000000000000000000000000-0000000000000000-1'); + }) + .get('/api/v2', headers => { + expect(headers['baggage']).toBeUndefined(); + expect(headers['sentry-trace']).toBeUndefined(); + }) + .get('/api/v3', headers => { + expect(headers['baggage']).toBeUndefined(); + expect(headers['sentry-trace']).toBeUndefined(); + }) + .start() + .then(([SERVER_URL, closeTestServer]) => { + const instrumentPath = join(__dirname, 'instrument.mjs'); + createRunner(__dirname, 'scenario.mjs') + .withFlags('--import', instrumentPath) + .withEnv({ SERVER_URL }) + .expect({ + transaction: { + // we're not too concerned with the actual transaction here since this is tested elsewhere + }, + }) + .start(closeTestServer); + }); + }); +}); diff --git a/dev-packages/node-integration-tests/utils/assertions.ts b/dev-packages/node-integration-tests/utils/assertions.ts index 0f2713280282..1d4e7d1b321a 100644 --- a/dev-packages/node-integration-tests/utils/assertions.ts +++ b/dev-packages/node-integration-tests/utils/assertions.ts @@ -7,7 +7,7 @@ import type { SerializedSession, SessionAggregates, TransactionEvent, -} from '@sentry/types'; +} from '@sentry/core'; /** * Asserts against a Sentry Event ignoring non-deterministic properties diff --git a/dev-packages/node-integration-tests/utils/index.ts b/dev-packages/node-integration-tests/utils/index.ts index 473a69c78cd8..b51a0a8f83c8 100644 --- a/dev-packages/node-integration-tests/utils/index.ts +++ b/dev-packages/node-integration-tests/utils/index.ts @@ -1,6 +1,6 @@ import type * as http from 'http'; import { parseSemver } from '@sentry/core'; -import type { EnvelopeItemType } from '@sentry/types'; +import type { EnvelopeItemType } from '@sentry/core'; const NODE_VERSION = parseSemver(process.versions.node).major; diff --git a/dev-packages/node-integration-tests/utils/runner.ts b/dev-packages/node-integration-tests/utils/runner.ts index 2b0a83f3c63e..bc4fb901e2db 100644 --- a/dev-packages/node-integration-tests/utils/runner.ts +++ b/dev-packages/node-integration-tests/utils/runner.ts @@ -13,7 +13,7 @@ import type { SerializedSession, SessionAggregates, TransactionEvent, -} from '@sentry/types'; +} from '@sentry/core'; import axios from 'axios'; import { assertEnvelopeHeader, @@ -338,6 +338,8 @@ export function createRunner(...paths: string[]) { const output = data.toString(); logs.push(output.trim()); + if (process.env.DEBUG) log('stderr line', output); + if (ensureNoErrorOutput) { complete(new Error(`Expected no error output but got: '${output}'`)); } diff --git a/dev-packages/node-integration-tests/utils/server.ts b/dev-packages/node-integration-tests/utils/server.ts index f46338d7de63..761ec1cd2429 100644 --- a/dev-packages/node-integration-tests/utils/server.ts +++ b/dev-packages/node-integration-tests/utils/server.ts @@ -1,6 +1,6 @@ import type { AddressInfo } from 'net'; import { parseEnvelope } from '@sentry/core'; -import type { Envelope } from '@sentry/types'; +import type { Envelope } from '@sentry/core'; import express from 'express'; /** diff --git a/dev-packages/rollup-utils/package.json b/dev-packages/rollup-utils/package.json index 66366107f869..8ae5f58657d3 100644 --- a/dev-packages/rollup-utils/package.json +++ b/dev-packages/rollup-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/rollup-utils", - "version": "8.40.0", + "version": "8.42.0", "description": "Rollup utilities used at Sentry for the Sentry JavaScript SDK", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/rollup-utils", diff --git a/dev-packages/size-limit-gh-action/package.json b/dev-packages/size-limit-gh-action/package.json index a879bedbdd83..8923cfdac3fc 100644 --- a/dev-packages/size-limit-gh-action/package.json +++ b/dev-packages/size-limit-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/size-limit-gh-action", "description": "An internal Github Action to compare the current size of a PR against the one on develop.", - "version": "8.40.0", + "version": "8.42.0", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/test-utils/package.json b/dev-packages/test-utils/package.json index f96285c9613b..f73c8b5db0d3 100644 --- a/dev-packages/test-utils/package.json +++ b/dev-packages/test-utils/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "8.40.0", + "version": "8.42.0", "name": "@sentry-internal/test-utils", "author": "Sentry", "license": "MIT", @@ -45,8 +45,7 @@ }, "devDependencies": { "@playwright/test": "^1.44.1", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "volta": { "extends": "../../package.json" diff --git a/dev-packages/test-utils/src/event-proxy-server.ts b/dev-packages/test-utils/src/event-proxy-server.ts index 73ced8df7053..07be845bc553 100644 --- a/dev-packages/test-utils/src/event-proxy-server.ts +++ b/dev-packages/test-utils/src/event-proxy-server.ts @@ -7,7 +7,7 @@ import * as path from 'path'; import * as util from 'util'; import * as zlib from 'zlib'; import { parseEnvelope } from '@sentry/core'; -import type { Envelope, EnvelopeItem, Event, SerializedSession } from '@sentry/types'; +import type { Envelope, EnvelopeItem, Event, SerializedSession } from '@sentry/core'; const readFile = util.promisify(fs.readFile); const writeFile = util.promisify(fs.writeFile); diff --git a/docs/assets/node-sdk-trace-propagation.png b/docs/assets/node-sdk-trace-propagation.png new file mode 100644 index 000000000000..f4d5c7bf1b5f Binary files /dev/null and b/docs/assets/node-sdk-trace-propagation.png differ diff --git a/docs/migration/draft-v9-migration-guide.md b/docs/migration/draft-v9-migration-guide.md index c543009d4995..684fd40ab894 100644 --- a/docs/migration/draft-v9-migration-guide.md +++ b/docs/migration/draft-v9-migration-guide.md @@ -2,6 +2,23 @@ # Deprecations +## General + +- **Returning `null` from `beforeSendSpan` span is deprecated.** +- **Passing `undefined` to `tracesSampleRate` / `tracesSampler` / `enableTracing` will be handled differently in v9** + + In v8, a setup like the following: + + ```ts + Sentry.init({ + tracesSampleRate: undefined, + }); + ``` + + Will result in tracing being _enabled_, although no spans will be generated. + In v9, we will streamline this behavior so that passing `undefined` will result in tracing being disabled, the same as not passing the option at all. + If you are relying on `undefined` being passed in and having tracing enabled because of this, you should update your config to set e.g. `tracesSampleRate: 0` instead, which will also enable tracing in v9. + ## `@sentry/utils` - **The `@sentry/utils` package has been deprecated. Import everything from `@sentry/core` instead.** @@ -15,15 +32,21 @@ - Deprecated `extractRequestData`. Instead manually extract relevant data off request. - Deprecated `arrayify`. No replacements. - Deprecated `memoBuilder`. No replacements. +- Deprecated `getNumberOfUrlSegments`. No replacements. - Deprecated `BAGGAGE_HEADER_NAME`. No replacements. - Deprecated `makeFifoCache`. No replacements. +- Deprecated `dynamicRequire`. No replacements. - Deprecated `flatten`. No replacements. +- Deprecated `_browserPerformanceTimeOriginMode`. No replacements. ## `@sentry/core` - Deprecated `transactionNamingScheme` option in `requestDataIntegration`. - Deprecated `debugIntegration`. To log outgoing events, use [Hook Options](https://docs.sentry.io/platforms/javascript/configuration/options/#hooks) (`beforeSend`, `beforeSendTransaction`, ...). - Deprecated `sessionTimingIntegration`. To capture session durations alongside events, use [Context](https://docs.sentry.io/platforms/javascript/enriching-events/context/) (`Sentry.setContext()`). +- Deprecated `addTracingHeadersToFetchRequest` method - this was only meant for internal use and is not needed anymore. +- Deprecated `generatePropagationContext()` in favor of using `generateTraceId()` directly. +- Deprecated `spanId` field on `propagationContext` - this field will be removed in v9, and should neither be read or set anymore. ## `@sentry/nestjs` @@ -43,8 +66,14 @@ ## `@sentry/types` +- **The `@sentry/types` package has been deprecated. Import everything from `@sentry/core` instead.** + - Deprecated `Request` in favor of `RequestEventData`. +## `@sentry/nuxt` + +- Deprecated `tracingOptions` in `Sentry.init()` in favor of passing the `vueIntegration()` to `Sentry.init({ integrations: [...] })` and setting `tracingOptions` there. + ## `@sentry/vue` - Deprecated `tracingOptions`, `trackComponents`, `timeout`, `hooks` options everywhere other than in the `tracingOptions` option of the `vueIntegration()`. @@ -66,8 +95,28 @@ }); ``` +## `@sentry/astro` + +- Deprecated passing `dsn`, `release`, `environment`, `sampleRate`, `tracesSampleRate`, `replaysSessionSampleRate` to the integration. Use the runtime-specific `Sentry.init()` calls for passing these options instead. + +## `@sentry/remix` + +- Deprecated `autoInstrumentRemix: false`. The next major version will default to behaving as if this option were `true` and the option itself will be removed. + +## `@sentry/react` + +- Deprecated `wrapUseRoutes`. Use `wrapUseRoutesV6` or `wrapUseRoutesV7` instead. +- Deprecated `wrapCreateBrowserRouter`. Use `wrapCreateBrowserRouterV6` or `wrapCreateBrowserRouterV7` instead. + +## `@sentry/opentelemetry` + +- Deprecated `generateSpanContextForPropagationContext` in favor of doing this manually - we do not need this export anymore. + ## Server-side SDKs (`@sentry/node` and all dependents) - Deprecated `processThreadBreadcrumbIntegration` in favor of `childProcessIntegration`. Functionally they are the same. - Deprecated `nestIntegration`. Use the NestJS SDK (`@sentry/nestjs`) instead. - Deprecated `setupNestErrorHandler`. Use the NestJS SDK (`@sentry/nestjs`) instead. +- Deprecated `addOpenTelemetryInstrumentation`. Use the `openTelemetryInstrumentations` option in `Sentry.init()` or your custom Sentry Client instead. +- Deprecated `registerEsmLoaderHooks.include` and `registerEsmLoaderHooks.exclude`. Set `onlyIncludeInstrumentedModules: true` instead. +- `registerEsmLoaderHooks` will only accept `true | false | undefined` in the future. The SDK will default to wrapping modules that are used as part of OpenTelemetry Instrumentation. diff --git a/docs/trace-propagation.md b/docs/trace-propagation.md new file mode 100644 index 000000000000..14de136135e1 --- /dev/null +++ b/docs/trace-propagation.md @@ -0,0 +1,14 @@ +# How Trace Propagation Works in the JavaScript SDKs + +Trace propagation describes how and when traceId & spanId are set and send for various types of events. +How this behaves varies a bit from Browser to Node SDKs. + +## Node SDKs (OpenTelemetry based) + +In the Node SDK and related OpenTelemetry-based SDKs, trace propagation works as follows: + +![node-sdk-trace-propagation-scenarios](./assets/node-sdk-trace-propagation.png) + +## Browser/Other SDKs + +TODO diff --git a/lerna.json b/lerna.json index 79fd6724de8e..1edfcb37b73f 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "8.40.0", + "version": "8.42.0", "npmClient": "yarn" } diff --git a/package.json b/package.json index 88f3725bf29f..780c68c65f33 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,9 @@ "clean:build": "lerna run clean", "clean:caches": "yarn rimraf eslintcache .nxcache && yarn jest --clearCache", "clean:deps": "lerna clean --yes && rm -rf node_modules && yarn", - "clean:tarballs": "rimraf -g **/*.tgz", - "clean:all": "run-s clean:build clean:tarballs clean:caches clean:deps", + "clean:tarballs": "rimraf {packages,dev-packages}/*/*.tgz", + "clean:watchman": "watchman watch-del \".\"", + "clean:all": "run-s clean:build clean:tarballs clean:caches clean:deps clean:watchman", "fix": "run-s fix:biome fix:prettier fix:lerna", "fix:lerna": "lerna run fix", "fix:biome": "biome check --apply .", @@ -44,7 +45,8 @@ }, "volta": { "node": "18.20.3", - "yarn": "1.22.22" + "yarn": "1.22.22", + "pnpm": "9.4.0" }, "workspaces": [ "packages/angular", @@ -123,7 +125,7 @@ "nodemon": "^2.0.16", "npm-run-all2": "^6.2.0", "prettier": "^3.1.1", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "rollup": "^4.24.2", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-license": "^3.3.1", diff --git a/packages/angular/package.json b/packages/angular/package.json index 66971da85773..6c4ed5df64f4 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/angular", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Angular", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular", @@ -21,9 +21,8 @@ "rxjs": "^6.5.5 || ^7.x" }, "dependencies": { - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0", "tslib": "^2.4.1" }, "devDependencies": { diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index fdb765934ea1..09ff9a187c55 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -4,7 +4,7 @@ import { Inject, Injectable } from '@angular/core'; import * as Sentry from '@sentry/browser'; import type { ReportDialogOptions } from '@sentry/browser'; import { consoleSandbox, isString } from '@sentry/core'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { runOutsideAngular } from './zone'; diff --git a/packages/angular/src/sdk.ts b/packages/angular/src/sdk.ts index d7cef5f55fdd..f5bf79be2f59 100755 --- a/packages/angular/src/sdk.ts +++ b/packages/angular/src/sdk.ts @@ -4,17 +4,18 @@ import { breadcrumbsIntegration, globalHandlersIntegration, httpContextIntegration, + init as browserInit, linkedErrorsIntegration, + setContext, } from '@sentry/browser'; -import { init as browserInit, setContext } from '@sentry/browser'; +import type { Client, Integration } from '@sentry/core'; import { applySdkMetadata, dedupeIntegration, functionToStringIntegration, inboundFiltersIntegration, + logger, } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { Client, Integration } from '@sentry/types'; import { IS_DEBUG_BUILD } from './flags'; diff --git a/packages/angular/src/tracing.ts b/packages/angular/src/tracing.ts index 0f5d3d49d211..4fcfbeffb0af 100644 --- a/packages/angular/src/tracing.ts +++ b/packages/angular/src/tracing.ts @@ -19,7 +19,7 @@ import { startInactiveSpan, } from '@sentry/browser'; import { logger, stripUrlQueryAndFragment, timestampInSeconds } from '@sentry/core'; -import type { Integration, Span } from '@sentry/types'; +import type { Integration, Span } from '@sentry/core'; import type { Observable } from 'rxjs'; import { Subscription } from 'rxjs'; import { filter, tap } from 'rxjs/operators'; diff --git a/packages/angular/test/errorhandler.test.ts b/packages/angular/test/errorhandler.test.ts index 1ae415c5706d..d2a65e86b51c 100644 --- a/packages/angular/test/errorhandler.test.ts +++ b/packages/angular/test/errorhandler.test.ts @@ -1,6 +1,6 @@ import { HttpErrorResponse } from '@angular/common/http'; import * as SentryBrowser from '@sentry/browser'; -import type { Client, Event } from '@sentry/types'; +import type { Client, Event } from '@sentry/core'; import { vi } from 'vitest'; import { SentryErrorHandler, createErrorHandler } from '../src/errorhandler'; diff --git a/packages/astro/package.json b/packages/astro/package.json index b000de7d211c..48d2424414ba 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/astro", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Astro", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/astro", @@ -56,10 +56,9 @@ "astro": ">=3.x || >=4.0.0-beta" }, "dependencies": { - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", "@sentry/vite-plugin": "^2.22.6" }, "devDependencies": { diff --git a/packages/astro/src/client/sdk.ts b/packages/astro/src/client/sdk.ts index 8a4617c652cf..24d29b3cc109 100644 --- a/packages/astro/src/client/sdk.ts +++ b/packages/astro/src/client/sdk.ts @@ -5,7 +5,7 @@ import { init as initBrowserSdk, } from '@sentry/browser'; import { applySdkMetadata } from '@sentry/core'; -import type { Client, Integration } from '@sentry/types'; +import type { Client, Integration } from '@sentry/core'; // Tree-shakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean; diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index 922fdd15dce1..85603431379b 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -11,6 +11,7 @@ export { addBreadcrumb, addEventProcessor, addIntegration, + // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, // eslint-disable-next-line deprecation/deprecation addRequestDataToEvent, diff --git a/packages/astro/src/index.types.ts b/packages/astro/src/index.types.ts index c05cfb4a3215..ce87a51c3af7 100644 --- a/packages/astro/src/index.types.ts +++ b/packages/astro/src/index.types.ts @@ -7,7 +7,7 @@ export * from '@sentry/node'; import type { NodeOptions } from '@sentry/node'; -import type { Client, Integration, Options, StackParser } from '@sentry/types'; +import type { Client, Integration, Options, StackParser } from '@sentry/core'; import type * as clientSdk from './index.client'; import type * as serverSdk from './index.server'; diff --git a/packages/astro/src/integration/index.ts b/packages/astro/src/integration/index.ts index eb976e24213d..49e33ff0231d 100644 --- a/packages/astro/src/integration/index.ts +++ b/packages/astro/src/integration/index.ts @@ -35,6 +35,15 @@ export const sentryAstro = (options: SentryOptions = {}): AstroIntegration => { // We don't need to check for AUTH_TOKEN here, because the plugin will pick it up from the env if (shouldUploadSourcemaps && command !== 'dev') { + // TODO(v9): Remove this warning + if (config?.vite?.build?.sourcemap === false) { + logger.warn( + "You disabled sourcemaps with the `vite.build.sourcemap` option. Currently, the Sentry SDK will override this option to generate sourcemaps. In future versions, the Sentry SDK will not override the `vite.build.sourcemap` option if you explicitly disable it. If you want to generate and upload sourcemaps please set the `vite.build.sourcemap` option to 'hidden' or undefined.", + ); + } + + // TODO: Add deleteSourcemapsAfterUpload option and warn if it isn't set. + updateConfig({ vite: { build: { diff --git a/packages/astro/src/integration/snippets.ts b/packages/astro/src/integration/snippets.ts index 4b784170d330..7ac05c163079 100644 --- a/packages/astro/src/integration/snippets.ts +++ b/packages/astro/src/integration/snippets.ts @@ -14,6 +14,7 @@ export function buildSdkInitFileImportSnippet(filePath: string): string { * default options. */ export function buildClientSnippet(options: SentryOptions): string { + /* eslint-disable deprecation/deprecation */ return `import * as Sentry from "@sentry/astro"; Sentry.init({ @@ -22,6 +23,7 @@ Sentry.init({ replaysSessionSampleRate: ${options.replaysSessionSampleRate ?? 0.1}, replaysOnErrorSampleRate: ${options.replaysOnErrorSampleRate ?? 1.0}, });`; + /* eslint-enable deprecation/deprecation */ } /** @@ -36,6 +38,7 @@ Sentry.init({ });`; } +/* eslint-disable deprecation/deprecation */ const buildCommonInitOptions = (options: SentryOptions): string => `dsn: ${ options.dsn ? JSON.stringify(options.dsn) : 'import.meta.env.PUBLIC_SENTRY_DSN' }, @@ -45,6 +48,7 @@ const buildCommonInitOptions = (options: SentryOptions): string => `dsn: ${ tracesSampleRate: ${options.tracesSampleRate ?? 1.0},${ options.sampleRate ? `\n sampleRate: ${options.sampleRate},` : '' }`; +/* eslint-enable deprecation/deprecation */ /** * We don't include the `BrowserTracing` integration if `bundleSizeOptimizations.excludeTracing` is falsy. @@ -61,9 +65,13 @@ const buildClientIntegrations = (options: SentryOptions): string => { } if ( + // eslint-disable-next-line deprecation/deprecation options.replaysSessionSampleRate == null || + // eslint-disable-next-line deprecation/deprecation options.replaysSessionSampleRate || + // eslint-disable-next-line deprecation/deprecation options.replaysOnErrorSampleRate == null || + // eslint-disable-next-line deprecation/deprecation options.replaysOnErrorSampleRate ) { integrations.push('Sentry.replayIntegration()'); diff --git a/packages/astro/src/integration/types.ts b/packages/astro/src/integration/types.ts index ede2f49ff732..b32b62556140 100644 --- a/packages/astro/src/integration/types.ts +++ b/packages/astro/src/integration/types.ts @@ -1,5 +1,5 @@ import type { BrowserOptions } from '@sentry/browser'; -import type { Options } from '@sentry/types'; +import type { Options } from '@sentry/core'; type SdkInitPaths = { /** @@ -150,6 +150,7 @@ type SdkEnabledOptions = { * Sentry code will be added to your bundle. * * @default true - the SDK is enabled by default for both, client and server. + * */ enabled?: | boolean @@ -159,6 +160,41 @@ type SdkEnabledOptions = { }; }; +type DeprecatedRuntimeOptions = Pick< + Options, + 'environment' | 'release' | 'dsn' | 'debug' | 'sampleRate' | 'tracesSampleRate' +> & + Pick & { + /** + * @deprecated Use the `environment` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead. + */ + environment?: string; + /** + * @deprecated Use the `release` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead. + */ + release?: string; + /** + * @deprecated Use the `dsn` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead. + */ + dsn?: string; + /** + * @deprecated Use the `sampleRate` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead. + */ + sampleRate?: number; + /** + * @deprecated Use the `tracesSampleRate` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead. + */ + tracesSampleRate?: number; + /** + * @deprecated Use the `replaysSessionSampleRate` option in your Sentry.init() call in sentry.client.config.(js|ts) instead. + */ + replaysSessionSampleRate?: number; + /** + * @deprecated Use the `replaysOnErrorSampleRate` option in your Sentry.init() call in sentry.client.config.(js|ts) instead. + */ + replaysOnErrorSampleRate?: number; + }; + /** * A subset of Sentry SDK options that can be set via the `sentryAstro` integration. * Some options (e.g. integrations) are set by default and cannot be changed here. @@ -169,8 +205,7 @@ type SdkEnabledOptions = { * If you specify a dedicated init file, the SDK options passed to `sentryAstro` will be ignored. */ export type SentryOptions = SdkInitPaths & - Pick & - Pick & + DeprecatedRuntimeOptions & InstrumentationOptions & SdkEnabledOptions & { /** @@ -187,4 +222,8 @@ export type SentryOptions = SdkInitPaths & * Do not define them in the `sentry.client.config.(js|ts)` or `sentry.server.config.(js|ts)` files. */ bundleSizeOptimizations?: BundleSizeOptimizationOptions; + /** + * If enabled, prints debug logs during the build process. + */ + debug?: boolean; }; diff --git a/packages/astro/src/server/middleware.ts b/packages/astro/src/server/middleware.ts index 781a5a75b7a9..de381de9d5ed 100644 --- a/packages/astro/src/server/middleware.ts +++ b/packages/astro/src/server/middleware.ts @@ -7,6 +7,7 @@ import { vercelWaitUntil, winterCGRequestToRequestData, } from '@sentry/core'; +import type { RequestEventData, Scope, SpanAttributes } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, @@ -21,7 +22,6 @@ import { startSpan, withIsolationScope, } from '@sentry/node'; -import type { RequestEventData, Scope, SpanAttributes } from '@sentry/types'; import type { APIContext, MiddlewareResponseHandler } from 'astro'; type MiddlewareOptions = { @@ -155,49 +155,50 @@ async function instrumentRequest( op: 'http.server', }, async span => { - const originalResponse = await next(); - - if (originalResponse.status) { - setHttpStatus(span, originalResponse.status); - } - - const client = getClient(); - const contentType = originalResponse.headers.get('content-type'); - - const isPageloadRequest = contentType && contentType.startsWith('text/html'); - if (!isPageloadRequest || !client) { - return originalResponse; - } - - // Type case necessary b/c the body's ReadableStream type doesn't include - // the async iterator that is actually available in Node - // We later on use the async iterator to read the body chunks - // see https://github.com/microsoft/TypeScript/issues/39051 - const originalBody = originalResponse.body as NodeJS.ReadableStream | null; - if (!originalBody) { - return originalResponse; + try { + const originalResponse = await next(); + if (originalResponse.status) { + setHttpStatus(span, originalResponse.status); + } + + const client = getClient(); + const contentType = originalResponse.headers.get('content-type'); + + const isPageloadRequest = contentType && contentType.startsWith('text/html'); + if (!isPageloadRequest || !client) { + return originalResponse; + } + + // Type case necessary b/c the body's ReadableStream type doesn't include + // the async iterator that is actually available in Node + // We later on use the async iterator to read the body chunks + // see https://github.com/microsoft/TypeScript/issues/39051 + const originalBody = originalResponse.body as NodeJS.ReadableStream | null; + if (!originalBody) { + return originalResponse; + } + + const decoder = new TextDecoder(); + + const newResponseStream = new ReadableStream({ + start: async controller => { + for await (const chunk of originalBody) { + const html = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true }); + const modifiedHtml = addMetaTagToHead(html); + controller.enqueue(new TextEncoder().encode(modifiedHtml)); + } + controller.close(); + }, + }); + + return new Response(newResponseStream, originalResponse); + } catch (e) { + sendErrorToSentry(e); + throw e; } - - const decoder = new TextDecoder(); - - const newResponseStream = new ReadableStream({ - start: async controller => { - for await (const chunk of originalBody) { - const html = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true }); - const modifiedHtml = addMetaTagToHead(html); - controller.enqueue(new TextEncoder().encode(modifiedHtml)); - } - controller.close(); - }, - }); - - return new Response(newResponseStream, originalResponse); }, ); return res; - } catch (e) { - sendErrorToSentry(e); - throw e; } finally { vercelWaitUntil( (async () => { diff --git a/packages/astro/test/server/middleware.test.ts b/packages/astro/test/server/middleware.test.ts index 87fcb611eab2..eff473d4401f 100644 --- a/packages/astro/test/server/middleware.test.ts +++ b/packages/astro/test/server/middleware.test.ts @@ -1,7 +1,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import * as SentryCore from '@sentry/core'; +import type { Client, Span } from '@sentry/core'; import * as SentryNode from '@sentry/node'; -import type { Client, Span } from '@sentry/types'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { handleRequest, interpolateRouteFromUrlAndParams } from '../../src/server/middleware'; diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index c6d231e12821..8aa8ef5cb6f9 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/aws-serverless", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for AWS Lambda and AWS Serverless Environments", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/serverless", @@ -64,11 +64,11 @@ "access": "public" }, "dependencies": { + "@opentelemetry/instrumentation": "^0.54.0", "@opentelemetry/instrumentation-aws-lambda": "0.44.0", "@opentelemetry/instrumentation-aws-sdk": "0.45.0", - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", "@types/aws-lambda": "^8.10.62" }, "devDependencies": { diff --git a/packages/aws-serverless/src/index.ts b/packages/aws-serverless/src/index.ts index 369e8824a3b9..6063c0c2f93d 100644 --- a/packages/aws-serverless/src/index.ts +++ b/packages/aws-serverless/src/index.ts @@ -120,6 +120,7 @@ export { spanToTraceHeader, spanToBaggageHeader, trpcMiddleware, + // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, zodErrorsIntegration, profiler, diff --git a/packages/aws-serverless/src/integration/aws.ts b/packages/aws-serverless/src/integration/aws.ts index bfbe16bac16c..f08513e1a342 100644 --- a/packages/aws-serverless/src/integration/aws.ts +++ b/packages/aws-serverless/src/integration/aws.ts @@ -1,24 +1,23 @@ +import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { AwsInstrumentation } from '@opentelemetry/instrumentation-aws-sdk'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration } from '@sentry/core'; -import { addOpenTelemetryInstrumentation } from '@sentry/node'; -import type { IntegrationFn } from '@sentry/types'; -const _awsIntegration = (() => { +/** + * Instrumentation for aws-sdk package + */ +export const awsIntegration = defineIntegration(() => { return { name: 'Aws', setupOnce() { - addOpenTelemetryInstrumentation( - new AwsInstrumentation({ - preRequestHook(span) { - span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.otel.aws'); - }, - }), - ); + registerInstrumentations({ + instrumentations: [ + new AwsInstrumentation({ + preRequestHook(span) { + span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.otel.aws'); + }, + }), + ], + }); }, }; -}) satisfies IntegrationFn; - -/** - * Instrumentation for aws-sdk package - */ -export const awsIntegration = defineIntegration(_awsIntegration); +}); diff --git a/packages/aws-serverless/src/integration/awslambda.ts b/packages/aws-serverless/src/integration/awslambda.ts index 2e1479914471..61776daed18c 100644 --- a/packages/aws-serverless/src/integration/awslambda.ts +++ b/packages/aws-serverless/src/integration/awslambda.ts @@ -1,7 +1,7 @@ import { AwsLambdaInstrumentation } from '@opentelemetry/instrumentation-aws-lambda'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration } from '@sentry/core'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '@sentry/node'; -import type { IntegrationFn } from '@sentry/types'; import { eventContextExtractor } from '../utils'; interface AwsLambdaOptions { diff --git a/packages/aws-serverless/src/sdk.ts b/packages/aws-serverless/src/sdk.ts index 68522927b0a9..c9bd6ae6834d 100644 --- a/packages/aws-serverless/src/sdk.ts +++ b/packages/aws-serverless/src/sdk.ts @@ -2,7 +2,8 @@ import { existsSync } from 'fs'; import { hostname } from 'os'; import { basename, resolve } from 'path'; import { types } from 'util'; -import { logger } from '@sentry/core'; +import type { Integration, Options, Scope, SdkMetadata, Span } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, logger } from '@sentry/core'; import type { NodeClient, NodeOptions } from '@sentry/node'; import { SDK_VERSION, @@ -16,12 +17,8 @@ import { startSpanManual, withScope, } from '@sentry/node'; -import type { Integration, Options, Scope, SdkMetadata, Span } from '@sentry/types'; import type { Context, Handler } from 'aws-lambda'; import { performance } from 'perf_hooks'; - -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; - import { DEBUG_BUILD } from './debug-build'; import { awsIntegration } from './integration/aws'; import { awsLambdaIntegration } from './integration/awslambda'; diff --git a/packages/aws-serverless/src/utils.ts b/packages/aws-serverless/src/utils.ts index b8a3e69dc0a9..e330fb01dc13 100644 --- a/packages/aws-serverless/src/utils.ts +++ b/packages/aws-serverless/src/utils.ts @@ -2,7 +2,7 @@ import type { TextMapGetter } from '@opentelemetry/api'; import type { Context as OtelContext } from '@opentelemetry/api'; import { context as otelContext, propagation } from '@opentelemetry/api'; import { addExceptionMechanism, isString } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; import type { Handler } from 'aws-lambda'; import type { APIGatewayProxyEventHeaders } from 'aws-lambda'; diff --git a/packages/aws-serverless/test/sdk.test.ts b/packages/aws-serverless/test/sdk.test.ts index 4f5daf3b94a9..7ab59670cdf2 100644 --- a/packages/aws-serverless/test/sdk.test.ts +++ b/packages/aws-serverless/test/sdk.test.ts @@ -1,6 +1,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import type { Callback, Handler } from 'aws-lambda'; import { init, wrapHandler } from '../src/sdk'; diff --git a/packages/browser-utils/package.json b/packages/browser-utils/package.json index 0ea618225e51..44918217aad7 100644 --- a/packages/browser-utils/package.json +++ b/packages/browser-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-utils", - "version": "8.40.0", + "version": "8.42.0", "description": "Browser Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser-utils", @@ -39,8 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/browser-utils/src/instrument/dom.ts b/packages/browser-utils/src/instrument/dom.ts index 7ae8b0d04441..633c29b45376 100644 --- a/packages/browser-utils/src/instrument/dom.ts +++ b/packages/browser-utils/src/instrument/dom.ts @@ -1,5 +1,4 @@ -import type { HandlerDataDom } from '@sentry/types'; - +import type { HandlerDataDom } from '@sentry/core'; import { addHandler, addNonEnumerableProperty, fill, maybeInstrument, triggerHandlers, uuid4 } from '@sentry/core'; import { WINDOW } from '../types'; @@ -64,24 +63,21 @@ export function instrumentDOM(): void { // could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still // guaranteed to fire at least once.) ['EventTarget', 'Node'].forEach((target: string) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - const proto = (WINDOW as any)[target] && (WINDOW as any)[target].prototype; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins + const globalObject = WINDOW as unknown as Record; + const targetObj = globalObject[target]; + const proto = targetObj && targetObj.prototype; + + // eslint-disable-next-line no-prototype-builtins if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) { return; } fill(proto, 'addEventListener', function (originalAddEventListener: AddEventListener): AddEventListener { - return function ( - this: Element, - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | AddEventListenerOptions, - ): AddEventListener { + return function (this: InstrumentedElement, type, listener, options): AddEventListener { if (type === 'click' || type == 'keypress') { try { - const el = this as InstrumentedElement; - const handlers = (el.__sentry_instrumentation_handlers__ = el.__sentry_instrumentation_handlers__ || {}); + const handlers = (this.__sentry_instrumentation_handlers__ = + this.__sentry_instrumentation_handlers__ || {}); const handlerForType = (handlers[type] = handlers[type] || { refCount: 0 }); if (!handlerForType.handler) { @@ -105,16 +101,10 @@ export function instrumentDOM(): void { proto, 'removeEventListener', function (originalRemoveEventListener: RemoveEventListener): RemoveEventListener { - return function ( - this: Element, - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | EventListenerOptions, - ): () => void { + return function (this: InstrumentedElement, type, listener, options): () => void { if (type === 'click' || type == 'keypress') { try { - const el = this as InstrumentedElement; - const handlers = el.__sentry_instrumentation_handlers__ || {}; + const handlers = this.__sentry_instrumentation_handlers__ || {}; const handlerForType = handlers[type]; if (handlerForType) { @@ -128,7 +118,7 @@ export function instrumentDOM(): void { // If there are no longer any custom handlers of any type on this element, cleanup everything. if (Object.keys(handlers).length === 0) { - delete el.__sentry_instrumentation_handlers__; + delete this.__sentry_instrumentation_handlers__; } } } catch (e) { diff --git a/packages/browser-utils/src/instrument/history.ts b/packages/browser-utils/src/instrument/history.ts index be74cde68871..0a166c6fe111 100644 --- a/packages/browser-utils/src/instrument/history.ts +++ b/packages/browser-utils/src/instrument/history.ts @@ -1,5 +1,5 @@ import { addHandler, fill, maybeInstrument, supportsHistory, triggerHandlers } from '@sentry/core'; -import type { HandlerDataHistory } from '@sentry/types'; +import type { HandlerDataHistory } from '@sentry/core'; import { WINDOW } from '../types'; let lastHref: string | undefined; diff --git a/packages/browser-utils/src/instrument/xhr.ts b/packages/browser-utils/src/instrument/xhr.ts index e97b7e54be60..506cc59a7bbf 100644 --- a/packages/browser-utils/src/instrument/xhr.ts +++ b/packages/browser-utils/src/instrument/xhr.ts @@ -1,5 +1,4 @@ -import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/types'; - +import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/core'; import { addHandler, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/core'; import { WINDOW } from '../types'; diff --git a/packages/browser-utils/src/metrics/browserMetrics.ts b/packages/browser-utils/src/metrics/browserMetrics.ts index d64bba34509a..a3200abdeeaa 100644 --- a/packages/browser-utils/src/metrics/browserMetrics.ts +++ b/packages/browser-utils/src/metrics/browserMetrics.ts @@ -1,11 +1,15 @@ /* eslint-disable max-lines */ -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getActiveSpan } from '@sentry/core'; -import { setMeasurement } from '@sentry/core'; -import { browserPerformanceTimeOrigin, getComponentName, htmlTreeAsString, logger, parseUrl } from '@sentry/core'; -import type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/types'; - -import { spanToJSON } from '@sentry/core'; -import { DEBUG_BUILD } from '../debug-build'; +import type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + browserPerformanceTimeOrigin, + getActiveSpan, + getComponentName, + htmlTreeAsString, + parseUrl, + setMeasurement, + spanToJSON, +} from '@sentry/core'; import { WINDOW } from '../types'; import { trackClsAsStandaloneSpan } from './cls'; import { @@ -229,7 +233,7 @@ export function startTrackingInteractions(): void { }); } -export { startTrackingINP, registerInpInteractionListener } from './inp'; +export { registerInpInteractionListener, startTrackingINP } from './inp'; /** * Starts tracking the Cumulative Layout Shift on the current page and collects the value and last entry @@ -241,7 +245,6 @@ function _trackCLS(): () => void { if (!entry) { return; } - DEBUG_BUILD && logger.log(`[Measurements] Adding CLS ${metric.value}`); _measurements['cls'] = { value: metric.value, unit: '' }; _clsEntry = entry; }, true); @@ -255,7 +258,6 @@ function _trackLCP(): () => void { return; } - DEBUG_BUILD && logger.log('[Measurements] Adding LCP'); _measurements['lcp'] = { value: metric.value, unit: 'millisecond' }; _lcpEntry = entry as LargestContentfulPaint; }, true); @@ -271,7 +273,6 @@ function _trackFID(): () => void { const timeOrigin = msToSec(browserPerformanceTimeOrigin as number); const startTime = msToSec(entry.startTime); - DEBUG_BUILD && logger.log('[Measurements] Adding FID'); _measurements['fid'] = { value: metric.value, unit: 'millisecond' }; _measurements['mark.fid'] = { value: timeOrigin + startTime, unit: 'second' }; }); @@ -284,7 +285,6 @@ function _trackTtfb(): () => void { return; } - DEBUG_BUILD && logger.log('[Measurements] Adding TTFB'); _measurements['ttfb'] = { value: metric.value, unit: 'millisecond' }; }); } @@ -305,7 +305,6 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries return; } - DEBUG_BUILD && logger.log('[Tracing] Adding & adjusting spans using Performance API'); const timeOrigin = msToSec(browserPerformanceTimeOrigin); const performanceEntries = performance.getEntries(); @@ -343,11 +342,9 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries const shouldRecord = entry.startTime < firstHidden.firstHiddenTime; if (entry.name === 'first-paint' && shouldRecord) { - DEBUG_BUILD && logger.log('[Measurements] Adding FP'); _measurements['fp'] = { value: entry.startTime, unit: 'millisecond' }; } if (entry.name === 'first-contentful-paint' && shouldRecord) { - DEBUG_BUILD && logger.log('[Measurements] Adding FCP'); _measurements['fcp'] = { value: entry.startTime, unit: 'millisecond' }; } break; @@ -423,7 +420,7 @@ export function _addMeasureSpans( duration: number, timeOrigin: number, ): number { - const navEntry = getNavigationEntry(); + const navEntry = getNavigationEntry(false); const requestTime = msToSec(navEntry ? navEntry.requestStart : 0); // Because performance.measure accepts arbitrary timestamps it can produce // spans that happen before the browser even makes a request for the page. @@ -618,8 +615,6 @@ function _trackNavigator(span: Span): void { /** Add LCP / CLS data to span to allow debugging */ function _setWebVitalAttributes(span: Span): void { if (_lcpEntry) { - DEBUG_BUILD && logger.log('[Measurements] Adding LCP Data'); - // Capture Properties of the LCP element that contributes to the LCP. if (_lcpEntry.element) { @@ -652,7 +647,6 @@ function _setWebVitalAttributes(span: Span): void { // See: https://developer.mozilla.org/en-US/docs/Web/API/LayoutShift if (_clsEntry && _clsEntry.sources) { - DEBUG_BUILD && logger.log('[Measurements] Adding CLS Data'); _clsEntry.sources.forEach((source, index) => span.setAttribute(`cls.source.${index + 1}`, htmlTreeAsString(source.node)), ); @@ -677,7 +671,7 @@ function setResourceEntrySizeData( * ttfb information is added via vendored web vitals library. */ function _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void { - const navEntry = getNavigationEntry(); + const navEntry = getNavigationEntry(false); if (!navEntry) { return; } @@ -685,7 +679,6 @@ function _addTtfbRequestTimeToMeasurements(_measurements: Measurements): void { const { responseStart, requestStart } = navEntry; if (requestStart <= responseStart) { - DEBUG_BUILD && logger.log('[Measurements] Adding TTFB Request Time'); _measurements['ttfb.requestTime'] = { value: responseStart - requestStart, unit: 'millisecond', diff --git a/packages/browser-utils/src/metrics/cls.ts b/packages/browser-utils/src/metrics/cls.ts index 05d2f934eb8c..43ff84c01965 100644 --- a/packages/browser-utils/src/metrics/cls.ts +++ b/packages/browser-utils/src/metrics/cls.ts @@ -11,7 +11,7 @@ import { spanToJSON, } from '@sentry/core'; import { browserPerformanceTimeOrigin, dropUndefinedKeys, htmlTreeAsString, logger } from '@sentry/core'; -import type { SpanAttributes } from '@sentry/types'; +import type { SpanAttributes } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import { addClsInstrumentationHandler } from './instrument'; import { msToSec, startStandaloneWebVitalSpan } from './utils'; diff --git a/packages/browser-utils/src/metrics/inp.ts b/packages/browser-utils/src/metrics/inp.ts index 4e90c89619d9..7ef99b4d32fd 100644 --- a/packages/browser-utils/src/metrics/inp.ts +++ b/packages/browser-utils/src/metrics/inp.ts @@ -1,16 +1,18 @@ +import type { Span, SpanAttributes } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + browserPerformanceTimeOrigin, + dropUndefinedKeys, getActiveSpan, getCurrentScope, getRootSpan, + htmlTreeAsString, spanToJSON, } from '@sentry/core'; -import { browserPerformanceTimeOrigin, dropUndefinedKeys, htmlTreeAsString } from '@sentry/core'; -import type { Span, SpanAttributes } from '@sentry/types'; import { addInpInstrumentationHandler, addPerformanceInstrumentationHandler, diff --git a/packages/browser-utils/src/metrics/utils.ts b/packages/browser-utils/src/metrics/utils.ts index 70327aeca838..b6bc9fc54f2f 100644 --- a/packages/browser-utils/src/metrics/utils.ts +++ b/packages/browser-utils/src/metrics/utils.ts @@ -1,6 +1,5 @@ -import type { SentrySpan } from '@sentry/core'; +import type { Integration, SentrySpan, Span, SpanAttributes, SpanTimeInput, StartSpanOptions } from '@sentry/core'; import { getClient, getCurrentScope, spanToJSON, startInactiveSpan, withActiveSpan } from '@sentry/core'; -import type { Integration, Span, SpanAttributes, SpanTimeInput, StartSpanOptions } from '@sentry/types'; import { WINDOW } from '../types'; /** diff --git a/packages/browser-utils/src/metrics/web-vitals/README.md b/packages/browser-utils/src/metrics/web-vitals/README.md index d779969dbe5d..c4b2b1a1c0cf 100644 --- a/packages/browser-utils/src/metrics/web-vitals/README.md +++ b/packages/browser-utils/src/metrics/web-vitals/README.md @@ -5,7 +5,7 @@ This was vendored from: https://github.com/GoogleChrome/web-vitals: v3.5.2 The commit SHA used is: -[7b44bea0d5ba6629c5fd34c3a09cc683077871d0](https://github.com/GoogleChrome/web-vitals/tree/7b44bea0d5ba6629c5fd34c3a09cc683077871d0) +[3d2b3dc8576cc003618952fa39902fab764a53e2](https://github.com/GoogleChrome/web-vitals/tree/3d2b3dc8576cc003618952fa39902fab764a53e2) Current vendored web vitals are: @@ -27,6 +27,14 @@ web-vitals only report once per pageload. ## CHANGELOG +https://github.com/getsentry/sentry-javascript/pull/14439 + +- Bumped from Web Vitals v3.5.2 to v4.2.4 + +https://github.com/getsentry/sentry-javascript/pull/11391 + +- Bumped from Web Vitals v3.0.4 to v3.5.2 + https://github.com/getsentry/sentry-javascript/pull/5987 - Bumped from Web Vitals v2.1.0 to v3.0.4 diff --git a/packages/browser-utils/src/metrics/web-vitals/getCLS.ts b/packages/browser-utils/src/metrics/web-vitals/getCLS.ts index 380cf2e54d47..a9b6f9f26999 100644 --- a/packages/browser-utils/src/metrics/web-vitals/getCLS.ts +++ b/packages/browser-utils/src/metrics/web-vitals/getCLS.ts @@ -20,7 +20,7 @@ import { observe } from './lib/observe'; import { onHidden } from './lib/onHidden'; import { runOnce } from './lib/runOnce'; import { onFCP } from './onFCP'; -import type { CLSMetric, CLSReportCallback, MetricRatingThresholds, ReportOpts } from './types'; +import type { CLSMetric, MetricRatingThresholds, ReportOpts } from './types'; /** Thresholds for CLS. See https://web.dev/articles/cls#what_is_a_good_cls_score */ export const CLSThresholds: MetricRatingThresholds = [0.1, 0.25]; @@ -46,7 +46,7 @@ export const CLSThresholds: MetricRatingThresholds = [0.1, 0.25]; * hidden. As a result, the `callback` function might be called multiple times * during the same page load._ */ -export const onCLS = (onReport: CLSReportCallback, opts: ReportOpts = {}): void => { +export const onCLS = (onReport: (metric: CLSMetric) => void, opts: ReportOpts = {}) => { // Start monitoring FCP so we can only report CLS if FCP is also reported. // Note: this is done to match the current behavior of CrUX. onFCP( @@ -57,7 +57,7 @@ export const onCLS = (onReport: CLSReportCallback, opts: ReportOpts = {}): void let sessionValue = 0; let sessionEntries: LayoutShift[] = []; - const handleEntries = (entries: LayoutShift[]): void => { + const handleEntries = (entries: LayoutShift[]) => { entries.forEach(entry => { // Only count layout shifts without recent user input. if (!entry.hadRecentInput) { diff --git a/packages/browser-utils/src/metrics/web-vitals/getFID.ts b/packages/browser-utils/src/metrics/web-vitals/getFID.ts index 92543b89e170..e8fd4fa908e7 100644 --- a/packages/browser-utils/src/metrics/web-vitals/getFID.ts +++ b/packages/browser-utils/src/metrics/web-vitals/getFID.ts @@ -21,7 +21,7 @@ import { observe } from './lib/observe'; import { onHidden } from './lib/onHidden'; import { runOnce } from './lib/runOnce'; import { whenActivated } from './lib/whenActivated'; -import type { FIDMetric, FIDReportCallback, MetricRatingThresholds, ReportOpts } from './types'; +import type { FIDMetric, MetricRatingThresholds, ReportOpts } from './types'; /** Thresholds for FID. See https://web.dev/articles/fid#what_is_a_good_fid_score */ export const FIDThresholds: MetricRatingThresholds = [100, 300]; @@ -35,7 +35,7 @@ export const FIDThresholds: MetricRatingThresholds = [100, 300]; * _**Important:** since FID is only reported after the user interacts with the * page, it's possible that it will not be reported for some page loads._ */ -export const onFID = (onReport: FIDReportCallback, opts: ReportOpts = {}) => { +export const onFID = (onReport: (metric: FIDMetric) => void, opts: ReportOpts = {}) => { whenActivated(() => { const visibilityWatcher = getVisibilityWatcher(); const metric = initMetric('FID'); @@ -56,6 +56,7 @@ export const onFID = (onReport: FIDReportCallback, opts: ReportOpts = {}) => { }; const po = observe('first-input', handleEntries); + report = bindReporter(onReport, metric, FIDThresholds, opts.reportAllChanges); if (po) { diff --git a/packages/browser-utils/src/metrics/web-vitals/getINP.ts b/packages/browser-utils/src/metrics/web-vitals/getINP.ts index e66f17eed2a1..ba6234e43c18 100644 --- a/packages/browser-utils/src/metrics/web-vitals/getINP.ts +++ b/packages/browser-utils/src/metrics/web-vitals/getINP.ts @@ -17,100 +17,18 @@ import { WINDOW } from '../../types'; import { bindReporter } from './lib/bindReporter'; import { initMetric } from './lib/initMetric'; +import { DEFAULT_DURATION_THRESHOLD, estimateP98LongestInteraction, processInteractionEntry } from './lib/interactions'; import { observe } from './lib/observe'; import { onHidden } from './lib/onHidden'; -import { getInteractionCount, initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill'; +import { initInteractionCountPolyfill } from './lib/polyfills/interactionCountPolyfill'; import { whenActivated } from './lib/whenActivated'; -import type { INPMetric, INPReportCallback, MetricRatingThresholds, ReportOpts } from './types'; +import { whenIdle } from './lib/whenIdle'; -interface Interaction { - id: number; - latency: number; - entries: PerformanceEventTiming[]; -} +import type { INPMetric, MetricRatingThresholds, ReportOpts } from './types'; /** Thresholds for INP. See https://web.dev/articles/inp#what_is_a_good_inp_score */ export const INPThresholds: MetricRatingThresholds = [200, 500]; -// Used to store the interaction count after a bfcache restore, since p98 -// interaction latencies should only consider the current navigation. -const prevInteractionCount = 0; - -/** - * Returns the interaction count since the last bfcache restore (or for the - * full page lifecycle if there were no bfcache restores). - */ -const getInteractionCountForNavigation = () => { - return getInteractionCount() - prevInteractionCount; -}; - -// To prevent unnecessary memory usage on pages with lots of interactions, -// store at most 10 of the longest interactions to consider as INP candidates. -const MAX_INTERACTIONS_TO_CONSIDER = 10; - -// A list of longest interactions on the page (by latency) sorted so the -// longest one is first. The list is as most MAX_INTERACTIONS_TO_CONSIDER long. -const longestInteractionList: Interaction[] = []; - -// A mapping of longest interactions by their interaction ID. -// This is used for faster lookup. -const longestInteractionMap: { [interactionId: string]: Interaction } = {}; - -/** - * Takes a performance entry and adds it to the list of worst interactions - * if its duration is long enough to make it among the worst. If the - * entry is part of an existing interaction, it is merged and the latency - * and entries list is updated as needed. - */ -const processEntry = (entry: PerformanceEventTiming) => { - // The least-long of the 10 longest interactions. - const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1]; - - const existingInteraction = longestInteractionMap[entry.interactionId!]; - - // Only process the entry if it's possibly one of the ten longest, - // or if it's part of an existing interaction. - if ( - existingInteraction || - longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER || - (minLongestInteraction && entry.duration > minLongestInteraction.latency) - ) { - // If the interaction already exists, update it. Otherwise create one. - if (existingInteraction) { - existingInteraction.entries.push(entry); - existingInteraction.latency = Math.max(existingInteraction.latency, entry.duration); - } else { - const interaction = { - id: entry.interactionId!, - latency: entry.duration, - entries: [entry], - }; - longestInteractionMap[interaction.id] = interaction; - longestInteractionList.push(interaction); - } - - // Sort the entries by latency (descending) and keep only the top ten. - longestInteractionList.sort((a, b) => b.latency - a.latency); - longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i => { - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete - delete longestInteractionMap[i.id]; - }); - } -}; - -/** - * Returns the estimated p98 longest interaction based on the stored - * interaction candidates and the interaction count for the current page. - */ -const estimateP98LongestInteraction = () => { - const candidateInteractionIndex = Math.min( - longestInteractionList.length - 1, - Math.floor(getInteractionCountForNavigation() / 50), - ); - - return longestInteractionList[candidateInteractionIndex]; -}; - /** * Calculates the [INP](https://web.dev/articles/inp) value for the current * page and calls the `callback` function once the value is ready, along with @@ -138,7 +56,12 @@ const estimateP98LongestInteraction = () => { * hidden. As a result, the `callback` function might be called multiple times * during the same page load._ */ -export const onINP = (onReport: INPReportCallback, opts: ReportOpts = {}) => { +export const onINP = (onReport: (metric: INPMetric) => void, opts: ReportOpts = {}) => { + // Return if the browser doesn't support all APIs needed to measure INP. + if (!('PerformanceEventTiming' in WINDOW && 'interactionId' in PerformanceEventTiming.prototype)) { + return; + } + whenActivated(() => { // TODO(philipwalton): remove once the polyfill is no longer needed. initInteractionCountPolyfill(); @@ -148,37 +71,23 @@ export const onINP = (onReport: INPReportCallback, opts: ReportOpts = {}) => { let report: ReturnType; const handleEntries = (entries: INPMetric['entries']) => { - entries.forEach(entry => { - if (entry.interactionId) { - processEntry(entry); - } - - // Entries of type `first-input` don't currently have an `interactionId`, - // so to consider them in INP we have to first check that an existing - // entry doesn't match the `duration` and `startTime`. - // Note that this logic assumes that `event` entries are dispatched - // before `first-input` entries. This is true in Chrome (the only browser - // that currently supports INP). - // TODO(philipwalton): remove once crbug.com/1325826 is fixed. - if (entry.entryType === 'first-input') { - const noMatchingEntry = !longestInteractionList.some(interaction => { - return interaction.entries.some(prevEntry => { - return entry.duration === prevEntry.duration && entry.startTime === prevEntry.startTime; - }); - }); - if (noMatchingEntry) { - processEntry(entry); - } + // Queue the `handleEntries()` callback in the next idle task. + // This is needed to increase the chances that all event entries that + // occurred between the user interaction and the next paint + // have been dispatched. Note: there is currently an experiment + // running in Chrome (EventTimingKeypressAndCompositionInteractionId) + // 123+ that if rolled out fully may make this no longer necessary. + whenIdle(() => { + entries.forEach(processInteractionEntry); + + const inp = estimateP98LongestInteraction(); + + if (inp && inp.latency !== metric.value) { + metric.value = inp.latency; + metric.entries = inp.entries; + report(); } }); - - const inp = estimateP98LongestInteraction(); - - if (inp && inp.latency !== metric.value) { - metric.value = inp.latency; - metric.entries = inp.entries; - report(); - } }; const po = observe('event', handleEntries, { @@ -188,29 +97,18 @@ export const onINP = (onReport: INPReportCallback, opts: ReportOpts = {}) => { // and performance. Running this callback for any interaction that spans // just one or two frames is likely not worth the insight that could be // gained. - durationThreshold: opts.durationThreshold != null ? opts.durationThreshold : 40, - } as PerformanceObserverInit); + durationThreshold: opts.durationThreshold != null ? opts.durationThreshold : DEFAULT_DURATION_THRESHOLD, + }); report = bindReporter(onReport, metric, INPThresholds, opts.reportAllChanges); if (po) { - // If browser supports interactionId (and so supports INP), also - // observe entries of type `first-input`. This is useful in cases + // Also observe entries of type `first-input`. This is useful in cases // where the first interaction is less than the `durationThreshold`. - if ('PerformanceEventTiming' in WINDOW && 'interactionId' in PerformanceEventTiming.prototype) { - po.observe({ type: 'first-input', buffered: true }); - } + po.observe({ type: 'first-input', buffered: true }); onHidden(() => { handleEntries(po.takeRecords() as INPMetric['entries']); - - // If the interaction count shows that there were interactions but - // none were captured by the PerformanceObserver, report a latency of 0. - if (metric.value < 0 && getInteractionCountForNavigation() > 0) { - metric.value = 0; - metric.entries = []; - } - report(true); }); } diff --git a/packages/browser-utils/src/metrics/web-vitals/getLCP.ts b/packages/browser-utils/src/metrics/web-vitals/getLCP.ts index b50358c98d61..17fd374e7611 100644 --- a/packages/browser-utils/src/metrics/web-vitals/getLCP.ts +++ b/packages/browser-utils/src/metrics/web-vitals/getLCP.ts @@ -23,7 +23,8 @@ import { observe } from './lib/observe'; import { onHidden } from './lib/onHidden'; import { runOnce } from './lib/runOnce'; import { whenActivated } from './lib/whenActivated'; -import type { LCPMetric, LCPReportCallback, MetricRatingThresholds, ReportOpts } from './types'; +import { whenIdle } from './lib/whenIdle'; +import type { LCPMetric, MetricRatingThresholds, ReportOpts } from './types'; /** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */ export const LCPThresholds: MetricRatingThresholds = [2500, 4000]; @@ -41,28 +42,34 @@ const reportedMetricIDs: Record = {}; * performance entry is dispatched, or once the final value of the metric has * been determined. */ -export const onLCP = (onReport: LCPReportCallback, opts: ReportOpts = {}) => { +export const onLCP = (onReport: (metric: LCPMetric) => void, opts: ReportOpts = {}) => { whenActivated(() => { const visibilityWatcher = getVisibilityWatcher(); const metric = initMetric('LCP'); let report: ReturnType; const handleEntries = (entries: LCPMetric['entries']) => { - const lastEntry = entries[entries.length - 1] as LargestContentfulPaint; - if (lastEntry) { + // If reportAllChanges is set then call this function for each entry, + // otherwise only consider the last one. + if (!opts.reportAllChanges) { + // eslint-disable-next-line no-param-reassign + entries = entries.slice(-1); + } + + entries.forEach(entry => { // Only report if the page wasn't hidden prior to LCP. - if (lastEntry.startTime < visibilityWatcher.firstHiddenTime) { + if (entry.startTime < visibilityWatcher.firstHiddenTime) { // The startTime attribute returns the value of the renderTime if it is // not 0, and the value of the loadTime otherwise. The activationStart // reference is used because LCP should be relative to page activation - // rather than navigation start if the page was prerendered. But in cases + // rather than navigation start if the page was pre-rendered. But in cases // where `activationStart` occurs after the LCP, this time should be // clamped at 0. - metric.value = Math.max(lastEntry.startTime - getActivationStart(), 0); - metric.entries = [lastEntry]; + metric.value = Math.max(entry.startTime - getActivationStart(), 0); + metric.entries = [entry]; report(); } - } + }); }; const po = observe('largest-contentful-paint', handleEntries); @@ -83,11 +90,14 @@ export const onLCP = (onReport: LCPReportCallback, opts: ReportOpts = {}) => { // stops LCP observation, it's unreliable since it can be programmatically // generated. See: https://github.com/GoogleChrome/web-vitals/issues/75 ['keydown', 'click'].forEach(type => { + // Wrap in a setTimeout so the callback is run in a separate task + // to avoid extending the keyboard/click handler to reduce INP impact + // https://github.com/GoogleChrome/web-vitals/issues/383 if (WINDOW.document) { - // Wrap in a setTimeout so the callback is run in a separate task - // to avoid extending the keyboard/click handler to reduce INP impact - // https://github.com/GoogleChrome/web-vitals/issues/383 - addEventListener(type, () => setTimeout(stopListening, 0), true); + addEventListener(type, () => whenIdle(stopListening as () => void), { + once: true, + capture: true, + }); } }); diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/generateUniqueID.ts b/packages/browser-utils/src/metrics/web-vitals/lib/generateUniqueID.ts index bdecdc6220ad..637d01398e0a 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/generateUniqueID.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/generateUniqueID.ts @@ -20,5 +20,5 @@ * @return {string} */ export const generateUniqueID = () => { - return `v3-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`; + return `v4-${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`; }; diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts b/packages/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts index 63cfa04b3ad4..1e8521c2ddc6 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts @@ -15,8 +15,25 @@ */ import { WINDOW } from '../../../types'; -import type { NavigationTimingPolyfillEntry } from '../types'; -export const getNavigationEntry = (): PerformanceNavigationTiming | NavigationTimingPolyfillEntry | undefined => { - return WINDOW.performance && performance.getEntriesByType && performance.getEntriesByType('navigation')[0]; +// sentry-specific change: +// add optional param to not check for responseStart (see comment below) +export const getNavigationEntry = (checkResponseStart = true): PerformanceNavigationTiming | void => { + const navigationEntry = + WINDOW.performance && WINDOW.performance.getEntriesByType && WINDOW.performance.getEntriesByType('navigation')[0]; + // Check to ensure the `responseStart` property is present and valid. + // In some cases no value is reported by the browser (for + // privacy/security reasons), and in other cases (bugs) the value is + // negative or is larger than the current page time. Ignore these cases: + // https://github.com/GoogleChrome/web-vitals/issues/137 + // https://github.com/GoogleChrome/web-vitals/issues/162 + // https://github.com/GoogleChrome/web-vitals/issues/275 + if ( + // sentry-specific change: + // We don't want to check for responseStart for our own use of `getNavigationEntry` + !checkResponseStart || + (navigationEntry && navigationEntry.responseStart > 0 && navigationEntry.responseStart < performance.now()) + ) { + return navigationEntry; + } }; diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts b/packages/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts index c254ad1259d9..b658be9475e9 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts @@ -24,7 +24,7 @@ const initHiddenTime = () => { // that visibility state is always 'hidden' during prerendering, so we have // to ignore that case until prerendering finishes (see: `prerenderingchange` // event logic below). - firstHiddenTime = WINDOW.document!.visibilityState === 'hidden' && !WINDOW.document!.prerendering ? 0 : Infinity; + return WINDOW.document!.visibilityState === 'hidden' && !WINDOW.document!.prerendering ? 0 : Infinity; }; const onVisibilityUpdate = (event: Event) => { @@ -41,8 +41,7 @@ const onVisibilityUpdate = (event: Event) => { firstHiddenTime = event.type === 'visibilitychange' ? event.timeStamp : 0; // Remove all listeners now that a `firstHiddenTime` value has been set. - removeEventListener('visibilitychange', onVisibilityUpdate, true); - removeEventListener('prerenderingchange', onVisibilityUpdate, true); + removeChangeListeners(); } }; @@ -55,13 +54,18 @@ const addChangeListeners = () => { addEventListener('prerenderingchange', onVisibilityUpdate, true); }; +const removeChangeListeners = () => { + removeEventListener('visibilitychange', onVisibilityUpdate, true); + removeEventListener('prerenderingchange', onVisibilityUpdate, true); +}; + export const getVisibilityWatcher = () => { if (WINDOW.document && firstHiddenTime < 0) { // If the document is hidden when this code runs, assume it was hidden // since navigation start. This isn't a perfect heuristic, but it's the // best we can do until an API is available to support querying past // visibilityState. - initHiddenTime(); + firstHiddenTime = initHiddenTime(); addChangeListeners(); } return { diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/interactions.ts b/packages/browser-utils/src/metrics/web-vitals/lib/interactions.ts new file mode 100644 index 000000000000..6d6390755656 --- /dev/null +++ b/packages/browser-utils/src/metrics/web-vitals/lib/interactions.ts @@ -0,0 +1,136 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getInteractionCount } from './polyfills/interactionCountPolyfill'; + +interface Interaction { + id: number; + latency: number; + entries: PerformanceEventTiming[]; +} + +interface EntryPreProcessingHook { + (entry: PerformanceEventTiming): void; +} + +// A list of longest interactions on the page (by latency) sorted so the +// longest one is first. The list is at most MAX_INTERACTIONS_TO_CONSIDER long. +export const longestInteractionList: Interaction[] = []; + +// A mapping of longest interactions by their interaction ID. +// This is used for faster lookup. +export const longestInteractionMap: Map = new Map(); + +// The default `durationThreshold` used across this library for observing +// `event` entries via PerformanceObserver. +export const DEFAULT_DURATION_THRESHOLD = 40; + +// Used to store the interaction count after a bfcache restore, since p98 +// interaction latencies should only consider the current navigation. +let prevInteractionCount = 0; + +/** + * Returns the interaction count since the last bfcache restore (or for the + * full page lifecycle if there were no bfcache restores). + */ +const getInteractionCountForNavigation = () => { + return getInteractionCount() - prevInteractionCount; +}; + +export const resetInteractions = () => { + prevInteractionCount = getInteractionCount(); + longestInteractionList.length = 0; + longestInteractionMap.clear(); +}; + +/** + * Returns the estimated p98 longest interaction based on the stored + * interaction candidates and the interaction count for the current page. + */ +export const estimateP98LongestInteraction = () => { + const candidateInteractionIndex = Math.min( + longestInteractionList.length - 1, + Math.floor(getInteractionCountForNavigation() / 50), + ); + + return longestInteractionList[candidateInteractionIndex]; +}; + +// To prevent unnecessary memory usage on pages with lots of interactions, +// store at most 10 of the longest interactions to consider as INP candidates. +const MAX_INTERACTIONS_TO_CONSIDER = 10; + +/** + * A list of callback functions to run before each entry is processed. + * Exposing this list allows the attribution build to hook into the + * entry processing pipeline. + */ +export const entryPreProcessingCallbacks: EntryPreProcessingHook[] = []; + +/** + * Takes a performance entry and adds it to the list of worst interactions + * if its duration is long enough to make it among the worst. If the + * entry is part of an existing interaction, it is merged and the latency + * and entries list is updated as needed. + */ +export const processInteractionEntry = (entry: PerformanceEventTiming) => { + entryPreProcessingCallbacks.forEach(cb => cb(entry)); + + // Skip further processing for entries that cannot be INP candidates. + if (!(entry.interactionId || entry.entryType === 'first-input')) return; + + // The least-long of the 10 longest interactions. + const minLongestInteraction = longestInteractionList[longestInteractionList.length - 1]; + + const existingInteraction = longestInteractionMap.get(entry.interactionId!); + + // Only process the entry if it's possibly one of the ten longest, + // or if it's part of an existing interaction. + if ( + existingInteraction || + longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER || + (minLongestInteraction && entry.duration > minLongestInteraction.latency) + ) { + // If the interaction already exists, update it. Otherwise create one. + if (existingInteraction) { + // If the new entry has a longer duration, replace the old entries, + // otherwise add to the array. + if (entry.duration > existingInteraction.latency) { + existingInteraction.entries = [entry]; + existingInteraction.latency = entry.duration; + } else if ( + entry.duration === existingInteraction.latency && + entry.startTime === (existingInteraction.entries[0] && existingInteraction.entries[0].startTime) + ) { + existingInteraction.entries.push(entry); + } + } else { + const interaction = { + id: entry.interactionId!, + latency: entry.duration, + entries: [entry], + }; + longestInteractionMap.set(interaction.id, interaction); + longestInteractionList.push(interaction); + } + + // Sort the entries by latency (descending) and keep only the top ten. + longestInteractionList.sort((a, b) => b.latency - a.latency); + if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) { + longestInteractionList.splice(MAX_INTERACTIONS_TO_CONSIDER).forEach(i => longestInteractionMap.delete(i.id)); + } + } +}; diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/observe.ts b/packages/browser-utils/src/metrics/web-vitals/lib/observe.ts index d763b14dfdf0..ad71468b6fb6 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/observe.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/observe.ts @@ -14,16 +14,19 @@ * limitations under the License. */ -import type { FirstInputPolyfillEntry, NavigationTimingPolyfillEntry } from '../types'; - interface PerformanceEntryMap { event: PerformanceEventTiming[]; - paint: PerformancePaintTiming[]; + 'first-input': PerformanceEventTiming[]; 'layout-shift': LayoutShift[]; 'largest-contentful-paint': LargestContentfulPaint[]; - 'first-input': PerformanceEventTiming[] | FirstInputPolyfillEntry[]; - navigation: PerformanceNavigationTiming[] | NavigationTimingPolyfillEntry[]; + 'long-animation-frame': PerformanceLongAnimationFrameTiming[]; + paint: PerformancePaintTiming[]; + navigation: PerformanceNavigationTiming[]; resource: PerformanceResourceTiming[]; + // Sentry-specific change: + // We add longtask as a supported entry type as we use this in + // our `instrumentPerformanceObserver` function also observes 'longtask' + // entries. longtask: PerformanceEntry[]; } diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts b/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts index 9f65196d27a2..81d83caa53b5 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts @@ -20,6 +20,16 @@ export interface OnHiddenCallback { (event: Event): void; } +// Sentry-specific change: +// This function's logic was NOT updated to web-vitals 4.2.4 but we continue +// to use the web-vitals 3.5.2 due to us having stricter browser support. +// PR with context that made the changes: https://github.com/GoogleChrome/web-vitals/pull/442/files#r1530492402 +// The PR removed listening to the `pagehide` event, in favour of only listening to `visibilitychange` event. +// This is "more correct" but some browsers we still support (Safari 12.1-14.0) don't fully support `visibilitychange` +// or have known bugs w.r.t the `visibilitychange` event. +// TODO (v9): If we decide to drop support for Safari 12.1-14.0, we can use the logic from web-vitals 4.2.4 +// In this case, we also need to update the integration tests that currently trigger the `pagehide` event to +// simulate the page being hidden. export const onHidden = (cb: OnHiddenCallback) => { const onHiddenOrPageHide = (event: Event) => { if (event.type === 'pagehide' || (WINDOW.document && WINDOW.document.visibilityState === 'hidden')) { diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.ts b/packages/browser-utils/src/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.ts index f6f02c04817b..4da20a602335 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/polyfills/interactionCountPolyfill.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import type { Metric } from '../../types'; import { observe } from '../observe'; declare global { @@ -27,8 +26,8 @@ let interactionCountEstimate = 0; let minKnownInteractionId = Infinity; let maxKnownInteractionId = 0; -const updateEstimate = (entries: Metric['entries']): void => { - (entries as PerformanceEventTiming[]).forEach(e => { +const updateEstimate = (entries: PerformanceEventTiming[]) => { + entries.forEach(e => { if (e.interactionId) { minKnownInteractionId = Math.min(minKnownInteractionId, e.interactionId); maxKnownInteractionId = Math.max(maxKnownInteractionId, e.interactionId); diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/runOnce.ts b/packages/browser-utils/src/metrics/web-vitals/lib/runOnce.ts index c232fa16b487..f2de2eadd2d9 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/runOnce.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/runOnce.ts @@ -14,15 +14,11 @@ * limitations under the License. */ -export interface RunOnceCallback { - (arg: unknown): void; -} - -export const runOnce = (cb: RunOnceCallback) => { +export const runOnce = (cb: () => void) => { let called = false; - return (arg: unknown) => { + return () => { if (!called) { - cb(arg); + cb(); called = true; } }; diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/whenIdle.ts b/packages/browser-utils/src/metrics/web-vitals/lib/whenIdle.ts new file mode 100644 index 000000000000..c140864b3539 --- /dev/null +++ b/packages/browser-utils/src/metrics/web-vitals/lib/whenIdle.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { WINDOW } from '../../../types'; +import { onHidden } from './onHidden'; +import { runOnce } from './runOnce'; + +/** + * Runs the passed callback during the next idle period, or immediately + * if the browser's visibility state is (or becomes) hidden. + */ +export const whenIdle = (cb: () => void): number => { + const rIC = WINDOW.requestIdleCallback || WINDOW.setTimeout; + + let handle = -1; + // eslint-disable-next-line no-param-reassign + cb = runOnce(cb) as () => void; + // If the document is hidden, run the callback immediately, otherwise + // race an idle callback with the next `visibilitychange` event. + if (WINDOW.document && WINDOW.document.visibilityState === 'hidden') { + cb(); + } else { + handle = rIC(cb); + onHidden(cb); + } + return handle; +}; diff --git a/packages/browser-utils/src/metrics/web-vitals/onFCP.ts b/packages/browser-utils/src/metrics/web-vitals/onFCP.ts index b08973fefb40..d01001ad48ec 100644 --- a/packages/browser-utils/src/metrics/web-vitals/onFCP.ts +++ b/packages/browser-utils/src/metrics/web-vitals/onFCP.ts @@ -20,7 +20,7 @@ import { getVisibilityWatcher } from './lib/getVisibilityWatcher'; import { initMetric } from './lib/initMetric'; import { observe } from './lib/observe'; import { whenActivated } from './lib/whenActivated'; -import type { FCPMetric, FCPReportCallback, MetricRatingThresholds, ReportOpts } from './types'; +import type { FCPMetric, MetricRatingThresholds, ReportOpts } from './types'; /** Thresholds for FCP. See https://web.dev/articles/fcp#what_is_a_good_fcp_score */ export const FCPThresholds: MetricRatingThresholds = [1800, 3000]; @@ -31,14 +31,14 @@ export const FCPThresholds: MetricRatingThresholds = [1800, 3000]; * relevant `paint` performance entry used to determine the value. The reported * value is a `DOMHighResTimeStamp`. */ -export const onFCP = (onReport: FCPReportCallback, opts: ReportOpts = {}): void => { +export const onFCP = (onReport: (metric: FCPMetric) => void, opts: ReportOpts = {}) => { whenActivated(() => { const visibilityWatcher = getVisibilityWatcher(); const metric = initMetric('FCP'); let report: ReturnType; const handleEntries = (entries: FCPMetric['entries']) => { - (entries as PerformancePaintTiming[]).forEach(entry => { + entries.forEach(entry => { if (entry.name === 'first-contentful-paint') { po!.disconnect(); @@ -59,7 +59,7 @@ export const onFCP = (onReport: FCPReportCallback, opts: ReportOpts = {}): void const po = observe('paint', handleEntries); if (po) { - report = bindReporter(onReport, metric, FCPThresholds, opts!.reportAllChanges); + report = bindReporter(onReport, metric, FCPThresholds, opts.reportAllChanges); } }); }; diff --git a/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts b/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts index 85f9b99bc0f4..7c8c1bb0b5c1 100644 --- a/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts +++ b/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts @@ -20,7 +20,7 @@ import { getActivationStart } from './lib/getActivationStart'; import { getNavigationEntry } from './lib/getNavigationEntry'; import { initMetric } from './lib/initMetric'; import { whenActivated } from './lib/whenActivated'; -import type { MetricRatingThresholds, ReportOpts, TTFBReportCallback } from './types'; +import type { MetricRatingThresholds, ReportOpts, TTFBMetric } from './types'; /** Thresholds for TTFB. See https://web.dev/articles/ttfb#what_is_a_good_ttfb_score */ export const TTFBThresholds: MetricRatingThresholds = [800, 1800]; @@ -55,31 +55,21 @@ const whenReady = (callback: () => void) => { * includes time spent on DNS lookup, connection negotiation, network latency, * and server processing time. */ -export const onTTFB = (onReport: TTFBReportCallback, opts: ReportOpts = {}) => { +export const onTTFB = (onReport: (metric: TTFBMetric) => void, opts: ReportOpts = {}) => { const metric = initMetric('TTFB'); const report = bindReporter(onReport, metric, TTFBThresholds, opts.reportAllChanges); whenReady(() => { - const navEntry = getNavigationEntry(); - - if (navEntry) { - const responseStart = navEntry.responseStart; - - // In some cases no value is reported by the browser (for - // privacy/security reasons), and in other cases (bugs) the value is - // negative or is larger than the current page time. Ignore these cases: - // https://github.com/GoogleChrome/web-vitals/issues/137 - // https://github.com/GoogleChrome/web-vitals/issues/162 - // https://github.com/GoogleChrome/web-vitals/issues/275 - if (responseStart <= 0 || responseStart > performance.now()) return; + const navigationEntry = getNavigationEntry(); + if (navigationEntry) { // The activationStart reference is used because TTFB should be // relative to page activation rather than navigation start if the // page was prerendered. But in cases where `activationStart` occurs // after the first byte is received, this time should be clamped at 0. - metric.value = Math.max(responseStart - getActivationStart(), 0); + metric.value = Math.max(navigationEntry.responseStart - getActivationStart(), 0); - metric.entries = [navEntry]; + metric.entries = [navigationEntry]; report(true); } }); diff --git a/packages/browser-utils/src/metrics/web-vitals/types.ts b/packages/browser-utils/src/metrics/web-vitals/types.ts index 41793221311b..5a17b811db96 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types.ts @@ -14,8 +14,6 @@ * limitations under the License. */ -import type { FirstInputPolyfillCallback } from './types/polyfills'; - export * from './types/base'; export * from './types/polyfills'; @@ -26,22 +24,6 @@ export * from './types/inp'; export * from './types/lcp'; export * from './types/ttfb'; -// -------------------------------------------------------------------------- -// Web Vitals package globals -// -------------------------------------------------------------------------- - -export interface WebVitalsGlobal { - firstInputPolyfill: (onFirstInput: FirstInputPolyfillCallback) => void; - resetFirstInputPolyfill: () => void; - firstHiddenTime: number; -} - -declare global { - interface Window { - webVitals: WebVitalsGlobal; - } -} - // -------------------------------------------------------------------------- // Everything below is modifications to built-in modules. // -------------------------------------------------------------------------- @@ -78,7 +60,7 @@ declare global { // https://wicg.github.io/event-timing/#sec-performance-event-timing interface PerformanceEventTiming extends PerformanceEntry { duration: DOMHighResTimeStamp; - interactionId?: number; + interactionId: number; } // https://wicg.github.io/layout-instability/#sec-layout-shift-attribution @@ -97,11 +79,17 @@ declare global { // https://w3c.github.io/largest-contentful-paint/#sec-largest-contentful-paint-interface interface LargestContentfulPaint extends PerformanceEntry { - renderTime: DOMHighResTimeStamp; - loadTime: DOMHighResTimeStamp; - size: number; - id: string; - url: string; - element?: Element; + readonly renderTime: DOMHighResTimeStamp; + readonly loadTime: DOMHighResTimeStamp; + readonly size: number; + readonly id: string; + readonly url: string; + readonly element: Element | null; + } + + // https://w3c.github.io/long-animation-frame/#sec-PerformanceLongAnimationFrameTiming + interface PerformanceLongAnimationFrameTiming extends PerformanceEntry { + renderStart: DOMHighResTimeStamp; + duration: DOMHighResTimeStamp; } } diff --git a/packages/browser-utils/src/metrics/web-vitals/types/base.ts b/packages/browser-utils/src/metrics/web-vitals/types/base.ts index 6279edffabd4..6b612e7e22c5 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/base.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/base.ts @@ -14,13 +14,12 @@ * limitations under the License. */ -import type { CLSMetric } from './cls'; -import type { FCPMetric } from './fcp'; -import type { FIDMetric } from './fid'; -import type { INPMetric } from './inp'; -import type { LCPMetric } from './lcp'; -import type { FirstInputPolyfillEntry, NavigationTimingPolyfillEntry } from './polyfills'; -import type { TTFBMetric } from './ttfb'; +import type { CLSMetric, CLSMetricWithAttribution } from './cls'; +import type { FCPMetric, FCPMetricWithAttribution } from './fcp'; +import type { FIDMetric, FIDMetricWithAttribution } from './fid'; +import type { INPMetric, INPMetricWithAttribution } from './inp'; +import type { LCPMetric, LCPMetricWithAttribution } from './lcp'; +import type { TTFBMetric, TTFBMetricWithAttribution } from './ttfb'; export interface Metric { /** @@ -61,7 +60,7 @@ export interface Metric { * The array may also be empty if the metric value was not based on any * entries (e.g. a CLS value of 0 given no layout shifts). */ - entries: (PerformanceEntry | LayoutShift | FirstInputPolyfillEntry | NavigationTimingPolyfillEntry)[]; + entries: PerformanceEntry[]; /** * The type of navigation. @@ -70,6 +69,7 @@ export interface Metric { * `undefined` if the browser doesn't support that API), with the following * exceptions: * - 'back-forward-cache': for pages that are restored from the bfcache. + * - 'back_forward' is renamed to 'back-forward' for consistency. * - 'prerender': for pages that were prerendered. * - 'restore': for pages that were discarded by the browser and then * restored by the user. @@ -80,17 +80,14 @@ export interface Metric { /** The union of supported metric types. */ export type MetricType = CLSMetric | FCPMetric | FIDMetric | INPMetric | LCPMetric | TTFBMetric; -/** - * A version of the `Metric` that is used with the attribution build. - */ -export interface MetricWithAttribution extends Metric { - /** - * An object containing potentially-helpful debugging information that - * can be sent along with the metric value for the current page visit in - * order to help identify issues happening to real-users in the field. - */ - attribution: { [key: string]: unknown }; -} +/** The union of supported metric attribution types. */ +export type MetricWithAttribution = + | CLSMetricWithAttribution + | FCPMetricWithAttribution + | FIDMetricWithAttribution + | INPMetricWithAttribution + | LCPMetricWithAttribution + | TTFBMetricWithAttribution; /** * The thresholds of metric's "good", "needs improvement", and "poor" ratings. @@ -107,6 +104,11 @@ export interface MetricWithAttribution extends Metric { */ export type MetricRatingThresholds = [number, number]; +/** + * @deprecated Use metric-specific function types instead, such as: + * `(metric: LCPMetric) => void`. If a single callback type is needed for + * multiple metrics, use `(metric: MetricType) => void`. + */ export interface ReportCallback { (metric: MetricType): void; } diff --git a/packages/browser-utils/src/metrics/web-vitals/types/cls.ts b/packages/browser-utils/src/metrics/web-vitals/types/cls.ts index a95a8fb30770..1d17c2d3eedb 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/cls.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/cls.ts @@ -72,17 +72,3 @@ export interface CLSAttribution { export interface CLSMetricWithAttribution extends CLSMetric { attribution: CLSAttribution; } - -/** - * A CLS-specific version of the ReportCallback function. - */ -export interface CLSReportCallback { - (metric: CLSMetric): void; -} - -/** - * A CLS-specific version of the ReportCallback function with attribution. - */ -export interface CLSReportCallbackWithAttribution { - (metric: CLSMetricWithAttribution): void; -} diff --git a/packages/browser-utils/src/metrics/web-vitals/types/fcp.ts b/packages/browser-utils/src/metrics/web-vitals/types/fcp.ts index 1a4c7d4962a3..ce668192766f 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/fcp.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/fcp.ts @@ -15,7 +15,6 @@ */ import type { LoadState, Metric } from './base'; -import type { NavigationTimingPolyfillEntry } from './polyfills'; /** * An FCP-specific version of the Metric object. @@ -55,7 +54,7 @@ export interface FCPAttribution { * general page load issues. This can be used to access `serverTiming` for example: * navigationEntry?.serverTiming */ - navigationEntry?: PerformanceNavigationTiming | NavigationTimingPolyfillEntry; + navigationEntry?: PerformanceNavigationTiming; } /** @@ -64,17 +63,3 @@ export interface FCPAttribution { export interface FCPMetricWithAttribution extends FCPMetric { attribution: FCPAttribution; } - -/** - * An FCP-specific version of the ReportCallback function. - */ -export interface FCPReportCallback { - (metric: FCPMetric): void; -} - -/** - * An FCP-specific version of the ReportCallback function with attribution. - */ -export interface FCPReportCallbackWithAttribution { - (metric: FCPMetricWithAttribution): void; -} diff --git a/packages/browser-utils/src/metrics/web-vitals/types/fid.ts b/packages/browser-utils/src/metrics/web-vitals/types/fid.ts index 2001269c9b46..953607adff98 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/fid.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/fid.ts @@ -15,14 +15,13 @@ */ import type { LoadState, Metric } from './base'; -import type { FirstInputPolyfillEntry } from './polyfills'; /** * An FID-specific version of the Metric object. */ export interface FIDMetric extends Metric { name: 'FID'; - entries: (PerformanceEventTiming | FirstInputPolyfillEntry)[]; + entries: PerformanceEventTiming[]; } /** @@ -46,10 +45,9 @@ export interface FIDAttribution { */ eventType: string; /** - * The `PerformanceEventTiming` entry corresponding to FID (or the - * polyfill entry in browsers that don't support Event Timing). + * The `PerformanceEventTiming` entry corresponding to FID. */ - eventEntry: PerformanceEventTiming | FirstInputPolyfillEntry; + eventEntry: PerformanceEventTiming; /** * The loading state of the document at the time when the first interaction * occurred (see `LoadState` for details). If the first interaction occurred @@ -65,17 +63,3 @@ export interface FIDAttribution { export interface FIDMetricWithAttribution extends FIDMetric { attribution: FIDAttribution; } - -/** - * An FID-specific version of the ReportCallback function. - */ -export interface FIDReportCallback { - (metric: FIDMetric): void; -} - -/** - * An FID-specific version of the ReportCallback function with attribution. - */ -export interface FIDReportCallbackWithAttribution { - (metric: FIDMetricWithAttribution): void; -} diff --git a/packages/browser-utils/src/metrics/web-vitals/types/inp.ts b/packages/browser-utils/src/metrics/web-vitals/types/inp.ts index e83e0a0ece2a..c19be79a1ce0 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/inp.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/inp.ts @@ -31,31 +31,87 @@ export interface INPMetric extends Metric { */ export interface INPAttribution { /** - * A selector identifying the element that the user interacted with for - * the event corresponding to INP. This element will be the `target` of the - * `event` dispatched. + * A selector identifying the element that the user first interacted with + * as part of the frame where the INP candidate interaction occurred. + * If this value is an empty string, that generally means the element was + * removed from the DOM after the interaction. */ - eventTarget?: string; + interactionTarget: string; /** - * The time when the user interacted for the event corresponding to INP. - * This time will match the `timeStamp` value of the `event` dispatched. + * A reference to the HTML element identified by `interactionTargetSelector`. + * NOTE: for attribution purpose, a selector identifying the element is + * typically more useful than the element itself. However, the element is + * also made available in case additional context is needed. */ - eventTime?: number; + interactionTargetElement: Node | undefined; /** - * The `type` of the `event` dispatched corresponding to INP. + * The time when the user first interacted during the frame where the INP + * candidate interaction occurred (if more than one interaction occurred + * within the frame, only the first time is reported). */ - eventType?: string; + interactionTime: DOMHighResTimeStamp; /** - * The `PerformanceEventTiming` entry corresponding to INP. + * The best-guess timestamp of the next paint after the interaction. + * In general, this timestamp is the same as the `startTime + duration` of + * the event timing entry. However, since `duration` values are rounded to + * the nearest 8ms, it can sometimes appear that the paint occurred before + * processing ended (which cannot happen). This value clamps the paint time + * so it's always after `processingEnd` from the Event Timing API and + * `renderStart` from the Long Animation Frame API (where available). + * It also averages the duration values for all entries in the same + * animation frame, which should be closer to the "real" value. */ - eventEntry?: PerformanceEventTiming; + nextPaintTime: DOMHighResTimeStamp; /** - * The loading state of the document at the time when the event corresponding - * to INP occurred (see `LoadState` for details). If the interaction occurred - * while the document was loading and executing script (e.g. usually in the - * `dom-interactive` phase) it can result in long delays. + * The type of interaction, based on the event type of the `event` entry + * that corresponds to the interaction (i.e. the first `event` entry + * containing an `interactionId` dispatched in a given animation frame). + * For "pointerdown", "pointerup", or "click" events this will be "pointer", + * and for "keydown" or "keyup" events this will be "keyboard". */ - loadState?: LoadState; + interactionType: 'pointer' | 'keyboard'; + /** + * An array of Event Timing entries that were processed within the same + * animation frame as the INP candidate interaction. + */ + processedEventEntries: PerformanceEventTiming[]; + /** + * If the browser supports the Long Animation Frame API, this array will + * include any `long-animation-frame` entries that intersect with the INP + * candidate interaction's `startTime` and the `processingEnd` time of the + * last event processed within that animation frame. If the browser does not + * support the Long Animation Frame API or no `long-animation-frame` entries + * are detect, this array will be empty. + */ + longAnimationFrameEntries: PerformanceLongAnimationFrameTiming[]; + /** + * The time from when the user interacted with the page until when the + * browser was first able to start processing event listeners for that + * interaction. This time captures the delay before event processing can + * begin due to the main thread being busy with other work. + */ + inputDelay: number; + /** + * The time from when the first event listener started running in response to + * the user interaction until when all event listener processing has finished. + */ + processingDuration: number; + /** + * The time from when the browser finished processing all event listeners for + * the user interaction until the next frame is presented on the screen and + * visible to the user. This time includes work on the main thread (such as + * `requestAnimationFrame()` callbacks, `ResizeObserver` and + * `IntersectionObserver` callbacks, and style/layout calculation) as well + * as off-main-thread work (such as compositor, GPU, and raster work). + */ + presentationDelay: number; + /** + * The loading state of the document at the time when the interaction + * corresponding to INP occurred (see `LoadState` for details). If the + * interaction occurred while the document was loading and executing script + * (e.g. usually in the `dom-interactive` phase) it can result in long delays. + */ + loadState: LoadState; } /** @@ -64,17 +120,3 @@ export interface INPAttribution { export interface INPMetricWithAttribution extends INPMetric { attribution: INPAttribution; } - -/** - * An INP-specific version of the ReportCallback function. - */ -export interface INPReportCallback { - (metric: INPMetric): void; -} - -/** - * An INP-specific version of the ReportCallback function with attribution. - */ -export interface INPReportCallbackWithAttribution { - (metric: INPMetricWithAttribution): void; -} diff --git a/packages/browser-utils/src/metrics/web-vitals/types/lcp.ts b/packages/browser-utils/src/metrics/web-vitals/types/lcp.ts index aaed1213508e..2dd5ea34f798 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/lcp.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/lcp.ts @@ -15,7 +15,6 @@ */ import type { Metric } from './base'; -import type { NavigationTimingPolyfillEntry } from './polyfills'; /** * An LCP-specific version of the Metric object. @@ -57,7 +56,7 @@ export interface LCPAttribution { * otherwise 0). See [Optimize LCP](https://web.dev/articles/optimize-lcp) for * details. */ - resourceLoadTime: number; + resourceLoadDuration: number; /** * The delta between when the LCP resource finishes loading until the LCP * element is fully rendered. See [Optimize @@ -69,7 +68,7 @@ export interface LCPAttribution { * general page load issues. This can be used to access `serverTiming` for example: * navigationEntry?.serverTiming */ - navigationEntry?: PerformanceNavigationTiming | NavigationTimingPolyfillEntry; + navigationEntry?: PerformanceNavigationTiming; /** * The `resource` entry for the LCP resource (if applicable), which is useful * for diagnosing resource load issues. @@ -87,17 +86,3 @@ export interface LCPAttribution { export interface LCPMetricWithAttribution extends LCPMetric { attribution: LCPAttribution; } - -/** - * An LCP-specific version of the ReportCallback function. - */ -export interface LCPReportCallback { - (metric: LCPMetric): void; -} - -/** - * An LCP-specific version of the ReportCallback function with attribution. - */ -export interface LCPReportCallbackWithAttribution { - (metric: LCPMetricWithAttribution): void; -} diff --git a/packages/browser-utils/src/metrics/web-vitals/types/polyfills.ts b/packages/browser-utils/src/metrics/web-vitals/types/polyfills.ts index 4216d72ac732..c4314c0697fa 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/polyfills.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/polyfills.ts @@ -19,16 +19,3 @@ export type FirstInputPolyfillEntry = Omit & { - type: PerformanceNavigationTiming['type']; -}; diff --git a/packages/browser-utils/src/metrics/web-vitals/types/ttfb.ts b/packages/browser-utils/src/metrics/web-vitals/types/ttfb.ts index 6a91394ad059..2a43668d7d8f 100644 --- a/packages/browser-utils/src/metrics/web-vitals/types/ttfb.ts +++ b/packages/browser-utils/src/metrics/web-vitals/types/ttfb.ts @@ -15,48 +15,59 @@ */ import type { Metric } from './base'; -import type { NavigationTimingPolyfillEntry } from './polyfills'; /** * A TTFB-specific version of the Metric object. */ export interface TTFBMetric extends Metric { name: 'TTFB'; - entries: PerformanceNavigationTiming[] | NavigationTimingPolyfillEntry[]; + entries: PerformanceNavigationTiming[]; } /** * An object containing potentially-helpful debugging information that * can be sent along with the TTFB value for the current page visit in order * to help identify issues happening to real-users in the field. + * + * NOTE: these values are primarily useful for page loads not handled via + * service worker, as browsers differ in what they report when service worker + * is involved, see: https://github.com/w3c/navigation-timing/issues/199 */ export interface TTFBAttribution { /** * The total time from when the user initiates loading the page to when the - * DNS lookup begins. This includes redirects, service worker startup, and - * HTTP cache lookup times. + * page starts to handle the request. Large values here are typically due + * to HTTP redirects, though other browser processing contributes to this + * duration as well (so even without redirect it's generally not zero). + */ + waitingDuration: number; + /** + * The total time spent checking the HTTP cache for a match. For navigations + * handled via service worker, this duration usually includes service worker + * start-up time as well as time processing `fetch` event listeners, with + * some exceptions, see: https://github.com/w3c/navigation-timing/issues/199 */ - waitingTime: number; + cacheDuration: number; /** - * The total time to resolve the DNS for the current request. + * The total time to resolve the DNS for the requested domain. */ - dnsTime: number; + dnsDuration: number; /** * The total time to create the connection to the requested domain. */ - connectionTime: number; + connectionDuration: number; /** - * The time time from when the request was sent until the first byte of the + * The total time from when the request was sent until the first byte of the * response was received. This includes network time as well as server * processing time. */ - requestTime: number; + requestDuration: number; /** * The `navigation` entry of the current page, which is useful for diagnosing - * general page load issues. This can be used to access `serverTiming` for example: - * navigationEntry?.serverTiming + * general page load issues. This can be used to access `serverTiming` for + * example: navigationEntry?.serverTiming */ - navigationEntry?: PerformanceNavigationTiming | NavigationTimingPolyfillEntry; + navigationEntry?: PerformanceNavigationTiming; } /** @@ -65,17 +76,3 @@ export interface TTFBAttribution { export interface TTFBMetricWithAttribution extends TTFBMetric { attribution: TTFBAttribution; } - -/** - * A TTFB-specific version of the ReportCallback function. - */ -export interface TTFBReportCallback { - (metric: TTFBMetric): void; -} - -/** - * A TTFB-specific version of the ReportCallback function with attribution. - */ -export interface TTFBReportCallbackWithAttribution { - (metric: TTFBMetricWithAttribution): void; -} diff --git a/packages/browser-utils/test/browser/browserMetrics.test.ts b/packages/browser-utils/test/browser/browserMetrics.test.ts index be78df6920fc..6ca155bccfc2 100644 --- a/packages/browser-utils/test/browser/browserMetrics.test.ts +++ b/packages/browser-utils/test/browser/browserMetrics.test.ts @@ -8,7 +8,7 @@ import { setCurrentClient, spanToJSON, } from '@sentry/core'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; import type { ResourceEntry } from '../../src/metrics/browserMetrics'; import { _addMeasureSpans, _addResourceSpans } from '../../src/metrics/browserMetrics'; import { WINDOW } from '../../src/types'; diff --git a/packages/browser-utils/test/utils/TestClient.ts b/packages/browser-utils/test/utils/TestClient.ts index b3e3c29cb8cd..6e8f01c6d3e8 100644 --- a/packages/browser-utils/test/utils/TestClient.ts +++ b/packages/browser-utils/test/utils/TestClient.ts @@ -6,7 +6,7 @@ import type { Event, ParameterizedString, SeverityLevel, -} from '@sentry/types'; +} from '@sentry/core'; export interface TestClientOptions extends ClientOptions, BrowserClientReplayOptions {} diff --git a/packages/browser/package.json b/packages/browser/package.json index 72f8921e411e..c11364a16565 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/browser", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for browsers", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser", @@ -39,15 +39,14 @@ "access": "public" }, "dependencies": { - "@sentry-internal/browser-utils": "8.40.0", - "@sentry-internal/feedback": "8.40.0", - "@sentry-internal/replay": "8.40.0", - "@sentry-internal/replay-canvas": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry-internal/browser-utils": "8.42.0", + "@sentry-internal/feedback": "8.42.0", + "@sentry-internal/replay": "8.42.0", + "@sentry-internal/replay-canvas": "8.42.0", + "@sentry/core": "8.42.0" }, "devDependencies": { - "@sentry-internal/integration-shims": "8.40.0", + "@sentry-internal/integration-shims": "8.42.0", "fake-indexeddb": "^4.0.1" }, "scripts": { diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index 8746fe6fda76..2ce5c7dfece6 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -1,7 +1,3 @@ -import type { Scope } from '@sentry/core'; -import { applySdkMetadata } from '@sentry/core'; -import { BaseClient } from '@sentry/core'; -import { getSDKSource, logger } from '@sentry/core'; import type { BrowserClientProfilingOptions, BrowserClientReplayOptions, @@ -10,10 +6,11 @@ import type { EventHint, Options, ParameterizedString, + Scope, SeverityLevel, UserFeedback, -} from '@sentry/types'; - +} from '@sentry/core'; +import { BaseClient, applySdkMetadata, getSDKSource, logger } from '@sentry/core'; import { DEBUG_BUILD } from './debug-build'; import { eventFromException, eventFromMessage } from './eventbuilder'; import { WINDOW } from './helpers'; @@ -22,7 +19,7 @@ import { createUserFeedbackEnvelope } from './userfeedback'; /** * Configuration options for the Sentry Browser SDK. - * @see @sentry/types Options for more information. + * @see @sentry/core Options for more information. */ export type BrowserOptions = Options & BrowserClientReplayOptions & diff --git a/packages/browser/src/eventbuilder.ts b/packages/browser/src/eventbuilder.ts index b4ee8d581eb9..7f7539f5cf5f 100644 --- a/packages/browser/src/eventbuilder.ts +++ b/packages/browser/src/eventbuilder.ts @@ -1,8 +1,17 @@ -import { getClient } from '@sentry/core'; +import type { + Event, + EventHint, + Exception, + ParameterizedString, + SeverityLevel, + StackFrame, + StackParser, +} from '@sentry/core'; import { addExceptionMechanism, addExceptionTypeValue, extractExceptionKeysForMessage, + getClient, isDOMError, isDOMException, isError, @@ -13,15 +22,6 @@ import { normalizeToSize, resolvedSyncPromise, } from '@sentry/core'; -import type { - Event, - EventHint, - Exception, - ParameterizedString, - SeverityLevel, - StackFrame, - StackParser, -} from '@sentry/types'; type Prototype = { constructor: (...args: unknown[]) => unknown }; diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index ebea58f1fa7c..492f9da23b38 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -15,7 +15,7 @@ export type { Thread, User, Session, -} from '@sentry/types'; +} from '@sentry/core'; export type { BrowserOptions } from './client'; diff --git a/packages/browser/src/helpers.ts b/packages/browser/src/helpers.ts index 8871b1ba2c68..cd0a734102e7 100644 --- a/packages/browser/src/helpers.ts +++ b/packages/browser/src/helpers.ts @@ -1,13 +1,14 @@ -import { captureException, withScope } from '@sentry/core'; +import type { Mechanism, WrappedFunction } from '@sentry/core'; import { GLOBAL_OBJ, addExceptionMechanism, addExceptionTypeValue, addNonEnumerableProperty, + captureException, getOriginalFunction, markFunctionWrapped, + withScope, } from '@sentry/core'; -import type { Mechanism, WrappedFunction } from '@sentry/types'; export const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; @@ -31,6 +32,21 @@ export function ignoreNextOnError(): void { }); } +// eslint-disable-next-line @typescript-eslint/ban-types +type WrappableFunction = Function; + +export function wrap( + fn: T, + options?: { + mechanism?: Mechanism; + }, +): WrappedFunction; +export function wrap( + fn: NonFunction, + options?: { + mechanism?: Mechanism; + }, +): NonFunction; /** * Instruments the given function and sends an event to Sentry every time the * function throws an exception. @@ -40,14 +56,12 @@ export function ignoreNextOnError(): void { * @returns The wrapped function. * @hidden */ -export function wrap( - fn: WrappedFunction, +export function wrap( + fn: T | NonFunction, options: { mechanism?: Mechanism; } = {}, - before?: WrappedFunction, - // eslint-disable-next-line @typescript-eslint/no-explicit-any -): any { +): NonFunction | WrappedFunction { // for future readers what this does is wrap a function and then create // a bi-directional wrapping between them. // @@ -55,14 +69,18 @@ export function wrap( // original.__sentry_wrapped__ -> wrapped // wrapped.__sentry_original__ -> original - if (typeof fn !== 'function') { + function isFunction(fn: T | NonFunction): fn is T { + return typeof fn === 'function'; + } + + if (!isFunction(fn)) { return fn; } try { // if we're dealing with a function that was previously wrapped, return // the original wrapper. - const wrapper = fn.__sentry_wrapped__; + const wrapper = (fn as WrappedFunction).__sentry_wrapped__; if (wrapper) { if (typeof wrapper === 'function') { return wrapper; @@ -84,18 +102,12 @@ export function wrap( return fn; } - /* eslint-disable prefer-rest-params */ + // Wrap the function itself // It is important that `sentryWrapped` is not an arrow function to preserve the context of `this` - const sentryWrapped: WrappedFunction = function (this: unknown): void { - const args = Array.prototype.slice.call(arguments); - + const sentryWrapped = function (this: unknown, ...args: unknown[]): unknown { try { - if (before && typeof before === 'function') { - before.apply(this, arguments); - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access - const wrappedArguments = args.map((arg: any) => wrap(arg, options)); + // Also wrap arguments that are themselves functions + const wrappedArguments = args.map(arg => wrap(arg, options)); // Attempt to invoke user-land function // NOTE: If you are a Sentry user, and you are seeing this stack frame, it @@ -125,18 +137,19 @@ export function wrap( throw ex; } - }; - /* eslint-enable prefer-rest-params */ + } as unknown as WrappedFunction; - // Accessing some objects may throw - // ref: https://github.com/getsentry/sentry-javascript/issues/1168 + // Wrap the wrapped function in a proxy, to ensure any other properties of the original function remain available try { for (const property in fn) { if (Object.prototype.hasOwnProperty.call(fn, property)) { - sentryWrapped[property] = fn[property]; + sentryWrapped[property as keyof T] = fn[property as keyof T]; } } - } catch (_oO) {} // eslint-disable-line no-empty + } catch { + // Accessing some objects may throw + // ref: https://github.com/getsentry/sentry-javascript/issues/1168 + } // Signal that this function has been wrapped/filled already // for both debugging and to prevent it to being wrapped/filled twice @@ -146,7 +159,8 @@ export function wrap( // Restore original function name (not all browsers allow that) try { - const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name') as PropertyDescriptor; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const descriptor = Object.getOwnPropertyDescriptor(sentryWrapped, 'name')!; if (descriptor.configurable) { Object.defineProperty(sentryWrapped, 'name', { get(): string { @@ -154,8 +168,10 @@ export function wrap( }, }); } - // eslint-disable-next-line no-empty - } catch (_oO) {} + } catch { + // This may throw if e.g. the descriptor does not exist, or a browser does not allow redefining `name`. + // to save some bytes we simply try-catch this + } return sentryWrapped; } diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index bc720295b090..827d2a90c993 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -73,7 +73,7 @@ export { zodErrorsIntegration, thirdPartyErrorFilterIntegration, } from '@sentry/core'; -export type { Span } from '@sentry/types'; +export type { Span } from '@sentry/core'; export { makeBrowserOfflineTransport } from './transports/offline'; export { browserProfilingIntegration } from './profiling/integration'; export { spotlightBrowserIntegration } from './integrations/spotlight'; diff --git a/packages/browser/src/integrations/breadcrumbs.ts b/packages/browser/src/integrations/breadcrumbs.ts index 889e1a54c201..5e31f5abe2a3 100644 --- a/packages/browser/src/integrations/breadcrumbs.ts +++ b/packages/browser/src/integrations/breadcrumbs.ts @@ -1,22 +1,11 @@ +/* eslint-disable max-lines */ + import { SENTRY_XHR_DATA_KEY, addClickKeypressInstrumentationHandler, addHistoryInstrumentationHandler, addXhrInstrumentationHandler, } from '@sentry-internal/browser-utils'; -import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core'; -import { - addConsoleInstrumentationHandler, - addFetchInstrumentationHandler, - getBreadcrumbLogLevelFromHttpStatusCode, - getComponentName, - getEventDescription, - htmlTreeAsString, - logger, - parseUrl, - safeJoin, - severityLevelFromString, -} from '@sentry/core'; import type { Breadcrumb, Client, @@ -31,8 +20,22 @@ import type { IntegrationFn, XhrBreadcrumbData, XhrBreadcrumbHint, -} from '@sentry/types'; - +} from '@sentry/core'; +import { + addBreadcrumb, + addConsoleInstrumentationHandler, + addFetchInstrumentationHandler, + defineIntegration, + getBreadcrumbLogLevelFromHttpStatusCode, + getClient, + getComponentName, + getEventDescription, + htmlTreeAsString, + logger, + parseUrl, + safeJoin, + severityLevelFromString, +} from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; diff --git a/packages/browser/src/integrations/browserapierrors.ts b/packages/browser/src/integrations/browserapierrors.ts index 2290c1a45d66..e1328a90831e 100644 --- a/packages/browser/src/integrations/browserapierrors.ts +++ b/packages/browser/src/integrations/browserapierrors.ts @@ -1,6 +1,5 @@ -import { defineIntegration } from '@sentry/core'; -import { fill, getFunctionName, getOriginalFunction } from '@sentry/core'; -import type { IntegrationFn, WrappedFunction } from '@sentry/types'; +import type { IntegrationFn, WrappedFunction } from '@sentry/core'; +import { defineIntegration, fill, getFunctionName, getOriginalFunction } from '@sentry/core'; import { WINDOW, wrap } from '../helpers'; @@ -96,8 +95,7 @@ const _browserApiErrorsIntegration = ((options: Partial export const browserApiErrorsIntegration = defineIntegration(_browserApiErrorsIntegration); function _wrapTimeFunction(original: () => void): () => number { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return function (this: any, ...args: any[]): number { + return function (this: unknown, ...args: unknown[]): number { const originalCallback = args[0]; args[0] = wrap(originalCallback, { mechanism: { @@ -110,11 +108,8 @@ function _wrapTimeFunction(original: () => void): () => number { }; } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function _wrapRAF(original: any): (callback: () => void) => any { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return function (this: any, callback: () => void): () => void { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access +function _wrapRAF(original: () => void): (callback: () => void) => unknown { + return function (this: unknown, callback: () => void): () => void { return original.apply(this, [ wrap(callback, { mechanism: { @@ -131,16 +126,14 @@ function _wrapRAF(original: any): (callback: () => void) => any { } function _wrapXHR(originalSend: () => void): () => void { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return function (this: XMLHttpRequest, ...args: any[]): void { + return function (this: XMLHttpRequest, ...args: unknown[]): void { // eslint-disable-next-line @typescript-eslint/no-this-alias const xhr = this; const xmlHttpRequestProps: XMLHttpRequestProp[] = ['onload', 'onerror', 'onprogress', 'onreadystatechange']; xmlHttpRequestProps.forEach(prop => { if (prop in xhr && typeof xhr[prop] === 'function') { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - fill(xhr, prop, function (original: WrappedFunction): () => any { + fill(xhr, prop, function (original) { const wrapOptions = { mechanism: { data: { @@ -169,30 +162,21 @@ function _wrapXHR(originalSend: () => void): () => void { } function _wrapEventTarget(target: string): void { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const globalObject = WINDOW as { [key: string]: any }; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - const proto = globalObject[target] && globalObject[target].prototype; + const globalObject = WINDOW as unknown as Record; + const targetObj = globalObject[target]; + const proto = targetObj && targetObj.prototype; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins + // eslint-disable-next-line no-prototype-builtins if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) { return; } fill(proto, 'addEventListener', function (original: VoidFunction,): ( - eventName: string, - fn: EventListenerObject, - options?: boolean | AddEventListenerOptions, - ) => void { - return function ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this: any, - eventName: string, - fn: EventListenerObject, - options?: boolean | AddEventListenerOptions, - ): (eventName: string, fn: EventListenerObject, capture?: boolean, secure?: boolean) => void { + ...args: Parameters + ) => ReturnType { + return function (this: unknown, eventName, fn, options): VoidFunction { try { - if (typeof fn.handleEvent === 'function') { + if (isEventListenerObject(fn)) { // ESlint disable explanation: // First, it is generally safe to call `wrap` with an unbound function. Furthermore, using `.bind()` would // introduce a bug here, because bind returns a new function that doesn't have our @@ -211,14 +195,13 @@ function _wrapEventTarget(target: string): void { }, }); } - } catch (err) { + } catch { // can sometimes get 'Permission denied to access property "handle Event' } return original.apply(this, [ eventName, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - wrap(fn as any as WrappedFunction, { + wrap(fn, { mechanism: { data: { function: 'addEventListener', @@ -234,48 +217,41 @@ function _wrapEventTarget(target: string): void { }; }); - fill( - proto, - 'removeEventListener', - function ( - originalRemoveEventListener: () => void, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ): (this: any, eventName: string, fn: EventListenerObject, options?: boolean | EventListenerOptions) => () => void { - return function ( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this: any, - eventName: string, - fn: EventListenerObject, - options?: boolean | EventListenerOptions, - ): () => void { - /** - * There are 2 possible scenarios here: - * - * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified - * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function - * as a pass-through, and call original `removeEventListener` with it. - * - * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using - * our wrapped version of `addEventListener`, which internally calls `wrap` helper. - * This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it, - * in order for us to make a distinction between wrapped/non-wrapped functions possible. - * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler. - * - * When someone adds a handler prior to initialization, and then do it again, but after, - * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible - * to get rid of the initial handler and it'd stick there forever. - */ - const wrappedEventHandler = fn as unknown as WrappedFunction; - try { - const originalEventHandler = wrappedEventHandler && wrappedEventHandler.__sentry_wrapped__; - if (originalEventHandler) { - originalRemoveEventListener.call(this, eventName, originalEventHandler, options); - } - } catch (e) { - // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments + fill(proto, 'removeEventListener', function (originalRemoveEventListener: VoidFunction,): ( + this: unknown, + ...args: Parameters + ) => ReturnType { + return function (this: unknown, eventName, fn, options): VoidFunction { + /** + * There are 2 possible scenarios here: + * + * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified + * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function + * as a pass-through, and call original `removeEventListener` with it. + * + * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using + * our wrapped version of `addEventListener`, which internally calls `wrap` helper. + * This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it, + * in order for us to make a distinction between wrapped/non-wrapped functions possible. + * If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler. + * + * When someone adds a handler prior to initialization, and then do it again, but after, + * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible + * to get rid of the initial handler and it'd stick there forever. + */ + try { + const originalEventHandler = (fn as WrappedFunction).__sentry_wrapped__; + if (originalEventHandler) { + originalRemoveEventListener.call(this, eventName, originalEventHandler, options); } - return originalRemoveEventListener.call(this, eventName, wrappedEventHandler, options); - }; - }, - ); + } catch (e) { + // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments + } + return originalRemoveEventListener.call(this, eventName, fn, options); + }; + }); +} + +function isEventListenerObject(obj: unknown): obj is EventListenerObject { + return typeof (obj as EventListenerObject).handleEvent === 'function'; } diff --git a/packages/browser/src/integrations/contextlines.ts b/packages/browser/src/integrations/contextlines.ts index eb4dd7e7f748..66500e238614 100644 --- a/packages/browser/src/integrations/contextlines.ts +++ b/packages/browser/src/integrations/contextlines.ts @@ -1,6 +1,5 @@ -import { defineIntegration } from '@sentry/core'; -import { GLOBAL_OBJ, addContextToFrame, stripUrlQueryAndFragment } from '@sentry/core'; -import type { Event, IntegrationFn, StackFrame } from '@sentry/types'; +import type { Event, IntegrationFn, StackFrame } from '@sentry/core'; +import { GLOBAL_OBJ, addContextToFrame, defineIntegration, stripUrlQueryAndFragment } from '@sentry/core'; const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; diff --git a/packages/browser/src/integrations/globalhandlers.ts b/packages/browser/src/integrations/globalhandlers.ts index 2b9278adf767..1f0d0a4b35c1 100644 --- a/packages/browser/src/integrations/globalhandlers.ts +++ b/packages/browser/src/integrations/globalhandlers.ts @@ -1,14 +1,16 @@ -import { captureEvent, defineIntegration, getClient } from '@sentry/core'; +import type { Client, Event, IntegrationFn, Primitive, StackParser } from '@sentry/core'; import { UNKNOWN_FUNCTION, addGlobalErrorInstrumentationHandler, addGlobalUnhandledRejectionInstrumentationHandler, + captureEvent, + defineIntegration, + getClient, getLocationHref, isPrimitive, isString, logger, } from '@sentry/core'; -import type { Client, Event, IntegrationFn, Primitive, StackParser } from '@sentry/types'; import type { BrowserClient } from '../client'; import { DEBUG_BUILD } from '../debug-build'; diff --git a/packages/browser/src/integrations/httpclient.ts b/packages/browser/src/integrations/httpclient.ts index 439941c97faf..eec0141bb97e 100644 --- a/packages/browser/src/integrations/httpclient.ts +++ b/packages/browser/src/integrations/httpclient.ts @@ -1,13 +1,16 @@ import { SENTRY_XHR_DATA_KEY, addXhrInstrumentationHandler } from '@sentry-internal/browser-utils'; -import { captureEvent, defineIntegration, getClient, isSentryRequestUrl } from '@sentry/core'; +import type { Client, Event as SentryEvent, IntegrationFn, SentryWrappedXMLHttpRequest } from '@sentry/core'; import { GLOBAL_OBJ, addExceptionMechanism, addFetchInstrumentationHandler, + captureEvent, + defineIntegration, + getClient, + isSentryRequestUrl, logger, supportsNativeFetch, } from '@sentry/core'; -import type { Client, Event as SentryEvent, IntegrationFn, SentryWrappedXMLHttpRequest } from '@sentry/types'; import { DEBUG_BUILD } from '../debug-build'; @@ -108,8 +111,8 @@ function _parseCookieHeaders( if (cookieString) { cookies = _parseCookieString(cookieString); } - } catch (e) { - DEBUG_BUILD && logger.log(`Could not extract cookies from header ${cookieHeader}`); + } catch { + // ignore it if parsing fails } return [headers, cookies]; @@ -138,14 +141,14 @@ function _xhrResponseHandler( if (cookieString) { responseCookies = _parseCookieString(cookieString); } - } catch (e) { - DEBUG_BUILD && logger.log('Could not extract cookies from response headers'); + } catch { + // ignore it if parsing fails } try { responseHeaders = _getXHRResponseHeaders(xhr); - } catch (e) { - DEBUG_BUILD && logger.log('Could not extract headers from response'); + } catch { + // ignore it if parsing fails } requestHeaders = headers; diff --git a/packages/browser/src/integrations/linkederrors.ts b/packages/browser/src/integrations/linkederrors.ts index 41d15566f7a2..4b99ac876386 100644 --- a/packages/browser/src/integrations/linkederrors.ts +++ b/packages/browser/src/integrations/linkederrors.ts @@ -1,6 +1,5 @@ -import { defineIntegration } from '@sentry/core'; -import { applyAggregateErrorsToEvent } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; +import { applyAggregateErrorsToEvent, defineIntegration } from '@sentry/core'; import { exceptionFromError } from '../eventbuilder'; interface LinkedErrorsOptions { diff --git a/packages/browser/src/integrations/reportingobserver.ts b/packages/browser/src/integrations/reportingobserver.ts index 0e65216e3043..81db7d0932d1 100644 --- a/packages/browser/src/integrations/reportingobserver.ts +++ b/packages/browser/src/integrations/reportingobserver.ts @@ -1,6 +1,12 @@ -import { captureMessage, defineIntegration, getClient, withScope } from '@sentry/core'; -import { GLOBAL_OBJ, supportsReportingObserver } from '@sentry/core'; -import type { Client, IntegrationFn } from '@sentry/types'; +import type { Client, IntegrationFn } from '@sentry/core'; +import { + GLOBAL_OBJ, + captureMessage, + defineIntegration, + getClient, + supportsReportingObserver, + withScope, +} from '@sentry/core'; const WINDOW = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; @@ -46,6 +52,13 @@ interface ReportingObserverOptions { types?: ReportTypes[]; } +/** This is experimental and the types are not included with TypeScript, sadly. */ +interface ReportingObserverClass { + new (handler: (reports: Report[]) => void, options: { buffered?: boolean; types?: ReportTypes[] }): { + observe: () => void; + }; +} + const SETUP_CLIENTS = new WeakMap(); const _reportingObserverIntegration = ((options: ReportingObserverOptions = {}) => { @@ -99,13 +112,14 @@ const _reportingObserverIntegration = ((options: ReportingObserverOptions = {}) return; } - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - const observer = new (WINDOW as any).ReportingObserver(handler, { - buffered: true, - types, - }); + const observer = new (WINDOW as typeof WINDOW & { ReportingObserver: ReportingObserverClass }).ReportingObserver( + handler, + { + buffered: true, + types, + }, + ); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access observer.observe(); }, diff --git a/packages/browser/src/integrations/spotlight.ts b/packages/browser/src/integrations/spotlight.ts index 3c50939833d6..7d3cc61d5015 100644 --- a/packages/browser/src/integrations/spotlight.ts +++ b/packages/browser/src/integrations/spotlight.ts @@ -1,10 +1,8 @@ import { getNativeImplementation } from '@sentry-internal/browser-utils'; -import { defineIntegration } from '@sentry/core'; -import { logger, serializeEnvelope } from '@sentry/core'; -import type { Client, Envelope, Event, IntegrationFn } from '@sentry/types'; -import type { WINDOW } from '../helpers'; - +import type { Client, Envelope, Event, IntegrationFn } from '@sentry/core'; +import { defineIntegration, logger, serializeEnvelope } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; +import type { WINDOW } from '../helpers'; export type SpotlightConnectionOptions = { /** diff --git a/packages/browser/src/metrics.ts b/packages/browser/src/metrics.ts index 00d73ec33b1c..96f56988c485 100644 --- a/packages/browser/src/metrics.ts +++ b/packages/browser/src/metrics.ts @@ -1,5 +1,5 @@ import { BrowserMetricsAggregator, metrics as metricsCore } from '@sentry/core'; -import type { DurationUnit, MetricData, Metrics } from '@sentry/types'; +import type { DurationUnit, MetricData, Metrics } from '@sentry/core'; /** * Adds a value to a counter metric diff --git a/packages/browser/src/profiling/integration.ts b/packages/browser/src/profiling/integration.ts index 1648fbf77a43..b0ca69a37b00 100644 --- a/packages/browser/src/profiling/integration.ts +++ b/packages/browser/src/profiling/integration.ts @@ -1,6 +1,6 @@ import { defineIntegration, getActiveSpan, getRootSpan } from '@sentry/core'; import { logger } from '@sentry/core'; -import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/types'; +import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import { startProfileForSpan } from './startProfileForSpan'; diff --git a/packages/browser/src/profiling/startProfileForSpan.ts b/packages/browser/src/profiling/startProfileForSpan.ts index fea01e6b64ae..35a8ab45ea82 100644 --- a/packages/browser/src/profiling/startProfileForSpan.ts +++ b/packages/browser/src/profiling/startProfileForSpan.ts @@ -1,6 +1,6 @@ import { getCurrentScope, spanToJSON } from '@sentry/core'; import { logger, timestampInSeconds, uuid4 } from '@sentry/core'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index 56ae15691aaf..21cbadb58176 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -1,16 +1,16 @@ /* eslint-disable max-lines */ - -import { DEFAULT_ENVIRONMENT, getClient, spanToJSON } from '@sentry/core'; +import type { DebugImage, Envelope, Event, EventEnvelope, Profile, Span, ThreadCpuProfile } from '@sentry/core'; import { + DEFAULT_ENVIRONMENT, browserPerformanceTimeOrigin, forEachEnvelopeItem, + getClient, getDebugImagesForResources, logger, + spanToJSON, timestampInSeconds, uuid4, } from '@sentry/core'; -import type { DebugImage, Envelope, Event, EventEnvelope, Profile, Span, ThreadCpuProfile } from '@sentry/types'; - import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; import type { JSSelfProfile, JSSelfProfileStack, JSSelfProfiler, JSSelfProfilerConstructor } from './jsSelfProfiling'; diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index d758aae4b229..70d21bfd3501 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -1,19 +1,22 @@ -import { getCurrentScope } from '@sentry/core'; -import { functionToStringIntegration, inboundFiltersIntegration } from '@sentry/core'; +import { addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils'; import { captureSession, + consoleSandbox, + dedupeIntegration, + functionToStringIntegration, getClient, + getCurrentScope, getIntegrationsToSetup, getReportDialogEndpoint, + inboundFiltersIntegration, initAndBind, lastEventId, + logger, + stackParserFromStackParserOptions, startSession, + supportsFetch, } from '@sentry/core'; -import { consoleSandbox, logger, stackParserFromStackParserOptions, supportsFetch } from '@sentry/core'; -import type { Client, DsnLike, Integration, Options, UserFeedback } from '@sentry/types'; - -import { addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils'; -import { dedupeIntegration } from '@sentry/core'; +import type { Client, DsnLike, Integration, Options, UserFeedback } from '@sentry/core'; import type { BrowserClientOptions, BrowserOptions } from './client'; import { BrowserClient } from './client'; import { DEBUG_BUILD } from './debug-build'; diff --git a/packages/browser/src/stack-parsers.ts b/packages/browser/src/stack-parsers.ts index 1ac53e898349..8089ace5663d 100644 --- a/packages/browser/src/stack-parsers.ts +++ b/packages/browser/src/stack-parsers.ts @@ -24,7 +24,7 @@ // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. import { UNKNOWN_FUNCTION, createStackParser } from '@sentry/core'; -import type { StackFrame, StackLineParser, StackLineParserFn } from '@sentry/types'; +import type { StackFrame, StackLineParser, StackLineParserFn } from '@sentry/core'; const OPERA10_PRIORITY = 10; const OPERA11_PRIORITY = 20; diff --git a/packages/browser/src/tracing/backgroundtab.ts b/packages/browser/src/tracing/backgroundtab.ts index 178a95ccb5a2..3a591bde2b8e 100644 --- a/packages/browser/src/tracing/backgroundtab.ts +++ b/packages/browser/src/tracing/backgroundtab.ts @@ -1,7 +1,4 @@ -import { SPAN_STATUS_ERROR, getActiveSpan, getRootSpan } from '@sentry/core'; -import { spanToJSON } from '@sentry/core'; -import { logger } from '@sentry/core'; - +import { SPAN_STATUS_ERROR, getActiveSpan, getRootSpan, logger, spanToJSON } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index a59706edb8fb..17030f2f4a43 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -9,33 +9,29 @@ import { startTrackingLongTasks, startTrackingWebVitals, } from '@sentry-internal/browser-utils'; +import type { Client, IntegrationFn, Span, StartSpanOptions, TransactionSource } from '@sentry/core'; import { + GLOBAL_OBJ, SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, TRACING_DEFAULTS, + browserPerformanceTimeOrigin, + generateTraceId, getActiveSpan, getClient, getCurrentScope, + getDomElement, getDynamicSamplingContextFromSpan, getIsolationScope, getRootSpan, + logger, + propagationContextFromHeaders, registerSpanErrorInstrumentation, spanIsSampled, spanToJSON, startIdleSpan, } from '@sentry/core'; -import { - GLOBAL_OBJ, - browserPerformanceTimeOrigin, - generatePropagationContext, - getDomElement, - logger, - propagationContextFromHeaders, -} from '@sentry/core'; -import type { Client, IntegrationFn, StartSpanOptions, TransactionSource } from '@sentry/types'; -import type { Span } from '@sentry/types'; - import { DEBUG_BUILD } from '../debug-build'; import { WINDOW } from '../helpers'; import { registerBackgroundTabDetection } from './backgroundtab'; @@ -299,16 +295,20 @@ export const browserTracingIntegration = ((_options: Partial { if (getClient() !== client) { return; } - if (activeSpan && !spanToJSON(activeSpan).timestamp) { - DEBUG_BUILD && logger.log(`[Tracing] Finishing current root span with op: ${spanToJSON(activeSpan).op}`); - // If there's an open transaction on the scope, we need to finish it before creating an new one. - activeSpan.end(); - } + maybeEndActiveSpan(); activeSpan = _createRouteSpan(client, { op: 'navigation', @@ -320,12 +320,7 @@ export const browserTracingIntegration = ((_options: Partial { it('should wrap only functions', () => { @@ -13,16 +13,24 @@ describe('internal wrap()', () => { const num = 42; expect(wrap(fn)).not.toBe(fn); - // @ts-expect-error Issue with `WrappedFunction` type from wrap fn expect(wrap(obj)).toBe(obj); - // @ts-expect-error Issue with `WrappedFunction` type from wrap fn expect(wrap(arr)).toBe(arr); - // @ts-expect-error Issue with `WrappedFunction` type from wrap fn expect(wrap(str)).toBe(str); - // @ts-expect-error Issue with `WrappedFunction` type from wrap fn expect(wrap(num)).toBe(num); }); + it('correctly infers types', () => { + const a = wrap(42); + expect(a > 40).toBe(true); + + const b = wrap('42'); + expect(b.length).toBe(2); + + const c = wrap(() => 42); + expect(c()).toBe(42); + expect(c.__sentry_original__).toBeInstanceOf(Function); + }); + it('should preserve correct function name when accessed', () => { const namedFunction = (): number => 1337; expect(wrap(namedFunction)).not.toBe(namedFunction); @@ -56,16 +64,6 @@ describe('internal wrap()', () => { expect(wrap(wrapped)).toBe(wrapped); }); - it('calls "before" function when invoking wrapped function', () => { - const fn = (() => 1337) as WrappedFunction; - const before = vi.fn(); - - const wrapped = wrap(fn, {}, before); - wrapped(); - - expect(before).toHaveBeenCalledTimes(1); - }); - it('attaches metadata to original and wrapped functions', () => { const fn = (() => 1337) as WrappedFunction; @@ -78,10 +76,11 @@ describe('internal wrap()', () => { expect(wrapped.__sentry_original__).toBe(fn); }); - it('copies over original functions properties', () => { - const fn = (() => 1337) as WrappedFunction; - fn.some = 1337; - fn.property = 'Rick'; + it('keeps original functions properties', () => { + const fn = Object.assign(() => 1337, { + some: 1337, + property: 'Rick', + }); const wrapped = wrap(fn); @@ -105,7 +104,7 @@ describe('internal wrap()', () => { }); it('recrusively wraps arguments that are functions', () => { - const fn = (() => 1337) as WrappedFunction; + const fn = (_arg1: unknown, _arg2: unknown) => 1337; const fnArgA = (): number => 1337; const fnArgB = (): number => 1337; @@ -162,7 +161,7 @@ describe('internal wrap()', () => { }); it('internal flags shouldnt be enumerable', () => { - const fn = (() => 1337) as WrappedFunction; + const fn = () => 1337; const wrapped = wrap(fn); // Shouldn't show up in iteration @@ -172,7 +171,7 @@ describe('internal wrap()', () => { expect(Object.keys(wrapped)).toEqual(expect.not.arrayContaining(['__sentry_wrapped__'])); // But should be accessible directly expect(wrapped.__sentry_original__).toBe(fn); - expect(fn.__sentry_wrapped__).toBe(wrapped); + expect((fn as WrappedFunction).__sentry_wrapped__).toBe(wrapped); }); it('should only return __sentry_wrapped__ when it is a function', () => { diff --git a/packages/browser/test/integrations/contextlines.test.ts b/packages/browser/test/integrations/contextlines.test.ts index 783cc36fec89..9e41659746f7 100644 --- a/packages/browser/test/integrations/contextlines.test.ts +++ b/packages/browser/test/integrations/contextlines.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import type { StackFrame } from '@sentry/types'; +import type { StackFrame } from '@sentry/core'; import { applySourceContextToFrame } from '../../src/integrations/contextlines'; diff --git a/packages/browser/test/integrations/reportingobserver.test.ts b/packages/browser/test/integrations/reportingobserver.test.ts index 9571d59d03d0..a9ceff983049 100644 --- a/packages/browser/test/integrations/reportingobserver.test.ts +++ b/packages/browser/test/integrations/reportingobserver.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import * as SentryCore from '@sentry/core'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import { reportingObserverIntegration } from '../../src/integrations/reportingobserver'; diff --git a/packages/browser/test/sdk.test.ts b/packages/browser/test/sdk.test.ts index 4929ee0f83d2..e00974ab0f5d 100644 --- a/packages/browser/test/sdk.test.ts +++ b/packages/browser/test/sdk.test.ts @@ -9,7 +9,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import * as SentryCore from '@sentry/core'; import { Scope, createTransport } from '@sentry/core'; import { resolvedSyncPromise } from '@sentry/core'; -import type { Client, Integration } from '@sentry/types'; +import type { Client, Integration } from '@sentry/core'; import type { BrowserOptions } from '../src'; import { WINDOW } from '../src'; diff --git a/packages/browser/test/tracing/browserTracingIntegration.test.ts b/packages/browser/test/tracing/browserTracingIntegration.test.ts index dbdebe473335..03b57f0438e2 100644 --- a/packages/browser/test/tracing/browserTracingIntegration.test.ts +++ b/packages/browser/test/tracing/browserTracingIntegration.test.ts @@ -30,7 +30,7 @@ import { spanToJSON, startInactiveSpan, } from '@sentry/core'; -import type { Span, StartSpanOptions } from '@sentry/types'; +import type { Span, StartSpanOptions } from '@sentry/core'; import { JSDOM } from 'jsdom'; import { BrowserClient } from '../../src/client'; import { WINDOW } from '../../src/helpers'; @@ -105,9 +105,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -176,9 +176,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); // this is what is used to get the span name - JSDOM does not update this on it's own! @@ -203,9 +203,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); // this is what is used to get the span name - JSDOM does not update this on it's own! @@ -230,9 +230,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -290,9 +290,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spanIsSampled(span!)).toBe(true); }); @@ -327,9 +327,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', testy: 'yes', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -483,9 +483,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(spanIsSampled(span!)).toBe(true); }); @@ -520,9 +520,9 @@ describe('browserTracingIntegration', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', testy: 'yes', }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -688,6 +688,7 @@ describe('browserTracingIntegration', () => { const propCtxAfterEnd = getCurrentScope().getPropagationContext(); expect(propCtxAfterEnd).toStrictEqual({ + // eslint-disable-next-line deprecation/deprecation spanId: propCtxBeforeEnd.spanId, traceId: propCtxBeforeEnd.traceId, sampled: true, @@ -727,6 +728,7 @@ describe('browserTracingIntegration', () => { const propCtxAfterEnd = getCurrentScope().getPropagationContext(); expect(propCtxAfterEnd).toStrictEqual({ + // eslint-disable-next-line deprecation/deprecation spanId: propCtxBeforeEnd.spanId, traceId: propCtxBeforeEnd.traceId, sampled: false, diff --git a/packages/browser/test/tracing/request.test.ts b/packages/browser/test/tracing/request.test.ts index cf11e59a013c..337d08caff24 100644 --- a/packages/browser/test/tracing/request.test.ts +++ b/packages/browser/test/tracing/request.test.ts @@ -2,7 +2,7 @@ import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vites import * as browserUtils from '@sentry-internal/browser-utils'; import * as utils from '@sentry/core'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import { WINDOW } from '../../src/helpers'; import { extractNetworkProtocol, instrumentOutgoingRequests, shouldAttachHeaders } from '../../src/tracing/request'; diff --git a/packages/browser/test/transports/fetch.test.ts b/packages/browser/test/transports/fetch.test.ts index 1b88e6263820..9a760439733b 100644 --- a/packages/browser/test/transports/fetch.test.ts +++ b/packages/browser/test/transports/fetch.test.ts @@ -2,7 +2,7 @@ import type { Mock } from 'vitest'; import { describe, expect, it, vi } from 'vitest'; import { createEnvelope, serializeEnvelope } from '@sentry/core'; -import type { EventEnvelope, EventItem } from '@sentry/types'; +import type { EventEnvelope, EventItem } from '@sentry/core'; import { makeFetchTransport } from '../../src/transports/fetch'; import type { BrowserTransportOptions } from '../../src/transports/types'; diff --git a/packages/browser/test/transports/offline.test.ts b/packages/browser/test/transports/offline.test.ts index 9f0e5ae5cdba..a9a396949588 100644 --- a/packages/browser/test/transports/offline.test.ts +++ b/packages/browser/test/transports/offline.test.ts @@ -10,7 +10,7 @@ import type { EventItem, InternalBaseTransportOptions, TransportMakeRequestResponse, -} from '@sentry/types'; +} from '@sentry/core'; import { createStore, makeBrowserOfflineTransport, push, shift, unshift } from '../../src/transports/offline'; diff --git a/packages/bun/package.json b/packages/bun/package.json index e2877c9444c3..005667ce4daa 100644 --- a/packages/bun/package.json +++ b/packages/bun/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/bun", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for bun", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/bun", @@ -39,10 +39,9 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/opentelemetry": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", + "@sentry/opentelemetry": "8.42.0" }, "devDependencies": { "bun-types": "latest" diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts index 02718da1153c..7377d2ac3bbd 100644 --- a/packages/bun/src/index.ts +++ b/packages/bun/src/index.ts @@ -17,7 +17,7 @@ export type { Stacktrace, Thread, User, -} from '@sentry/types'; +} from '@sentry/core'; export type { AddRequestDataToEventOptions } from '@sentry/core'; export { @@ -140,6 +140,7 @@ export { spanToTraceHeader, spanToBaggageHeader, trpcMiddleware, + // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, zodErrorsIntegration, profiler, diff --git a/packages/bun/src/integrations/bunserver.ts b/packages/bun/src/integrations/bunserver.ts index f2811a026919..862d5bd87212 100644 --- a/packages/bun/src/integrations/bunserver.ts +++ b/packages/bun/src/integrations/bunserver.ts @@ -1,3 +1,4 @@ +import type { IntegrationFn, RequestEventData, SpanAttributes } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -5,12 +6,13 @@ import { captureException, continueTrace, defineIntegration, + extractQueryParamsFromUrl, + getSanitizedUrlString, + parseUrl, setHttpStatus, startSpan, withIsolationScope, } from '@sentry/core'; -import { extractQueryParamsFromUrl, getSanitizedUrlString, parseUrl } from '@sentry/core'; -import type { IntegrationFn, RequestEventData, SpanAttributes } from '@sentry/types'; const INTEGRATION_NAME = 'BunServer'; diff --git a/packages/bun/src/sdk.ts b/packages/bun/src/sdk.ts index 534592a9ebb9..8bded2d492af 100644 --- a/packages/bun/src/sdk.ts +++ b/packages/bun/src/sdk.ts @@ -4,6 +4,7 @@ import { linkedErrorsIntegration, requestDataIntegration, } from '@sentry/core'; +import type { Integration, Options } from '@sentry/core'; import type { NodeClient } from '@sentry/node'; import { consoleIntegration, @@ -16,7 +17,6 @@ import { onUncaughtExceptionIntegration, onUnhandledRejectionIntegration, } from '@sentry/node'; -import type { Integration, Options } from '@sentry/types'; import { BunClient } from './client'; import { bunServerIntegration } from './integrations/bunserver'; diff --git a/packages/bun/src/transports/index.ts b/packages/bun/src/transports/index.ts index 0dd3da97638b..efe10ab22646 100644 --- a/packages/bun/src/transports/index.ts +++ b/packages/bun/src/transports/index.ts @@ -1,6 +1,5 @@ -import { createTransport, suppressTracing } from '@sentry/core'; -import { rejectedSyncPromise } from '@sentry/core'; -import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; +import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core'; +import { createTransport, rejectedSyncPromise, suppressTracing } from '@sentry/core'; export interface BunTransportOptions extends BaseTransportOptions { /** Custom headers for the transport. Used by the XHRTransport and FetchTransport */ diff --git a/packages/bun/src/types.ts b/packages/bun/src/types.ts index 933edef42627..fa0e2171214f 100644 --- a/packages/bun/src/types.ts +++ b/packages/bun/src/types.ts @@ -1,4 +1,4 @@ -import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/types'; +import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/core'; import type { BunClient } from './client'; import type { BunTransportOptions } from './transports'; @@ -39,7 +39,7 @@ export interface BaseBunOptions { /** * Configuration options for the Sentry Bun SDK - * @see @sentry/types Options for more information. + * @see @sentry/core Options for more information. */ export interface BunOptions extends Options, BaseBunOptions {} diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json index 052f56a6bb3f..0d87d9cf01bd 100644 --- a/packages/cloudflare/package.json +++ b/packages/cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/cloudflare", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Cloudflare Workers and Pages", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/cloudflare", @@ -39,8 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "optionalDependencies": { "@cloudflare/workers-types": "^4.x" diff --git a/packages/cloudflare/src/async.ts b/packages/cloudflare/src/async.ts index c287a04474eb..462912b8756f 100644 --- a/packages/cloudflare/src/async.ts +++ b/packages/cloudflare/src/async.ts @@ -1,5 +1,5 @@ import { getDefaultCurrentScope, getDefaultIsolationScope, setAsyncContextStrategy } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; // Need to use node: prefix for cloudflare workers compatibility // Note: Because we are using node:async_hooks, we need to set `node_compat` in the wrangler.toml diff --git a/packages/cloudflare/src/client.ts b/packages/cloudflare/src/client.ts index 22b6859d9bf8..dd8a0cccdec8 100644 --- a/packages/cloudflare/src/client.ts +++ b/packages/cloudflare/src/client.ts @@ -1,7 +1,5 @@ -import type { ServerRuntimeClientOptions } from '@sentry/core'; +import type { ClientOptions, Options, ServerRuntimeClientOptions } from '@sentry/core'; import { ServerRuntimeClient, applySdkMetadata } from '@sentry/core'; -import type { ClientOptions, Options } from '@sentry/types'; - import type { CloudflareTransportOptions } from './transport'; /** @@ -37,7 +35,7 @@ interface BaseCloudflareOptions {} /** * Configuration options for the Sentry Cloudflare SDK * - * @see @sentry/types Options for more information. + * @see @sentry/core Options for more information. */ export interface CloudflareOptions extends Options, BaseCloudflareOptions {} diff --git a/packages/cloudflare/src/d1.ts b/packages/cloudflare/src/d1.ts index a67574fabb9e..7dc5e8c60f4c 100644 --- a/packages/cloudflare/src/d1.ts +++ b/packages/cloudflare/src/d1.ts @@ -1,6 +1,6 @@ import type { D1Database, D1PreparedStatement, D1Response } from '@cloudflare/workers-types'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, addBreadcrumb, startSpan } from '@sentry/core'; -import type { Span, SpanAttributes, StartSpanOptions } from '@sentry/types'; +import type { Span, SpanAttributes, StartSpanOptions } from '@sentry/core'; // Patching is based on internal Cloudflare D1 API // https://github.com/cloudflare/workerd/blob/cd5279e7b305003f1d9c851e73efa9d67e4b68b2/src/cloudflare/internal/d1-api.ts diff --git a/packages/cloudflare/src/handler.ts b/packages/cloudflare/src/handler.ts index 51260f01d755..06cb13bb8b05 100644 --- a/packages/cloudflare/src/handler.ts +++ b/packages/cloudflare/src/handler.ts @@ -40,8 +40,7 @@ export function withSentry>( ): E { setAsyncLocalStorageAsyncContextStrategy(); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - if ('fetch' in handler && typeof handler.fetch === 'function' && !(handler.fetch as any).__SENTRY_INSTRUMENTED__) { + if ('fetch' in handler && typeof handler.fetch === 'function' && !isInstrumented(handler.fetch)) { handler.fetch = new Proxy(handler.fetch, { apply(target, thisArg, args: Parameters>>) { const [request, env, context] = args; @@ -50,16 +49,10 @@ export function withSentry>( }, }); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - (handler.fetch as any).__SENTRY_INSTRUMENTED__ = true; + markAsInstrumented(handler.fetch); } - if ( - 'scheduled' in handler && - typeof handler.scheduled === 'function' && - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - !(handler.scheduled as any).__SENTRY_INSTRUMENTED__ - ) { + if ('scheduled' in handler && typeof handler.scheduled === 'function' && !isInstrumented(handler.scheduled)) { handler.scheduled = new Proxy(handler.scheduled, { apply(target, thisArg, args: Parameters>>) { const [event, env, context] = args; @@ -97,9 +90,28 @@ export function withSentry>( }, }); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - (handler.scheduled as any).__SENTRY_INSTRUMENTED__ = true; + markAsInstrumented(handler.scheduled); } return handler; } + +type SentryInstrumented = T & { + __SENTRY_INSTRUMENTED__?: boolean; +}; + +function markAsInstrumented(handler: T): void { + try { + (handler as SentryInstrumented).__SENTRY_INSTRUMENTED__ = true; + } catch { + // ignore errors here + } +} + +function isInstrumented(handler: T): boolean | undefined { + try { + return (handler as SentryInstrumented).__SENTRY_INSTRUMENTED__; + } catch { + return false; + } +} diff --git a/packages/cloudflare/src/index.ts b/packages/cloudflare/src/index.ts index 106cf4ab22fb..f3c80b8ddf32 100644 --- a/packages/cloudflare/src/index.ts +++ b/packages/cloudflare/src/index.ts @@ -17,7 +17,7 @@ export type { Stacktrace, Thread, User, -} from '@sentry/types'; +} from '@sentry/core'; export type { AddRequestDataToEventOptions } from '@sentry/core'; export type { CloudflareOptions } from './client'; diff --git a/packages/cloudflare/src/integrations/fetch.ts b/packages/cloudflare/src/integrations/fetch.ts index 2fbb93315795..651d41f826a1 100644 --- a/packages/cloudflare/src/integrations/fetch.ts +++ b/packages/cloudflare/src/integrations/fetch.ts @@ -1,10 +1,3 @@ -import { addBreadcrumb, defineIntegration, getClient, instrumentFetchRequest, isSentryRequestUrl } from '@sentry/core'; -import { - LRUMap, - addFetchInstrumentationHandler, - getBreadcrumbLogLevelFromHttpStatusCode, - stringMatchesSomePattern, -} from '@sentry/core'; import type { Client, FetchBreadcrumbData, @@ -12,7 +5,18 @@ import type { HandlerDataFetch, IntegrationFn, Span, -} from '@sentry/types'; +} from '@sentry/core'; +import { + LRUMap, + addBreadcrumb, + addFetchInstrumentationHandler, + defineIntegration, + getBreadcrumbLogLevelFromHttpStatusCode, + getClient, + instrumentFetchRequest, + isSentryRequestUrl, + stringMatchesSomePattern, +} from '@sentry/core'; const INTEGRATION_NAME = 'Fetch'; diff --git a/packages/cloudflare/src/request.ts b/packages/cloudflare/src/request.ts index cda67bfb7314..979b426ef5dc 100644 --- a/packages/cloudflare/src/request.ts +++ b/packages/cloudflare/src/request.ts @@ -1,5 +1,5 @@ import type { ExecutionContext, IncomingRequestCfProperties } from '@cloudflare/workers-types'; - +import type { SpanAttributes } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_HTTP_REQUEST_METHOD, SEMANTIC_ATTRIBUTE_SENTRY_OP, @@ -11,10 +11,9 @@ import { flush, setHttpStatus, startSpan, + stripUrlQueryAndFragment, withIsolationScope, } from '@sentry/core'; -import { stripUrlQueryAndFragment } from '@sentry/core'; -import type { SpanAttributes } from '@sentry/types'; import type { CloudflareOptions } from './client'; import { addCloudResourceContext, addCultureContext, addRequest } from './scope-utils'; import { init } from './sdk'; diff --git a/packages/cloudflare/src/scope-utils.ts b/packages/cloudflare/src/scope-utils.ts index afa155907766..018cb0a27c6b 100644 --- a/packages/cloudflare/src/scope-utils.ts +++ b/packages/cloudflare/src/scope-utils.ts @@ -1,7 +1,7 @@ import type { IncomingRequestCfProperties } from '@cloudflare/workers-types'; import { winterCGRequestToRequestData } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; /** * Set cloud resource context on scope. diff --git a/packages/cloudflare/src/sdk.ts b/packages/cloudflare/src/sdk.ts index 0c8a50c4e44d..89f3fe99d050 100644 --- a/packages/cloudflare/src/sdk.ts +++ b/packages/cloudflare/src/sdk.ts @@ -1,3 +1,4 @@ +import type { Integration } from '@sentry/core'; import { dedupeIntegration, functionToStringIntegration, @@ -6,12 +7,10 @@ import { initAndBind, linkedErrorsIntegration, requestDataIntegration, + stackParserFromStackParserOptions, } from '@sentry/core'; -import { stackParserFromStackParserOptions } from '@sentry/core'; -import type { Integration } from '@sentry/types'; import type { CloudflareClientOptions, CloudflareOptions } from './client'; import { CloudflareClient } from './client'; - import { fetchIntegration } from './integrations/fetch'; import { makeCloudflareTransport } from './transport'; import { defaultStackParser } from './vendor/stacktrace'; diff --git a/packages/cloudflare/src/transport.ts b/packages/cloudflare/src/transport.ts index 9854a9050b51..40b8549df9cd 100644 --- a/packages/cloudflare/src/transport.ts +++ b/packages/cloudflare/src/transport.ts @@ -1,6 +1,5 @@ -import { createTransport, suppressTracing } from '@sentry/core'; -import { SentryError } from '@sentry/core'; -import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; +import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core'; +import { SentryError, createTransport, suppressTracing } from '@sentry/core'; export interface CloudflareTransportOptions extends BaseTransportOptions { /** Fetch API init parameters. */ diff --git a/packages/cloudflare/src/vendor/stacktrace.ts b/packages/cloudflare/src/vendor/stacktrace.ts index 303600d495df..62e16bcea835 100644 --- a/packages/cloudflare/src/vendor/stacktrace.ts +++ b/packages/cloudflare/src/vendor/stacktrace.ts @@ -22,7 +22,7 @@ // SOFTWARE. import { basename, createStackParser, nodeStackLineParser } from '@sentry/core'; -import type { StackLineParser, StackLineParserFn, StackParser } from '@sentry/types'; +import type { StackLineParser, StackLineParserFn, StackParser } from '@sentry/core'; type GetModuleFn = (filename: string | undefined) => string | undefined; diff --git a/packages/cloudflare/test/handler.test.ts b/packages/cloudflare/test/handler.test.ts index 861360c7906f..aa5cd6b24992 100644 --- a/packages/cloudflare/test/handler.test.ts +++ b/packages/cloudflare/test/handler.test.ts @@ -5,7 +5,7 @@ import { beforeEach, describe, expect, test, vi } from 'vitest'; import type { ScheduledController } from '@cloudflare/workers-types'; import * as SentryCore from '@sentry/core'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { CloudflareClient } from '../src/client'; import { withSentry } from '../src/handler'; @@ -213,8 +213,8 @@ describe('withSentry', () => { }, op: 'faas.cron', origin: 'auto.faas.cloudflare', - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); }); diff --git a/packages/cloudflare/test/integrations/fetch.test.ts b/packages/cloudflare/test/integrations/fetch.test.ts index 86bb092facc8..43a3c749e64b 100644 --- a/packages/cloudflare/test/integrations/fetch.test.ts +++ b/packages/cloudflare/test/integrations/fetch.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import * as sentryCore from '@sentry/core'; import * as sentryUtils from '@sentry/core'; import { createStackParser } from '@sentry/core'; -import type { HandlerDataFetch, Integration } from '@sentry/types'; +import type { HandlerDataFetch, Integration } from '@sentry/core'; import { CloudflareClient } from '../../src/client'; import { fetchIntegration } from '../../src/integrations/fetch'; diff --git a/packages/cloudflare/test/request.test.ts b/packages/cloudflare/test/request.test.ts index d35ccf3d50a7..90268c18aa22 100644 --- a/packages/cloudflare/test/request.test.ts +++ b/packages/cloudflare/test/request.test.ts @@ -4,7 +4,7 @@ import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest'; import * as SentryCore from '@sentry/core'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { setAsyncLocalStorageAsyncContextStrategy } from '../src/async'; import type { CloudflareOptions } from '../src/client'; import { CloudflareClient } from '../src/client'; @@ -217,7 +217,7 @@ describe('withSentry', () => { ); expect(sentryEvent.contexts?.trace).toEqual({ parent_span_id: '1121201211212012', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: '12312012123120121231201212312012', }); }); @@ -267,9 +267,9 @@ describe('withSentry', () => { }, op: 'http.server', origin: 'auto.http.cloudflare', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); }); diff --git a/packages/cloudflare/test/transport.test.ts b/packages/cloudflare/test/transport.test.ts index 069bc119dc37..d3aca638eba1 100644 --- a/packages/cloudflare/test/transport.test.ts +++ b/packages/cloudflare/test/transport.test.ts @@ -1,5 +1,5 @@ import { createEnvelope, serializeEnvelope } from '@sentry/core'; -import type { EventEnvelope, EventItem } from '@sentry/types'; +import type { EventEnvelope, EventItem } from '@sentry/core'; import { afterAll, describe, expect, it, vi } from 'vitest'; import type { CloudflareTransportOptions } from '../src/transport'; diff --git a/packages/core/package.json b/packages/core/package.json index 8ba0845d7187..8ab66a571b9e 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/core", - "version": "8.40.0", + "version": "8.42.0", "description": "Base implementation for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/core", @@ -38,9 +38,6 @@ "publishConfig": { "access": "public" }, - "dependencies": { - "@sentry/types": "8.40.0" - }, "TODO(v9):": "Remove these dependencies", "devDependencies": { "@types/array.prototype.flat": "^1.2.1", diff --git a/packages/core/src/api.ts b/packages/core/src/api.ts index b7cd786d215a..548b40a3ce30 100644 --- a/packages/core/src/api.ts +++ b/packages/core/src/api.ts @@ -1,4 +1,4 @@ -import type { DsnComponents, DsnLike, SdkInfo } from '@sentry/types'; +import type { DsnComponents, DsnLike, SdkInfo } from './types-hoist'; import { dsnToString, makeDsn } from './utils-hoist/dsn'; const SENTRY_API_VERSION = '7'; diff --git a/packages/core/src/asyncContext/stackStrategy.ts b/packages/core/src/asyncContext/stackStrategy.ts index 256efb4a79e2..68c72fb8e92d 100644 --- a/packages/core/src/asyncContext/stackStrategy.ts +++ b/packages/core/src/asyncContext/stackStrategy.ts @@ -1,8 +1,7 @@ -import type { Client, Scope as ScopeInterface } from '@sentry/types'; import { getDefaultCurrentScope, getDefaultIsolationScope } from '../defaultScopes'; import { Scope } from '../scope'; - -import { isThenable } from '../utils-hoist'; +import type { Client, Scope as ScopeInterface } from '../types-hoist'; +import { isThenable } from '../utils-hoist/is'; import { getMainCarrier, getSentryCarrier } from './../carrier'; import type { AsyncContextStrategy } from './types'; diff --git a/packages/core/src/asyncContext/types.ts b/packages/core/src/asyncContext/types.ts index 9fb9f9f4bec8..7b5bf8acc54c 100644 --- a/packages/core/src/asyncContext/types.ts +++ b/packages/core/src/asyncContext/types.ts @@ -1,4 +1,4 @@ -import type { Scope } from '@sentry/types'; +import type { Scope } from '../types-hoist'; import type { getTraceData } from '../utils/traceData'; import type { startInactiveSpan, diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 2387523d46ee..5d06d539b6ec 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -29,10 +29,10 @@ import type { TransactionEvent, Transport, TransportMakeRequestResponse, -} from '@sentry/types'; +} from './types-hoist'; import { getEnvelopeEndpointWithUrlEncodedAuth } from './api'; -import { getIsolationScope } from './currentScopes'; +import { getCurrentScope, getIsolationScope, getTraceContextFromScope } from './currentScopes'; import { DEBUG_BUILD } from './debug-build'; import { createEventEnvelope, createSessionEnvelope } from './envelope'; import type { IntegrationIndex } from './integration'; @@ -40,15 +40,14 @@ import { afterSetupIntegrations } from './integration'; import { setupIntegration, setupIntegrations } from './integration'; import type { Scope } from './scope'; import { updateSession } from './session'; -import { getDynamicSamplingContextFromClient } from './tracing/dynamicSamplingContext'; +import { getDynamicSamplingContextFromScope } from './tracing/dynamicSamplingContext'; import { createClientReportEnvelope } from './utils-hoist/clientreport'; import { dsnToString, makeDsn } from './utils-hoist/dsn'; import { addItemToEnvelope, createAttachmentEnvelopeItem } from './utils-hoist/envelope'; import { SentryError } from './utils-hoist/error'; import { isParameterizedString, isPlainObject, isPrimitive, isThenable } from './utils-hoist/is'; -import { logger } from './utils-hoist/logger'; +import { consoleSandbox, logger } from './utils-hoist/logger'; import { checkOrSetAlreadyCaught, uuid4 } from './utils-hoist/misc'; -import { dropUndefinedKeys } from './utils-hoist/object'; import { SyncPromise, rejectedSyncPromise, resolvedSyncPromise } from './utils-hoist/syncpromise'; import { parseSampleRate } from './utils/parseSampleRate'; import { prepareEvent } from './utils/prepareEvent'; @@ -142,6 +141,18 @@ export abstract class BaseClient implements Client { url, }); } + + // TODO(v9): Remove this deprecation warning + const tracingOptions = ['enableTracing', 'tracesSampleRate', 'tracesSampler'] as const; + const undefinedOption = tracingOptions.find(option => option in options && options[option] == undefined); + if (undefinedOption) { + consoleSandbox(() => { + // eslint-disable-next-line no-console + console.warn( + `[Sentry] Deprecation warning: \`${undefinedOption}\` is set to undefined, which leads to tracing being enabled. In v9, a value of \`undefined\` will result in tracing being disabled.`, + ); + }); + } } /** @@ -249,7 +260,7 @@ export abstract class BaseClient implements Client { } /** - * @see SdkMetadata in @sentry/types + * @see SdkMetadata * * @return The metadata of the SDK */ @@ -660,7 +671,7 @@ export abstract class BaseClient implements Client { protected _prepareEvent( event: Event, hint: EventHint, - currentScope?: Scope, + currentScope = getCurrentScope(), isolationScope = getIsolationScope(), ): PromiseLike { const options = this.getOptions(); @@ -680,30 +691,18 @@ export abstract class BaseClient implements Client { return evt; } - const propagationContext = { - ...isolationScope.getPropagationContext(), - ...(currentScope ? currentScope.getPropagationContext() : undefined), + evt.contexts = { + trace: getTraceContextFromScope(currentScope), + ...evt.contexts, }; - const trace = evt.contexts && evt.contexts.trace; - if (!trace && propagationContext) { - const { traceId: trace_id, spanId, parentSpanId, dsc } = propagationContext; - evt.contexts = { - trace: dropUndefinedKeys({ - trace_id, - span_id: spanId, - parent_span_id: parentSpanId, - }), - ...evt.contexts, - }; + const dynamicSamplingContext = getDynamicSamplingContextFromScope(this, currentScope); - const dynamicSamplingContext = dsc ? dsc : getDynamicSamplingContextFromClient(trace_id, this); + evt.sdkProcessingMetadata = { + dynamicSamplingContext, + ...evt.sdkProcessingMetadata, + }; - evt.sdkProcessingMetadata = { - dynamicSamplingContext, - ...evt.sdkProcessingMetadata, - }; - } return evt; }); } diff --git a/packages/core/src/breadcrumbs.ts b/packages/core/src/breadcrumbs.ts index 2b1f78b50e8d..b4a167a6f4d3 100644 --- a/packages/core/src/breadcrumbs.ts +++ b/packages/core/src/breadcrumbs.ts @@ -1,5 +1,5 @@ -import type { Breadcrumb, BreadcrumbHint } from '@sentry/types'; import { getClient, getIsolationScope } from './currentScopes'; +import type { Breadcrumb, BreadcrumbHint } from './types-hoist'; import { consoleSandbox } from './utils-hoist/logger'; import { dateTimestampInSeconds } from './utils-hoist/time'; diff --git a/packages/core/src/carrier.ts b/packages/core/src/carrier.ts index 6f212fc67edb..d053234b4929 100644 --- a/packages/core/src/carrier.ts +++ b/packages/core/src/carrier.ts @@ -1,6 +1,6 @@ -import type { Client, Integration, MetricsAggregator, Scope } from '@sentry/types'; import type { AsyncContextStack } from './asyncContext/stackStrategy'; import type { AsyncContextStrategy } from './asyncContext/types'; +import type { Client, Integration, MetricsAggregator, Scope } from './types-hoist'; import { SDK_VERSION } from './utils-hoist/version'; import { GLOBAL_OBJ } from './utils-hoist/worldwide'; diff --git a/packages/core/src/checkin.ts b/packages/core/src/checkin.ts index f9e16f8d8cd1..34f2428cbcfb 100644 --- a/packages/core/src/checkin.ts +++ b/packages/core/src/checkin.ts @@ -5,7 +5,7 @@ import type { DynamicSamplingContext, SdkMetadata, SerializedCheckIn, -} from '@sentry/types'; +} from './types-hoist'; import { dsnToString } from './utils-hoist/dsn'; import { createEnvelope } from './utils-hoist/envelope'; import { dropUndefinedKeys } from './utils-hoist/object'; diff --git a/packages/core/src/currentScopes.ts b/packages/core/src/currentScopes.ts index 77e8aa70a02a..85b148738467 100644 --- a/packages/core/src/currentScopes.ts +++ b/packages/core/src/currentScopes.ts @@ -1,8 +1,8 @@ -import type { Scope } from '@sentry/types'; -import type { Client } from '@sentry/types'; import { getAsyncContextStrategy } from './asyncContext'; import { getMainCarrier } from './carrier'; import { Scope as ScopeClass } from './scope'; +import type { Client, Scope, TraceContext } from './types-hoist'; +import { dropUndefinedKeys } from './utils-hoist/object'; import { getGlobalSingleton } from './utils-hoist/worldwide'; /** @@ -120,3 +120,22 @@ export function withIsolationScope( export function getClient(): C | undefined { return getCurrentScope().getClient(); } + +/** + * Get a trace context for the given scope. + */ +export function getTraceContextFromScope(scope: Scope): TraceContext { + const propagationContext = scope.getPropagationContext(); + + // TODO(v9): Use generateSpanId() instead of spanId + // eslint-disable-next-line deprecation/deprecation + const { traceId, spanId, parentSpanId } = propagationContext; + + const traceContext: TraceContext = dropUndefinedKeys({ + trace_id: traceId, + span_id: spanId, + parent_span_id: parentSpanId, + }); + + return traceContext; +} diff --git a/packages/core/src/defaultScopes.ts b/packages/core/src/defaultScopes.ts index fa2f4700fdf9..c9fb32c2049e 100644 --- a/packages/core/src/defaultScopes.ts +++ b/packages/core/src/defaultScopes.ts @@ -1,5 +1,5 @@ -import type { Scope } from '@sentry/types'; import { Scope as ScopeClass } from './scope'; +import type { Scope } from './types-hoist'; import { getGlobalSingleton } from './utils-hoist/worldwide'; /** Get the default current scope. */ diff --git a/packages/core/src/envelope.ts b/packages/core/src/envelope.ts index 8ecdeb0d604f..7281f2d2ea7f 100644 --- a/packages/core/src/envelope.ts +++ b/packages/core/src/envelope.ts @@ -1,3 +1,5 @@ +import { getDynamicSamplingContextFromSpan } from './tracing/dynamicSamplingContext'; +import type { SentrySpan } from './tracing/sentrySpan'; import type { Client, DsnComponents, @@ -14,9 +16,7 @@ import type { SpanEnvelope, SpanItem, SpanJSON, -} from '@sentry/types'; -import { getDynamicSamplingContextFromSpan } from './tracing/dynamicSamplingContext'; -import type { SentrySpan } from './tracing/sentrySpan'; +} from './types-hoist'; import { dsnToString } from './utils-hoist/dsn'; import { createEnvelope, diff --git a/packages/core/src/eventProcessors.ts b/packages/core/src/eventProcessors.ts index 5886384879c5..0691fac89680 100644 --- a/packages/core/src/eventProcessors.ts +++ b/packages/core/src/eventProcessors.ts @@ -1,6 +1,5 @@ -import type { Event, EventHint, EventProcessor } from '@sentry/types'; - import { DEBUG_BUILD } from './debug-build'; +import type { Event, EventHint, EventProcessor } from './types-hoist'; import { isThenable } from './utils-hoist/is'; import { logger } from './utils-hoist/logger'; import { SyncPromise } from './utils-hoist/syncpromise'; diff --git a/packages/core/src/exports.ts b/packages/core/src/exports.ts index 5e2be168487c..0ae3fa3d2775 100644 --- a/packages/core/src/exports.ts +++ b/packages/core/src/exports.ts @@ -13,7 +13,7 @@ import type { SessionContext, SeverityLevel, User, -} from '@sentry/types'; +} from './types-hoist'; import { DEFAULT_ENVIRONMENT } from './constants'; import { getClient, getCurrentScope, getIsolationScope, withIsolationScope } from './currentScopes'; diff --git a/packages/core/src/feedback.ts b/packages/core/src/feedback.ts index e49f8ddc27a9..95a5bc4fa2a9 100644 --- a/packages/core/src/feedback.ts +++ b/packages/core/src/feedback.ts @@ -1,5 +1,5 @@ -import type { EventHint, FeedbackEvent, SendFeedbackParams } from '@sentry/types'; import { getClient, getCurrentScope } from './currentScopes'; +import type { EventHint, FeedbackEvent, SendFeedbackParams } from './types-hoist'; import { dropUndefinedKeys } from './utils-hoist/object'; /** diff --git a/packages/core/src/fetch.ts b/packages/core/src/fetch.ts index 65629d1291ac..7385298f925c 100644 --- a/packages/core/src/fetch.ts +++ b/packages/core/src/fetch.ts @@ -1,20 +1,13 @@ -import type { Client, HandlerDataFetch, Scope, Span, SpanOrigin } from '@sentry/types'; -import { getClient, getCurrentScope, getIsolationScope } from './currentScopes'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from './semanticAttributes'; -import { - SPAN_STATUS_ERROR, - getDynamicSamplingContextFromClient, - getDynamicSamplingContextFromSpan, - setHttpStatus, - startInactiveSpan, -} from './tracing'; +import { SPAN_STATUS_ERROR, setHttpStatus, startInactiveSpan } from './tracing'; import { SentryNonRecordingSpan } from './tracing/sentryNonRecordingSpan'; -import { SENTRY_BAGGAGE_KEY_PREFIX, dynamicSamplingContextToSentryBaggageHeader } from './utils-hoist/baggage'; +import type { Client, HandlerDataFetch, Scope, Span, SpanOrigin } from './types-hoist'; +import { SENTRY_BAGGAGE_KEY_PREFIX } from './utils-hoist/baggage'; import { isInstanceOf } from './utils-hoist/is'; -import { generateSentryTraceHeader } from './utils-hoist/tracing'; import { parseUrl } from './utils-hoist/url'; import { hasTracingEnabled } from './utils/hasTracingEnabled'; -import { getActiveSpan, spanToTraceHeader } from './utils/spanUtils'; +import { getActiveSpan } from './utils/spanUtils'; +import { getTraceData } from './utils/traceData'; type PolymorphicRequestHeaders = | Record @@ -59,9 +52,6 @@ export function instrumentFetchRequest( return undefined; } - const scope = getCurrentScope(); - const client = getClient(); - const { method, url } = handlerData.fetchData; const fullUrl = getFullURL(url); @@ -88,37 +78,34 @@ export function instrumentFetchRequest( handlerData.fetchData.__span = span.spanContext().spanId; spans[span.spanContext().spanId] = span; - if (shouldAttachHeaders(handlerData.fetchData.url) && client) { + if (shouldAttachHeaders(handlerData.fetchData.url)) { const request: string | Request = handlerData.args[0]; - // In case the user hasn't set the second argument of a fetch call we default it to `{}`. - handlerData.args[1] = handlerData.args[1] || {}; - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const options: { [key: string]: any } = handlerData.args[1]; + const options: { [key: string]: unknown } = handlerData.args[1] || {}; - options.headers = addTracingHeadersToFetchRequest( + const headers = _addTracingHeadersToFetchRequest( request, - client, - scope, options, // If performance is disabled (TWP) or there's no active root span (pageload/navigation/interaction), // we do not want to use the span as base for the trace headers, // which means that the headers will be generated from the scope and the sampling decision is deferred hasTracingEnabled() && hasParent ? span : undefined, ); + if (headers) { + // Ensure this is actually set, if no options have been passed previously + handlerData.args[1] = options; + options.headers = headers; + } } return span; } /** - * Adds sentry-trace and baggage headers to the various forms of fetch headers + * Adds sentry-trace and baggage headers to the various forms of fetch headers. */ -export function addTracingHeadersToFetchRequest( - request: string | unknown, // unknown is actually type Request but we can't export DOM types from this package, - client: Client, - scope: Scope, +function _addTracingHeadersToFetchRequest( + request: string | Request, fetchOptionsObj: { headers?: | { @@ -128,31 +115,24 @@ export function addTracingHeadersToFetchRequest( }, span?: Span, ): PolymorphicRequestHeaders | undefined { - const isolationScope = getIsolationScope(); + const traceHeaders = getTraceData({ span }); + const sentryTrace = traceHeaders['sentry-trace']; + const baggage = traceHeaders.baggage; - const { traceId, spanId, sampled, dsc } = { - ...isolationScope.getPropagationContext(), - ...scope.getPropagationContext(), - }; - - const sentryTraceHeader = span ? spanToTraceHeader(span) : generateSentryTraceHeader(traceId, spanId, sampled); - - const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader( - dsc || (span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromClient(traceId, client)), - ); + // Nothing to do, when we return undefined here, the original headers will be used + if (!sentryTrace) { + return undefined; + } - const headers = - fetchOptionsObj.headers || - (typeof Request !== 'undefined' && isInstanceOf(request, Request) ? (request as Request).headers : undefined); + const headers = fetchOptionsObj.headers || (isRequest(request) ? request.headers : undefined); if (!headers) { - return { 'sentry-trace': sentryTraceHeader, baggage: sentryBaggageHeader }; - } else if (typeof Headers !== 'undefined' && isInstanceOf(headers, Headers)) { - const newHeaders = new Headers(headers as Headers); - - newHeaders.set('sentry-trace', sentryTraceHeader); + return { ...traceHeaders }; + } else if (isHeaders(headers)) { + const newHeaders = new Headers(headers); + newHeaders.set('sentry-trace', sentryTrace); - if (sentryBaggageHeader) { + if (baggage) { const prevBaggageHeader = newHeaders.get('baggage'); if (prevBaggageHeader) { const prevHeaderStrippedFromSentryBaggage = stripBaggageHeaderOfSentryBaggageValues(prevBaggageHeader); @@ -160,16 +140,14 @@ export function addTracingHeadersToFetchRequest( 'baggage', // If there are non-sentry entries (i.e. if the stripped string is non-empty/truthy) combine the stripped header and sentry baggage header // otherwise just set the sentry baggage header - prevHeaderStrippedFromSentryBaggage - ? `${prevHeaderStrippedFromSentryBaggage},${sentryBaggageHeader}` - : sentryBaggageHeader, + prevHeaderStrippedFromSentryBaggage ? `${prevHeaderStrippedFromSentryBaggage},${baggage}` : baggage, ); } else { - newHeaders.set('baggage', sentryBaggageHeader); + newHeaders.set('baggage', baggage); } } - return newHeaders as PolymorphicRequestHeaders; + return newHeaders; } else if (Array.isArray(headers)) { const newHeaders = [ ...headers @@ -187,13 +165,13 @@ export function addTracingHeadersToFetchRequest( } }), // Attach the new sentry-trace header - ['sentry-trace', sentryTraceHeader], + ['sentry-trace', sentryTrace], ]; - if (sentryBaggageHeader) { + if (baggage) { // If there are multiple entries with the same key, the browser will merge the values into a single request header. // Its therefore safe to simply push a "baggage" entry, even though there might already be another baggage header. - newHeaders.push(['baggage', sentryBaggageHeader]); + newHeaders.push(['baggage', baggage]); } return newHeaders as PolymorphicRequestHeaders; @@ -211,18 +189,39 @@ export function addTracingHeadersToFetchRequest( newBaggageHeaders.push(stripBaggageHeaderOfSentryBaggageValues(existingBaggageHeader)); } - if (sentryBaggageHeader) { - newBaggageHeaders.push(sentryBaggageHeader); + if (baggage) { + newBaggageHeaders.push(baggage); } return { ...(headers as Exclude), - 'sentry-trace': sentryTraceHeader, + 'sentry-trace': sentryTrace, baggage: newBaggageHeaders.length > 0 ? newBaggageHeaders.join(',') : undefined, }; } } +/** + * Adds sentry-trace and baggage headers to the various forms of fetch headers. + * + * @deprecated This function will not be exported anymore in v9. + */ +export function addTracingHeadersToFetchRequest( + request: string | unknown, + _client: Client | undefined, + _scope: Scope | undefined, + fetchOptionsObj: { + headers?: + | { + [key: string]: string[] | string | undefined; + } + | PolymorphicRequestHeaders; + }, + span?: Span, +): PolymorphicRequestHeaders | undefined { + return _addTracingHeadersToFetchRequest(request as Request, fetchOptionsObj, span); +} + function getFullURL(url: string): string | undefined { try { const parsed = new URL(url); @@ -260,3 +259,11 @@ function stripBaggageHeaderOfSentryBaggageValues(baggageHeader: string): string .join(',') ); } + +function isRequest(request: unknown): request is Request { + return typeof Request !== 'undefined' && isInstanceOf(request, Request); +} + +function isHeaders(headers: unknown): headers is Headers { + return typeof Headers !== 'undefined' && isInstanceOf(headers, Headers); +} diff --git a/packages/core/src/getCurrentHubShim.ts b/packages/core/src/getCurrentHubShim.ts index 46f8f94cb490..ceea470a727c 100644 --- a/packages/core/src/getCurrentHubShim.ts +++ b/packages/core/src/getCurrentHubShim.ts @@ -1,4 +1,3 @@ -import type { Client, EventHint, Hub, Integration, IntegrationClass, SeverityLevel } from '@sentry/types'; import { addBreadcrumb } from './breadcrumbs'; import { getClient, getCurrentScope, getIsolationScope, withScope } from './currentScopes'; import { @@ -12,6 +11,7 @@ import { setUser, startSession, } from './exports'; +import type { Client, EventHint, Hub, Integration, IntegrationClass, SeverityLevel } from './types-hoist'; /** * This is for legacy reasons, and returns a proxy object instead of a hub to be used. diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c56c568d092f..751279cde693 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,3 @@ -// TODO(v9): Don't have this file be in the "utils-hoist" folder but "utils" folder - it's cleaner - export type { ClientClass as SentryCoreCurrentScopes } from './sdk'; export type { AsyncContextStrategy } from './asyncContext/types'; export type { Carrier } from './carrier'; @@ -40,6 +38,7 @@ export { withScope, withIsolationScope, getClient, + getTraceContextFromScope, } from './currentScopes'; export { getDefaultCurrentScope, @@ -106,16 +105,22 @@ export { thirdPartyErrorFilterIntegration } from './integrations/third-party-err // eslint-disable-next-line deprecation/deprecation export { metrics } from './metrics/exports'; export { profiler } from './profiling'; -export type { MetricData } from '@sentry/types'; // eslint-disable-next-line deprecation/deprecation export { metricsDefault } from './metrics/exports-default'; export { BrowserMetricsAggregator } from './metrics/browser-aggregator'; export { getMetricSummaryJsonForSpan } from './metrics/metric-summary'; -export { addTracingHeadersToFetchRequest, instrumentFetchRequest } from './fetch'; +export { + // eslint-disable-next-line deprecation/deprecation + addTracingHeadersToFetchRequest, + instrumentFetchRequest, +} from './fetch'; export { trpcMiddleware } from './trpc'; export { captureFeedback } from './feedback'; // eslint-disable-next-line deprecation/deprecation export { getCurrentHubShim, getCurrentHub } from './getCurrentHubShim'; +// TODO(v9): Make this structure pretty again and don't do "export *" export * from './utils-hoist/index'; +// TODO(v9): Make this structure pretty again and don't do "export *" +export * from './types-hoist/index'; diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts index 9f447163d8f0..f4432ebf2d0a 100644 --- a/packages/core/src/integration.ts +++ b/packages/core/src/integration.ts @@ -1,15 +1,9 @@ -import type { Client, Event, EventHint, Integration, IntegrationFn, Options } from '@sentry/types'; import { getClient } from './currentScopes'; +import type { Client, Event, EventHint, Integration, IntegrationFn, Options } from './types-hoist'; import { DEBUG_BUILD } from './debug-build'; import { logger } from './utils-hoist/logger'; -declare module '@sentry/types' { - interface Integration { - isDefaultInstance?: boolean; - } -} - export const installedIntegrations: string[] = []; /** Map of integrations assigned to a client */ @@ -17,6 +11,8 @@ export type IntegrationIndex = { [key: string]: Integration; }; +type IntegrationWithDefaultInstance = Integration & { isDefaultInstance?: true }; + /** * Remove duplicates from the given array, preferring the last instance of any duplicate. Not guaranteed to * preserve the order of integrations in the array. @@ -26,10 +22,10 @@ export type IntegrationIndex = { function filterDuplicates(integrations: Integration[]): Integration[] { const integrationsByName: { [key: string]: Integration } = {}; - integrations.forEach(currentInstance => { + integrations.forEach((currentInstance: IntegrationWithDefaultInstance) => { const { name } = currentInstance; - const existingInstance = integrationsByName[name]; + const existingInstance: IntegrationWithDefaultInstance | undefined = integrationsByName[name]; // We want integrations later in the array to overwrite earlier ones of the same type, except that we never want a // default instance to overwrite an existing user instance @@ -49,7 +45,7 @@ export function getIntegrationsToSetup(options: Pick { + defaultIntegrations.forEach((integration: IntegrationWithDefaultInstance) => { integration.isDefaultInstance = true; }); diff --git a/packages/core/src/integrations/captureconsole.ts b/packages/core/src/integrations/captureconsole.ts index aec865320d52..563296511fd6 100644 --- a/packages/core/src/integrations/captureconsole.ts +++ b/packages/core/src/integrations/captureconsole.ts @@ -1,7 +1,7 @@ -import type { CaptureContext, IntegrationFn } from '@sentry/types'; import { getClient, withScope } from '../currentScopes'; import { captureException, captureMessage } from '../exports'; import { defineIntegration } from '../integration'; +import type { CaptureContext, IntegrationFn } from '../types-hoist'; import { addConsoleInstrumentationHandler } from '../utils-hoist/instrument/console'; import { CONSOLE_LEVELS } from '../utils-hoist/logger'; import { addExceptionMechanism } from '../utils-hoist/misc'; diff --git a/packages/core/src/integrations/debug.ts b/packages/core/src/integrations/debug.ts index 4c372e2942bb..66c70571365a 100644 --- a/packages/core/src/integrations/debug.ts +++ b/packages/core/src/integrations/debug.ts @@ -1,5 +1,5 @@ -import type { Event, EventHint, IntegrationFn } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { Event, EventHint, IntegrationFn } from '../types-hoist'; import { consoleSandbox } from '../utils-hoist/logger'; const INTEGRATION_NAME = 'Debug'; diff --git a/packages/core/src/integrations/dedupe.ts b/packages/core/src/integrations/dedupe.ts index d0a3b75e9f0c..7687c1f5b73e 100644 --- a/packages/core/src/integrations/dedupe.ts +++ b/packages/core/src/integrations/dedupe.ts @@ -1,5 +1,5 @@ -import type { Event, Exception, IntegrationFn, StackFrame } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { Event, Exception, IntegrationFn, StackFrame } from '../types-hoist'; import { DEBUG_BUILD } from '../debug-build'; import { logger } from '../utils-hoist/logger'; diff --git a/packages/core/src/integrations/extraerrordata.ts b/packages/core/src/integrations/extraerrordata.ts index d56d82daa2c1..9a74135db2a8 100644 --- a/packages/core/src/integrations/extraerrordata.ts +++ b/packages/core/src/integrations/extraerrordata.ts @@ -1,5 +1,5 @@ -import type { Contexts, Event, EventHint, ExtendedError, IntegrationFn } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { Contexts, Event, EventHint, ExtendedError, IntegrationFn } from '../types-hoist'; import { DEBUG_BUILD } from '../debug-build'; import { isError, isPlainObject } from '../utils-hoist/is'; diff --git a/packages/core/src/integrations/functiontostring.ts b/packages/core/src/integrations/functiontostring.ts index b43c882f381f..ddac187ac7c9 100644 --- a/packages/core/src/integrations/functiontostring.ts +++ b/packages/core/src/integrations/functiontostring.ts @@ -1,6 +1,6 @@ -import type { Client, IntegrationFn, WrappedFunction } from '@sentry/types'; import { getClient } from '../currentScopes'; import { defineIntegration } from '../integration'; +import type { Client, IntegrationFn, WrappedFunction } from '../types-hoist'; import { getOriginalFunction } from '../utils-hoist/object'; let originalFunctionToString: () => void; diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index f03068cabf26..c78b602d3304 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -1,4 +1,4 @@ -import type { Event, IntegrationFn, StackFrame } from '@sentry/types'; +import type { Event, IntegrationFn, StackFrame } from '../types-hoist'; import { DEBUG_BUILD } from '../debug-build'; import { defineIntegration } from '../integration'; diff --git a/packages/core/src/integrations/linkederrors.ts b/packages/core/src/integrations/linkederrors.ts index fc2f62ec120e..caaefae1a6d5 100644 --- a/packages/core/src/integrations/linkederrors.ts +++ b/packages/core/src/integrations/linkederrors.ts @@ -1,5 +1,5 @@ -import type { IntegrationFn } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { IntegrationFn } from '../types-hoist'; import { applyAggregateErrorsToEvent } from '../utils-hoist/aggregate-errors'; import { exceptionFromError } from '../utils-hoist/eventbuilder'; diff --git a/packages/core/src/integrations/metadata.ts b/packages/core/src/integrations/metadata.ts index 1f02b57461b5..dc1107d5d423 100644 --- a/packages/core/src/integrations/metadata.ts +++ b/packages/core/src/integrations/metadata.ts @@ -1,5 +1,5 @@ -import type { EventItem } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { EventItem } from '../types-hoist'; import { addMetadataToStackFrames, stripMetadataFromStackFrames } from '../metadata'; import { forEachEnvelopeItem } from '../utils-hoist/envelope'; diff --git a/packages/core/src/integrations/requestdata.ts b/packages/core/src/integrations/requestdata.ts index cce86a8966c8..8f23912c5b58 100644 --- a/packages/core/src/integrations/requestdata.ts +++ b/packages/core/src/integrations/requestdata.ts @@ -1,5 +1,5 @@ -import type { IntegrationFn } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { IntegrationFn } from '../types-hoist'; import { type AddRequestDataToEventOptions, addNormalizedRequestDataToEvent, diff --git a/packages/core/src/integrations/rewriteframes.ts b/packages/core/src/integrations/rewriteframes.ts index 88e9038cfd47..ab9d1b812987 100644 --- a/packages/core/src/integrations/rewriteframes.ts +++ b/packages/core/src/integrations/rewriteframes.ts @@ -1,5 +1,5 @@ -import type { Event, StackFrame, Stacktrace } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { Event, StackFrame, Stacktrace } from '../types-hoist'; import { basename, relative } from '../utils-hoist/path'; import { GLOBAL_OBJ } from '../utils-hoist/worldwide'; diff --git a/packages/core/src/integrations/sessiontiming.ts b/packages/core/src/integrations/sessiontiming.ts index e52cb3c97482..a7112c4f939c 100644 --- a/packages/core/src/integrations/sessiontiming.ts +++ b/packages/core/src/integrations/sessiontiming.ts @@ -1,5 +1,5 @@ -import type { IntegrationFn } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { IntegrationFn } from '../types-hoist'; import { timestampInSeconds } from '../utils-hoist/time'; const INTEGRATION_NAME = 'SessionTiming'; diff --git a/packages/core/src/integrations/third-party-errors-filter.ts b/packages/core/src/integrations/third-party-errors-filter.ts index 5e64a8736826..9e5e776a5b0f 100644 --- a/packages/core/src/integrations/third-party-errors-filter.ts +++ b/packages/core/src/integrations/third-party-errors-filter.ts @@ -1,6 +1,6 @@ -import type { Event, EventItem } from '@sentry/types'; import { defineIntegration } from '../integration'; import { addMetadataToStackFrames, stripMetadataFromStackFrames } from '../metadata'; +import type { Event, EventItem } from '../types-hoist'; import { forEachEnvelopeItem } from '../utils-hoist/envelope'; import { getFramesFromEvent } from '../utils-hoist/stacktrace'; diff --git a/packages/core/src/integrations/zoderrors.ts b/packages/core/src/integrations/zoderrors.ts index 1c2cb8e59b56..fc36925eb0ea 100644 --- a/packages/core/src/integrations/zoderrors.ts +++ b/packages/core/src/integrations/zoderrors.ts @@ -1,6 +1,5 @@ -import type { IntegrationFn } from '@sentry/types'; -import type { Event, EventHint } from '@sentry/types'; import { defineIntegration } from '../integration'; +import type { Event, EventHint, IntegrationFn } from '../types-hoist'; import { isError } from '../utils-hoist/is'; import { truncate } from '../utils-hoist/string'; diff --git a/packages/core/src/metadata.ts b/packages/core/src/metadata.ts index 11a0af6eaadb..a3933dc2a45f 100644 --- a/packages/core/src/metadata.ts +++ b/packages/core/src/metadata.ts @@ -1,4 +1,4 @@ -import type { Event, StackParser } from '@sentry/types'; +import type { Event, StackParser } from './types-hoist'; import { GLOBAL_OBJ } from './utils-hoist/worldwide'; /** Keys are source filename/url, values are metadata objects. */ diff --git a/packages/core/src/metrics/aggregator.ts b/packages/core/src/metrics/aggregator.ts index 0fee0551fc66..b3213ef87f0c 100644 --- a/packages/core/src/metrics/aggregator.ts +++ b/packages/core/src/metrics/aggregator.ts @@ -1,4 +1,4 @@ -import type { Client, MeasurementUnit, MetricsAggregator as MetricsAggregatorBase, Primitive } from '@sentry/types'; +import type { Client, MeasurementUnit, MetricsAggregator as MetricsAggregatorBase, Primitive } from '../types-hoist'; import { timestampInSeconds } from '../utils-hoist/time'; import { updateMetricSummaryOnActiveSpan } from '../utils/spanUtils'; import { DEFAULT_FLUSH_INTERVAL, MAX_WEIGHT, SET_METRIC_TYPE } from './constants'; @@ -20,9 +20,8 @@ export class MetricsAggregator implements MetricsAggregatorBase { // that we store in memory. private _bucketsTotalWeight; - // Cast to any so that it can use Node.js timeout - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private readonly _interval: any; + // We adjust the type here to add the `unref()` part, as setInterval can technically return a number of a NodeJS.Timer. + private readonly _interval: ReturnType & { unref?: () => void }; // SDKs are required to shift the flush interval by random() * rollup_in_seconds. // That shift is determined once per startup to create jittering. @@ -40,11 +39,8 @@ export class MetricsAggregator implements MetricsAggregatorBase { this._buckets = new Map(); this._bucketsTotalWeight = 0; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this._interval = setInterval(() => this._flush(), DEFAULT_FLUSH_INTERVAL) as any; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + this._interval = setInterval(() => this._flush(), DEFAULT_FLUSH_INTERVAL); if (this._interval.unref) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access this._interval.unref(); } diff --git a/packages/core/src/metrics/browser-aggregator.ts b/packages/core/src/metrics/browser-aggregator.ts index 0818f691f313..fca72f48f40f 100644 --- a/packages/core/src/metrics/browser-aggregator.ts +++ b/packages/core/src/metrics/browser-aggregator.ts @@ -1,4 +1,4 @@ -import type { Client, MeasurementUnit, MetricsAggregator, Primitive } from '@sentry/types'; +import type { Client, MeasurementUnit, MetricsAggregator, Primitive } from '../types-hoist'; import { timestampInSeconds } from '../utils-hoist/time'; import { updateMetricSummaryOnActiveSpan } from '../utils/spanUtils'; import { DEFAULT_BROWSER_FLUSH_INTERVAL, SET_METRIC_TYPE } from './constants'; diff --git a/packages/core/src/metrics/envelope.ts b/packages/core/src/metrics/envelope.ts index 8924df587771..7c1a4d612577 100644 --- a/packages/core/src/metrics/envelope.ts +++ b/packages/core/src/metrics/envelope.ts @@ -1,4 +1,4 @@ -import type { Client, DsnComponents, MetricBucketItem, SdkMetadata, StatsdEnvelope, StatsdItem } from '@sentry/types'; +import type { Client, DsnComponents, MetricBucketItem, SdkMetadata, StatsdEnvelope, StatsdItem } from '../types-hoist'; import { dsnToString } from '../utils-hoist/dsn'; import { createEnvelope } from '../utils-hoist/envelope'; import { logger } from '../utils-hoist/logger'; diff --git a/packages/core/src/metrics/exports-default.ts b/packages/core/src/metrics/exports-default.ts index 7a271696f025..e071015b73f1 100644 --- a/packages/core/src/metrics/exports-default.ts +++ b/packages/core/src/metrics/exports-default.ts @@ -4,7 +4,7 @@ import type { MetricData, Metrics, MetricsAggregator as MetricsAggregatorInterface, -} from '@sentry/types'; +} from '../types-hoist'; import { MetricsAggregator } from './aggregator'; import { metrics as metricsCore } from './exports'; diff --git a/packages/core/src/metrics/exports.ts b/packages/core/src/metrics/exports.ts index 96a52f62e5c9..00f100bcaeb2 100644 --- a/packages/core/src/metrics/exports.ts +++ b/packages/core/src/metrics/exports.ts @@ -1,7 +1,7 @@ -import type { Client, DurationUnit, MetricData, MetricsAggregator as MetricsAggregatorInterface } from '@sentry/types'; import { getClient } from '../currentScopes'; import { DEBUG_BUILD } from '../debug-build'; import { startSpanManual } from '../tracing'; +import type { Client, DurationUnit, MetricData, MetricsAggregator as MetricsAggregatorInterface } from '../types-hoist'; import { logger } from '../utils-hoist/logger'; import { timestampInSeconds } from '../utils-hoist/time'; import { getGlobalSingleton } from '../utils-hoist/worldwide'; diff --git a/packages/core/src/metrics/instance.ts b/packages/core/src/metrics/instance.ts index f7d37d8118ed..28b57ae7f75c 100644 --- a/packages/core/src/metrics/instance.ts +++ b/packages/core/src/metrics/instance.ts @@ -1,4 +1,4 @@ -import type { MetricInstance } from '@sentry/types'; +import type { MetricInstance } from '../types-hoist'; import { COUNTER_METRIC_TYPE, DISTRIBUTION_METRIC_TYPE, GAUGE_METRIC_TYPE, SET_METRIC_TYPE } from './constants'; import { simpleHash } from './utils'; diff --git a/packages/core/src/metrics/metric-summary.ts b/packages/core/src/metrics/metric-summary.ts index 90a3365ccdaf..e7a8a00c289a 100644 --- a/packages/core/src/metrics/metric-summary.ts +++ b/packages/core/src/metrics/metric-summary.ts @@ -1,6 +1,6 @@ -import type { MeasurementUnit, Span } from '@sentry/types'; -import type { MetricSummary } from '@sentry/types'; -import type { Primitive } from '@sentry/types'; +import type { MeasurementUnit, Span } from '../types-hoist'; +import type { MetricSummary } from '../types-hoist'; +import type { Primitive } from '../types-hoist'; import { dropUndefinedKeys } from '../utils-hoist/object'; import type { MetricType } from './types'; diff --git a/packages/core/src/metrics/types.ts b/packages/core/src/metrics/types.ts index 000c401e7a34..d1d01cd1abab 100644 --- a/packages/core/src/metrics/types.ts +++ b/packages/core/src/metrics/types.ts @@ -1,4 +1,4 @@ -import type { MetricBucketItem } from '@sentry/types'; +import type { MetricBucketItem } from '../types-hoist'; import type { COUNTER_METRIC_TYPE, DISTRIBUTION_METRIC_TYPE, GAUGE_METRIC_TYPE, SET_METRIC_TYPE } from './constants'; export type MetricType = diff --git a/packages/core/src/metrics/utils.ts b/packages/core/src/metrics/utils.ts index 06df4a96bced..903a185e27f3 100644 --- a/packages/core/src/metrics/utils.ts +++ b/packages/core/src/metrics/utils.ts @@ -1,4 +1,4 @@ -import type { MeasurementUnit, MetricBucketItem, Primitive } from '@sentry/types'; +import type { MeasurementUnit, MetricBucketItem, Primitive } from '../types-hoist'; import { dropUndefinedKeys } from '../utils-hoist/object'; import type { MetricType } from './types'; diff --git a/packages/core/src/profiling.ts b/packages/core/src/profiling.ts index 877f9d71ac15..9f55a3879b8d 100644 --- a/packages/core/src/profiling.ts +++ b/packages/core/src/profiling.ts @@ -1,4 +1,4 @@ -import type { Profiler, ProfilingIntegration } from '@sentry/types'; +import type { Profiler, ProfilingIntegration } from './types-hoist'; import { getClient } from './currentScopes'; import { DEBUG_BUILD } from './debug-build'; diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index e03f378cac20..656ada3d6355 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -20,13 +20,13 @@ import type { Session, SeverityLevel, User, -} from '@sentry/types'; +} from './types-hoist'; import { updateSession } from './session'; import { isPlainObject } from './utils-hoist/is'; import { logger } from './utils-hoist/logger'; import { uuid4 } from './utils-hoist/misc'; -import { generatePropagationContext } from './utils-hoist/propagationContext'; +import { generateSpanId, generateTraceId } from './utils-hoist/propagationContext'; import { dateTimestampInSeconds } from './utils-hoist/time'; import { merge } from './utils/merge'; import { _getSpanForScope, _setSpanForScope } from './utils/spanOnScope'; @@ -115,7 +115,10 @@ class ScopeClass implements ScopeInterface { this._extra = {}; this._contexts = {}; this._sdkProcessingMetadata = {}; - this._propagationContext = generatePropagationContext(); + this._propagationContext = { + traceId: generateTraceId(), + spanId: generateSpanId(), + }; } /** @@ -398,7 +401,7 @@ class ScopeClass implements ScopeInterface { this._session = undefined; _setSpanForScope(this, undefined); this._attachments = []; - this._propagationContext = generatePropagationContext(); + this.setPropagationContext({ traceId: generateTraceId() }); this._notifyScopeListeners(); return this; @@ -491,8 +494,14 @@ class ScopeClass implements ScopeInterface { /** * @inheritDoc */ - public setPropagationContext(context: PropagationContext): this { - this._propagationContext = context; + public setPropagationContext( + context: Omit & Partial>, + ): this { + this._propagationContext = { + // eslint-disable-next-line deprecation/deprecation + spanId: generateSpanId(), + ...context, + }; return this; } @@ -591,10 +600,6 @@ class ScopeClass implements ScopeInterface { } } -// NOTE: By exporting this here as const & type, instead of doing `export class`, -// We can get the correct class when importing from `@sentry/core`, but the original type (from `@sentry/types`) -// This is helpful for interop, e.g. when doing `import type { Scope } from '@sentry/node';` (which re-exports this) - /** * Holds additional event information. */ diff --git a/packages/core/src/sdk.ts b/packages/core/src/sdk.ts index 82895b9a03f9..64037fa37d5c 100644 --- a/packages/core/src/sdk.ts +++ b/packages/core/src/sdk.ts @@ -1,5 +1,5 @@ -import type { Client, ClientOptions } from '@sentry/types'; import { getCurrentScope } from './currentScopes'; +import type { Client, ClientOptions } from './types-hoist'; import { DEBUG_BUILD } from './debug-build'; import { consoleSandbox, logger } from './utils-hoist/logger'; diff --git a/packages/core/src/server-runtime-client.ts b/packages/core/src/server-runtime-client.ts index 93c1051ed6ec..5435d5c8fff0 100644 --- a/packages/core/src/server-runtime-client.ts +++ b/packages/core/src/server-runtime-client.ts @@ -10,16 +10,16 @@ import type { SerializedCheckIn, SeverityLevel, TraceContext, -} from '@sentry/types'; +} from './types-hoist'; import { BaseClient } from './baseclient'; import { createCheckInEnvelope } from './checkin'; -import { getIsolationScope } from './currentScopes'; +import { getIsolationScope, getTraceContextFromScope } from './currentScopes'; import { DEBUG_BUILD } from './debug-build'; import type { Scope } from './scope'; import { SessionFlusher } from './sessionflusher'; import { - getDynamicSamplingContextFromClient, + getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan, registerSpanErrorInstrumentation, } from './tracing'; @@ -28,7 +28,7 @@ import { logger } from './utils-hoist/logger'; import { uuid4 } from './utils-hoist/misc'; import { resolvedSyncPromise } from './utils-hoist/syncpromise'; import { _getSpanForScope } from './utils/spanOnScope'; -import { getRootSpan, spanToTraceContext } from './utils/spanUtils'; +import { spanToTraceContext } from './utils/spanUtils'; export interface ServerRuntimeClientOptions extends ClientOptions { platform?: string; @@ -251,7 +251,7 @@ export class ServerRuntimeClient< } /** Extract trace information from scope */ - private _getTraceInfoFromScope( + protected _getTraceInfoFromScope( scope: Scope | undefined, ): [dynamicSamplingContext: Partial | undefined, traceContext: TraceContext | undefined] { if (!scope) { @@ -259,22 +259,11 @@ export class ServerRuntimeClient< } const span = _getSpanForScope(scope); - if (span) { - const rootSpan = getRootSpan(span); - const samplingContext = getDynamicSamplingContextFromSpan(rootSpan); - return [samplingContext, spanToTraceContext(rootSpan)]; - } - - const { traceId, spanId, parentSpanId, dsc } = scope.getPropagationContext(); - const traceContext: TraceContext = { - trace_id: traceId, - span_id: spanId, - parent_span_id: parentSpanId, - }; - if (dsc) { - return [dsc, traceContext]; - } - return [getDynamicSamplingContextFromClient(traceId, this), traceContext]; + const traceContext = span ? spanToTraceContext(span) : getTraceContextFromScope(scope); + const dynamicSamplingContext = span + ? getDynamicSamplingContextFromSpan(span) + : getDynamicSamplingContextFromScope(this, scope); + return [dynamicSamplingContext, traceContext]; } } diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index bf584482e87b..058fd7d68c14 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -1,4 +1,4 @@ -import type { SerializedSession, Session, SessionContext, SessionStatus } from '@sentry/types'; +import type { SerializedSession, Session, SessionContext, SessionStatus } from './types-hoist'; import { dropUndefinedKeys, timestampInSeconds, uuid4 } from './utils-hoist'; /** diff --git a/packages/core/src/sessionflusher.ts b/packages/core/src/sessionflusher.ts index 8734c0de2f12..e35b8f70785d 100644 --- a/packages/core/src/sessionflusher.ts +++ b/packages/core/src/sessionflusher.ts @@ -1,11 +1,11 @@ +import { getIsolationScope } from './currentScopes'; import type { AggregationCounts, Client, RequestSessionStatus, SessionAggregates, SessionFlusherLike, -} from '@sentry/types'; -import { getIsolationScope } from './currentScopes'; +} from './types-hoist'; import { dropUndefinedKeys } from './utils-hoist/object'; type ReleaseHealthAttributes = { diff --git a/packages/core/src/tracing/dynamicSamplingContext.ts b/packages/core/src/tracing/dynamicSamplingContext.ts index 1e8ca0448b3b..cdf6951fe95b 100644 --- a/packages/core/src/tracing/dynamicSamplingContext.ts +++ b/packages/core/src/tracing/dynamicSamplingContext.ts @@ -1,4 +1,4 @@ -import type { Client, DynamicSamplingContext, Span } from '@sentry/types'; +import type { Client, DynamicSamplingContext, Scope, Span } from '../types-hoist'; import { DEFAULT_ENVIRONMENT } from '../constants'; import { getClient } from '../currentScopes'; @@ -51,6 +51,14 @@ export function getDynamicSamplingContextFromClient(trace_id: string, client: Cl return dsc; } +/** + * Get the dynamic sampling context for the currently active scopes. + */ +export function getDynamicSamplingContextFromScope(client: Client, scope: Scope): Partial { + const propagationContext = scope.getPropagationContext(); + return propagationContext.dsc || getDynamicSamplingContextFromClient(propagationContext.traceId, client); +} + /** * Creates a dynamic sampling context from a span (and client and scope) * @@ -64,8 +72,6 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly(callback: () => T): T { */ export function startNewTrace(callback: () => T): T { return withScope(scope => { - scope.setPropagationContext(generatePropagationContext()); + scope.setPropagationContext({ traceId: generateTraceId() }); DEBUG_BUILD && logger.info(`Starting a new trace with id ${scope.getPropagationContext().traceId}`); return withActiveSpan(null, callback); }); diff --git a/packages/core/src/tracing/utils.ts b/packages/core/src/tracing/utils.ts index 80ad6762dfb8..a0442aa0eeec 100644 --- a/packages/core/src/tracing/utils.ts +++ b/packages/core/src/tracing/utils.ts @@ -1,5 +1,5 @@ -import type { Span } from '@sentry/types'; -import type { Scope } from '@sentry/types'; +import type { Span } from '../types-hoist'; +import type { Scope } from '../types-hoist'; import { addNonEnumerableProperty } from '../utils-hoist/object'; const SCOPE_ON_START_SPAN_FIELD = '_sentryScope'; diff --git a/packages/core/src/transports/base.ts b/packages/core/src/transports/base.ts index d2f02fc32a82..5303e43e6adf 100644 --- a/packages/core/src/transports/base.ts +++ b/packages/core/src/transports/base.ts @@ -9,7 +9,7 @@ import type { Transport, TransportMakeRequestResponse, TransportRequestExecutor, -} from '@sentry/types'; +} from '../types-hoist'; import { DEBUG_BUILD } from '../debug-build'; import { @@ -61,8 +61,7 @@ export function createTransport( return resolvedSyncPromise({}); } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const filteredEnvelope: Envelope = createEnvelope(envelope[0], filteredEnvelopeItems as any); + const filteredEnvelope: Envelope = createEnvelope(envelope[0], filteredEnvelopeItems as (typeof envelope)[1]); // Creates client report for each item in an envelope const recordEnvelopeLoss = (reason: EventDropReason): void => { diff --git a/packages/core/src/transports/multiplexed.ts b/packages/core/src/transports/multiplexed.ts index afb839b15863..29534fd13d9b 100644 --- a/packages/core/src/transports/multiplexed.ts +++ b/packages/core/src/transports/multiplexed.ts @@ -6,7 +6,7 @@ import type { EventItem, Transport, TransportMakeRequestResponse, -} from '@sentry/types'; +} from '../types-hoist'; import { getEnvelopeEndpointWithUrlEncodedAuth } from '../api'; import { dsnFromString } from '../utils-hoist/dsn'; diff --git a/packages/core/src/transports/offline.ts b/packages/core/src/transports/offline.ts index f8d3196dd7b5..cf8902739db7 100644 --- a/packages/core/src/transports/offline.ts +++ b/packages/core/src/transports/offline.ts @@ -1,4 +1,4 @@ -import type { Envelope, InternalBaseTransportOptions, Transport, TransportMakeRequestResponse } from '@sentry/types'; +import type { Envelope, InternalBaseTransportOptions, Transport, TransportMakeRequestResponse } from '../types-hoist'; import { DEBUG_BUILD } from '../debug-build'; import { envelopeContainsItemType } from '../utils-hoist/envelope'; diff --git a/packages/types/src/attachment.ts b/packages/core/src/types-hoist/attachment.ts similarity index 100% rename from packages/types/src/attachment.ts rename to packages/core/src/types-hoist/attachment.ts diff --git a/packages/types/src/breadcrumb.ts b/packages/core/src/types-hoist/breadcrumb.ts similarity index 100% rename from packages/types/src/breadcrumb.ts rename to packages/core/src/types-hoist/breadcrumb.ts diff --git a/packages/types/src/browseroptions.ts b/packages/core/src/types-hoist/browseroptions.ts similarity index 86% rename from packages/types/src/browseroptions.ts rename to packages/core/src/types-hoist/browseroptions.ts index 63341322ff56..1df40c6fd614 100644 --- a/packages/types/src/browseroptions.ts +++ b/packages/core/src/types-hoist/browseroptions.ts @@ -1,6 +1,6 @@ /** * Options added to the Browser SDK's init options that are specific for Replay. - * Note: This type was moved to @sentry/types to avoid a circular dependency between Browser and Replay. + * Note: This type was moved to @sentry/core to avoid a circular dependency between Browser and Replay. */ export type BrowserClientReplayOptions = { /** diff --git a/packages/types/src/checkin.ts b/packages/core/src/types-hoist/checkin.ts similarity index 100% rename from packages/types/src/checkin.ts rename to packages/core/src/types-hoist/checkin.ts diff --git a/packages/types/src/client.ts b/packages/core/src/types-hoist/client.ts similarity index 100% rename from packages/types/src/client.ts rename to packages/core/src/types-hoist/client.ts diff --git a/packages/types/src/clientreport.ts b/packages/core/src/types-hoist/clientreport.ts similarity index 100% rename from packages/types/src/clientreport.ts rename to packages/core/src/types-hoist/clientreport.ts diff --git a/packages/types/src/context.ts b/packages/core/src/types-hoist/context.ts similarity index 100% rename from packages/types/src/context.ts rename to packages/core/src/types-hoist/context.ts diff --git a/packages/types/src/datacategory.ts b/packages/core/src/types-hoist/datacategory.ts similarity index 100% rename from packages/types/src/datacategory.ts rename to packages/core/src/types-hoist/datacategory.ts diff --git a/packages/types/src/debugMeta.ts b/packages/core/src/types-hoist/debugMeta.ts similarity index 100% rename from packages/types/src/debugMeta.ts rename to packages/core/src/types-hoist/debugMeta.ts diff --git a/packages/types/src/dsn.ts b/packages/core/src/types-hoist/dsn.ts similarity index 100% rename from packages/types/src/dsn.ts rename to packages/core/src/types-hoist/dsn.ts diff --git a/packages/types/src/envelope.ts b/packages/core/src/types-hoist/envelope.ts similarity index 100% rename from packages/types/src/envelope.ts rename to packages/core/src/types-hoist/envelope.ts diff --git a/packages/types/src/error.ts b/packages/core/src/types-hoist/error.ts similarity index 100% rename from packages/types/src/error.ts rename to packages/core/src/types-hoist/error.ts diff --git a/packages/types/src/event.ts b/packages/core/src/types-hoist/event.ts similarity index 100% rename from packages/types/src/event.ts rename to packages/core/src/types-hoist/event.ts diff --git a/packages/types/src/eventprocessor.ts b/packages/core/src/types-hoist/eventprocessor.ts similarity index 100% rename from packages/types/src/eventprocessor.ts rename to packages/core/src/types-hoist/eventprocessor.ts diff --git a/packages/types/src/exception.ts b/packages/core/src/types-hoist/exception.ts similarity index 100% rename from packages/types/src/exception.ts rename to packages/core/src/types-hoist/exception.ts diff --git a/packages/types/src/extra.ts b/packages/core/src/types-hoist/extra.ts similarity index 100% rename from packages/types/src/extra.ts rename to packages/core/src/types-hoist/extra.ts diff --git a/packages/types/src/feedback/config.ts b/packages/core/src/types-hoist/feedback/config.ts similarity index 100% rename from packages/types/src/feedback/config.ts rename to packages/core/src/types-hoist/feedback/config.ts diff --git a/packages/types/src/feedback/form.ts b/packages/core/src/types-hoist/feedback/form.ts similarity index 100% rename from packages/types/src/feedback/form.ts rename to packages/core/src/types-hoist/feedback/form.ts diff --git a/packages/types/src/feedback/index.ts b/packages/core/src/types-hoist/feedback/index.ts similarity index 100% rename from packages/types/src/feedback/index.ts rename to packages/core/src/types-hoist/feedback/index.ts diff --git a/packages/types/src/feedback/sendFeedback.ts b/packages/core/src/types-hoist/feedback/sendFeedback.ts similarity index 100% rename from packages/types/src/feedback/sendFeedback.ts rename to packages/core/src/types-hoist/feedback/sendFeedback.ts diff --git a/packages/types/src/feedback/theme.ts b/packages/core/src/types-hoist/feedback/theme.ts similarity index 100% rename from packages/types/src/feedback/theme.ts rename to packages/core/src/types-hoist/feedback/theme.ts diff --git a/packages/types/src/hub.ts b/packages/core/src/types-hoist/hub.ts similarity index 100% rename from packages/types/src/hub.ts rename to packages/core/src/types-hoist/hub.ts diff --git a/packages/core/src/types-hoist/index.ts b/packages/core/src/types-hoist/index.ts new file mode 100644 index 000000000000..5dd1839aeba7 --- /dev/null +++ b/packages/core/src/types-hoist/index.ts @@ -0,0 +1,181 @@ +export type { Attachment } from './attachment'; +export type { + Breadcrumb, + BreadcrumbHint, + FetchBreadcrumbData, + XhrBreadcrumbData, + FetchBreadcrumbHint, + XhrBreadcrumbHint, +} from './breadcrumb'; +export type { Client } from './client'; +export type { ClientReport, Outcome, EventDropReason } from './clientreport'; +export type { + Context, + Contexts, + DeviceContext, + OsContext, + AppContext, + CultureContext, + TraceContext, + CloudResourceContext, + MissingInstrumentationContext, +} from './context'; +export type { DataCategory } from './datacategory'; +export type { DsnComponents, DsnLike, DsnProtocol } from './dsn'; +export type { DebugImage, DebugMeta } from './debugMeta'; +export type { + AttachmentItem, + BaseEnvelopeHeaders, + BaseEnvelopeItemHeaders, + ClientReportEnvelope, + ClientReportItem, + DynamicSamplingContext, + Envelope, + EnvelopeItemType, + EnvelopeItem, + EventEnvelope, + EventEnvelopeHeaders, + EventItem, + ReplayEnvelope, + FeedbackItem, + SessionEnvelope, + SessionItem, + UserFeedbackItem, + CheckInItem, + CheckInEnvelope, + StatsdItem, + StatsdEnvelope, + ProfileItem, + ProfileChunkEnvelope, + ProfileChunkItem, + SpanEnvelope, + SpanItem, +} from './envelope'; +export type { ExtendedError } from './error'; +export type { Event, EventHint, EventType, ErrorEvent, TransactionEvent } from './event'; +export type { EventProcessor } from './eventprocessor'; +export type { Exception } from './exception'; +export type { Extra, Extras } from './extra'; +// eslint-disable-next-line deprecation/deprecation +export type { Hub } from './hub'; +export type { Integration, IntegrationClass, IntegrationFn } from './integration'; +export type { Mechanism } from './mechanism'; +export type { ExtractedNodeRequestData, HttpHeaderValue, Primitive, WorkerLocation } from './misc'; +export type { ClientOptions, Options } from './options'; +export type { Package } from './package'; +export type { PolymorphicEvent, PolymorphicRequest } from './polymorphics'; +export type { + ThreadId, + FrameId, + StackId, + ThreadCpuSample, + ThreadCpuStack, + ThreadCpuFrame, + ThreadCpuProfile, + ContinuousThreadCpuProfile, + Profile, + ProfileChunk, +} from './profiling'; +export type { ReplayEvent, ReplayRecordingData, ReplayRecordingMode } from './replay'; +export type { + FeedbackEvent, + FeedbackFormData, + FeedbackInternalOptions, + FeedbackModalIntegration, + FeedbackScreenshotIntegration, + SendFeedback, + SendFeedbackParams, + UserFeedback, +} from './feedback'; +export type { + QueryParams, + RequestEventData, + // eslint-disable-next-line deprecation/deprecation + Request, + SanitizedRequestData, +} from './request'; +export type { Runtime } from './runtime'; +export type { CaptureContext, Scope, ScopeContext, ScopeData } from './scope'; +export type { SdkInfo } from './sdkinfo'; +export type { SdkMetadata } from './sdkmetadata'; +export type { + SessionAggregates, + AggregationCounts, + Session, + SessionContext, + SessionStatus, + RequestSession, + RequestSessionStatus, + SessionFlusherLike, + SerializedSession, +} from './session'; + +export type { SeverityLevel } from './severity'; +export type { + Span, + SentrySpanArguments, + SpanOrigin, + SpanAttributeValue, + SpanAttributes, + SpanTimeInput, + SpanJSON, + SpanContextData, + TraceFlag, + MetricSummary, +} from './span'; +export type { SpanStatus } from './spanStatus'; +export type { TimedEvent } from './timedEvent'; +export type { StackFrame } from './stackframe'; +export type { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; +export type { PropagationContext, TracePropagationTargets, SerializedTraceData } from './tracing'; +export type { StartSpanOptions } from './startSpanOptions'; +export type { + TraceparentData, + TransactionSource, +} from './transaction'; +export type { CustomSamplingContext, SamplingContext } from './samplingcontext'; +export type { + DurationUnit, + InformationUnit, + FractionUnit, + MeasurementUnit, + NoneUnit, + Measurements, +} from './measurement'; +export type { Thread } from './thread'; +export type { + Transport, + TransportRequest, + TransportMakeRequestResponse, + InternalBaseTransportOptions, + BaseTransportOptions, + TransportRequestExecutor, +} from './transport'; +export type { User } from './user'; +export type { WebFetchHeaders, WebFetchRequest } from './webfetchapi'; +export type { WrappedFunction } from './wrappedfunction'; +export type { + HandlerDataFetch, + HandlerDataXhr, + HandlerDataDom, + HandlerDataConsole, + HandlerDataHistory, + HandlerDataError, + HandlerDataUnhandledRejection, + ConsoleLevel, + SentryXhrData, + SentryWrappedXMLHttpRequest, +} from './instrument'; + +export type { BrowserClientReplayOptions, BrowserClientProfilingOptions } from './browseroptions'; +export type { CheckIn, MonitorConfig, FinishedCheckIn, InProgressCheckIn, SerializedCheckIn } from './checkin'; +export type { + MetricsAggregator, + MetricBucketItem, + MetricInstance, + MetricData, + Metrics, +} from './metrics'; +export type { ParameterizedString } from './parameterize'; +export type { ContinuousProfiler, ProfilingIntegration, Profiler } from './profiling'; +export type { ViewHierarchyData, ViewHierarchyWindow } from './view-hierarchy'; diff --git a/packages/types/src/instrument.ts b/packages/core/src/types-hoist/instrument.ts similarity index 100% rename from packages/types/src/instrument.ts rename to packages/core/src/types-hoist/instrument.ts diff --git a/packages/types/src/integration.ts b/packages/core/src/types-hoist/integration.ts similarity index 100% rename from packages/types/src/integration.ts rename to packages/core/src/types-hoist/integration.ts diff --git a/packages/types/src/measurement.ts b/packages/core/src/types-hoist/measurement.ts similarity index 100% rename from packages/types/src/measurement.ts rename to packages/core/src/types-hoist/measurement.ts diff --git a/packages/types/src/mechanism.ts b/packages/core/src/types-hoist/mechanism.ts similarity index 100% rename from packages/types/src/mechanism.ts rename to packages/core/src/types-hoist/mechanism.ts diff --git a/packages/types/src/metrics.ts b/packages/core/src/types-hoist/metrics.ts similarity index 100% rename from packages/types/src/metrics.ts rename to packages/core/src/types-hoist/metrics.ts diff --git a/packages/types/src/misc.ts b/packages/core/src/types-hoist/misc.ts similarity index 100% rename from packages/types/src/misc.ts rename to packages/core/src/types-hoist/misc.ts diff --git a/packages/types/src/opentelemetry.ts b/packages/core/src/types-hoist/opentelemetry.ts similarity index 100% rename from packages/types/src/opentelemetry.ts rename to packages/core/src/types-hoist/opentelemetry.ts diff --git a/packages/types/src/options.ts b/packages/core/src/types-hoist/options.ts similarity index 100% rename from packages/types/src/options.ts rename to packages/core/src/types-hoist/options.ts diff --git a/packages/types/src/package.ts b/packages/core/src/types-hoist/package.ts similarity index 100% rename from packages/types/src/package.ts rename to packages/core/src/types-hoist/package.ts diff --git a/packages/types/src/parameterize.ts b/packages/core/src/types-hoist/parameterize.ts similarity index 100% rename from packages/types/src/parameterize.ts rename to packages/core/src/types-hoist/parameterize.ts diff --git a/packages/types/src/polymorphics.ts b/packages/core/src/types-hoist/polymorphics.ts similarity index 100% rename from packages/types/src/polymorphics.ts rename to packages/core/src/types-hoist/polymorphics.ts diff --git a/packages/types/src/profiling.ts b/packages/core/src/types-hoist/profiling.ts similarity index 100% rename from packages/types/src/profiling.ts rename to packages/core/src/types-hoist/profiling.ts diff --git a/packages/types/src/replay.ts b/packages/core/src/types-hoist/replay.ts similarity index 100% rename from packages/types/src/replay.ts rename to packages/core/src/types-hoist/replay.ts diff --git a/packages/types/src/request.ts b/packages/core/src/types-hoist/request.ts similarity index 100% rename from packages/types/src/request.ts rename to packages/core/src/types-hoist/request.ts diff --git a/packages/types/src/runtime.ts b/packages/core/src/types-hoist/runtime.ts similarity index 100% rename from packages/types/src/runtime.ts rename to packages/core/src/types-hoist/runtime.ts diff --git a/packages/types/src/samplingcontext.ts b/packages/core/src/types-hoist/samplingcontext.ts similarity index 100% rename from packages/types/src/samplingcontext.ts rename to packages/core/src/types-hoist/samplingcontext.ts diff --git a/packages/types/src/scope.ts b/packages/core/src/types-hoist/scope.ts similarity index 98% rename from packages/types/src/scope.ts rename to packages/core/src/types-hoist/scope.ts index d2c33bf0b720..d3fe29f5e4b1 100644 --- a/packages/types/src/scope.ts +++ b/packages/core/src/types-hoist/scope.ts @@ -226,7 +226,9 @@ export interface Scope { /** * Add propagation context to the scope, used for distributed tracing */ - setPropagationContext(context: PropagationContext): this; + setPropagationContext( + context: Omit & Partial>, + ): this; /** * Get propagation context from the scope, used for distributed tracing diff --git a/packages/types/src/sdkinfo.ts b/packages/core/src/types-hoist/sdkinfo.ts similarity index 100% rename from packages/types/src/sdkinfo.ts rename to packages/core/src/types-hoist/sdkinfo.ts diff --git a/packages/types/src/sdkmetadata.ts b/packages/core/src/types-hoist/sdkmetadata.ts similarity index 100% rename from packages/types/src/sdkmetadata.ts rename to packages/core/src/types-hoist/sdkmetadata.ts diff --git a/packages/types/src/session.ts b/packages/core/src/types-hoist/session.ts similarity index 100% rename from packages/types/src/session.ts rename to packages/core/src/types-hoist/session.ts diff --git a/packages/types/src/severity.ts b/packages/core/src/types-hoist/severity.ts similarity index 100% rename from packages/types/src/severity.ts rename to packages/core/src/types-hoist/severity.ts diff --git a/packages/types/src/span.ts b/packages/core/src/types-hoist/span.ts similarity index 100% rename from packages/types/src/span.ts rename to packages/core/src/types-hoist/span.ts diff --git a/packages/types/src/spanStatus.ts b/packages/core/src/types-hoist/spanStatus.ts similarity index 100% rename from packages/types/src/spanStatus.ts rename to packages/core/src/types-hoist/spanStatus.ts diff --git a/packages/types/src/stackframe.ts b/packages/core/src/types-hoist/stackframe.ts similarity index 100% rename from packages/types/src/stackframe.ts rename to packages/core/src/types-hoist/stackframe.ts diff --git a/packages/types/src/stacktrace.ts b/packages/core/src/types-hoist/stacktrace.ts similarity index 100% rename from packages/types/src/stacktrace.ts rename to packages/core/src/types-hoist/stacktrace.ts diff --git a/packages/types/src/startSpanOptions.ts b/packages/core/src/types-hoist/startSpanOptions.ts similarity index 100% rename from packages/types/src/startSpanOptions.ts rename to packages/core/src/types-hoist/startSpanOptions.ts diff --git a/packages/types/src/thread.ts b/packages/core/src/types-hoist/thread.ts similarity index 100% rename from packages/types/src/thread.ts rename to packages/core/src/types-hoist/thread.ts diff --git a/packages/types/src/timedEvent.ts b/packages/core/src/types-hoist/timedEvent.ts similarity index 100% rename from packages/types/src/timedEvent.ts rename to packages/core/src/types-hoist/timedEvent.ts diff --git a/packages/types/src/tracing.ts b/packages/core/src/types-hoist/tracing.ts similarity index 95% rename from packages/types/src/tracing.ts rename to packages/core/src/types-hoist/tracing.ts index 7af40f3507f7..c93a70c9fdd3 100644 --- a/packages/types/src/tracing.ts +++ b/packages/core/src/types-hoist/tracing.ts @@ -20,6 +20,8 @@ export interface PropagationContext { * particular execution context when performance monitoring is disabled. * * The ID of a current span (if one exists) should have precedence over this value when propagating trace data. + * + * @deprecated This value will not be used anymore in the future, and should not be set or read anymore. */ spanId: string; /** diff --git a/packages/types/src/transaction.ts b/packages/core/src/types-hoist/transaction.ts similarity index 100% rename from packages/types/src/transaction.ts rename to packages/core/src/types-hoist/transaction.ts diff --git a/packages/types/src/transport.ts b/packages/core/src/types-hoist/transport.ts similarity index 100% rename from packages/types/src/transport.ts rename to packages/core/src/types-hoist/transport.ts diff --git a/packages/types/src/user.ts b/packages/core/src/types-hoist/user.ts similarity index 100% rename from packages/types/src/user.ts rename to packages/core/src/types-hoist/user.ts diff --git a/packages/types/src/view-hierarchy.ts b/packages/core/src/types-hoist/view-hierarchy.ts similarity index 100% rename from packages/types/src/view-hierarchy.ts rename to packages/core/src/types-hoist/view-hierarchy.ts diff --git a/packages/types/src/webfetchapi.ts b/packages/core/src/types-hoist/webfetchapi.ts similarity index 100% rename from packages/types/src/webfetchapi.ts rename to packages/core/src/types-hoist/webfetchapi.ts diff --git a/packages/core/src/types-hoist/wrappedfunction.ts b/packages/core/src/types-hoist/wrappedfunction.ts new file mode 100644 index 000000000000..91960b0d59fb --- /dev/null +++ b/packages/core/src/types-hoist/wrappedfunction.ts @@ -0,0 +1,10 @@ +/** + * A function that is possibly wrapped by Sentry. + */ +// eslint-disable-next-line @typescript-eslint/ban-types +export type WrappedFunction = T & { + // TODO(v9): Remove this + [key: string]: any; + __sentry_wrapped__?: WrappedFunction; + __sentry_original__?: T; +}; diff --git a/packages/core/src/utils-hoist/aggregate-errors.ts b/packages/core/src/utils-hoist/aggregate-errors.ts index 864956ad4716..5f791183f02b 100644 --- a/packages/core/src/utils-hoist/aggregate-errors.ts +++ b/packages/core/src/utils-hoist/aggregate-errors.ts @@ -1,4 +1,4 @@ -import type { Event, EventHint, Exception, ExtendedError, StackParser } from '@sentry/types'; +import type { Event, EventHint, Exception, ExtendedError, StackParser } from '../types-hoist'; import { isInstanceOf } from './is'; import { truncate } from './string'; diff --git a/packages/core/src/utils-hoist/anr.ts b/packages/core/src/utils-hoist/anr.ts index 839903de062c..0602321117bf 100644 --- a/packages/core/src/utils-hoist/anr.ts +++ b/packages/core/src/utils-hoist/anr.ts @@ -1,4 +1,4 @@ -import type { StackFrame } from '@sentry/types'; +import type { StackFrame } from '../types-hoist'; import { filenameIsInApp } from './node-stack-trace'; import { dropUndefinedKeys } from './object'; import { UNKNOWN_FUNCTION } from './stacktrace'; diff --git a/packages/core/src/utils-hoist/baggage.ts b/packages/core/src/utils-hoist/baggage.ts index 93c8c3918748..5fb60af8a203 100644 --- a/packages/core/src/utils-hoist/baggage.ts +++ b/packages/core/src/utils-hoist/baggage.ts @@ -1,4 +1,4 @@ -import type { DynamicSamplingContext } from '@sentry/types'; +import type { DynamicSamplingContext } from '../types-hoist'; import { DEBUG_BUILD } from './debug-build'; import { isString } from './is'; diff --git a/packages/core/src/utils-hoist/breadcrumb-log-level.ts b/packages/core/src/utils-hoist/breadcrumb-log-level.ts index a19d70e00412..584e43d63364 100644 --- a/packages/core/src/utils-hoist/breadcrumb-log-level.ts +++ b/packages/core/src/utils-hoist/breadcrumb-log-level.ts @@ -1,4 +1,4 @@ -import type { SeverityLevel } from '@sentry/types'; +import type { SeverityLevel } from '../types-hoist'; /** * Determine a breadcrumb's log level (only `warning` or `error`) based on an HTTP status code. diff --git a/packages/core/src/utils-hoist/buildPolyfills/types.ts b/packages/core/src/utils-hoist/buildPolyfills/types.ts index 806f302460a8..10e2f4a944a4 100644 --- a/packages/core/src/utils-hoist/buildPolyfills/types.ts +++ b/packages/core/src/utils-hoist/buildPolyfills/types.ts @@ -1,4 +1,4 @@ -import type { Primitive } from '@sentry/types'; +import type { Primitive } from '../../types-hoist'; export type GenericObject = { [key: string]: Value }; export type GenericFunction = (...args: unknown[]) => Value; diff --git a/packages/core/src/utils-hoist/clientreport.ts b/packages/core/src/utils-hoist/clientreport.ts index c0dbb6cb3aba..65ca239a166d 100644 --- a/packages/core/src/utils-hoist/clientreport.ts +++ b/packages/core/src/utils-hoist/clientreport.ts @@ -1,4 +1,4 @@ -import type { ClientReport, ClientReportEnvelope, ClientReportItem } from '@sentry/types'; +import type { ClientReport, ClientReportEnvelope, ClientReportItem } from '../types-hoist'; import { createEnvelope } from './envelope'; import { dateTimestampInSeconds } from './time'; diff --git a/packages/core/src/utils-hoist/debug-ids.ts b/packages/core/src/utils-hoist/debug-ids.ts index 4802b9356965..859f8c10ba2b 100644 --- a/packages/core/src/utils-hoist/debug-ids.ts +++ b/packages/core/src/utils-hoist/debug-ids.ts @@ -1,7 +1,12 @@ -import type { DebugImage, StackFrame, StackParser } from '@sentry/types'; +import type { DebugImage, StackParser } from '../types-hoist'; import { GLOBAL_OBJ } from './worldwide'; -const debugIdStackParserCache = new WeakMap>(); +type StackString = string; +type CachedResult = [string, string]; + +let parsedStackResults: Record | undefined; +let lastKeysCount: number | undefined; +let cachedFilenameDebugIds: Record | undefined; /** * Returns a map of filenames to debug identifiers. @@ -12,38 +17,46 @@ export function getFilenameToDebugIdMap(stackParser: StackParser): Record; - const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser); - if (cachedDebugIdStackFrameCache) { - debugIdStackFramesCache = cachedDebugIdStackFrameCache; - } else { - debugIdStackFramesCache = new Map(); - debugIdStackParserCache.set(stackParser, debugIdStackFramesCache); + const debugIdKeys = Object.keys(debugIdMap); + + // If the count of registered globals hasn't changed since the last call, we + // can just return the cached result. + if (cachedFilenameDebugIds && debugIdKeys.length === lastKeysCount) { + return cachedFilenameDebugIds; } + lastKeysCount = debugIdKeys.length; + // Build a map of filename -> debug_id. - return Object.keys(debugIdMap).reduce>((acc, debugIdStackTrace) => { - let parsedStack: StackFrame[]; + cachedFilenameDebugIds = debugIdKeys.reduce>((acc, stackKey) => { + if (!parsedStackResults) { + parsedStackResults = {}; + } + + const result = parsedStackResults[stackKey]; - const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace); - if (cachedParsedStack) { - parsedStack = cachedParsedStack; + if (result) { + acc[result[0]] = result[1]; } else { - parsedStack = stackParser(debugIdStackTrace); - debugIdStackFramesCache.set(debugIdStackTrace, parsedStack); - } + const parsedStack = stackParser(stackKey); - for (let i = parsedStack.length - 1; i >= 0; i--) { - const stackFrame = parsedStack[i]; - const file = stackFrame && stackFrame.filename; + for (let i = parsedStack.length - 1; i >= 0; i--) { + const stackFrame = parsedStack[i]; + const filename = stackFrame && stackFrame.filename; + const debugId = debugIdMap[stackKey]; - if (stackFrame && file) { - acc[file] = debugIdMap[debugIdStackTrace] as string; - break; + if (filename && debugId) { + acc[filename] = debugId; + parsedStackResults[stackKey] = [filename, debugId]; + break; + } } } + return acc; }, {}); + + return cachedFilenameDebugIds; } /** @@ -55,6 +68,10 @@ export function getDebugImagesForResources( ): DebugImage[] { const filenameDebugIdMap = getFilenameToDebugIdMap(stackParser); + if (!filenameDebugIdMap) { + return []; + } + const images: DebugImage[] = []; for (const path of resource_paths) { if (path && filenameDebugIdMap[path]) { diff --git a/packages/core/src/utils-hoist/dsn.ts b/packages/core/src/utils-hoist/dsn.ts index 5ca4aa96c180..abce9a5d6be7 100644 --- a/packages/core/src/utils-hoist/dsn.ts +++ b/packages/core/src/utils-hoist/dsn.ts @@ -1,4 +1,4 @@ -import type { DsnComponents, DsnLike, DsnProtocol } from '@sentry/types'; +import type { DsnComponents, DsnLike, DsnProtocol } from '../types-hoist'; import { DEBUG_BUILD } from './debug-build'; import { consoleSandbox, logger } from './logger'; diff --git a/packages/core/src/utils-hoist/envelope.ts b/packages/core/src/utils-hoist/envelope.ts index 945bd4d66366..5014d6fe130d 100644 --- a/packages/core/src/utils-hoist/envelope.ts +++ b/packages/core/src/utils-hoist/envelope.ts @@ -13,7 +13,7 @@ import type { SdkMetadata, SpanItem, SpanJSON, -} from '@sentry/types'; +} from '../types-hoist'; import { dsnToString } from './dsn'; import { normalize } from './normalize'; diff --git a/packages/core/src/utils-hoist/error.ts b/packages/core/src/utils-hoist/error.ts index af0f80e9dce7..03fc404656dc 100644 --- a/packages/core/src/utils-hoist/error.ts +++ b/packages/core/src/utils-hoist/error.ts @@ -1,4 +1,4 @@ -import type { ConsoleLevel } from '@sentry/types'; +import type { ConsoleLevel } from '../types-hoist'; /** An error emitted by Sentry SDKs and related utilities. */ export class SentryError extends Error { diff --git a/packages/core/src/utils-hoist/eventbuilder.ts b/packages/core/src/utils-hoist/eventbuilder.ts index ecfb98e80783..42d23927f081 100644 --- a/packages/core/src/utils-hoist/eventbuilder.ts +++ b/packages/core/src/utils-hoist/eventbuilder.ts @@ -9,7 +9,7 @@ import type { SeverityLevel, StackFrame, StackParser, -} from '@sentry/types'; +} from '../types-hoist'; import { isError, isErrorEvent, isParameterizedString, isPlainObject } from './is'; import { addExceptionMechanism, addExceptionTypeValue } from './misc'; diff --git a/packages/core/src/utils-hoist/index.ts b/packages/core/src/utils-hoist/index.ts index c04f314c40f2..e53cd0edb59b 100644 --- a/packages/core/src/utils-hoist/index.ts +++ b/packages/core/src/utils-hoist/index.ts @@ -49,6 +49,7 @@ export { parseSemver, uuid4, } from './misc'; +// eslint-disable-next-line deprecation/deprecation export { dynamicRequire, isNodeEnv, loadModule } from './node'; export { normalize, normalizeToSize, normalizeUrlToBase } from './normalize'; export { @@ -113,6 +114,7 @@ export { } from './supports'; export { SyncPromise, rejectedSyncPromise, resolvedSyncPromise } from './syncpromise'; export { + // eslint-disable-next-line deprecation/deprecation _browserPerformanceTimeOriginMode, browserPerformanceTimeOrigin, dateTimestampInSeconds, @@ -159,13 +161,19 @@ export { parseBaggageHeader, } from './baggage'; +// eslint-disable-next-line deprecation/deprecation export { getNumberOfUrlSegments, getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment } from './url'; // eslint-disable-next-line deprecation/deprecation export { makeFifoCache } from './cache'; export { eventFromMessage, eventFromUnknownInput, exceptionFromError, parseStackFrames } from './eventbuilder'; export { callFrameToStackFrame, watchdogTimer } from './anr'; export { LRUMap } from './lru'; -export { generatePropagationContext } from './propagationContext'; +export { + // eslint-disable-next-line deprecation/deprecation + generatePropagationContext, + generateTraceId, + generateSpanId, +} from './propagationContext'; export { vercelWaitUntil } from './vercelWaitUntil'; export { SDK_VERSION } from './version'; export { getDebugImagesForResources, getFilenameToDebugIdMap } from './debug-ids'; diff --git a/packages/core/src/utils-hoist/instrument/console.ts b/packages/core/src/utils-hoist/instrument/console.ts index f75faa3346c2..955407e5573b 100644 --- a/packages/core/src/utils-hoist/instrument/console.ts +++ b/packages/core/src/utils-hoist/instrument/console.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/ban-types */ -import type { ConsoleLevel, HandlerDataConsole } from '@sentry/types'; +import type { ConsoleLevel, HandlerDataConsole } from '../../types-hoist'; import { CONSOLE_LEVELS, originalConsoleMethods } from '../logger'; import { fill } from '../object'; diff --git a/packages/core/src/utils-hoist/instrument/fetch.ts b/packages/core/src/utils-hoist/instrument/fetch.ts index ad28edf81e3f..39c8862ba618 100644 --- a/packages/core/src/utils-hoist/instrument/fetch.ts +++ b/packages/core/src/utils-hoist/instrument/fetch.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { HandlerDataFetch } from '@sentry/types'; +import type { HandlerDataFetch } from '../../types-hoist'; import { isError } from '../is'; import { addNonEnumerableProperty, fill } from '../object'; diff --git a/packages/core/src/utils-hoist/instrument/globalError.ts b/packages/core/src/utils-hoist/instrument/globalError.ts index a3ee2149817f..6565f42c2329 100644 --- a/packages/core/src/utils-hoist/instrument/globalError.ts +++ b/packages/core/src/utils-hoist/instrument/globalError.ts @@ -1,4 +1,4 @@ -import type { HandlerDataError } from '@sentry/types'; +import type { HandlerDataError } from '../../types-hoist'; import { GLOBAL_OBJ } from '../worldwide'; import { addHandler, maybeInstrument, triggerHandlers } from './handlers'; diff --git a/packages/core/src/utils-hoist/instrument/globalUnhandledRejection.ts b/packages/core/src/utils-hoist/instrument/globalUnhandledRejection.ts index 878540500dac..5e47cd125a35 100644 --- a/packages/core/src/utils-hoist/instrument/globalUnhandledRejection.ts +++ b/packages/core/src/utils-hoist/instrument/globalUnhandledRejection.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { HandlerDataUnhandledRejection } from '@sentry/types'; +import type { HandlerDataUnhandledRejection } from '../../types-hoist'; import { GLOBAL_OBJ } from '../worldwide'; import { addHandler, maybeInstrument, triggerHandlers } from './handlers'; diff --git a/packages/core/src/utils-hoist/is.ts b/packages/core/src/utils-hoist/is.ts index f019508662cd..28ebfd7be2f7 100644 --- a/packages/core/src/utils-hoist/is.ts +++ b/packages/core/src/utils-hoist/is.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { ParameterizedString, PolymorphicEvent, Primitive } from '@sentry/types'; +import type { ParameterizedString, PolymorphicEvent, Primitive } from '../types-hoist'; // eslint-disable-next-line @typescript-eslint/unbound-method const objectToString = Object.prototype.toString; diff --git a/packages/core/src/utils-hoist/isBrowser.ts b/packages/core/src/utils-hoist/isBrowser.ts index 1670d347f4bb..b77d65c0f3ff 100644 --- a/packages/core/src/utils-hoist/isBrowser.ts +++ b/packages/core/src/utils-hoist/isBrowser.ts @@ -13,8 +13,6 @@ type ElectronProcess = { type?: string }; // Electron renderers with nodeIntegration enabled are detected as Node.js so we specifically test for them function isElectronNodeRenderer(): boolean { - return ( - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - (GLOBAL_OBJ as any).process !== undefined && ((GLOBAL_OBJ as any).process as ElectronProcess).type === 'renderer' - ); + const process = (GLOBAL_OBJ as typeof GLOBAL_OBJ & { process?: ElectronProcess }).process; + return !!process && process.type === 'renderer'; } diff --git a/packages/core/src/utils-hoist/logger.ts b/packages/core/src/utils-hoist/logger.ts index c56dc2fff699..a18b19be6db6 100644 --- a/packages/core/src/utils-hoist/logger.ts +++ b/packages/core/src/utils-hoist/logger.ts @@ -1,4 +1,4 @@ -import type { ConsoleLevel } from '@sentry/types'; +import type { ConsoleLevel } from '../types-hoist'; import { DEBUG_BUILD } from './debug-build'; import { GLOBAL_OBJ, getGlobalSingleton } from './worldwide'; diff --git a/packages/core/src/utils-hoist/misc.ts b/packages/core/src/utils-hoist/misc.ts index 0f02b5ba14de..5a3190e0f87b 100644 --- a/packages/core/src/utils-hoist/misc.ts +++ b/packages/core/src/utils-hoist/misc.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { Event, Exception, Mechanism, StackFrame } from '@sentry/types'; +import type { Event, Exception, Mechanism, StackFrame } from '../types-hoist'; import { addNonEnumerableProperty } from './object'; import { snipLine } from './string'; @@ -211,8 +211,7 @@ export function addContextToFrame(lines: string[], frame: StackFrame, linesOfCon * @returns `true` if the exception has already been captured, `false` if not (with the side effect of marking it seen) */ export function checkOrSetAlreadyCaught(exception: unknown): boolean { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - if (exception && (exception as any).__sentry_captured__) { + if (isAlreadyCaptured(exception)) { return true; } @@ -227,6 +226,12 @@ export function checkOrSetAlreadyCaught(exception: unknown): boolean { return false; } +function isAlreadyCaptured(exception: unknown): boolean | void { + try { + return (exception as { __sentry_captured__?: boolean }).__sentry_captured__; + } catch {} // eslint-disable-line no-empty +} + /** * Checks whether the given input is already an array, and if it isn't, wraps it in one. * diff --git a/packages/core/src/utils-hoist/node-stack-trace.ts b/packages/core/src/utils-hoist/node-stack-trace.ts index fc96fccc8847..946492ede855 100644 --- a/packages/core/src/utils-hoist/node-stack-trace.ts +++ b/packages/core/src/utils-hoist/node-stack-trace.ts @@ -21,7 +21,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -import type { StackLineParser, StackLineParserFn } from '@sentry/types'; +import type { StackLineParser, StackLineParserFn } from '../types-hoist'; import { UNKNOWN_FUNCTION } from './stacktrace'; export type GetModuleFn = (filename: string | undefined) => string | undefined; diff --git a/packages/core/src/utils-hoist/node.ts b/packages/core/src/utils-hoist/node.ts index 8640a5a95801..3805248bdedd 100644 --- a/packages/core/src/utils-hoist/node.ts +++ b/packages/core/src/utils-hoist/node.ts @@ -23,6 +23,7 @@ export function isNodeEnv(): boolean { * Requires a module which is protected against bundler minification. * * @param request The module path to resolve + * @deprecated This function will be removed in the next major version. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function dynamicRequire(mod: any, request: string): any { @@ -47,6 +48,7 @@ export function loadModule(moduleName: string): T | undefined { let mod: T | undefined; try { + // eslint-disable-next-line deprecation/deprecation mod = dynamicRequire(module, moduleName); } catch (e) { // no-empty @@ -54,7 +56,9 @@ export function loadModule(moduleName: string): T | undefined { if (!mod) { try { + // eslint-disable-next-line deprecation/deprecation const { cwd } = dynamicRequire(module, 'process'); + // eslint-disable-next-line deprecation/deprecation mod = dynamicRequire(module, `${cwd()}/node_modules/${moduleName}`) as T; } catch (e) { // no-empty diff --git a/packages/core/src/utils-hoist/normalize.ts b/packages/core/src/utils-hoist/normalize.ts index fe108fdbdd0e..c1e8e2c630ad 100644 --- a/packages/core/src/utils-hoist/normalize.ts +++ b/packages/core/src/utils-hoist/normalize.ts @@ -1,4 +1,4 @@ -import type { Primitive } from '@sentry/types'; +import type { Primitive } from '../types-hoist'; import { isSyntheticEvent, isVueViewModel } from './is'; import type { MemoFunc } from './memo'; diff --git a/packages/core/src/utils-hoist/object.ts b/packages/core/src/utils-hoist/object.ts index d3e785f7639d..f5703feaa1da 100644 --- a/packages/core/src/utils-hoist/object.ts +++ b/packages/core/src/utils-hoist/object.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { WrappedFunction } from '@sentry/types'; +import type { WrappedFunction } from '../types-hoist'; import { htmlTreeAsString } from './browser'; import { DEBUG_BUILD } from './debug-build'; @@ -81,7 +81,8 @@ export function markFunctionWrapped(wrapped: WrappedFunction, original: WrappedF * @param func the function to unwrap * @returns the unwrapped version of the function if available. */ -export function getOriginalFunction(func: WrappedFunction): WrappedFunction | undefined { +// eslint-disable-next-line @typescript-eslint/ban-types +export function getOriginalFunction(func: WrappedFunction): T | undefined { return func.__sentry_original__; } @@ -295,7 +296,8 @@ function isPojo(input: unknown): input is Record { export function objectify(wat: unknown): typeof Object { let objectified; switch (true) { - case wat === undefined || wat === null: + // this will catch both undefined and null + case wat == undefined: objectified = new String(wat); break; diff --git a/packages/core/src/utils-hoist/propagationContext.ts b/packages/core/src/utils-hoist/propagationContext.ts index 745531c8aa98..9c045034606e 100644 --- a/packages/core/src/utils-hoist/propagationContext.ts +++ b/packages/core/src/utils-hoist/propagationContext.ts @@ -1,12 +1,28 @@ -import type { PropagationContext } from '@sentry/types'; +import type { PropagationContext } from '../types-hoist'; import { uuid4 } from './misc'; /** - * Returns a new minimal propagation context + * Returns a new minimal propagation context. + * + * @deprecated Use `generateTraceId` and `generateSpanId` instead. */ export function generatePropagationContext(): PropagationContext { return { - traceId: uuid4(), - spanId: uuid4().substring(16), + traceId: generateTraceId(), + spanId: generateSpanId(), }; } + +/** + * Generate a random, valid trace ID. + */ +export function generateTraceId(): string { + return uuid4(); +} + +/** + * Generate a random, valid span ID. + */ +export function generateSpanId(): string { + return uuid4().substring(16); +} diff --git a/packages/core/src/utils-hoist/ratelimit.ts b/packages/core/src/utils-hoist/ratelimit.ts index 6131cff2bb2c..db2053bdabd6 100644 --- a/packages/core/src/utils-hoist/ratelimit.ts +++ b/packages/core/src/utils-hoist/ratelimit.ts @@ -1,4 +1,4 @@ -import type { DataCategory, TransportMakeRequestResponse } from '@sentry/types'; +import type { DataCategory, TransportMakeRequestResponse } from '../types-hoist'; // Intentionally keeping the key broad, as we don't know for sure what rate limit headers get returned from backend export type RateLimits = Record; diff --git a/packages/core/src/utils-hoist/requestdata.ts b/packages/core/src/utils-hoist/requestdata.ts index 975b993f69c7..bff0f3f629bd 100644 --- a/packages/core/src/utils-hoist/requestdata.ts +++ b/packages/core/src/utils-hoist/requestdata.ts @@ -7,7 +7,7 @@ import type { TransactionSource, WebFetchHeaders, WebFetchRequest, -} from '@sentry/types'; +} from '../types-hoist'; import { parseCookie } from './cookie'; import { DEBUG_BUILD } from './debug-build'; diff --git a/packages/core/src/utils-hoist/severity.ts b/packages/core/src/utils-hoist/severity.ts index f5217b8b87c9..cdf25f6104d0 100644 --- a/packages/core/src/utils-hoist/severity.ts +++ b/packages/core/src/utils-hoist/severity.ts @@ -1,4 +1,4 @@ -import type { SeverityLevel } from '@sentry/types'; +import type { SeverityLevel } from '../types-hoist'; /** * @deprecated This variable has been deprecated and will be removed in the next major version. diff --git a/packages/core/src/utils-hoist/stacktrace.ts b/packages/core/src/utils-hoist/stacktrace.ts index 7fddda6db158..f7713fb50744 100644 --- a/packages/core/src/utils-hoist/stacktrace.ts +++ b/packages/core/src/utils-hoist/stacktrace.ts @@ -1,4 +1,4 @@ -import type { Event, StackFrame, StackLineParser, StackParser } from '@sentry/types'; +import type { Event, StackFrame, StackLineParser, StackParser } from '../types-hoist'; const STACKTRACE_FRAME_LIMIT = 50; export const UNKNOWN_FUNCTION = '?'; diff --git a/packages/core/src/utils-hoist/time.ts b/packages/core/src/utils-hoist/time.ts index df67493888e3..e03e7ba4d39b 100644 --- a/packages/core/src/utils-hoist/time.ts +++ b/packages/core/src/utils-hoist/time.ts @@ -70,6 +70,8 @@ export const timestampInSeconds = createUnixTimestampInSecondsFunc(); /** * Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only. + * + * @deprecated This variable will be removed in the next major version. */ export let _browserPerformanceTimeOriginMode: string; @@ -84,6 +86,7 @@ export const browserPerformanceTimeOrigin = ((): number | undefined => { const { performance } = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window; if (!performance || !performance.now) { + // eslint-disable-next-line deprecation/deprecation _browserPerformanceTimeOriginMode = 'none'; return undefined; } @@ -113,15 +116,18 @@ export const browserPerformanceTimeOrigin = ((): number | undefined => { if (timeOriginIsReliable || navigationStartIsReliable) { // Use the more reliable time origin if (timeOriginDelta <= navigationStartDelta) { + // eslint-disable-next-line deprecation/deprecation _browserPerformanceTimeOriginMode = 'timeOrigin'; return performance.timeOrigin; } else { + // eslint-disable-next-line deprecation/deprecation _browserPerformanceTimeOriginMode = 'navigationStart'; return navigationStart; } } // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date. + // eslint-disable-next-line deprecation/deprecation _browserPerformanceTimeOriginMode = 'dateNow'; return dateNow; })(); diff --git a/packages/core/src/utils-hoist/tracing.ts b/packages/core/src/utils-hoist/tracing.ts index 69a18f1a4c38..eb649ff34d6c 100644 --- a/packages/core/src/utils-hoist/tracing.ts +++ b/packages/core/src/utils-hoist/tracing.ts @@ -1,7 +1,7 @@ -import type { PropagationContext, TraceparentData } from '@sentry/types'; +import type { PropagationContext, TraceparentData } from '../types-hoist'; import { baggageHeaderToDynamicSamplingContext } from './baggage'; -import { uuid4 } from './misc'; +import { generateSpanId, generateTraceId } from './propagationContext'; // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp is used for readability here export const TRACEPARENT_REGEXP = new RegExp( @@ -54,30 +54,29 @@ export function propagationContextFromHeaders( const traceparentData = extractTraceparentData(sentryTrace); const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggage); - const { traceId, parentSpanId, parentSampled } = traceparentData || {}; - - if (!traceparentData) { - return { - traceId: traceId || uuid4(), - spanId: uuid4().substring(16), - }; - } else { - return { - traceId: traceId || uuid4(), - parentSpanId: parentSpanId || uuid4().substring(16), - spanId: uuid4().substring(16), - sampled: parentSampled, - dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it - }; + if (!traceparentData || !traceparentData.traceId) { + return { traceId: generateTraceId(), spanId: generateSpanId() }; } + + const { traceId, parentSpanId, parentSampled } = traceparentData; + + const virtualSpanId = generateSpanId(); + + return { + traceId, + parentSpanId, + spanId: virtualSpanId, + sampled: parentSampled, + dsc: dynamicSamplingContext || {}, // If we have traceparent data but no DSC it means we are not head of trace and we must freeze it + }; } /** * Create sentry-trace header from span context values. */ export function generateSentryTraceHeader( - traceId: string = uuid4(), - spanId: string = uuid4().substring(16), + traceId: string = generateTraceId(), + spanId: string = generateSpanId(), sampled?: boolean, ): string { let sampledString = ''; diff --git a/packages/core/src/utils-hoist/url.ts b/packages/core/src/utils-hoist/url.ts index e324f41f82a3..44dc669da93a 100644 --- a/packages/core/src/utils-hoist/url.ts +++ b/packages/core/src/utils-hoist/url.ts @@ -50,7 +50,10 @@ export function stripUrlQueryAndFragment(urlPath: string): string { /** * Returns number of URL segments of a passed string URL. + * + * @deprecated This function will be removed in the next major version. */ +// TODO(v9): Hoist this function into the places where we use it. (as it stands only react router v6 instrumentation) export function getNumberOfUrlSegments(url: string): number { // split at '/' or at '\/' to split regex urls correctly return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length; diff --git a/packages/core/src/utils-hoist/worldwide.ts b/packages/core/src/utils-hoist/worldwide.ts index 62b2d3d397b6..0338cfc4940b 100644 --- a/packages/core/src/utils-hoist/worldwide.ts +++ b/packages/core/src/utils-hoist/worldwide.ts @@ -12,7 +12,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { Client, MetricsAggregator, Scope } from '@sentry/types'; +import type { Client, MetricsAggregator, Scope } from '../types-hoist'; import type { SdkSource } from './env'; import type { logger } from './logger'; diff --git a/packages/core/src/utils/applyScopeDataToEvent.ts b/packages/core/src/utils/applyScopeDataToEvent.ts index ccf3f62ae153..fccca13f87b9 100644 --- a/packages/core/src/utils/applyScopeDataToEvent.ts +++ b/packages/core/src/utils/applyScopeDataToEvent.ts @@ -1,6 +1,6 @@ -import type { Breadcrumb, Event, ScopeData, Span } from '@sentry/types'; import { getDynamicSamplingContextFromSpan } from '../tracing/dynamicSamplingContext'; -import { dropUndefinedKeys } from '../utils-hoist'; +import type { Breadcrumb, Event, ScopeData, Span } from '../types-hoist'; +import { dropUndefinedKeys } from '../utils-hoist/object'; import { merge } from './merge'; import { getRootSpan, spanToJSON, spanToTraceContext } from './spanUtils'; diff --git a/packages/core/src/utils/hasTracingEnabled.ts b/packages/core/src/utils/hasTracingEnabled.ts index 9441a0fc7bed..6d99eede931e 100644 --- a/packages/core/src/utils/hasTracingEnabled.ts +++ b/packages/core/src/utils/hasTracingEnabled.ts @@ -1,5 +1,5 @@ -import type { Options } from '@sentry/types'; import { getClient } from '../currentScopes'; +import type { Options } from '../types-hoist'; // Treeshakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean | undefined; diff --git a/packages/core/src/utils/isSentryRequestUrl.ts b/packages/core/src/utils/isSentryRequestUrl.ts index a3f3e08be3e0..614c98bf4081 100644 --- a/packages/core/src/utils/isSentryRequestUrl.ts +++ b/packages/core/src/utils/isSentryRequestUrl.ts @@ -1,4 +1,4 @@ -import type { Client, DsnComponents } from '@sentry/types'; +import type { Client, DsnComponents } from '../types-hoist'; /** * Checks whether given url points to Sentry server diff --git a/packages/core/src/utils/parameterize.ts b/packages/core/src/utils/parameterize.ts index 1ad880618a48..392f4b70b444 100644 --- a/packages/core/src/utils/parameterize.ts +++ b/packages/core/src/utils/parameterize.ts @@ -1,4 +1,4 @@ -import type { ParameterizedString } from '@sentry/types'; +import type { ParameterizedString } from '../types-hoist'; /** * Tagged template function which returns parameterized representation of the message diff --git a/packages/core/src/utils/prepareEvent.ts b/packages/core/src/utils/prepareEvent.ts index bf23a0e3ee79..4c1c848a1a57 100644 --- a/packages/core/src/utils/prepareEvent.ts +++ b/packages/core/src/utils/prepareEvent.ts @@ -7,7 +7,7 @@ import type { Scope as ScopeInterface, ScopeContext, StackParser, -} from '@sentry/types'; +} from '../types-hoist'; import { DEFAULT_ENVIRONMENT } from '../constants'; import { getGlobalScope } from '../currentScopes'; @@ -129,23 +129,26 @@ export function prepareEvent( } /** - * Enhances event using the client configuration. - * It takes care of all "static" values like environment, release and `dist`, - * as well as truncating overly long values. + * Enhances event using the client configuration. + * It takes care of all "static" values like environment, release and `dist`, + * as well as truncating overly long values. + * + * Only exported for tests. + * * @param event event instance to be enhanced */ -function applyClientOptions(event: Event, options: ClientOptions): void { +export function applyClientOptions(event: Event, options: ClientOptions): void { const { environment, release, dist, maxValueLength = 250 } = options; - if (!('environment' in event)) { - event.environment = 'environment' in options ? environment : DEFAULT_ENVIRONMENT; - } + // empty strings do not make sense for environment, release, and dist + // so we handle them the same as if they were not provided + event.environment = event.environment || environment || DEFAULT_ENVIRONMENT; - if (event.release === undefined && release !== undefined) { + if (!event.release && release) { event.release = release; } - if (event.dist === undefined && dist !== undefined) { + if (!event.dist && dist) { event.dist = dist; } @@ -176,7 +179,7 @@ export function applyDebugIds(event: Event, stackParser: StackParser): void { event!.exception!.values!.forEach(exception => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion exception.stacktrace!.frames!.forEach(frame => { - if (frame.filename) { + if (filenameDebugIdMap && frame.filename) { frame.debug_id = filenameDebugIdMap[frame.filename]; } }); diff --git a/packages/core/src/utils/sdkMetadata.ts b/packages/core/src/utils/sdkMetadata.ts index 7d2905abf84f..74c2f2e75e1c 100644 --- a/packages/core/src/utils/sdkMetadata.ts +++ b/packages/core/src/utils/sdkMetadata.ts @@ -1,4 +1,4 @@ -import type { Options } from '@sentry/types'; +import type { Options } from '../types-hoist'; import { SDK_VERSION } from '../utils-hoist/version'; /** diff --git a/packages/core/src/utils/spanOnScope.ts b/packages/core/src/utils/spanOnScope.ts index e7607f0fa090..bdc47b66d208 100644 --- a/packages/core/src/utils/spanOnScope.ts +++ b/packages/core/src/utils/spanOnScope.ts @@ -1,4 +1,4 @@ -import type { Scope, Span } from '@sentry/types'; +import type { Scope, Span } from '../types-hoist'; import { addNonEnumerableProperty } from '../utils-hoist/object'; const SCOPE_SPAN_FIELD = '_sentrySpan'; diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index d9232b1f48bc..594a297f9395 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -1,3 +1,11 @@ +import { getAsyncContextStrategy } from '../asyncContext'; +import { getMainCarrier } from '../carrier'; +import { getCurrentScope } from '../currentScopes'; +import { getMetricSummaryJsonForSpan, updateMetricSummaryOnSpan } from '../metrics/metric-summary'; +import type { MetricType } from '../metrics/types'; +import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes'; +import type { SentrySpan } from '../tracing/sentrySpan'; +import { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus'; import type { MeasurementUnit, Primitive, @@ -8,17 +16,10 @@ import type { SpanStatus, SpanTimeInput, TraceContext, -} from '@sentry/types'; -import { getAsyncContextStrategy } from '../asyncContext'; -import { getMainCarrier } from '../carrier'; -import { getCurrentScope } from '../currentScopes'; -import { getMetricSummaryJsonForSpan, updateMetricSummaryOnSpan } from '../metrics/metric-summary'; -import type { MetricType } from '../metrics/types'; -import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes'; -import type { SentrySpan } from '../tracing/sentrySpan'; -import { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus'; +} from '../types-hoist'; import { consoleSandbox } from '../utils-hoist/logger'; import { addNonEnumerableProperty, dropUndefinedKeys } from '../utils-hoist/object'; +import { generateSpanId } from '../utils-hoist/propagationContext'; import { timestampInSeconds } from '../utils-hoist/time'; import { generateSentryTraceHeader } from '../utils-hoist/tracing'; import { _getSpanForScope } from './spanOnScope'; @@ -54,10 +55,18 @@ export function spanToTransactionTraceContext(span: Span): TraceContext { * Convert a span to a trace context, which can be sent as the `trace` context in a non-transaction event. */ export function spanToTraceContext(span: Span): TraceContext { - const { spanId: span_id, traceId: trace_id } = span.spanContext(); - const { parent_span_id } = spanToJSON(span); + const { spanId, traceId: trace_id, isRemote } = span.spanContext(); + + // If the span is remote, we use a random/virtual span as span_id to the trace context, + // and the remote span as parent_span_id + const parent_span_id = isRemote ? spanId : spanToJSON(span).parent_span_id; + const span_id = isRemote ? generateSpanId() : spanId; - return dropUndefinedKeys({ parent_span_id, span_id, trace_id }); + return dropUndefinedKeys({ + parent_span_id, + span_id, + trace_id, + }); } /** diff --git a/packages/core/src/utils/traceData.ts b/packages/core/src/utils/traceData.ts index 04727510e07c..b73ddf2828bf 100644 --- a/packages/core/src/utils/traceData.ts +++ b/packages/core/src/utils/traceData.ts @@ -1,13 +1,13 @@ -import type { SerializedTraceData } from '@sentry/types'; import { getAsyncContextStrategy } from '../asyncContext'; import { getMainCarrier } from '../carrier'; import { getClient, getCurrentScope } from '../currentScopes'; import { isEnabled } from '../exports'; -import { getDynamicSamplingContextFromClient, getDynamicSamplingContextFromSpan } from '../tracing'; +import { getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan } from '../tracing'; +import type { Scope, SerializedTraceData, Span } from '../types-hoist'; import { dynamicSamplingContextToSentryBaggageHeader } from '../utils-hoist/baggage'; import { logger } from '../utils-hoist/logger'; import { TRACEPARENT_REGEXP, generateSentryTraceHeader } from '../utils-hoist/tracing'; -import { getActiveSpan, getRootSpan, spanToTraceHeader } from './spanUtils'; +import { getActiveSpan, spanToTraceHeader } from './spanUtils'; /** * Extracts trace propagation data from the current span or from the client's scope (via transaction or propagation @@ -20,35 +20,23 @@ import { getActiveSpan, getRootSpan, spanToTraceHeader } from './spanUtils'; * @returns an object with the tracing data values. The object keys are the name of the tracing key to be used as header * or meta tag name. */ -export function getTraceData(): SerializedTraceData { - if (!isEnabled()) { +export function getTraceData(options: { span?: Span } = {}): SerializedTraceData { + const client = getClient(); + if (!isEnabled() || !client) { return {}; } const carrier = getMainCarrier(); const acs = getAsyncContextStrategy(carrier); if (acs.getTraceData) { - return acs.getTraceData(); + return acs.getTraceData(options); } - const client = getClient(); const scope = getCurrentScope(); - const span = getActiveSpan(); - - const { dsc, sampled, traceId } = scope.getPropagationContext(); - const rootSpan = span && getRootSpan(span); - - const sentryTrace = span ? spanToTraceHeader(span) : generateSentryTraceHeader(traceId, undefined, sampled); - - const dynamicSamplingContext = rootSpan - ? getDynamicSamplingContextFromSpan(rootSpan) - : dsc - ? dsc - : client - ? getDynamicSamplingContextFromClient(traceId, client) - : undefined; - - const baggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + const span = options.span || getActiveSpan(); + const sentryTrace = span ? spanToTraceHeader(span) : scopeToTraceHeader(scope); + const dsc = span ? getDynamicSamplingContextFromSpan(span) : getDynamicSamplingContextFromScope(client, scope); + const baggage = dynamicSamplingContextToSentryBaggageHeader(dsc); const isValidSentryTraceHeader = TRACEPARENT_REGEXP.test(sentryTrace); if (!isValidSentryTraceHeader) { @@ -56,35 +44,18 @@ export function getTraceData(): SerializedTraceData { return {}; } - const validBaggage = isValidBaggageString(baggage); - if (!validBaggage) { - logger.warn('Invalid baggage data. Not returning "baggage" value'); - } - return { 'sentry-trace': sentryTrace, - ...(validBaggage && { baggage }), + baggage, }; } /** - * Tests string against baggage spec as defined in: - * - * - W3C Baggage grammar: https://www.w3.org/TR/baggage/#definition - * - RFC7230 token definition: https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6 - * - * exported for testing + * Get a sentry-trace header value for the given scope. */ -export function isValidBaggageString(baggage?: string): boolean { - if (!baggage || !baggage.length) { - return false; - } - const keyRegex = "[-!#$%&'*+.^_`|~A-Za-z0-9]+"; - const valueRegex = '[!#-+-./0-9:<=>?@A-Z\\[\\]a-z{-}]+'; - const spaces = '\\s*'; - // eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor -- RegExp for readability, no user input - const baggageRegex = new RegExp( - `^${keyRegex}${spaces}=${spaces}${valueRegex}(${spaces},${spaces}${keyRegex}${spaces}=${spaces}${valueRegex})*$`, - ); - return baggageRegex.test(baggage); +function scopeToTraceHeader(scope: Scope): string { + // TODO(v9): Use generateSpanId() instead of spanId + // eslint-disable-next-line deprecation/deprecation + const { traceId, sampled, spanId } = scope.getPropagationContext(); + return generateSentryTraceHeader(traceId, spanId, sampled); } diff --git a/packages/core/test/lib/api.test.ts b/packages/core/test/lib/api.test.ts index 89a8ad3cf20f..37e67e5a8da1 100644 --- a/packages/core/test/lib/api.test.ts +++ b/packages/core/test/lib/api.test.ts @@ -1,6 +1,5 @@ -import type { DsnComponents, SdkInfo } from '@sentry/types'; - import { getEnvelopeEndpointWithUrlEncodedAuth, getReportDialogEndpoint } from '../../src/api'; +import type { DsnComponents, SdkInfo } from '../../src/types-hoist'; import { makeDsn } from '../../src/utils-hoist/dsn'; const ingestDsn = 'https://abc@xxxx.ingest.sentry.io:1234/subpath/123'; diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/baseclient.test.ts similarity index 94% rename from packages/core/test/lib/base.test.ts rename to packages/core/test/lib/baseclient.test.ts index 296a496d2d40..ce480879bb27 100644 --- a/packages/core/test/lib/base.test.ts +++ b/packages/core/test/lib/baseclient.test.ts @@ -1,5 +1,5 @@ import { SentryError, SyncPromise, dsnToString } from '@sentry/core'; -import type { Client, Envelope, ErrorEvent, Event, TransactionEvent } from '@sentry/types'; +import type { Client, Envelope, ErrorEvent, Event, TransactionEvent } from '../../src/types-hoist'; import * as loggerModule from '../../src/utils-hoist/logger'; import * as miscModule from '../../src/utils-hoist/misc'; @@ -29,7 +29,7 @@ declare var global: any; const clientEventFromException = jest.spyOn(TestClient.prototype, 'eventFromException'); const clientProcess = jest.spyOn(TestClient.prototype as any, '_process'); -jest.spyOn(miscModule, 'uuid4').mockImplementation(() => '42'); +jest.spyOn(miscModule, 'uuid4').mockImplementation(() => '12312012123120121231201212312012'); jest.spyOn(loggerModule, 'consoleSandbox').mockImplementation(cb => cb()); jest.spyOn(stringModule, 'truncate').mockImplementation(str => str); jest.spyOn(timeModule, 'dateTimestampInSeconds').mockImplementation(() => 2020); @@ -77,6 +77,56 @@ describe('BaseClient', () => { }); }); + describe('constructor() / warnings', () => { + test('does not warn for defaults', () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); + new TestClient(options); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(0); + consoleWarnSpy.mockRestore(); + }); + + describe.each(['tracesSampleRate', 'tracesSampler', 'enableTracing'])('%s', key => { + it('warns when set to undefined', () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, [key]: undefined }); + new TestClient(options); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(1); + expect(consoleWarnSpy).toBeCalledWith( + `[Sentry] Deprecation warning: \`${key}\` is set to undefined, which leads to tracing being enabled. In v9, a value of \`undefined\` will result in tracing being disabled.`, + ); + consoleWarnSpy.mockRestore(); + }); + + it('warns when set to null', () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, [key]: null }); + new TestClient(options); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(1); + expect(consoleWarnSpy).toBeCalledWith( + `[Sentry] Deprecation warning: \`${key}\` is set to undefined, which leads to tracing being enabled. In v9, a value of \`undefined\` will result in tracing being disabled.`, + ); + consoleWarnSpy.mockRestore(); + }); + + it('does not warn when set to 0', () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + + const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, [key]: 0 }); + new TestClient(options); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(0); + consoleWarnSpy.mockRestore(); + }); + }); + }); + describe('getOptions()', () => { test('returns the options', () => { expect.assertions(1); @@ -215,7 +265,7 @@ describe('BaseClient', () => { expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', exception: { values: [ { @@ -328,7 +378,7 @@ describe('BaseClient', () => { expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', level: 'info', message: 'test message', timestamp: 2020, @@ -438,7 +488,7 @@ describe('BaseClient', () => { expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', message: 'message', timestamp: 2020, }), @@ -466,14 +516,14 @@ describe('BaseClient', () => { expect(TestClient.instance!.event).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', message: 'message', timestamp: 1234, }), ); }); - test('it adds a trace context all events', () => { + test('it adds a trace context to all events xxx', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN }); @@ -482,17 +532,11 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, { event_id: 'wat' }, scope); - expect(TestClient.instance!.event!).toEqual( - expect.objectContaining({ - contexts: { - trace: { - parent_span_id: undefined, - span_id: expect.any(String), - trace_id: expect.any(String), - }, - }, - }), - ); + expect(TestClient.instance?.event?.contexts?.trace).toEqual({ + parent_span_id: undefined, + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), + }); }); test('adds `event_id` from hint if available', () => { @@ -526,7 +570,7 @@ describe('BaseClient', () => { expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', message: 'message', timestamp: 2020, }), @@ -545,14 +589,14 @@ describe('BaseClient', () => { expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'env', - event_id: '42', + event_id: '12312012123120121231201212312012', message: 'message', timestamp: 2020, }), ); }); - test('allows for environment to be explicitly set to falsy value', () => { + test('uses default environment when set to falsy value', () => { expect.assertions(1); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, environment: undefined }); @@ -563,8 +607,8 @@ describe('BaseClient', () => { expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ - environment: undefined, - event_id: '42', + environment: 'production', + event_id: '12312012123120121231201212312012', message: 'message', timestamp: 2020, }), @@ -583,7 +627,7 @@ describe('BaseClient', () => { expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', message: 'message', release: 'v1.0.0', timestamp: 2020, @@ -601,7 +645,7 @@ describe('BaseClient', () => { client.captureEvent({ message: 'message' }, undefined, scope); - expect(TestClient.instance!.event!).toHaveProperty('event_id', '42'); + expect(TestClient.instance!.event!).toHaveProperty('event_id', '12312012123120121231201212312012'); expect(TestClient.instance!.event!).toHaveProperty('message', 'message'); expect(TestClient.instance!.event!).toHaveProperty('breadcrumbs'); expect(TestClient.instance!.event!.breadcrumbs![0]).toHaveProperty('message', 'breadcrumb'); @@ -640,7 +684,7 @@ describe('BaseClient', () => { expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', extra: { b: 'b' }, message: 'message', tags: { a: 'a' }, @@ -663,7 +707,7 @@ describe('BaseClient', () => { expect(TestClient.instance!.event!).toEqual( expect.objectContaining({ environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', fingerprint: ['abcd'], message: 'message', timestamp: 2020, @@ -763,7 +807,7 @@ describe('BaseClient', () => { // also has trace context from global scope contexts: { ...normalizedObject, trace: expect.anything() }, environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', extra: normalizedObject, timestamp: 2020, user: normalizedObject, @@ -813,7 +857,7 @@ describe('BaseClient', () => { // also has trace context from global scope contexts: { ...normalizedObject, trace: expect.anything() }, environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', extra: normalizedObject, timestamp: 2020, user: normalizedObject, @@ -868,7 +912,7 @@ describe('BaseClient', () => { // also has trace context from global scope contexts: { ...normalizedObject, trace: expect.anything() }, environment: 'production', - event_id: '42', + event_id: '12312012123120121231201212312012', extra: normalizedObject, timestamp: 2020, user: normalizedObject, @@ -1122,6 +1166,8 @@ describe('BaseClient', () => { }); test('calls `beforeSendSpan` and discards the span', () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + const beforeSendSpan = jest.fn(() => null); const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN, beforeSendSpan }); const client = new TestClient(options); @@ -1150,6 +1196,12 @@ describe('BaseClient', () => { const capturedEvent = TestClient.instance!.event!; expect(capturedEvent.spans).toHaveLength(0); expect(client['_outcomes']).toEqual({ 'before_send:span': 2 }); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(1); + expect(consoleWarnSpy).toBeCalledWith( + '[Sentry] Deprecation warning: Returning null from `beforeSendSpan` will be disallowed from SDK version 9.0.0 onwards. The callback will only support mutating spans. To drop certain spans, configure the respective integrations directly.', + ); + consoleWarnSpy.mockRestore(); }); test('calls `beforeSend` and logs info about invalid return value', () => { diff --git a/packages/core/test/lib/checkin.test.ts b/packages/core/test/lib/checkin.test.ts index 5ae6bac6b5f3..14a699ced3e6 100644 --- a/packages/core/test/lib/checkin.test.ts +++ b/packages/core/test/lib/checkin.test.ts @@ -1,4 +1,4 @@ -import type { SerializedCheckIn } from '@sentry/types'; +import type { SerializedCheckIn } from '../../src/types-hoist'; import { createCheckInEnvelope } from '../../src/checkin'; diff --git a/packages/core/test/lib/envelope.test.ts b/packages/core/test/lib/envelope.test.ts index 253ac07d96c2..8909fb8df202 100644 --- a/packages/core/test/lib/envelope.test.ts +++ b/packages/core/test/lib/envelope.test.ts @@ -1,4 +1,4 @@ -import type { Client, DsnComponents, DynamicSamplingContext, Event } from '@sentry/types'; +import type { Client, DsnComponents, DynamicSamplingContext, Event } from '../../src/types-hoist'; import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, diff --git a/packages/core/test/lib/feedback.test.ts b/packages/core/test/lib/feedback.test.ts index cd9e99e43bdb..0146c834d6c1 100644 --- a/packages/core/test/lib/feedback.test.ts +++ b/packages/core/test/lib/feedback.test.ts @@ -1,4 +1,3 @@ -import type { Span } from '@sentry/types'; import { Scope, addBreadcrumb, @@ -9,6 +8,7 @@ import { withScope, } from '../../src'; import { captureFeedback } from '../../src/feedback'; +import type { Span } from '../../src/types-hoist'; import { TestClient, getDefaultTestClientOptions } from '../mocks/client'; describe('captureFeedback', () => { @@ -52,7 +52,7 @@ describe('captureFeedback', () => { trace: { environment: 'production', public_key: 'dsn', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, [ @@ -62,8 +62,8 @@ describe('captureFeedback', () => { breadcrumbs: undefined, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { message: 'test', @@ -112,7 +112,7 @@ describe('captureFeedback', () => { trace: { environment: 'production', public_key: 'dsn', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, [ @@ -122,8 +122,8 @@ describe('captureFeedback', () => { breadcrumbs: undefined, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { name: 'doe', @@ -194,7 +194,7 @@ describe('captureFeedback', () => { trace: { environment: 'production', public_key: 'dsn', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }, [ @@ -204,8 +204,8 @@ describe('captureFeedback', () => { breadcrumbs: undefined, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { message: 'test', @@ -417,7 +417,7 @@ describe('captureFeedback', () => { event_id: expect.any(String), sent_at: expect.any(String), trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), environment: 'production', public_key: 'dsn', }, @@ -429,8 +429,8 @@ describe('captureFeedback', () => { breadcrumbs: [{ message: 'test breadcrumb', timestamp: 12345 }], contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { contact_email: 're@example.org', diff --git a/packages/core/test/lib/integration.test.ts b/packages/core/test/lib/integration.test.ts index 128c46984d90..3a4d41089116 100644 --- a/packages/core/test/lib/integration.test.ts +++ b/packages/core/test/lib/integration.test.ts @@ -1,5 +1,5 @@ -import type { Integration, Options } from '@sentry/types'; import { getCurrentScope } from '../../src/currentScopes'; +import type { Integration, Options } from '../../src/types-hoist'; import { addIntegration, getIntegrationsToSetup, installedIntegrations, setupIntegration } from '../../src/integration'; import { setCurrentClient } from '../../src/sdk'; diff --git a/packages/core/test/lib/integrations/captureconsole.test.ts b/packages/core/test/lib/integrations/captureconsole.test.ts index 18fe7e637499..3c646d378f88 100644 --- a/packages/core/test/lib/integrations/captureconsole.test.ts +++ b/packages/core/test/lib/integrations/captureconsole.test.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/unbound-method */ -import type { Client, ConsoleLevel, Event } from '@sentry/types'; import * as CurrentScopes from '../../../src/currentScopes'; import * as SentryCore from '../../../src/exports'; +import type { Client, ConsoleLevel, Event } from '../../../src/types-hoist'; import { captureConsoleIntegration } from '../../../src/integrations/captureconsole'; import { addConsoleInstrumentationHandler } from '../../../src/utils-hoist/instrument/console'; diff --git a/packages/core/test/lib/integrations/debug.test.ts b/packages/core/test/lib/integrations/debug.test.ts index 87e1027af6e0..00a938a185e6 100644 --- a/packages/core/test/lib/integrations/debug.test.ts +++ b/packages/core/test/lib/integrations/debug.test.ts @@ -1,4 +1,4 @@ -import type { Client, Event, EventHint } from '@sentry/types'; +import type { Client, Event, EventHint } from '../../../src/types-hoist'; import { debugIntegration } from '../../../src/integrations/debug'; diff --git a/packages/core/test/lib/integrations/dedupe.test.ts b/packages/core/test/lib/integrations/dedupe.test.ts index 9478f41a6492..2e7b10fe1c4c 100644 --- a/packages/core/test/lib/integrations/dedupe.test.ts +++ b/packages/core/test/lib/integrations/dedupe.test.ts @@ -1,4 +1,4 @@ -import type { Event as SentryEvent, Exception, StackFrame, Stacktrace } from '@sentry/types'; +import type { Event as SentryEvent, Exception, StackFrame, Stacktrace } from '../../../src/types-hoist'; import { _shouldDropEvent, dedupeIntegration } from '../../../src/integrations/dedupe'; diff --git a/packages/core/test/lib/integrations/extraerrordata.test.ts b/packages/core/test/lib/integrations/extraerrordata.test.ts index d38f8fff25ee..c4048f3122b1 100644 --- a/packages/core/test/lib/integrations/extraerrordata.test.ts +++ b/packages/core/test/lib/integrations/extraerrordata.test.ts @@ -1,4 +1,4 @@ -import type { Event as SentryEvent, ExtendedError } from '@sentry/types'; +import type { Event as SentryEvent, ExtendedError } from '../../../src/types-hoist'; import { extraErrorDataIntegration } from '../../../src/integrations/extraerrordata'; diff --git a/packages/core/test/lib/integrations/inboundfilters.test.ts b/packages/core/test/lib/integrations/inboundfilters.test.ts index eb68c8c14d3b..13d6d783adf6 100644 --- a/packages/core/test/lib/integrations/inboundfilters.test.ts +++ b/packages/core/test/lib/integrations/inboundfilters.test.ts @@ -1,4 +1,4 @@ -import type { Event, EventProcessor } from '@sentry/types'; +import type { Event, EventProcessor } from '../../../src/types-hoist'; import type { InboundFiltersOptions } from '../../../src/integrations/inboundfilters'; import { inboundFiltersIntegration } from '../../../src/integrations/inboundfilters'; diff --git a/packages/core/test/lib/integrations/metadata.test.ts b/packages/core/test/lib/integrations/metadata.test.ts index 2e4a70bfa848..c93f930ca273 100644 --- a/packages/core/test/lib/integrations/metadata.test.ts +++ b/packages/core/test/lib/integrations/metadata.test.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '../../../src/types-hoist'; import { GLOBAL_OBJ, diff --git a/packages/core/test/lib/integrations/requestdata.test.ts b/packages/core/test/lib/integrations/requestdata.test.ts index 4603d5b290cf..aebd140b2bf3 100644 --- a/packages/core/test/lib/integrations/requestdata.test.ts +++ b/packages/core/test/lib/integrations/requestdata.test.ts @@ -1,7 +1,7 @@ import type { IncomingMessage } from 'http'; -import type { Event, EventProcessor } from '@sentry/types'; import type { RequestDataIntegrationOptions } from '../../../src'; import { requestDataIntegration, setCurrentClient } from '../../../src'; +import type { Event, EventProcessor } from '../../../src/types-hoist'; import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; diff --git a/packages/core/test/lib/integrations/rewriteframes.test.ts b/packages/core/test/lib/integrations/rewriteframes.test.ts index f3ea865b459d..e31976ba5785 100644 --- a/packages/core/test/lib/integrations/rewriteframes.test.ts +++ b/packages/core/test/lib/integrations/rewriteframes.test.ts @@ -1,4 +1,4 @@ -import type { Event, StackFrame } from '@sentry/types'; +import type { Event, StackFrame } from '../../../src/types-hoist'; import { generateIteratee, rewriteFramesIntegration } from '../../../src/integrations/rewriteframes'; diff --git a/packages/core/test/lib/integrations/sessiontiming.test.ts b/packages/core/test/lib/integrations/sessiontiming.test.ts index 1fd2fa53e361..fb694fe8be0f 100644 --- a/packages/core/test/lib/integrations/sessiontiming.test.ts +++ b/packages/core/test/lib/integrations/sessiontiming.test.ts @@ -1,5 +1,5 @@ -import type { Event } from '@sentry/types'; import { sessionTimingIntegration } from '../../../src/integrations/sessiontiming'; +import type { Event } from '../../../src/types-hoist'; // eslint-disable-next-line deprecation/deprecation const sessionTiming = sessionTimingIntegration(); diff --git a/packages/core/test/lib/integrations/third-party-errors-filter.test.ts b/packages/core/test/lib/integrations/third-party-errors-filter.test.ts index 91cfe7d4900b..ec35cf07f6ab 100644 --- a/packages/core/test/lib/integrations/third-party-errors-filter.test.ts +++ b/packages/core/test/lib/integrations/third-party-errors-filter.test.ts @@ -1,6 +1,6 @@ -import type { Client, Event } from '@sentry/types'; import { thirdPartyErrorFilterIntegration } from '../../../src/integrations/third-party-errors-filter'; import { addMetadataToStackFrames } from '../../../src/metadata'; +import type { Client, Event } from '../../../src/types-hoist'; import { nodeStackLineParser } from '../../../src/utils-hoist/node-stack-trace'; import { createStackParser } from '../../../src/utils-hoist/stacktrace'; import { GLOBAL_OBJ } from '../../../src/utils-hoist/worldwide'; diff --git a/packages/core/test/lib/integrations/zoderrrors.test.ts b/packages/core/test/lib/integrations/zoderrrors.test.ts index 33dc2609ac09..d5583fb57380 100644 --- a/packages/core/test/lib/integrations/zoderrrors.test.ts +++ b/packages/core/test/lib/integrations/zoderrrors.test.ts @@ -1,4 +1,4 @@ -import type { Event, EventHint } from '@sentry/types'; +import type { Event, EventHint } from '../../../src/types-hoist'; import { applyZodErrorsToEvent } from '../../../src/integrations/zoderrors'; diff --git a/packages/core/test/lib/metadata.test.ts b/packages/core/test/lib/metadata.test.ts index c3b31b68423f..7dbbe8a0ea1b 100644 --- a/packages/core/test/lib/metadata.test.ts +++ b/packages/core/test/lib/metadata.test.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '../../src/types-hoist'; import { addMetadataToStackFrames, getMetadataForUrl, stripMetadataFromStackFrames } from '../../src/metadata'; import { nodeStackLineParser } from '../../src/utils-hoist/node-stack-trace'; diff --git a/packages/core/test/lib/prepareEvent.test.ts b/packages/core/test/lib/prepareEvent.test.ts index a905d948475a..bd0798cc0898 100644 --- a/packages/core/test/lib/prepareEvent.test.ts +++ b/packages/core/test/lib/prepareEvent.test.ts @@ -1,3 +1,4 @@ +import { GLOBAL_OBJ, createStackParser, getGlobalScope, getIsolationScope } from '../../src'; import type { Attachment, Breadcrumb, @@ -7,11 +8,11 @@ import type { EventHint, EventProcessor, ScopeContext, -} from '@sentry/types'; -import { GLOBAL_OBJ, createStackParser, getGlobalScope, getIsolationScope } from '../../src'; +} from '../../src/types-hoist'; import { Scope } from '../../src/scope'; import { + applyClientOptions, applyDebugIds, applyDebugMeta, parseEventHintOrCaptureContext, @@ -518,3 +519,136 @@ describe('prepareEvent', () => { }); }); }); + +describe('applyClientOptions', () => { + it('works with defaults', () => { + const event: Event = {}; + const options = {} as ClientOptions; + + applyClientOptions(event, options); + + expect(event).toEqual({ + environment: 'production', + }); + + // These should not be set at all on the event + expect('release' in event).toBe(false); + expect('dist' in event).toBe(false); + }); + + it('works with event data and no options', () => { + const event: Event = { + environment: 'blub', + release: 'blab', + dist: 'blib', + }; + const options = {} as ClientOptions; + + applyClientOptions(event, options); + + expect(event).toEqual({ + environment: 'blub', + release: 'blab', + dist: 'blib', + }); + }); + + it('event data has precedence over options', () => { + const event: Event = { + environment: 'blub', + release: 'blab', + dist: 'blib', + }; + const options = { + environment: 'blub2', + release: 'blab2', + dist: 'blib2', + } as ClientOptions; + + applyClientOptions(event, options); + + expect(event).toEqual({ + environment: 'blub', + release: 'blab', + dist: 'blib', + }); + }); + + it('option data is used if no event data exists', () => { + const event: Event = {}; + const options = { + environment: 'blub2', + release: 'blab2', + dist: 'blib2', + } as ClientOptions; + + applyClientOptions(event, options); + + expect(event).toEqual({ + environment: 'blub2', + release: 'blab2', + dist: 'blib2', + }); + }); + + it('option data is ignored if empty string', () => { + const event: Event = {}; + const options = { + environment: '', + release: '', + dist: '', + } as ClientOptions; + + applyClientOptions(event, options); + + expect(event).toEqual({ + environment: 'production', + }); + + // These should not be set at all on the event + expect('release' in event).toBe(false); + expect('dist' in event).toBe(false); + }); + + it('option data is used if event data is undefined', () => { + const event: Event = { + environment: undefined, + release: undefined, + dist: undefined, + }; + const options = { + environment: 'blub2', + release: 'blab2', + dist: 'blib2', + } as ClientOptions; + + applyClientOptions(event, options); + + expect(event).toEqual({ + environment: 'blub2', + release: 'blab2', + dist: 'blib2', + }); + }); + + it('option data is used if event data is empty string', () => { + const event: Event = { + environment: '', + release: '', + dist: '', + }; + const options = { + environment: 'blub2', + release: 'blab2', + dist: 'blib2', + } as ClientOptions; + + applyClientOptions(event, options); + + expect(event).toEqual({ + environment: 'blub2', + release: 'blab2', + dist: 'blib2', + }); + }); +}); diff --git a/packages/core/test/lib/scope.test.ts b/packages/core/test/lib/scope.test.ts index c6a081948453..df95e08dcb97 100644 --- a/packages/core/test/lib/scope.test.ts +++ b/packages/core/test/lib/scope.test.ts @@ -1,4 +1,3 @@ -import type { Breadcrumb, Client, Event, RequestSessionStatus } from '@sentry/types'; import { applyScopeDataToEvent, getCurrentScope, @@ -7,6 +6,7 @@ import { withIsolationScope, withScope, } from '../../src'; +import type { Breadcrumb, Client, Event, RequestSessionStatus } from '../../src/types-hoist'; import { Scope } from '../../src/scope'; import { TestClient, getDefaultTestClientOptions } from '../mocks/client'; @@ -1002,15 +1002,4 @@ describe('withIsolationScope()', () => { done(); }); }); - - it('Scope type is equal to Scope from @sentry/types', () => { - // We pass the Scope _class_ here to the callback, - // Which actually is typed as using the Scope from @sentry/types - // This should not TS-error, as we export the type from core as well - const scope = withScope((scope: Scope) => { - return scope; - }); - - expect(scope).toBeDefined(); - }); }); diff --git a/packages/core/test/lib/sdk.test.ts b/packages/core/test/lib/sdk.test.ts index 74213cd8d99f..9da1dec65789 100644 --- a/packages/core/test/lib/sdk.test.ts +++ b/packages/core/test/lib/sdk.test.ts @@ -1,5 +1,5 @@ -import type { Client, Integration } from '@sentry/types'; import { captureCheckIn, getCurrentScope, setCurrentClient } from '../../src'; +import type { Client, Integration } from '../../src/types-hoist'; import { installedIntegrations } from '../../src/integration'; import { initAndBind } from '../../src/sdk'; diff --git a/packages/core/test/lib/serverruntimeclient.test.ts b/packages/core/test/lib/serverruntimeclient.test.ts index 8b149f7f2aaa..40be09bf011c 100644 --- a/packages/core/test/lib/serverruntimeclient.test.ts +++ b/packages/core/test/lib/serverruntimeclient.test.ts @@ -1,4 +1,4 @@ -import type { Event, EventHint } from '@sentry/types'; +import type { Event, EventHint } from '../../src/types-hoist'; import { createTransport } from '../../src'; import type { ServerRuntimeClientOptions } from '../../src/server-runtime-client'; diff --git a/packages/core/test/lib/session.test.ts b/packages/core/test/lib/session.test.ts index 55524866dcc2..dfe96e135088 100644 --- a/packages/core/test/lib/session.test.ts +++ b/packages/core/test/lib/session.test.ts @@ -1,4 +1,4 @@ -import type { SessionContext } from '@sentry/types'; +import type { SessionContext } from '../../src/types-hoist'; import { closeSession, makeSession, updateSession } from '../../src/session'; import { timestampInSeconds } from '../../src/utils-hoist/time'; diff --git a/packages/core/test/lib/sessionflusher.test.ts b/packages/core/test/lib/sessionflusher.test.ts index 808ba6308069..00f9becfdbf0 100644 --- a/packages/core/test/lib/sessionflusher.test.ts +++ b/packages/core/test/lib/sessionflusher.test.ts @@ -1,4 +1,4 @@ -import type { Client } from '@sentry/types'; +import type { Client } from '../../src/types-hoist'; import { SessionFlusher } from '../../src/sessionflusher'; diff --git a/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts b/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts index 628aec7e5fb7..579f90fbad56 100644 --- a/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts +++ b/packages/core/test/lib/tracing/dynamicSamplingContext.test.ts @@ -1,4 +1,3 @@ -import type { Span, SpanContextData, TransactionSource } from '@sentry/types'; import { SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, @@ -7,6 +6,7 @@ import { } from '../../../src'; import { SentrySpan, getDynamicSamplingContextFromSpan, startInactiveSpan } from '../../../src/tracing'; import { freezeDscOnSpan } from '../../../src/tracing/dynamicSamplingContext'; +import type { Span, SpanContextData, TransactionSource } from '../../../src/types-hoist'; import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; describe('getDynamicSamplingContextFromSpan', () => { diff --git a/packages/core/test/lib/tracing/errors.test.ts b/packages/core/test/lib/tracing/errors.test.ts index 68a3463b7878..7b3f08a6765b 100644 --- a/packages/core/test/lib/tracing/errors.test.ts +++ b/packages/core/test/lib/tracing/errors.test.ts @@ -1,5 +1,5 @@ -import type { HandlerDataError, HandlerDataUnhandledRejection } from '@sentry/types'; import { setCurrentClient, spanToJSON, startInactiveSpan, startSpan } from '../../../src'; +import type { HandlerDataError, HandlerDataUnhandledRejection } from '../../../src/types-hoist'; import { _resetErrorsInstrumented, registerSpanErrorInstrumentation } from '../../../src/tracing/errors'; import * as globalErrorModule from '../../../src/utils-hoist/instrument/globalError'; diff --git a/packages/core/test/lib/tracing/idleSpan.test.ts b/packages/core/test/lib/tracing/idleSpan.test.ts index 7a59fc790f0a..3d720f383173 100644 --- a/packages/core/test/lib/tracing/idleSpan.test.ts +++ b/packages/core/test/lib/tracing/idleSpan.test.ts @@ -1,6 +1,5 @@ import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; -import type { Event, Span } from '@sentry/types'; import { SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, SentryNonRecordingSpan, @@ -17,6 +16,7 @@ import { startSpanManual, } from '../../../src'; import { TRACING_DEFAULTS, startIdleSpan } from '../../../src/tracing/idleSpan'; +import type { Event, Span } from '../../../src/types-hoist'; const dsn = 'https://123@sentry.io/42'; diff --git a/packages/core/test/lib/tracing/sentryNonRecordingSpan.test.ts b/packages/core/test/lib/tracing/sentryNonRecordingSpan.test.ts index d5643c3d3651..373e81946093 100644 --- a/packages/core/test/lib/tracing/sentryNonRecordingSpan.test.ts +++ b/packages/core/test/lib/tracing/sentryNonRecordingSpan.test.ts @@ -1,6 +1,6 @@ -import type { Span } from '@sentry/types'; import { SPAN_STATUS_ERROR } from '../../../src/tracing'; import { SentryNonRecordingSpan } from '../../../src/tracing/sentryNonRecordingSpan'; +import type { Span } from '../../../src/types-hoist'; import { TRACE_FLAG_NONE, spanIsSampled, spanToJSON } from '../../../src/utils/spanUtils'; describe('SentryNonRecordingSpan', () => { @@ -16,8 +16,8 @@ describe('SentryNonRecordingSpan', () => { expect(spanIsSampled(span)).toBe(false); expect(span.isRecording()).toBe(false); expect(spanToJSON(span)).toEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); // Ensure all methods work @@ -30,8 +30,8 @@ describe('SentryNonRecordingSpan', () => { // but nothing is actually set/readable expect(spanToJSON(span)).toEqual({ - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); }); diff --git a/packages/core/test/lib/tracing/sentrySpan.test.ts b/packages/core/test/lib/tracing/sentrySpan.test.ts index 447e42328a2e..9a1c9f69255c 100644 --- a/packages/core/test/lib/tracing/sentrySpan.test.ts +++ b/packages/core/test/lib/tracing/sentrySpan.test.ts @@ -161,6 +161,8 @@ describe('SentrySpan', () => { }); test('does not send the span if `beforeSendSpan` drops the span', () => { + const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined); + const beforeSendSpan = jest.fn(() => null); const client = new TestClient( getDefaultTestClientOptions({ @@ -185,6 +187,12 @@ describe('SentrySpan', () => { expect(mockSend).not.toHaveBeenCalled(); expect(recordDroppedEventSpy).toHaveBeenCalledWith('before_send', 'span'); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(1); + expect(consoleWarnSpy).toBeCalledWith( + '[Sentry] Deprecation warning: Returning null from `beforeSendSpan` will be disallowed from SDK version 9.0.0 onwards. The callback will only support mutating spans. To drop certain spans, configure the respective integrations directly.', + ); + consoleWarnSpy.mockRestore(); }); }); diff --git a/packages/core/test/lib/tracing/trace.test.ts b/packages/core/test/lib/tracing/trace.test.ts index fe58ce6f9f7d..ac7605481649 100644 --- a/packages/core/test/lib/tracing/trace.test.ts +++ b/packages/core/test/lib/tracing/trace.test.ts @@ -1,4 +1,3 @@ -import type { Event, Span, StartSpanOptions } from '@sentry/types'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -25,6 +24,7 @@ import { } from '../../../src/tracing'; import { SentryNonRecordingSpan } from '../../../src/tracing/sentryNonRecordingSpan'; import { startNewTrace } from '../../../src/tracing/trace'; +import type { Event, Span, StartSpanOptions } from '../../../src/types-hoist'; import { _setSpanForScope } from '../../../src/utils/spanOnScope'; import { getActiveSpan, getRootSpan, getSpanDescendants, spanIsSampled } from '../../../src/utils/spanUtils'; import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; @@ -198,11 +198,11 @@ describe('startSpan', () => { }, origin: 'auto.http.browser', description: 'GET users/[id]', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: isError ? 'internal_error' : undefined, timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); }); @@ -350,8 +350,8 @@ describe('startSpan', () => { 'sentry.sample_rate': 1, 'sentry.origin': 'manual', }, - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, }); @@ -375,7 +375,7 @@ describe('startSpan', () => { 'sentry.origin': 'manual', }, parent_span_id: innerParentSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: outerTraceId, origin: 'manual', }, @@ -774,8 +774,8 @@ describe('startSpanManual', () => { 'sentry.sample_rate': 1, 'sentry.origin': 'manual', }, - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, }); @@ -799,7 +799,7 @@ describe('startSpanManual', () => { 'sentry.origin': 'manual', }, parent_span_id: innerParentSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: outerTraceId, origin: 'manual', }, @@ -1096,8 +1096,8 @@ describe('startInactiveSpan', () => { 'sentry.sample_rate': 1, 'sentry.origin': 'manual', }, - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, }); @@ -1121,7 +1121,7 @@ describe('startInactiveSpan', () => { 'sentry.origin': 'manual', }, parent_span_id: innerParentSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: outerTraceId, origin: 'manual', }, diff --git a/packages/core/test/lib/transports/base.test.ts b/packages/core/test/lib/transports/base.test.ts index 438dbb93c836..3c21c8bd70ed 100644 --- a/packages/core/test/lib/transports/base.test.ts +++ b/packages/core/test/lib/transports/base.test.ts @@ -1,4 +1,4 @@ -import type { AttachmentItem, EventEnvelope, EventItem, TransportMakeRequestResponse } from '@sentry/types'; +import type { AttachmentItem, EventEnvelope, EventItem, TransportMakeRequestResponse } from '../../../src/types-hoist'; import { createTransport } from '../../../src/transports/base'; import { createEnvelope, serializeEnvelope } from '../../../src/utils-hoist/envelope'; diff --git a/packages/core/test/lib/transports/multiplexed.test.ts b/packages/core/test/lib/transports/multiplexed.test.ts index 97d69e5a6113..647acbdc856e 100644 --- a/packages/core/test/lib/transports/multiplexed.test.ts +++ b/packages/core/test/lib/transports/multiplexed.test.ts @@ -6,7 +6,7 @@ import type { EventItem, TransactionEvent, Transport, -} from '@sentry/types'; +} from '../../../src/types-hoist'; import { createClientReportEnvelope, diff --git a/packages/core/test/lib/transports/offline.test.ts b/packages/core/test/lib/transports/offline.test.ts index c266a00d1378..5aa29596fa25 100644 --- a/packages/core/test/lib/transports/offline.test.ts +++ b/packages/core/test/lib/transports/offline.test.ts @@ -7,7 +7,7 @@ import type { ReplayEnvelope, ReplayEvent, TransportMakeRequestResponse, -} from '@sentry/types'; +} from '../../../src/types-hoist'; import { createClientReportEnvelope, diff --git a/packages/core/test/lib/utils/applyScopeDataToEvent.test.ts b/packages/core/test/lib/utils/applyScopeDataToEvent.test.ts index 7fb7befcd2a7..cb2757c95301 100644 --- a/packages/core/test/lib/utils/applyScopeDataToEvent.test.ts +++ b/packages/core/test/lib/utils/applyScopeDataToEvent.test.ts @@ -1,5 +1,5 @@ -import type { Attachment, Breadcrumb, Event, EventProcessor, EventType, ScopeData } from '@sentry/types'; import { startInactiveSpan } from '../../../src'; +import type { Attachment, Breadcrumb, Event, EventProcessor, EventType, ScopeData } from '../../../src/types-hoist'; import { applyScopeDataToEvent, mergeAndOverwriteScopeData, diff --git a/packages/core/test/lib/utils/isSentryRequestUrl.test.ts b/packages/core/test/lib/utils/isSentryRequestUrl.test.ts index b223f856b95e..a8d7c43a0784 100644 --- a/packages/core/test/lib/utils/isSentryRequestUrl.test.ts +++ b/packages/core/test/lib/utils/isSentryRequestUrl.test.ts @@ -1,4 +1,4 @@ -import type { Client } from '@sentry/types'; +import type { Client } from '../../../src/types-hoist'; import { isSentryRequestUrl } from '../../../src'; diff --git a/packages/core/test/lib/utils/parameterize.test.ts b/packages/core/test/lib/utils/parameterize.test.ts index 413ba8043c49..c772c2a410c3 100644 --- a/packages/core/test/lib/utils/parameterize.test.ts +++ b/packages/core/test/lib/utils/parameterize.test.ts @@ -1,4 +1,4 @@ -import type { ParameterizedString } from '@sentry/types'; +import type { ParameterizedString } from '../../../src/types-hoist'; import { parameterize } from '../../../src/utils/parameterize'; diff --git a/packages/core/test/lib/utils/spanUtils.test.ts b/packages/core/test/lib/utils/spanUtils.test.ts index 4f763a5edba6..f7187695a025 100644 --- a/packages/core/test/lib/utils/spanUtils.test.ts +++ b/packages/core/test/lib/utils/spanUtils.test.ts @@ -1,4 +1,3 @@ -import type { Span, SpanAttributes, SpanStatus, SpanTimeInput } from '@sentry/types'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -13,10 +12,50 @@ import { startSpan, timestampInSeconds, } from '../../../src'; +import type { Span, SpanAttributes, SpanStatus, SpanTimeInput } from '../../../src/types-hoist'; import type { OpenTelemetrySdkTraceBaseSpan } from '../../../src/utils/spanUtils'; +import { spanToTraceContext } from '../../../src/utils/spanUtils'; import { getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../../../src/utils/spanUtils'; import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; +function createMockedOtelSpan({ + spanId, + traceId, + isRemote, + attributes = {}, + startTime = Date.now(), + name = 'test span', + status = { code: SPAN_STATUS_UNSET }, + endTime = Date.now(), + parentSpanId, +}: { + spanId: string; + traceId: string; + attributes?: SpanAttributes; + startTime?: SpanTimeInput; + isRemote?: boolean; + name?: string; + status?: SpanStatus; + endTime?: SpanTimeInput; + parentSpanId?: string; +}): Span { + return { + spanContext: () => { + return { + spanId, + traceId, + isRemote, + }; + }, + attributes, + startTime, + name, + status, + endTime, + parentSpanId, + } as OpenTelemetrySdkTraceBaseSpan; +} + describe('spanToTraceHeader', () => { test('simple', () => { const span = new SentrySpan(); @@ -28,6 +67,88 @@ describe('spanToTraceHeader', () => { }); }); +describe('spanToTraceContext', () => { + it('works with a minimal span', () => { + const span = new SentrySpan({ spanId: '1234', traceId: 'ABCD' }); + + expect(spanToTraceContext(span)).toEqual({ + span_id: '1234', + trace_id: 'ABCD', + }); + }); + + it('works with a span with parentSpanId', () => { + const span = new SentrySpan({ + spanId: '1234', + traceId: 'ABCD', + parentSpanId: '5678', + }); + + expect(spanToTraceContext(span)).toEqual({ + span_id: '1234', + trace_id: 'ABCD', + parent_span_id: '5678', + }); + }); + + it('works with a local OTEL span', () => { + const span = createMockedOtelSpan({ + spanId: '1234', + traceId: 'ABCD', + isRemote: false, + }); + + expect(spanToTraceContext(span)).toEqual({ + span_id: '1234', + trace_id: 'ABCD', + }); + }); + + it('works with a local OTEL span with parentSpanId', () => { + const span = createMockedOtelSpan({ + spanId: '1234', + traceId: 'ABCD', + isRemote: false, + parentSpanId: 'XYZ', + }); + + expect(spanToTraceContext(span)).toEqual({ + parent_span_id: 'XYZ', + span_id: '1234', + trace_id: 'ABCD', + }); + }); + + it('works with a remote OTEL span', () => { + const span = createMockedOtelSpan({ + spanId: '1234', + traceId: 'ABCD', + isRemote: true, + }); + + expect(spanToTraceContext(span)).toEqual({ + parent_span_id: '1234', + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + trace_id: 'ABCD', + }); + }); + + it('works with a remote OTEL span with parentSpanId', () => { + const span = createMockedOtelSpan({ + spanId: '1234', + traceId: 'ABCD', + isRemote: true, + parentSpanId: 'XYZ', + }); + + expect(spanToTraceContext(span)).toEqual({ + parent_span_id: '1234', + span_id: expect.stringMatching(/^[0-9a-f]{16}$/), + trace_id: 'ABCD', + }); + }); +}); + describe('spanTimeInputToSeconds', () => { it('works with undefined', () => { const now = timestampInSeconds(); @@ -111,41 +232,6 @@ describe('spanToJSON', () => { }); describe('OpenTelemetry Span', () => { - function createMockedOtelSpan({ - spanId, - traceId, - attributes, - startTime, - name, - status, - endTime, - parentSpanId, - }: { - spanId: string; - traceId: string; - attributes: SpanAttributes; - startTime: SpanTimeInput; - name: string; - status: SpanStatus; - endTime: SpanTimeInput; - parentSpanId?: string; - }): Span { - return { - spanContext: () => { - return { - spanId, - traceId, - }; - }, - attributes, - startTime, - name, - status, - endTime, - parentSpanId, - } as OpenTelemetrySdkTraceBaseSpan; - } - it('works with a simple span', () => { const span = createMockedOtelSpan({ spanId: 'SPAN-1', diff --git a/packages/core/test/lib/utils/traceData.test.ts b/packages/core/test/lib/utils/traceData.test.ts index aa6d2497dd54..aad060b462de 100644 --- a/packages/core/test/lib/utils/traceData.test.ts +++ b/packages/core/test/lib/utils/traceData.test.ts @@ -1,231 +1,282 @@ -import { SentrySpan, getTraceData } from '../../../src/'; -import * as SentryCoreCurrentScopes from '../../../src/currentScopes'; -import * as SentryCoreExports from '../../../src/exports'; -import * as SentryCoreTracing from '../../../src/tracing'; -import * as SentryCoreSpanUtils from '../../../src/utils/spanUtils'; - -import { isValidBaggageString } from '../../../src/utils/traceData'; - -const TRACE_FLAG_SAMPLED = 1; - -const mockedSpan = new SentrySpan({ - traceId: '12345678901234567890123456789012', - spanId: '1234567890123456', - sampled: true, -}); +import { + SentrySpan, + getCurrentScope, + getGlobalScope, + getIsolationScope, + getMainCarrier, + getTraceData, + setAsyncContextStrategy, + setCurrentClient, + withActiveSpan, +} from '../../../src/'; +import { getAsyncContextStrategy } from '../../../src/asyncContext'; +import { freezeDscOnSpan } from '../../../src/tracing/dynamicSamplingContext'; +import type { Client, Span } from '../../../src/types-hoist'; + +import type { TestClientOptions } from '../../mocks/client'; +import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; + +const dsn = 'https://123@sentry.io/42'; + +const SCOPE_TRACE_ID = '12345678901234567890123456789012'; +const SCOPE_SPAN_ID = '1234567890123456'; + +function setupClient(opts?: Partial): Client { + getCurrentScope().setPropagationContext({ + traceId: SCOPE_TRACE_ID, + spanId: SCOPE_SPAN_ID, + }); -const mockedClient = {} as any; + const options = getDefaultTestClientOptions({ + dsn, + tracesSampleRate: 1, + ...opts, + }); + const client = new TestClient(options); + setCurrentClient(client); + client.init(); -const mockedScope = { - getPropagationContext: () => ({ - traceId: '123', - }), -} as any; + return client; +} describe('getTraceData', () => { beforeEach(() => { - jest.spyOn(SentryCoreExports, 'isEnabled').mockReturnValue(true); + setAsyncContextStrategy(undefined); + getCurrentScope().clear(); + getIsolationScope().clear(); + getGlobalScope().clear(); + getCurrentScope().setClient(undefined); }); afterEach(() => { jest.clearAllMocks(); }); - it('returns the tracing data from the span, if a span is available', () => { - { - jest.spyOn(SentryCoreTracing, 'getDynamicSamplingContextFromSpan').mockReturnValueOnce({ - environment: 'production', - }); - jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => mockedSpan); - jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce(() => mockedScope); + it('uses the ACS implementation, if available', () => { + setupClient(); + + const carrier = getMainCarrier(); + + const customFn = jest.fn((options?: { span?: Span }) => { + expect(options).toEqual({ span: undefined }); + return { + 'sentry-trace': 'abc', + baggage: 'xyz', + }; + }) as typeof getTraceData; + + const acs = { + ...getAsyncContextStrategy(carrier), + getTraceData: customFn, + }; + setAsyncContextStrategy(acs); + + const span = new SentrySpan({ + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + sampled: true, + }); + withActiveSpan(span, () => { const data = getTraceData(); expect(data).toEqual({ - 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', - baggage: 'sentry-environment=production', + 'sentry-trace': 'abc', + baggage: 'xyz', }); - } + }); }); - it('returns propagationContext DSC data if no span is available', () => { - jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => undefined); - jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce( - () => - ({ - getPropagationContext: () => ({ - traceId: '12345678901234567890123456789012', - sampled: true, - spanId: '1234567890123456', - dsc: { - environment: 'staging', - public_key: 'key', - trace_id: '12345678901234567890123456789012', - }, - }), - }) as any, - ); - jest.spyOn(SentryCoreCurrentScopes, 'getClient').mockImplementationOnce(() => mockedClient); + it('passes span to ACS implementation, if available', () => { + setupClient(); - const traceData = getTraceData(); + const carrier = getMainCarrier(); - expect(traceData).toEqual({ - 'sentry-trace': expect.stringMatching(/12345678901234567890123456789012-(.{16})-1/), - baggage: 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=12345678901234567890123456789012', + const span = new SentrySpan({ + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + sampled: true, + }); + + const customFn = jest.fn((options?: { span?: Span }) => { + expect(options).toEqual({ span }); + return { + 'sentry-trace': 'abc', + baggage: 'xyz', + }; + }) as typeof getTraceData; + + const acs = { + ...getAsyncContextStrategy(carrier), + getTraceData: customFn, + }; + setAsyncContextStrategy(acs); + + const data = getTraceData({ span }); + + expect(data).toEqual({ + 'sentry-trace': 'abc', + baggage: 'xyz', }); }); - it('returns only the `sentry-trace` value if no DSC is available', () => { - jest.spyOn(SentryCoreTracing, 'getDynamicSamplingContextFromClient').mockReturnValueOnce({ - trace_id: '', - public_key: undefined, - }); - - // @ts-expect-error - we don't need to provide all the properties - jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => ({ - isRecording: () => true, - spanContext: () => { - return { - traceId: '12345678901234567890123456789012', - spanId: '1234567890123456', - traceFlags: TRACE_FLAG_SAMPLED, - }; - }, - })); + it('returns the tracing data from the span, if a span is available', () => { + setupClient(); - jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce(() => mockedScope); - jest.spyOn(SentryCoreCurrentScopes, 'getClient').mockImplementationOnce(() => mockedClient); + const span = new SentrySpan({ + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + sampled: true, + }); - const traceData = getTraceData(); + withActiveSpan(span, () => { + const data = getTraceData(); - expect(traceData).toEqual({ + expect(data).toEqual({ + 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: + 'sentry-environment=production,sentry-public_key=123,sentry-trace_id=12345678901234567890123456789012,sentry-sampled=true', + }); + }); + }); + + it('allows to pass a span directly', () => { + setupClient(); + + const span = new SentrySpan({ + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + sampled: true, + }); + + const data = getTraceData({ span }); + + expect(data).toEqual({ 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: + 'sentry-environment=production,sentry-public_key=123,sentry-trace_id=12345678901234567890123456789012,sentry-sampled=true', }); }); - it('returns only the `sentry-trace` tag if no DSC is available without a client', () => { - jest.spyOn(SentryCoreTracing, 'getDynamicSamplingContextFromClient').mockReturnValueOnce({ - trace_id: '', - public_key: undefined, - }); - - // @ts-expect-error - we don't need to provide all the properties - jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => ({ - isRecording: () => true, - spanContext: () => { - return { - traceId: '12345678901234567890123456789012', - spanId: '1234567890123456', - traceFlags: TRACE_FLAG_SAMPLED, - }; + it('returns propagationContext DSC data if no span is available', () => { + setupClient(); + + getCurrentScope().setPropagationContext({ + traceId: '12345678901234567890123456789012', + sampled: true, + spanId: '1234567890123456', + dsc: { + environment: 'staging', + public_key: 'key', + trace_id: '12345678901234567890123456789012', }, - })); - jest.spyOn(SentryCoreCurrentScopes, 'getCurrentScope').mockImplementationOnce(() => mockedScope); - jest.spyOn(SentryCoreCurrentScopes, 'getClient').mockImplementationOnce(() => undefined); + }); const traceData = getTraceData(); expect(traceData).toEqual({ 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=12345678901234567890123456789012', }); - expect('baggage' in traceData).toBe(false); }); - it('returns an empty object if the `sentry-trace` value is invalid', () => { - // @ts-expect-error - we don't need to provide all the properties - jest.spyOn(SentryCoreSpanUtils, 'getActiveSpan').mockImplementationOnce(() => ({ - isRecording: () => true, - spanContext: () => { - return { - traceId: '1234567890123456789012345678901+', - spanId: '1234567890123456', - traceFlags: TRACE_FLAG_SAMPLED, - }; - }, - })); + it('returns frozen DSC from SentrySpan if available', () => { + setupClient(); - const traceData = getTraceData(); + const span = new SentrySpan({ + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + sampled: true, + }); - expect(traceData).toEqual({}); + freezeDscOnSpan(span, { + environment: 'test-dev', + public_key: '456', + trace_id: '12345678901234567890123456789088', + }); + + withActiveSpan(span, () => { + const data = getTraceData(); + + expect(data).toEqual({ + 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: 'sentry-environment=test-dev,sentry-public_key=456,sentry-trace_id=12345678901234567890123456789088', + }); + }); }); - it('returns an empty object if the SDK is disabled', () => { - jest.spyOn(SentryCoreExports, 'isEnabled').mockReturnValueOnce(false); + it('works with an OTEL span with frozen DSC in traceState', () => { + setupClient(); + const traceId = '12345678901234567890123456789099'; + const spanId = '1234567890123499'; + + const span = new SentrySpan({ + traceId, + spanId, + sampled: true, + }); + + span.spanContext = () => { + const traceState = { + set: () => traceState, + unset: () => traceState, + get: (key: string) => { + if (key === 'sentry.dsc') { + return 'sentry-environment=test-dev,sentry-public_key=456,sentry-trace_id=12345678901234567890123456789088'; + } + return undefined; + }, + serialize: () => '', + }; + + return { + traceId, + spanId, + sampled: true, + traceFlags: 1, + traceState, + }; + }; + + withActiveSpan(span, () => { + const data = getTraceData(); + + expect(data).toEqual({ + 'sentry-trace': '12345678901234567890123456789099-1234567890123499-1', + baggage: 'sentry-environment=test-dev,sentry-public_key=456,sentry-trace_id=12345678901234567890123456789088', + }); + }); + }); + + it('returns empty object without a client', () => { const traceData = getTraceData(); expect(traceData).toEqual({}); }); -}); -describe('isValidBaggageString', () => { - it.each([ - 'sentry-environment=production', - 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=abc', - // @ is allowed in values - 'sentry-release=project@1.0.0', - // spaces are allowed around the delimiters - 'sentry-environment=staging , sentry-public_key=key ,sentry-release=myproject@1.0.0', - 'sentry-environment=staging , thirdparty=value ,sentry-release=myproject@1.0.0', - // these characters are explicitly allowed for keys in the baggage spec: - "!#$%&'*+-.^_`|~1234567890abcxyzABCXYZ=true", - // special characters in values are fine (except for ",;\ - see other test) - 'key=(value)', - 'key=[{(value)}]', - 'key=some$value', - 'key=more#value', - 'key=max&value', - 'key=max:value', - 'key=x=value', - ])('returns true if the baggage string is valid (%s)', baggageString => { - expect(isValidBaggageString(baggageString)).toBe(true); - }); + it('returns an empty object if the `sentry-trace` value is invalid', () => { + // Invalid traceID + const traceId = '1234567890123456789012345678901+'; + const spanId = '1234567890123499'; + + const span = new SentrySpan({ + traceId, + spanId, + sampled: true, + }); - it.each([ - // baggage spec doesn't permit leading spaces - ' sentry-environment=production,sentry-publickey=key,sentry-trace_id=abc', - // no spaces in keys or values - 'sentry-public key=key', - 'sentry-publickey=my key', - // no delimiters ("(),/:;<=>?@[\]{}") in keys - 'asdf(x=value', - 'asdf)x=value', - 'asdf,x=value', - 'asdf/x=value', - 'asdf:x=value', - 'asdf;x=value', - 'asdfx=value', - 'asdf?x=value', - 'asdf@x=value', - 'asdf[x=value', - 'asdf]x=value', - 'asdf\\x=value', - 'asdf{x=value', - 'asdf}x=value', - // no ,;\" in values - 'key=va,lue', - 'key=va;lue', - 'key=va\\lue', - 'key=va"lue"', - // baggage headers can have properties but we currently don't support them - 'sentry-environment=production;prop1=foo;prop2=bar,nextkey=value', - // no fishy stuff - 'absolutely not a valid baggage string', - 'val"/>', - 'something"/>', - '', - '/>', - '" onblur="alert("xss")', - ])('returns false if the baggage string is invalid (%s)', baggageString => { - expect(isValidBaggageString(baggageString)).toBe(false); + withActiveSpan(span, () => { + const data = getTraceData(); + expect(data).toEqual({}); + }); }); - it('returns false if the baggage string is empty', () => { - expect(isValidBaggageString('')).toBe(false); - }); + it('returns an empty object if the SDK is disabled', () => { + setupClient({ dsn: undefined }); + + const traceData = getTraceData(); - it('returns false if the baggage string is empty', () => { - expect(isValidBaggageString(undefined)).toBe(false); + expect(traceData).toEqual({}); }); }); diff --git a/packages/core/test/mocks/client.ts b/packages/core/test/mocks/client.ts index 712134388aef..eaf06909c9ab 100644 --- a/packages/core/test/mocks/client.ts +++ b/packages/core/test/mocks/client.ts @@ -7,7 +7,7 @@ import type { ParameterizedString, Session, SeverityLevel, -} from '@sentry/types'; +} from '../../src/types-hoist'; import { BaseClient } from '../../src/baseclient'; import { initAndBind } from '../../src/sdk'; diff --git a/packages/core/test/mocks/integration.ts b/packages/core/test/mocks/integration.ts index 1962596ce79c..5028bfa71ac7 100644 --- a/packages/core/test/mocks/integration.ts +++ b/packages/core/test/mocks/integration.ts @@ -1,4 +1,4 @@ -import type { Client, Event, EventProcessor, Integration } from '@sentry/types'; +import type { Client, Event, EventProcessor, Integration } from '../../src/types-hoist'; import { getClient, getCurrentScope } from '../../src'; diff --git a/packages/core/test/mocks/transport.ts b/packages/core/test/mocks/transport.ts index af6863237562..a0670700076a 100644 --- a/packages/core/test/mocks/transport.ts +++ b/packages/core/test/mocks/transport.ts @@ -1,4 +1,4 @@ -import type { Transport } from '@sentry/types'; +import type { Transport } from '../../src/types-hoist'; import { createTransport } from '../../src/transports/base'; import { SyncPromise } from '../../src/utils-hoist/syncpromise'; diff --git a/packages/core/test/utils-hoist/aggregate-errors.test.ts b/packages/core/test/utils-hoist/aggregate-errors.test.ts index 3d13a4d29b21..535325bd0491 100644 --- a/packages/core/test/utils-hoist/aggregate-errors.test.ts +++ b/packages/core/test/utils-hoist/aggregate-errors.test.ts @@ -1,4 +1,4 @@ -import type { Event, EventHint, Exception, ExtendedError, StackParser } from '@sentry/types'; +import type { Event, EventHint, Exception, ExtendedError, StackParser } from '../../src/types-hoist'; import { applyAggregateErrorsToEvent } from '../../src/utils-hoist/aggregate-errors'; import { createStackParser } from '../../src/utils-hoist/stacktrace'; diff --git a/packages/core/test/utils-hoist/clientreport.test.ts b/packages/core/test/utils-hoist/clientreport.test.ts index 698ad195d7fa..f925d74fa50c 100644 --- a/packages/core/test/utils-hoist/clientreport.test.ts +++ b/packages/core/test/utils-hoist/clientreport.test.ts @@ -1,4 +1,4 @@ -import type { ClientReport } from '@sentry/types'; +import type { ClientReport } from '../../src/types-hoist'; import { createClientReportEnvelope } from '../../src/utils-hoist/clientreport'; import { parseEnvelope, serializeEnvelope } from '../../src/utils-hoist/envelope'; diff --git a/packages/core/test/utils-hoist/envelope.test.ts b/packages/core/test/utils-hoist/envelope.test.ts index 9ebfd447fb14..dfb24f043fe8 100644 --- a/packages/core/test/utils-hoist/envelope.test.ts +++ b/packages/core/test/utils-hoist/envelope.test.ts @@ -1,4 +1,4 @@ -import type { Event, EventEnvelope, SpanAttributes } from '@sentry/types'; +import type { Event, EventEnvelope, SpanAttributes } from '../../src/types-hoist'; import { SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, @@ -62,10 +62,10 @@ describe('envelope', () => { }, description: expect.any(String), op: expect.any(String), - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: expect.any(String), exclusive_time: expect.any(Number), measurements: { inp: { value: expect.any(Number), unit: expect.any(String) } }, diff --git a/packages/core/test/utils-hoist/eventbuilder.test.ts b/packages/core/test/utils-hoist/eventbuilder.test.ts index e12726746e04..afc193a343e3 100644 --- a/packages/core/test/utils-hoist/eventbuilder.test.ts +++ b/packages/core/test/utils-hoist/eventbuilder.test.ts @@ -1,4 +1,4 @@ -import type { Client } from '@sentry/types'; +import type { Client } from '../../src/types-hoist'; import { eventFromUnknownInput } from '../../src/utils-hoist/eventbuilder'; import { nodeStackLineParser } from '../../src/utils-hoist/node-stack-trace'; import { createStackParser } from '../../src/utils-hoist/stacktrace'; diff --git a/packages/core/test/utils-hoist/misc.test.ts b/packages/core/test/utils-hoist/misc.test.ts index 679f0173ffca..a042215fbcb9 100644 --- a/packages/core/test/utils-hoist/misc.test.ts +++ b/packages/core/test/utils-hoist/misc.test.ts @@ -1,4 +1,4 @@ -import type { Event, Mechanism, StackFrame } from '@sentry/types'; +import type { Event, Mechanism, StackFrame } from '../../src/types-hoist'; import { addContextToFrame, diff --git a/packages/core/test/utils-hoist/object.test.ts b/packages/core/test/utils-hoist/object.test.ts index 2fadb530bdf2..ed83b5d87aef 100644 --- a/packages/core/test/utils-hoist/object.test.ts +++ b/packages/core/test/utils-hoist/object.test.ts @@ -2,7 +2,7 @@ * @jest-environment jsdom */ -import type { WrappedFunction } from '@sentry/types'; +import type { WrappedFunction } from '../../src/types-hoist'; import { addNonEnumerableProperty, diff --git a/packages/core/test/utils-hoist/proagationContext.test.ts b/packages/core/test/utils-hoist/proagationContext.test.ts index 5e895af0ba58..700e9d0b7942 100644 --- a/packages/core/test/utils-hoist/proagationContext.test.ts +++ b/packages/core/test/utils-hoist/proagationContext.test.ts @@ -2,6 +2,7 @@ import { generatePropagationContext } from '../../src/utils-hoist/propagationCon describe('generatePropagationContext', () => { it('generates a new minimal propagation context', () => { + // eslint-disable-next-line deprecation/deprecation expect(generatePropagationContext()).toEqual({ traceId: expect.stringMatching(/^[0-9a-f]{32}$/), spanId: expect.stringMatching(/^[0-9a-f]{16}$/), diff --git a/packages/core/test/utils-hoist/requestdata.test.ts b/packages/core/test/utils-hoist/requestdata.test.ts index 3df3ee7e84eb..a36a0669dc7b 100644 --- a/packages/core/test/utils-hoist/requestdata.test.ts +++ b/packages/core/test/utils-hoist/requestdata.test.ts @@ -1,7 +1,7 @@ /* eslint-disable deprecation/deprecation */ import type * as net from 'net'; import { addRequestDataToEvent, extractPathForTransaction, extractRequestData } from '@sentry/core'; -import type { Event, PolymorphicRequest, TransactionSource, User } from '@sentry/types'; +import type { Event, PolymorphicRequest, TransactionSource, User } from '../../src/types-hoist'; import { getClientIPAddress } from '../../src/utils-hoist/vendor/getIpAddress'; describe('addRequestDataToEvent', () => { diff --git a/packages/core/test/utils-hoist/url.test.ts b/packages/core/test/utils-hoist/url.test.ts index fd8b861516ab..cd793e1d3d0c 100644 --- a/packages/core/test/utils-hoist/url.test.ts +++ b/packages/core/test/utils-hoist/url.test.ts @@ -33,6 +33,7 @@ describe('getNumberOfUrlSegments', () => { ['multi param parameterized path', '/stores/:storeId/products/:productId', 4], ['regex path', String(/\/api\/post[0-9]/), 2], ])('%s', (_: string, input, output) => { + // eslint-disable-next-line deprecation/deprecation expect(getNumberOfUrlSegments(input)).toEqual(output); }); }); diff --git a/packages/deno/package.json b/packages/deno/package.json index 2e19f129656f..5a27481538cd 100644 --- a/packages/deno/package.json +++ b/packages/deno/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/deno", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Deno", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/deno", @@ -24,8 +24,7 @@ "/build" ], "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "devDependencies": { "@rollup/plugin-typescript": "^11.1.5", diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts index 5538f92519a9..892f6ce681c0 100644 --- a/packages/deno/src/index.ts +++ b/packages/deno/src/index.ts @@ -17,7 +17,7 @@ export type { Stacktrace, Thread, User, -} from '@sentry/types'; +} from '@sentry/core'; export type { AddRequestDataToEventOptions } from '@sentry/core'; export type { DenoOptions } from './types'; diff --git a/packages/deno/src/integrations/breadcrumbs.ts b/packages/deno/src/integrations/breadcrumbs.ts index 77c471793ed3..f826ed8310cb 100644 --- a/packages/deno/src/integrations/breadcrumbs.ts +++ b/packages/deno/src/integrations/breadcrumbs.ts @@ -1,12 +1,3 @@ -import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core'; -import { - addConsoleInstrumentationHandler, - addFetchInstrumentationHandler, - getBreadcrumbLogLevelFromHttpStatusCode, - getEventDescription, - safeJoin, - severityLevelFromString, -} from '@sentry/core'; import type { Client, Event as SentryEvent, @@ -15,7 +6,18 @@ import type { HandlerDataConsole, HandlerDataFetch, IntegrationFn, -} from '@sentry/types'; +} from '@sentry/core'; +import { + addBreadcrumb, + addConsoleInstrumentationHandler, + addFetchInstrumentationHandler, + defineIntegration, + getBreadcrumbLogLevelFromHttpStatusCode, + getClient, + getEventDescription, + safeJoin, + severityLevelFromString, +} from '@sentry/core'; interface BreadcrumbsOptions { console: boolean; diff --git a/packages/deno/src/integrations/context.ts b/packages/deno/src/integrations/context.ts index 926fcd065f1b..d89c129d2f75 100644 --- a/packages/deno/src/integrations/context.ts +++ b/packages/deno/src/integrations/context.ts @@ -1,5 +1,5 @@ import { defineIntegration } from '@sentry/core'; -import type { Event, IntegrationFn } from '@sentry/types'; +import type { Event, IntegrationFn } from '@sentry/core'; const INTEGRATION_NAME = 'DenoContext'; diff --git a/packages/deno/src/integrations/contextlines.ts b/packages/deno/src/integrations/contextlines.ts index 44dc400c9aa0..d969ab001d7e 100644 --- a/packages/deno/src/integrations/contextlines.ts +++ b/packages/deno/src/integrations/contextlines.ts @@ -1,6 +1,5 @@ -import { defineIntegration } from '@sentry/core'; -import { LRUMap, addContextToFrame } from '@sentry/core'; -import type { Event, IntegrationFn, StackFrame } from '@sentry/types'; +import type { Event, IntegrationFn, StackFrame } from '@sentry/core'; +import { LRUMap, addContextToFrame, defineIntegration } from '@sentry/core'; const INTEGRATION_NAME = 'ContextLines'; const FILE_CONTENT_CACHE = new LRUMap(100); diff --git a/packages/deno/src/integrations/deno-cron.ts b/packages/deno/src/integrations/deno-cron.ts index bdf330319c4c..25d4c9e7d854 100644 --- a/packages/deno/src/integrations/deno-cron.ts +++ b/packages/deno/src/integrations/deno-cron.ts @@ -1,5 +1,5 @@ import { defineIntegration, getClient, withMonitor } from '@sentry/core'; -import type { Client, IntegrationFn } from '@sentry/types'; +import type { Client, IntegrationFn } from '@sentry/core'; import { parseScheduleToString } from './deno-cron-format'; type CronOptions = { backoffSchedule?: number[]; signal?: AbortSignal }; diff --git a/packages/deno/src/integrations/globalhandlers.ts b/packages/deno/src/integrations/globalhandlers.ts index bf985f1096c8..cb799b0be132 100644 --- a/packages/deno/src/integrations/globalhandlers.ts +++ b/packages/deno/src/integrations/globalhandlers.ts @@ -1,10 +1,5 @@ -import type { ServerRuntimeClient } from '@sentry/core'; -import { defineIntegration } from '@sentry/core'; -import { captureEvent } from '@sentry/core'; -import { getClient } from '@sentry/core'; -import { flush } from '@sentry/core'; -import { eventFromUnknownInput, isPrimitive } from '@sentry/core'; -import type { Client, Event, IntegrationFn, Primitive, StackParser } from '@sentry/types'; +import type { Client, Event, IntegrationFn, Primitive, ServerRuntimeClient, StackParser } from '@sentry/core'; +import { captureEvent, defineIntegration, eventFromUnknownInput, flush, getClient, isPrimitive } from '@sentry/core'; type GlobalHandlersIntegrationsOptionKeys = 'error' | 'unhandledrejection'; diff --git a/packages/deno/src/integrations/normalizepaths.ts b/packages/deno/src/integrations/normalizepaths.ts index ad8b18694652..417fd139b545 100644 --- a/packages/deno/src/integrations/normalizepaths.ts +++ b/packages/deno/src/integrations/normalizepaths.ts @@ -1,6 +1,5 @@ -import { defineIntegration } from '@sentry/core'; -import { createStackParser, dirname, nodeStackLineParser } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; +import { createStackParser, defineIntegration, dirname, nodeStackLineParser } from '@sentry/core'; const INTEGRATION_NAME = 'NormalizePaths'; diff --git a/packages/deno/src/sdk.ts b/packages/deno/src/sdk.ts index 57c6817c51ee..25dc550fc353 100644 --- a/packages/deno/src/sdk.ts +++ b/packages/deno/src/sdk.ts @@ -1,14 +1,15 @@ -import type { ServerRuntimeClientOptions } from '@sentry/core'; +import type { Client, Integration, Options, ServerRuntimeClientOptions, StackParser } from '@sentry/core'; import { + createStackParser, dedupeIntegration, functionToStringIntegration, + getIntegrationsToSetup, inboundFiltersIntegration, + initAndBind, linkedErrorsIntegration, + nodeStackLineParser, + stackParserFromStackParserOptions, } from '@sentry/core'; -import { getIntegrationsToSetup, initAndBind } from '@sentry/core'; -import { createStackParser, nodeStackLineParser, stackParserFromStackParserOptions } from '@sentry/core'; -import type { Client, Integration, Options, StackParser } from '@sentry/types'; - import { DenoClient } from './client'; import { breadcrumbsIntegration } from './integrations/breadcrumbs'; import { denoContextIntegration } from './integrations/context'; diff --git a/packages/deno/src/transports/index.ts b/packages/deno/src/transports/index.ts index d55c58f6054f..3d4e26a9f805 100644 --- a/packages/deno/src/transports/index.ts +++ b/packages/deno/src/transports/index.ts @@ -1,6 +1,5 @@ -import { createTransport, suppressTracing } from '@sentry/core'; -import { consoleSandbox, logger, rejectedSyncPromise } from '@sentry/core'; -import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; +import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core'; +import { consoleSandbox, createTransport, logger, rejectedSyncPromise, suppressTracing } from '@sentry/core'; export interface DenoTransportOptions extends BaseTransportOptions { /** Custom headers for the transport. Used by the XHRTransport and FetchTransport */ diff --git a/packages/deno/src/types.ts b/packages/deno/src/types.ts index 92752c5b9d0b..422e561bb644 100644 --- a/packages/deno/src/types.ts +++ b/packages/deno/src/types.ts @@ -1,5 +1,4 @@ -import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/types'; - +import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/core'; import type { DenoTransportOptions } from './transports'; export interface BaseDenoOptions { @@ -30,7 +29,7 @@ export interface BaseDenoOptions { /** * Configuration options for the Sentry Deno SDK - * @see @sentry/types Options for more information. + * @see @sentry/core Options for more information. */ export interface DenoOptions extends Options, BaseDenoOptions {} diff --git a/packages/deno/test/build.ts b/packages/deno/test/build.ts index 86bb371afc08..2ea3d4191454 100644 --- a/packages/deno/test/build.ts +++ b/packages/deno/test/build.ts @@ -1,4 +1,4 @@ // We use this as the entry point to bundle Sentry dependencies that are used by the tests. -export * as sentryTypes from '@sentry/types'; +export * as sentryTypes from '@sentry/core'; export * as sentryUtils from '@sentry/core'; export * as sentryCore from '@sentry/core'; diff --git a/packages/ember/addon/index.ts b/packages/ember/addon/index.ts index 2080581b6138..9f1b536dc656 100644 --- a/packages/ember/addon/index.ts +++ b/packages/ember/addon/index.ts @@ -9,7 +9,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, app import { GLOBAL_OBJ } from '@sentry/core'; import Ember from 'ember'; -import type { Client, TransactionSource } from '@sentry/types'; +import type { Client, TransactionSource } from '@sentry/core'; import type { EmberSentryConfig, GlobalConfig, OwnConfig } from './types'; function _getSentryInitConfig(): EmberSentryConfig['sentry'] { diff --git a/packages/ember/addon/instance-initializers/sentry-performance.ts b/packages/ember/addon/instance-initializers/sentry-performance.ts index 614426cb47c9..73acdd28c43b 100644 --- a/packages/ember/addon/instance-initializers/sentry-performance.ts +++ b/packages/ember/addon/instance-initializers/sentry-performance.ts @@ -19,8 +19,8 @@ import { startInactiveSpan, } from '@sentry/browser'; import { GLOBAL_OBJ, browserPerformanceTimeOrigin, timestampInSeconds } from '@sentry/core'; +import type { Span } from '@sentry/core'; import type { ExtendedBackburner } from '@sentry/ember/runloop'; -import type { Span } from '@sentry/types'; import type { EmberRouterMain, EmberSentryConfig, GlobalConfig, OwnConfig } from '../types'; function getSentryConfig(): EmberSentryConfig { diff --git a/packages/ember/package.json b/packages/ember/package.json index e24ce2271cd3..3d66ebf35ec5 100644 --- a/packages/ember/package.json +++ b/packages/ember/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/ember", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Ember.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/ember", @@ -32,9 +32,8 @@ "dependencies": { "@babel/core": "^7.24.4", "@embroider/macros": "^1.16.0", - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0", "ember-auto-import": "^2.7.2", "ember-cli-babel": "^8.2.0", "ember-cli-htmlbars": "^6.1.1", diff --git a/packages/ember/tests/helpers/utils.ts b/packages/ember/tests/helpers/utils.ts index eaeeae0114b6..bce62a85dea1 100644 --- a/packages/ember/tests/helpers/utils.ts +++ b/packages/ember/tests/helpers/utils.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; const defaultAssertOptions = { method: 'POST', diff --git a/packages/eslint-config-sdk/package.json b/packages/eslint-config-sdk/package.json index 329660ba4abe..2952a2b21a3b 100644 --- a/packages/eslint-config-sdk/package.json +++ b/packages/eslint-config-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-config-sdk", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK eslint config", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-config-sdk", @@ -22,8 +22,8 @@ "access": "public" }, "dependencies": { - "@sentry-internal/eslint-plugin-sdk": "8.40.0", - "@sentry-internal/typescript": "8.40.0", + "@sentry-internal/eslint-plugin-sdk": "8.42.0", + "@sentry-internal/typescript": "8.42.0", "@typescript-eslint/eslint-plugin": "^5.48.0", "@typescript-eslint/parser": "^5.48.0", "eslint-config-prettier": "^6.11.0", diff --git a/packages/eslint-plugin-sdk/package.json b/packages/eslint-plugin-sdk/package.json index 7b2229bda873..9853cf646ef3 100644 --- a/packages/eslint-plugin-sdk/package.json +++ b/packages/eslint-plugin-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-plugin-sdk", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK eslint plugin", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-plugin-sdk", diff --git a/packages/feedback/package.json b/packages/feedback/package.json index fcd961e9376e..70e5fb17d046 100644 --- a/packages/feedback/package.json +++ b/packages/feedback/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/feedback", - "version": "8.40.0", + "version": "8.42.0", "description": "Sentry SDK integration for user feedback", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/feedback", @@ -39,8 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "devDependencies": { "preact": "^10.19.4" diff --git a/packages/feedback/src/core/TestClient.ts b/packages/feedback/src/core/TestClient.ts index c938acd182f5..f688cdb51a85 100644 --- a/packages/feedback/src/core/TestClient.ts +++ b/packages/feedback/src/core/TestClient.ts @@ -1,6 +1,5 @@ -import { BaseClient, createTransport, initAndBind } from '@sentry/core'; -import { resolvedSyncPromise } from '@sentry/core'; -import type { BrowserClientReplayOptions, ClientOptions, Event, SeverityLevel } from '@sentry/types'; +import type { BrowserClientReplayOptions, ClientOptions, Event, SeverityLevel } from '@sentry/core'; +import { BaseClient, createTransport, initAndBind, resolvedSyncPromise } from '@sentry/core'; export interface TestClientOptions extends ClientOptions, BrowserClientReplayOptions {} diff --git a/packages/feedback/src/core/createMainStyles.ts b/packages/feedback/src/core/createMainStyles.ts index 7c2b995274fc..6ed6e2e357d8 100644 --- a/packages/feedback/src/core/createMainStyles.ts +++ b/packages/feedback/src/core/createMainStyles.ts @@ -1,4 +1,4 @@ -import type { FeedbackInternalOptions } from '@sentry/types'; +import type { FeedbackInternalOptions } from '@sentry/core'; import { DOCUMENT } from '../constants'; const PURPLE = 'rgba(88, 74, 192, 1)'; diff --git a/packages/feedback/src/core/integration.ts b/packages/feedback/src/core/integration.ts index 1ff5f9778cb3..fb1bd1fc143e 100644 --- a/packages/feedback/src/core/integration.ts +++ b/packages/feedback/src/core/integration.ts @@ -1,12 +1,11 @@ -import { getClient } from '@sentry/core'; -import { isBrowser, logger } from '@sentry/core'; import type { FeedbackInternalOptions, FeedbackModalIntegration, FeedbackScreenshotIntegration, Integration, IntegrationFn, -} from '@sentry/types'; +} from '@sentry/core'; +import { getClient, isBrowser, logger } from '@sentry/core'; import { ADD_SCREENSHOT_LABEL, CANCEL_BUTTON_LABEL, diff --git a/packages/feedback/src/core/mockSdk.ts b/packages/feedback/src/core/mockSdk.ts index cb9b2a982397..24413d907fc3 100644 --- a/packages/feedback/src/core/mockSdk.ts +++ b/packages/feedback/src/core/mockSdk.ts @@ -1,4 +1,4 @@ -import type { Envelope, Transport, TransportMakeRequestResponse } from '@sentry/types'; +import type { Envelope, Transport, TransportMakeRequestResponse } from '@sentry/core'; import type { TestClientOptions } from './TestClient'; import { getDefaultClientOptions, init } from './TestClient'; diff --git a/packages/feedback/src/core/sendFeedback.test.ts b/packages/feedback/src/core/sendFeedback.test.ts index 96df79828ac8..826dd3f05daf 100644 --- a/packages/feedback/src/core/sendFeedback.test.ts +++ b/packages/feedback/src/core/sendFeedback.test.ts @@ -49,7 +49,7 @@ describe('sendFeedback', () => { event_id: expect.any(String), sent_at: expect.any(String), trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), environment: 'production', public_key: 'dsn', }, @@ -61,8 +61,8 @@ describe('sendFeedback', () => { breadcrumbs: undefined, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { message: 'mi', @@ -105,7 +105,7 @@ describe('sendFeedback', () => { event_id: expect.any(String), sent_at: expect.any(String), trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), environment: 'production', public_key: 'dsn', }, @@ -117,8 +117,8 @@ describe('sendFeedback', () => { breadcrumbs: undefined, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { name: 'doe', @@ -157,7 +157,7 @@ describe('sendFeedback', () => { event_id: expect.any(String), sent_at: expect.any(String), trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), environment: 'production', public_key: 'dsn', sample_rate: '1', @@ -172,8 +172,8 @@ describe('sendFeedback', () => { breadcrumbs: undefined, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { contact_email: 're@example.org', @@ -221,7 +221,7 @@ describe('sendFeedback', () => { event_id: expect.any(String), sent_at: expect.any(String), trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), environment: 'production', public_key: 'dsn', }, @@ -233,8 +233,8 @@ describe('sendFeedback', () => { breadcrumbs: [{ message: 'test breadcrumb', timestamp: 12345 }], contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { contact_email: 're@example.org', @@ -374,7 +374,7 @@ describe('sendFeedback', () => { event_id: eventId, sent_at: expect.any(String), trace: { - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), environment: 'production', public_key: 'dsn', }, @@ -386,8 +386,8 @@ describe('sendFeedback', () => { breadcrumbs: undefined, contexts: { trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, feedback: { contact_email: 're@example.org', diff --git a/packages/feedback/src/core/sendFeedback.ts b/packages/feedback/src/core/sendFeedback.ts index 3503c55a2ef2..8342a03a2f71 100644 --- a/packages/feedback/src/core/sendFeedback.ts +++ b/packages/feedback/src/core/sendFeedback.ts @@ -1,8 +1,5 @@ -import { captureFeedback } from '@sentry/core'; -import { getClient } from '@sentry/core'; -import { getCurrentScope } from '@sentry/core'; -import { getLocationHref } from '@sentry/core'; -import type { Event, EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/types'; +import type { Event, EventHint, SendFeedback, SendFeedbackParams, TransportMakeRequestResponse } from '@sentry/core'; +import { captureFeedback, getClient, getCurrentScope, getLocationHref } from '@sentry/core'; import { FEEDBACK_API_SOURCE } from '../constants'; /** diff --git a/packages/feedback/src/core/types.ts b/packages/feedback/src/core/types.ts index a85987301702..7f6b0d72e6af 100644 --- a/packages/feedback/src/core/types.ts +++ b/packages/feedback/src/core/types.ts @@ -1,4 +1,4 @@ -import type { FeedbackInternalOptions } from '@sentry/types'; +import type { FeedbackInternalOptions } from '@sentry/core'; /** * Partial configuration that overrides default configuration values diff --git a/packages/feedback/src/modal/components/Dialog.css.ts b/packages/feedback/src/modal/components/Dialog.css.ts index da12e3d70990..8459108d1fc2 100644 --- a/packages/feedback/src/modal/components/Dialog.css.ts +++ b/packages/feedback/src/modal/components/Dialog.css.ts @@ -60,7 +60,7 @@ const DIALOG = ` gap: 16px; padding: var(--dialog-padding, 24px); max-width: 100%; - width: var(--form-width, 272px); + width: 100%; max-height: 100%; overflow: auto; @@ -72,12 +72,6 @@ const DIALOG = ` transition: transform 0.2s ease-in-out; } -@media (max-width: 600px) { - .dialog__content { - width: var(--form-width, 100%); - } -} - `; const DIALOG_HEADER = ` @@ -90,7 +84,20 @@ const DIALOG_HEADER = ` } .dialog__title { align-self: center; + width: var(--form-width, 272px); } + +@media (max-width: 600px) { + .dialog__title { + width: auto; + } +} + +.dialog__position:has(.editor) .dialog__title { + width: auto; +} + + .brand-link { display: inline-flex; } @@ -115,7 +122,11 @@ const FORM = ` flex-direction: column; justify-content: space-between; gap: 20px; - width: 100%; + width: var(--form-width, 100%); +} + +.dialog__position:has(.editor) .form__right { + width: var(--form-width, 272px); } .form__top { diff --git a/packages/feedback/src/modal/components/Dialog.tsx b/packages/feedback/src/modal/components/Dialog.tsx index b711335a96c3..7bcde062a7c7 100644 --- a/packages/feedback/src/modal/components/Dialog.tsx +++ b/packages/feedback/src/modal/components/Dialog.tsx @@ -1,4 +1,4 @@ -import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/types'; +import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/core'; // biome-ignore lint/nursery/noUnusedImports: reason import { Fragment, h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars import type { VNode } from 'preact'; diff --git a/packages/feedback/src/modal/components/DialogHeader.tsx b/packages/feedback/src/modal/components/DialogHeader.tsx index 217ce6676ee0..3615bdf5068b 100644 --- a/packages/feedback/src/modal/components/DialogHeader.tsx +++ b/packages/feedback/src/modal/components/DialogHeader.tsx @@ -1,4 +1,4 @@ -import type { FeedbackInternalOptions } from '@sentry/types'; +import type { FeedbackInternalOptions } from '@sentry/core'; // biome-ignore lint/nursery/noUnusedImports: reason import { h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars import type { VNode } from 'preact'; diff --git a/packages/feedback/src/modal/components/Form.tsx b/packages/feedback/src/modal/components/Form.tsx index 4267e10f81d4..e42772875fc3 100644 --- a/packages/feedback/src/modal/components/Form.tsx +++ b/packages/feedback/src/modal/components/Form.tsx @@ -4,7 +4,7 @@ import type { FeedbackInternalOptions, FeedbackScreenshotIntegration, SendFeedback, -} from '@sentry/types'; +} from '@sentry/core'; // biome-ignore lint/nursery/noUnusedImports: reason import { h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars import type { JSX, VNode } from 'preact'; diff --git a/packages/feedback/src/modal/integration.tsx b/packages/feedback/src/modal/integration.tsx index 25a782db1237..72797cdc5557 100644 --- a/packages/feedback/src/modal/integration.tsx +++ b/packages/feedback/src/modal/integration.tsx @@ -1,5 +1,5 @@ import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core'; -import type { FeedbackFormData, FeedbackModalIntegration, IntegrationFn, User } from '@sentry/types'; +import type { FeedbackFormData, FeedbackModalIntegration, IntegrationFn, User } from '@sentry/core'; import { h, render } from 'preact'; import * as hooks from 'preact/hooks'; import { DOCUMENT } from '../constants'; diff --git a/packages/feedback/src/screenshot/components/ScreenshotEditor.tsx b/packages/feedback/src/screenshot/components/ScreenshotEditor.tsx index 11e49c9692ae..57996c7dee7f 100644 --- a/packages/feedback/src/screenshot/components/ScreenshotEditor.tsx +++ b/packages/feedback/src/screenshot/components/ScreenshotEditor.tsx @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ -import type { FeedbackInternalOptions, FeedbackModalIntegration } from '@sentry/types'; +import type { FeedbackInternalOptions, FeedbackModalIntegration } from '@sentry/core'; import type { ComponentType, VNode, h as hType } from 'preact'; // biome-ignore lint/nursery/noUnusedImports: reason import { h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-vars diff --git a/packages/feedback/src/screenshot/integration.ts b/packages/feedback/src/screenshot/integration.ts index d4060c0071e2..8281040f7655 100644 --- a/packages/feedback/src/screenshot/integration.ts +++ b/packages/feedback/src/screenshot/integration.ts @@ -1,5 +1,5 @@ -import type { FeedbackScreenshotIntegration, IntegrationFn } from '@sentry/types'; -import type { Attachment } from '@sentry/types'; +import type { FeedbackScreenshotIntegration, IntegrationFn } from '@sentry/core'; +import type { Attachment } from '@sentry/core'; import type { h as hType } from 'preact'; import type * as Hooks from 'preact/hooks'; import { DOCUMENT } from '../constants'; diff --git a/packages/feedback/src/util/mergeOptions.ts b/packages/feedback/src/util/mergeOptions.ts index 0a30a893c777..c3a0c0508fcd 100644 --- a/packages/feedback/src/util/mergeOptions.ts +++ b/packages/feedback/src/util/mergeOptions.ts @@ -1,4 +1,4 @@ -import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/types'; +import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/core'; import type { OptionalFeedbackConfiguration } from '../core/types'; /** diff --git a/packages/feedback/src/util/validate.ts b/packages/feedback/src/util/validate.ts index 5525e191dd9d..83c54a1f19c3 100644 --- a/packages/feedback/src/util/validate.ts +++ b/packages/feedback/src/util/validate.ts @@ -1,4 +1,4 @@ -import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/types'; +import type { FeedbackFormData, FeedbackInternalOptions } from '@sentry/core'; export type Props = Pick< FeedbackInternalOptions, diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index b19ec235a12a..5a98e37acc9c 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/gatsby", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Gatsby.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby", @@ -45,9 +45,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/react": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/react": "8.42.0", "@sentry/webpack-plugin": "2.22.6" }, "peerDependencies": { diff --git a/packages/gatsby/src/sdk.ts b/packages/gatsby/src/sdk.ts index 93e9ee7617e4..ff2bea5b68fe 100644 --- a/packages/gatsby/src/sdk.ts +++ b/packages/gatsby/src/sdk.ts @@ -1,7 +1,7 @@ import { applySdkMetadata } from '@sentry/core'; import { init as reactInit } from '@sentry/react'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import type { GatsbyOptions } from './utils/types'; /** diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json index fcbda8702504..3e73add9552f 100644 --- a/packages/google-cloud-serverless/package.json +++ b/packages/google-cloud-serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/google-cloud-serverless", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Google Cloud Functions", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/google-cloud", @@ -48,9 +48,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", "@types/express": "^4.17.14" }, "devDependencies": { diff --git a/packages/google-cloud-serverless/src/gcpfunction/http.ts b/packages/google-cloud-serverless/src/gcpfunction/http.ts index 46b61c0ee8f1..3679ef61e173 100644 --- a/packages/google-cloud-serverless/src/gcpfunction/http.ts +++ b/packages/google-cloud-serverless/src/gcpfunction/http.ts @@ -27,8 +27,7 @@ export function wrapHttpFunction(fn: HttpFunction, wrapOptions: Partial=14.18" diff --git a/packages/integration-shims/src/Feedback.ts b/packages/integration-shims/src/Feedback.ts index caec59969918..ca29e7cada8b 100644 --- a/packages/integration-shims/src/Feedback.ts +++ b/packages/integration-shims/src/Feedback.ts @@ -1,5 +1,5 @@ import { consoleSandbox } from '@sentry/core'; -import type { Integration } from '@sentry/types'; +import type { Integration } from '@sentry/core'; import { FAKE_FUNCTION } from './common'; const FEEDBACK_INTEGRATION_METHODS = ['attachTo', 'createForm', 'createWidget', 'remove'] as const; diff --git a/packages/integration-shims/src/Replay.ts b/packages/integration-shims/src/Replay.ts index 30c06a9ab461..d71a41535937 100644 --- a/packages/integration-shims/src/Replay.ts +++ b/packages/integration-shims/src/Replay.ts @@ -1,5 +1,5 @@ import { consoleSandbox } from '@sentry/core'; -import type { Integration } from '@sentry/types'; +import type { Integration } from '@sentry/core'; import { FAKE_FUNCTION } from './common'; const REPLAY_INTEGRATION_METHODS = ['start', 'stop', 'flush'] as const; diff --git a/packages/integration-shims/src/metrics.ts b/packages/integration-shims/src/metrics.ts index a30a4a3c678e..a8862ee39c03 100644 --- a/packages/integration-shims/src/metrics.ts +++ b/packages/integration-shims/src/metrics.ts @@ -1,5 +1,5 @@ import { consoleSandbox } from '@sentry/core'; -import type { Metrics } from '@sentry/types'; +import type { Metrics } from '@sentry/core'; function warn(): void { consoleSandbox(() => { diff --git a/packages/nestjs/README.md b/packages/nestjs/README.md index 749e3d4efd6c..1a3ae775b7fd 100644 --- a/packages/nestjs/README.md +++ b/packages/nestjs/README.md @@ -134,7 +134,7 @@ after each cron job run. ```typescript import { Cron } from '@nestjs/schedule'; import { SentryCron, MonitorConfig } from '@sentry/nestjs'; -import type { MonitorConfig } from '@sentry/types'; +import type { MonitorConfig } from '@sentry/core'; const monitorConfig: MonitorConfig = { schedule: { diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index a28796f93c0f..6bdbb3d6aa5c 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nestjs", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for NestJS", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nestjs", @@ -44,9 +44,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0" }, "devDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", diff --git a/packages/nestjs/src/decorators.ts b/packages/nestjs/src/decorators.ts index 0a23ab488a2f..782e113e1877 100644 --- a/packages/nestjs/src/decorators.ts +++ b/packages/nestjs/src/decorators.ts @@ -1,7 +1,7 @@ import { captureException } from '@sentry/core'; +import type { MonitorConfig } from '@sentry/core'; import * as Sentry from '@sentry/node'; import { startSpan } from '@sentry/node'; -import type { MonitorConfig } from '@sentry/types'; import { isExpectedError } from './helpers'; /** diff --git a/packages/nestjs/src/setup.ts b/packages/nestjs/src/setup.ts index 08646402b187..55e168c53963 100644 --- a/packages/nestjs/src/setup.ts +++ b/packages/nestjs/src/setup.ts @@ -3,12 +3,13 @@ import type { CallHandler, DynamicModule, ExecutionContext, + HttpServer, NestInterceptor, OnModuleInit, } from '@nestjs/common'; import { Catch, Global, HttpException, Injectable, Logger, Module } from '@nestjs/common'; -import type { HttpServer } from '@nestjs/common'; import { APP_INTERCEPTOR, BaseExceptionFilter } from '@nestjs/core'; +import type { Span } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -16,10 +17,9 @@ import { getClient, getDefaultIsolationScope, getIsolationScope, + logger, spanToJSON, } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { Span } from '@sentry/types'; import type { Observable } from 'rxjs'; import { isExpectedError } from './helpers'; diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index fa9adb74efd5..44c3950bad62 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nextjs", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Next.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs", @@ -80,13 +80,12 @@ "@opentelemetry/instrumentation-http": "0.53.0", "@opentelemetry/semantic-conventions": "^1.27.0", "@rollup/plugin-commonjs": "28.0.1", - "@sentry-internal/browser-utils": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/opentelemetry": "8.40.0", - "@sentry/react": "8.40.0", - "@sentry/types": "8.40.0", - "@sentry/vercel-edge": "8.40.0", + "@sentry-internal/browser-utils": "8.42.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", + "@sentry/opentelemetry": "8.42.0", + "@sentry/react": "8.42.0", + "@sentry/vercel-edge": "8.42.0", "@sentry/webpack-plugin": "2.22.6", "chalk": "3.0.0", "resolve": "1.22.8", diff --git a/packages/nextjs/src/client/browserTracingIntegration.ts b/packages/nextjs/src/client/browserTracingIntegration.ts index c50dbbf1686e..53cb3e4f6a3f 100644 --- a/packages/nextjs/src/client/browserTracingIntegration.ts +++ b/packages/nextjs/src/client/browserTracingIntegration.ts @@ -1,5 +1,5 @@ +import type { Integration } from '@sentry/core'; import { browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/react'; -import type { Integration } from '@sentry/types'; import { nextRouterInstrumentNavigation, nextRouterInstrumentPageLoad } from './routing/nextRoutingInstrumentation'; /** diff --git a/packages/nextjs/src/client/index.ts b/packages/nextjs/src/client/index.ts index 5d8c6c46b911..163e29f0b9a7 100644 --- a/packages/nextjs/src/client/index.ts +++ b/packages/nextjs/src/client/index.ts @@ -1,9 +1,7 @@ -import { addEventProcessor, applySdkMetadata } from '@sentry/core'; -import { GLOBAL_OBJ } from '@sentry/core'; +import type { Client, EventProcessor, Integration } from '@sentry/core'; +import { GLOBAL_OBJ, addEventProcessor, applySdkMetadata } from '@sentry/core'; import type { BrowserOptions } from '@sentry/react'; import { getDefaultIntegrations as getReactDefaultIntegrations, init as reactInit } from '@sentry/react'; -import type { Client, EventProcessor, Integration } from '@sentry/types'; - import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor'; import { getVercelEnv } from '../common/getVercelEnv'; import { isRedirectNavigationError } from '../common/nextNavigationErrorUtils'; @@ -13,8 +11,9 @@ import { INCOMPLETE_APP_ROUTER_INSTRUMENTATION_TRANSACTION_NAME } from './routin import { applyTunnelRouteOption } from './tunnelRoute'; export * from '@sentry/react'; - +export * from '../common'; export { captureUnderscoreErrorException } from '../common/pages-router-instrumentation/_error'; +export { browserTracingIntegration } from './browserTracingIntegration'; const globalWithInjectedValues = GLOBAL_OBJ as typeof GLOBAL_OBJ & { _sentryRewriteFramesAssetPrefixPath: string; @@ -85,7 +84,3 @@ function getDefaultIntegrations(options: BrowserOptions): Integration[] { export function withSentryConfig(exportedUserNextConfig: T): T { return exportedUserNextConfig; } - -export { browserTracingIntegration } from './browserTracingIntegration'; - -export * from '../common'; diff --git a/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts b/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts index 11faf8d2a68b..9bb6e6288a84 100644 --- a/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts +++ b/packages/nextjs/src/client/routing/appRouterRoutingInstrumentation.ts @@ -4,8 +4,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, } from '@sentry/core'; import { GLOBAL_OBJ, browserPerformanceTimeOrigin } from '@sentry/core'; +import type { Client, Span } from '@sentry/core'; import { WINDOW, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan } from '@sentry/react'; -import type { Client, Span } from '@sentry/types'; export const INCOMPLETE_APP_ROUTER_INSTRUMENTATION_TRANSACTION_NAME = 'incomplete-app-router-transaction'; diff --git a/packages/nextjs/src/client/routing/nextRoutingInstrumentation.ts b/packages/nextjs/src/client/routing/nextRoutingInstrumentation.ts index a25c765e0143..d37fd2de2276 100644 --- a/packages/nextjs/src/client/routing/nextRoutingInstrumentation.ts +++ b/packages/nextjs/src/client/routing/nextRoutingInstrumentation.ts @@ -1,5 +1,5 @@ +import type { Client } from '@sentry/core'; import { WINDOW } from '@sentry/react'; -import type { Client } from '@sentry/types'; import { appRouterInstrumentNavigation, appRouterInstrumentPageLoad } from './appRouterRoutingInstrumentation'; import { pagesRouterInstrumentNavigation, pagesRouterInstrumentPageLoad } from './pagesRouterRoutingInstrumentation'; diff --git a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts index 6a2df057017c..cb583bb419e1 100644 --- a/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts +++ b/packages/nextjs/src/client/routing/pagesRouterRoutingInstrumentation.ts @@ -1,21 +1,24 @@ import type { ParsedUrlQuery } from 'querystring'; +import type { Client, TransactionSource } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + browserPerformanceTimeOrigin, + logger, + parseBaggageHeader, + stripUrlQueryAndFragment, } from '@sentry/core'; -import { browserPerformanceTimeOrigin, logger, parseBaggageHeader, stripUrlQueryAndFragment } from '@sentry/core'; import { WINDOW, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan } from '@sentry/react'; -import type { Client, TransactionSource } from '@sentry/types'; - import type { NEXT_DATA } from 'next/dist/shared/lib/utils'; import RouterImport from 'next/router'; // next/router v10 is CJS // // For ESM/CJS interoperability 'reasons', depending on how this file is loaded, Router might be on the default export -// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any -const Router: typeof RouterImport = RouterImport.events ? RouterImport : (RouterImport as any).default; +const Router: typeof RouterImport = RouterImport.events + ? RouterImport + : (RouterImport as unknown as { default: typeof RouterImport }).default; import { DEBUG_BUILD } from '../../common/debug-build'; diff --git a/packages/nextjs/src/common/captureRequestError.ts b/packages/nextjs/src/common/captureRequestError.ts index 2dc4d8ff6325..6de33ad11a8e 100644 --- a/packages/nextjs/src/common/captureRequestError.ts +++ b/packages/nextjs/src/common/captureRequestError.ts @@ -1,6 +1,5 @@ -import { captureException, withScope } from '@sentry/core'; -import { headersToDict } from '@sentry/core'; -import type { RequestEventData } from '@sentry/types'; +import type { RequestEventData } from '@sentry/core'; +import { captureException, headersToDict, withScope } from '@sentry/core'; type RequestInfo = { path: string; diff --git a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts index 1a117517a964..61365b180d77 100644 --- a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts +++ b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts @@ -1,6 +1,5 @@ -import { suppressTracing } from '@sentry/core'; -import { GLOBAL_OBJ } from '@sentry/core'; -import type { Event, EventHint } from '@sentry/types'; +import type { Event, EventHint } from '@sentry/core'; +import { GLOBAL_OBJ, suppressTracing } from '@sentry/core'; import type { StackFrame } from 'stacktrace-parser'; import * as stackTraceParser from 'stacktrace-parser'; diff --git a/packages/nextjs/src/common/pages-router-instrumentation/_error.ts b/packages/nextjs/src/common/pages-router-instrumentation/_error.ts index a96b3131a56f..68a3ef782688 100644 --- a/packages/nextjs/src/common/pages-router-instrumentation/_error.ts +++ b/packages/nextjs/src/common/pages-router-instrumentation/_error.ts @@ -1,5 +1,4 @@ -import { captureException, httpRequestToRequestData, withScope } from '@sentry/core'; -import { vercelWaitUntil } from '@sentry/core'; +import { captureException, httpRequestToRequestData, vercelWaitUntil, withScope } from '@sentry/core'; import type { NextPageContext } from 'next'; import { flushSafelyWithTimeout } from '../utils/responseEnd'; diff --git a/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts index 347ac9ffd7e9..3cc5b4d340e5 100644 --- a/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts +++ b/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts @@ -4,13 +4,14 @@ import { captureException, continueTrace, httpRequestToRequestData, + isString, + logger, + objectify, setHttpStatus, startSpanManual, + vercelWaitUntil, withIsolationScope, } from '@sentry/core'; -import { isString, logger, objectify } from '@sentry/core'; - -import { vercelWaitUntil } from '@sentry/core'; import type { NextApiRequest } from 'next'; import type { AugmentedNextApiResponse, NextApiHandler } from '../types'; import { flushSafelyWithTimeout } from '../utils/responseEnd'; diff --git a/packages/nextjs/src/common/pages-router-instrumentation/wrapPageComponentWithSentry.ts b/packages/nextjs/src/common/pages-router-instrumentation/wrapPageComponentWithSentry.ts index 3d481235be25..b08bdad5e9ab 100644 --- a/packages/nextjs/src/common/pages-router-instrumentation/wrapPageComponentWithSentry.ts +++ b/packages/nextjs/src/common/pages-router-instrumentation/wrapPageComponentWithSentry.ts @@ -1,5 +1,4 @@ -import { captureException, getCurrentScope, withIsolationScope } from '@sentry/core'; -import { extractTraceparentData } from '@sentry/core'; +import { captureException, extractTraceparentData, getCurrentScope, withIsolationScope } from '@sentry/core'; interface FunctionComponent { (...args: unknown[]): unknown; diff --git a/packages/nextjs/src/common/types.ts b/packages/nextjs/src/common/types.ts index 517c3677d556..ebf35c68c1ba 100644 --- a/packages/nextjs/src/common/types.ts +++ b/packages/nextjs/src/common/types.ts @@ -1,5 +1,4 @@ -import type { SentrySpan } from '@sentry/core'; -import type { WebFetchHeaders, WrappedFunction } from '@sentry/types'; +import type { SentrySpan, WebFetchHeaders, WrappedFunction } from '@sentry/core'; import type { NextApiRequest, NextApiResponse } from 'next'; import type { RequestAsyncStorage } from '../config/templates/requestAsyncStorageShim'; diff --git a/packages/nextjs/src/common/utils/responseEnd.ts b/packages/nextjs/src/common/utils/responseEnd.ts index 1ccfd1f913d5..b35fd9022427 100644 --- a/packages/nextjs/src/common/utils/responseEnd.ts +++ b/packages/nextjs/src/common/utils/responseEnd.ts @@ -1,8 +1,6 @@ import type { ServerResponse } from 'http'; -import { flush, setHttpStatus } from '@sentry/core'; -import { fill, logger } from '@sentry/core'; -import type { Span } from '@sentry/types'; - +import type { Span } from '@sentry/core'; +import { fill, flush, logger, setHttpStatus } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import type { ResponseEndMethod, WrappedResponseEndMethod } from '../types'; diff --git a/packages/nextjs/src/common/utils/tracingUtils.ts b/packages/nextjs/src/common/utils/tracingUtils.ts index e849e502913f..4f5e9c9fa5d3 100644 --- a/packages/nextjs/src/common/utils/tracingUtils.ts +++ b/packages/nextjs/src/common/utils/tracingUtils.ts @@ -1,6 +1,5 @@ -import { Scope, getActiveSpan, getRootSpan, spanToJSON, startNewTrace } from '@sentry/core'; -import { GLOBAL_OBJ, logger } from '@sentry/core'; -import type { PropagationContext } from '@sentry/types'; +import type { PropagationContext } from '@sentry/core'; +import { GLOBAL_OBJ, Scope, getActiveSpan, getRootSpan, logger, spanToJSON, startNewTrace } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import { TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION } from '../span-attributes-with-logic-attached'; @@ -68,8 +67,8 @@ let nextjsEscapedAsyncStorage: AsyncLocalStorage; * first time. */ export function escapeNextjsTracing(cb: () => T): T { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - const MaybeGlobalAsyncLocalStorage = (GLOBAL_OBJ as any).AsyncLocalStorage; + const MaybeGlobalAsyncLocalStorage = (GLOBAL_OBJ as { AsyncLocalStorage?: new () => AsyncLocalStorage }) + .AsyncLocalStorage; if (!MaybeGlobalAsyncLocalStorage) { DEBUG_BUILD && diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index 5a9320fd143a..8d5ab14c77c3 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -1,3 +1,4 @@ +import type { RequestEventData } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SPAN_STATUS_ERROR, @@ -6,12 +7,11 @@ import { getClient, getIsolationScope, handleCallbackErrors, + logger, startSpan, + vercelWaitUntil, withIsolationScope, } from '@sentry/core'; -import { logger, vercelWaitUntil } from '@sentry/core'; -import type { RequestEventData } from '@sentry/types'; - import { DEBUG_BUILD } from './debug-build'; import { isNotFoundNavigationError, isRedirectNavigationError } from './nextNavigationErrorUtils'; import { flushSafelyWithTimeout } from './utils/responseEnd'; diff --git a/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts b/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts index baff31c3ee3c..4b764aeeed8e 100644 --- a/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts +++ b/packages/nextjs/src/common/wrapGenerationFunctionWithSentry.ts @@ -1,23 +1,25 @@ +import type { RequestEventData, WebFetchHeaders } from '@sentry/core'; import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SPAN_STATUS_ERROR, SPAN_STATUS_OK, Scope, captureException, + generateSpanId, + generateTraceId, getActiveSpan, getCapturedScopesOnSpan, getClient, getRootSpan, handleCallbackErrors, + propagationContextFromHeaders, setCapturedScopesOnSpan, startSpanManual, + winterCGHeadersToDict, withIsolationScope, withScope, } from '@sentry/core'; -import { propagationContextFromHeaders, uuid4, winterCGHeadersToDict } from '@sentry/core'; -import type { RequestEventData, WebFetchHeaders } from '@sentry/types'; - -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import type { GenerationFunctionContext } from '../common/types'; import { isNotFoundNavigationError, isRedirectNavigationError } from './nextNavigationErrorUtils'; import { TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL } from './span-attributes-with-logic-attached'; @@ -87,8 +89,8 @@ export function wrapGenerationFunctionWithSentry a headersDict?.['sentry-trace'] ? propagationContextFromHeaders(headersDict['sentry-trace'], headersDict['baggage']) : { - traceId: requestTraceId || uuid4(), - spanId: uuid4().substring(16), + traceId: requestTraceId || generateTraceId(), + spanId: generateSpanId(), }, ); scope.setPropagationContext(propagationContext); diff --git a/packages/nextjs/src/common/wrapMiddlewareWithSentry.ts b/packages/nextjs/src/common/wrapMiddlewareWithSentry.ts index 058d856dfd81..660cf0bb3940 100644 --- a/packages/nextjs/src/common/wrapMiddlewareWithSentry.ts +++ b/packages/nextjs/src/common/wrapMiddlewareWithSentry.ts @@ -12,7 +12,7 @@ import { winterCGRequestToRequestData, withIsolationScope, } from '@sentry/core'; -import type { TransactionSource } from '@sentry/types'; +import type { TransactionSource } from '@sentry/core'; import type { EdgeRouteHandler } from '../edge/types'; import { flushSafelyWithTimeout } from './utils/responseEnd'; diff --git a/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts b/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts index 82bd208f9946..8cf3e59205b2 100644 --- a/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts +++ b/packages/nextjs/src/common/wrapRouteHandlerWithSentry.ts @@ -1,3 +1,4 @@ +import type { RequestEventData } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, @@ -8,16 +9,15 @@ import { getIsolationScope, getRootSpan, handleCallbackErrors, + propagationContextFromHeaders, setCapturedScopesOnSpan, setHttpStatus, + winterCGHeadersToDict, withIsolationScope, withScope, } from '@sentry/core'; -import type { RequestEventData } from '@sentry/types'; -import type { RouteHandlerContext } from './types'; - -import { propagationContextFromHeaders, winterCGHeadersToDict } from '@sentry/core'; import { isNotFoundNavigationError, isRedirectNavigationError } from './nextNavigationErrorUtils'; +import type { RouteHandlerContext } from './types'; import { commonObjectToIsolationScope } from './utils/tracingUtils'; /** diff --git a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts index 15536665c988..0d4ffe5f32d1 100644 --- a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts +++ b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts @@ -1,22 +1,25 @@ +import type { RequestEventData } from '@sentry/core'; import { + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SPAN_STATUS_ERROR, SPAN_STATUS_OK, Scope, captureException, + generateSpanId, + generateTraceId, getActiveSpan, getCapturedScopesOnSpan, getRootSpan, handleCallbackErrors, + propagationContextFromHeaders, setCapturedScopesOnSpan, startSpanManual, + vercelWaitUntil, + winterCGHeadersToDict, withIsolationScope, withScope, } from '@sentry/core'; -import { propagationContextFromHeaders, uuid4, vercelWaitUntil, winterCGHeadersToDict } from '@sentry/core'; -import type { RequestEventData } from '@sentry/types'; - -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { isNotFoundNavigationError, isRedirectNavigationError } from '../common/nextNavigationErrorUtils'; import type { ServerComponentContext } from '../common/types'; import { TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL } from './span-attributes-with-logic-attached'; @@ -65,8 +68,8 @@ export function wrapServerComponentWithSentry any> headersDict?.['sentry-trace'] ? propagationContextFromHeaders(headersDict['sentry-trace'], headersDict['baggage']) : { - traceId: requestTraceId || uuid4(), - spanId: uuid4().substring(16), + traceId: requestTraceId || generateTraceId(), + spanId: generateSpanId(), }, ); diff --git a/packages/nextjs/src/config/templates/requestAsyncStorageShim.ts b/packages/nextjs/src/config/templates/requestAsyncStorageShim.ts index 483d00341312..2499891cc40e 100644 --- a/packages/nextjs/src/config/templates/requestAsyncStorageShim.ts +++ b/packages/nextjs/src/config/templates/requestAsyncStorageShim.ts @@ -1,4 +1,4 @@ -import type { WebFetchHeaders } from '@sentry/types'; +import type { WebFetchHeaders } from '@sentry/core'; export interface RequestAsyncStorage { getStore: () => diff --git a/packages/nextjs/src/config/templates/routeHandlerWrapperTemplate.ts b/packages/nextjs/src/config/templates/routeHandlerWrapperTemplate.ts index d0b9fba5ce3b..9e68fd453112 100644 --- a/packages/nextjs/src/config/templates/routeHandlerWrapperTemplate.ts +++ b/packages/nextjs/src/config/templates/routeHandlerWrapperTemplate.ts @@ -1,5 +1,5 @@ +import type { WebFetchHeaders } from '@sentry/core'; import * as Sentry from '@sentry/nextjs'; -import type { WebFetchHeaders } from '@sentry/types'; // @ts-expect-error Because we cannot be sure if the RequestAsyncStorage module exists (it is not part of the Next.js public // API) we use a shim if it doesn't exist. The logic for this is in the wrapping loader. import * as origModule from '__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__'; diff --git a/packages/nextjs/src/config/templates/serverComponentWrapperTemplate.ts b/packages/nextjs/src/config/templates/serverComponentWrapperTemplate.ts index d569715e74fc..f4223d752d47 100644 --- a/packages/nextjs/src/config/templates/serverComponentWrapperTemplate.ts +++ b/packages/nextjs/src/config/templates/serverComponentWrapperTemplate.ts @@ -1,5 +1,5 @@ +import type { WebFetchHeaders } from '@sentry/core'; import * as Sentry from '@sentry/nextjs'; -import type { WebFetchHeaders } from '@sentry/types'; // @ts-expect-error Because we cannot be sure if the RequestAsyncStorage module exists (it is not part of the Next.js public // API) we use a shim if it doesn't exist. The logic for this is in the wrapping loader. import * as origModule from '__SENTRY_NEXTJS_REQUEST_ASYNC_STORAGE_SHIM__'; @@ -41,14 +41,13 @@ if (typeof serverComponent === 'function') { // Current assumption is that Next.js applies some loader magic to userfiles, but not files in node_modules. This file // is technically a userfile so it gets the loader magic applied. wrappedServerComponent = new Proxy(serverComponent, { - apply: (originalFunction, thisArg, args) => { + apply: (originalFunction: (...args: unknown[]) => unknown, thisArg, args) => { let sentryTraceHeader: string | undefined | null = undefined; let baggageHeader: string | undefined | null = undefined; let headers: WebFetchHeaders | undefined = undefined; // We try-catch here just in `requestAsyncStorage` is undefined since it may not be defined try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const requestAsyncStore = requestAsyncStorage?.getStore() as ReturnType; sentryTraceHeader = requestAsyncStore?.headers.get('sentry-trace') ?? undefined; baggageHeader = requestAsyncStore?.headers.get('baggage') ?? undefined; @@ -57,8 +56,7 @@ if (typeof serverComponent === 'function') { /** empty */ } - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access - return Sentry.wrapServerComponentWithSentry(originalFunction as any, { + return Sentry.wrapServerComponentWithSentry(originalFunction, { componentRoute: '__ROUTE__', componentType: '__COMPONENT_TYPE__', sentryTraceHeader, diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts index 75b1c29281fa..75ce7258fae5 100644 --- a/packages/nextjs/src/config/types.ts +++ b/packages/nextjs/src/config/types.ts @@ -470,7 +470,7 @@ export type IgnoreWarningsOption = ( // The two possible formats for providing custom webpack config in `next.config.js` export type WebpackConfigFunction = (config: WebpackConfigObject, options: BuildContext) => WebpackConfigObject; export type WebpackConfigObject = { - devtool?: string; + devtool?: string | boolean; plugins?: Array; entry: WebpackEntryProperty; output: { filename: string; path: string }; diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 445ef32ab1e3..20f1a00ce3c0 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -336,13 +336,33 @@ export function constructWebpackConfigFunction( if (sentryWebpackPlugin) { if (!userSentryOptions.sourcemaps?.disable) { + // TODO(v9): Remove this warning + if (newConfig.devtool === false) { + const runtimePrefix = !isServer ? 'Client' : runtime === 'edge' ? 'Edge' : 'Node.js'; + // eslint-disable-next-line no-console + console.warn( + `[@sentry/nextjs - ${runtimePrefix}] You disabled sourcemaps with the Webpack \`devtool\` option. Currently, the Sentry SDK will override this option to generate sourcemaps. In future versions, the Sentry SDK will not override the \`devtool\` option if you explicitly disable it. If you want to generate and upload sourcemaps please set the \`devtool\` option to 'hidden-source-map' or undefined.`, + ); + } + + // TODO(v9): Remove this warning and print warning in case source map deletion is auto configured + if (!isServer && !userSentryOptions.sourcemaps?.deleteSourcemapsAfterUpload) { + // eslint-disable-next-line no-console + console.warn( + "[@sentry/nextjs] The Sentry SDK has enabled source map generation for your Next.js app. If you don't want to serve Source Maps to your users, either set the `deleteSourceMapsAfterUpload` option to true, or manually delete the source maps after the build. In future Sentry SDK versions `deleteSourceMapsAfterUpload` will default to `true`.", + ); + } + // `hidden-source-map` produces the same sourcemaps as `source-map`, but doesn't include the `sourceMappingURL` // comment at the bottom. For folks who aren't publicly hosting their sourcemaps, this is helpful because then // the browser won't look for them and throw errors into the console when it can't find them. Because this is a // front-end-only problem, and because `sentry-cli` handles sourcemaps more reliably with the comment than // without, the option to use `hidden-source-map` only applies to the client-side build. - newConfig.devtool = - isServer || userNextConfig.productionBrowserSourceMaps ? 'source-map' : 'hidden-source-map'; + if (isServer || userNextConfig.productionBrowserSourceMaps) { + newConfig.devtool = 'source-map'; + } else { + newConfig.devtool = 'hidden-source-map'; + } } newConfig.plugins = newConfig.plugins || []; diff --git a/packages/nextjs/src/edge/distDirRewriteFramesIntegration.ts b/packages/nextjs/src/edge/distDirRewriteFramesIntegration.ts index b9a72d8d95b3..9691cce74782 100644 --- a/packages/nextjs/src/edge/distDirRewriteFramesIntegration.ts +++ b/packages/nextjs/src/edge/distDirRewriteFramesIntegration.ts @@ -1,5 +1,4 @@ -import { defineIntegration, rewriteFramesIntegration } from '@sentry/core'; -import { escapeStringForRegex } from '@sentry/core'; +import { defineIntegration, escapeStringForRegex, rewriteFramesIntegration } from '@sentry/core'; export const distDirRewriteFramesIntegration = defineIntegration(({ distDirName }: { distDirName: string }) => { const distDirAbsPath = distDirName.replace(/(\/|\\)$/, ''); // We strip trailing slashes because "app:///_next" also doesn't have one diff --git a/packages/nextjs/src/edge/index.ts b/packages/nextjs/src/edge/index.ts index ba66c0ba9560..24ec193df0d1 100644 --- a/packages/nextjs/src/edge/index.ts +++ b/packages/nextjs/src/edge/index.ts @@ -1,4 +1,5 @@ import { + GLOBAL_OBJ, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, @@ -6,17 +7,19 @@ import { getRootSpan, registerSpanErrorInstrumentation, spanToJSON, + stripUrlQueryAndFragment, + vercelWaitUntil, } from '@sentry/core'; - -import { GLOBAL_OBJ, stripUrlQueryAndFragment, vercelWaitUntil } from '@sentry/core'; import type { VercelEdgeOptions } from '@sentry/vercel-edge'; import { getDefaultIntegrations, init as vercelEdgeInit } from '@sentry/vercel-edge'; - import { isBuild } from '../common/utils/isBuild'; import { flushSafelyWithTimeout } from '../common/utils/responseEnd'; import { distDirRewriteFramesIntegration } from './distDirRewriteFramesIntegration'; +export * from '@sentry/vercel-edge'; +export * from '../common'; export { captureUnderscoreErrorException } from '../common/pages-router-instrumentation/_error'; +export { wrapApiHandlerWithSentry } from './wrapApiHandlerWithSentry'; export type EdgeOptions = VercelEdgeOptions; @@ -95,9 +98,3 @@ export function init(options: VercelEdgeOptions = {}): void { export function withSentryConfig(exportedUserNextConfig: T): T { return exportedUserNextConfig; } - -export * from '@sentry/vercel-edge'; - -export * from '../common'; - -export { wrapApiHandlerWithSentry } from './wrapApiHandlerWithSentry'; diff --git a/packages/nextjs/src/edge/rewriteFramesIntegration.ts b/packages/nextjs/src/edge/rewriteFramesIntegration.ts index b191488c2b68..db3aa26b7469 100644 --- a/packages/nextjs/src/edge/rewriteFramesIntegration.ts +++ b/packages/nextjs/src/edge/rewriteFramesIntegration.ts @@ -1,6 +1,10 @@ -import { defineIntegration, rewriteFramesIntegration as originalRewriteFramesIntegration } from '@sentry/core'; -import { GLOBAL_OBJ, escapeStringForRegex } from '@sentry/core'; -import type { IntegrationFn, StackFrame } from '@sentry/types'; +import type { IntegrationFn, StackFrame } from '@sentry/core'; +import { + GLOBAL_OBJ, + defineIntegration, + escapeStringForRegex, + rewriteFramesIntegration as originalRewriteFramesIntegration, +} from '@sentry/core'; const globalWithInjectedValues = GLOBAL_OBJ as typeof GLOBAL_OBJ & { _sentryRewriteFramesDistDir?: string; diff --git a/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts index fa31511e4c28..90f03b547980 100644 --- a/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts +++ b/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts @@ -9,9 +9,10 @@ import { handleCallbackErrors, setCapturedScopesOnSpan, startSpan, + vercelWaitUntil, + winterCGRequestToRequestData, withIsolationScope, } from '@sentry/core'; -import { vercelWaitUntil, winterCGRequestToRequestData } from '@sentry/core'; import { flushSafelyWithTimeout } from '../common/utils/responseEnd'; import type { EdgeRouteHandler } from './types'; diff --git a/packages/nextjs/src/index.types.ts b/packages/nextjs/src/index.types.ts index 9dc9e84a147a..1b6a0e09ed85 100644 --- a/packages/nextjs/src/index.types.ts +++ b/packages/nextjs/src/index.types.ts @@ -7,7 +7,7 @@ export * from './client'; export * from './server'; export * from './edge'; -import type { Client, Integration, Options, StackParser } from '@sentry/types'; +import type { Client, Integration, Options, StackParser } from '@sentry/core'; import type * as clientSdk from './client'; import type { ServerComponentContext, VercelCronsConfig } from './common/types'; diff --git a/packages/nextjs/src/server/distDirRewriteFramesIntegration.ts b/packages/nextjs/src/server/distDirRewriteFramesIntegration.ts index dfa61ff44b98..6941fb60f19f 100644 --- a/packages/nextjs/src/server/distDirRewriteFramesIntegration.ts +++ b/packages/nextjs/src/server/distDirRewriteFramesIntegration.ts @@ -1,6 +1,5 @@ import * as path from 'path'; -import { defineIntegration, rewriteFramesIntegration } from '@sentry/core'; -import { escapeStringForRegex } from '@sentry/core'; +import { defineIntegration, escapeStringForRegex, rewriteFramesIntegration } from '@sentry/core'; export const distDirRewriteFramesIntegration = defineIntegration(({ distDirName }: { distDirName: string }) => { // nextjs always puts the build directory at the project root level, which is also where you run `next start` from, so diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index c79c35932e5b..f6ea8cde141f 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -1,3 +1,11 @@ +import { context } from '@opentelemetry/api'; +import { + ATTR_HTTP_REQUEST_METHOD, + ATTR_HTTP_ROUTE, + ATTR_URL_QUERY, + SEMATTRS_HTTP_METHOD, + SEMATTRS_HTTP_TARGET, +} from '@opentelemetry/semantic-conventions'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -13,19 +21,10 @@ import { spanToJSON, } from '@sentry/core'; import { GLOBAL_OBJ, extractTraceparentData, logger, stripUrlQueryAndFragment } from '@sentry/core'; +import type { EventProcessor } from '@sentry/core'; import type { NodeClient, NodeOptions } from '@sentry/node'; import { getDefaultIntegrations, httpIntegration, init as nodeInit } from '@sentry/node'; - -import { context } from '@opentelemetry/api'; -import { - ATTR_HTTP_REQUEST_METHOD, - ATTR_HTTP_ROUTE, - ATTR_URL_QUERY, - SEMATTRS_HTTP_METHOD, - SEMATTRS_HTTP_TARGET, -} from '@opentelemetry/semantic-conventions'; import { getScopesFromContext } from '@sentry/opentelemetry'; -import type { EventProcessor } from '@sentry/types'; import { DEBUG_BUILD } from '../common/debug-build'; import { devErrorSymbolicationEventProcessor } from '../common/devErrorSymbolicationEventProcessor'; import { getVercelEnv } from '../common/getVercelEnv'; diff --git a/packages/nextjs/src/server/rewriteFramesIntegration.ts b/packages/nextjs/src/server/rewriteFramesIntegration.ts index 0c8af92fb958..56d56587eabb 100644 --- a/packages/nextjs/src/server/rewriteFramesIntegration.ts +++ b/packages/nextjs/src/server/rewriteFramesIntegration.ts @@ -1,7 +1,10 @@ import * as path from 'path'; -import { defineIntegration, rewriteFramesIntegration as originalRewriteFramesIntegration } from '@sentry/core'; -import { escapeStringForRegex } from '@sentry/core'; -import type { IntegrationFn, StackFrame } from '@sentry/types'; +import type { IntegrationFn, StackFrame } from '@sentry/core'; +import { + defineIntegration, + escapeStringForRegex, + rewriteFramesIntegration as originalRewriteFramesIntegration, +} from '@sentry/core'; const globalWithInjectedValues = global as typeof global & { _sentryRewriteFramesDistDir?: string; diff --git a/packages/nextjs/test/clientSdk.test.ts b/packages/nextjs/test/clientSdk.test.ts index eafe07547ffb..3464c5de3c93 100644 --- a/packages/nextjs/test/clientSdk.test.ts +++ b/packages/nextjs/test/clientSdk.test.ts @@ -1,8 +1,8 @@ import { getGlobalScope, getIsolationScope } from '@sentry/core'; import { logger } from '@sentry/core'; +import type { Integration } from '@sentry/core'; import * as SentryReact from '@sentry/react'; import { WINDOW, getClient, getCurrentScope } from '@sentry/react'; -import type { Integration } from '@sentry/types'; import { JSDOM } from 'jsdom'; import { breadcrumbsIntegration, browserTracingIntegration, init } from '../src/client'; diff --git a/packages/nextjs/test/config/wrappers.test.ts b/packages/nextjs/test/config/wrappers.test.ts index e2928d59016e..de9d125b7830 100644 --- a/packages/nextjs/test/config/wrappers.test.ts +++ b/packages/nextjs/test/config/wrappers.test.ts @@ -1,7 +1,7 @@ import type { IncomingMessage, ServerResponse } from 'http'; import * as SentryCore from '@sentry/core'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import { wrapGetInitialPropsWithSentry, wrapGetServerSidePropsWithSentry } from '../../src/common'; const startSpanManualSpy = jest.spyOn(SentryCore, 'startSpanManual'); diff --git a/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts b/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts index 947b3c9f3f69..ac20f0ab21ab 100644 --- a/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts +++ b/packages/nextjs/test/performance/pagesRouterInstrumentation.test.ts @@ -1,5 +1,5 @@ +import type { Client } from '@sentry/core'; import { WINDOW } from '@sentry/react'; -import type { Client } from '@sentry/types'; import { JSDOM } from 'jsdom'; import type { NEXT_DATA } from 'next/dist/shared/lib/utils'; import Router from 'next/router'; diff --git a/packages/nextjs/test/serverSdk.test.ts b/packages/nextjs/test/serverSdk.test.ts index d37a1c46d015..0c3c9cfbb27a 100644 --- a/packages/nextjs/test/serverSdk.test.ts +++ b/packages/nextjs/test/serverSdk.test.ts @@ -1,7 +1,7 @@ import { GLOBAL_OBJ } from '@sentry/core'; +import type { Integration } from '@sentry/core'; import { getCurrentScope } from '@sentry/node'; import * as SentryNode from '@sentry/node'; -import type { Integration } from '@sentry/types'; import { init } from '../src/server'; diff --git a/packages/node/package.json b/packages/node/package.json index 781b0ea0f1be..697aa00a9751 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/node", - "version": "8.40.0", + "version": "8.42.0", "description": "Sentry Node SDK using OpenTelemetry for performance instrumentation", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node", @@ -97,9 +97,8 @@ "@opentelemetry/sdk-trace-base": "^1.26.0", "@opentelemetry/semantic-conventions": "^1.27.0", "@prisma/instrumentation": "5.19.1", - "@sentry/core": "8.40.0", - "@sentry/opentelemetry": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/opentelemetry": "8.42.0", "import-in-the-middle": "^1.11.2" }, "devDependencies": { diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index df6cce5383a3..4572cf65b9ce 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -61,6 +61,7 @@ export type { NodeOptions } from './types'; export { addRequestDataToEvent, DEFAULT_USER_INCLUDES, extractRequestData } from '@sentry/core'; export { + // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, // These are custom variants that need to be used instead of the core one // As they have slightly different implementations @@ -164,4 +165,4 @@ export type { Thread, User, Span, -} from '@sentry/types'; +} from '@sentry/core'; diff --git a/packages/node/src/integrations/anr/common.ts b/packages/node/src/integrations/anr/common.ts index e2e50fae4179..e2666e3ecd3e 100644 --- a/packages/node/src/integrations/anr/common.ts +++ b/packages/node/src/integrations/anr/common.ts @@ -1,4 +1,4 @@ -import type { Contexts, DsnComponents, Primitive, SdkMetadata } from '@sentry/types'; +import type { Contexts, DsnComponents, Primitive, SdkMetadata } from '@sentry/core'; export interface AnrIntegrationOptions { /** diff --git a/packages/node/src/integrations/anr/index.ts b/packages/node/src/integrations/anr/index.ts index 1fa2218d5879..9e979f64e5c3 100644 --- a/packages/node/src/integrations/anr/index.ts +++ b/packages/node/src/integrations/anr/index.ts @@ -1,8 +1,15 @@ -import * as diagnosticsChannel from 'node:diagnostics_channel'; import { Worker } from 'node:worker_threads'; -import { defineIntegration, getCurrentScope, getGlobalScope, getIsolationScope, mergeScopeData } from '@sentry/core'; -import { GLOBAL_OBJ, getFilenameToDebugIdMap, logger } from '@sentry/core'; -import type { Contexts, Event, EventHint, Integration, IntegrationFn, ScopeData } from '@sentry/types'; +import type { Contexts, Event, EventHint, Integration, IntegrationFn, ScopeData } from '@sentry/core'; +import { + GLOBAL_OBJ, + defineIntegration, + getCurrentScope, + getFilenameToDebugIdMap, + getGlobalScope, + getIsolationScope, + logger, + mergeScopeData, +} from '@sentry/core'; import { NODE_VERSION } from '../../nodeVersion'; import type { NodeClient } from '../../sdk/client'; import type { AnrIntegrationOptions, WorkerStartData } from './common'; @@ -101,13 +108,6 @@ type AnrReturn = (options?: Partial) => Integration & Anr export const anrIntegration = defineIntegration(_anrIntegration) as AnrReturn; -function onModuleLoad(callback: () => void): void { - // eslint-disable-next-line deprecation/deprecation - diagnosticsChannel.channel('module.require.end').subscribe(() => callback()); - // eslint-disable-next-line deprecation/deprecation - diagnosticsChannel.channel('module.import.asyncEnd').subscribe(() => callback()); -} - /** * Starts the ANR worker thread * @@ -161,12 +161,6 @@ async function _startWorker( } } - let debugImages: Record = getFilenameToDebugIdMap(initOptions.stackParser); - - onModuleLoad(() => { - debugImages = getFilenameToDebugIdMap(initOptions.stackParser); - }); - const worker = new Worker(new URL(`data:application/javascript;base64,${base64WorkerScript}`), { workerData: options, // We don't want any Node args to be passed to the worker @@ -185,7 +179,7 @@ async function _startWorker( // serialized without making it a SerializedSession const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined; // message the worker to tell it the main event loop is still running - worker.postMessage({ session, debugImages }); + worker.postMessage({ session, debugImages: getFilenameToDebugIdMap(initOptions.stackParser) }); } catch (_) { // } diff --git a/packages/node/src/integrations/anr/worker.ts b/packages/node/src/integrations/anr/worker.ts index bada36db274e..354cea514618 100644 --- a/packages/node/src/integrations/anr/worker.ts +++ b/packages/node/src/integrations/anr/worker.ts @@ -1,21 +1,19 @@ import { Session as InspectorSession } from 'node:inspector'; import { parentPort, workerData } from 'node:worker_threads'; +import type { DebugImage, Event, ScopeData, Session, StackFrame } from '@sentry/core'; import { applyScopeDataToEvent, + callFrameToStackFrame, createEventEnvelope, createSessionEnvelope, getEnvelopeEndpointWithUrlEncodedAuth, makeSession, - updateSession, -} from '@sentry/core'; -import { - callFrameToStackFrame, normalizeUrlToBase, stripSentryFramesAndReverse, + updateSession, uuid4, watchdogTimer, } from '@sentry/core'; -import type { DebugImage, Event, ScopeData, Session, StackFrame } from '@sentry/types'; import { makeNodeTransport } from '../../transports'; import { createGetModuleFromFilename } from '../../utils/module'; @@ -121,6 +119,8 @@ function applyScopeToEvent(event: Event, scope: ScopeData): void { applyScopeDataToEvent(event, scope); if (!event.contexts?.trace) { + // TODO(v9): Use generateSpanId() instead of spanId + // eslint-disable-next-line deprecation/deprecation const { traceId, spanId, parentSpanId } = scope.propagationContext; event.contexts = { trace: { diff --git a/packages/node/src/integrations/console.ts b/packages/node/src/integrations/console.ts index 9413ed6da4bf..5e5e6ac414d9 100644 --- a/packages/node/src/integrations/console.ts +++ b/packages/node/src/integrations/console.ts @@ -1,6 +1,12 @@ import * as util from 'node:util'; -import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core'; -import { addConsoleInstrumentationHandler, severityLevelFromString, truncate } from '@sentry/core'; +import { + addBreadcrumb, + addConsoleInstrumentationHandler, + defineIntegration, + getClient, + severityLevelFromString, + truncate, +} from '@sentry/core'; const INTEGRATION_NAME = 'Console'; diff --git a/packages/node/src/integrations/context.ts b/packages/node/src/integrations/context.ts index e8ab2c7f84f1..5176a3a3348a 100644 --- a/packages/node/src/integrations/context.ts +++ b/packages/node/src/integrations/context.ts @@ -1,10 +1,10 @@ /* eslint-disable max-lines */ + import { execFile } from 'node:child_process'; import { readFile, readdir } from 'node:fs'; import * as os from 'node:os'; import { join } from 'node:path'; import { promisify } from 'node:util'; -import { defineIntegration } from '@sentry/core'; import type { AppContext, CloudResourceContext, @@ -14,7 +14,8 @@ import type { Event, IntegrationFn, OsContext, -} from '@sentry/types'; +} from '@sentry/core'; +import { defineIntegration } from '@sentry/core'; export const readFileAsync = promisify(readFile); export const readDirAsync = promisify(readdir); @@ -171,8 +172,7 @@ async function getOsContext(): Promise { function getCultureContext(): CultureContext | undefined { try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any - if (typeof (process.versions as unknown as any).icu !== 'string') { + if (typeof process.versions.icu !== 'string') { // Node was built without ICU support return; } diff --git a/packages/node/src/integrations/contextlines.ts b/packages/node/src/integrations/contextlines.ts index 5c77b0e845f1..5e1bd75913c9 100644 --- a/packages/node/src/integrations/contextlines.ts +++ b/packages/node/src/integrations/contextlines.ts @@ -1,9 +1,7 @@ import { createReadStream } from 'node:fs'; import { createInterface } from 'node:readline'; -import { defineIntegration } from '@sentry/core'; -import { LRUMap, logger, snipLine } from '@sentry/core'; -import type { Event, IntegrationFn, StackFrame } from '@sentry/types'; - +import type { Event, IntegrationFn, StackFrame } from '@sentry/core'; +import { LRUMap, defineIntegration, logger, snipLine } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; const LRU_FILE_CONTENTS_CACHE = new LRUMap>(10); diff --git a/packages/node/src/integrations/http/SentryHttpInstrumentation.ts b/packages/node/src/integrations/http/SentryHttpInstrumentation.ts index 4d948c9d37c4..382e5bde8a0a 100644 --- a/packages/node/src/integrations/http/SentryHttpInstrumentation.ts +++ b/packages/node/src/integrations/http/SentryHttpInstrumentation.ts @@ -5,6 +5,7 @@ import { VERSION } from '@opentelemetry/core'; import type { InstrumentationConfig } from '@opentelemetry/instrumentation'; import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation'; import { getRequestInfo } from '@opentelemetry/instrumentation-http'; +import type { RequestEventData, SanitizedRequestData, Scope } from '@sentry/core'; import { addBreadcrumb, getBreadcrumbLogLevelFromHttpStatusCode, @@ -17,7 +18,6 @@ import { stripUrlQueryAndFragment, withIsolationScope, } from '@sentry/core'; -import type { RequestEventData, SanitizedRequestData, Scope } from '@sentry/types'; import { DEBUG_BUILD } from '../../debug-build'; import type { NodeClient } from '../../sdk/client'; import { getRequestUrl } from '../../utils/getRequestUrl'; diff --git a/packages/node/src/integrations/http/index.ts b/packages/node/src/integrations/http/index.ts index 224bd56485a1..12b9564737a0 100644 --- a/packages/node/src/integrations/http/index.ts +++ b/packages/node/src/integrations/http/index.ts @@ -2,11 +2,9 @@ import type { ClientRequest, IncomingMessage, RequestOptions, ServerResponse } f import { diag } from '@opentelemetry/api'; import type { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; - +import type { IntegrationFn, Span } from '@sentry/core'; import { defineIntegration } from '@sentry/core'; import { getClient } from '@sentry/opentelemetry'; -import type { IntegrationFn, Span } from '@sentry/types'; - import { generateInstrumentOnce } from '../../otel/instrument'; import type { NodeClient } from '../../sdk/client'; import type { HTTPModuleRequestIncomingMessage } from '../../transports/http-module'; diff --git a/packages/node/src/integrations/local-variables/index.ts b/packages/node/src/integrations/local-variables/index.ts index 36db00bdb9aa..13a580383fcf 100644 --- a/packages/node/src/integrations/local-variables/index.ts +++ b/packages/node/src/integrations/local-variables/index.ts @@ -1,4 +1,4 @@ -import type { Integration } from '@sentry/types'; +import type { Integration } from '@sentry/core'; import { NODE_VERSION } from '../../nodeVersion'; import type { LocalVariablesIntegrationOptions } from './common'; import { localVariablesAsyncIntegration } from './local-variables-async'; diff --git a/packages/node/src/integrations/local-variables/local-variables-async.ts b/packages/node/src/integrations/local-variables/local-variables-async.ts index 19a67db88057..89d92e46bd59 100644 --- a/packages/node/src/integrations/local-variables/local-variables-async.ts +++ b/packages/node/src/integrations/local-variables/local-variables-async.ts @@ -1,12 +1,9 @@ import { Worker } from 'node:worker_threads'; -import { defineIntegration } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { Event, EventHint, Exception, IntegrationFn } from '@sentry/types'; - +import type { Event, EventHint, Exception, IntegrationFn } from '@sentry/core'; +import { defineIntegration, logger } from '@sentry/core'; import type { NodeClient } from '../../sdk/client'; import type { FrameVariables, LocalVariablesIntegrationOptions, LocalVariablesWorkerArgs } from './common'; -import { LOCAL_VARIABLES_KEY } from './common'; -import { functionNamesMatch } from './common'; +import { LOCAL_VARIABLES_KEY, functionNamesMatch } from './common'; // This string is a placeholder that gets overwritten with the worker code. export const base64WorkerScript = '###LocalVariablesWorkerScript###'; diff --git a/packages/node/src/integrations/local-variables/local-variables-sync.ts b/packages/node/src/integrations/local-variables/local-variables-sync.ts index 454de1d9d356..4de0fe8aa478 100644 --- a/packages/node/src/integrations/local-variables/local-variables-sync.ts +++ b/packages/node/src/integrations/local-variables/local-variables-sync.ts @@ -1,8 +1,6 @@ import type { Debugger, InspectorNotification, Runtime, Session } from 'node:inspector'; -import { defineIntegration, getClient } from '@sentry/core'; -import { LRUMap, logger } from '@sentry/core'; -import type { Event, Exception, IntegrationFn, StackFrame, StackParser } from '@sentry/types'; - +import type { Event, Exception, IntegrationFn, StackFrame, StackParser } from '@sentry/core'; +import { LRUMap, defineIntegration, getClient, logger } from '@sentry/core'; import { NODE_MAJOR } from '../../nodeVersion'; import type { NodeClient } from '../../sdk/client'; import type { diff --git a/packages/node/src/integrations/modules.ts b/packages/node/src/integrations/modules.ts index 9a48dc82464a..f3c187589de1 100644 --- a/packages/node/src/integrations/modules.ts +++ b/packages/node/src/integrations/modules.ts @@ -1,8 +1,7 @@ import { existsSync, readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; -import { defineIntegration } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; +import { defineIntegration, logger } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import { isCjs } from '../utils/commonjs'; diff --git a/packages/node/src/integrations/node-fetch.ts b/packages/node/src/integrations/node-fetch.ts index d02fa53f789f..a4678be7239a 100644 --- a/packages/node/src/integrations/node-fetch.ts +++ b/packages/node/src/integrations/node-fetch.ts @@ -1,20 +1,20 @@ -import { context, propagation, trace } from '@opentelemetry/api'; +import { registerInstrumentations } from '@opentelemetry/instrumentation'; import type { UndiciRequest, UndiciResponse } from '@opentelemetry/instrumentation-undici'; import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'; +import type { IntegrationFn, SanitizedRequestData } from '@sentry/core'; import { + LRUMap, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, addBreadcrumb, defineIntegration, - getCurrentScope, + getBreadcrumbLogLevelFromHttpStatusCode, + getClient, + getSanitizedUrlString, + getTraceData, hasTracingEnabled, + parseUrl, } from '@sentry/core'; -import { getBreadcrumbLogLevelFromHttpStatusCode, getSanitizedUrlString, parseUrl } from '@sentry/core'; -import { - addOpenTelemetryInstrumentation, - generateSpanContextForPropagationContext, - getPropagationContextFromSpan, -} from '@sentry/opentelemetry'; -import type { IntegrationFn, SanitizedRequestData } from '@sentry/types'; +import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry'; interface NodeFetchOptions { /** @@ -37,6 +37,8 @@ const _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => { return { name: 'NodeFetch', setupOnce() { + const propagationDecisionMap = new LRUMap(100); + const instrumentation = new UndiciInstrumentation({ requireParentforSpans: false, ignoreRequestHook: request => { @@ -50,22 +52,10 @@ const _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => { // If tracing is disabled, we still want to propagate traces // So we do that manually here, matching what the instrumentation does otherwise if (!hasTracingEnabled()) { - const ctx = context.active(); - const addedHeaders: Record = {}; - - // We generate a virtual span context from the active one, - // Where we attach the URL to the trace state, so the propagator can pick it up - const activeSpan = trace.getSpan(ctx); - const propagationContext = activeSpan - ? getPropagationContextFromSpan(activeSpan) - : getCurrentScope().getPropagationContext(); - - const spanContext = generateSpanContextForPropagationContext(propagationContext); - // We know that in practice we'll _always_ haven a traceState here - spanContext.traceState = spanContext.traceState?.set('sentry.url', url); - const ctxWithUrlTraceState = trace.setSpanContext(ctx, spanContext); - - propagation.inject(ctxWithUrlTraceState, addedHeaders); + const tracePropagationTargets = getClient()?.getOptions().tracePropagationTargets; + const addedHeaders = shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap) + ? getTraceData() + : {}; const requestHeaders = request.headers; if (Array.isArray(requestHeaders)) { @@ -94,7 +84,7 @@ const _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => { }, }); - addOpenTelemetryInstrumentation(instrumentation); + registerInstrumentations({ instrumentations: [instrumentation] }); }, }; }) satisfies IntegrationFn; diff --git a/packages/node/src/integrations/onuncaughtexception.ts b/packages/node/src/integrations/onuncaughtexception.ts index d0e728119fc2..0634159338a6 100644 --- a/packages/node/src/integrations/onuncaughtexception.ts +++ b/packages/node/src/integrations/onuncaughtexception.ts @@ -1,7 +1,4 @@ -import { captureException, defineIntegration } from '@sentry/core'; -import { getClient } from '@sentry/core'; -import { logger } from '@sentry/core'; - +import { captureException, defineIntegration, getClient, logger } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import type { NodeClient } from '../sdk/client'; import { logAndExitProcess } from '../utils/errorhandling'; diff --git a/packages/node/src/integrations/onunhandledrejection.ts b/packages/node/src/integrations/onunhandledrejection.ts index a30881d89d4b..ecf89960cbd6 100644 --- a/packages/node/src/integrations/onunhandledrejection.ts +++ b/packages/node/src/integrations/onunhandledrejection.ts @@ -1,6 +1,5 @@ -import { captureException, defineIntegration, getClient } from '@sentry/core'; -import { consoleSandbox } from '@sentry/core'; -import type { Client, IntegrationFn } from '@sentry/types'; +import type { Client, IntegrationFn } from '@sentry/core'; +import { captureException, consoleSandbox, defineIntegration, getClient } from '@sentry/core'; import { logAndExitProcess } from '../utils/errorhandling'; type UnhandledRejectionMode = 'none' | 'warn' | 'strict'; diff --git a/packages/node/src/integrations/spotlight.ts b/packages/node/src/integrations/spotlight.ts index 20828dab4eb6..49a169076798 100644 --- a/packages/node/src/integrations/spotlight.ts +++ b/packages/node/src/integrations/spotlight.ts @@ -1,7 +1,6 @@ import * as http from 'node:http'; -import { defineIntegration } from '@sentry/core'; -import { logger, serializeEnvelope } from '@sentry/core'; -import type { Client, Envelope, IntegrationFn } from '@sentry/types'; +import type { Client, Envelope, IntegrationFn } from '@sentry/core'; +import { defineIntegration, logger, serializeEnvelope } from '@sentry/core'; type SpotlightConnectionOptions = { /** diff --git a/packages/node/src/integrations/tracing/amqplib.ts b/packages/node/src/integrations/tracing/amqplib.ts index d56dd365924c..f6320406edaf 100644 --- a/packages/node/src/integrations/tracing/amqplib.ts +++ b/packages/node/src/integrations/tracing/amqplib.ts @@ -1,7 +1,7 @@ import type { Span } from '@opentelemetry/api'; import { AmqplibInstrumentation, type AmqplibInstrumentationConfig } from '@opentelemetry/instrumentation-amqplib'; +import type { IntegrationFn } from '@sentry/core'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; import { generateInstrumentOnce } from '../../otel/instrument'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; diff --git a/packages/node/src/integrations/tracing/connect.ts b/packages/node/src/integrations/tracing/connect.ts index b2938d5ee6f2..30e12b245347 100644 --- a/packages/node/src/integrations/tracing/connect.ts +++ b/packages/node/src/integrations/tracing/connect.ts @@ -1,4 +1,5 @@ import { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect'; +import type { IntegrationFn, Span } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -7,7 +8,6 @@ import { getClient, spanToJSON, } from '@sentry/core'; -import type { IntegrationFn, Span } from '@sentry/types'; import { generateInstrumentOnce } from '../../otel/instrument'; import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; diff --git a/packages/node/src/integrations/tracing/dataloader.ts b/packages/node/src/integrations/tracing/dataloader.ts index 87a479cf0589..6339515c6f28 100644 --- a/packages/node/src/integrations/tracing/dataloader.ts +++ b/packages/node/src/integrations/tracing/dataloader.ts @@ -5,7 +5,7 @@ import { defineIntegration, spanToJSON, } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; const INTEGRATION_NAME = 'Dataloader'; diff --git a/packages/node/src/integrations/tracing/express.ts b/packages/node/src/integrations/tracing/express.ts index 3db47f551ccb..73312353da46 100644 --- a/packages/node/src/integrations/tracing/express.ts +++ b/packages/node/src/integrations/tracing/express.ts @@ -1,9 +1,16 @@ import type * as http from 'node:http'; import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; -import { SEMANTIC_ATTRIBUTE_SENTRY_OP, defineIntegration, getDefaultIsolationScope, spanToJSON } from '@sentry/core'; -import { captureException, getClient, getIsolationScope } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + captureException, + defineIntegration, + getClient, + getDefaultIsolationScope, + getIsolationScope, + logger, + spanToJSON, +} from '@sentry/core'; import { DEBUG_BUILD } from '../../debug-build'; import { generateInstrumentOnce } from '../../otel/instrument'; import type { NodeClient } from '../../sdk/client'; diff --git a/packages/node/src/integrations/tracing/fastify.ts b/packages/node/src/integrations/tracing/fastify.ts index 5a75e204b5f5..a87980045b54 100644 --- a/packages/node/src/integrations/tracing/fastify.ts +++ b/packages/node/src/integrations/tracing/fastify.ts @@ -8,7 +8,7 @@ import { getIsolationScope, spanToJSON, } from '@sentry/core'; -import type { IntegrationFn, Span } from '@sentry/types'; +import type { IntegrationFn, Span } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; diff --git a/packages/node/src/integrations/tracing/genericPool.ts b/packages/node/src/integrations/tracing/genericPool.ts index ab3e5c25a207..6c4169d66b99 100644 --- a/packages/node/src/integrations/tracing/genericPool.ts +++ b/packages/node/src/integrations/tracing/genericPool.ts @@ -1,6 +1,6 @@ import { GenericPoolInstrumentation } from '@opentelemetry/instrumentation-generic-pool'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; const INTEGRATION_NAME = 'GenericPool'; diff --git a/packages/node/src/integrations/tracing/graphql.ts b/packages/node/src/integrations/tracing/graphql.ts index c2f1402a0229..4de5172f8c12 100644 --- a/packages/node/src/integrations/tracing/graphql.ts +++ b/packages/node/src/integrations/tracing/graphql.ts @@ -1,7 +1,7 @@ import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql'; import { defineIntegration, getRootSpan, spanToJSON } from '@sentry/core'; +import type { IntegrationFn } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_GRAPHQL_OPERATION } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; import { generateInstrumentOnce } from '../../otel/instrument'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; diff --git a/packages/node/src/integrations/tracing/hapi/index.ts b/packages/node/src/integrations/tracing/hapi/index.ts index 113c37bfc90b..3fe5dd27c6d8 100644 --- a/packages/node/src/integrations/tracing/hapi/index.ts +++ b/packages/node/src/integrations/tracing/hapi/index.ts @@ -1,4 +1,5 @@ import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi'; +import type { IntegrationFn, Span } from '@sentry/core'; import { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, @@ -8,10 +9,9 @@ import { getClient, getDefaultIsolationScope, getIsolationScope, + logger, spanToJSON, } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { IntegrationFn, Span } from '@sentry/types'; import { DEBUG_BUILD } from '../../../debug-build'; import { generateInstrumentOnce } from '../../../otel/instrument'; import { ensureIsWrapped } from '../../../utils/ensureIsWrapped'; diff --git a/packages/node/src/integrations/tracing/index.ts b/packages/node/src/integrations/tracing/index.ts index c8f6348aeee0..1d6a7e9fdb8f 100644 --- a/packages/node/src/integrations/tracing/index.ts +++ b/packages/node/src/integrations/tracing/index.ts @@ -1,4 +1,4 @@ -import type { Integration } from '@sentry/types'; +import type { Integration } from '@sentry/core'; import { instrumentOtelHttp } from '../http'; import { amqplibIntegration, instrumentAmqplib } from './amqplib'; diff --git a/packages/node/src/integrations/tracing/kafka.ts b/packages/node/src/integrations/tracing/kafka.ts index 68a9ccf8bab4..37d976f5d4e1 100644 --- a/packages/node/src/integrations/tracing/kafka.ts +++ b/packages/node/src/integrations/tracing/kafka.ts @@ -1,7 +1,6 @@ import { KafkaJsInstrumentation } from '@opentelemetry/instrumentation-kafkajs'; - +import type { IntegrationFn } from '@sentry/core'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; import { generateInstrumentOnce } from '../../otel/instrument'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; diff --git a/packages/node/src/integrations/tracing/knex.ts b/packages/node/src/integrations/tracing/knex.ts index 55457680e101..4af0f7f1b787 100644 --- a/packages/node/src/integrations/tracing/knex.ts +++ b/packages/node/src/integrations/tracing/knex.ts @@ -1,6 +1,6 @@ import { KnexInstrumentation } from '@opentelemetry/instrumentation-knex'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; const INTEGRATION_NAME = 'Knex'; diff --git a/packages/node/src/integrations/tracing/koa.ts b/packages/node/src/integrations/tracing/koa.ts index 26ecea2133b1..469ab63a0d82 100644 --- a/packages/node/src/integrations/tracing/koa.ts +++ b/packages/node/src/integrations/tracing/koa.ts @@ -1,5 +1,6 @@ import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa'; import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions'; +import type { IntegrationFn, Span } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, @@ -7,10 +8,9 @@ import { defineIntegration, getDefaultIsolationScope, getIsolationScope, + logger, spanToJSON, } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { IntegrationFn, Span } from '@sentry/types'; import { DEBUG_BUILD } from '../../debug-build'; import { generateInstrumentOnce } from '../../otel/instrument'; import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; diff --git a/packages/node/src/integrations/tracing/lrumemoizer.ts b/packages/node/src/integrations/tracing/lrumemoizer.ts index 6c8a1962338c..9bd1477cc9c5 100644 --- a/packages/node/src/integrations/tracing/lrumemoizer.ts +++ b/packages/node/src/integrations/tracing/lrumemoizer.ts @@ -1,7 +1,7 @@ import { LruMemoizerInstrumentation } from '@opentelemetry/instrumentation-lru-memoizer'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; const INTEGRATION_NAME = 'LruMemoizer'; diff --git a/packages/node/src/integrations/tracing/mongo.ts b/packages/node/src/integrations/tracing/mongo.ts index 5f4d4e66a8a6..f145c772006f 100644 --- a/packages/node/src/integrations/tracing/mongo.ts +++ b/packages/node/src/integrations/tracing/mongo.ts @@ -1,6 +1,6 @@ import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; diff --git a/packages/node/src/integrations/tracing/mongoose.ts b/packages/node/src/integrations/tracing/mongoose.ts index 58234c1ec87f..baf3053ba638 100644 --- a/packages/node/src/integrations/tracing/mongoose.ts +++ b/packages/node/src/integrations/tracing/mongoose.ts @@ -1,6 +1,6 @@ import { MongooseInstrumentation } from '@opentelemetry/instrumentation-mongoose'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; diff --git a/packages/node/src/integrations/tracing/mysql.ts b/packages/node/src/integrations/tracing/mysql.ts index d6509de0f765..96ad15ad3de8 100644 --- a/packages/node/src/integrations/tracing/mysql.ts +++ b/packages/node/src/integrations/tracing/mysql.ts @@ -1,6 +1,6 @@ import { MySQLInstrumentation } from '@opentelemetry/instrumentation-mysql'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; const INTEGRATION_NAME = 'Mysql'; diff --git a/packages/node/src/integrations/tracing/mysql2.ts b/packages/node/src/integrations/tracing/mysql2.ts index c44fa2433528..6e141339780f 100644 --- a/packages/node/src/integrations/tracing/mysql2.ts +++ b/packages/node/src/integrations/tracing/mysql2.ts @@ -1,6 +1,6 @@ import { MySQL2Instrumentation } from '@opentelemetry/instrumentation-mysql2'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; diff --git a/packages/node/src/integrations/tracing/nest/helpers.ts b/packages/node/src/integrations/tracing/nest/helpers.ts index 236a54ae2a42..7e5e63db43e5 100644 --- a/packages/node/src/integrations/tracing/nest/helpers.ts +++ b/packages/node/src/integrations/tracing/nest/helpers.ts @@ -1,6 +1,10 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, withActiveSpan } from '@sentry/core'; -import { addNonEnumerableProperty } from '@sentry/core'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + addNonEnumerableProperty, + withActiveSpan, +} from '@sentry/core'; import type { CatchTarget, InjectableTarget, NextFunction, Observable, Subscription } from './types'; const sentryPatched = 'sentryPatched'; diff --git a/packages/node/src/integrations/tracing/nest/nest.ts b/packages/node/src/integrations/tracing/nest/nest.ts index f21a3fd3eae6..1c63c22783aa 100644 --- a/packages/node/src/integrations/tracing/nest/nest.ts +++ b/packages/node/src/integrations/tracing/nest/nest.ts @@ -1,16 +1,17 @@ import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core'; +import type { Span } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, captureException, + consoleSandbox, defineIntegration, getClient, getDefaultIsolationScope, getIsolationScope, + logger, spanToJSON, } from '@sentry/core'; -import { consoleSandbox, logger } from '@sentry/core'; -import type { Span } from '@sentry/types'; import { generateInstrumentOnce } from '../../../otel/instrument'; import { SentryNestEventInstrumentation } from './sentry-nest-event-instrumentation'; import { SentryNestInstrumentation } from './sentry-nest-instrumentation'; diff --git a/packages/node/src/integrations/tracing/nest/sentry-nest-event-instrumentation.ts b/packages/node/src/integrations/tracing/nest/sentry-nest-event-instrumentation.ts index 59dac31b8218..c9907945d1b5 100644 --- a/packages/node/src/integrations/tracing/nest/sentry-nest-event-instrumentation.ts +++ b/packages/node/src/integrations/tracing/nest/sentry-nest-event-instrumentation.ts @@ -5,8 +5,7 @@ import { InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile, } from '@opentelemetry/instrumentation'; -import { captureException, startSpan } from '@sentry/core'; -import { SDK_VERSION } from '@sentry/core'; +import { SDK_VERSION, captureException, startSpan } from '@sentry/core'; import { getEventSpanOptions } from './helpers'; import type { OnEventTarget } from './types'; diff --git a/packages/node/src/integrations/tracing/nest/sentry-nest-instrumentation.ts b/packages/node/src/integrations/tracing/nest/sentry-nest-instrumentation.ts index 66449995ac1e..91428a96c88d 100644 --- a/packages/node/src/integrations/tracing/nest/sentry-nest-instrumentation.ts +++ b/packages/node/src/integrations/tracing/nest/sentry-nest-instrumentation.ts @@ -5,9 +5,17 @@ import { InstrumentationNodeModuleDefinition, InstrumentationNodeModuleFile, } from '@opentelemetry/instrumentation'; -import { getActiveSpan, startInactiveSpan, startSpan, startSpanManual, withActiveSpan } from '@sentry/core'; -import { SDK_VERSION, addNonEnumerableProperty, isThenable } from '@sentry/core'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; +import { + SDK_VERSION, + addNonEnumerableProperty, + getActiveSpan, + isThenable, + startInactiveSpan, + startSpan, + startSpanManual, + withActiveSpan, +} from '@sentry/core'; import { getMiddlewareSpanOptions, getNextProxy, instrumentObservable, isPatched } from './helpers'; import type { CallHandler, CatchTarget, InjectableTarget, MinimalNestJsExecutionContext, Observable } from './types'; diff --git a/packages/node/src/integrations/tracing/postgres.ts b/packages/node/src/integrations/tracing/postgres.ts index 6df045156d41..d436b95b45d8 100644 --- a/packages/node/src/integrations/tracing/postgres.ts +++ b/packages/node/src/integrations/tracing/postgres.ts @@ -1,6 +1,6 @@ import { PgInstrumentation } from '@opentelemetry/instrumentation-pg'; import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; diff --git a/packages/node/src/integrations/tracing/prisma.ts b/packages/node/src/integrations/tracing/prisma.ts index 56768bf1ba71..a42d41a6b5ec 100644 --- a/packages/node/src/integrations/tracing/prisma.ts +++ b/packages/node/src/integrations/tracing/prisma.ts @@ -1,7 +1,7 @@ // When importing CJS modules into an ESM module, we cannot import the named exports directly. import * as prismaInstrumentation from '@prisma/instrumentation'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; const INTEGRATION_NAME = 'Prisma'; diff --git a/packages/node/src/integrations/tracing/redis.ts b/packages/node/src/integrations/tracing/redis.ts index 7888aaf66be3..be788815c177 100644 --- a/packages/node/src/integrations/tracing/redis.ts +++ b/packages/node/src/integrations/tracing/redis.ts @@ -2,6 +2,7 @@ import type { Span } from '@opentelemetry/api'; import type { RedisResponseCustomAttributeFunction } from '@opentelemetry/instrumentation-ioredis'; import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'; import { RedisInstrumentation } from '@opentelemetry/instrumentation-redis-4'; +import type { IntegrationFn } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_CACHE_HIT, SEMANTIC_ATTRIBUTE_CACHE_ITEM_SIZE, @@ -10,9 +11,8 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON, + truncate, } from '@sentry/core'; -import { truncate } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; import { generateInstrumentOnce } from '../../otel/instrument'; import { GET_COMMANDS, diff --git a/packages/node/src/integrations/tracing/tedious.ts b/packages/node/src/integrations/tracing/tedious.ts index 6ad1cf56f28e..8671edd2c09f 100644 --- a/packages/node/src/integrations/tracing/tedious.ts +++ b/packages/node/src/integrations/tracing/tedious.ts @@ -1,6 +1,6 @@ import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn } from '@sentry/core'; import { generateInstrumentOnce } from '../../otel/instrument'; const TEDIUS_INSTRUMENTED_METHODS = new Set([ diff --git a/packages/node/src/otel/instrument.ts b/packages/node/src/otel/instrument.ts index 6db677a3956c..c5bd7500a739 100644 --- a/packages/node/src/otel/instrument.ts +++ b/packages/node/src/otel/instrument.ts @@ -1,5 +1,4 @@ -import type { Instrumentation } from '@opentelemetry/instrumentation'; -import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; +import { type Instrumentation, registerInstrumentations } from '@opentelemetry/instrumentation'; /** Exported only for tests. */ export const INSTRUMENTED: Record = {}; @@ -26,7 +25,9 @@ export function generateInstrumentOnce( const instrumentation = creator(options); INSTRUMENTED[name] = instrumentation; - addOpenTelemetryInstrumentation(instrumentation); + registerInstrumentations({ + instrumentations: [instrumentation], + }); }, { id: name }, ); diff --git a/packages/node/src/proxy/base.ts b/packages/node/src/proxy/base.ts index 6e374160b16a..d758abf2b224 100644 --- a/packages/node/src/proxy/base.ts +++ b/packages/node/src/proxy/base.ts @@ -81,8 +81,7 @@ export abstract class Agent extends http.Agent { if (options) { // First check the `secureEndpoint` property explicitly, since this // means that a parent `Agent` is "passing through" to this instance. - // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access - if (typeof (options as any).secureEndpoint === 'boolean') { + if (typeof (options as Partial).secureEndpoint === 'boolean') { return options.secureEndpoint; } diff --git a/packages/node/src/sdk/api.ts b/packages/node/src/sdk/api.ts index e7b09a18b4a4..dd7ccc8ca75d 100644 --- a/packages/node/src/sdk/api.ts +++ b/packages/node/src/sdk/api.ts @@ -1,7 +1,7 @@ // PUBLIC APIS +import type { StackParser } from '@sentry/core'; import { GLOBAL_OBJ, createStackParser, nodeStackLineParser } from '@sentry/core'; -import type { StackParser } from '@sentry/types'; import { createGetModuleFromFilename } from '../utils/module'; /** diff --git a/packages/node/src/sdk/client.ts b/packages/node/src/sdk/client.ts index 8179d40e2819..b51237a328ea 100644 --- a/packages/node/src/sdk/client.ts +++ b/packages/node/src/sdk/client.ts @@ -1,10 +1,11 @@ import * as os from 'node:os'; import type { Tracer } from '@opentelemetry/api'; import { trace } from '@opentelemetry/api'; +import { registerInstrumentations } from '@opentelemetry/instrumentation'; import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; -import type { ServerRuntimeClientOptions } from '@sentry/core'; -import { SDK_VERSION, ServerRuntimeClient, applySdkMetadata } from '@sentry/core'; -import { logger } from '@sentry/core'; +import type { DynamicSamplingContext, Scope, ServerRuntimeClientOptions, TraceContext } from '@sentry/core'; +import { SDK_VERSION, ServerRuntimeClient, applySdkMetadata, logger } from '@sentry/core'; +import { getTraceContextForScope } from '@sentry/opentelemetry'; import { isMainThread, threadId } from 'worker_threads'; import { DEBUG_BUILD } from '../debug-build'; import type { NodeClientOptions } from '../types'; @@ -26,6 +27,12 @@ export class NodeClient extends ServerRuntimeClient { serverName: options.serverName || global.process.env.SENTRY_NAME || os.hostname(), }; + if (options.openTelemetryInstrumentations) { + registerInstrumentations({ + instrumentations: options.openTelemetryInstrumentations, + }); + } + applySdkMetadata(clientOptions, 'node'); logger.log( @@ -115,4 +122,15 @@ export class NodeClient extends ServerRuntimeClient { process.on('beforeExit', this._clientReportOnExitFlushListener); } } + + /** Custom implementation for OTEL, so we can handle scope-span linking. */ + protected _getTraceInfoFromScope( + scope: Scope | undefined, + ): [dynamicSamplingContext: Partial | undefined, traceContext: TraceContext | undefined] { + if (!scope) { + return [undefined, undefined]; + } + + return getTraceContextForScope(this, scope); + } } diff --git a/packages/node/src/sdk/index.ts b/packages/node/src/sdk/index.ts index 2a64fb0d904f..1104386fb2ca 100644 --- a/packages/node/src/sdk/index.ts +++ b/packages/node/src/sdk/index.ts @@ -1,4 +1,7 @@ +import type { Integration, Options } from '@sentry/core'; import { + consoleSandbox, + dropUndefinedKeys, endSession, functionToStringIntegration, getClient, @@ -8,15 +11,11 @@ import { hasTracingEnabled, inboundFiltersIntegration, linkedErrorsIntegration, - requestDataIntegration, - startSession, -} from '@sentry/core'; -import { - consoleSandbox, - dropUndefinedKeys, logger, propagationContextFromHeaders, + requestDataIntegration, stackParserFromStackParserOptions, + startSession, } from '@sentry/core'; import { enhanceDscWithOpenTelemetryRootSpanName, @@ -24,13 +23,11 @@ import { setOpenTelemetryContextAsyncContextStrategy, setupEventContextTrace, } from '@sentry/opentelemetry'; -import type { Integration, Options } from '@sentry/types'; import { DEBUG_BUILD } from '../debug-build'; +import { childProcessIntegration } from '../integrations/childProcess'; import { consoleIntegration } from '../integrations/console'; import { nodeContextIntegration } from '../integrations/context'; import { contextLinesIntegration } from '../integrations/contextlines'; - -import { childProcessIntegration } from '../integrations/childProcess'; import { httpIntegration } from '../integrations/http'; import { localVariablesIntegration } from '../integrations/local-variables'; import { modulesIntegration } from '../integrations/modules'; diff --git a/packages/node/src/sdk/initOtel.ts b/packages/node/src/sdk/initOtel.ts index fd37e5ef477f..eb62cef6ac65 100644 --- a/packages/node/src/sdk/initOtel.ts +++ b/packages/node/src/sdk/initOtel.ts @@ -7,11 +7,9 @@ import { ATTR_SERVICE_VERSION, SEMRESATTRS_SERVICE_NAMESPACE, } from '@opentelemetry/semantic-conventions'; -import { SDK_VERSION } from '@sentry/core'; -import { GLOBAL_OBJ, consoleSandbox, logger } from '@sentry/core'; +import { GLOBAL_OBJ, SDK_VERSION, consoleSandbox, logger } from '@sentry/core'; import { SentryPropagator, SentrySampler, SentrySpanProcessor } from '@sentry/opentelemetry'; import { createAddHookMessageChannel } from 'import-in-the-middle'; - import { getOpenTelemetryInstrumentationToPreload } from '../integrations/tracing'; import { SentryContextManager } from '../otel/contextManager'; import type { EsmLoaderHookOptions } from '../types'; @@ -42,10 +40,12 @@ interface RegisterOptions { } function getRegisterOptions(esmHookConfig?: EsmLoaderHookOptions): RegisterOptions { + // TODO(v9): Make onlyIncludeInstrumentedModules: true the default behavior. if (esmHookConfig?.onlyIncludeInstrumentedModules) { const { addHookMessagePort } = createAddHookMessageChannel(); // If the user supplied include, we need to use that as a starting point or use an empty array to ensure no modules // are wrapped if they are not hooked + // eslint-disable-next-line deprecation/deprecation return { data: { addHookMessagePort, include: esmHookConfig.include || [] }, transferList: [addHookMessagePort] }; } @@ -75,7 +75,7 @@ export function maybeInitializeEsmLoader(esmHookConfig?: EsmLoaderHookOptions): consoleSandbox(() => { // eslint-disable-next-line no-console console.warn( - '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or use version 7.x of the Sentry Node.js SDK.', + '[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or upgrade your Node.js version.', ); }); } diff --git a/packages/node/src/sdk/scope.ts b/packages/node/src/sdk/scope.ts index 0633c1f57f43..cc376fbf086c 100644 --- a/packages/node/src/sdk/scope.ts +++ b/packages/node/src/sdk/scope.ts @@ -1,6 +1,6 @@ import { context } from '@opentelemetry/api'; +import type { Scope } from '@sentry/core'; import { getScopesFromContext } from '@sentry/opentelemetry'; -import type { Scope } from '@sentry/types'; /** * Update the active isolation scope. diff --git a/packages/node/src/transports/http.ts b/packages/node/src/transports/http.ts index ce3b34dbc909..39211c281d50 100644 --- a/packages/node/src/transports/http.ts +++ b/packages/node/src/transports/http.ts @@ -2,15 +2,14 @@ import * as http from 'node:http'; import * as https from 'node:https'; import { Readable } from 'node:stream'; import { createGzip } from 'node:zlib'; -import { createTransport, suppressTracing } from '@sentry/core'; -import { consoleSandbox } from '@sentry/core'; import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest, TransportRequestExecutor, -} from '@sentry/types'; +} from '@sentry/core'; +import { consoleSandbox, createTransport, suppressTracing } from '@sentry/core'; import { HttpsProxyAgent } from '../proxy'; import type { HTTPModule } from './http-module'; diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts index 7235e2057c34..ebcdee869523 100644 --- a/packages/node/src/types.ts +++ b/packages/node/src/types.ts @@ -1,12 +1,30 @@ import type { Span as WriteableSpan } from '@opentelemetry/api'; +import type { Instrumentation } from '@opentelemetry/instrumentation'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import type { ClientOptions, Options, SamplingContext, Scope, Span, TracePropagationTargets } from '@sentry/types'; +import type { ClientOptions, Options, SamplingContext, Scope, Span, TracePropagationTargets } from '@sentry/core'; import type { NodeTransportOptions } from './transports'; +/** + * Note: In the next major version of the Sentry SDK this interface will be removed and the SDK will by default only wrap + * ESM modules that are required to be wrapped by OpenTelemetry Instrumentation. + */ export interface EsmLoaderHookOptions { + /** + * Provide a list of modules to wrap with `import-in-the-middle`. + * + * @deprecated It is recommended to use `onlyIncludeInstrumentedModules: true` instead of manually defining modules to include and exclude. + */ include?: Array; - exclude?: Array /** + + /** + * Provide a list of modules to prevent them from being wrapped with `import-in-the-middle`. + * + * @deprecated It is recommended to use `onlyIncludeInstrumentedModules: true` instead of manually defining modules to include and exclude. + */ + exclude?: Array; + + /** * When set to `true`, `import-in-the-middle` will only wrap ESM modules that are specifically instrumented by * OpenTelemetry plugins. This is useful to avoid issues where `import-in-the-middle` is not compatible with some of * your dependencies. @@ -16,7 +34,11 @@ export interface EsmLoaderHookOptions { * `Sentry.init()`. * * Defaults to `false`. - */; + * + * Note: In the next major version of the Sentry SDK this option will be removed and the SDK will by default only wrap + * ESM modules that are required to be wrapped by OpenTelemetry Instrumentation. + */ + // TODO(v9): Make `onlyIncludeInstrumentedModules: true` the default behavior. onlyIncludeInstrumentedModules?: boolean; } @@ -87,9 +109,18 @@ export interface BaseNodeOptions { * * The `SentryPropagator` * * The `SentryContextManager` * * The `SentrySampler` + * + * If you are registering your own OpenTelemetry Loader Hooks (or `import-in-the-middle` hooks), it is also recommended to set the `registerEsmLoaderHooks` option to false. */ skipOpenTelemetrySetup?: boolean; + /** + * Provide an array of OpenTelemetry Instrumentations that should be registered. + * + * Use this option if you want to register OpenTelemetry instrumentation that the Sentry SDK does not yet have support for. + */ + openTelemetryInstrumentations?: Instrumentation[]; + /** * The max. duration in seconds that the SDK will wait for parent spans to be finished before discarding a span. * The SDK will automatically clean up spans that have no finished parent after this duration. @@ -117,7 +148,11 @@ export interface BaseNodeOptions { * ``` * * Defaults to `true`. + * + * Note: In the next major version of the SDK, the possibility to provide fine-grained control will be removed from this option. + * This means that it will only be possible to pass `true` or `false`. The default value will continue to be `true`. */ + // TODO(v9): Only accept true | false | undefined. registerEsmLoaderHooks?: boolean | EsmLoaderHookOptions; /** @@ -137,7 +172,7 @@ export interface BaseNodeOptions { /** * Configuration options for the Sentry Node SDK - * @see @sentry/types Options for more information. + * @see @sentry/core Options for more information. */ export interface NodeOptions extends Options, BaseNodeOptions {} @@ -156,7 +191,7 @@ export interface CurrentScopes { * The base `Span` type is basically a `WriteableSpan`. * There are places where we basically want to allow passing _any_ span, * so in these cases we type this as `AbstractSpan` which could be either a regular `Span` or a `ReadableSpan`. - * You'll have to make sur to check revelant fields before accessing them. + * You'll have to make sur to check relevant fields before accessing them. * * Note that technically, the `Span` exported from `@opentelemetry/sdk-trace-base` matches this, * but we cannot be 100% sure that we are actually getting such a span, so this type is more defensive. diff --git a/packages/node/src/utils/addOriginToSpan.ts b/packages/node/src/utils/addOriginToSpan.ts index 9d2acfcd83b2..22ed30ed37e0 100644 --- a/packages/node/src/utils/addOriginToSpan.ts +++ b/packages/node/src/utils/addOriginToSpan.ts @@ -1,6 +1,6 @@ import type { Span } from '@opentelemetry/api'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; -import type { SpanOrigin } from '@sentry/types'; +import type { SpanOrigin } from '@sentry/core'; /** Adds an origin to an OTEL Span. */ export function addOriginToSpan(span: Span, origin: SpanOrigin): void { diff --git a/packages/node/src/utils/createMissingInstrumentationContext.ts b/packages/node/src/utils/createMissingInstrumentationContext.ts index 849e49e8b8e2..1930bcf782eb 100644 --- a/packages/node/src/utils/createMissingInstrumentationContext.ts +++ b/packages/node/src/utils/createMissingInstrumentationContext.ts @@ -1,4 +1,4 @@ -import type { MissingInstrumentationContext } from '@sentry/types'; +import type { MissingInstrumentationContext } from '@sentry/core'; import { isCjs } from './commonjs'; export const createMissingInstrumentationContext = (pkg: string): MissingInstrumentationContext => ({ diff --git a/packages/node/src/utils/ensureIsWrapped.ts b/packages/node/src/utils/ensureIsWrapped.ts index 26bf8799fb42..0babb401d1f7 100644 --- a/packages/node/src/utils/ensureIsWrapped.ts +++ b/packages/node/src/utils/ensureIsWrapped.ts @@ -1,6 +1,5 @@ import { isWrapped } from '@opentelemetry/core'; -import { getClient, getGlobalScope, hasTracingEnabled, isEnabled } from '@sentry/core'; -import { consoleSandbox } from '@sentry/core'; +import { consoleSandbox, getClient, getGlobalScope, hasTracingEnabled, isEnabled } from '@sentry/core'; import type { NodeClient } from '../sdk/client'; import { isCjs } from './commonjs'; import { createMissingInstrumentationContext } from './createMissingInstrumentationContext'; diff --git a/packages/node/src/utils/entry-point.ts b/packages/node/src/utils/entry-point.ts new file mode 100644 index 000000000000..e73130f1efff --- /dev/null +++ b/packages/node/src/utils/entry-point.ts @@ -0,0 +1,66 @@ +import { resolve } from 'node:path'; +import { defaultStackParser } from '../sdk/api'; + +export interface ProcessInterface { + execArgv: string[]; + argv: string[]; + cwd: () => string; +} + +export interface ProcessArgs { + appPath: string; + importPaths: string[]; + requirePaths: string[]; +} + +/** + * Parses the process arguments to determine the app path, import paths, and require paths. + */ +export function parseProcessPaths(proc: ProcessInterface): ProcessArgs { + const { execArgv, argv, cwd: getCwd } = proc; + const cwd = getCwd(); + const appPath = resolve(cwd, argv[1] || ''); + + const joinedArgs = execArgv.join(' '); + const importPaths = Array.from(joinedArgs.matchAll(/--import[ =](\S+)/g)).map(e => resolve(cwd, e[1] || '')); + const requirePaths = Array.from(joinedArgs.matchAll(/--require[ =](\S+)/g)).map(e => resolve(cwd, e[1] || '')); + + return { appPath, importPaths, requirePaths }; +} + +/** + * Gets the current entry point type. + * + * `app` means this function was most likely called via the app entry point. + * `import` means this function was most likely called from an --import cli arg. + * `require` means this function was most likely called from a --require cli arg. + * `unknown` means we couldn't determine for sure. + */ +export function getEntryPointType(proc: ProcessInterface = process): 'import' | 'require' | 'app' | 'unknown' { + const filenames = defaultStackParser(new Error().stack || '') + .map(f => f.filename) + .filter(Boolean) as string[]; + + const { appPath, importPaths, requirePaths } = parseProcessPaths(proc); + + const output = []; + + if (appPath && filenames.includes(appPath)) { + output.push('app'); + } + + if (importPaths.some(p => filenames.includes(p))) { + output.push('import'); + } + + if (requirePaths.some(p => filenames.includes(p))) { + output.push('require'); + } + + // We only only return anything other than 'unknown' if we only got one match. + if (output.length === 1) { + return output[0] as 'import' | 'require' | 'app'; + } + + return 'unknown'; +} diff --git a/packages/node/src/utils/errorhandling.ts b/packages/node/src/utils/errorhandling.ts index a6a255c53fd7..8eda429ba38e 100644 --- a/packages/node/src/utils/errorhandling.ts +++ b/packages/node/src/utils/errorhandling.ts @@ -1,5 +1,4 @@ -import { getClient } from '@sentry/core'; -import { consoleSandbox, logger } from '@sentry/core'; +import { consoleSandbox, getClient, logger } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import type { NodeClient } from '../sdk/client'; diff --git a/packages/node/src/utils/prepareEvent.ts b/packages/node/src/utils/prepareEvent.ts index db89c2b198c0..b15b698550bc 100644 --- a/packages/node/src/utils/prepareEvent.ts +++ b/packages/node/src/utils/prepareEvent.ts @@ -1,5 +1,5 @@ import { Scope } from '@sentry/core'; -import type { CaptureContext, EventHint, Scope as ScopeInterface, ScopeContext } from '@sentry/types'; +import type { CaptureContext, EventHint, Scope as ScopeInterface, ScopeContext } from '@sentry/core'; /** * This type makes sure that we get either a CaptureContext, OR an EventHint. diff --git a/packages/node/test/integration/transactions.test.ts b/packages/node/test/integration/transactions.test.ts index e13d239821d3..3affbe37fb2c 100644 --- a/packages/node/test/integration/transactions.test.ts +++ b/packages/node/test/integration/transactions.test.ts @@ -2,8 +2,8 @@ import { TraceFlags, context, trace } from '@opentelemetry/api'; import type { SpanProcessor } from '@opentelemetry/sdk-trace-base'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { logger } from '@sentry/core'; +import type { TransactionEvent } from '@sentry/core'; import { SentrySpanProcessor } from '@sentry/opentelemetry'; -import type { TransactionEvent } from '@sentry/types'; import * as Sentry from '../../src'; import { cleanupOtel, getProvider, mockSdkInit } from '../helpers/mockSdkInit'; @@ -94,9 +94,9 @@ describe('Integration | Transactions', () => { 'test.outer': 'test value', }, op: 'test op', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.test', }); @@ -107,7 +107,7 @@ describe('Integration | Transactions', () => { sample_rate: '1', sampled: 'true', release: '8.0.0', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), transaction: 'test name', }); @@ -136,12 +136,12 @@ describe('Integration | Transactions', () => { }, description: 'inner span 1', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, { data: { @@ -150,12 +150,12 @@ describe('Integration | Transactions', () => { }, description: 'inner span 2', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, ]); }); @@ -245,9 +245,9 @@ describe('Integration | Transactions', () => { 'sentry.sample_rate': 1, }, op: 'test op', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.test', }, }), @@ -283,9 +283,9 @@ describe('Integration | Transactions', () => { 'sentry.sample_rate': 1, }, op: 'test op b', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, }), @@ -386,9 +386,9 @@ describe('Integration | Transactions', () => { 'test.outer': 'test value', 'sentry.sample_rate': 1, }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, }), @@ -421,9 +421,9 @@ describe('Integration | Transactions', () => { 'test.outer': 'test value b', 'sentry.sample_rate': 1, }, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, }), @@ -494,7 +494,7 @@ describe('Integration | Transactions', () => { 'sentry.sample_rate': 1, }, op: 'test op', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), parent_span_id: parentSpanId, status: 'ok', trace_id: traceId, @@ -528,8 +528,8 @@ describe('Integration | Transactions', () => { }, description: 'inner span 1', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), @@ -541,8 +541,8 @@ describe('Integration | Transactions', () => { }, description: 'inner span 2', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), @@ -577,17 +577,9 @@ describe('Integration | Transactions', () => { throw new Error('No exporter found, aborting test...'); } - let innerSpan1Id: string | undefined; - let innerSpan2Id: string | undefined; - void Sentry.startSpan({ name: 'test name' }, async () => { - const subSpan = Sentry.startInactiveSpan({ name: 'inner span 1' }); - innerSpan1Id = subSpan.spanContext().spanId; - subSpan.end(); - - Sentry.startSpan({ name: 'inner span 2' }, innerSpan => { - innerSpan2Id = innerSpan.spanContext().spanId; - }); + Sentry.startInactiveSpan({ name: 'inner span 1' }).end(); + Sentry.startInactiveSpan({ name: 'inner span 2' }).end(); // Pretend this is pending for 10 minutes await new Promise(resolve => setTimeout(resolve, 10 * 60 * 1000)); @@ -596,7 +588,13 @@ describe('Integration | Transactions', () => { jest.advanceTimersByTime(1); // Child-spans have been added to the exporter, but they are pending since they are waiting for their parent - expect(exporter['_finishedSpans'].length).toBe(2); + const finishedSpans1 = []; + exporter['_finishedSpanBuckets'].forEach((bucket: any) => { + if (bucket) { + finishedSpans1.push(...bucket.spans); + } + }); + expect(finishedSpans1.length).toBe(2); expect(beforeSendTransaction).toHaveBeenCalledTimes(0); // Now wait for 5 mins @@ -608,18 +606,21 @@ describe('Integration | Transactions', () => { jest.advanceTimersByTime(1); // Old spans have been cleared away - expect(exporter['_finishedSpans'].length).toBe(0); + const finishedSpans2 = []; + exporter['_finishedSpanBuckets'].forEach((bucket: any) => { + if (bucket) { + finishedSpans2.push(...bucket.spans); + } + }); + expect(finishedSpans2.length).toBe(0); // Called once for the 'other span' expect(beforeSendTransaction).toHaveBeenCalledTimes(1); expect(logs).toEqual( expect.arrayContaining([ - 'SpanExporter has 1 unsent spans remaining', - 'SpanExporter has 2 unsent spans remaining', - 'SpanExporter exported 1 spans, 2 unsent spans remaining', - `SpanExporter dropping span inner span 1 (${innerSpan1Id}) because it is pending for more than 5 minutes.`, - `SpanExporter dropping span inner span 2 (${innerSpan2Id}) because it is pending for more than 5 minutes.`, + 'SpanExporter dropped 2 spans because they were pending for more than 300 seconds.', + 'SpanExporter exported 1 spans, 0 unsent spans remaining', ]), ); }); diff --git a/packages/node/test/integrations/contextlines.test.ts b/packages/node/test/integrations/contextlines.test.ts index 4c609b22a3f4..47827d8cfeb2 100644 --- a/packages/node/test/integrations/contextlines.test.ts +++ b/packages/node/test/integrations/contextlines.test.ts @@ -1,6 +1,6 @@ import * as fs from 'node:fs'; import { parseStackFrames } from '@sentry/core'; -import type { StackFrame } from '@sentry/types'; +import type { StackFrame } from '@sentry/core'; import { MAX_CONTEXTLINES_COLNO, diff --git a/packages/node/test/integrations/express.test.ts b/packages/node/test/integrations/express.test.ts index 3071dce968d5..417c3b783216 100644 --- a/packages/node/test/integrations/express.test.ts +++ b/packages/node/test/integrations/express.test.ts @@ -1,6 +1,6 @@ import * as http from 'http'; import { getCurrentScope, getIsolationScope, setAsyncContextStrategy, setCurrentClient, withScope } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; import { expressErrorHandler } from '../../src/integrations/tracing/express'; import { NodeClient } from '../../src/sdk/client'; import { getDefaultNodeClientOptions } from '../helpers/getDefaultNodeClientOptions'; diff --git a/packages/node/test/integrations/spotlight.test.ts b/packages/node/test/integrations/spotlight.test.ts index c78c81fdba14..fef4765c9b15 100644 --- a/packages/node/test/integrations/spotlight.test.ts +++ b/packages/node/test/integrations/spotlight.test.ts @@ -1,6 +1,6 @@ import * as http from 'http'; import { createEnvelope, logger } from '@sentry/core'; -import type { Envelope, EventEnvelope } from '@sentry/types'; +import type { Envelope, EventEnvelope } from '@sentry/core'; import { spotlightIntegration } from '../../src/integrations/spotlight'; import { NodeClient } from '../../src/sdk/client'; diff --git a/packages/node/test/sdk/api.test.ts b/packages/node/test/sdk/api.test.ts index e2699b4496f2..4b0ff80c4d5c 100644 --- a/packages/node/test/sdk/api.test.ts +++ b/packages/node/test/sdk/api.test.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { getActiveSpan, getClient, startInactiveSpan, startSpan, withActiveSpan } from '../../src'; import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit'; diff --git a/packages/node/test/sdk/client.test.ts b/packages/node/test/sdk/client.test.ts index 1aa4cf14fdff..5f351ff3e990 100644 --- a/packages/node/test/sdk/client.test.ts +++ b/packages/node/test/sdk/client.test.ts @@ -1,5 +1,6 @@ import * as os from 'os'; import { ProxyTracer } from '@opentelemetry/api'; +import * as opentelemetryInstrumentationPackage from '@opentelemetry/instrumentation'; import { SDK_VERSION, SessionFlusher, @@ -9,8 +10,8 @@ import { setCurrentClient, withIsolationScope, } from '@sentry/core'; -import type { Event, EventHint } from '@sentry/types'; -import type { Scope } from '@sentry/types'; +import type { Event, EventHint } from '@sentry/core'; +import type { Scope } from '@sentry/core'; import { setOpenTelemetryContextAsyncContextStrategy } from '@sentry/opentelemetry'; import { NodeClient, initOpenTelemetry } from '../../src'; @@ -495,6 +496,21 @@ describe('NodeClient', () => { expect(sendEnvelopeSpy).toHaveBeenCalledTimes(0); }); }); + + it('registers instrumentations provided with `openTelemetryInstrumentations`', () => { + const registerInstrumentationsSpy = jest + .spyOn(opentelemetryInstrumentationPackage, 'registerInstrumentations') + .mockImplementationOnce(() => () => undefined); + const instrumentationsArray = ['foobar'] as unknown as opentelemetryInstrumentationPackage.Instrumentation[]; + + new NodeClient(getDefaultNodeClientOptions({ openTelemetryInstrumentations: instrumentationsArray })); + + expect(registerInstrumentationsSpy).toHaveBeenCalledWith( + expect.objectContaining({ + instrumentations: instrumentationsArray, + }), + ); + }); }); describe('flush/close', () => { diff --git a/packages/node/test/sdk/init.test.ts b/packages/node/test/sdk/init.test.ts index 3444b6e43582..074de8296cd9 100644 --- a/packages/node/test/sdk/init.test.ts +++ b/packages/node/test/sdk/init.test.ts @@ -1,5 +1,5 @@ import { logger } from '@sentry/core'; -import type { Integration } from '@sentry/types'; +import type { Integration } from '@sentry/core'; import * as SentryOpentelemetry from '@sentry/opentelemetry'; import { getClient, getIsolationScope } from '../../src/'; diff --git a/packages/node/test/sdk/scope.test.ts b/packages/node/test/sdk/scope.test.ts index 5e84e412f912..f31c4ba4d663 100644 --- a/packages/node/test/sdk/scope.test.ts +++ b/packages/node/test/sdk/scope.test.ts @@ -1,5 +1,5 @@ import { Scope, getGlobalScope, prepareEvent } from '@sentry/core'; -import type { Attachment, Breadcrumb, Client, ClientOptions, EventProcessor } from '@sentry/types'; +import type { Attachment, Breadcrumb, Client, ClientOptions, EventProcessor } from '@sentry/core'; import { getIsolationScope } from '../../src'; import { mockSdkInit } from '../helpers/mockSdkInit'; diff --git a/packages/node/test/transports/http.test.ts b/packages/node/test/transports/http.test.ts index 445db5f14c95..40dd28e438f9 100644 --- a/packages/node/test/transports/http.test.ts +++ b/packages/node/test/transports/http.test.ts @@ -2,7 +2,7 @@ import * as http from 'http'; import { createGunzip } from 'zlib'; import { createTransport } from '@sentry/core'; import { addItemToEnvelope, createAttachmentEnvelopeItem, createEnvelope, serializeEnvelope } from '@sentry/core'; -import type { EventEnvelope, EventItem } from '@sentry/types'; +import type { EventEnvelope, EventItem } from '@sentry/core'; import { makeNodeTransport } from '../../src/transports'; diff --git a/packages/node/test/transports/https.test.ts b/packages/node/test/transports/https.test.ts index f907086698e1..06835f361e67 100644 --- a/packages/node/test/transports/https.test.ts +++ b/packages/node/test/transports/https.test.ts @@ -2,7 +2,7 @@ import * as http from 'http'; import * as https from 'https'; import { createTransport } from '@sentry/core'; import { createEnvelope, serializeEnvelope } from '@sentry/core'; -import type { EventEnvelope, EventItem } from '@sentry/types'; +import type { EventEnvelope, EventItem } from '@sentry/core'; import { makeNodeTransport } from '../../src/transports'; import type { HTTPModule, HTTPModuleRequestIncomingMessage } from '../../src/transports/http-module'; diff --git a/packages/node/test/utils/entry-point.test.ts b/packages/node/test/utils/entry-point.test.ts new file mode 100644 index 000000000000..5013482bca46 --- /dev/null +++ b/packages/node/test/utils/entry-point.test.ts @@ -0,0 +1,102 @@ +import type { ProcessArgs, ProcessInterface } from '../../src/utils/entry-point'; +import { getEntryPointType, parseProcessPaths } from '../../src/utils/entry-point'; + +const PROCESS_ARG_TESTS: [ProcessInterface, ProcessArgs][] = [ + [ + { cwd: () => '/user/tim/docs', argv: ['/bin/node', 'app.js'], execArgv: ['--import', './something.js'] }, + { appPath: '/user/tim/docs/app.js', importPaths: ['/user/tim/docs/something.js'], requirePaths: [] }, + ], + [ + { + cwd: () => '/user/tim/docs', + argv: ['/bin/node', 'app.js'], + execArgv: ['--import', './something.js', '--import=./else.js'], + }, + { + appPath: '/user/tim/docs/app.js', + importPaths: ['/user/tim/docs/something.js', '/user/tim/docs/else.js'], + requirePaths: [], + }, + ], + [ + { + cwd: () => '/user/tim/docs', + argv: ['/bin/node', 'app.js'], + execArgv: ['--require', './something.js', '--import=else.js'], + }, + { + appPath: '/user/tim/docs/app.js', + importPaths: ['/user/tim/docs/else.js'], + requirePaths: ['/user/tim/docs/something.js'], + }, + ], + [ + { + cwd: () => '/user/tim/docs', + argv: ['/bin/node', 'app.js'], + execArgv: ['--require=here/something.js'], + }, + { + appPath: '/user/tim/docs/app.js', + importPaths: [], + requirePaths: ['/user/tim/docs/here/something.js'], + }, + ], +]; + +describe('getEntryPointType', () => { + it.each(PROCESS_ARG_TESTS)('parseProcessArgs', (input, output) => { + const result = parseProcessPaths(input); + expect(result).toStrictEqual(output); + }); + + it('app absolute', () => { + const ctx = getEntryPointType({ + cwd: () => __dirname, + argv: ['/bin/node', __filename], + execArgv: [], + }); + + expect(ctx).toEqual('app'); + }); + + it('app relative', () => { + const ctx = getEntryPointType({ + cwd: () => __dirname, + argv: ['/bin/node', 'entry-point.test.ts'], + execArgv: [], + }); + + expect(ctx).toEqual('app'); + }); + + it('import absolute', () => { + const ctx = getEntryPointType({ + cwd: () => __dirname, + argv: ['/bin/node', 'app.ts'], + execArgv: ['--import', __filename], + }); + + expect(ctx).toEqual('import'); + }); + + it('import relative', () => { + const ctx = getEntryPointType({ + cwd: () => __dirname, + argv: ['/bin/node', 'app.ts'], + execArgv: ['--import', './entry-point.test.ts'], + }); + + expect(ctx).toEqual('import'); + }); + + it('require relative', () => { + const ctx = getEntryPointType({ + cwd: () => __dirname, + argv: ['/bin/node', 'app.ts'], + execArgv: ['--require', './entry-point.test.ts'], + }); + + expect(ctx).toEqual('require'); + }); +}); diff --git a/packages/node/tsconfig.json b/packages/node/tsconfig.json index 8f38d240197e..b9683a850600 100644 --- a/packages/node/tsconfig.json +++ b/packages/node/tsconfig.json @@ -4,7 +4,7 @@ "include": ["src/**/*"], "compilerOptions": { - "lib": ["es2018"], + "lib": ["es2018", "es2020.string"], "module": "Node16" } } diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index fe8477ca82dc..949680d467df 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nuxt", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Nuxt (EXPERIMENTAL)", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nuxt", @@ -39,18 +39,17 @@ "access": "public" }, "peerDependencies": { - "nuxt": "3.x" + "nuxt": ">=3.7.0 || 4.x" }, "dependencies": { "@nuxt/kit": "^3.13.2", - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/opentelemetry": "8.40.0", + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", + "@sentry/opentelemetry": "8.42.0", "@sentry/rollup-plugin": "2.22.6", - "@sentry/types": "8.40.0", "@sentry/vite-plugin": "2.22.6", - "@sentry/vue": "8.40.0" + "@sentry/vue": "8.42.0" }, "devDependencies": { "@nuxt/module-builder": "^0.8.4", diff --git a/packages/nuxt/src/client/index.ts b/packages/nuxt/src/client/index.ts index 849c305a22e3..d476348ed937 100644 --- a/packages/nuxt/src/client/index.ts +++ b/packages/nuxt/src/client/index.ts @@ -2,3 +2,4 @@ export * from '@sentry/vue'; export { init } from './sdk'; export { piniaIntegration } from './piniaIntegration'; +export { vueIntegration } from './vueIntegration'; diff --git a/packages/nuxt/src/client/piniaIntegration.ts b/packages/nuxt/src/client/piniaIntegration.ts index e5e838267363..b0a5936e9142 100644 --- a/packages/nuxt/src/client/piniaIntegration.ts +++ b/packages/nuxt/src/client/piniaIntegration.ts @@ -1,7 +1,5 @@ -import { defineIntegration } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; - -import { consoleSandbox } from '@sentry/core'; +import type { IntegrationFn } from '@sentry/core'; +import { consoleSandbox, defineIntegration } from '@sentry/core'; import { createSentryPiniaPlugin } from '@sentry/vue'; const INTEGRATION_NAME = 'Pinia'; diff --git a/packages/nuxt/src/client/sdk.ts b/packages/nuxt/src/client/sdk.ts index d7a59556e37f..45c02583cbfc 100644 --- a/packages/nuxt/src/client/sdk.ts +++ b/packages/nuxt/src/client/sdk.ts @@ -1,6 +1,6 @@ import { getDefaultIntegrations as getBrowserDefaultIntegrations, init as initBrowser } from '@sentry/browser'; import { applySdkMetadata } from '@sentry/core'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import type { SentryNuxtClientOptions } from '../common/types'; /** diff --git a/packages/nuxt/src/client/vueIntegration.ts b/packages/nuxt/src/client/vueIntegration.ts new file mode 100644 index 000000000000..77f1b7fb3d51 --- /dev/null +++ b/packages/nuxt/src/client/vueIntegration.ts @@ -0,0 +1,36 @@ +import { GLOBAL_OBJ, defineIntegration } from '@sentry/core'; +import type { VueIntegrationOptions } from '@sentry/vue'; + +type Options = Omit< + VueIntegrationOptions, + | 'app' + | 'Vue' + // TODO(v9): Should be removed from parent type so we can remove it here + | 'hooks' + // TODO(v9): Should be removed from parent type so we can remove it here + | 'timeout' + // TODO(v9): Should be removed from parent type so we can remove it here + | 'trackComponents' +>; + +// Since the options object needs to cross the boundary between some builds (i.e. the nuxt module build and our client +// SDK build) we cannot use a getter that is exported from here. Instead we'll pass the options object through a global +// to the module. +export type GlobalObjWithIntegrationOptions = { _sentryNuxtVueIntegrationOptions?: Options }; + +// The vue integration is actually set up in the Sentry Client Module. There it is set up as soon as the nuxt app object is available. +// However, we need to export the vueIntegration from the Client SDK. This means all this integration does is store away +// its options for the Sentry Client Module to pick them up when initializing the actual vueIntegration. + +/** + * Add additional error and span instrumentation specialized for Vue. + */ +export const vueIntegration = defineIntegration((options: Options = {}) => { + return { + // NOTE: This name is different from the original vueIntegration's name. + name: 'NuxtVueIntegration', + setup() { + (GLOBAL_OBJ as GlobalObjWithIntegrationOptions)._sentryNuxtVueIntegrationOptions = options; + }, + }; +}); diff --git a/packages/nuxt/src/index.types.ts b/packages/nuxt/src/index.types.ts index ceb6c7fc207c..fd4bd00856be 100644 --- a/packages/nuxt/src/index.types.ts +++ b/packages/nuxt/src/index.types.ts @@ -1,4 +1,4 @@ -import type { Client, Integration, Options, StackParser } from '@sentry/types'; +import type { Client, Integration, Options, StackParser } from '@sentry/core'; import type { SentryNuxtClientOptions } from './common/types'; import type * as clientSdk from './index.client'; import type * as serverSdk from './index.server'; diff --git a/packages/nuxt/src/module.ts b/packages/nuxt/src/module.ts index 5a684998da5a..bd6cb96122de 100644 --- a/packages/nuxt/src/module.ts +++ b/packages/nuxt/src/module.ts @@ -13,7 +13,7 @@ export default defineNuxtModule({ name: '@sentry/nuxt/module', configKey: 'sentry', compatibility: { - nuxt: '^3.0.0', + nuxt: '>=3.7.0', }, }, defaults: {}, diff --git a/packages/nuxt/src/runtime/plugins/sentry.client.ts b/packages/nuxt/src/runtime/plugins/sentry.client.ts index b89a2fa87a8d..39d62737f645 100644 --- a/packages/nuxt/src/runtime/plugins/sentry.client.ts +++ b/packages/nuxt/src/runtime/plugins/sentry.client.ts @@ -1,6 +1,7 @@ -import { getClient } from '@sentry/core'; +import { GLOBAL_OBJ, getClient } from '@sentry/core'; import { browserTracingIntegration, vueIntegration } from '@sentry/vue'; import { defineNuxtPlugin } from 'nuxt/app'; +import type { GlobalObjWithIntegrationOptions } from '../../client/vueIntegration'; import { reportNuxtError } from '../utils'; // --- Types are copied from @sentry/vue (so it does not need to be exported) --- @@ -53,7 +54,14 @@ export default defineNuxtPlugin({ // Adding the Vue integration without the Vue error handler // Nuxt is registering their own error handler, which is unset after hydration: https://github.com/nuxt/nuxt/blob/d3fdbcaac6cf66d21e25d259390d7824696f1a87/packages/nuxt/src/app/entry.ts#L64-L73 // We don't want to wrap the existing error handler, as it leads to a 500 error: https://github.com/getsentry/sentry-javascript/issues/12515 - sentryClient.addIntegration(vueIntegration({ app: vueApp, attachErrorHandler: false })); + sentryClient.addIntegration( + vueIntegration({ + // We pick up the options from the "fake" vueIntegration exported by the SDK. + ...(GLOBAL_OBJ as GlobalObjWithIntegrationOptions)._sentryNuxtVueIntegrationOptions, + app: vueApp, + attachErrorHandler: false, + }), + ); } }); diff --git a/packages/nuxt/src/runtime/utils.ts b/packages/nuxt/src/runtime/utils.ts index 54819fd9bd77..3041ad58956c 100644 --- a/packages/nuxt/src/runtime/utils.ts +++ b/packages/nuxt/src/runtime/utils.ts @@ -1,6 +1,5 @@ -import { captureException, getClient, getTraceMetaTags } from '@sentry/core'; -import { dropUndefinedKeys } from '@sentry/core'; -import type { ClientOptions, Context } from '@sentry/types'; +import type { ClientOptions, Context } from '@sentry/core'; +import { captureException, dropUndefinedKeys, getClient, getTraceMetaTags } from '@sentry/core'; import type { VueOptions } from '@sentry/vue/src/types'; import type { CapturedErrorContext } from 'nitropack'; import type { NuxtRenderHTMLContext } from 'nuxt/app'; diff --git a/packages/nuxt/src/server/sdk.ts b/packages/nuxt/src/server/sdk.ts index 6c4dd4712a1a..32d2b2bc6cac 100644 --- a/packages/nuxt/src/server/sdk.ts +++ b/packages/nuxt/src/server/sdk.ts @@ -1,12 +1,12 @@ -import { applySdkMetadata, flush, getGlobalScope } from '@sentry/core'; -import { logger, vercelWaitUntil } from '@sentry/core'; +import * as path from 'node:path'; +import type { Client, EventProcessor, Integration } from '@sentry/core'; +import { applySdkMetadata, flush, getGlobalScope, logger, vercelWaitUntil } from '@sentry/core'; import { type NodeOptions, getDefaultIntegrations as getDefaultNodeIntegrations, httpIntegration, init as initNode, } from '@sentry/node'; -import type { Client, EventProcessor, Integration } from '@sentry/types'; import { DEBUG_BUILD } from '../common/debug-build'; import type { SentryNuxtServerOptions } from '../common/types'; @@ -33,23 +33,26 @@ export function init(options: SentryNuxtServerOptions): Client | undefined { } /** - * Filter out transactions for Nuxt build assets - * This regex matches the default path to the nuxt-generated build assets (`_nuxt`). + * Filter out transactions for resource requests which we don't want to send to Sentry + * for quota reasons. * * Only exported for testing */ export function lowQualityTransactionsFilter(options: SentryNuxtServerOptions): EventProcessor { return Object.assign( (event => { - if (event.type === 'transaction' && event.transaction?.match(/^GET \/_nuxt\//)) { - // todo: the buildAssetDir could be changed in the nuxt config - change this to a more generic solution + if (event.type !== 'transaction' || !event.transaction) { + return event; + } + // We don't want to send transaction for file requests, so everything ending with a *.someExtension should be filtered out + // path.extname will return an empty string for normal page requests + if (path.extname(event.transaction)) { options.debug && DEBUG_BUILD && logger.log('NuxtLowQualityTransactionsFilter filtered transaction: ', event.transaction); return null; - } else { - return event; } + return event; }) satisfies EventProcessor, { id: 'NuxtLowQualityTransactionsFilter' }, ); @@ -100,9 +103,12 @@ export function mergeRegisterEsmLoaderHooks( ): SentryNuxtServerOptions['registerEsmLoaderHooks'] { if (typeof options.registerEsmLoaderHooks === 'object' && options.registerEsmLoaderHooks !== null) { return { + // eslint-disable-next-line deprecation/deprecation exclude: Array.isArray(options.registerEsmLoaderHooks.exclude) - ? [...options.registerEsmLoaderHooks.exclude, /vue/] - : options.registerEsmLoaderHooks.exclude ?? [/vue/], + ? // eslint-disable-next-line deprecation/deprecation + [...options.registerEsmLoaderHooks.exclude, /vue/] + : // eslint-disable-next-line deprecation/deprecation + options.registerEsmLoaderHooks.exclude ?? [/vue/], }; } return options.registerEsmLoaderHooks ?? { exclude: [/vue/] }; diff --git a/packages/nuxt/test/server/sdk.test.ts b/packages/nuxt/test/server/sdk.test.ts index 56888afc9a79..2d4679a27649 100644 --- a/packages/nuxt/test/server/sdk.test.ts +++ b/packages/nuxt/test/server/sdk.test.ts @@ -1,9 +1,9 @@ +import type { EventProcessor } from '@sentry/core'; import * as SentryNode from '@sentry/node'; import type { NodeClient } from '@sentry/node'; import { Scope } from '@sentry/node'; import { getGlobalScope } from '@sentry/node'; import { SDK_VERSION } from '@sentry/node'; -import type { EventProcessor } from '@sentry/types'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import type { SentryNuxtServerOptions } from '../../src/common/types'; import { init } from '../../src/server'; @@ -45,45 +45,39 @@ describe('Nuxt Server SDK', () => { expect(init({})).not.toBeUndefined(); }); - it('filters out low quality transactions', async () => { + describe('low quality transactions filter (%s)', () => { const beforeSendEvent = vi.fn(event => event); const client = init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', }) as NodeClient; client.on('beforeSendEvent', beforeSendEvent); - client.captureEvent({ type: 'transaction', transaction: 'GET /' }); - client.captureEvent({ type: 'transaction', transaction: 'GET /_nuxt/some_asset.js' }); - // Although this has the name of the build asset directory (_nuxt), it should not be filtered out as it would not match the regex - client.captureEvent({ type: 'transaction', transaction: 'GET _nuxt/some_asset.js' }); - client.captureEvent({ type: 'transaction', transaction: 'POST /_server' }); - - await client!.flush(); + it.each([ + [ + 'GET /_nuxt/some_asset.js', + 'GET _nuxt/some_asset.js', + 'GET /icons/favicon.ico', + 'GET /assets/logo.png', + 'GET /icons/zones/forest.svg', + ], + ])('filters out low quality transactions', async transaction => { + client.captureEvent({ type: 'transaction', transaction }); + await client!.flush(); + expect(beforeSendEvent).not.toHaveBeenCalled(); + }); - expect(beforeSendEvent).toHaveBeenCalledTimes(3); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET /', - }), - expect.any(Object), - ); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET _nuxt/some_asset.js', - }), - expect.any(Object), - ); - expect(beforeSendEvent).not.toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET /_nuxt/some_asset.js', - }), - expect.any(Object), - ); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'POST /_server', - }), - expect.any(Object), + it.each(['GET /', 'POST /_server'])( + 'does not filter out high quality or route transactions (%s)', + async transaction => { + client.captureEvent({ type: 'transaction', transaction }); + await client!.flush(); + expect(beforeSendEvent).toHaveBeenCalledWith( + expect.objectContaining({ + transaction, + }), + expect.any(Object), + ); + }, ); }); diff --git a/packages/opentelemetry/package.json b/packages/opentelemetry/package.json index 20759d16ee6f..167c3c0b2a5d 100644 --- a/packages/opentelemetry/package.json +++ b/packages/opentelemetry/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/opentelemetry", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry utilities for OpenTelemetry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/opentelemetry", @@ -39,8 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", diff --git a/packages/opentelemetry/src/asyncContextStrategy.ts b/packages/opentelemetry/src/asyncContextStrategy.ts index 31da9479921f..cfc4254819d7 100644 --- a/packages/opentelemetry/src/asyncContextStrategy.ts +++ b/packages/opentelemetry/src/asyncContextStrategy.ts @@ -1,8 +1,6 @@ import * as api from '@opentelemetry/api'; +import type { Scope, withActiveSpan as defaultWithActiveSpan } from '@sentry/core'; import { getDefaultCurrentScope, getDefaultIsolationScope, setAsyncContextStrategy } from '@sentry/core'; -import type { withActiveSpan as defaultWithActiveSpan } from '@sentry/core'; -import type { Scope } from '@sentry/types'; - import { SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY, SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY, diff --git a/packages/opentelemetry/src/constants.ts b/packages/opentelemetry/src/constants.ts index 0f056d09a4ea..22e3d01c46a8 100644 --- a/packages/opentelemetry/src/constants.ts +++ b/packages/opentelemetry/src/constants.ts @@ -4,7 +4,6 @@ export const SENTRY_TRACE_HEADER = 'sentry-trace'; export const SENTRY_BAGGAGE_HEADER = 'baggage'; export const SENTRY_TRACE_STATE_DSC = 'sentry.dsc'; -export const SENTRY_TRACE_STATE_PARENT_SPAN_ID = 'sentry.parent_span_id'; export const SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING = 'sentry.sampled_not_recording'; export const SENTRY_TRACE_STATE_URL = 'sentry.url'; diff --git a/packages/opentelemetry/src/contextManager.ts b/packages/opentelemetry/src/contextManager.ts index 27ef6e5d5cda..95154c929319 100644 --- a/packages/opentelemetry/src/contextManager.ts +++ b/packages/opentelemetry/src/contextManager.ts @@ -1,6 +1,6 @@ import type { Context, ContextManager } from '@opentelemetry/api'; import { getCurrentScope, getIsolationScope } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; import { SENTRY_FORK_ISOLATION_SCOPE_CONTEXT_KEY, diff --git a/packages/opentelemetry/src/custom/client.ts b/packages/opentelemetry/src/custom/client.ts index b10659bd488a..18ec73825f7c 100644 --- a/packages/opentelemetry/src/custom/client.ts +++ b/packages/opentelemetry/src/custom/client.ts @@ -1,10 +1,8 @@ import type { Tracer } from '@opentelemetry/api'; import { trace } from '@opentelemetry/api'; import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; -import type { BaseClient } from '@sentry/core'; +import type { BaseClient, Client } from '@sentry/core'; import { SDK_VERSION } from '@sentry/core'; -import type { Client } from '@sentry/types'; - import type { OpenTelemetryClient as OpenTelemetryClientInterface } from '../types'; // Typescript complains if we do not use `...args: any[]` for the mixin, with: diff --git a/packages/opentelemetry/src/index.ts b/packages/opentelemetry/src/index.ts index 98460b575c8d..30228d0dd763 100644 --- a/packages/opentelemetry/src/index.ts +++ b/packages/opentelemetry/src/index.ts @@ -24,10 +24,18 @@ export { getDynamicSamplingContextFromSpan } from '@sentry/core'; export { isSentryRequestSpan } from './utils/isSentryRequest'; export { enhanceDscWithOpenTelemetryRootSpanName } from './utils/enhanceDscWithOpenTelemetryRootSpanName'; +// eslint-disable-next-line deprecation/deprecation export { generateSpanContextForPropagationContext } from './utils/generateSpanContextForPropagationContext'; export { getActiveSpan } from './utils/getActiveSpan'; -export { startSpan, startSpanManual, startInactiveSpan, withActiveSpan, continueTrace } from './trace'; +export { + startSpan, + startSpanManual, + startInactiveSpan, + withActiveSpan, + continueTrace, + getTraceContextForScope, +} from './trace'; export { suppressTracing } from './utils/suppressTracing'; @@ -37,7 +45,11 @@ export { setupEventContextTrace } from './setupEventContextTrace'; export { setOpenTelemetryContextAsyncContextStrategy } from './asyncContextStrategy'; export { wrapContextManagerClass } from './contextManager'; -export { SentryPropagator, getPropagationContextFromSpan } from './propagator'; +export { + SentryPropagator, + getPropagationContextFromSpan, + shouldPropagateTraceForUrl, +} from './propagator'; export { SentrySpanProcessor } from './spanProcessor'; export { SentrySampler, @@ -46,6 +58,7 @@ export { export { openTelemetrySetupCheck } from './utils/setupCheck'; +// eslint-disable-next-line deprecation/deprecation export { addOpenTelemetryInstrumentation } from './instrumentation'; // Legacy diff --git a/packages/opentelemetry/src/instrumentation.ts b/packages/opentelemetry/src/instrumentation.ts index 8dd20eac7115..979282d0e467 100644 --- a/packages/opentelemetry/src/instrumentation.ts +++ b/packages/opentelemetry/src/instrumentation.ts @@ -4,6 +4,9 @@ import { registerInstrumentations } from '@opentelemetry/instrumentation'; /** * This method takes an OpenTelemetry instrumentation or * array of instrumentations and registers them with OpenTelemetry. + * + * @deprecated This method will be removed in the next major version of the SDK. + * Use the `openTelemetryInstrumentations` option in `Sentry.init()` or your custom Sentry Client instead. */ export function addOpenTelemetryInstrumentation(...instrumentations: Instrumentation[]): void { registerInstrumentations({ diff --git a/packages/opentelemetry/src/propagator.ts b/packages/opentelemetry/src/propagator.ts index 054a348fd7b5..09ba10a173a4 100644 --- a/packages/opentelemetry/src/propagator.ts +++ b/packages/opentelemetry/src/propagator.ts @@ -1,43 +1,38 @@ -import type { Baggage, Context, Span, TextMapGetter, TextMapSetter } from '@opentelemetry/api'; -import { INVALID_TRACEID } from '@opentelemetry/api'; -import { context } from '@opentelemetry/api'; -import { propagation, trace } from '@opentelemetry/api'; +import type { Baggage, Context, Span, SpanContext, TextMapGetter, TextMapSetter } from '@opentelemetry/api'; +import { INVALID_TRACEID, TraceFlags, context, propagation, trace } from '@opentelemetry/api'; import { W3CBaggagePropagator, isTracingSuppressed } from '@opentelemetry/core'; import { ATTR_URL_FULL, SEMATTRS_HTTP_URL } from '@opentelemetry/semantic-conventions'; -import type { continueTrace } from '@sentry/core'; -import { getRootSpan } from '@sentry/core'; -import { spanToJSON } from '@sentry/core'; -import { - getClient, - getCurrentScope, - getDynamicSamplingContextFromClient, - getDynamicSamplingContextFromSpan, - getIsolationScope, -} from '@sentry/core'; +import type { DynamicSamplingContext, Options, PropagationContext, continueTrace } from '@sentry/core'; import { LRUMap, SENTRY_BAGGAGE_KEY_PREFIX, baggageHeaderToDynamicSamplingContext, generateSentryTraceHeader, + generateSpanId, + getClient, + getCurrentScope, + getDynamicSamplingContextFromScope, + getDynamicSamplingContextFromSpan, + getIsolationScope, + getRootSpan, logger, parseBaggageHeader, propagationContextFromHeaders, + spanToJSON, stringMatchesSomePattern, } from '@sentry/core'; -import type { DynamicSamplingContext, Options, PropagationContext } from '@sentry/types'; - import { SENTRY_BAGGAGE_HEADER, SENTRY_TRACE_HEADER, SENTRY_TRACE_STATE_DSC, - SENTRY_TRACE_STATE_PARENT_SPAN_ID, SENTRY_TRACE_STATE_URL, } from './constants'; import { DEBUG_BUILD } from './debug-build'; import { getScopesFromContext, setScopesOnContext } from './utils/contextData'; -import { generateSpanContextForPropagationContext } from './utils/generateSpanContextForPropagationContext'; import { getSamplingDecision } from './utils/getSamplingDecision'; +import { makeTraceState } from './utils/makeTraceState'; import { setIsSetup } from './utils/setupCheck'; +import { spanHasParentId } from './utils/spanTypes'; /** Get the Sentry propagation context from a span context. */ export function getPropagationContextFromSpan(span: Span): PropagationContext { @@ -49,8 +44,7 @@ export function getPropagationContextFromSpan(span: Span): PropagationContext { const dscString = traceState ? traceState.get(SENTRY_TRACE_STATE_DSC) : undefined; const traceStateDsc = dscString ? baggageHeaderToDynamicSamplingContext(dscString) : undefined; - const parentSpanId = traceState ? traceState.get(SENTRY_TRACE_STATE_PARENT_SPAN_ID) || undefined : undefined; - + const parentSpanId = spanHasParentId(span) ? span.parentSpanId : undefined; const sampled = getSamplingDecision(spanContext); // No trace state? --> Take DSC from root span @@ -93,11 +87,7 @@ export class SentryPropagator extends W3CBaggagePropagator { const url = activeSpan && getCurrentURL(activeSpan); const tracePropagationTargets = getClient()?.getOptions()?.tracePropagationTargets; - if ( - typeof url === 'string' && - tracePropagationTargets && - !this._shouldInjectTraceData(tracePropagationTargets, url) - ) { + if (!shouldPropagateTraceForUrl(url, tracePropagationTargets, this._urlMatchesTargetsMap)) { DEBUG_BUILD && logger.log( '[Tracing] Not injecting trace data for url because it does not match tracePropagationTargets:', @@ -151,20 +141,9 @@ export class SentryPropagator extends W3CBaggagePropagator { : maybeSentryTraceHeader : undefined; - const propagationContext = propagationContextFromHeaders(sentryTrace, baggage); - // Add remote parent span context - const ctxWithSpanContext = getContextWithRemoteActiveSpan(context, { sentryTrace, baggage }); - - // Also update the scope on the context (to be sure this is picked up everywhere) - const scopes = getScopesFromContext(ctxWithSpanContext); - const newScopes = { - scope: scopes ? scopes.scope.clone() : getCurrentScope().clone(), - isolationScope: scopes ? scopes.isolationScope : getIsolationScope(), - }; - newScopes.scope.setPropagationContext(propagationContext); - - return setScopesOnContext(ctxWithSpanContext, newScopes); + // If there is no incoming trace, this will return the context as-is + return ensureScopesOnContext(getContextWithRemoteActiveSpan(context, { sentryTrace, baggage })); } /** @@ -173,39 +152,70 @@ export class SentryPropagator extends W3CBaggagePropagator { public fields(): string[] { return [SENTRY_TRACE_HEADER, SENTRY_BAGGAGE_HEADER]; } +} - /** If we want to inject trace data for a given URL. */ - private _shouldInjectTraceData(tracePropagationTargets: Options['tracePropagationTargets'], url: string): boolean { - if (tracePropagationTargets === undefined) { - return true; - } +const NOT_PROPAGATED_MESSAGE = + '[Tracing] Not injecting trace data for url because it does not match tracePropagationTargets:'; - const cachedDecision = this._urlMatchesTargetsMap.get(url); - if (cachedDecision !== undefined) { - return cachedDecision; - } +/** + * Check if a given URL should be propagated to or not. + * If no url is defined, or no trace propagation targets are defined, this will always return `true`. + * You can also optionally provide a decision map, to cache decisions and avoid repeated regex lookups. + */ +export function shouldPropagateTraceForUrl( + url: string | undefined, + tracePropagationTargets: Options['tracePropagationTargets'], + decisionMap?: LRUMap, +): boolean { + if (typeof url !== 'string' || !tracePropagationTargets) { + return true; + } - const decision = stringMatchesSomePattern(url, tracePropagationTargets); - this._urlMatchesTargetsMap.set(url, decision); - return decision; + const cachedDecision = decisionMap?.get(url); + if (cachedDecision !== undefined) { + DEBUG_BUILD && !cachedDecision && logger.log(NOT_PROPAGATED_MESSAGE, url); + return cachedDecision; } + + const decision = stringMatchesSomePattern(url, tracePropagationTargets); + decisionMap?.set(url, decision); + + DEBUG_BUILD && !decision && logger.log(NOT_PROPAGATED_MESSAGE, url); + return decision; } -function getInjectionData(context: Context): { +/** + * Get propagation injection data for the given context. + */ +export function getInjectionData(context: Context): { dynamicSamplingContext: Partial | undefined; traceId: string | undefined; spanId: string | undefined; sampled: boolean | undefined; } { const span = trace.getSpan(context); - const spanIsRemote = span?.spanContext().isRemote; - // If we have a local span, we can just pick everything from it - if (span && !spanIsRemote) { + // If we have a remote span, the spanId should be considered as the parentSpanId, not spanId itself + // Instead, we use a virtual (generated) spanId for propagation + if (span && span.spanContext().isRemote) { + const spanContext = span.spanContext(); + const dynamicSamplingContext = getDynamicSamplingContextFromSpan(span); + + return { + dynamicSamplingContext, + traceId: spanContext.traceId, + // Because this is a remote span, we do not want to propagate this directly + // As otherwise things may be attached "directly" to an unrelated span + spanId: generateSpanId(), + sampled: getSamplingDecision(spanContext), + }; + } + + // If we have a local span, we just use this + if (span) { const spanContext = span.spanContext(); + const dynamicSamplingContext = getDynamicSamplingContextFromSpan(span); - const propagationContext = getPropagationContextFromSpan(span); - const dynamicSamplingContext = getDynamicSamplingContext(propagationContext, spanContext.traceId); return { dynamicSamplingContext, traceId: spanContext.traceId, @@ -215,45 +225,43 @@ function getInjectionData(context: Context): { } // Else we try to use the propagation context from the scope + // The only scenario where this should happen is when we neither have a span, nor an incoming trace const scope = getScopesFromContext(context)?.scope || getCurrentScope(); + const client = getClient(); const propagationContext = scope.getPropagationContext(); - const dynamicSamplingContext = getDynamicSamplingContext(propagationContext, propagationContext.traceId); + const dynamicSamplingContext = client ? getDynamicSamplingContextFromScope(client, scope) : undefined; return { dynamicSamplingContext, traceId: propagationContext.traceId, + // TODO(v9): Use generateSpanId() instead + // eslint-disable-next-line deprecation/deprecation spanId: propagationContext.spanId, sampled: propagationContext.sampled, }; } -/** Get the DSC from a context, or fall back to use the one from the client. */ -function getDynamicSamplingContext( - propagationContext: PropagationContext, - traceId: string | undefined, -): Partial | undefined { - // If we have a DSC on the propagation context, we just use it - if (propagationContext?.dsc) { - return propagationContext.dsc; - } - - // Else, we try to generate a new one - const client = getClient(); - - if (client) { - return getDynamicSamplingContextFromClient(traceId || propagationContext.traceId, client); - } - - return undefined; -} - function getContextWithRemoteActiveSpan( ctx: Context, { sentryTrace, baggage }: Parameters[0], ): Context { const propagationContext = propagationContextFromHeaders(sentryTrace, baggage); - const spanContext = generateSpanContextForPropagationContext(propagationContext); + const { traceId, parentSpanId, sampled, dsc } = propagationContext; + + // We only want to set the virtual span if we are continuing a concrete trace + // Otherwise, we ignore the incoming trace here, e.g. if we have no trace headers + if (!parentSpanId) { + return ctx; + } + + const spanContext = generateRemoteSpanContext({ + traceId, + spanId: parentSpanId, + sampled, + dsc, + }); + return trace.setSpanContext(ctx, spanContext); } @@ -266,11 +274,24 @@ export function continueTraceAsRemoteSpan( options: Parameters[0], callback: () => T, ): T { - const ctxWithSpanContext = getContextWithRemoteActiveSpan(ctx, options); + const ctxWithSpanContext = ensureScopesOnContext(getContextWithRemoteActiveSpan(ctx, options)); return context.with(ctxWithSpanContext, callback); } +function ensureScopesOnContext(ctx: Context): Context { + // If there are no scopes yet on the context, ensure we have them + const scopes = getScopesFromContext(ctx); + const newScopes = { + // If we have no scope here, this is most likely either the root context or a context manually derived from it + // In this case, we want to fork the current scope, to ensure we do not pollute the root scope + scope: scopes ? scopes.scope : getCurrentScope().clone(), + isolationScope: scopes ? scopes.isolationScope : getIsolationScope(), + }; + + return setScopesOnContext(ctx, newScopes); +} + /** Try to get the existing baggage header so we can merge this in. */ function getExistingBaggage(carrier: unknown): string | undefined { try { @@ -307,3 +328,31 @@ function getCurrentURL(span: Span): string | undefined { return undefined; } + +function generateRemoteSpanContext({ + spanId, + traceId, + sampled, + dsc, +}: { + spanId: string; + traceId: string; + sampled: boolean | undefined; + dsc?: Partial; +}): SpanContext { + // We store the DSC as OTEL trace state on the span context + const traceState = makeTraceState({ + dsc, + sampled, + }); + + const spanContext: SpanContext = { + traceId, + spanId, + isRemote: true, + traceFlags: sampled ? TraceFlags.SAMPLED : TraceFlags.NONE, + traceState, + }; + + return spanContext; +} diff --git a/packages/opentelemetry/src/sampler.ts b/packages/opentelemetry/src/sampler.ts index b5cfc2ee5514..a561bb863561 100644 --- a/packages/opentelemetry/src/sampler.ts +++ b/packages/opentelemetry/src/sampler.ts @@ -1,25 +1,23 @@ import type { Attributes, Context, Span, TraceState as TraceStateInterface } from '@opentelemetry/api'; -import { SpanKind } from '@opentelemetry/api'; -import { isSpanContextValid, trace } from '@opentelemetry/api'; +import { SpanKind, isSpanContextValid, trace } from '@opentelemetry/api'; import { TraceState } from '@opentelemetry/core'; import type { Sampler, SamplingResult } from '@opentelemetry/sdk-trace-base'; import { SamplingDecision } from '@opentelemetry/sdk-trace-base'; +import { + ATTR_HTTP_REQUEST_METHOD, + ATTR_URL_FULL, + SEMATTRS_HTTP_METHOD, + SEMATTRS_HTTP_URL, +} from '@opentelemetry/semantic-conventions'; +import type { Client, SpanAttributes } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, hasTracingEnabled, + logger, sampleSpan, } from '@sentry/core'; -import { logger } from '@sentry/core'; -import type { Client, SpanAttributes } from '@sentry/types'; import { SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING, SENTRY_TRACE_STATE_URL } from './constants'; - -import { - ATTR_HTTP_REQUEST_METHOD, - ATTR_URL_FULL, - SEMATTRS_HTTP_METHOD, - SEMATTRS_HTTP_URL, -} from '@opentelemetry/semantic-conventions'; import { DEBUG_BUILD } from './debug-build'; import { getPropagationContextFromSpan } from './propagator'; import { getSamplingDecision } from './utils/getSamplingDecision'; @@ -48,7 +46,7 @@ export class SentrySampler implements Sampler { ): SamplingResult { const options = this._client.getOptions(); - const parentSpan = trace.getSpan(context); + const parentSpan = getValidSpan(context); const parentContext = parentSpan?.spanContext(); if (!hasTracingEnabled(options)) { @@ -210,3 +208,12 @@ function getBaseTraceState(context: Context, spanAttributes: SpanAttributes): Tr return traceState; } + +/** + * If the active span is invalid, we want to ignore it as parent. + * This aligns with how otel tracers and default samplers handle these cases. + */ +function getValidSpan(context: Context): Span | undefined { + const span = trace.getSpan(context); + return span && isSpanContextValid(span.spanContext()) ? span : undefined; +} diff --git a/packages/opentelemetry/src/setupEventContextTrace.ts b/packages/opentelemetry/src/setupEventContextTrace.ts index 051b1cba1364..1bf9bcb961be 100644 --- a/packages/opentelemetry/src/setupEventContextTrace.ts +++ b/packages/opentelemetry/src/setupEventContextTrace.ts @@ -1,9 +1,6 @@ -import { getDynamicSamplingContextFromSpan, getRootSpan } from '@sentry/core'; -import { dropUndefinedKeys } from '@sentry/core'; -import type { Client } from '@sentry/types'; -import { SENTRY_TRACE_STATE_PARENT_SPAN_ID } from './constants'; +import type { Client } from '@sentry/core'; +import { getDynamicSamplingContextFromSpan, getRootSpan, spanToTraceContext } from '@sentry/core'; import { getActiveSpan } from './utils/getActiveSpan'; -import { spanHasParentId } from './utils/spanTypes'; /** Ensure the `trace` context is set on all events. */ export function setupEventContextTrace(client: Client): void { @@ -15,25 +12,9 @@ export function setupEventContextTrace(client: Client): void { return; } - const spanContext = span.spanContext(); - - // If we have a parent span id from trace state, use that ('' means no parent should be used) - // Else, pick the one from the span - const parentSpanIdFromTraceState = spanContext.traceState?.get(SENTRY_TRACE_STATE_PARENT_SPAN_ID); - const parent_span_id = - typeof parentSpanIdFromTraceState === 'string' - ? parentSpanIdFromTraceState || undefined - : spanHasParentId(span) - ? span.parentSpanId - : undefined; - // If event has already set `trace` context, use that one. event.contexts = { - trace: dropUndefinedKeys({ - trace_id: spanContext.traceId, - span_id: spanContext.spanId, - parent_span_id, - }), + trace: spanToTraceContext(span), ...event.contexts, }; diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index 11d822f66ec1..ad044372e0df 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -2,31 +2,27 @@ import type { Span } from '@opentelemetry/api'; import { SpanKind } from '@opentelemetry/api'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import { ATTR_HTTP_RESPONSE_STATUS_CODE, SEMATTRS_HTTP_STATUS_CODE } from '@opentelemetry/semantic-conventions'; -import { - captureEvent, - getCapturedScopesOnSpan, - getDynamicSamplingContextFromSpan, - getMetricSummaryJsonForSpan, - timedEventsToMeasurements, -} from '@sentry/core'; +import type { SpanJSON, SpanOrigin, TraceContext, TransactionEvent, TransactionSource } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + captureEvent, + dropUndefinedKeys, + getCapturedScopesOnSpan, + getDynamicSamplingContextFromSpan, + getMetricSummaryJsonForSpan, getStatusMessage, + logger, spanTimeInputToSeconds, + timedEventsToMeasurements, } from '@sentry/core'; -import { dropUndefinedKeys, logger } from '@sentry/core'; -import type { SpanJSON, SpanOrigin, TraceContext, TransactionEvent, TransactionSource } from '@sentry/types'; -import { SENTRY_TRACE_STATE_PARENT_SPAN_ID } from './constants'; - import { DEBUG_BUILD } from './debug-build'; import { SEMANTIC_ATTRIBUTE_SENTRY_PARENT_IS_REMOTE } from './semanticAttributes'; import { getRequestSpanData } from './utils/getRequestSpanData'; import type { SpanNode } from './utils/groupSpansWithParents'; -import { getLocalParentId } from './utils/groupSpansWithParents'; -import { groupSpansWithParents } from './utils/groupSpansWithParents'; +import { getLocalParentId, groupSpansWithParents } from './utils/groupSpansWithParents'; import { mapStatus } from './utils/mapStatus'; import { parseSpanDescription } from './utils/parseSpanDescription'; @@ -35,60 +31,121 @@ type SpanNodeCompleted = SpanNode & { span: ReadableSpan }; const MAX_SPAN_COUNT = 1000; const DEFAULT_TIMEOUT = 300; // 5 min +interface FinishedSpanBucket { + timestampInS: number; + spans: Set; +} + /** * A Sentry-specific exporter that converts OpenTelemetry Spans to Sentry Spans & Transactions. */ export class SentrySpanExporter { private _flushTimeout: ReturnType | undefined; - private _finishedSpans: ReadableSpan[]; - private _timeout: number; - public constructor(options?: { timeout?: number }) { - this._finishedSpans = []; - this._timeout = options?.timeout || DEFAULT_TIMEOUT; + /* + * A quick explanation on the buckets: We do bucketing of finished spans for efficiency. This span exporter is + * accumulating spans until a root span is encountered and then it flushes all the spans that are descendants of that + * root span. Because it is totally in the realm of possibilities that root spans are never finished, and we don't + * want to accumulate spans indefinitely in memory, we need to periodically evacuate spans. Naively we could simply + * store the spans in an array and each time a new span comes in we could iterate through the entire array and + * evacuate all spans that have an end-timestamp that is older than our limit. This could get quite expensive because + * we would have to iterate a potentially large number of spans every time we evacuate. We want to avoid these large + * bursts of computation. + * + * Instead we go for a bucketing approach and put spans into buckets, based on what second + * (modulo the time limit) the span was put into the exporter. With buckets, when we decide to evacuate, we can + * iterate through the bucket entries instead, which have an upper bound of items, making the evacuation much more + * efficient. Cleaning up also becomes much more efficient since it simply involves de-referencing a bucket within the + * bucket array, and letting garbage collection take care of the rest. + */ + private _finishedSpanBuckets: (FinishedSpanBucket | undefined)[]; + private _finishedSpanBucketSize: number; + private _spansToBucketEntry: WeakMap; + private _lastCleanupTimestampInS: number; + + public constructor(options?: { + /** Lower bound of time in seconds until spans that are buffered but have not been sent as part of a transaction get cleared from memory. */ + timeout?: number; + }) { + this._finishedSpanBucketSize = options?.timeout || DEFAULT_TIMEOUT; + this._finishedSpanBuckets = new Array(this._finishedSpanBucketSize).fill(undefined); + this._lastCleanupTimestampInS = Math.floor(Date.now() / 1000); + this._spansToBucketEntry = new WeakMap(); } /** Export a single span. */ public export(span: ReadableSpan): void { - this._finishedSpans.push(span); - - // If the span has a local parent ID, we don't need to export anything just yet - if (getLocalParentId(span)) { - const openSpanCount = this._finishedSpans.length; - DEBUG_BUILD && logger.log(`SpanExporter has ${openSpanCount} unsent spans remaining`); - this._cleanupOldSpans(); - return; + const currentTimestampInS = Math.floor(Date.now() / 1000); + + if (this._lastCleanupTimestampInS !== currentTimestampInS) { + let droppedSpanCount = 0; + this._finishedSpanBuckets.forEach((bucket, i) => { + if (bucket && bucket.timestampInS <= currentTimestampInS - this._finishedSpanBucketSize) { + droppedSpanCount += bucket.spans.size; + this._finishedSpanBuckets[i] = undefined; + } + }); + if (droppedSpanCount > 0) { + DEBUG_BUILD && + logger.log( + `SpanExporter dropped ${droppedSpanCount} spans because they were pending for more than ${this._finishedSpanBucketSize} seconds.`, + ); + } + this._lastCleanupTimestampInS = currentTimestampInS; } - this._clearTimeout(); - - // If we got a parent span, we try to send the span tree - // Wait a tick for this, to ensure we avoid race conditions - this._flushTimeout = setTimeout(() => { - this.flush(); - }, 1); + const currentBucketIndex = currentTimestampInS % this._finishedSpanBucketSize; + const currentBucket = this._finishedSpanBuckets[currentBucketIndex] || { + timestampInS: currentTimestampInS, + spans: new Set(), + }; + this._finishedSpanBuckets[currentBucketIndex] = currentBucket; + currentBucket.spans.add(span); + this._spansToBucketEntry.set(span, currentBucket); + + // If the span doesn't have a local parent ID (it's a root span), we're gonna flush all the ended spans + if (!getLocalParentId(span)) { + this._clearTimeout(); + + // If we got a parent span, we try to send the span tree + // Wait a tick for this, to ensure we avoid race conditions + this._flushTimeout = setTimeout(() => { + this.flush(); + }, 1); + } } /** Try to flush any pending spans immediately. */ public flush(): void { this._clearTimeout(); - const openSpanCount = this._finishedSpans.length; + const finishedSpans: ReadableSpan[] = []; + this._finishedSpanBuckets.forEach(bucket => { + if (bucket) { + finishedSpans.push(...bucket.spans); + } + }); + + const sentSpans = maybeSend(finishedSpans); - const remainingSpans = maybeSend(this._finishedSpans); + const sentSpanCount = sentSpans.size; - const remainingOpenSpanCount = remainingSpans.length; - const sentSpanCount = openSpanCount - remainingOpenSpanCount; + const remainingOpenSpanCount = finishedSpans.length - sentSpanCount; DEBUG_BUILD && logger.log(`SpanExporter exported ${sentSpanCount} spans, ${remainingOpenSpanCount} unsent spans remaining`); - this._cleanupOldSpans(remainingSpans); + sentSpans.forEach(span => { + const bucketEntry = this._spansToBucketEntry.get(span); + if (bucketEntry) { + bucketEntry.spans.delete(span); + } + }); } /** Clear the exporter. */ public clear(): void { - this._finishedSpans = []; + this._finishedSpanBuckets = this._finishedSpanBuckets.fill(undefined); this._clearTimeout(); } @@ -99,52 +156,33 @@ export class SentrySpanExporter { this._flushTimeout = undefined; } } - - /** - * Remove any span that is older than 5min. - * We do this to avoid leaking memory. - */ - private _cleanupOldSpans(spans = this._finishedSpans): void { - const currentTimeSeconds = Date.now() / 1000; - this._finishedSpans = spans.filter(span => { - const shouldDrop = shouldCleanupSpan(span, currentTimeSeconds, this._timeout); - DEBUG_BUILD && - shouldDrop && - logger.log( - `SpanExporter dropping span ${span.name} (${ - span.spanContext().spanId - }) because it is pending for more than 5 minutes.`, - ); - return !shouldDrop; - }); - } } /** * Send the given spans, but only if they are part of a finished transaction. * - * Returns the unsent spans. + * Returns the sent spans. * Spans remain unsent when their parent span is not yet finished. * This will happen regularly, as child spans are generally finished before their parents. * But it _could_ also happen because, for whatever reason, a parent span was lost. * In this case, we'll eventually need to clean this up. */ -function maybeSend(spans: ReadableSpan[]): ReadableSpan[] { +function maybeSend(spans: ReadableSpan[]): Set { const grouped = groupSpansWithParents(spans); - const remaining = new Set(grouped); + const sentSpans = new Set(); const rootNodes = getCompletedRootNodes(grouped); rootNodes.forEach(root => { - remaining.delete(root); const span = root.span; + sentSpans.add(span); const transactionEvent = createTransactionForOtelSpan(span); // We'll recursively add all the child spans to this array const spans = transactionEvent.spans || []; root.children.forEach(child => { - createAndFinishSpanForOtelSpan(child, spans, remaining); + createAndFinishSpanForOtelSpan(child, spans, sentSpans); }); // spans.sort() mutates the array, but we do not use this anymore after this point @@ -162,9 +200,7 @@ function maybeSend(spans: ReadableSpan[]): ReadableSpan[] { captureEvent(transactionEvent); }); - return Array.from(remaining) - .map(node => node.span) - .filter((span): span is ReadableSpan => !!span); + return sentSpans; } function nodeIsCompletedRootNode(node: SpanNode): node is SpanNodeCompleted { @@ -175,11 +211,6 @@ function getCompletedRootNodes(nodes: SpanNode[]): SpanNodeCompleted[] { return nodes.filter(nodeIsCompletedRootNode); } -function shouldCleanupSpan(span: ReadableSpan, currentTimeSeconds: number, maxStartTimeOffsetSeconds: number): boolean { - const cutoff = currentTimeSeconds - maxStartTimeOffsetSeconds; - return spanTimeInputToSeconds(span.startTime) < cutoff; -} - function parseSpan(span: ReadableSpan): { op?: string; origin?: SpanOrigin; source?: TransactionSource } { const attributes = span.attributes; @@ -207,15 +238,12 @@ function createTransactionForOtelSpan(span: ReadableSpan): TransactionEvent { const { traceId: trace_id, spanId: span_id } = span.spanContext(); - const parentSpanIdFromTraceState = span.spanContext().traceState?.get(SENTRY_TRACE_STATE_PARENT_SPAN_ID); - // If parentSpanIdFromTraceState is defined at all, we want it to take precedence // In that case, an empty string should be interpreted as "no parent span id", // even if `span.parentSpanId` is set // this is the case when we are starting a new trace, where we have a virtual span based on the propagationContext // We only want to continue the traceId in this case, but ignore the parent span - const parent_span_id = - typeof parentSpanIdFromTraceState === 'string' ? parentSpanIdFromTraceState || undefined : span.parentSpanId; + const parent_span_id = span.parentSpanId; const status = mapStatus(span); @@ -260,16 +288,19 @@ function createTransactionForOtelSpan(span: ReadableSpan): TransactionEvent { return transactionEvent; } -function createAndFinishSpanForOtelSpan(node: SpanNode, spans: SpanJSON[], remaining: Set): void { - remaining.delete(node); +function createAndFinishSpanForOtelSpan(node: SpanNode, spans: SpanJSON[], sentSpans: Set): void { const span = node.span; + if (span) { + sentSpans.add(span); + } + const shouldDrop = !span; // If this span should be dropped, we still want to create spans for the children of this if (shouldDrop) { node.children.forEach(child => { - createAndFinishSpanForOtelSpan(child, spans, remaining); + createAndFinishSpanForOtelSpan(child, spans, sentSpans); }); return; } @@ -308,7 +339,7 @@ function createAndFinishSpanForOtelSpan(node: SpanNode, spans: SpanJSON[], remai spans.push(spanJSON); node.children.forEach(child => { - createAndFinishSpanForOtelSpan(child, spans, remaining); + createAndFinishSpanForOtelSpan(child, spans, sentSpans); }); } diff --git a/packages/opentelemetry/src/trace.ts b/packages/opentelemetry/src/trace.ts index 1ed0fa6a1322..e1f082c1d424 100644 --- a/packages/opentelemetry/src/trace.ts +++ b/packages/opentelemetry/src/trace.ts @@ -1,22 +1,24 @@ import type { Context, Span, SpanContext, SpanOptions, Tracer } from '@opentelemetry/api'; -import { INVALID_SPANID, SpanStatusCode, TraceFlags, context, trace } from '@opentelemetry/api'; +import { SpanStatusCode, TraceFlags, context, trace } from '@opentelemetry/api'; import { suppressTracing } from '@opentelemetry/core'; +import type { Client, DynamicSamplingContext, Scope, Span as SentrySpan, TraceContext } from '@sentry/core'; import { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, continueTrace as baseContinueTrace, getClient, getCurrentScope, + getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan, getRootSpan, + getTraceContextFromScope, handleCallbackErrors, spanToJSON, + spanToTraceContext, } from '@sentry/core'; -import type { Client, Scope, Span as SentrySpan } from '@sentry/types'; import { continueTraceAsRemoteSpan } from './propagator'; - import type { OpenTelemetryClient, OpenTelemetrySpanContext } from './types'; -import { getContextFromScope, getScopesFromContext } from './utils/contextData'; +import { getContextFromScope } from './utils/contextData'; import { getSamplingDecision } from './utils/getSamplingDecision'; import { makeTraceState } from './utils/makeTraceState'; @@ -176,39 +178,11 @@ function ensureTimestampInMilliseconds(timestamp: number): number { function getContext(scope: Scope | undefined, forceTransaction: boolean | undefined): Context { const ctx = getContextForScope(scope); - // Note: If the context is the ROOT_CONTEXT, no scope is attached - // Thus we will not use the propagation context in this case, which is desired - const actualScope = getScopesFromContext(ctx)?.scope; const parentSpan = trace.getSpan(ctx); - // In the case that we have no parent span, we need to "simulate" one to ensure the propagation context is correct + // In the case that we have no parent span, we start a new trace + // Note that if we continue a trace, we'll always have a remote parent span here anyhow if (!parentSpan) { - const client = getClient(); - - if (actualScope && client) { - const propagationContext = actualScope.getPropagationContext(); - - // We store the DSC as OTEL trace state on the span context - const traceState = makeTraceState({ - parentSpanId: propagationContext.parentSpanId, - // Not defined yet, we want to pick this up on-demand only - dsc: undefined, - sampled: propagationContext.sampled, - }); - - const spanOptions: SpanContext = { - traceId: propagationContext.traceId, - spanId: propagationContext.parentSpanId || propagationContext.spanId, - isRemote: true, - traceFlags: propagationContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE, - traceState, - }; - - // Add remote parent span context, - return trace.setSpanContext(ctx, spanOptions); - } - - // if we have no scope or client, we just return the context as-is return ctx; } @@ -234,7 +208,6 @@ function getContext(scope: Scope | undefined, forceTransaction: boolean | undefi const traceState = makeTraceState({ dsc, - parentSpanId: spanId !== INVALID_SPANID ? spanId : undefined, sampled, }); @@ -279,6 +252,25 @@ export function continueTrace(options: Parameters[0 }); } +/** + * Get the trace context for a given scope. + * We have a custom implemention here because we need an OTEL-specific way to get the span from a scope. + */ +export function getTraceContextForScope( + client: Client, + scope: Scope, +): [dynamicSamplingContext: Partial, traceContext: TraceContext] { + const ctx = getContextFromScope(scope); + const span = ctx && trace.getSpan(ctx); + + const traceContext = span ? spanToTraceContext(span) : getTraceContextFromScope(scope); + + const dynamicSamplingContext = span + ? getDynamicSamplingContextFromSpan(span) + : getDynamicSamplingContextFromScope(client, scope); + return [dynamicSamplingContext, traceContext]; +} + function getActiveSpanWrapper(parentSpan: Span | SentrySpan | undefined | null): (callback: () => T) => T { return parentSpan !== undefined ? (callback: () => T) => { diff --git a/packages/opentelemetry/src/types.ts b/packages/opentelemetry/src/types.ts index 341fbea88d38..807e9b1d857f 100644 --- a/packages/opentelemetry/src/types.ts +++ b/packages/opentelemetry/src/types.ts @@ -1,6 +1,6 @@ import type { Span as WriteableSpan, SpanKind, Tracer } from '@opentelemetry/api'; import type { BasicTracerProvider, ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import type { Scope, Span, StartSpanOptions } from '@sentry/types'; +import type { Scope, Span, StartSpanOptions } from '@sentry/core'; export interface OpenTelemetryClient { tracer: Tracer; diff --git a/packages/opentelemetry/src/utils/addOriginToSpan.ts b/packages/opentelemetry/src/utils/addOriginToSpan.ts index 9d2acfcd83b2..22ed30ed37e0 100644 --- a/packages/opentelemetry/src/utils/addOriginToSpan.ts +++ b/packages/opentelemetry/src/utils/addOriginToSpan.ts @@ -1,6 +1,6 @@ import type { Span } from '@opentelemetry/api'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; -import type { SpanOrigin } from '@sentry/types'; +import type { SpanOrigin } from '@sentry/core'; /** Adds an origin to an OTEL Span. */ export function addOriginToSpan(span: Span, origin: SpanOrigin): void { diff --git a/packages/opentelemetry/src/utils/contextData.ts b/packages/opentelemetry/src/utils/contextData.ts index e91b91ffe223..389520ef5293 100644 --- a/packages/opentelemetry/src/utils/contextData.ts +++ b/packages/opentelemetry/src/utils/contextData.ts @@ -1,7 +1,6 @@ import type { Context } from '@opentelemetry/api'; +import type { Scope } from '@sentry/core'; import { addNonEnumerableProperty } from '@sentry/core'; -import type { Scope } from '@sentry/types'; - import { SENTRY_SCOPES_CONTEXT_KEY } from '../constants'; import type { CurrentScopes } from '../types'; diff --git a/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts b/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts index af086451ac1b..4aa9ecfdb8b6 100644 --- a/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts +++ b/packages/opentelemetry/src/utils/enhanceDscWithOpenTelemetryRootSpanName.ts @@ -1,5 +1,6 @@ -import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, spanToJSON } from '@sentry/core'; -import type { Client } from '@sentry/types'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, hasTracingEnabled, spanToJSON } from '@sentry/core'; +import type { Client } from '@sentry/core'; +import { getSamplingDecision } from './getSamplingDecision'; import { parseSpanDescription } from './parseSpanDescription'; import { spanHasName } from './spanTypes'; @@ -9,20 +10,31 @@ import { spanHasName } from './spanTypes'; */ export function enhanceDscWithOpenTelemetryRootSpanName(client: Client): void { client.on('createDsc', (dsc, rootSpan) => { + if (!rootSpan) { + return; + } + // We want to overwrite the transaction on the DSC that is created by default in core // The reason for this is that we want to infer the span name, not use the initial one // Otherwise, we'll get names like "GET" instead of e.g. "GET /foo" // `parseSpanDescription` takes the attributes of the span into account for the name // This mutates the passed-in DSC - if (rootSpan) { - const jsonSpan = spanToJSON(rootSpan); - const attributes = jsonSpan.data || {}; - const source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]; - const { description } = spanHasName(rootSpan) ? parseSpanDescription(rootSpan) : { description: undefined }; - if (source !== 'url' && description) { - dsc.transaction = description; - } + const jsonSpan = spanToJSON(rootSpan); + const attributes = jsonSpan.data || {}; + const source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]; + + const { description } = spanHasName(rootSpan) ? parseSpanDescription(rootSpan) : { description: undefined }; + if (source !== 'url' && description) { + dsc.transaction = description; + } + + // Also ensure sampling decision is correctly inferred + // In core, we use `spanIsSampled`, which just looks at the trace flags + // but in OTEL, we use a slightly more complex logic to be able to differntiate between unsampled and deferred sampling + if (hasTracingEnabled()) { + const sampled = getSamplingDecision(rootSpan.spanContext()); + dsc.sampled = sampled == undefined ? undefined : String(sampled); } }); } diff --git a/packages/opentelemetry/src/utils/generateSpanContextForPropagationContext.ts b/packages/opentelemetry/src/utils/generateSpanContextForPropagationContext.ts index d2aa470213f7..bf0af49b1200 100644 --- a/packages/opentelemetry/src/utils/generateSpanContextForPropagationContext.ts +++ b/packages/opentelemetry/src/utils/generateSpanContextForPropagationContext.ts @@ -1,22 +1,24 @@ import type { SpanContext } from '@opentelemetry/api'; import { TraceFlags } from '@opentelemetry/api'; -import type { PropagationContext } from '@sentry/types'; +import type { PropagationContext } from '@sentry/core'; import { makeTraceState } from './makeTraceState'; /** * Generates a SpanContext that represents a PropagationContext. * This can be set on a `context` to make this a (virtual) active span. + * + * @deprecated This function is deprecated and will be removed in the next major version. */ export function generateSpanContextForPropagationContext(propagationContext: PropagationContext): SpanContext { // We store the DSC as OTEL trace state on the span context const traceState = makeTraceState({ - parentSpanId: propagationContext.parentSpanId, dsc: propagationContext.dsc, sampled: propagationContext.sampled, }); const spanContext: SpanContext = { traceId: propagationContext.traceId, + // TODO: Do not create an invalid span context here spanId: propagationContext.parentSpanId || '', isRemote: true, traceFlags: propagationContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE, diff --git a/packages/opentelemetry/src/utils/getRequestSpanData.ts b/packages/opentelemetry/src/utils/getRequestSpanData.ts index 1ba4e374fc6c..cc27aadf7a78 100644 --- a/packages/opentelemetry/src/utils/getRequestSpanData.ts +++ b/packages/opentelemetry/src/utils/getRequestSpanData.ts @@ -7,7 +7,7 @@ import { SEMATTRS_HTTP_URL, } from '@opentelemetry/semantic-conventions'; import { getSanitizedUrlString, parseUrl } from '@sentry/core'; -import type { SanitizedRequestData } from '@sentry/types'; +import type { SanitizedRequestData } from '@sentry/core'; import { spanHasAttributes } from './spanTypes'; diff --git a/packages/opentelemetry/src/utils/getTraceData.ts b/packages/opentelemetry/src/utils/getTraceData.ts index 8d91c74bd294..1134a9e70f34 100644 --- a/packages/opentelemetry/src/utils/getTraceData.ts +++ b/packages/opentelemetry/src/utils/getTraceData.ts @@ -1,22 +1,30 @@ import * as api from '@opentelemetry/api'; -import { dropUndefinedKeys } from '@sentry/core'; -import type { SerializedTraceData } from '@sentry/types'; +import { + dynamicSamplingContextToSentryBaggageHeader, + generateSentryTraceHeader, + getCapturedScopesOnSpan, +} from '@sentry/core'; +import type { SerializedTraceData, Span } from '@sentry/core'; +import { getInjectionData } from '../propagator'; +import { getContextFromScope } from './contextData'; /** * Otel-specific implementation of `getTraceData`. * @see `@sentry/core` version of `getTraceData` for more information */ -export function getTraceData(): SerializedTraceData { - const headersObject: Record = {}; +export function getTraceData({ span }: { span?: Span } = {}): SerializedTraceData { + let ctx = api.context.active(); - api.propagation.inject(api.context.active(), headersObject); - - if (!headersObject['sentry-trace']) { - return {}; + if (span) { + const { scope } = getCapturedScopesOnSpan(span); + // fall back to current context if for whatever reason we can't find the one of the span + ctx = (scope && getContextFromScope(scope)) || api.trace.setSpan(api.context.active(), span); } - return dropUndefinedKeys({ - 'sentry-trace': headersObject['sentry-trace'], - baggage: headersObject.baggage, - }); + const { traceId, spanId, sampled, dynamicSamplingContext } = getInjectionData(ctx); + + return { + 'sentry-trace': generateSentryTraceHeader(traceId, spanId, sampled), + baggage: dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext), + }; } diff --git a/packages/opentelemetry/src/utils/makeTraceState.ts b/packages/opentelemetry/src/utils/makeTraceState.ts index e292274cade0..c232c981bb41 100644 --- a/packages/opentelemetry/src/utils/makeTraceState.ts +++ b/packages/opentelemetry/src/utils/makeTraceState.ts @@ -1,32 +1,22 @@ import { TraceState } from '@opentelemetry/core'; import { dynamicSamplingContextToSentryBaggageHeader } from '@sentry/core'; -import type { DynamicSamplingContext } from '@sentry/types'; -import { - SENTRY_TRACE_STATE_DSC, - SENTRY_TRACE_STATE_PARENT_SPAN_ID, - SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING, -} from '../constants'; +import type { DynamicSamplingContext } from '@sentry/core'; +import { SENTRY_TRACE_STATE_DSC, SENTRY_TRACE_STATE_SAMPLED_NOT_RECORDING } from '../constants'; /** * Generate a TraceState for the given data. */ export function makeTraceState({ - parentSpanId, dsc, sampled, }: { - parentSpanId?: string; dsc?: Partial; sampled?: boolean; }): TraceState { // We store the DSC as OTEL trace state on the span context const dscString = dsc ? dynamicSamplingContextToSentryBaggageHeader(dsc) : undefined; - // We _always_ set the parent span ID, even if it is empty - // If we'd set this to 'undefined' we could not know if the trace state was set, but there was no parentSpanId, - // vs the trace state was not set at all (in which case we want to do fallback handling) - // If `''`, it should be considered "no parent" - const traceStateBase = new TraceState().set(SENTRY_TRACE_STATE_PARENT_SPAN_ID, parentSpanId || ''); + const traceStateBase = new TraceState(); const traceStateWithDsc = dscString ? traceStateBase.set(SENTRY_TRACE_STATE_DSC, dscString) : traceStateBase; diff --git a/packages/opentelemetry/src/utils/mapStatus.ts b/packages/opentelemetry/src/utils/mapStatus.ts index a3db71a60c00..e3a9b375be6b 100644 --- a/packages/opentelemetry/src/utils/mapStatus.ts +++ b/packages/opentelemetry/src/utils/mapStatus.ts @@ -5,7 +5,7 @@ import { SEMATTRS_RPC_GRPC_STATUS_CODE, } from '@opentelemetry/semantic-conventions'; import { SPAN_STATUS_ERROR, SPAN_STATUS_OK, getSpanStatusFromHttpCode } from '@sentry/core'; -import type { SpanAttributes, SpanStatus } from '@sentry/types'; +import type { SpanAttributes, SpanStatus } from '@sentry/core'; import type { AbstractSpan } from '../types'; import { spanHasAttributes, spanHasStatus } from './spanTypes'; diff --git a/packages/opentelemetry/src/utils/parseSpanDescription.ts b/packages/opentelemetry/src/utils/parseSpanDescription.ts index aff1fc5e2d69..a1aa47e5b6ce 100644 --- a/packages/opentelemetry/src/utils/parseSpanDescription.ts +++ b/packages/opentelemetry/src/utils/parseSpanDescription.ts @@ -13,10 +13,14 @@ import { SEMATTRS_MESSAGING_SYSTEM, SEMATTRS_RPC_SERVICE, } from '@opentelemetry/semantic-conventions'; -import { getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment } from '@sentry/core'; -import type { SpanAttributes, TransactionSource } from '@sentry/types'; - -import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; +import type { SpanAttributes, TransactionSource } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + getSanitizedUrlString, + parseUrl, + stripUrlQueryAndFragment, +} from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_GRAPHQL_OPERATION } from '../semanticAttributes'; import type { AbstractSpan } from '../types'; import { getSpanKind } from './getSpanKind'; diff --git a/packages/opentelemetry/test/asyncContextStrategy.test.ts b/packages/opentelemetry/test/asyncContextStrategy.test.ts index 915d33671e68..d0c4c137c236 100644 --- a/packages/opentelemetry/test/asyncContextStrategy.test.ts +++ b/packages/opentelemetry/test/asyncContextStrategy.test.ts @@ -8,7 +8,7 @@ import { withScope, } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; import { setOpenTelemetryContextAsyncContextStrategy } from '../src/asyncContextStrategy'; import { TestClient, getDefaultTestClientOptions } from './helpers/TestClient'; import { setupOtel } from './helpers/initOtel'; diff --git a/packages/opentelemetry/test/helpers/TestClient.ts b/packages/opentelemetry/test/helpers/TestClient.ts index 18a169c0a817..54d4ec488cef 100644 --- a/packages/opentelemetry/test/helpers/TestClient.ts +++ b/packages/opentelemetry/test/helpers/TestClient.ts @@ -1,6 +1,6 @@ import { BaseClient, createTransport, getCurrentScope } from '@sentry/core'; import { resolvedSyncPromise } from '@sentry/core'; -import type { Client, ClientOptions, Event, Options, SeverityLevel } from '@sentry/types'; +import type { Client, ClientOptions, Event, Options, SeverityLevel } from '@sentry/core'; import { wrapClientClass } from '../../src/custom/client'; import type { OpenTelemetryClient } from '../../src/types'; diff --git a/packages/opentelemetry/test/helpers/initOtel.ts b/packages/opentelemetry/test/helpers/initOtel.ts index 7e59400cc1b1..53bd039762ad 100644 --- a/packages/opentelemetry/test/helpers/initOtel.ts +++ b/packages/opentelemetry/test/helpers/initOtel.ts @@ -16,6 +16,7 @@ import { SentryPropagator } from '../../src/propagator'; import { SentrySampler } from '../../src/sampler'; import { setupEventContextTrace } from '../../src/setupEventContextTrace'; import { SentrySpanProcessor } from '../../src/spanProcessor'; +import { enhanceDscWithOpenTelemetryRootSpanName } from '../../src/utils/enhanceDscWithOpenTelemetryRootSpanName'; import type { TestClientInterface } from './TestClient'; /** @@ -44,6 +45,7 @@ export function initOtel(): void { } setupEventContextTrace(client); + enhanceDscWithOpenTelemetryRootSpanName(client); const provider = setupOtel(client); client.traceProvider = provider; diff --git a/packages/opentelemetry/test/helpers/mockSdkInit.ts b/packages/opentelemetry/test/helpers/mockSdkInit.ts index 6a3d9b171833..869d4c82446f 100644 --- a/packages/opentelemetry/test/helpers/mockSdkInit.ts +++ b/packages/opentelemetry/test/helpers/mockSdkInit.ts @@ -1,6 +1,6 @@ import { ProxyTracerProvider, context, propagation, trace } from '@opentelemetry/api'; import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; -import type { ClientOptions, Options } from '@sentry/types'; +import type { ClientOptions, Options } from '@sentry/core'; import { getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core'; import { setOpenTelemetryContextAsyncContextStrategy } from '../../src/asyncContextStrategy'; diff --git a/packages/opentelemetry/test/integration/transactions.test.ts b/packages/opentelemetry/test/integration/transactions.test.ts index b66147a413d7..bc0179b55e38 100644 --- a/packages/opentelemetry/test/integration/transactions.test.ts +++ b/packages/opentelemetry/test/integration/transactions.test.ts @@ -12,7 +12,7 @@ import { withIsolationScope, } from '@sentry/core'; import { logger } from '@sentry/core'; -import type { Event, TransactionEvent } from '@sentry/types'; +import type { Event, TransactionEvent } from '@sentry/core'; import { TraceState } from '@opentelemetry/core'; import { SENTRY_TRACE_STATE_DSC } from '../../src/constants'; @@ -109,9 +109,9 @@ describe('Integration | Transactions', () => { 'test.outer': 'test value', }, op: 'test op', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.test', }); @@ -121,7 +121,7 @@ describe('Integration | Transactions', () => { public_key: expect.any(String), sample_rate: '1', sampled: 'true', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), transaction: 'test name', release: '8.0.0', }); @@ -151,12 +151,12 @@ describe('Integration | Transactions', () => { }, description: 'inner span 1', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, { data: { @@ -165,12 +165,12 @@ describe('Integration | Transactions', () => { }, description: 'inner span 2', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, ]); }); @@ -260,9 +260,9 @@ describe('Integration | Transactions', () => { 'sentry.sample_rate': 1, }, op: 'test op', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.test', }, }), @@ -298,9 +298,9 @@ describe('Integration | Transactions', () => { 'sentry.sample_rate': 1, }, op: 'test op b', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), status: 'ok', - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', }, }), @@ -327,7 +327,6 @@ describe('Integration | Transactions', () => { const parentSpanId = '6e0c63257de34c92'; const traceState = makeTraceState({ - parentSpanId, dsc: undefined, sampled: true, }); @@ -377,7 +376,7 @@ describe('Integration | Transactions', () => { 'sentry.sample_rate': 1, }, op: 'test op', - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), parent_span_id: parentSpanId, status: 'ok', trace_id: traceId, @@ -411,8 +410,8 @@ describe('Integration | Transactions', () => { }, description: 'inner span 1', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), @@ -424,8 +423,8 @@ describe('Integration | Transactions', () => { }, description: 'inner span 2', origin: 'manual', - parent_span_id: expect.any(String), - span_id: expect.any(String), + parent_span_id: expect.stringMatching(/[a-f0-9]{16}/), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), @@ -460,24 +459,22 @@ describe('Integration | Transactions', () => { throw new Error('No exporter found, aborting test...'); } - let innerSpan1Id: string | undefined; - let innerSpan2Id: string | undefined; - void startSpan({ name: 'test name' }, async () => { - const subSpan = startInactiveSpan({ name: 'inner span 1' }); - innerSpan1Id = subSpan.spanContext().spanId; - subSpan.end(); - - startSpan({ name: 'inner span 2' }, innerSpan => { - innerSpan2Id = innerSpan.spanContext().spanId; - }); + startInactiveSpan({ name: 'inner span 1' }).end(); + startInactiveSpan({ name: 'inner span 2' }).end(); // Pretend this is pending for 10 minutes await new Promise(resolve => setTimeout(resolve, 10 * 60 * 1000)); }); // Child-spans have been added to the exporter, but they are pending since they are waiting for their parent - expect(exporter['_finishedSpans'].length).toBe(2); + const finishedSpans1 = []; + exporter['_finishedSpanBuckets'].forEach(bucket => { + if (bucket) { + finishedSpans1.push(...bucket.spans); + } + }); + expect(finishedSpans1.length).toBe(2); expect(beforeSendTransaction).toHaveBeenCalledTimes(0); // Now wait for 5 mins @@ -489,18 +486,21 @@ describe('Integration | Transactions', () => { jest.advanceTimersByTime(1); // Old spans have been cleared away - expect(exporter['_finishedSpans'].length).toBe(0); + const finishedSpans2 = []; + exporter['_finishedSpanBuckets'].forEach(bucket => { + if (bucket) { + finishedSpans2.push(...bucket.spans); + } + }); + expect(finishedSpans2.length).toBe(0); // Called once for the 'other span' expect(beforeSendTransaction).toHaveBeenCalledTimes(1); expect(logs).toEqual( expect.arrayContaining([ - 'SpanExporter has 1 unsent spans remaining', - 'SpanExporter has 2 unsent spans remaining', - 'SpanExporter exported 1 spans, 2 unsent spans remaining', - `SpanExporter dropping span inner span 1 (${innerSpan1Id}) because it is pending for more than 5 minutes.`, - `SpanExporter dropping span inner span 2 (${innerSpan2Id}) because it is pending for more than 5 minutes.`, + 'SpanExporter dropped 2 spans because they were pending for more than 300 seconds.', + 'SpanExporter exported 1 spans, 0 unsent spans remaining', ]), ); }); @@ -553,7 +553,13 @@ describe('Integration | Transactions', () => { expect(transactions[0]?.spans).toHaveLength(2); // No spans are pending - expect(exporter['_finishedSpans'].length).toBe(0); + const finishedSpans = []; + exporter['_finishedSpanBuckets'].forEach(bucket => { + if (bucket) { + finishedSpans.push(...bucket.spans); + } + }); + expect(finishedSpans.length).toBe(0); }); it('discards child spans that are finished after their parent span', async () => { @@ -607,8 +613,14 @@ describe('Integration | Transactions', () => { expect(transactions[0]?.spans).toHaveLength(1); // subSpan2 is pending (and will eventually be cleaned up) - expect(exporter['_finishedSpans'].length).toBe(1); - expect(exporter['_finishedSpans'][0]?.name).toBe('inner span 2'); + const finishedSpans: any = []; + exporter['_finishedSpanBuckets'].forEach(bucket => { + if (bucket) { + finishedSpans.push(...bucket.spans); + } + }); + expect(finishedSpans.length).toBe(1); + expect(finishedSpans[0]?.name).toBe('inner span 2'); }); it('uses & inherits DSC on span trace state', async () => { diff --git a/packages/opentelemetry/test/propagator.test.ts b/packages/opentelemetry/test/propagator.test.ts index d3b9483674a1..56aed551353e 100644 --- a/packages/opentelemetry/test/propagator.test.ts +++ b/packages/opentelemetry/test/propagator.test.ts @@ -12,7 +12,6 @@ import { getCurrentScope, withScope } from '@sentry/core'; import { SENTRY_BAGGAGE_HEADER, SENTRY_SCOPES_CONTEXT_KEY, SENTRY_TRACE_HEADER } from '../src/constants'; import { SentryPropagator } from '../src/propagator'; -import { getScopesFromContext } from '../src/utils/contextData'; import { getSamplingDecision } from '../src/utils/getSamplingDecision'; import { makeTraceState } from '../src/utils/makeTraceState'; import { cleanupOtel, mockSdkInit } from './helpers/mockSdkInit'; @@ -101,39 +100,6 @@ describe('SentryPropagator', () => { }); }); - it('uses scope propagation context over remote spanContext', () => { - context.with( - trace.setSpanContext(ROOT_CONTEXT, { - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - spanId: '6e0c63257de34c92', - traceFlags: TraceFlags.NONE, - isRemote: true, - }), - () => { - withScope(scope => { - scope.setPropagationContext({ - traceId: 'TRACE_ID', - parentSpanId: 'PARENT_SPAN_ID', - spanId: 'SPAN_ID', - sampled: true, - }); - - propagator.inject(context.active(), carrier, defaultTextMapSetter); - - expect(baggageToArray(carrier[SENTRY_BAGGAGE_HEADER])).toEqual( - [ - 'sentry-environment=production', - 'sentry-release=1.0.0', - 'sentry-public_key=abc', - 'sentry-trace_id=TRACE_ID', - ].sort(), - ); - expect(carrier[SENTRY_TRACE_HEADER]).toBe('TRACE_ID-SPAN_ID-1'); - }); - }, - ); - }); - it('uses propagation data from current scope if no scope & span is found', () => { const scope = getCurrentScope(); const traceId = scope.getPropagationContext().traceId; @@ -181,7 +147,6 @@ describe('SentryPropagator', () => { traceFlags: TraceFlags.SAMPLED, isRemote: true, traceState: makeTraceState({ - parentSpanId: '6e0c63257de34c92', dsc: { transaction: 'sampled-transaction', sampled: 'true', @@ -256,7 +221,6 @@ describe('SentryPropagator', () => { traceFlags: TraceFlags.NONE, isRemote: true, traceState: makeTraceState({ - parentSpanId: '6e0c63257de34c92', dsc: { transaction: 'sampled-transaction', sampled: 'false', @@ -291,7 +255,6 @@ describe('SentryPropagator', () => { isRemote: true, traceState: makeTraceState({ sampled: false, - parentSpanId: '6e0c63257de34c92', dsc: { transaction: 'sampled-transaction', trace_id: 'dsc_trace_id', @@ -383,14 +346,53 @@ describe('SentryPropagator', () => { }); }, ); + }); + + it('uses remote span with deferred sampling decision over propagation context', () => { + const carrier: Record = {}; + context.with( + trace.setSpanContext(ROOT_CONTEXT, { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.NONE, + isRemote: true, + }), + () => { + withScope(scope => { + scope.setPropagationContext({ + traceId: 'TRACE_ID', + parentSpanId: 'PARENT_SPAN_ID', + spanId: 'SPAN_ID', + sampled: true, + }); + + propagator.inject(context.active(), carrier, defaultTextMapSetter); + + expect(baggageToArray(carrier[SENTRY_BAGGAGE_HEADER])).toEqual( + [ + 'sentry-environment=production', + 'sentry-release=1.0.0', + 'sentry-public_key=abc', + 'sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b', + ].sort(), + ); + // Used spanId is a random ID, not from the remote span + expect(carrier[SENTRY_TRACE_HEADER]).toMatch(/d4cda95b652f4a1592b449d5929fda1b-[a-f0-9]{16}/); + expect(carrier[SENTRY_TRACE_HEADER]).not.toBe('d4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92'); + }); + }, + ); + }); - const carrier2: Record = {}; + it('uses remote span over propagation context', () => { + const carrier: Record = {}; context.with( trace.setSpanContext(ROOT_CONTEXT, { traceId: 'd4cda95b652f4a1592b449d5929fda1b', spanId: '6e0c63257de34c92', traceFlags: TraceFlags.NONE, isRemote: true, + traceState: makeTraceState({ sampled: false }), }), () => { withScope(scope => { @@ -401,17 +403,20 @@ describe('SentryPropagator', () => { sampled: true, }); - propagator.inject(context.active(), carrier2, defaultTextMapSetter); + propagator.inject(context.active(), carrier, defaultTextMapSetter); - expect(baggageToArray(carrier2[SENTRY_BAGGAGE_HEADER])).toEqual( + expect(baggageToArray(carrier[SENTRY_BAGGAGE_HEADER])).toEqual( [ 'sentry-environment=production', 'sentry-release=1.0.0', 'sentry-public_key=abc', - 'sentry-trace_id=TRACE_ID', + 'sentry-sampled=false', + 'sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b', ].sort(), ); - expect(carrier2[SENTRY_TRACE_HEADER]).toBe('TRACE_ID-SPAN_ID-1'); + // Used spanId is a random ID, not from the remote span + expect(carrier[SENTRY_TRACE_HEADER]).toMatch(/d4cda95b652f4a1592b449d5929fda1b-[a-f0-9]{16}-0/); + expect(carrier[SENTRY_TRACE_HEADER]).not.toBe('d4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-0'); }); }, ); @@ -557,7 +562,7 @@ describe('SentryPropagator', () => { spanId: '6e0c63257de34c92', traceFlags: TraceFlags.SAMPLED, traceId: 'd4cda95b652f4a1592b449d5929fda1b', - traceState: makeTraceState({ parentSpanId: '6e0c63257de34c92' }), + traceState: makeTraceState({}), }); expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(true); }); @@ -571,7 +576,7 @@ describe('SentryPropagator', () => { spanId: '6e0c63257de34c92', traceFlags: TraceFlags.NONE, traceId: 'd4cda95b652f4a1592b449d5929fda1b', - traceState: makeTraceState({ parentSpanId: '6e0c63257de34c92', sampled: false }), + traceState: makeTraceState({ sampled: false }), }); expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(false); }); @@ -585,41 +590,20 @@ describe('SentryPropagator', () => { spanId: '6e0c63257de34c92', traceFlags: TraceFlags.NONE, traceId: 'd4cda95b652f4a1592b449d5929fda1b', - traceState: makeTraceState({ parentSpanId: '6e0c63257de34c92' }), + traceState: makeTraceState({}), }); expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(undefined); }); - it('sets data from sentry trace header on scope', () => { - const sentryTraceHeader = 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1'; - carrier[SENTRY_TRACE_HEADER] = sentryTraceHeader; - const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); - - const scopes = getScopesFromContext(context); - - expect(scopes).toBeDefined(); - expect(scopes?.scope.getPropagationContext()).toEqual({ - spanId: expect.any(String), - sampled: true, - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - parentSpanId: '6e0c63257de34c92', - dsc: {}, - }); - expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(true); - }); - it('handles undefined sentry trace header', () => { const sentryTraceHeader = undefined; carrier[SENTRY_TRACE_HEADER] = sentryTraceHeader; const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); - expect(trace.getSpanContext(context)).toEqual({ - isRemote: true, - spanId: expect.any(String), - traceFlags: TraceFlags.NONE, - traceId: expect.any(String), - traceState: makeTraceState({}), + expect(trace.getSpanContext(context)).toEqual(undefined); + expect(getCurrentScope().getPropagationContext()).toEqual({ + spanId: expect.stringMatching(/[a-f0-9]{16}/), + traceId: expect.stringMatching(/[a-f0-9]{32}/), }); - expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(undefined); }); it('sets data from baggage header on span context', () => { @@ -635,7 +619,6 @@ describe('SentryPropagator', () => { traceFlags: TraceFlags.SAMPLED, traceId: 'd4cda95b652f4a1592b449d5929fda1b', traceState: makeTraceState({ - parentSpanId: '6e0c63257de34c92', dsc: { environment: 'production', release: '1.0.0', @@ -648,55 +631,29 @@ describe('SentryPropagator', () => { expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(true); }); - it('sets data from baggage header on scope', () => { - const sentryTraceHeader = 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1'; - const baggage = - 'sentry-environment=production,sentry-release=1.0.0,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b,sentry-transaction=dsc-transaction'; - carrier[SENTRY_TRACE_HEADER] = sentryTraceHeader; - carrier[SENTRY_BAGGAGE_HEADER] = baggage; - const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); - - const scopes = getScopesFromContext(context); - - expect(scopes).toBeDefined(); - expect(scopes?.scope.getPropagationContext()).toEqual({ - spanId: expect.any(String), - sampled: true, - traceId: 'd4cda95b652f4a1592b449d5929fda1b', - parentSpanId: '6e0c63257de34c92', - dsc: { - environment: 'production', - release: '1.0.0', - public_key: 'abc', - trace_id: 'd4cda95b652f4a1592b449d5929fda1b', - transaction: 'dsc-transaction', - }, - }); - }); - it('handles empty dsc baggage header', () => { + const sentryTraceHeader = 'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1'; const baggage = ''; + carrier[SENTRY_TRACE_HEADER] = sentryTraceHeader; carrier[SENTRY_BAGGAGE_HEADER] = baggage; const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); expect(trace.getSpanContext(context)).toEqual({ isRemote: true, - spanId: expect.any(String), - traceFlags: TraceFlags.NONE, - traceId: expect.any(String), + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + traceId: 'd4cda95b652f4a1592b449d5929fda1b', traceState: makeTraceState({}), }); - expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(undefined); + expect(getSamplingDecision(trace.getSpanContext(context)!)).toBe(true); }); it('handles when sentry-trace is an empty array', () => { carrier[SENTRY_TRACE_HEADER] = []; const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter); - expect(trace.getSpanContext(context)).toEqual({ - isRemote: true, - spanId: expect.any(String), - traceFlags: TraceFlags.NONE, - traceId: expect.any(String), - traceState: makeTraceState({}), + expect(trace.getSpanContext(context)).toEqual(undefined); + expect(getCurrentScope().getPropagationContext()).toEqual({ + spanId: expect.stringMatching(/[a-f0-9]{16}/), + traceId: expect.stringMatching(/[a-f0-9]{32}/), }); }); }); diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts index 0a709c9fb5da..2c22318ec977 100644 --- a/packages/opentelemetry/test/trace.test.ts +++ b/packages/opentelemetry/test/trace.test.ts @@ -20,7 +20,7 @@ import { suppressTracing, withScope, } from '@sentry/core'; -import type { Event, Scope } from '@sentry/types'; +import type { Event, Scope } from '@sentry/core'; import { SEMATTRS_HTTP_METHOD } from '@opentelemetry/semantic-conventions'; import { continueTrace, startInactiveSpan, startSpan, startSpanManual } from '../src/trace'; @@ -329,9 +329,7 @@ describe('trace', () => { it('allows to pass parentSpan=null', () => { startSpan({ name: 'GET users/[id' }, () => { startSpan({ name: 'child', parentSpan: null }, span => { - // Due to the way we propagate the scope in OTEL, - // the parent_span_id is not actually undefined here, but comes from the propagation context - expect(spanToJSON(span).parent_span_id).toBe(getCurrentScope().getPropagationContext().spanId); + expect(spanToJSON(span).parent_span_id).toBe(undefined); }); }); }); @@ -391,8 +389,8 @@ describe('trace', () => { 'sentry.sample_rate': 1, 'sentry.origin': 'manual', }, - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', status: 'ok', }); @@ -416,7 +414,7 @@ describe('trace', () => { 'sentry.sample_rate': 1, }, parent_span_id: innerParentSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: outerTraceId, origin: 'manual', status: 'ok', @@ -591,10 +589,7 @@ describe('trace', () => { it('allows to pass parentSpan=null', () => { startSpan({ name: 'outer' }, () => { const span = startInactiveSpan({ name: 'test span', parentSpan: null }); - - // Due to the way we propagate the scope in OTEL, - // the parent_span_id is not actually undefined here, but comes from the propagation context - expect(spanToJSON(span).parent_span_id).toBe(getCurrentScope().getPropagationContext().spanId); + expect(spanToJSON(span).parent_span_id).toBe(undefined); span.end(); }); }); @@ -651,8 +646,8 @@ describe('trace', () => { 'sentry.sample_rate': 1, 'sentry.origin': 'manual', }, - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', status: 'ok', }); @@ -676,7 +671,7 @@ describe('trace', () => { 'sentry.sample_rate': 1, }, parent_span_id: innerParentSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: outerTraceId, origin: 'manual', status: 'ok', @@ -881,9 +876,7 @@ describe('trace', () => { it('allows to pass parentSpan=null', () => { startSpan({ name: 'outer' }, () => { startSpanManual({ name: 'GET users/[id]', parentSpan: null }, span => { - // Due to the way we propagate the scope in OTEL, - // the parent_span_id is not actually undefined here, but comes from the propagation context - expect(spanToJSON(span).parent_span_id).toBe(getCurrentScope().getPropagationContext().spanId); + expect(spanToJSON(span).parent_span_id).toBe(undefined); span.end(); }); }); @@ -948,8 +941,8 @@ describe('trace', () => { 'sentry.sample_rate': 1, 'sentry.origin': 'manual', }, - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'manual', status: 'ok', }); @@ -973,7 +966,7 @@ describe('trace', () => { 'sentry.sample_rate': 1, }, parent_span_id: innerParentSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), trace_id: outerTraceId, origin: 'manual', status: 'ok', @@ -1016,17 +1009,21 @@ describe('trace', () => { }); describe('propagation', () => { - it('picks up the trace context from the scope, if there is no parent', () => { + it('starts new trace, if there is no parent', () => { withScope(scope => { const propagationContext = scope.getPropagationContext(); const span = startInactiveSpan({ name: 'test span' }); expect(span).toBeDefined(); - expect(spanToJSON(span).trace_id).toEqual(propagationContext.traceId); - expect(spanToJSON(span).parent_span_id).toEqual(propagationContext.spanId); + const traceId = spanToJSON(span).trace_id; + expect(traceId).toMatch(/[a-f0-9]{32}/); + expect(spanToJSON(span).parent_span_id).toBe(undefined); + expect(spanToJSON(span).trace_id).not.toEqual(propagationContext.traceId); expect(getDynamicSamplingContextFromSpan(span)).toEqual({ - ...getDynamicSamplingContextFromClient(propagationContext.traceId, getClient()!), + trace_id: traceId, + environment: 'production', + public_key: 'username', sample_rate: '1', sampled: 'true', transaction: 'test span', @@ -1034,18 +1031,23 @@ describe('trace', () => { }); }); - it('picks up the trace context from the scope, including parentSpanId, if there is no parent', () => { + // Note: This _should_ never happen, when we have an incoming trace, we should always have a parent span + it('starts new trace, ignoring parentSpanId, if there is no parent', () => { withScope(scope => { const propagationContext = scope.getPropagationContext(); propagationContext.parentSpanId = '1121201211212012'; const span = startInactiveSpan({ name: 'test span' }); expect(span).toBeDefined(); - expect(spanToJSON(span).trace_id).toEqual(propagationContext.traceId); - expect(spanToJSON(span).parent_span_id).toEqual('1121201211212012'); + const traceId = spanToJSON(span).trace_id; + expect(traceId).toMatch(/[a-f0-9]{32}/); + expect(spanToJSON(span).parent_span_id).toBe(undefined); + expect(spanToJSON(span).trace_id).not.toEqual(propagationContext.traceId); expect(getDynamicSamplingContextFromSpan(span)).toEqual({ - ...getDynamicSamplingContextFromClient(propagationContext.traceId, getClient()!), + environment: 'production', + public_key: 'username', + trace_id: traceId, sample_rate: '1', sampled: 'true', transaction: 'test span', @@ -1082,7 +1084,6 @@ describe('trace', () => { isRemote: false, traceFlags: TraceFlags.SAMPLED, traceState: makeTraceState({ - parentSpanId: '1121201211212011', dsc: { release: '1.0', environment: 'production', @@ -1112,7 +1113,6 @@ describe('trace', () => { isRemote: true, traceFlags: TraceFlags.SAMPLED, traceState: makeTraceState({ - parentSpanId: '1121201211212011', dsc: { release: '1.0', environment: 'production', @@ -1450,6 +1450,27 @@ describe('trace (sampling)', () => { }, }); }); + + it('ignores parent span context if it is invalid', () => { + mockSdkInit({ tracesSampleRate: 1 }); + const traceId = 'd4cda95b652f4a1592b449d5929fda1b'; + + const spanContext = { + traceId, + spanId: 'INVALID', + traceFlags: TraceFlags.SAMPLED, + }; + + context.with(trace.setSpanContext(ROOT_CONTEXT, spanContext), () => { + startSpan({ name: 'outer' }, span => { + expect(span.isRecording()).toBe(true); + expect(span.spanContext().spanId).not.toBe('INVALID'); + expect(span.spanContext().spanId).toMatch(/[a-f0-9]{16}/); + expect(span.spanContext().traceId).not.toBe(traceId); + expect(span.spanContext().traceId).toMatch(/[a-f0-9]{32}/); + }); + }); + }); }); describe('HTTP methods (sampling)', () => { @@ -1519,14 +1540,7 @@ describe('continueTrace', () => { it('works without trace & baggage data', () => { const scope = continueTrace({ sentryTrace: undefined, baggage: undefined }, () => { const span = getActiveSpan()!; - expect(span).toBeDefined(); - expect(spanToJSON(span)).toEqual({ - span_id: '', - trace_id: expect.any(String), - }); - expect(getSamplingDecision(span.spanContext())).toBe(undefined); - expect(spanIsSampled(span)).toBe(false); - + expect(span).toBeUndefined(); return getCurrentScope(); }); diff --git a/packages/opentelemetry/test/utils/getTraceData.test.ts b/packages/opentelemetry/test/utils/getTraceData.test.ts new file mode 100644 index 000000000000..e0f2270d8e22 --- /dev/null +++ b/packages/opentelemetry/test/utils/getTraceData.test.ts @@ -0,0 +1,93 @@ +import { context, trace } from '@opentelemetry/api'; +import { getCurrentScope, setAsyncContextStrategy } from '@sentry/core'; +import { getTraceData } from '../../src/utils/getTraceData'; +import { makeTraceState } from '../../src/utils/makeTraceState'; +import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit'; + +describe('getTraceData', () => { + beforeEach(() => { + setAsyncContextStrategy(undefined); + mockSdkInit(); + }); + + afterEach(() => { + cleanupOtel(); + jest.clearAllMocks(); + }); + + it('returns the tracing data from the span, if a span is available', () => { + const ctx = trace.setSpanContext(context.active(), { + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + traceFlags: 1, + }); + + context.with(ctx, () => { + const data = getTraceData(); + + expect(data).toEqual({ + 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: + 'sentry-environment=production,sentry-public_key=username,sentry-trace_id=12345678901234567890123456789012,sentry-sampled=true', + }); + }); + }); + + it('allows to pass a span directly', () => { + const ctx = trace.setSpanContext(context.active(), { + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + traceFlags: 1, + }); + + const span = trace.getSpan(ctx)!; + + const data = getTraceData({ span }); + + expect(data).toEqual({ + 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: + 'sentry-environment=production,sentry-public_key=username,sentry-trace_id=12345678901234567890123456789012,sentry-sampled=true', + }); + }); + + it('returns propagationContext DSC data if no span is available', () => { + getCurrentScope().setPropagationContext({ + traceId: '12345678901234567890123456789012', + sampled: true, + spanId: '1234567890123456', + dsc: { + environment: 'staging', + public_key: 'key', + trace_id: '12345678901234567890123456789012', + }, + }); + + const traceData = getTraceData(); + + expect(traceData).toEqual({ + 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: 'sentry-environment=staging,sentry-public_key=key,sentry-trace_id=12345678901234567890123456789012', + }); + }); + + it('works with an span with frozen DSC in traceState', () => { + const ctx = trace.setSpanContext(context.active(), { + traceId: '12345678901234567890123456789012', + spanId: '1234567890123456', + traceFlags: 1, + traceState: makeTraceState({ + dsc: { environment: 'test-dev', public_key: '456', trace_id: '12345678901234567890123456789088' }, + }), + }); + + context.with(ctx, () => { + const data = getTraceData(); + + expect(data).toEqual({ + 'sentry-trace': '12345678901234567890123456789012-1234567890123456-1', + baggage: 'sentry-environment=test-dev,sentry-public_key=456,sentry-trace_id=12345678901234567890123456789088', + }); + }); + }); +}); diff --git a/packages/opentelemetry/test/utils/mapStatus.test.ts b/packages/opentelemetry/test/utils/mapStatus.test.ts index d4e831d5ded1..79ffdf057b5a 100644 --- a/packages/opentelemetry/test/utils/mapStatus.test.ts +++ b/packages/opentelemetry/test/utils/mapStatus.test.ts @@ -1,7 +1,7 @@ /* eslint-disable deprecation/deprecation */ import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_RPC_GRPC_STATUS_CODE } from '@opentelemetry/semantic-conventions'; import { SPAN_STATUS_ERROR, SPAN_STATUS_OK } from '@sentry/core'; -import type { SpanStatus } from '@sentry/types'; +import type { SpanStatus } from '@sentry/core'; import { mapStatus } from '../../src/utils/mapStatus'; import { createSpan } from '../helpers/createSpan'; diff --git a/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts b/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts index 029c25ad968d..95c68e5416f1 100644 --- a/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts +++ b/packages/opentelemetry/test/utils/setupEventContextTrace.test.ts @@ -51,8 +51,8 @@ describe('setupEventContextTrace', () => { expect.objectContaining({ contexts: expect.objectContaining({ trace: { - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }, }), }), diff --git a/packages/profiling-node/package.json b/packages/profiling-node/package.json index 3f2e630fc304..8833a51235cc 100644 --- a/packages/profiling-node/package.json +++ b/packages/profiling-node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/profiling-node", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Node.js Profiling", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/profiling-node", @@ -75,9 +75,8 @@ "test": "cross-env SENTRY_PROFILER_BINARY_DIR=lib jest --config jest.config.js" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", "detect-libc": "^2.0.2", "node-abi": "^3.61.0" }, @@ -86,8 +85,7 @@ "@types/node-abi": "^3.0.3", "clang-format": "^1.8.0", "cross-env": "^7.0.3", - "node-gyp": "^9.4.1", - "typescript": "^4.9.5" + "node-gyp": "^9.4.1" }, "volta": { "extends": "../../package.json" diff --git a/packages/profiling-node/scripts/prune-profiler-binaries.js b/packages/profiling-node/scripts/prune-profiler-binaries.js index 22fc13ce28b6..a0c5ce7fc33d 100755 --- a/packages/profiling-node/scripts/prune-profiler-binaries.js +++ b/packages/profiling-node/scripts/prune-profiler-binaries.js @@ -62,6 +62,7 @@ const NODE_TO_ABI = { 16: '93', 18: '108', 20: '115', + 22: '127', }; if (NODE) { @@ -73,9 +74,13 @@ if (NODE) { NODE = NODE_TO_ABI['18']; } else if (NODE.startsWith('20')) { NODE = NODE_TO_ABI['20']; + } else if (NODE.startsWith('22')) { + NODE = NODE_TO_ABI['22']; } else { ARGV_ERRORS.push( - '❌ Sentry: Invalid node version passed as argument, please make sure --target_node is a valid major node version. Supported versions are 16, 18 and 20.', + `❌ Sentry: Invalid node version passed as argument, please make sure --target_node is a valid major node version. Supported versions are ${Object.keys( + NODE_TO_ABI, + ).join(', ')}.`, ); } } diff --git a/packages/profiling-node/src/cpu_profiler.ts b/packages/profiling-node/src/cpu_profiler.ts index 76fad9a286a6..4897745ededa 100644 --- a/packages/profiling-node/src/cpu_profiler.ts +++ b/packages/profiling-node/src/cpu_profiler.ts @@ -143,6 +143,7 @@ export function importCppBindingsModule(): PrivateV8CpuProfilerBindings { return require('../sentry_cpu_profiler-linux-arm64-musl-127.node'); } } + if (stdlib === 'glibc') { if (abi === '93') { return require('../sentry_cpu_profiler-linux-arm64-glibc-93.node'); diff --git a/packages/profiling-node/src/integration.ts b/packages/profiling-node/src/integration.ts index 65bab5084d3e..8aed8eb3a305 100644 --- a/packages/profiling-node/src/integration.ts +++ b/packages/profiling-node/src/integration.ts @@ -1,28 +1,28 @@ /* eslint-disable max-lines */ +import type { Event, IntegrationFn, Profile, ProfileChunk, ProfilingIntegration, Span } from '@sentry/core'; import { + LRUMap, + consoleSandbox, defineIntegration, getCurrentScope, getGlobalScope, getIsolationScope, getRootSpan, + logger, spanToJSON, + uuid4, } from '@sentry/core'; import type { NodeClient } from '@sentry/node'; -import type { Event, IntegrationFn, Profile, ProfileChunk, ProfilingIntegration, Span } from '@sentry/types'; - -import { LRUMap, consoleSandbox, logger, uuid4 } from '@sentry/core'; - import { CpuProfilerBindings } from './cpu_profiler'; import { DEBUG_BUILD } from './debug-build'; import { NODE_MAJOR, NODE_VERSION } from './nodeVersion'; import { MAX_PROFILE_DURATION_MS, maybeProfileSpan, stopSpanProfile } from './spanProfileUtils'; import type { RawThreadCpuProfile } from './types'; import { ProfileFormat } from './types'; -import { PROFILER_THREAD_NAME } from './utils'; - import { PROFILER_THREAD_ID_STRING, + PROFILER_THREAD_NAME, addProfilesToEnvelope, createProfilingChunkEvent, createProfilingEvent, diff --git a/packages/profiling-node/src/spanProfileUtils.ts b/packages/profiling-node/src/spanProfileUtils.ts index 75c78b6dfc6b..39196578a9bc 100644 --- a/packages/profiling-node/src/spanProfileUtils.ts +++ b/packages/profiling-node/src/spanProfileUtils.ts @@ -1,8 +1,6 @@ -import { spanIsSampled, spanToJSON } from '@sentry/core'; -import { logger, uuid4 } from '@sentry/core'; +import type { CustomSamplingContext, Span } from '@sentry/core'; +import { logger, spanIsSampled, spanToJSON, uuid4 } from '@sentry/core'; import type { NodeClient } from '@sentry/node'; -import type { CustomSamplingContext, Span } from '@sentry/types'; - import { CpuProfilerBindings } from './cpu_profiler'; import { DEBUG_BUILD } from './debug-build'; import type { RawThreadCpuProfile } from './types'; diff --git a/packages/profiling-node/src/types.ts b/packages/profiling-node/src/types.ts index 1c2c444887cd..2423ca94651b 100644 --- a/packages/profiling-node/src/types.ts +++ b/packages/profiling-node/src/types.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; interface Sample { stack_id: number; diff --git a/packages/profiling-node/src/utils.ts b/packages/profiling-node/src/utils.ts index c6051a90978f..1c0828a5468c 100644 --- a/packages/profiling-node/src/utils.ts +++ b/packages/profiling-node/src/utils.ts @@ -1,13 +1,4 @@ -/* eslint-disable max-lines */ import * as os from 'os'; -import { - createEnvelope, - dsnToString, - forEachEnvelopeItem, - getDebugImagesForResources, - logger, - uuid4, -} from '@sentry/core'; import type { Client, Context, @@ -23,7 +14,15 @@ import type { ProfileChunkItem, SdkInfo, ThreadCpuProfile, -} from '@sentry/types'; +} from '@sentry/core'; +import { + createEnvelope, + dsnToString, + forEachEnvelopeItem, + getDebugImagesForResources, + logger, + uuid4, +} from '@sentry/core'; import { env, versions } from 'process'; import { isMainThread, threadId } from 'worker_threads'; diff --git a/packages/profiling-node/test/cpu_profiler.test.ts b/packages/profiling-node/test/cpu_profiler.test.ts index b370ae7f96c9..4db0b98891a3 100644 --- a/packages/profiling-node/test/cpu_profiler.test.ts +++ b/packages/profiling-node/test/cpu_profiler.test.ts @@ -1,4 +1,4 @@ -import type { ContinuousThreadCpuProfile, ThreadCpuProfile } from '@sentry/types'; +import type { ContinuousThreadCpuProfile, ThreadCpuProfile } from '@sentry/core'; import { CpuProfilerBindings, PrivateCpuProfilerBindings } from '../src/cpu_profiler'; import type { RawThreadCpuProfile } from '../src/types'; diff --git a/packages/profiling-node/test/integration.test.ts b/packages/profiling-node/test/integration.test.ts index 92d1018e18d4..39788b00bc56 100644 --- a/packages/profiling-node/test/integration.test.ts +++ b/packages/profiling-node/test/integration.test.ts @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; -import type { Transport } from '@sentry/types'; +import type { Transport } from '@sentry/core'; import type { NodeClient } from '@sentry/node'; import { _nodeProfilingIntegration } from '../src/integration'; diff --git a/packages/profiling-node/test/spanProfileUtils.test.ts b/packages/profiling-node/test/spanProfileUtils.test.ts index e679001994da..9974eb6ebc64 100644 --- a/packages/profiling-node/test/spanProfileUtils.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.test.ts @@ -2,9 +2,9 @@ import * as Sentry from '@sentry/node'; import { getMainCarrier } from '@sentry/core'; import { GLOBAL_OBJ, createEnvelope, logger } from '@sentry/core'; +import type { ProfilingIntegration } from '@sentry/core'; +import type { ProfileChunk, Transport } from '@sentry/core'; import type { NodeClientOptions } from '@sentry/node/build/types/types'; -import type { ProfilingIntegration } from '@sentry/types'; -import type { ProfileChunk, Transport } from '@sentry/types'; import { CpuProfilerBindings } from '../src/cpu_profiler'; import { _nodeProfilingIntegration } from '../src/integration'; diff --git a/packages/profiling-node/test/spanProfileUtils.worker.test.ts b/packages/profiling-node/test/spanProfileUtils.worker.test.ts index 12727aebc954..e2db2ecb7706 100644 --- a/packages/profiling-node/test/spanProfileUtils.worker.test.ts +++ b/packages/profiling-node/test/spanProfileUtils.worker.test.ts @@ -7,9 +7,9 @@ jest.mock('worker_threads', () => { }); jest.setTimeout(10000); +import type { Transport } from '@sentry/core'; +import { type ProfilingIntegration } from '@sentry/core'; import * as Sentry from '@sentry/node'; -import type { Transport } from '@sentry/types'; -import { type ProfilingIntegration } from '@sentry/types'; import { _nodeProfilingIntegration } from '../src/integration'; function makeContinuousProfilingClient(): [Sentry.NodeClient, Transport] { diff --git a/packages/profiling-node/test/utils.test.ts b/packages/profiling-node/test/utils.test.ts index 9d834f1dc9b3..dac0bf16be79 100644 --- a/packages/profiling-node/test/utils.test.ts +++ b/packages/profiling-node/test/utils.test.ts @@ -1,5 +1,5 @@ import { addItemToEnvelope, createEnvelope, uuid4 } from '@sentry/core'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { addProfilesToEnvelope, diff --git a/packages/react/package.json b/packages/react/package.json index 13f7242e3a54..938714906a2a 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/react", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for React.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react", @@ -39,9 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0", "hoist-non-react-statics": "^3.3.2" }, "peerDependencies": { diff --git a/packages/react/src/error.ts b/packages/react/src/error.ts index 09121c3c85c2..a3bec777245a 100644 --- a/packages/react/src/error.ts +++ b/packages/react/src/error.ts @@ -1,6 +1,6 @@ import { captureException } from '@sentry/browser'; import { isError } from '@sentry/core'; -import type { EventHint } from '@sentry/types'; +import type { EventHint } from '@sentry/core'; import { version } from 'react'; import type { ErrorInfo } from 'react'; diff --git a/packages/react/src/errorboundary.tsx b/packages/react/src/errorboundary.tsx index 84b2ac464e9d..91cc0e2cdc17 100644 --- a/packages/react/src/errorboundary.tsx +++ b/packages/react/src/errorboundary.tsx @@ -1,7 +1,7 @@ import type { ReportDialogOptions } from '@sentry/browser'; import { getClient, showReportDialog, withScope } from '@sentry/browser'; import { logger } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; import hoistNonReactStatics from 'hoist-non-react-statics'; import * as React from 'react'; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 5fe088ec448b..e72eb09645ec 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -16,6 +16,16 @@ export { export { reactRouterV6BrowserTracingIntegration, withSentryReactRouterV6Routing, + // eslint-disable-next-line deprecation/deprecation wrapUseRoutes, + wrapUseRoutesV6, + // eslint-disable-next-line deprecation/deprecation wrapCreateBrowserRouter, + wrapCreateBrowserRouterV6, } from './reactrouterv6'; +export { + reactRouterV7BrowserTracingIntegration, + withSentryReactRouterV7Routing, + wrapCreateBrowserRouterV7, + wrapUseRoutesV7, +} from './reactrouterv7'; diff --git a/packages/react/src/profiler.tsx b/packages/react/src/profiler.tsx index 26585d83ae64..9804e497055a 100644 --- a/packages/react/src/profiler.tsx +++ b/packages/react/src/profiler.tsx @@ -1,7 +1,6 @@ import { startInactiveSpan } from '@sentry/browser'; -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanToJSON, withActiveSpan } from '@sentry/core'; -import { timestampInSeconds } from '@sentry/core'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, spanToJSON, timestampInSeconds, withActiveSpan } from '@sentry/core'; import hoistNonReactStatics from 'hoist-non-react-statics'; import * as React from 'react'; diff --git a/packages/react/src/reactrouter.tsx b/packages/react/src/reactrouter.tsx index 1b9102273e9c..9f02f69cff06 100644 --- a/packages/react/src/reactrouter.tsx +++ b/packages/react/src/reactrouter.tsx @@ -13,7 +13,7 @@ import { getRootSpan, spanToJSON, } from '@sentry/core'; -import type { Client, Integration, Span, TransactionSource } from '@sentry/types'; +import type { Client, Integration, Span, TransactionSource } from '@sentry/core'; import hoistNonReactStatics from 'hoist-non-react-statics'; import * as React from 'react'; import type { ReactElement } from 'react'; @@ -223,7 +223,7 @@ function computeRootMatch(pathname: string): Match { /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */ export function withSentryRouting

, R extends React.ComponentType

>(Route: R): R { - const componentDisplayName = (Route as any).displayName || (Route as any).name; + const componentDisplayName = Route.displayName || Route.name; const WrappedRoute: React.FC

= (props: P) => { if (props && props.computedMatch && props.computedMatch.isExact) { diff --git a/packages/react/src/reactrouterv3.ts b/packages/react/src/reactrouterv3.ts index df495de3e711..75868340d56e 100644 --- a/packages/react/src/reactrouterv3.ts +++ b/packages/react/src/reactrouterv3.ts @@ -9,7 +9,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, } from '@sentry/core'; -import type { Integration, TransactionSource } from '@sentry/types'; +import type { Integration, TransactionSource } from '@sentry/core'; import type { Location } from './types'; diff --git a/packages/react/src/reactrouterv6-compat-utils.tsx b/packages/react/src/reactrouterv6-compat-utils.tsx new file mode 100644 index 000000000000..7752e49d69a1 --- /dev/null +++ b/packages/react/src/reactrouterv6-compat-utils.tsx @@ -0,0 +1,436 @@ +/* eslint-disable max-lines */ +// Inspired from Donnie McNeal's solution: +// https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536 + +import { + WINDOW, + browserTracingIntegration, + startBrowserTracingNavigationSpan, + startBrowserTracingPageLoadSpan, +} from '@sentry/browser'; +import type { Client, Integration, Span, TransactionSource } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + getActiveSpan, + getClient, + getCurrentScope, + getNumberOfUrlSegments, + getRootSpan, + logger, + spanToJSON, +} from '@sentry/core'; +import * as React from 'react'; + +import hoistNonReactStatics from 'hoist-non-react-statics'; +import { DEBUG_BUILD } from './debug-build'; +import type { + Action, + AgnosticDataRouteMatch, + CreateRouterFunction, + CreateRoutesFromChildren, + Location, + MatchRoutes, + RouteMatch, + RouteObject, + Router, + RouterState, + UseEffect, + UseLocation, + UseNavigationType, + UseRoutes, +} from './types'; + +let _useEffect: UseEffect; +let _useLocation: UseLocation; +let _useNavigationType: UseNavigationType; +let _createRoutesFromChildren: CreateRoutesFromChildren; +let _matchRoutes: MatchRoutes; +let _stripBasename: boolean = false; + +const CLIENTS_WITH_INSTRUMENT_NAVIGATION = new WeakSet(); + +export interface ReactRouterOptions { + useEffect: UseEffect; + useLocation: UseLocation; + useNavigationType: UseNavigationType; + createRoutesFromChildren: CreateRoutesFromChildren; + matchRoutes: MatchRoutes; + stripBasename?: boolean; +} + +type V6CompatibleVersion = '6' | '7'; + +/** + * Creates a wrapCreateBrowserRouter function that can be used with all React Router v6 compatible versions. + */ +export function createV6CompatibleWrapCreateBrowserRouter< + TState extends RouterState = RouterState, + TRouter extends Router = Router, +>( + createRouterFunction: CreateRouterFunction, + version: V6CompatibleVersion, +): CreateRouterFunction { + if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) { + DEBUG_BUILD && + logger.warn( + `reactRouterV${version}Instrumentation was unable to wrap the \`createRouter\` function because of one or more missing parameters.`, + ); + + return createRouterFunction; + } + + // `opts` for createBrowserHistory and createMemoryHistory are different, but also not relevant for us at the moment. + // `basename` is the only option that is relevant for us, and it is the same for all. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return function (routes: RouteObject[], opts?: Record & { basename?: string }): TRouter { + const router = createRouterFunction(routes, opts); + const basename = opts && opts.basename; + + const activeRootSpan = getActiveRootSpan(); + + // The initial load ends when `createBrowserRouter` is called. + // This is the earliest convenient time to update the transaction name. + // Callbacks to `router.subscribe` are not called for the initial load. + if (router.state.historyAction === 'POP' && activeRootSpan) { + updatePageloadTransaction(activeRootSpan, router.state.location, routes, undefined, basename); + } + + router.subscribe((state: RouterState) => { + const location = state.location; + if (state.historyAction === 'PUSH' || state.historyAction === 'POP') { + handleNavigation(location, routes, state.historyAction, version, undefined, basename); + } + }); + + return router; + }; +} + +/** + * Creates a browser tracing integration that can be used with all React Router v6 compatible versions. + */ +export function createReactRouterV6CompatibleTracingIntegration( + options: Parameters[0] & ReactRouterOptions, + version: V6CompatibleVersion, +): Integration { + const integration = browserTracingIntegration({ + ...options, + instrumentPageLoad: false, + instrumentNavigation: false, + }); + + const { + useEffect, + useLocation, + useNavigationType, + createRoutesFromChildren, + matchRoutes, + stripBasename, + instrumentPageLoad = true, + instrumentNavigation = true, + } = options; + + return { + ...integration, + setup() { + _useEffect = useEffect; + _useLocation = useLocation; + _useNavigationType = useNavigationType; + _matchRoutes = matchRoutes; + _createRoutesFromChildren = createRoutesFromChildren; + _stripBasename = stripBasename || false; + }, + afterAllSetup(client) { + integration.afterAllSetup(client); + + const initPathName = WINDOW && WINDOW.location && WINDOW.location.pathname; + if (instrumentPageLoad && initPathName) { + startBrowserTracingPageLoadSpan(client, { + name: initPathName, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.pageload.react.reactrouter_v${version}`, + }, + }); + } + + if (instrumentNavigation) { + CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client); + } + }, + }; +} + +export function createV6CompatibleWrapUseRoutes(origUseRoutes: UseRoutes, version: V6CompatibleVersion): UseRoutes { + if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) { + DEBUG_BUILD && + logger.warn( + 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.', + ); + + return origUseRoutes; + } + + let isMountRenderPass: boolean = true; + + const SentryRoutes: React.FC<{ + children?: React.ReactNode; + routes: RouteObject[]; + locationArg?: Partial | string; + }> = (props: { children?: React.ReactNode; routes: RouteObject[]; locationArg?: Partial | string }) => { + const { routes, locationArg } = props; + + const Routes = origUseRoutes(routes, locationArg); + + const location = _useLocation(); + const navigationType = _useNavigationType(); + + // A value with stable identity to either pick `locationArg` if available or `location` if not + const stableLocationParam = + typeof locationArg === 'string' || (locationArg && locationArg.pathname) + ? (locationArg as { pathname: string }) + : location; + + _useEffect(() => { + const normalizedLocation = + typeof stableLocationParam === 'string' ? { pathname: stableLocationParam } : stableLocationParam; + + if (isMountRenderPass) { + updatePageloadTransaction(getActiveRootSpan(), normalizedLocation, routes); + isMountRenderPass = false; + } else { + handleNavigation(normalizedLocation, routes, navigationType, version); + } + }, [navigationType, stableLocationParam]); + + return Routes; + }; + + // eslint-disable-next-line react/display-name + return (routes: RouteObject[], locationArg?: Partial | string): React.ReactElement | null => { + return ; + }; +} + +export function handleNavigation( + location: Location, + routes: RouteObject[], + navigationType: Action, + version: V6CompatibleVersion, + matches?: AgnosticDataRouteMatch, + basename?: string, +): void { + const branches = Array.isArray(matches) ? matches : _matchRoutes(routes, location, basename); + + const client = getClient(); + if (!client || !CLIENTS_WITH_INSTRUMENT_NAVIGATION.has(client)) { + return; + } + + if ((navigationType === 'PUSH' || navigationType === 'POP') && branches) { + const [name, source] = getNormalizedName(routes, location, branches, basename); + + startBrowserTracingNavigationSpan(client, { + name, + attributes: { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: `auto.navigation.react.reactrouter_v${version}`, + }, + }); + } +} + +/** + * Strip the basename from a pathname if exists. + * + * Vendored and modified from `react-router` + * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038 + */ +function stripBasenameFromPathname(pathname: string, basename: string): string { + if (!basename || basename === '/') { + return pathname; + } + + if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { + return pathname; + } + + // We want to leave trailing slash behavior in the user's control, so if they + // specify a basename with a trailing slash, we should support it + const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length; + const nextChar = pathname.charAt(startIndex); + if (nextChar && nextChar !== '/') { + // pathname does not start with basename/ + return pathname; + } + + return pathname.slice(startIndex) || '/'; +} + +function sendIndexPath(pathBuilder: string, pathname: string, basename: string): [string, TransactionSource] { + const reconstructedPath = pathBuilder || _stripBasename ? stripBasenameFromPathname(pathname, basename) : pathname; + + const formattedPath = + // If the path ends with a slash, remove it + reconstructedPath[reconstructedPath.length - 1] === '/' + ? reconstructedPath.slice(0, -1) + : // If the path ends with a wildcard, remove it + reconstructedPath.slice(-2) === '/*' + ? reconstructedPath.slice(0, -1) + : reconstructedPath; + + return [formattedPath, 'route']; +} + +function pathEndsWithWildcard(path: string, branch: RouteMatch): boolean { + return (path.slice(-2) === '/*' && branch.route.children && branch.route.children.length > 0) || false; +} + +function pathIsWildcardAndHasChildren(path: string, branch: RouteMatch): boolean { + return (path === '*' && branch.route.children && branch.route.children.length > 0) || false; +} + +function getNormalizedName( + routes: RouteObject[], + location: Location, + branches: RouteMatch[], + basename: string = '', +): [string, TransactionSource] { + if (!routes || routes.length === 0) { + return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url']; + } + + let pathBuilder = ''; + if (branches) { + for (const branch of branches) { + const route = branch.route; + if (route) { + // Early return if index route + if (route.index) { + return sendIndexPath(pathBuilder, branch.pathname, basename); + } + const path = route.path; + + // If path is not a wildcard and has no child routes, append the path + if (path && !pathIsWildcardAndHasChildren(path, branch)) { + const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`; + pathBuilder += newPath; + + // If the path matches the current location, return the path + if (basename + branch.pathname === location.pathname) { + if ( + // If the route defined on the element is something like + // Product} /> + // We should check against the branch.pathname for the number of / separators + // TODO(v9): Put the implementation of `getNumberOfUrlSegments` in this file + // eslint-disable-next-line deprecation/deprecation + getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) && + // We should not count wildcard operators in the url segments calculation + pathBuilder.slice(-2) !== '/*' + ) { + return [(_stripBasename ? '' : basename) + newPath, 'route']; + } + + // if the last character of the pathbuilder is a wildcard and there are children, remove the wildcard + if (pathEndsWithWildcard(pathBuilder, branch)) { + pathBuilder = pathBuilder.slice(0, -1); + } + + return [(_stripBasename ? '' : basename) + pathBuilder, 'route']; + } + } + } + } + } + + return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url']; +} + +function updatePageloadTransaction( + activeRootSpan: Span | undefined, + location: Location, + routes: RouteObject[], + matches?: AgnosticDataRouteMatch, + basename?: string, +): void { + const branches = Array.isArray(matches) + ? matches + : (_matchRoutes(routes, location, basename) as unknown as RouteMatch[]); + + if (branches) { + const [name, source] = getNormalizedName(routes, location, branches, basename); + + getCurrentScope().setTransactionName(name); + + if (activeRootSpan) { + activeRootSpan.updateName(name); + activeRootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source); + } + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function createV6CompatibleWithSentryReactRouterRouting

, R extends React.FC

>( + Routes: R, + version: V6CompatibleVersion, +): R { + if (!_useEffect || !_useLocation || !_useNavigationType || !_createRoutesFromChildren || !_matchRoutes) { + DEBUG_BUILD && + logger.warn(`reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters. + useEffect: ${_useEffect}. useLocation: ${_useLocation}. useNavigationType: ${_useNavigationType}. + createRoutesFromChildren: ${_createRoutesFromChildren}. matchRoutes: ${_matchRoutes}.`); + + return Routes; + } + + let isMountRenderPass: boolean = true; + + const SentryRoutes: React.FC

= (props: P) => { + const location = _useLocation(); + const navigationType = _useNavigationType(); + + _useEffect( + () => { + const routes = _createRoutesFromChildren(props.children) as RouteObject[]; + + if (isMountRenderPass) { + updatePageloadTransaction(getActiveRootSpan(), location, routes); + isMountRenderPass = false; + } else { + handleNavigation(location, routes, navigationType, version); + } + }, + // `props.children` is purposely not included in the dependency array, because we do not want to re-run this effect + // when the children change. We only want to start transactions when the location or navigation type change. + [location, navigationType], + ); + + // @ts-expect-error Setting more specific React Component typing for `R` generic above + // will break advanced type inference done by react router params + return ; + }; + + hoistNonReactStatics(SentryRoutes, Routes); + + // @ts-expect-error Setting more specific React Component typing for `R` generic above + // will break advanced type inference done by react router params + return SentryRoutes; +} + +function getActiveRootSpan(): Span | undefined { + const span = getActiveSpan(); + const rootSpan = span ? getRootSpan(span) : undefined; + + if (!rootSpan) { + return undefined; + } + + const op = spanToJSON(rootSpan).op; + + // Only use this root span if it is a pageload or navigation span + return op === 'navigation' || op === 'pageload' ? rootSpan : undefined; +} diff --git a/packages/react/src/reactrouterv6.tsx b/packages/react/src/reactrouterv6.tsx index b209391f1dda..81afc2933861 100644 --- a/packages/react/src/reactrouterv6.tsx +++ b/packages/react/src/reactrouterv6.tsx @@ -1,63 +1,13 @@ -/* eslint-disable max-lines */ -// Inspired from Donnie McNeal's solution: -// https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536 - -import { - WINDOW, - browserTracingIntegration, - startBrowserTracingNavigationSpan, - startBrowserTracingPageLoadSpan, -} from '@sentry/browser'; +import type { browserTracingIntegration } from '@sentry/browser'; +import type { Integration } from '@sentry/core'; +import type { ReactRouterOptions } from './reactrouterv6-compat-utils'; import { - SEMANTIC_ATTRIBUTE_SENTRY_OP, - SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - getActiveSpan, - getClient, - getCurrentScope, - getRootSpan, - spanToJSON, -} from '@sentry/core'; -import { getNumberOfUrlSegments, logger } from '@sentry/core'; -import type { Client, Integration, Span, TransactionSource } from '@sentry/types'; -import hoistNonReactStatics from 'hoist-non-react-statics'; -import * as React from 'react'; - -import { DEBUG_BUILD } from './debug-build'; -import type { - Action, - AgnosticDataRouteMatch, - CreateRouterFunction, - CreateRoutesFromChildren, - Location, - MatchRoutes, - RouteMatch, - RouteObject, - Router, - RouterState, - UseEffect, - UseLocation, - UseNavigationType, - UseRoutes, -} from './types'; - -let _useEffect: UseEffect; -let _useLocation: UseLocation; -let _useNavigationType: UseNavigationType; -let _createRoutesFromChildren: CreateRoutesFromChildren; -let _matchRoutes: MatchRoutes; -let _stripBasename: boolean = false; - -const CLIENTS_WITH_INSTRUMENT_NAVIGATION = new WeakSet(); - -interface ReactRouterOptions { - useEffect: UseEffect; - useLocation: UseLocation; - useNavigationType: UseNavigationType; - createRoutesFromChildren: CreateRoutesFromChildren; - matchRoutes: MatchRoutes; - stripBasename?: boolean; -} + createReactRouterV6CompatibleTracingIntegration, + createV6CompatibleWithSentryReactRouterRouting, + createV6CompatibleWrapCreateBrowserRouter, + createV6CompatibleWrapUseRoutes, +} from './reactrouterv6-compat-utils'; +import type { CreateRouterFunction, Router, RouterState, UseRoutes } from './types'; /** * A browser tracing integration that uses React Router v6 to instrument navigations. @@ -66,356 +16,45 @@ interface ReactRouterOptions { export function reactRouterV6BrowserTracingIntegration( options: Parameters[0] & ReactRouterOptions, ): Integration { - const integration = browserTracingIntegration({ - ...options, - instrumentPageLoad: false, - instrumentNavigation: false, - }); - - const { - useEffect, - useLocation, - useNavigationType, - createRoutesFromChildren, - matchRoutes, - stripBasename, - instrumentPageLoad = true, - instrumentNavigation = true, - } = options; - - return { - ...integration, - setup() { - _useEffect = useEffect; - _useLocation = useLocation; - _useNavigationType = useNavigationType; - _matchRoutes = matchRoutes; - _createRoutesFromChildren = createRoutesFromChildren; - _stripBasename = stripBasename || false; - }, - afterAllSetup(client) { - integration.afterAllSetup(client); - - const initPathName = WINDOW && WINDOW.location && WINDOW.location.pathname; - if (instrumentPageLoad && initPathName) { - startBrowserTracingPageLoadSpan(client, { - name: initPathName, - attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.react.reactrouter_v6', - }, - }); - } - - if (instrumentNavigation) { - CLIENTS_WITH_INSTRUMENT_NAVIGATION.add(client); - } - }, - }; + return createReactRouterV6CompatibleTracingIntegration(options, '6'); } /** - * Strip the basename from a pathname if exists. - * - * Vendored and modified from `react-router` - * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038 + * A wrapper function that adds Sentry routing instrumentation to a React Router v6 useRoutes hook. + * This is used to automatically capture route changes as transactions when using the useRoutes hook. */ -function stripBasenameFromPathname(pathname: string, basename: string): string { - if (!basename || basename === '/') { - return pathname; - } - - if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) { - return pathname; - } - - // We want to leave trailing slash behavior in the user's control, so if they - // specify a basename with a trailing slash, we should support it - const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length; - const nextChar = pathname.charAt(startIndex); - if (nextChar && nextChar !== '/') { - // pathname does not start with basename/ - return pathname; - } - - return pathname.slice(startIndex) || '/'; -} - -function sendIndexPath(pathBuilder: string, pathname: string, basename: string): [string, TransactionSource] { - const reconstructedPath = pathBuilder || _stripBasename ? stripBasenameFromPathname(pathname, basename) : pathname; - - const formattedPath = - // If the path ends with a slash, remove it - reconstructedPath[reconstructedPath.length - 1] === '/' - ? reconstructedPath.slice(0, -1) - : // If the path ends with a wildcard, remove it - reconstructedPath.slice(-2) === '/*' - ? reconstructedPath.slice(0, -1) - : reconstructedPath; - - return [formattedPath, 'route']; -} - -function pathEndsWithWildcard(path: string, branch: RouteMatch): boolean { - return (path.slice(-2) === '/*' && branch.route.children && branch.route.children.length > 0) || false; -} - -function pathIsWildcardAndHasChildren(path: string, branch: RouteMatch): boolean { - return (path === '*' && branch.route.children && branch.route.children.length > 0) || false; -} - -function getNormalizedName( - routes: RouteObject[], - location: Location, - branches: RouteMatch[], - basename: string = '', -): [string, TransactionSource] { - if (!routes || routes.length === 0) { - return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url']; - } - - let pathBuilder = ''; - if (branches) { - for (const branch of branches) { - const route = branch.route; - if (route) { - // Early return if index route - if (route.index) { - return sendIndexPath(pathBuilder, branch.pathname, basename); - } - const path = route.path; - - // If path is not a wildcard and has no child routes, append the path - if (path && !pathIsWildcardAndHasChildren(path, branch)) { - const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`; - pathBuilder += newPath; - - // If the path matches the current location, return the path - if (basename + branch.pathname === location.pathname) { - if ( - // If the route defined on the element is something like - // Product} /> - // We should check against the branch.pathname for the number of / separators - getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) && - // We should not count wildcard operators in the url segments calculation - pathBuilder.slice(-2) !== '/*' - ) { - return [(_stripBasename ? '' : basename) + newPath, 'route']; - } - - // if the last character of the pathbuilder is a wildcard and there are children, remove the wildcard - if (pathEndsWithWildcard(pathBuilder, branch)) { - pathBuilder = pathBuilder.slice(0, -1); - } - - return [(_stripBasename ? '' : basename) + pathBuilder, 'route']; - } - } - } - } - } - - return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url']; -} - -function updatePageloadTransaction( - activeRootSpan: Span | undefined, - location: Location, - routes: RouteObject[], - matches?: AgnosticDataRouteMatch, - basename?: string, -): void { - const branches = Array.isArray(matches) - ? matches - : (_matchRoutes(routes, location, basename) as unknown as RouteMatch[]); - - if (branches) { - const [name, source] = getNormalizedName(routes, location, branches, basename); - - getCurrentScope().setTransactionName(name); - - if (activeRootSpan) { - activeRootSpan.updateName(name); - activeRootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, source); - } - } -} - -function handleNavigation( - location: Location, - routes: RouteObject[], - navigationType: Action, - matches?: AgnosticDataRouteMatch, - basename?: string, -): void { - const branches = Array.isArray(matches) ? matches : _matchRoutes(routes, location, basename); - - const client = getClient(); - if (!client || !CLIENTS_WITH_INSTRUMENT_NAVIGATION.has(client)) { - return; - } - - if ((navigationType === 'PUSH' || navigationType === 'POP') && branches) { - const [name, source] = getNormalizedName(routes, location, branches, basename); - - startBrowserTracingNavigationSpan(client, { - name, - attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react.reactrouter_v6', - }, - }); - } +export function wrapUseRoutesV6(origUseRoutes: UseRoutes): UseRoutes { + return createV6CompatibleWrapUseRoutes(origUseRoutes, '6'); } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function withSentryReactRouterV6Routing

, R extends React.FC

>(Routes: R): R { - if (!_useEffect || !_useLocation || !_useNavigationType || !_createRoutesFromChildren || !_matchRoutes) { - DEBUG_BUILD && - logger.warn(`reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters. - useEffect: ${_useEffect}. useLocation: ${_useLocation}. useNavigationType: ${_useNavigationType}. - createRoutesFromChildren: ${_createRoutesFromChildren}. matchRoutes: ${_matchRoutes}.`); - - return Routes; - } - - let isMountRenderPass: boolean = true; - - const SentryRoutes: React.FC

= (props: P) => { - const location = _useLocation(); - const navigationType = _useNavigationType(); - - _useEffect( - () => { - const routes = _createRoutesFromChildren(props.children) as RouteObject[]; - - if (isMountRenderPass) { - updatePageloadTransaction(getActiveRootSpan(), location, routes); - isMountRenderPass = false; - } else { - handleNavigation(location, routes, navigationType); - } - }, - // `props.children` is purposely not included in the dependency array, because we do not want to re-run this effect - // when the children change. We only want to start transactions when the location or navigation type change. - [location, navigationType], - ); - - // @ts-expect-error Setting more specific React Component typing for `R` generic above - // will break advanced type inference done by react router params - return ; - }; - - hoistNonReactStatics(SentryRoutes, Routes); - - // @ts-expect-error Setting more specific React Component typing for `R` generic above - // will break advanced type inference done by react router params - return SentryRoutes; -} - -export function wrapUseRoutes(origUseRoutes: UseRoutes): UseRoutes { - if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) { - DEBUG_BUILD && - logger.warn( - 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.', - ); - - return origUseRoutes; - } - - let isMountRenderPass: boolean = true; - - const SentryRoutes: React.FC<{ - children?: React.ReactNode; - routes: RouteObject[]; - locationArg?: Partial | string; - }> = (props: { children?: React.ReactNode; routes: RouteObject[]; locationArg?: Partial | string }) => { - const { routes, locationArg } = props; - - const Routes = origUseRoutes(routes, locationArg); - - const location = _useLocation(); - const navigationType = _useNavigationType(); - - // A value with stable identity to either pick `locationArg` if available or `location` if not - const stableLocationParam = - typeof locationArg === 'string' || (locationArg && locationArg.pathname) - ? (locationArg as { pathname: string }) - : location; - - _useEffect(() => { - const normalizedLocation = - typeof stableLocationParam === 'string' ? { pathname: stableLocationParam } : stableLocationParam; - - if (isMountRenderPass) { - updatePageloadTransaction(getActiveRootSpan(), normalizedLocation, routes); - isMountRenderPass = false; - } else { - handleNavigation(normalizedLocation, routes, navigationType); - } - }, [navigationType, stableLocationParam]); - - return Routes; - }; - - // eslint-disable-next-line react/display-name - return (routes: RouteObject[], locationArg?: Partial | string): React.ReactElement | null => { - return ; - }; -} +/** + * Alias for backwards compatibility + * @deprecated Use `wrapUseRoutesV6` or `wrapUseRoutesV7` instead. + */ +export const wrapUseRoutes = wrapUseRoutesV6; -export function wrapCreateBrowserRouter< +/** + * A wrapper function that adds Sentry routing instrumentation to a React Router v6 createBrowserRouter function. + * This is used to automatically capture route changes as transactions when using the createBrowserRouter API. + */ +export function wrapCreateBrowserRouterV6< TState extends RouterState = RouterState, TRouter extends Router = Router, >(createRouterFunction: CreateRouterFunction): CreateRouterFunction { - if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes) { - DEBUG_BUILD && - logger.warn( - 'reactRouterV6Instrumentation was unable to wrap the `createRouter` function because of one or more missing parameters.', - ); - - return createRouterFunction; - } - - // `opts` for createBrowserHistory and createMemoryHistory are different, but also not relevant for us at the moment. - // `basename` is the only option that is relevant for us, and it is the same for all. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return function (routes: RouteObject[], opts?: Record & { basename?: string }): TRouter { - const router = createRouterFunction(routes, opts); - const basename = opts && opts.basename; - - const activeRootSpan = getActiveRootSpan(); - - // The initial load ends when `createBrowserRouter` is called. - // This is the earliest convenient time to update the transaction name. - // Callbacks to `router.subscribe` are not called for the initial load. - if (router.state.historyAction === 'POP' && activeRootSpan) { - updatePageloadTransaction(activeRootSpan, router.state.location, routes, undefined, basename); - } - - router.subscribe((state: RouterState) => { - const location = state.location; - if (state.historyAction === 'PUSH' || state.historyAction === 'POP') { - handleNavigation(location, routes, state.historyAction, undefined, basename); - } - }); - - return router; - }; + return createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, '6'); } -function getActiveRootSpan(): Span | undefined { - const span = getActiveSpan(); - const rootSpan = span ? getRootSpan(span) : undefined; - - if (!rootSpan) { - return undefined; - } - - const op = spanToJSON(rootSpan).op; +/** + * Alias for backwards compatibility + * @deprecated Use `wrapCreateBrowserRouterV6` or `wrapCreateBrowserRouterV7` instead. + */ +export const wrapCreateBrowserRouter = wrapCreateBrowserRouterV6; - // Only use this root span if it is a pageload or navigation span - return op === 'navigation' || op === 'pageload' ? rootSpan : undefined; +/** + * A higher-order component that adds Sentry routing instrumentation to a React Router v6 Route component. + * This is used to automatically capture route changes as transactions. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function withSentryReactRouterV6Routing

, R extends React.FC

>(routes: R): R { + return createV6CompatibleWithSentryReactRouterRouting(routes, '6'); } diff --git a/packages/react/src/reactrouterv7.tsx b/packages/react/src/reactrouterv7.tsx new file mode 100644 index 000000000000..df2badd35e44 --- /dev/null +++ b/packages/react/src/reactrouterv7.tsx @@ -0,0 +1,49 @@ +// React Router v7 uses the same integration as v6 +import type { browserTracingIntegration } from '@sentry/browser'; +import type { Integration } from '@sentry/core'; +import type { ReactRouterOptions } from './reactrouterv6-compat-utils'; +import { + createReactRouterV6CompatibleTracingIntegration, + createV6CompatibleWithSentryReactRouterRouting, + createV6CompatibleWrapCreateBrowserRouter, + createV6CompatibleWrapUseRoutes, +} from './reactrouterv6-compat-utils'; +import type { CreateRouterFunction, Router, RouterState, UseRoutes } from './types'; + +/** + * A browser tracing integration that uses React Router v7 to instrument navigations. + * Expects `useEffect`, `useLocation`, `useNavigationType`, `createRoutesFromChildren` and `matchRoutes` to be passed as options. + */ +export function reactRouterV7BrowserTracingIntegration( + options: Parameters[0] & ReactRouterOptions, +): Integration { + return createReactRouterV6CompatibleTracingIntegration(options, '7'); +} + +/** + * A higher-order component that adds Sentry routing instrumentation to a React Router v7 Route component. + * This is used to automatically capture route changes as transactions. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function withSentryReactRouterV7Routing

, R extends React.FC

>(routes: R): R { + return createV6CompatibleWithSentryReactRouterRouting(routes, '7'); +} + +/** + * A wrapper function that adds Sentry routing instrumentation to a React Router v7 createBrowserRouter function. + * This is used to automatically capture route changes as transactions when using the createBrowserRouter API. + */ +export function wrapCreateBrowserRouterV7< + TState extends RouterState = RouterState, + TRouter extends Router = Router, +>(createRouterFunction: CreateRouterFunction): CreateRouterFunction { + return createV6CompatibleWrapCreateBrowserRouter(createRouterFunction, '7'); +} + +/** + * A wrapper function that adds Sentry routing instrumentation to a React Router v7 useRoutes hook. + * This is used to automatically capture route changes as transactions when using the useRoutes hook. + */ +export function wrapUseRoutesV7(origUseRoutes: UseRoutes): UseRoutes { + return createV6CompatibleWrapUseRoutes(origUseRoutes, '7'); +} diff --git a/packages/react/src/redux.ts b/packages/react/src/redux.ts index c3dea1b517c7..47830b384a15 100644 --- a/packages/react/src/redux.ts +++ b/packages/react/src/redux.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { addBreadcrumb, getClient, getCurrentScope, getGlobalScope } from '@sentry/core'; -import { addNonEnumerableProperty } from '@sentry/core'; -import type { Scope } from '@sentry/types'; +import type { Scope } from '@sentry/core'; +import { addBreadcrumb, addNonEnumerableProperty, getClient, getCurrentScope, getGlobalScope } from '@sentry/core'; interface Action { type: T; diff --git a/packages/react/src/sdk.ts b/packages/react/src/sdk.ts index 952b1d3c3927..da63e6d9aa08 100644 --- a/packages/react/src/sdk.ts +++ b/packages/react/src/sdk.ts @@ -1,7 +1,7 @@ import type { BrowserOptions } from '@sentry/browser'; import { init as browserInit, setContext } from '@sentry/browser'; import { applySdkMetadata } from '@sentry/core'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import { version } from 'react'; diff --git a/packages/react/src/tanstackrouter.ts b/packages/react/src/tanstackrouter.ts index 2efefba49e31..48c4ccb56888 100644 --- a/packages/react/src/tanstackrouter.ts +++ b/packages/react/src/tanstackrouter.ts @@ -1,12 +1,15 @@ -import { WINDOW, startBrowserTracingNavigationSpan, startBrowserTracingPageLoadSpan } from '@sentry/browser'; +import { + WINDOW, + browserTracingIntegration as originalBrowserTracingIntegration, + startBrowserTracingNavigationSpan, + startBrowserTracingPageLoadSpan, +} from '@sentry/browser'; +import type { Integration } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, } from '@sentry/core'; - -import { browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/browser'; -import type { Integration } from '@sentry/types'; import type { VendoredTanstackRouter, VendoredTanstackRouterRouteMatch } from './vendor/tanstackrouter-types'; /** diff --git a/packages/react/test/errorboundary.test.tsx b/packages/react/test/errorboundary.test.tsx index b4d907ef0873..e0a7328995e0 100644 --- a/packages/react/test/errorboundary.test.tsx +++ b/packages/react/test/errorboundary.test.tsx @@ -1,5 +1,5 @@ import { Scope, getClient, setCurrentClient } from '@sentry/browser'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import { fireEvent, render, screen } from '@testing-library/react'; import * as React from 'react'; import { useState } from 'react'; diff --git a/packages/react/test/profiler.test.tsx b/packages/react/test/profiler.test.tsx index 07f34d526915..a04abd7b9f71 100644 --- a/packages/react/test/profiler.test.tsx +++ b/packages/react/test/profiler.test.tsx @@ -1,5 +1,5 @@ import { SentrySpan } from '@sentry/core'; -import type { StartSpanOptions } from '@sentry/types'; +import type { StartSpanOptions } from '@sentry/core'; import { render } from '@testing-library/react'; import { renderHook } from '@testing-library/react-hooks'; // biome-ignore lint/nursery/noUnusedImports: Need React import for JSX diff --git a/packages/react/test/reactrouterv6.4.test.tsx b/packages/react/test/reactrouterv6.4.test.tsx index f3b7288872fc..3ae6a69bdf56 100644 --- a/packages/react/test/reactrouterv6.4.test.tsx +++ b/packages/react/test/reactrouterv6.4.test.tsx @@ -94,6 +94,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -135,6 +136,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -168,6 +170,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -213,6 +216,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -264,6 +268,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -315,6 +320,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -378,6 +384,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -419,6 +426,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -471,6 +479,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -528,6 +537,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { stripBasename: true, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -585,6 +595,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { stripBasename: true, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( @@ -637,6 +648,7 @@ describe('reactRouterV6BrowserTracingIntegration (v6.4)', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction); const router = sentryCreateBrowserRouter( diff --git a/packages/react/test/reactrouterv6.test.tsx b/packages/react/test/reactrouterv6.test.tsx index de65159c56e4..b9cf4003c330 100644 --- a/packages/react/test/reactrouterv6.test.tsx +++ b/packages/react/test/reactrouterv6.test.tsx @@ -536,6 +536,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -577,6 +578,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -611,6 +613,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -645,6 +648,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -682,6 +686,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -726,6 +731,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -776,6 +782,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -826,6 +833,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -882,6 +890,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -962,6 +971,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -1040,6 +1050,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -1098,6 +1109,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => @@ -1155,6 +1167,7 @@ describe('reactRouterV6BrowserTracingIntegration', () => { matchRoutes, }), ); + // eslint-disable-next-line deprecation/deprecation const wrappedUseRoutes = wrapUseRoutes(useRoutes); const Routes = () => diff --git a/packages/remix/package.json b/packages/remix/package.json index 5b5be3dfc911..3a0d716edf93 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/remix", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Remix", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/remix", @@ -54,11 +54,10 @@ "dependencies": { "@remix-run/router": "1.x", "@sentry/cli": "^2.38.2", - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/opentelemetry": "8.40.0", - "@sentry/react": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", + "@sentry/opentelemetry": "8.42.0", + "@sentry/react": "8.42.0", "glob": "^10.3.4", "opentelemetry-instrumentation-remix": "0.7.1", "yargs": "^17.6.0" diff --git a/packages/remix/src/client/browserTracingIntegration.ts b/packages/remix/src/client/browserTracingIntegration.ts index ce7387904e57..a52b3ac7e30b 100644 --- a/packages/remix/src/client/browserTracingIntegration.ts +++ b/packages/remix/src/client/browserTracingIntegration.ts @@ -1,5 +1,5 @@ +import type { Integration } from '@sentry/core'; import { browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/react'; -import type { Integration } from '@sentry/types'; import { setGlobals, startPageloadSpan } from './performance'; import type { RemixBrowserTracingIntegrationOptions } from './performance'; /** diff --git a/packages/remix/src/client/errors.tsx b/packages/remix/src/client/errors.tsx index 8aa5e2e85dfb..6005ba2cb480 100644 --- a/packages/remix/src/client/errors.tsx +++ b/packages/remix/src/client/errors.tsx @@ -1,6 +1,4 @@ -import { captureException } from '@sentry/core'; -import { isNodeEnv } from '@sentry/core'; - +import { captureException, isNodeEnv } from '@sentry/core'; import { isResponse } from '../utils/vendor/response'; /** diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 83028abc3862..c9518cdf5352 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -1,13 +1,18 @@ +import type { Client, StartSpanOptions } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, getCurrentScope, getRootSpan, + isNodeEnv, + logger, } from '@sentry/core'; -import { isNodeEnv, logger } from '@sentry/core'; -import type { browserTracingIntegration as originalBrowserTracingIntegration } from '@sentry/react'; -import type { BrowserClient, ErrorBoundaryProps } from '@sentry/react'; +import type { + BrowserClient, + ErrorBoundaryProps, + browserTracingIntegration as originalBrowserTracingIntegration, +} from '@sentry/react'; import { WINDOW, getClient, @@ -15,9 +20,7 @@ import { startBrowserTracingPageLoadSpan, withErrorBoundary, } from '@sentry/react'; -import type { Client, StartSpanOptions } from '@sentry/types'; import * as React from 'react'; - import { DEBUG_BUILD } from '../utils/debug-build'; import { getFutureFlagsBrowser, readRemixVersionFromLoader } from '../utils/futureFlags'; diff --git a/packages/remix/src/index.client.tsx b/packages/remix/src/index.client.tsx index f75581f14a68..846366c1d73c 100644 --- a/packages/remix/src/index.client.tsx +++ b/packages/remix/src/index.client.tsx @@ -1,13 +1,15 @@ -import { applySdkMetadata } from '@sentry/core'; -import { logger } from '@sentry/core'; +/* eslint-enable @typescript-eslint/no-unused-vars */ + +import type { Client } from '@sentry/core'; +import { applySdkMetadata, logger } from '@sentry/core'; import { init as reactInit } from '@sentry/react'; -import type { Client } from '@sentry/types'; import { DEBUG_BUILD } from './utils/debug-build'; import type { RemixOptions } from './utils/remixOptions'; -export { captureRemixErrorBoundaryError } from './client/errors'; -export { withSentry } from './client/performance'; export { browserTracingIntegration } from './client/browserTracingIntegration'; +export { captureRemixErrorBoundaryError } from './client/errors'; +export { withSentry } from './client/performance'; +export * from '@sentry/react'; // This is a no-op function that does nothing. It's here to make sure that the // function signature is the same as in the server SDK. @@ -25,9 +27,6 @@ export async function captureRemixServerException( 'This function is a no-op in the browser environment.', ); } -/* eslint-enable @typescript-eslint/no-unused-vars */ - -export * from '@sentry/react'; export function init(options: RemixOptions): Client | undefined { const opts = { diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index 2e7dd3708806..a92d1d94ca08 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -1,8 +1,7 @@ -import { applySdkMetadata } from '@sentry/core'; -import { logger } from '@sentry/core'; +import { applySdkMetadata, logger } from '@sentry/core'; +import type { Integration } from '@sentry/core'; import type { NodeClient, NodeOptions } from '@sentry/node'; import { getDefaultIntegrations as getDefaultNodeIntegrations, init as nodeInit, isInitialized } from '@sentry/node'; -import type { Integration } from '@sentry/types'; import { DEBUG_BUILD } from './utils/debug-build'; import { instrumentServer } from './utils/instrumentServer'; @@ -16,6 +15,7 @@ export { addBreadcrumb, addEventProcessor, addIntegration, + // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, // eslint-disable-next-line deprecation/deprecation addRequestDataToEvent, @@ -168,6 +168,7 @@ export function getRemixDefaultIntegrations(options: RemixOptions): Integration[ return [ ...getDefaultNodeIntegrations(options as NodeOptions).filter(integration => integration.name !== 'Http'), httpIntegration(), + // eslint-disable-next-line deprecation/deprecation options.autoInstrumentRemix ? remixIntegration() : undefined, ].filter(int => int) as Integration[]; } diff --git a/packages/remix/src/index.types.ts b/packages/remix/src/index.types.ts index 46052b99473d..cfba5f67e781 100644 --- a/packages/remix/src/index.types.ts +++ b/packages/remix/src/index.types.ts @@ -3,7 +3,7 @@ export * from './index.client'; export * from './index.server'; -import type { Client, Integration, Options, StackParser } from '@sentry/types'; +import type { Client, Integration, Options, StackParser } from '@sentry/core'; import * as clientSdk from './index.client'; import * as serverSdk from './index.server'; diff --git a/packages/remix/src/utils/errors.ts b/packages/remix/src/utils/errors.ts index d2e040bcd05c..94c1c8755ad4 100644 --- a/packages/remix/src/utils/errors.ts +++ b/packages/remix/src/utils/errors.ts @@ -9,7 +9,7 @@ import { objectify, winterCGRequestToRequestData, } from '@sentry/core'; -import type { RequestEventData, Span } from '@sentry/types'; +import type { RequestEventData, Span } from '@sentry/core'; import { DEBUG_BUILD } from './debug-build'; import type { RemixOptions } from './remixOptions'; import { storeFormDataKeys } from './utils'; diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index ac1382bc5e00..797c295b0abf 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -1,24 +1,25 @@ /* eslint-disable max-lines */ +import type { RequestEventData, Span, TransactionSource, WrappedFunction } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + fill, getActiveSpan, getClient, getRootSpan, + getTraceData, hasTracingEnabled, + isNodeEnv, + loadModule, + logger, setHttpStatus, spanToJSON, - spanToTraceHeader, startSpan, winterCGRequestToRequestData, withIsolationScope, } from '@sentry/core'; -import { dynamicSamplingContextToSentryBaggageHeader, fill, isNodeEnv, loadModule, logger } from '@sentry/core'; -import { continueTrace, getDynamicSamplingContextFromSpan } from '@sentry/opentelemetry'; -import type { RequestEventData, TransactionSource, WrappedFunction } from '@sentry/types'; -import type { Span } from '@sentry/types'; - +import { continueTrace } from '@sentry/opentelemetry'; import { DEBUG_BUILD } from './debug-build'; import { captureRemixServerException, errorHandleDataFunction, errorHandleDocumentRequestFunction } from './errors'; import { getFutureFlagsServer, getRemixVersionFromBuild } from './futureFlags'; @@ -204,18 +205,13 @@ function getTraceAndBaggage(): { sentryTrace?: string; sentryBaggage?: string; } { - if (isNodeEnv() && hasTracingEnabled()) { - const span = getActiveSpan(); - const rootSpan = span && getRootSpan(span); - - if (rootSpan) { - const dynamicSamplingContext = getDynamicSamplingContextFromSpan(rootSpan); + if (isNodeEnv()) { + const traceData = getTraceData(); - return { - sentryTrace: spanToTraceHeader(span), - sentryBaggage: dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext), - }; - } + return { + sentryTrace: traceData['sentry-trace'], + sentryBaggage: traceData.baggage, + }; } return {}; @@ -404,6 +400,7 @@ export function instrumentBuild( build: ServerBuild | (() => ServerBuild | Promise), options: RemixOptions, ): ServerBuild | (() => ServerBuild | Promise) { + // eslint-disable-next-line deprecation/deprecation const autoInstrumentRemix = options?.autoInstrumentRemix || false; if (typeof build === 'function') { @@ -439,6 +436,7 @@ const makeWrappedCreateRequestHandler = (options: RemixOptions) => const newBuild = instrumentBuild(build, options); const requestHandler = origCreateRequestHandler.call(this, newBuild, ...args); + // eslint-disable-next-line deprecation/deprecation return wrapRequestHandler(requestHandler, newBuild, options.autoInstrumentRemix || false); }; }; diff --git a/packages/remix/src/utils/integrations/http.ts b/packages/remix/src/utils/integrations/http.ts index be519a36806a..9d35cb4547df 100644 --- a/packages/remix/src/utils/integrations/http.ts +++ b/packages/remix/src/utils/integrations/http.ts @@ -1,5 +1,5 @@ +import type { IntegrationFn } from '@sentry/core'; import { httpIntegration as originalHttpIntegration } from '@sentry/node'; -import type { IntegrationFn } from '@sentry/types'; type HttpOptions = Parameters[0]; diff --git a/packages/remix/src/utils/integrations/opentelemetry.ts b/packages/remix/src/utils/integrations/opentelemetry.ts index fa1d8fd1b749..cfc952e9dd23 100644 --- a/packages/remix/src/utils/integrations/opentelemetry.ts +++ b/packages/remix/src/utils/integrations/opentelemetry.ts @@ -1,8 +1,8 @@ import { RemixInstrumentation } from 'opentelemetry-instrumentation-remix'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration } from '@sentry/core'; +import type { Client, IntegrationFn, Span } from '@sentry/core'; import { generateInstrumentOnce, getClient, spanToJSON } from '@sentry/node'; -import type { Client, IntegrationFn, Span } from '@sentry/types'; import type { RemixOptions } from '../remixOptions'; const INTEGRATION_NAME = 'Remix'; diff --git a/packages/remix/src/utils/remixOptions.ts b/packages/remix/src/utils/remixOptions.ts index 4f73eca92ff3..58e8ae74b1d2 100644 --- a/packages/remix/src/utils/remixOptions.ts +++ b/packages/remix/src/utils/remixOptions.ts @@ -1,8 +1,25 @@ +import type { Options } from '@sentry/core'; import type { NodeOptions } from '@sentry/node'; import type { BrowserOptions } from '@sentry/react'; -import type { Options } from '@sentry/types'; export type RemixOptions = (Options | BrowserOptions | NodeOptions) & { captureActionFormDataKeys?: Record; - autoInstrumentRemix?: boolean; -}; +} & ( + | { + /** + * Enables OpenTelemetry Remix instrumentation. + * + * Note: This option will be the default behavior and will be removed in the next major version. + */ + autoInstrumentRemix?: true; + } + | { + /** + * Enables OpenTelemetry Remix instrumentation + * + * @deprecated Setting this option to `false` is deprecated as the next major version will default to behaving as if this option were `true` and the option itself will be removed. + * It is recommended to set this option to `true`. + */ + autoInstrumentRemix?: false; + } + ); diff --git a/packages/remix/src/utils/utils.ts b/packages/remix/src/utils/utils.ts index 5d1024dbc057..221ae4cf8e6c 100644 --- a/packages/remix/src/utils/utils.ts +++ b/packages/remix/src/utils/utils.ts @@ -1,6 +1,6 @@ import type { DataFunctionArgs } from '@remix-run/node'; import { logger } from '@sentry/core'; -import type { Span, TransactionSource } from '@sentry/types'; +import type { Span, TransactionSource } from '@sentry/core'; import { DEBUG_BUILD } from './debug-build'; import { getRequestMatch, matchServerRoutes } from './vendor/response'; import type { ServerRoute, ServerRouteManifest } from './vendor/types'; diff --git a/packages/remix/test/integration/package.json b/packages/remix/test/integration/package.json index 552c26debdc9..b00f17b330f9 100644 --- a/packages/remix/test/integration/package.json +++ b/packages/remix/test/integration/package.json @@ -32,7 +32,6 @@ "@sentry-internal/replay": "file:../../../replay-internal", "@sentry-internal/replay-canvas": "file:../../../replay-canvas", "@sentry-internal/feedback": "file:../../../feedback", - "@sentry/types": "file:../../../types", "@vanilla-extract/css": "1.13.0", "@vanilla-extract/integration": "6.2.4", "@types/mime": "^3.0.0", diff --git a/packages/remix/test/integration/test/client/capture-exception.test.ts b/packages/remix/test/integration/test/client/capture-exception.test.ts index b7e38abf2f4c..68aaa9e0a018 100644 --- a/packages/remix/test/integration/test/client/capture-exception.test.ts +++ b/packages/remix/test/integration/test/client/capture-exception.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; test('should report a manually captured error.', async ({ page }) => { diff --git a/packages/remix/test/integration/test/client/capture-message.test.ts b/packages/remix/test/integration/test/client/capture-message.test.ts index 234b6ee3d961..ab1a9083d132 100644 --- a/packages/remix/test/integration/test/client/capture-message.test.ts +++ b/packages/remix/test/integration/test/client/capture-message.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; test('should report a manually captured message.', async ({ page }) => { diff --git a/packages/remix/test/integration/test/client/click-error.test.ts b/packages/remix/test/integration/test/client/click-error.test.ts index 1e27cdcbdd69..f9e895b3a8f2 100644 --- a/packages/remix/test/integration/test/client/click-error.test.ts +++ b/packages/remix/test/integration/test/client/click-error.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; const useV2 = process.env.REMIX_VERSION === '2'; diff --git a/packages/remix/test/integration/test/client/errorboundary.test.ts b/packages/remix/test/integration/test/client/errorboundary.test.ts index 8fdfad307179..c679f736ea8e 100644 --- a/packages/remix/test/integration/test/client/errorboundary.test.ts +++ b/packages/remix/test/integration/test/client/errorboundary.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; const useV2 = process.env.REMIX_VERSION === '2'; diff --git a/packages/remix/test/integration/test/client/manualtracing.test.ts b/packages/remix/test/integration/test/client/manualtracing.test.ts index 4c1b01507617..01ae4cf66521 100644 --- a/packages/remix/test/integration/test/client/manualtracing.test.ts +++ b/packages/remix/test/integration/test/client/manualtracing.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { getMultipleSentryEnvelopeRequests } from './utils/helpers'; const useV2 = process.env.REMIX_VERSION === '2'; diff --git a/packages/remix/test/integration/test/client/meta-tags.test.ts b/packages/remix/test/integration/test/client/meta-tags.test.ts index db919d950a2c..5e54226c65d6 100644 --- a/packages/remix/test/integration/test/client/meta-tags.test.ts +++ b/packages/remix/test/integration/test/client/meta-tags.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { getFirstSentryEnvelopeRequest } from './utils/helpers'; test('should inject `sentry-trace` and `baggage` meta tags inside the root page.', async ({ page }) => { diff --git a/packages/remix/test/integration/test/client/pageload.test.ts b/packages/remix/test/integration/test/client/pageload.test.ts index 0e60986873fc..bf45a512fabe 100644 --- a/packages/remix/test/integration/test/client/pageload.test.ts +++ b/packages/remix/test/integration/test/client/pageload.test.ts @@ -1,7 +1,7 @@ const useV2 = process.env.REMIX_VERSION === '2'; import { expect, test } from '@playwright/test'; -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { getFirstSentryEnvelopeRequest } from './utils/helpers'; test('should add `pageload` transaction on load.', async ({ page }) => { diff --git a/packages/remix/test/integration/test/client/root-loader.test.ts b/packages/remix/test/integration/test/client/root-loader.test.ts index 53b7648756e5..431195e8eab7 100644 --- a/packages/remix/test/integration/test/client/root-loader.test.ts +++ b/packages/remix/test/integration/test/client/root-loader.test.ts @@ -25,8 +25,8 @@ test('should inject `sentry-trace` and `baggage` into root loader returning an e const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; @@ -41,8 +41,8 @@ test('should inject `sentry-trace` and `baggage` into root loader returning a pl const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; @@ -59,8 +59,8 @@ test('should inject `sentry-trace` and `baggage` into root loader returning a `J const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; @@ -77,8 +77,8 @@ test('should inject `sentry-trace` and `baggage` into root loader returning a de const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; @@ -93,8 +93,8 @@ test('should inject `sentry-trace` and `baggage` into root loader returning `nul const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; @@ -109,8 +109,8 @@ test('should inject `sentry-trace` and `baggage` into root loader returning `und const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; @@ -130,8 +130,8 @@ test('should inject `sentry-trace` and `baggage` into root loader throwing a red const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; @@ -151,8 +151,8 @@ test('should inject `sentry-trace` and `baggage` into root loader returning a re const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page); - expect(sentryTrace).toEqual(expect.any(String)); - expect(sentryBaggage).toEqual(expect.any(String)); + expect(sentryTrace).toMatch(/.+/); + expect(sentryBaggage).toMatch(/.+/); const rootData = (await getRouteData(page))['root']; diff --git a/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts b/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts index d97427d4f67a..bf69b5e7e35b 100644 --- a/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-legacy/loader.test.ts @@ -1,4 +1,4 @@ -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { describe, expect, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; diff --git a/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts b/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts index dcf45ed617f1..93235b33d54d 100644 --- a/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts +++ b/packages/remix/test/integration/test/server/instrumentation-otel/loader.test.ts @@ -1,4 +1,4 @@ -import { Event } from '@sentry/types'; +import { Event } from '@sentry/core'; import { describe, expect, it } from 'vitest'; import { RemixTestEnv, assertSentryEvent, assertSentryTransaction } from '../utils/helpers'; diff --git a/packages/remix/test/integration/test/server/utils/helpers.ts b/packages/remix/test/integration/test/server/utils/helpers.ts index 61de1975972b..6ab89c7856ac 100644 --- a/packages/remix/test/integration/test/server/utils/helpers.ts +++ b/packages/remix/test/integration/test/server/utils/helpers.ts @@ -3,9 +3,9 @@ import { AddressInfo } from 'net'; import * as path from 'path'; import { createRequestHandler } from '@remix-run/express'; import { logger } from '@sentry/core'; +import type { EnvelopeItemType, Event, TransactionEvent } from '@sentry/core'; /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import * as Sentry from '@sentry/node'; -import type { EnvelopeItemType, Event, TransactionEvent } from '@sentry/types'; import type { AxiosRequestConfig } from 'axios'; import axios from 'axios'; import express from 'express'; diff --git a/packages/replay-canvas/package.json b/packages/replay-canvas/package.json index 3f533c0560ed..82c4b8e75b2d 100644 --- a/packages/replay-canvas/package.json +++ b/packages/replay-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay-canvas", - "version": "8.40.0", + "version": "8.42.0", "description": "Replay canvas integration", "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", @@ -68,9 +68,8 @@ "@sentry-internal/rrweb": "2.29.0" }, "dependencies": { - "@sentry-internal/replay": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry-internal/replay": "8.42.0", + "@sentry/core": "8.42.0" }, "engines": { "node": ">=14.18" diff --git a/packages/replay-canvas/src/canvas.ts b/packages/replay-canvas/src/canvas.ts index e398a545a9ec..6809cdaf815f 100644 --- a/packages/replay-canvas/src/canvas.ts +++ b/packages/replay-canvas/src/canvas.ts @@ -1,7 +1,7 @@ import type { CanvasManagerInterface, CanvasManagerOptions } from '@sentry-internal/replay'; import { CanvasManager } from '@sentry-internal/rrweb'; import { defineIntegration } from '@sentry/core'; -import type { Integration, IntegrationFn } from '@sentry/types'; +import type { Integration, IntegrationFn } from '@sentry/core'; interface ReplayCanvasIntegration extends Integration { snapshot: (canvasElement?: HTMLCanvasElement) => Promise; diff --git a/packages/replay-internal/package.json b/packages/replay-internal/package.json index 23eb1e00aa64..bbdf55c68ee9 100644 --- a/packages/replay-internal/package.json +++ b/packages/replay-internal/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay", - "version": "8.40.0", + "version": "8.42.0", "description": "User replays for Sentry", "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", @@ -68,7 +68,7 @@ "homepage": "https://docs.sentry.io/platforms/javascript/session-replay/", "devDependencies": { "@babel/core": "^7.17.5", - "@sentry-internal/replay-worker": "8.40.0", + "@sentry-internal/replay-worker": "8.42.0", "@sentry-internal/rrweb": "2.29.0", "@sentry-internal/rrweb-snapshot": "2.29.0", "fflate": "^0.8.1", @@ -76,9 +76,8 @@ "jsdom-worker": "^0.2.1" }, "dependencies": { - "@sentry-internal/browser-utils": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry-internal/browser-utils": "8.42.0", + "@sentry/core": "8.42.0" }, "engines": { "node": ">=14.18" diff --git a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts index 956e1fe5c63f..e84c8fb95b62 100644 --- a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts +++ b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts @@ -1,5 +1,5 @@ import { setTimeout } from '@sentry-internal/browser-utils'; -import type { ErrorEvent, Event, TransactionEvent, TransportMakeRequestResponse } from '@sentry/types'; +import type { ErrorEvent, Event, TransactionEvent, TransportMakeRequestResponse } from '@sentry/core'; import type { ReplayContainer } from '../types'; import { isErrorEvent, isTransactionEvent } from '../util/eventUtils'; diff --git a/packages/replay-internal/src/coreHandlers/handleBeforeSendEvent.ts b/packages/replay-internal/src/coreHandlers/handleBeforeSendEvent.ts index a6f2284e7db4..d3491dcb4db7 100644 --- a/packages/replay-internal/src/coreHandlers/handleBeforeSendEvent.ts +++ b/packages/replay-internal/src/coreHandlers/handleBeforeSendEvent.ts @@ -1,5 +1,5 @@ import { getLocationHref } from '@sentry/core'; -import type { ErrorEvent, Event } from '@sentry/types'; +import type { ErrorEvent, Event } from '@sentry/core'; import type { ReplayContainer } from '../types'; import { createBreadcrumb } from '../util/createBreadcrumb'; diff --git a/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts b/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts index d521d3871a6c..f029fe0854fd 100644 --- a/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts +++ b/packages/replay-internal/src/coreHandlers/handleBreadcrumbs.ts @@ -1,7 +1,5 @@ -import { getClient } from '@sentry/core'; -import { normalize } from '@sentry/core'; -import type { Breadcrumb } from '@sentry/types'; - +import type { Breadcrumb } from '@sentry/core'; +import { getClient, normalize } from '@sentry/core'; import { CONSOLE_ARG_MAX_SIZE } from '../constants'; import type { ReplayContainer } from '../types'; import type { ReplayFrame } from '../types/replayFrame'; diff --git a/packages/replay-internal/src/coreHandlers/handleClick.ts b/packages/replay-internal/src/coreHandlers/handleClick.ts index 6be19626315c..da9f51fa2179 100644 --- a/packages/replay-internal/src/coreHandlers/handleClick.ts +++ b/packages/replay-internal/src/coreHandlers/handleClick.ts @@ -1,6 +1,6 @@ import { setTimeout } from '@sentry-internal/browser-utils'; import { IncrementalSource, MouseInteractions, record } from '@sentry-internal/rrweb'; -import type { Breadcrumb } from '@sentry/types'; +import type { Breadcrumb } from '@sentry/core'; import { WINDOW } from '../constants'; import type { diff --git a/packages/replay-internal/src/coreHandlers/handleDom.ts b/packages/replay-internal/src/coreHandlers/handleDom.ts index 168d9529ccb3..457568172a2c 100644 --- a/packages/replay-internal/src/coreHandlers/handleDom.ts +++ b/packages/replay-internal/src/coreHandlers/handleDom.ts @@ -2,7 +2,7 @@ import { record } from '@sentry-internal/rrweb'; import type { serializedElementNodeWithId, serializedNodeWithId } from '@sentry-internal/rrweb-snapshot'; import { NodeType } from '@sentry-internal/rrweb-snapshot'; import { htmlTreeAsString } from '@sentry/core'; -import type { Breadcrumb, HandlerDataDom } from '@sentry/types'; +import type { Breadcrumb, HandlerDataDom } from '@sentry/core'; import type { ReplayContainer } from '../types'; import { createBreadcrumb } from '../util/createBreadcrumb'; diff --git a/packages/replay-internal/src/coreHandlers/handleGlobalEvent.ts b/packages/replay-internal/src/coreHandlers/handleGlobalEvent.ts index 6ba64244fddf..49853014c943 100644 --- a/packages/replay-internal/src/coreHandlers/handleGlobalEvent.ts +++ b/packages/replay-internal/src/coreHandlers/handleGlobalEvent.ts @@ -1,4 +1,4 @@ -import type { Event, EventHint } from '@sentry/types'; +import type { Event, EventHint } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import type { ReplayContainer } from '../types'; diff --git a/packages/replay-internal/src/coreHandlers/handleHistory.ts b/packages/replay-internal/src/coreHandlers/handleHistory.ts index 79167114c135..b033e6e43eaf 100644 --- a/packages/replay-internal/src/coreHandlers/handleHistory.ts +++ b/packages/replay-internal/src/coreHandlers/handleHistory.ts @@ -1,4 +1,4 @@ -import type { HandlerDataHistory } from '@sentry/types'; +import type { HandlerDataHistory } from '@sentry/core'; import type { HistoryData, ReplayContainer, ReplayPerformanceEntry } from '../types'; import { createPerformanceSpans } from '../util/createPerformanceSpans'; diff --git a/packages/replay-internal/src/coreHandlers/handleKeyboardEvent.ts b/packages/replay-internal/src/coreHandlers/handleKeyboardEvent.ts index 52ea76030ebd..5c4485321b26 100644 --- a/packages/replay-internal/src/coreHandlers/handleKeyboardEvent.ts +++ b/packages/replay-internal/src/coreHandlers/handleKeyboardEvent.ts @@ -1,5 +1,5 @@ import { htmlTreeAsString } from '@sentry/core'; -import type { Breadcrumb } from '@sentry/types'; +import type { Breadcrumb } from '@sentry/core'; import type { ReplayContainer } from '../types'; import { createBreadcrumb } from '../util/createBreadcrumb'; diff --git a/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts b/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts index 8b95a1f5fabe..3b3da66284d0 100644 --- a/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts +++ b/packages/replay-internal/src/coreHandlers/handleNetworkBreadcrumbs.ts @@ -1,5 +1,5 @@ import { getClient } from '@sentry/core'; -import type { Breadcrumb, BreadcrumbHint, FetchBreadcrumbData, XhrBreadcrumbData } from '@sentry/types'; +import type { Breadcrumb, BreadcrumbHint, FetchBreadcrumbData, XhrBreadcrumbData } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import type { FetchHint, ReplayContainer, ReplayNetworkOptions, XhrHint } from '../types'; diff --git a/packages/replay-internal/src/coreHandlers/util/addBreadcrumbEvent.ts b/packages/replay-internal/src/coreHandlers/util/addBreadcrumbEvent.ts index d24f43bd5d4a..a88eb8cabdeb 100644 --- a/packages/replay-internal/src/coreHandlers/util/addBreadcrumbEvent.ts +++ b/packages/replay-internal/src/coreHandlers/util/addBreadcrumbEvent.ts @@ -1,6 +1,6 @@ import { EventType } from '@sentry-internal/rrweb'; import { normalize } from '@sentry/core'; -import type { Breadcrumb } from '@sentry/types'; +import type { Breadcrumb } from '@sentry/core'; import type { ReplayContainer } from '../../types'; diff --git a/packages/replay-internal/src/coreHandlers/util/addFeedbackBreadcrumb.ts b/packages/replay-internal/src/coreHandlers/util/addFeedbackBreadcrumb.ts index 39fc2923cabd..014a1a60686f 100644 --- a/packages/replay-internal/src/coreHandlers/util/addFeedbackBreadcrumb.ts +++ b/packages/replay-internal/src/coreHandlers/util/addFeedbackBreadcrumb.ts @@ -1,5 +1,5 @@ import { EventType } from '@sentry-internal/rrweb'; -import type { FeedbackEvent } from '@sentry/types'; +import type { FeedbackEvent } from '@sentry/core'; import type { ReplayBreadcrumbFrameEvent, ReplayContainer } from '../../types'; diff --git a/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts b/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts index 8da058674516..d52af5c8526c 100644 --- a/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts +++ b/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts @@ -1,5 +1,5 @@ import { setTimeout } from '@sentry-internal/browser-utils'; -import type { Breadcrumb, FetchBreadcrumbData } from '@sentry/types'; +import type { Breadcrumb, FetchBreadcrumbData } from '@sentry/core'; import { DEBUG_BUILD } from '../../debug-build'; import type { diff --git a/packages/replay-internal/src/coreHandlers/util/shouldSampleForBufferEvent.ts b/packages/replay-internal/src/coreHandlers/util/shouldSampleForBufferEvent.ts index 2144aab4182c..4b46cee85963 100644 --- a/packages/replay-internal/src/coreHandlers/util/shouldSampleForBufferEvent.ts +++ b/packages/replay-internal/src/coreHandlers/util/shouldSampleForBufferEvent.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { UNABLE_TO_SEND_REPLAY } from '../../constants'; import type { ReplayContainer } from '../../types'; diff --git a/packages/replay-internal/src/coreHandlers/util/xhrUtils.ts b/packages/replay-internal/src/coreHandlers/util/xhrUtils.ts index d7ac201c0756..e05dda8e29eb 100644 --- a/packages/replay-internal/src/coreHandlers/util/xhrUtils.ts +++ b/packages/replay-internal/src/coreHandlers/util/xhrUtils.ts @@ -1,5 +1,5 @@ import { SENTRY_XHR_DATA_KEY } from '@sentry-internal/browser-utils'; -import type { Breadcrumb, XhrBreadcrumbData } from '@sentry/types'; +import type { Breadcrumb, XhrBreadcrumbData } from '@sentry/core'; import { DEBUG_BUILD } from '../../debug-build'; import type { diff --git a/packages/replay-internal/src/eventBuffer/EventBufferCompressionWorker.ts b/packages/replay-internal/src/eventBuffer/EventBufferCompressionWorker.ts index 13fab7e6717b..5f7481671105 100644 --- a/packages/replay-internal/src/eventBuffer/EventBufferCompressionWorker.ts +++ b/packages/replay-internal/src/eventBuffer/EventBufferCompressionWorker.ts @@ -1,4 +1,4 @@ -import type { ReplayRecordingData } from '@sentry/types'; +import type { ReplayRecordingData } from '@sentry/core'; import { REPLAY_MAX_EVENT_BUFFER_SIZE } from '../constants'; import { DEBUG_BUILD } from '../debug-build'; diff --git a/packages/replay-internal/src/eventBuffer/EventBufferProxy.ts b/packages/replay-internal/src/eventBuffer/EventBufferProxy.ts index c982567e49c1..82a5c6a65d07 100644 --- a/packages/replay-internal/src/eventBuffer/EventBufferProxy.ts +++ b/packages/replay-internal/src/eventBuffer/EventBufferProxy.ts @@ -1,4 +1,4 @@ -import type { ReplayRecordingData } from '@sentry/types'; +import type { ReplayRecordingData } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import type { AddEventResult, EventBuffer, EventBufferType, RecordingEvent } from '../types'; diff --git a/packages/replay-internal/src/integration.ts b/packages/replay-internal/src/integration.ts index 3c3f768b50df..bd152f9bba48 100644 --- a/packages/replay-internal/src/integration.ts +++ b/packages/replay-internal/src/integration.ts @@ -1,13 +1,5 @@ -import { parseSampleRate } from '@sentry/core'; -import { consoleSandbox, dropUndefinedKeys, isBrowser } from '@sentry/core'; -import type { - BrowserClientReplayOptions, - Client, - Integration, - IntegrationFn, - ReplayRecordingMode, -} from '@sentry/types'; - +import type { BrowserClientReplayOptions, Client, Integration, IntegrationFn, ReplayRecordingMode } from '@sentry/core'; +import { consoleSandbox, dropUndefinedKeys, isBrowser, parseSampleRate } from '@sentry/core'; import { DEFAULT_FLUSH_MAX_DELAY, DEFAULT_FLUSH_MIN_DELAY, diff --git a/packages/replay-internal/src/replay.ts b/packages/replay-internal/src/replay.ts index d87a73a7e51d..f3169106d458 100644 --- a/packages/replay-internal/src/replay.ts +++ b/packages/replay-internal/src/replay.ts @@ -1,9 +1,7 @@ /* eslint-disable max-lines */ // TODO: We might want to split this file up import { EventType, record } from '@sentry-internal/rrweb'; +import type { ReplayRecordingMode, Span } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getActiveSpan, getClient, getRootSpan, spanToJSON } from '@sentry/core'; -import type { ReplayRecordingMode, Span } from '@sentry/types'; -import { logger } from './util/logger'; - import { BUFFER_CHECKOUT_TIME, SESSION_IDLE_EXPIRE_DURATION, @@ -21,7 +19,6 @@ import { clearSession } from './session/clearSession'; import { loadOrCreateSession } from './session/loadOrCreateSession'; import { saveSession } from './session/saveSession'; import { shouldRefreshSession } from './session/shouldRefreshSession'; - import type { AddEventResult, AddUpdateCallback, @@ -53,6 +50,7 @@ import { debounce } from './util/debounce'; import { getHandleRecordingEmit } from './util/handleRecordingEmit'; import { isExpired } from './util/isExpired'; import { isSessionExpired } from './util/isSessionExpired'; +import { logger } from './util/logger'; import { resetReplayIdOnDynamicSamplingContext } from './util/resetReplayIdOnDynamicSamplingContext'; import { sendReplay } from './util/sendReplay'; import { RateLimitError } from './util/sendReplayRequest'; diff --git a/packages/replay-internal/src/types/replay.ts b/packages/replay-internal/src/types/replay.ts index 4f78a438ecc3..7cd4c78a21c5 100644 --- a/packages/replay-internal/src/types/replay.ts +++ b/packages/replay-internal/src/types/replay.ts @@ -8,7 +8,7 @@ import type { SentryWrappedXMLHttpRequest, Span, XhrBreadcrumbHint, -} from '@sentry/types'; +} from '@sentry/core'; import type { SKIPPED, THROTTLED } from '../util/throttle'; import type { AllPerformanceEntry, AllPerformanceEntryData, ReplayPerformanceEntry } from './performance'; diff --git a/packages/replay-internal/src/types/replayFrame.ts b/packages/replay-internal/src/types/replayFrame.ts index 0fa43ff41eb2..7e887bb3c808 100644 --- a/packages/replay-internal/src/types/replayFrame.ts +++ b/packages/replay-internal/src/types/replayFrame.ts @@ -1,4 +1,4 @@ -import type { Breadcrumb } from '@sentry/types'; +import type { Breadcrumb } from '@sentry/core'; import type { HistoryData, diff --git a/packages/replay-internal/src/util/addGlobalListeners.ts b/packages/replay-internal/src/util/addGlobalListeners.ts index 70344413d3ba..cfc765e1b383 100644 --- a/packages/replay-internal/src/util/addGlobalListeners.ts +++ b/packages/replay-internal/src/util/addGlobalListeners.ts @@ -3,7 +3,7 @@ import { addHistoryInstrumentationHandler, } from '@sentry-internal/browser-utils'; import { addEventProcessor, getClient } from '@sentry/core'; -import type { DynamicSamplingContext } from '@sentry/types'; +import type { DynamicSamplingContext } from '@sentry/core'; import { handleAfterSendEvent } from '../coreHandlers/handleAfterSendEvent'; import { handleBeforeSendEvent } from '../coreHandlers/handleBeforeSendEvent'; diff --git a/packages/replay-internal/src/util/createReplayEnvelope.ts b/packages/replay-internal/src/util/createReplayEnvelope.ts index 4f4376a0e501..e1215c1904d4 100644 --- a/packages/replay-internal/src/util/createReplayEnvelope.ts +++ b/packages/replay-internal/src/util/createReplayEnvelope.ts @@ -1,5 +1,5 @@ import { createEnvelope, createEventEnvelopeHeaders, getSdkMetadataForEnvelopeHeader } from '@sentry/core'; -import type { DsnComponents, ReplayEnvelope, ReplayEvent, ReplayRecordingData } from '@sentry/types'; +import type { DsnComponents, ReplayEnvelope, ReplayEvent, ReplayRecordingData } from '@sentry/core'; /** * Create a replay envelope ready to be sent. diff --git a/packages/replay-internal/src/util/eventUtils.ts b/packages/replay-internal/src/util/eventUtils.ts index 8d2256bb57e3..ced9a7d115e4 100644 --- a/packages/replay-internal/src/util/eventUtils.ts +++ b/packages/replay-internal/src/util/eventUtils.ts @@ -1,4 +1,4 @@ -import type { ErrorEvent, Event, FeedbackEvent, ReplayEvent, TransactionEvent } from '@sentry/types'; +import type { ErrorEvent, Event, FeedbackEvent, ReplayEvent, TransactionEvent } from '@sentry/core'; /** If the event is an error event */ export function isErrorEvent(event: Event): event is ErrorEvent { diff --git a/packages/replay-internal/src/util/isRrwebError.ts b/packages/replay-internal/src/util/isRrwebError.ts index 0cb50bfb6802..275a93777b2e 100644 --- a/packages/replay-internal/src/util/isRrwebError.ts +++ b/packages/replay-internal/src/util/isRrwebError.ts @@ -1,4 +1,4 @@ -import type { Event, EventHint } from '@sentry/types'; +import type { Event, EventHint } from '@sentry/core'; /** * Returns true if we think the given event is an error originating inside of rrweb. diff --git a/packages/replay-internal/src/util/logger.ts b/packages/replay-internal/src/util/logger.ts index 3cc98980ec7e..4ee45c44309c 100644 --- a/packages/replay-internal/src/util/logger.ts +++ b/packages/replay-internal/src/util/logger.ts @@ -1,7 +1,5 @@ -import { addBreadcrumb, captureException } from '@sentry/core'; -import { logger as coreLogger, severityLevelFromString } from '@sentry/core'; -import type { ConsoleLevel, SeverityLevel } from '@sentry/types'; - +import type { ConsoleLevel, SeverityLevel } from '@sentry/core'; +import { addBreadcrumb, captureException, logger as coreLogger, severityLevelFromString } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; type ReplayConsoleLevels = Extract; diff --git a/packages/replay-internal/src/util/prepareRecordingData.ts b/packages/replay-internal/src/util/prepareRecordingData.ts index 2ee3391d6f42..dd5261d0ba6c 100644 --- a/packages/replay-internal/src/util/prepareRecordingData.ts +++ b/packages/replay-internal/src/util/prepareRecordingData.ts @@ -1,4 +1,4 @@ -import type { ReplayRecordingData } from '@sentry/types'; +import type { ReplayRecordingData } from '@sentry/core'; /** * Prepare the recording data ready to be sent. diff --git a/packages/replay-internal/src/util/prepareReplayEvent.ts b/packages/replay-internal/src/util/prepareReplayEvent.ts index e071bec88a61..f1d21efcce86 100644 --- a/packages/replay-internal/src/util/prepareReplayEvent.ts +++ b/packages/replay-internal/src/util/prepareReplayEvent.ts @@ -1,6 +1,6 @@ import type { IntegrationIndex } from '@sentry/core'; import { getIsolationScope, prepareEvent } from '@sentry/core'; -import type { Client, EventHint, ReplayEvent, Scope } from '@sentry/types'; +import type { Client, EventHint, ReplayEvent, Scope } from '@sentry/core'; /** * Prepare a replay event & enrich it with the SDK metadata. diff --git a/packages/replay-internal/src/util/resetReplayIdOnDynamicSamplingContext.ts b/packages/replay-internal/src/util/resetReplayIdOnDynamicSamplingContext.ts index b38de9e3312d..7e264811ce3a 100644 --- a/packages/replay-internal/src/util/resetReplayIdOnDynamicSamplingContext.ts +++ b/packages/replay-internal/src/util/resetReplayIdOnDynamicSamplingContext.ts @@ -1,5 +1,5 @@ import { getActiveSpan, getCurrentScope, getDynamicSamplingContextFromSpan } from '@sentry/core'; -import type { DynamicSamplingContext } from '@sentry/types'; +import type { DynamicSamplingContext } from '@sentry/core'; /** * Reset the `replay_id` field on the DSC. diff --git a/packages/replay-internal/src/util/sendReplayRequest.ts b/packages/replay-internal/src/util/sendReplayRequest.ts index 89c7740bc0b7..5ab25228b486 100644 --- a/packages/replay-internal/src/util/sendReplayRequest.ts +++ b/packages/replay-internal/src/util/sendReplayRequest.ts @@ -1,9 +1,5 @@ -import { getClient, getCurrentScope } from '@sentry/core'; -import type { RateLimits } from '@sentry/core'; -import { resolvedSyncPromise } from '@sentry/core'; -import { isRateLimited, updateRateLimits } from '@sentry/core'; -import type { ReplayEvent, TransportMakeRequestResponse } from '@sentry/types'; - +import type { RateLimits, ReplayEvent, TransportMakeRequestResponse } from '@sentry/core'; +import { getClient, getCurrentScope, isRateLimited, resolvedSyncPromise, updateRateLimits } from '@sentry/core'; import { REPLAY_EVENT_NAME, UNABLE_TO_SEND_REPLAY } from '../constants'; import { DEBUG_BUILD } from '../debug-build'; import type { SendReplayData } from '../types'; diff --git a/packages/replay-internal/test.setup.ts b/packages/replay-internal/test.setup.ts index 17f7d5c9f2b7..c7d1ffa8eb51 100644 --- a/packages/replay-internal/test.setup.ts +++ b/packages/replay-internal/test.setup.ts @@ -5,7 +5,7 @@ import type { Mocked, MockedFunction } from 'vitest'; /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { getClient } from '@sentry/core'; import * as SentryUtils from '@sentry/core'; -import type { ReplayRecordingData, Transport } from '@sentry/types'; +import type { ReplayRecordingData, Transport } from '@sentry/core'; import type { ReplayContainer, Session } from './src/types'; diff --git a/packages/replay-internal/test/fixtures/error.ts b/packages/replay-internal/test/fixtures/error.ts index 1fde3a179ffc..1b8354126107 100644 --- a/packages/replay-internal/test/fixtures/error.ts +++ b/packages/replay-internal/test/fixtures/error.ts @@ -1,4 +1,4 @@ -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; export function Error(obj?: Event): any { const timestamp = Date.now() / 1000; diff --git a/packages/replay-internal/test/fixtures/transaction.ts b/packages/replay-internal/test/fixtures/transaction.ts index 6264802f74d8..1062213e66a2 100644 --- a/packages/replay-internal/test/fixtures/transaction.ts +++ b/packages/replay-internal/test/fixtures/transaction.ts @@ -1,4 +1,4 @@ -import type { Event, SeverityLevel } from '@sentry/types'; +import type { Event, SeverityLevel } from '@sentry/core'; export function Transaction(traceId?: string, obj?: Partial): any { const timestamp = Date.now() / 1000; diff --git a/packages/replay-internal/test/integration/beforeAddRecordingEvent.test.ts b/packages/replay-internal/test/integration/beforeAddRecordingEvent.test.ts index a3b587ee0bda..dd0d98783893 100644 --- a/packages/replay-internal/test/integration/beforeAddRecordingEvent.test.ts +++ b/packages/replay-internal/test/integration/beforeAddRecordingEvent.test.ts @@ -7,7 +7,7 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } import * as SentryBrowserUtils from '@sentry-internal/browser-utils'; import * as SentryCore from '@sentry/core'; -import type { Transport } from '@sentry/types'; +import type { Transport } from '@sentry/core'; import type { Replay } from '../../src/integration'; import type { ReplayContainer } from '../../src/replay'; diff --git a/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts b/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts index aa88e9582d32..4bfe99d95f20 100644 --- a/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts +++ b/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts @@ -10,7 +10,7 @@ import { useFakeTimers } from '../../utils/use-fake-timers'; useFakeTimers(); import { getClient } from '@sentry/core'; -import type { ErrorEvent, Event } from '@sentry/types'; +import type { ErrorEvent, Event } from '@sentry/core'; import { UNABLE_TO_SEND_REPLAY } from '../../../src/constants'; import { handleAfterSendEvent } from '../../../src/coreHandlers/handleAfterSendEvent'; diff --git a/packages/replay-internal/test/integration/coreHandlers/handleGlobalEvent.test.ts b/packages/replay-internal/test/integration/coreHandlers/handleGlobalEvent.test.ts index a3ad967e1586..5bab5ab1a715 100644 --- a/packages/replay-internal/test/integration/coreHandlers/handleGlobalEvent.test.ts +++ b/packages/replay-internal/test/integration/coreHandlers/handleGlobalEvent.test.ts @@ -5,7 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { getClient } from '@sentry/core'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { REPLAY_EVENT_NAME, SESSION_IDLE_EXPIRE_DURATION } from '../../../src/constants'; import { handleGlobalEventListener } from '../../../src/coreHandlers/handleGlobalEvent'; diff --git a/packages/replay-internal/test/integration/eventProcessors.test.ts b/packages/replay-internal/test/integration/eventProcessors.test.ts index b6c5bd23624d..26ae88364a61 100644 --- a/packages/replay-internal/test/integration/eventProcessors.test.ts +++ b/packages/replay-internal/test/integration/eventProcessors.test.ts @@ -5,7 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { getClient, getCurrentScope } from '@sentry/core'; -import type { Event } from '@sentry/types'; +import type { Event } from '@sentry/core'; import { BASE_TIMESTAMP } from '..'; import { resetSdkMock } from '../mocks/resetSdkMock'; diff --git a/packages/replay-internal/test/integration/rateLimiting.test.ts b/packages/replay-internal/test/integration/rateLimiting.test.ts index 6a60f8251b93..f75ab257b9f5 100644 --- a/packages/replay-internal/test/integration/rateLimiting.test.ts +++ b/packages/replay-internal/test/integration/rateLimiting.test.ts @@ -6,7 +6,7 @@ import type { MockedFunction } from 'vitest'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { getClient } from '@sentry/core'; -import type { Transport, TransportMakeRequestResponse } from '@sentry/types'; +import type { Transport, TransportMakeRequestResponse } from '@sentry/core'; import { DEFAULT_FLUSH_MIN_DELAY } from '../../src/constants'; import type { ReplayContainer } from '../../src/replay'; diff --git a/packages/replay-internal/test/integration/sendReplayEvent.test.ts b/packages/replay-internal/test/integration/sendReplayEvent.test.ts index 29f063fa4b94..bc58d463cf66 100644 --- a/packages/replay-internal/test/integration/sendReplayEvent.test.ts +++ b/packages/replay-internal/test/integration/sendReplayEvent.test.ts @@ -7,7 +7,7 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } import * as SentryBrowserUtils from '@sentry-internal/browser-utils'; import * as SentryCore from '@sentry/core'; -import type { Transport } from '@sentry/types'; +import type { Transport } from '@sentry/core'; import { DEFAULT_FLUSH_MIN_DELAY, WINDOW } from '../../src/constants'; import type { ReplayContainer } from '../../src/replay'; diff --git a/packages/replay-internal/test/integration/session.test.ts b/packages/replay-internal/test/integration/session.test.ts index 0d3621cd4f70..78ecee16027e 100644 --- a/packages/replay-internal/test/integration/session.test.ts +++ b/packages/replay-internal/test/integration/session.test.ts @@ -5,7 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { getClient } from '@sentry/core'; -import type { Transport } from '@sentry/types'; +import type { Transport } from '@sentry/core'; import { DEFAULT_FLUSH_MIN_DELAY, diff --git a/packages/replay-internal/test/integration/start.test.ts b/packages/replay-internal/test/integration/start.test.ts index 5a4ccc087ed9..8b2136d16120 100644 --- a/packages/replay-internal/test/integration/start.test.ts +++ b/packages/replay-internal/test/integration/start.test.ts @@ -5,7 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { getClient } from '@sentry/core'; -import type { Transport } from '@sentry/types'; +import type { Transport } from '@sentry/core'; import { DEFAULT_FLUSH_MIN_DELAY, SESSION_IDLE_EXPIRE_DURATION } from '../../src/constants'; import type { Replay } from '../../src/integration'; diff --git a/packages/replay-internal/test/mocks/mockSdk.ts b/packages/replay-internal/test/mocks/mockSdk.ts index 38adc7f9c476..5595bf04a261 100644 --- a/packages/replay-internal/test/mocks/mockSdk.ts +++ b/packages/replay-internal/test/mocks/mockSdk.ts @@ -1,4 +1,4 @@ -import type { Envelope, Transport, TransportMakeRequestResponse } from '@sentry/types'; +import type { Envelope, Transport, TransportMakeRequestResponse } from '@sentry/core'; import { vi } from 'vitest'; import type { Replay as ReplayIntegration } from '../../src/integration'; diff --git a/packages/replay-internal/test/types.ts b/packages/replay-internal/test/types.ts index 336f11b7bed9..ff28aa40a5f7 100644 --- a/packages/replay-internal/test/types.ts +++ b/packages/replay-internal/test/types.ts @@ -1,3 +1,3 @@ -import type { HandlerDataDom } from '@sentry/types'; +import type { HandlerDataDom } from '@sentry/core'; export type DomHandler = (data: HandlerDataDom) => void; diff --git a/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts b/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts index 4cd75a609ec3..58d10db23e40 100644 --- a/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts @@ -8,7 +8,7 @@ import { useFakeTimers } from '../../utils/use-fake-timers'; useFakeTimers(); -import type { Breadcrumb } from '@sentry/types'; +import type { Breadcrumb } from '@sentry/core'; import { BASE_TIMESTAMP } from '../..'; import { ClickDetector, ignoreElement } from '../../../src/coreHandlers/handleClick'; diff --git a/packages/replay-internal/test/unit/coreHandlers/handleDom.test.ts b/packages/replay-internal/test/unit/coreHandlers/handleDom.test.ts index 993291be675e..8d5453c31f2c 100644 --- a/packages/replay-internal/test/unit/coreHandlers/handleDom.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/handleDom.test.ts @@ -4,7 +4,7 @@ import { describe, expect, test } from 'vitest'; -import type { HandlerDataDom } from '@sentry/types'; +import type { HandlerDataDom } from '@sentry/core'; import { handleDom } from '../../../src/coreHandlers/handleDom'; diff --git a/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts b/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts index 04955477f679..512c2b0f33eb 100644 --- a/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts @@ -11,7 +11,7 @@ import type { FetchBreadcrumbHint, SentryWrappedXMLHttpRequest, XhrBreadcrumbHint, -} from '@sentry/types'; +} from '@sentry/core'; import { BASE_TIMESTAMP } from '../..'; import { NETWORK_BODY_MAX_SIZE } from '../../../src/constants'; diff --git a/packages/replay-internal/test/unit/session/createSession.test.ts b/packages/replay-internal/test/unit/session/createSession.test.ts index 3f8cd4ce3ca7..8cd186f4aeea 100644 --- a/packages/replay-internal/test/unit/session/createSession.test.ts +++ b/packages/replay-internal/test/unit/session/createSession.test.ts @@ -7,7 +7,7 @@ import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest'; import * as Sentry from '@sentry/core'; -import type { Hub } from '@sentry/types'; +import type { Hub } from '@sentry/core'; import { WINDOW } from '../../../src/constants'; import { createSession } from '../../../src/session/createSession'; import { saveSession } from '../../../src/session/saveSession'; diff --git a/packages/replay-internal/test/unit/util/createReplayEnvelope.test.ts b/packages/replay-internal/test/unit/util/createReplayEnvelope.test.ts index 6967f3f32a26..9971c3e57b3f 100644 --- a/packages/replay-internal/test/unit/util/createReplayEnvelope.test.ts +++ b/packages/replay-internal/test/unit/util/createReplayEnvelope.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from 'vitest'; import { makeDsn } from '@sentry/core'; -import type { ReplayEvent } from '@sentry/types'; +import type { ReplayEvent } from '@sentry/core'; import { createReplayEnvelope } from '../../../src/util/createReplayEnvelope'; diff --git a/packages/replay-internal/test/unit/util/prepareReplayEvent.test.ts b/packages/replay-internal/test/unit/util/prepareReplayEvent.test.ts index b93a8651267c..14d2e36e9a07 100644 --- a/packages/replay-internal/test/unit/util/prepareReplayEvent.test.ts +++ b/packages/replay-internal/test/unit/util/prepareReplayEvent.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { getClient, getCurrentScope, setCurrentClient } from '@sentry/core'; -import type { ReplayEvent } from '@sentry/types'; +import type { ReplayEvent } from '@sentry/core'; import { REPLAY_EVENT_NAME } from '../../../src/constants'; import { prepareReplayEvent } from '../../../src/util/prepareReplayEvent'; diff --git a/packages/replay-internal/test/utils/TestClient.ts b/packages/replay-internal/test/utils/TestClient.ts index f534ac77c3c6..48ce724605f7 100644 --- a/packages/replay-internal/test/utils/TestClient.ts +++ b/packages/replay-internal/test/utils/TestClient.ts @@ -7,7 +7,7 @@ import type { Event, ParameterizedString, SeverityLevel, -} from '@sentry/types'; +} from '@sentry/core'; export interface TestClientOptions extends ClientOptions, BrowserClientReplayOptions {} diff --git a/packages/replay-worker/package.json b/packages/replay-worker/package.json index accccdf2baae..8094b57611b1 100644 --- a/packages/replay-worker/package.json +++ b/packages/replay-worker/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay-worker", - "version": "8.40.0", + "version": "8.42.0", "description": "Worker for @sentry-internal/replay", "main": "build/esm/index.js", "module": "build/esm/index.js", diff --git a/packages/solid/package.json b/packages/solid/package.json index 9de59618b038..78421f059645 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/solid", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Solid", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solid", @@ -44,9 +44,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0" }, "peerDependencies": { "@solidjs/router": "^0.13.4", diff --git a/packages/solid/src/sdk.ts b/packages/solid/src/sdk.ts index 2a08964b1b67..b17a42051474 100644 --- a/packages/solid/src/sdk.ts +++ b/packages/solid/src/sdk.ts @@ -1,7 +1,7 @@ import type { BrowserOptions } from '@sentry/browser'; import { init as browserInit } from '@sentry/browser'; import { applySdkMetadata } from '@sentry/core'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; /** * Initializes the Solid SDK diff --git a/packages/solid/src/solidrouter.ts b/packages/solid/src/solidrouter.ts index b4c0972decff..c2641ac1acf9 100644 --- a/packages/solid/src/solidrouter.ts +++ b/packages/solid/src/solidrouter.ts @@ -11,7 +11,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getClient, } from '@sentry/core'; -import type { Client, Integration, Span } from '@sentry/types'; +import type { Client, Integration, Span } from '@sentry/core'; import type { BeforeLeaveEventArgs, HashRouter, diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index 4db6751fb693..277870c98c8a 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/solidstart", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Solid Start", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solidstart", @@ -67,11 +67,10 @@ }, "dependencies": { "@opentelemetry/instrumentation": "^0.54.0", - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/opentelemetry": "8.40.0", - "@sentry/solid": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", + "@sentry/opentelemetry": "8.42.0", + "@sentry/solid": "8.42.0", "@sentry/vite-plugin": "2.22.6" }, "devDependencies": { diff --git a/packages/solidstart/src/client/sdk.ts b/packages/solidstart/src/client/sdk.ts index 8b1b6f7f39d5..e656fdcba921 100644 --- a/packages/solidstart/src/client/sdk.ts +++ b/packages/solidstart/src/client/sdk.ts @@ -1,11 +1,11 @@ import { applySdkMetadata } from '@sentry/core'; +import type { Client, Integration } from '@sentry/core'; import type { BrowserOptions } from '@sentry/solid'; import { browserTracingIntegration, getDefaultIntegrations as getDefaultSolidIntegrations, init as initSolidSDK, } from '@sentry/solid'; -import type { Client, Integration } from '@sentry/types'; // Treeshakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean; diff --git a/packages/solidstart/src/index.types.ts b/packages/solidstart/src/index.types.ts index 13ff38425a1c..85b712281f38 100644 --- a/packages/solidstart/src/index.types.ts +++ b/packages/solidstart/src/index.types.ts @@ -5,7 +5,7 @@ export * from './client'; export * from './server'; export * from './vite'; -import type { Client, Integration, Options, StackParser } from '@sentry/types'; +import type { Client, Integration, Options, StackParser } from '@sentry/core'; import type * as clientSdk from './client'; import type * as serverSdk from './server'; diff --git a/packages/solidstart/src/server/index.ts b/packages/solidstart/src/server/index.ts index d709a373e501..6ff657695081 100644 --- a/packages/solidstart/src/server/index.ts +++ b/packages/solidstart/src/server/index.ts @@ -7,6 +7,7 @@ export { addBreadcrumb, addEventProcessor, addIntegration, + // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, // eslint-disable-next-line deprecation/deprecation addRequestDataToEvent, diff --git a/packages/solidstart/src/server/utils.ts b/packages/solidstart/src/server/utils.ts index 90bf9b426a93..cd2c4c12ab96 100644 --- a/packages/solidstart/src/server/utils.ts +++ b/packages/solidstart/src/server/utils.ts @@ -1,6 +1,6 @@ import { logger } from '@sentry/core'; +import type { EventProcessor, Options } from '@sentry/core'; import { flush, getGlobalScope } from '@sentry/node'; -import type { EventProcessor, Options } from '@sentry/types'; import { DEBUG_BUILD } from '../common/debug-build'; /** Flush the event queue to ensure that events get sent to Sentry before the response is finished and the lambda ends */ diff --git a/packages/solidstart/src/vite/sourceMaps.ts b/packages/solidstart/src/vite/sourceMaps.ts index 548038515e79..0f8178356d88 100644 --- a/packages/solidstart/src/vite/sourceMaps.ts +++ b/packages/solidstart/src/vite/sourceMaps.ts @@ -15,18 +15,22 @@ export function makeSourceMapsVitePlugin(options: SentrySolidStartPluginOptions) apply: 'build', enforce: 'post', config(config) { - const sourceMapsPreviouslyNotEnabled = !config.build?.sourcemap; - if (debug && sourceMapsPreviouslyNotEnabled) { + // TODO(v9): Remove this warning + if (config.build?.sourcemap === false) { // eslint-disable-next-line no-console - console.log('[Sentry SolidStart Plugin] Enabling source map generation'); - if (!sourceMapsUploadOptions?.filesToDeleteAfterUpload) { - // eslint-disable-next-line no-console - console.warn( - `[Sentry SolidStart PLugin] We recommend setting the \`sourceMapsUploadOptions.filesToDeleteAfterUpload\` option to clean up source maps after uploading. -[Sentry SolidStart Plugin] Otherwise, source maps might be deployed to production, depending on your configuration`, - ); - } + console.warn( + "[Sentry SolidStart Plugin] You disabled sourcemaps with the `build.sourcemap` option. Currently, the Sentry SDK will override this option to generate sourcemaps. In future versions, the Sentry SDK will not override the `build.sourcemap` option if you explicitly disable it. If you want to generate and upload sourcemaps please set the `build.sourcemap` option to 'hidden' or undefined.", + ); } + + // TODO(v9): Remove this warning and print warning in case source map deletion is auto configured + if (!sourceMapsUploadOptions?.filesToDeleteAfterUpload) { + // eslint-disable-next-line no-console + console.warn( + "[Sentry SolidStart Plugin] The Sentry SDK has enabled source map generation for your SolidStart app. If you don't want to serve Source Maps to your users, either configure the `filesToDeleteAfterUpload` option with a glob to remove source maps after uploading them, or manually delete the source maps after the build. In future Sentry SDK versions source maps will be deleted automatically after uploading them.", + ); + } + return { ...config, build: { diff --git a/packages/solidstart/test/client/sdk.test.ts b/packages/solidstart/test/client/sdk.test.ts index b242e03ceb70..dc0df6993b81 100644 --- a/packages/solidstart/test/client/sdk.test.ts +++ b/packages/solidstart/test/client/sdk.test.ts @@ -46,6 +46,7 @@ describe('browserTracingIntegration', () => { ?.getOptions() .integrations.find(integration => integration.name === 'BrowserTracing'); expect(browserTracingIntegration).toBeDefined(); + // @ts-expect-error Non public field expect(browserTracingIntegration!.isDefaultInstance).toEqual(true); }); @@ -76,6 +77,7 @@ describe('browserTracingIntegration', () => { ?.getOptions() .integrations.find(integration => integration.name === 'BrowserTracing'); expect(browserTracingIntegration).toBeDefined(); + // @ts-expect-error Non public field expect(browserTracingIntegration!.isDefaultInstance).toBeUndefined(); }); }); diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 338e4e18f975..81cff6ab1733 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/svelte", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Svelte", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/svelte", @@ -39,9 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0", "magic-string": "^0.30.0" }, "peerDependencies": { diff --git a/packages/svelte/src/performance.ts b/packages/svelte/src/performance.ts index e30c54299603..b50be258bc58 100644 --- a/packages/svelte/src/performance.ts +++ b/packages/svelte/src/performance.ts @@ -1,5 +1,5 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/browser'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; import { afterUpdate, beforeUpdate, onMount } from 'svelte'; import { startInactiveSpan } from '@sentry/core'; diff --git a/packages/svelte/src/sdk.ts b/packages/svelte/src/sdk.ts index 29a3379a5140..1d21b72ef59d 100644 --- a/packages/svelte/src/sdk.ts +++ b/packages/svelte/src/sdk.ts @@ -1,8 +1,7 @@ import type { BrowserOptions } from '@sentry/browser'; import { addEventProcessor, init as browserInit } from '@sentry/browser'; -import { applySdkMetadata } from '@sentry/core'; -import { getDomElement } from '@sentry/core'; -import type { Client, EventProcessor } from '@sentry/types'; +import type { Client, EventProcessor } from '@sentry/core'; +import { applySdkMetadata, getDomElement } from '@sentry/core'; /** * Inits the Svelte SDK */ diff --git a/packages/svelte/test/performance.test.ts b/packages/svelte/test/performance.test.ts index 929bb9394e95..21adeee255c3 100644 --- a/packages/svelte/test/performance.test.ts +++ b/packages/svelte/test/performance.test.ts @@ -7,7 +7,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { act, render } from '@testing-library/svelte'; import { getClient, getCurrentScope, getIsolationScope, init, startSpan } from '../src'; -import type { TransactionEvent } from '@sentry/types'; +import type { TransactionEvent } from '@sentry/core'; // @ts-expect-error svelte import import DummyComponent from './components/Dummy.svelte'; @@ -66,7 +66,7 @@ describe('Sentry.trackComponent()', () => { span_id: initSpanId, start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(transaction.spans![1]).toEqual({ @@ -78,10 +78,10 @@ describe('Sentry.trackComponent()', () => { op: 'ui.svelte.update', origin: 'auto.ui.svelte', parent_span_id: rootSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); @@ -121,7 +121,7 @@ describe('Sentry.trackComponent()', () => { span_id: initSpanId, start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(transaction.spans![1]).toEqual({ @@ -133,10 +133,10 @@ describe('Sentry.trackComponent()', () => { op: 'ui.svelte.update', origin: 'auto.ui.svelte', parent_span_id: rootSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); expect(transaction.spans![2]).toEqual({ @@ -148,10 +148,10 @@ describe('Sentry.trackComponent()', () => { op: 'ui.svelte.update', origin: 'auto.ui.svelte', parent_span_id: rootSpanId, - span_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), start_timestamp: expect.any(Number), timestamp: expect.any(Number), - trace_id: expect.any(String), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), }); }); diff --git a/packages/svelte/test/sdk.test.ts b/packages/svelte/test/sdk.test.ts index 27ca155533e3..02d01d27fae9 100644 --- a/packages/svelte/test/sdk.test.ts +++ b/packages/svelte/test/sdk.test.ts @@ -6,7 +6,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { SDK_VERSION } from '@sentry/browser'; import * as SentryBrowser from '@sentry/browser'; -import type { EventProcessor } from '@sentry/types'; +import type { EventProcessor } from '@sentry/core'; import { detectAndReportSvelteKit, init as svelteInit, isSvelteKitApp } from '../src/sdk'; diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 67f1853b361c..4bad4933adee 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/sveltekit", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for SvelteKit", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/sveltekit", @@ -40,11 +40,10 @@ } }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/node": "8.40.0", - "@sentry/opentelemetry": "8.40.0", - "@sentry/svelte": "8.40.0", - "@sentry/types": "8.40.0", + "@sentry/core": "8.42.0", + "@sentry/node": "8.42.0", + "@sentry/opentelemetry": "8.42.0", + "@sentry/svelte": "8.42.0", "@sentry/vite-plugin": "2.22.6", "magic-string": "0.30.7", "magicast": "0.2.8", diff --git a/packages/sveltekit/src/client/browserTracingIntegration.ts b/packages/sveltekit/src/client/browserTracingIntegration.ts index f41de176b073..800911118ec3 100644 --- a/packages/sveltekit/src/client/browserTracingIntegration.ts +++ b/packages/sveltekit/src/client/browserTracingIntegration.ts @@ -1,6 +1,6 @@ import { navigating, page } from '$app/stores'; -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; -import { dropUndefinedKeys } from '@sentry/core'; +import type { Client, Integration, Span } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, dropUndefinedKeys } from '@sentry/core'; import { WINDOW, browserTracingIntegration as originalBrowserTracingIntegration, @@ -9,7 +9,6 @@ import { startBrowserTracingPageLoadSpan, startInactiveSpan, } from '@sentry/svelte'; -import type { Client, Integration, Span } from '@sentry/types'; /** * A custom `BrowserTracing` integration for SvelteKit. diff --git a/packages/sveltekit/src/client/sdk.ts b/packages/sveltekit/src/client/sdk.ts index f01a033012a3..35ef46118edc 100644 --- a/packages/sveltekit/src/client/sdk.ts +++ b/packages/sveltekit/src/client/sdk.ts @@ -1,8 +1,8 @@ import { applySdkMetadata } from '@sentry/core'; +import type { Client, Integration } from '@sentry/core'; import type { BrowserOptions } from '@sentry/svelte'; import { getDefaultIntegrations as getDefaultSvelteIntegrations } from '@sentry/svelte'; import { WINDOW, init as initSvelteSdk } from '@sentry/svelte'; -import type { Client, Integration } from '@sentry/types'; import { browserTracingIntegration as svelteKitBrowserTracingIntegration } from './browserTracingIntegration'; diff --git a/packages/sveltekit/src/index.types.ts b/packages/sveltekit/src/index.types.ts index f7f0db30a249..95cac7b9318b 100644 --- a/packages/sveltekit/src/index.types.ts +++ b/packages/sveltekit/src/index.types.ts @@ -5,7 +5,7 @@ export * from './client'; export * from './vite'; export * from './server'; -import type { Client, Integration, Options, StackParser } from '@sentry/types'; +import type { Client, Integration, Options, StackParser } from '@sentry/core'; import type { HandleClientError, HandleServerError } from '@sveltejs/kit'; import type * as clientSdk from './client'; diff --git a/packages/sveltekit/src/server/handle.ts b/packages/sveltekit/src/server/handle.ts index 2b7f32e0876a..19a0c2507da5 100644 --- a/packages/sveltekit/src/server/handle.ts +++ b/packages/sveltekit/src/server/handle.ts @@ -1,3 +1,4 @@ +import type { Span } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, @@ -6,13 +7,13 @@ import { getDefaultIsolationScope, getIsolationScope, getTraceMetaTags, + logger, setHttpStatus, + startSpan, + winterCGRequestToRequestData, withIsolationScope, } from '@sentry/core'; -import { startSpan } from '@sentry/core'; -import { logger, winterCGRequestToRequestData } from '@sentry/core'; import { continueTrace } from '@sentry/node'; -import type { Span } from '@sentry/types'; import type { Handle, ResolveOptions } from '@sveltejs/kit'; import { DEBUG_BUILD } from '../common/debug-build'; diff --git a/packages/sveltekit/src/server/index.ts b/packages/sveltekit/src/server/index.ts index 4247dd46ff7a..f1c00d2f5e3a 100644 --- a/packages/sveltekit/src/server/index.ts +++ b/packages/sveltekit/src/server/index.ts @@ -7,6 +7,7 @@ export { addBreadcrumb, addEventProcessor, addIntegration, + // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, // eslint-disable-next-line deprecation/deprecation addRequestDataToEvent, diff --git a/packages/sveltekit/src/server/rewriteFramesIntegration.ts b/packages/sveltekit/src/server/rewriteFramesIntegration.ts index c01e248f937c..44afbca2d6df 100644 --- a/packages/sveltekit/src/server/rewriteFramesIntegration.ts +++ b/packages/sveltekit/src/server/rewriteFramesIntegration.ts @@ -1,6 +1,12 @@ -import { defineIntegration, rewriteFramesIntegration as originalRewriteFramesIntegration } from '@sentry/core'; -import { GLOBAL_OBJ, basename, escapeStringForRegex, join } from '@sentry/core'; -import type { IntegrationFn, StackFrame } from '@sentry/types'; +import type { IntegrationFn, StackFrame } from '@sentry/core'; +import { + GLOBAL_OBJ, + basename, + defineIntegration, + escapeStringForRegex, + join, + rewriteFramesIntegration as originalRewriteFramesIntegration, +} from '@sentry/core'; import { WRAPPED_MODULE_SUFFIX } from '../vite/autoInstrument'; import type { GlobalWithSentryValues } from '../vite/injectGlobalValues'; diff --git a/packages/sveltekit/src/vite/detectAdapter.ts b/packages/sveltekit/src/vite/detectAdapter.ts index 7717aa4bd4c2..e979eb0c43e4 100644 --- a/packages/sveltekit/src/vite/detectAdapter.ts +++ b/packages/sveltekit/src/vite/detectAdapter.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; -import type { Package } from '@sentry/types'; +import type { Package } from '@sentry/core'; /** * Supported @sveltejs/adapters-[adapter] SvelteKit adapters diff --git a/packages/sveltekit/src/vite/sourceMaps.ts b/packages/sveltekit/src/vite/sourceMaps.ts index 9a5656f3f78f..b664e2d23db5 100644 --- a/packages/sveltekit/src/vite/sourceMaps.ts +++ b/packages/sveltekit/src/vite/sourceMaps.ts @@ -269,7 +269,10 @@ function getFiles(dir: string): string[] { function detectSentryRelease(): string { let releaseFallback: string; try { - releaseFallback = child_process.execSync('git rev-parse HEAD', { stdio: 'ignore' }).toString().trim(); + releaseFallback = child_process + .execSync('git rev-parse HEAD', { stdio: ['ignore', 'pipe', 'ignore'] }) + .toString() + .trim(); } catch (_) { // the command can throw for various reasons. Most importantly: // - git is not installed diff --git a/packages/sveltekit/test/client/browserTracingIntegration.test.ts b/packages/sveltekit/test/client/browserTracingIntegration.test.ts index a21dbbe66bae..a70b46abbcbb 100644 --- a/packages/sveltekit/test/client/browserTracingIntegration.test.ts +++ b/packages/sveltekit/test/client/browserTracingIntegration.test.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/unbound-method */ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; import { writable } from 'svelte/store'; import { navigating, page } from '$app/stores'; diff --git a/packages/sveltekit/test/server/handle.test.ts b/packages/sveltekit/test/server/handle.test.ts index c25b926c7ace..c5225124ace3 100644 --- a/packages/sveltekit/test/server/handle.test.ts +++ b/packages/sveltekit/test/server/handle.test.ts @@ -7,9 +7,9 @@ import { spanIsSampled, spanToJSON, } from '@sentry/core'; +import type { EventEnvelopeHeaders, Span } from '@sentry/core'; import { NodeClient, setCurrentClient } from '@sentry/node'; import * as SentryNode from '@sentry/node'; -import type { EventEnvelopeHeaders, Span } from '@sentry/types'; import type { Handle } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit'; import { vi } from 'vitest'; diff --git a/packages/sveltekit/test/server/load.test.ts b/packages/sveltekit/test/server/load.test.ts index c2ee2b2943a3..1001d8464ad4 100644 --- a/packages/sveltekit/test/server/load.test.ts +++ b/packages/sveltekit/test/server/load.test.ts @@ -5,9 +5,9 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, } from '@sentry/core'; +import type { Event } from '@sentry/core'; import { NodeClient, getCurrentScope, getIsolationScope, setCurrentClient } from '@sentry/node'; import * as SentryNode from '@sentry/node'; -import type { Event } from '@sentry/types'; import type { Load, ServerLoad } from '@sveltejs/kit'; import { error, redirect } from '@sveltejs/kit'; @@ -265,8 +265,8 @@ describe('wrapServerLoadWithSentry calls `startSpan`', () => { 'sentry.sample_rate': 1, }, op: 'function.sveltekit.server.load', - span_id: expect.any(String), - trace_id: expect.any(String), + span_id: expect.stringMatching(/[a-f0-9]{16}/), + trace_id: expect.stringMatching(/[a-f0-9]{32}/), origin: 'auto.function.sveltekit', }); expect(transaction.transaction).toEqual('/users/123'); diff --git a/packages/sveltekit/test/server/rewriteFramesIntegration.ts b/packages/sveltekit/test/server/rewriteFramesIntegration.ts index ab0306876e20..3dfd5d3e460e 100644 --- a/packages/sveltekit/test/server/rewriteFramesIntegration.ts +++ b/packages/sveltekit/test/server/rewriteFramesIntegration.ts @@ -1,6 +1,6 @@ import { rewriteFramesIntegration } from '@sentry/browser'; import { basename } from '@sentry/core'; -import type { Event, StackFrame } from '@sentry/types'; +import type { Event, StackFrame } from '@sentry/core'; import { rewriteFramesIteratee } from '../../src/server/rewriteFramesIntegration'; import type { GlobalWithSentryValues } from '../../src/vite/injectGlobalValues'; diff --git a/packages/sveltekit/test/utils.ts b/packages/sveltekit/test/utils.ts index a4e0299b396d..ec15e0d24c03 100644 --- a/packages/sveltekit/test/utils.ts +++ b/packages/sveltekit/test/utils.ts @@ -1,6 +1,6 @@ import { createTransport } from '@sentry/core'; import { resolvedSyncPromise } from '@sentry/core'; -import type { ClientOptions } from '@sentry/types'; +import type { ClientOptions } from '@sentry/core'; export function getDefaultNodeClientOptions(options: Partial = {}): ClientOptions { return { diff --git a/packages/types/README.md b/packages/types/README.md index 4c0e2d9cbc34..a7fa71c4421b 100644 --- a/packages/types/README.md +++ b/packages/types/README.md @@ -4,7 +4,11 @@

-# Sentry JavaScript SDK Types +# Sentry JavaScript SDK Types (DEPRECATED) + +> DEPRECATION NOTICE: The `@sentry/types` package is deprecated. +> All exports have been moved to `@sentry/core`. +> Import everything from `@sentry/core` instead. [![npm version](https://img.shields.io/npm/v/@sentry/types.svg)](https://www.npmjs.com/package/@sentry/types) [![npm dm](https://img.shields.io/npm/dm/@sentry/types.svg)](https://www.npmjs.com/package/@sentry/types) diff --git a/packages/types/package.json b/packages/types/package.json index 97e0dcfca7f1..8a30e6189cf5 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/types", - "version": "8.40.0", + "version": "8.42.0", "description": "Types for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/types", @@ -55,6 +55,9 @@ "fix": "eslint . --format stylish --fix", "yalc:publish": "yalc publish --push --sig" }, + "dependencies": { + "@sentry/core": "8.42.0" + }, "volta": { "extends": "../../package.json" }, diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 5dd1839aeba7..372e5e854a87 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,181 +1,570 @@ -export type { Attachment } from './attachment'; -export type { - Breadcrumb, - BreadcrumbHint, - FetchBreadcrumbData, - XhrBreadcrumbData, - FetchBreadcrumbHint, - XhrBreadcrumbHint, -} from './breadcrumb'; -export type { Client } from './client'; -export type { ClientReport, Outcome, EventDropReason } from './clientreport'; -export type { - Context, - Contexts, - DeviceContext, - OsContext, - AppContext, - CultureContext, - TraceContext, - CloudResourceContext, - MissingInstrumentationContext, -} from './context'; -export type { DataCategory } from './datacategory'; -export type { DsnComponents, DsnLike, DsnProtocol } from './dsn'; -export type { DebugImage, DebugMeta } from './debugMeta'; -export type { - AttachmentItem, - BaseEnvelopeHeaders, - BaseEnvelopeItemHeaders, - ClientReportEnvelope, - ClientReportItem, - DynamicSamplingContext, - Envelope, - EnvelopeItemType, - EnvelopeItem, - EventEnvelope, - EventEnvelopeHeaders, - EventItem, - ReplayEnvelope, - FeedbackItem, - SessionEnvelope, - SessionItem, - UserFeedbackItem, - CheckInItem, - CheckInEnvelope, - StatsdItem, - StatsdEnvelope, - ProfileItem, - ProfileChunkEnvelope, - ProfileChunkItem, - SpanEnvelope, - SpanItem, -} from './envelope'; -export type { ExtendedError } from './error'; -export type { Event, EventHint, EventType, ErrorEvent, TransactionEvent } from './event'; -export type { EventProcessor } from './eventprocessor'; -export type { Exception } from './exception'; -export type { Extra, Extras } from './extra'; -// eslint-disable-next-line deprecation/deprecation -export type { Hub } from './hub'; -export type { Integration, IntegrationClass, IntegrationFn } from './integration'; -export type { Mechanism } from './mechanism'; -export type { ExtractedNodeRequestData, HttpHeaderValue, Primitive, WorkerLocation } from './misc'; -export type { ClientOptions, Options } from './options'; -export type { Package } from './package'; -export type { PolymorphicEvent, PolymorphicRequest } from './polymorphics'; -export type { - ThreadId, - FrameId, - StackId, - ThreadCpuSample, - ThreadCpuStack, - ThreadCpuFrame, - ThreadCpuProfile, - ContinuousThreadCpuProfile, - Profile, - ProfileChunk, -} from './profiling'; -export type { ReplayEvent, ReplayRecordingData, ReplayRecordingMode } from './replay'; -export type { - FeedbackEvent, - FeedbackFormData, - FeedbackInternalOptions, - FeedbackModalIntegration, - FeedbackScreenshotIntegration, - SendFeedback, - SendFeedbackParams, - UserFeedback, -} from './feedback'; -export type { - QueryParams, - RequestEventData, - // eslint-disable-next-line deprecation/deprecation - Request, - SanitizedRequestData, -} from './request'; -export type { Runtime } from './runtime'; -export type { CaptureContext, Scope, ScopeContext, ScopeData } from './scope'; -export type { SdkInfo } from './sdkinfo'; -export type { SdkMetadata } from './sdkmetadata'; -export type { - SessionAggregates, - AggregationCounts, - Session, - SessionContext, - SessionStatus, - RequestSession, - RequestSessionStatus, - SessionFlusherLike, - SerializedSession, -} from './session'; - -export type { SeverityLevel } from './severity'; -export type { - Span, - SentrySpanArguments, - SpanOrigin, - SpanAttributeValue, - SpanAttributes, - SpanTimeInput, - SpanJSON, - SpanContextData, - TraceFlag, - MetricSummary, -} from './span'; -export type { SpanStatus } from './spanStatus'; -export type { TimedEvent } from './timedEvent'; -export type { StackFrame } from './stackframe'; -export type { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from './stacktrace'; -export type { PropagationContext, TracePropagationTargets, SerializedTraceData } from './tracing'; -export type { StartSpanOptions } from './startSpanOptions'; -export type { - TraceparentData, - TransactionSource, -} from './transaction'; -export type { CustomSamplingContext, SamplingContext } from './samplingcontext'; -export type { - DurationUnit, - InformationUnit, - FractionUnit, - MeasurementUnit, - NoneUnit, - Measurements, -} from './measurement'; -export type { Thread } from './thread'; -export type { - Transport, - TransportRequest, - TransportMakeRequestResponse, - InternalBaseTransportOptions, - BaseTransportOptions, - TransportRequestExecutor, -} from './transport'; -export type { User } from './user'; -export type { WebFetchHeaders, WebFetchRequest } from './webfetchapi'; -export type { WrappedFunction } from './wrappedfunction'; -export type { - HandlerDataFetch, - HandlerDataXhr, - HandlerDataDom, - HandlerDataConsole, - HandlerDataHistory, - HandlerDataError, - HandlerDataUnhandledRejection, - ConsoleLevel, - SentryXhrData, - SentryWrappedXMLHttpRequest, -} from './instrument'; +/* eslint-disable max-lines */ +import type { + AggregationCounts as AggregationCounts_imported, + AppContext as AppContext_imported, + Attachment as Attachment_imported, + AttachmentItem as AttachmentItem_imported, + BaseEnvelopeHeaders as BaseEnvelopeHeaders_imported, + BaseEnvelopeItemHeaders as BaseEnvelopeItemHeaders_imported, + BaseTransportOptions as BaseTransportOptions_imported, + Breadcrumb as Breadcrumb_imported, + BreadcrumbHint as BreadcrumbHint_imported, + BrowserClientProfilingOptions as BrowserClientProfilingOptions_imported, + BrowserClientReplayOptions as BrowserClientReplayOptions_imported, + CaptureContext as CaptureContext_imported, + CheckIn as CheckIn_imported, + CheckInEnvelope as CheckInEnvelope_imported, + CheckInItem as CheckInItem_imported, + Client as Client_imported, + ClientOptions as ClientOptions_imported, + ClientReport as ClientReport_imported, + ClientReportEnvelope as ClientReportEnvelope_imported, + ClientReportItem as ClientReportItem_imported, + CloudResourceContext as CloudResourceContext_imported, + ConsoleLevel as ConsoleLevel_imported, + Context as Context_imported, + Contexts as Contexts_imported, + ContinuousProfiler as ContinuousProfiler_imported, + ContinuousThreadCpuProfile as ContinuousThreadCpuProfile_imported, + CultureContext as CultureContext_imported, + CustomSamplingContext as CustomSamplingContext_imported, + DataCategory as DataCategory_imported, + DebugImage as DebugImage_imported, + DebugMeta as DebugMeta_imported, + DeviceContext as DeviceContext_imported, + DsnComponents as DsnComponents_imported, + DsnLike as DsnLike_imported, + DsnProtocol as DsnProtocol_imported, + DurationUnit as DurationUnit_imported, + DynamicSamplingContext as DynamicSamplingContext_imported, + Envelope as Envelope_imported, + EnvelopeItem as EnvelopeItem_imported, + EnvelopeItemType as EnvelopeItemType_imported, + ErrorEvent as ErrorEvent_imported, + Event as Event_imported, + EventDropReason as EventDropReason_imported, + EventEnvelope as EventEnvelope_imported, + EventEnvelopeHeaders as EventEnvelopeHeaders_imported, + EventHint as EventHint_imported, + EventItem as EventItem_imported, + EventProcessor as EventProcessor_imported, + EventType as EventType_imported, + Exception as Exception_imported, + ExtendedError as ExtendedError_imported, + Extra as Extra_imported, + ExtractedNodeRequestData as ExtractedNodeRequestData_imported, + Extras as Extras_imported, + FeedbackEvent as FeedbackEvent_imported, + FeedbackFormData as FeedbackFormData_imported, + FeedbackInternalOptions as FeedbackInternalOptions_imported, + FeedbackItem as FeedbackItem_imported, + FeedbackModalIntegration as FeedbackModalIntegration_imported, + FeedbackScreenshotIntegration as FeedbackScreenshotIntegration_imported, + FetchBreadcrumbData as FetchBreadcrumbData_imported, + FetchBreadcrumbHint as FetchBreadcrumbHint_imported, + FinishedCheckIn as FinishedCheckIn_imported, + FractionUnit as FractionUnit_imported, + FrameId as FrameId_imported, + HandlerDataConsole as HandlerDataConsole_imported, + HandlerDataDom as HandlerDataDom_imported, + HandlerDataError as HandlerDataError_imported, + HandlerDataFetch as HandlerDataFetch_imported, + HandlerDataHistory as HandlerDataHistory_imported, + HandlerDataUnhandledRejection as HandlerDataUnhandledRejection_imported, + HandlerDataXhr as HandlerDataXhr_imported, + HttpHeaderValue as HttpHeaderValue_imported, + Hub as Hub_imported, + InProgressCheckIn as InProgressCheckIn_imported, + InformationUnit as InformationUnit_imported, + Integration as Integration_imported, + IntegrationClass as IntegrationClass_imported, + IntegrationFn as IntegrationFn_imported, + InternalBaseTransportOptions as InternalBaseTransportOptions_imported, + MeasurementUnit as MeasurementUnit_imported, + Measurements as Measurements_imported, + Mechanism as Mechanism_imported, + MetricBucketItem as MetricBucketItem_imported, + MetricData as MetricData_imported, + MetricInstance as MetricInstance_imported, + MetricSummary as MetricSummary_imported, + Metrics as Metrics_imported, + MetricsAggregator as MetricsAggregator_imported, + MissingInstrumentationContext as MissingInstrumentationContext_imported, + MonitorConfig as MonitorConfig_imported, + NoneUnit as NoneUnit_imported, + Options as Options_imported, + OsContext as OsContext_imported, + Outcome as Outcome_imported, + Package as Package_imported, + ParameterizedString as ParameterizedString_imported, + PolymorphicEvent as PolymorphicEvent_imported, + PolymorphicRequest as PolymorphicRequest_imported, + Primitive as Primitive_imported, + Profile as Profile_imported, + ProfileChunk as ProfileChunk_imported, + ProfileChunkEnvelope as ProfileChunkEnvelope_imported, + ProfileChunkItem as ProfileChunkItem_imported, + ProfileItem as ProfileItem_imported, + Profiler as Profiler_imported, + ProfilingIntegration as ProfilingIntegration_imported, + PropagationContext as PropagationContext_imported, + QueryParams as QueryParams_imported, + ReplayEnvelope as ReplayEnvelope_imported, + ReplayEvent as ReplayEvent_imported, + ReplayRecordingData as ReplayRecordingData_imported, + ReplayRecordingMode as ReplayRecordingMode_imported, + Request as Request_imported, + RequestEventData as RequestEventData_imported, + RequestSession as RequestSession_imported, + RequestSessionStatus as RequestSessionStatus_imported, + Runtime as Runtime_imported, + SamplingContext as SamplingContext_imported, + SanitizedRequestData as SanitizedRequestData_imported, + Scope as Scope_imported, + ScopeContext as ScopeContext_imported, + ScopeData as ScopeData_imported, + SdkInfo as SdkInfo_imported, + SdkMetadata as SdkMetadata_imported, + SendFeedback as SendFeedback_imported, + SendFeedbackParams as SendFeedbackParams_imported, + SentrySpanArguments as SentrySpanArguments_imported, + SentryWrappedXMLHttpRequest as SentryWrappedXMLHttpRequest_imported, + SentryXhrData as SentryXhrData_imported, + SerializedCheckIn as SerializedCheckIn_imported, + SerializedSession as SerializedSession_imported, + SerializedTraceData as SerializedTraceData_imported, + Session as Session_imported, + SessionAggregates as SessionAggregates_imported, + SessionContext as SessionContext_imported, + SessionEnvelope as SessionEnvelope_imported, + SessionFlusherLike as SessionFlusherLike_imported, + SessionItem as SessionItem_imported, + SessionStatus as SessionStatus_imported, + SeverityLevel as SeverityLevel_imported, + Span as Span_imported, + SpanAttributeValue as SpanAttributeValue_imported, + SpanAttributes as SpanAttributes_imported, + SpanContextData as SpanContextData_imported, + SpanEnvelope as SpanEnvelope_imported, + SpanItem as SpanItem_imported, + SpanJSON as SpanJSON_imported, + SpanOrigin as SpanOrigin_imported, + SpanStatus as SpanStatus_imported, + SpanTimeInput as SpanTimeInput_imported, + StackFrame as StackFrame_imported, + StackId as StackId_imported, + StackLineParser as StackLineParser_imported, + StackLineParserFn as StackLineParserFn_imported, + StackParser as StackParser_imported, + Stacktrace as Stacktrace_imported, + StartSpanOptions as StartSpanOptions_imported, + StatsdEnvelope as StatsdEnvelope_imported, + StatsdItem as StatsdItem_imported, + Thread as Thread_imported, + ThreadCpuFrame as ThreadCpuFrame_imported, + ThreadCpuProfile as ThreadCpuProfile_imported, + ThreadCpuSample as ThreadCpuSample_imported, + ThreadCpuStack as ThreadCpuStack_imported, + ThreadId as ThreadId_imported, + TimedEvent as TimedEvent_imported, + TraceContext as TraceContext_imported, + TraceFlag as TraceFlag_imported, + TracePropagationTargets as TracePropagationTargets_imported, + TraceparentData as TraceparentData_imported, + TransactionEvent as TransactionEvent_imported, + TransactionSource as TransactionSource_imported, + Transport as Transport_imported, + TransportMakeRequestResponse as TransportMakeRequestResponse_imported, + TransportRequest as TransportRequest_imported, + TransportRequestExecutor as TransportRequestExecutor_imported, + User as User_imported, + UserFeedback as UserFeedback_imported, + UserFeedbackItem as UserFeedbackItem_imported, + ViewHierarchyData as ViewHierarchyData_imported, + ViewHierarchyWindow as ViewHierarchyWindow_imported, + WebFetchHeaders as WebFetchHeaders_imported, + WebFetchRequest as WebFetchRequest_imported, + WorkerLocation as WorkerLocation_imported, + WrappedFunction as WrappedFunction_imported, + XhrBreadcrumbData as XhrBreadcrumbData_imported, + XhrBreadcrumbHint as XhrBreadcrumbHint_imported, +} from '@sentry/core'; -export type { BrowserClientReplayOptions, BrowserClientProfilingOptions } from './browseroptions'; -export type { CheckIn, MonitorConfig, FinishedCheckIn, InProgressCheckIn, SerializedCheckIn } from './checkin'; -export type { - MetricsAggregator, - MetricBucketItem, - MetricInstance, - MetricData, - Metrics, -} from './metrics'; -export type { ParameterizedString } from './parameterize'; -export type { ContinuousProfiler, ProfilingIntegration, Profiler } from './profiling'; -export type { ViewHierarchyData, ViewHierarchyWindow } from './view-hierarchy'; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Attachment = Attachment_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Breadcrumb = Breadcrumb_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type BreadcrumbHint = BreadcrumbHint_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FetchBreadcrumbData = FetchBreadcrumbData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type XhrBreadcrumbData = XhrBreadcrumbData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FetchBreadcrumbHint = FetchBreadcrumbHint_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type XhrBreadcrumbHint = XhrBreadcrumbHint_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Client = Client_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ClientReport = ClientReport_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Outcome = Outcome_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EventDropReason = EventDropReason_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Context = Context_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Contexts = Contexts_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DeviceContext = DeviceContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type OsContext = OsContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type AppContext = AppContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type CultureContext = CultureContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TraceContext = TraceContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type CloudResourceContext = CloudResourceContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MissingInstrumentationContext = MissingInstrumentationContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DataCategory = DataCategory_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DsnComponents = DsnComponents_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DsnLike = DsnLike_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DsnProtocol = DsnProtocol_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DebugImage = DebugImage_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DebugMeta = DebugMeta_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type AttachmentItem = AttachmentItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type BaseEnvelopeHeaders = BaseEnvelopeHeaders_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type BaseEnvelopeItemHeaders = BaseEnvelopeItemHeaders_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ClientReportEnvelope = ClientReportEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ClientReportItem = ClientReportItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DynamicSamplingContext = DynamicSamplingContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Envelope = Envelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EnvelopeItemType = EnvelopeItemType_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EnvelopeItem = EnvelopeItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EventEnvelope = EventEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EventEnvelopeHeaders = EventEnvelopeHeaders_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EventItem = EventItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ReplayEnvelope = ReplayEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FeedbackItem = FeedbackItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SessionEnvelope = SessionEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SessionItem = SessionItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type UserFeedbackItem = UserFeedbackItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type CheckInItem = CheckInItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type CheckInEnvelope = CheckInEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StatsdItem = StatsdItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StatsdEnvelope = StatsdEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ProfileItem = ProfileItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ProfileChunkEnvelope = ProfileChunkEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ProfileChunkItem = ProfileChunkItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanEnvelope = SpanEnvelope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanItem = SpanItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ExtendedError = ExtendedError_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Event = Event_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EventHint = EventHint_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EventType = EventType_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ErrorEvent = ErrorEvent_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TransactionEvent = TransactionEvent_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type EventProcessor = EventProcessor_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Exception = Exception_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Extra = Extra_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Extras = Extras_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +// eslint-disable-next-line deprecation/deprecation +export type Hub = Hub_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Integration = Integration_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type IntegrationClass = IntegrationClass_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type IntegrationFn = IntegrationFn_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Mechanism = Mechanism_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ExtractedNodeRequestData = ExtractedNodeRequestData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HttpHeaderValue = HttpHeaderValue_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Primitive = Primitive_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type WorkerLocation = WorkerLocation_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ClientOptions = ClientOptions_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Options = Options_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Package = Package_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type PolymorphicEvent = PolymorphicEvent_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type PolymorphicRequest = PolymorphicRequest_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ThreadId = ThreadId_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FrameId = FrameId_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StackId = StackId_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ThreadCpuSample = ThreadCpuSample_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ThreadCpuStack = ThreadCpuStack_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ThreadCpuFrame = ThreadCpuFrame_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ThreadCpuProfile = ThreadCpuProfile_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ContinuousThreadCpuProfile = ContinuousThreadCpuProfile_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Profile = Profile_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ProfileChunk = ProfileChunk_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ReplayEvent = ReplayEvent_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ReplayRecordingData = ReplayRecordingData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ReplayRecordingMode = ReplayRecordingMode_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FeedbackEvent = FeedbackEvent_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FeedbackFormData = FeedbackFormData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FeedbackInternalOptions = FeedbackInternalOptions_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FeedbackModalIntegration = FeedbackModalIntegration_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FeedbackScreenshotIntegration = FeedbackScreenshotIntegration_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SendFeedback = SendFeedback_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SendFeedbackParams = SendFeedbackParams_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type UserFeedback = UserFeedback_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type QueryParams = QueryParams_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type RequestEventData = RequestEventData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +// eslint-disable-next-line deprecation/deprecation +export type Request = Request_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SanitizedRequestData = SanitizedRequestData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Runtime = Runtime_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type CaptureContext = CaptureContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Scope = Scope_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ScopeContext = ScopeContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ScopeData = ScopeData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SdkInfo = SdkInfo_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SdkMetadata = SdkMetadata_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SessionAggregates = SessionAggregates_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type AggregationCounts = AggregationCounts_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Session = Session_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SessionContext = SessionContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SessionStatus = SessionStatus_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type RequestSession = RequestSession_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type RequestSessionStatus = RequestSessionStatus_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SessionFlusherLike = SessionFlusherLike_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SerializedSession = SerializedSession_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SeverityLevel = SeverityLevel_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Span = Span_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SentrySpanArguments = SentrySpanArguments_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanOrigin = SpanOrigin_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanAttributeValue = SpanAttributeValue_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanAttributes = SpanAttributes_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanTimeInput = SpanTimeInput_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanJSON = SpanJSON_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanContextData = SpanContextData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TraceFlag = TraceFlag_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MetricSummary = MetricSummary_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SpanStatus = SpanStatus_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TimedEvent = TimedEvent_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StackFrame = StackFrame_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Stacktrace = Stacktrace_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StackParser = StackParser_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StackLineParser = StackLineParser_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StackLineParserFn = StackLineParserFn_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type PropagationContext = PropagationContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TracePropagationTargets = TracePropagationTargets_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SerializedTraceData = SerializedTraceData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type StartSpanOptions = StartSpanOptions_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TraceparentData = TraceparentData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TransactionSource = TransactionSource_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type CustomSamplingContext = CustomSamplingContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SamplingContext = SamplingContext_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type DurationUnit = DurationUnit_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type InformationUnit = InformationUnit_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FractionUnit = FractionUnit_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MeasurementUnit = MeasurementUnit_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type NoneUnit = NoneUnit_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Measurements = Measurements_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Thread = Thread_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Transport = Transport_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TransportRequest = TransportRequest_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TransportMakeRequestResponse = TransportMakeRequestResponse_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type InternalBaseTransportOptions = InternalBaseTransportOptions_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type BaseTransportOptions = BaseTransportOptions_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type TransportRequestExecutor = TransportRequestExecutor_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type User = User_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type WebFetchHeaders = WebFetchHeaders_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type WebFetchRequest = WebFetchRequest_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type WrappedFunction = WrappedFunction_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HandlerDataFetch = HandlerDataFetch_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HandlerDataXhr = HandlerDataXhr_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HandlerDataDom = HandlerDataDom_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HandlerDataConsole = HandlerDataConsole_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HandlerDataHistory = HandlerDataHistory_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HandlerDataError = HandlerDataError_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type HandlerDataUnhandledRejection = HandlerDataUnhandledRejection_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ConsoleLevel = ConsoleLevel_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SentryXhrData = SentryXhrData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SentryWrappedXMLHttpRequest = SentryWrappedXMLHttpRequest_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type BrowserClientReplayOptions = BrowserClientReplayOptions_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type BrowserClientProfilingOptions = BrowserClientProfilingOptions_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type CheckIn = CheckIn_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MonitorConfig = MonitorConfig_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type FinishedCheckIn = FinishedCheckIn_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type InProgressCheckIn = InProgressCheckIn_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type SerializedCheckIn = SerializedCheckIn_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MetricsAggregator = MetricsAggregator_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MetricBucketItem = MetricBucketItem_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MetricInstance = MetricInstance_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type MetricData = MetricData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Metrics = Metrics_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ParameterizedString = ParameterizedString_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ContinuousProfiler = ContinuousProfiler_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ProfilingIntegration = ProfilingIntegration_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type Profiler = Profiler_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ViewHierarchyData = ViewHierarchyData_imported; +/** @deprecated This type has been moved to `@sentry/core`. */ +export type ViewHierarchyWindow = ViewHierarchyWindow_imported; diff --git a/packages/types/src/wrappedfunction.ts b/packages/types/src/wrappedfunction.ts deleted file mode 100644 index 410e5da1cfc1..000000000000 --- a/packages/types/src/wrappedfunction.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** JSDoc */ -export interface WrappedFunction extends Function { - [key: string]: any; - __sentry_wrapped__?: WrappedFunction; - __sentry_original__?: WrappedFunction; -} diff --git a/packages/typescript/package.json b/packages/typescript/package.json index fa5fd69fbc31..ec18bea1fb1d 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/typescript", - "version": "8.40.0", + "version": "8.42.0", "description": "Typescript configuration used at Sentry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/typescript", diff --git a/packages/utils/package.json b/packages/utils/package.json index 9cb0f1e92f32..9bb812b85cb7 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/utils", - "version": "8.40.0", + "version": "8.42.0", "description": "Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/utils", @@ -39,8 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 28629a1b240e..1d8d712e5b0f 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -517,6 +517,7 @@ export const watchdogTimer = watchdogTimer_imported; export const LRUMap = LRUMap_imported; /** @deprecated Import from `@sentry/core` instead. */ +// eslint-disable-next-line deprecation/deprecation export const generatePropagationContext = generatePropagationContext_imported; /** @deprecated Import from `@sentry/core` instead. */ @@ -592,6 +593,7 @@ export const supportsReferrerPolicy = supportsReferrerPolicy_imported; export const supportsReportingObserver = supportsReportingObserver_imported; /** @deprecated Import from `@sentry/core` instead. */ +// eslint-disable-next-line deprecation/deprecation export const _browserPerformanceTimeOriginMode = _browserPerformanceTimeOriginMode_imported; /** @deprecated Import from `@sentry/core` instead. */ @@ -601,6 +603,7 @@ export const browserPerformanceTimeOrigin = browserPerformanceTimeOrigin_importe export const supportsHistory = supportsHistory_imported; /** @deprecated Import from `@sentry/core` instead. */ +// eslint-disable-next-line deprecation/deprecation export const dynamicRequire = dynamicRequire_imported; /** @deprecated Import from `@sentry/core` instead. */ @@ -666,6 +669,7 @@ export const _optionalChainDelete = _optionalChainDelete_imported; export const BAGGAGE_HEADER_NAME = BAGGAGE_HEADER_NAME_imported; /** @deprecated Import from `@sentry/core` instead. */ +// eslint-disable-next-line deprecation/deprecation export const getNumberOfUrlSegments = getNumberOfUrlSegments_imported; /** @deprecated Import from `@sentry/core` instead. */ diff --git a/packages/vercel-edge/package.json b/packages/vercel-edge/package.json index a0e5d438c9dc..54fcde136c90 100644 --- a/packages/vercel-edge/package.json +++ b/packages/vercel-edge/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vercel-edge", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for the Vercel Edge Runtime", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vercel-edge", @@ -40,8 +40,7 @@ }, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/core": "8.42.0" }, "devDependencies": { "@edge-runtime/types": "3.0.1", @@ -49,7 +48,7 @@ "@opentelemetry/resources": "^1.26.0", "@opentelemetry/sdk-trace-base": "^1.26.0", "@opentelemetry/semantic-conventions": "^1.27.0", - "@sentry/opentelemetry": "8.40.0" + "@sentry/opentelemetry": "8.42.0" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/vercel-edge/src/index.ts b/packages/vercel-edge/src/index.ts index 1675e9b5b359..d6e6fc046837 100644 --- a/packages/vercel-edge/src/index.ts +++ b/packages/vercel-edge/src/index.ts @@ -17,7 +17,7 @@ export type { Stacktrace, Thread, User, -} from '@sentry/types'; +} from '@sentry/core'; export type { AddRequestDataToEventOptions } from '@sentry/core'; export type { VercelEdgeOptions } from './types'; diff --git a/packages/vercel-edge/src/integrations/wintercg-fetch.ts b/packages/vercel-edge/src/integrations/wintercg-fetch.ts index 7371ebcec8b7..da9e044945e2 100644 --- a/packages/vercel-edge/src/integrations/wintercg-fetch.ts +++ b/packages/vercel-edge/src/integrations/wintercg-fetch.ts @@ -1,10 +1,3 @@ -import { addBreadcrumb, defineIntegration, getClient, instrumentFetchRequest, isSentryRequestUrl } from '@sentry/core'; -import { - LRUMap, - addFetchInstrumentationHandler, - getBreadcrumbLogLevelFromHttpStatusCode, - stringMatchesSomePattern, -} from '@sentry/core'; import type { Client, FetchBreadcrumbData, @@ -12,7 +5,18 @@ import type { HandlerDataFetch, IntegrationFn, Span, -} from '@sentry/types'; +} from '@sentry/core'; +import { + LRUMap, + addBreadcrumb, + addFetchInstrumentationHandler, + defineIntegration, + getBreadcrumbLogLevelFromHttpStatusCode, + getClient, + instrumentFetchRequest, + isSentryRequestUrl, + stringMatchesSomePattern, +} from '@sentry/core'; const INTEGRATION_NAME = 'WinterCGFetch'; diff --git a/packages/vercel-edge/src/sdk.ts b/packages/vercel-edge/src/sdk.ts index 141a3ba19ff5..2ddfa96fcd45 100644 --- a/packages/vercel-edge/src/sdk.ts +++ b/packages/vercel-edge/src/sdk.ts @@ -1,4 +1,16 @@ +import { DiagLogLevel, diag } from '@opentelemetry/api'; +import { Resource } from '@opentelemetry/resources'; +import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; +import { + ATTR_SERVICE_NAME, + ATTR_SERVICE_VERSION, + SEMRESATTRS_SERVICE_NAMESPACE, +} from '@opentelemetry/semantic-conventions'; +import type { Client, Integration, Options } from '@sentry/core'; import { + GLOBAL_OBJ, + SDK_VERSION, + createStackParser, dedupeIntegration, functionToStringIntegration, getCurrentScope, @@ -6,26 +18,11 @@ import { hasTracingEnabled, inboundFiltersIntegration, linkedErrorsIntegration, - requestDataIntegration, -} from '@sentry/core'; -import { - GLOBAL_OBJ, - SDK_VERSION, - createStackParser, logger, nodeStackLineParser, + requestDataIntegration, stackParserFromStackParserOptions, } from '@sentry/core'; -import type { Client, Integration, Options } from '@sentry/types'; - -import { DiagLogLevel, diag } from '@opentelemetry/api'; -import { Resource } from '@opentelemetry/resources'; -import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; -import { - ATTR_SERVICE_NAME, - ATTR_SERVICE_VERSION, - SEMRESATTRS_SERVICE_NAMESPACE, -} from '@opentelemetry/semantic-conventions'; import { SentryPropagator, SentrySampler, diff --git a/packages/vercel-edge/src/transports/index.ts b/packages/vercel-edge/src/transports/index.ts index ade9f83944f7..e938477b3003 100644 --- a/packages/vercel-edge/src/transports/index.ts +++ b/packages/vercel-edge/src/transports/index.ts @@ -1,6 +1,5 @@ -import { createTransport, suppressTracing } from '@sentry/core'; -import { SentryError } from '@sentry/core'; -import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; +import type { BaseTransportOptions, Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/core'; +import { SentryError, createTransport, suppressTracing } from '@sentry/core'; export interface VercelEdgeTransportOptions extends BaseTransportOptions { /** Fetch API init parameters. */ diff --git a/packages/vercel-edge/src/transports/types.ts b/packages/vercel-edge/src/transports/types.ts index e6c0ab869662..70bf888f2666 100644 --- a/packages/vercel-edge/src/transports/types.ts +++ b/packages/vercel-edge/src/transports/types.ts @@ -1,4 +1,4 @@ -import type { BaseTransportOptions } from '@sentry/types'; +import type { BaseTransportOptions } from '@sentry/core'; export interface VercelEdgeTransportOptions extends BaseTransportOptions { /** Fetch API init parameters. */ diff --git a/packages/vercel-edge/src/types.ts b/packages/vercel-edge/src/types.ts index 26bc1b911875..2128f23b35a8 100644 --- a/packages/vercel-edge/src/types.ts +++ b/packages/vercel-edge/src/types.ts @@ -1,4 +1,4 @@ -import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/types'; +import type { ClientOptions, Options, TracePropagationTargets } from '@sentry/core'; import type { VercelEdgeClient } from './client'; import type { VercelEdgeTransportOptions } from './transports'; @@ -60,7 +60,7 @@ export interface BaseVercelEdgeOptions { /** * Configuration options for the Sentry VercelEdge SDK - * @see @sentry/types Options for more information. + * @see @sentry/core Options for more information. */ export interface VercelEdgeOptions extends Options, BaseVercelEdgeOptions {} diff --git a/packages/vercel-edge/test/transports/index.test.ts b/packages/vercel-edge/test/transports/index.test.ts index 4534d1b8169a..4434a177d0f8 100644 --- a/packages/vercel-edge/test/transports/index.test.ts +++ b/packages/vercel-edge/test/transports/index.test.ts @@ -1,7 +1,7 @@ import { afterAll, describe, expect, it, vi } from 'vitest'; import { createEnvelope, serializeEnvelope } from '@sentry/core'; -import type { EventEnvelope, EventItem } from '@sentry/types'; +import type { EventEnvelope, EventItem } from '@sentry/core'; import type { VercelEdgeTransportOptions } from '../../src/transports'; import { IsolatedPromiseBuffer, makeEdgeTransport } from '../../src/transports'; diff --git a/packages/vercel-edge/test/wintercg-fetch.test.ts b/packages/vercel-edge/test/wintercg-fetch.test.ts index ac00e27dcac8..16e530710844 100644 --- a/packages/vercel-edge/test/wintercg-fetch.test.ts +++ b/packages/vercel-edge/test/wintercg-fetch.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import * as sentryCore from '@sentry/core'; import * as sentryUtils from '@sentry/core'; import { createStackParser } from '@sentry/core'; -import type { HandlerDataFetch, Integration } from '@sentry/types'; +import type { HandlerDataFetch, Integration } from '@sentry/core'; import { VercelEdgeClient } from '../src/index'; import { winterCGFetchIntegration } from '../src/integrations/wintercg-fetch'; diff --git a/packages/vue/package.json b/packages/vue/package.json index 037f6f7fad0d..d99c78e1d9bc 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vue", - "version": "8.40.0", + "version": "8.42.0", "description": "Official Sentry SDK for Vue.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vue", @@ -39,9 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0" }, "peerDependencies": { "pinia": "2.x", diff --git a/packages/vue/src/browserTracingIntegration.ts b/packages/vue/src/browserTracingIntegration.ts index e3d178628724..8f542ddf1b1d 100644 --- a/packages/vue/src/browserTracingIntegration.ts +++ b/packages/vue/src/browserTracingIntegration.ts @@ -2,7 +2,7 @@ import { browserTracingIntegration as originalBrowserTracingIntegration, startBrowserTracingNavigationSpan, } from '@sentry/browser'; -import type { Integration, StartSpanOptions } from '@sentry/types'; +import type { Integration, StartSpanOptions } from '@sentry/core'; import { instrumentVueRouter } from './router'; // The following type is an intersection of the Route type from VueRouter v2, v3, and v4. diff --git a/packages/vue/src/errorhandler.ts b/packages/vue/src/errorhandler.ts index 95ca6ce483c0..6a3951cc1855 100644 --- a/packages/vue/src/errorhandler.ts +++ b/packages/vue/src/errorhandler.ts @@ -1,6 +1,4 @@ -import { captureException } from '@sentry/core'; -import { consoleSandbox } from '@sentry/core'; - +import { captureException, consoleSandbox } from '@sentry/core'; import type { ViewModel, Vue, VueOptions } from './types'; import { formatComponentName, generateComponentTrace } from './vendor/components'; diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 096b7a2144e5..7e57d55865f7 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -5,4 +5,5 @@ export { browserTracingIntegration } from './browserTracingIntegration'; export { attachErrorHandler } from './errorhandler'; export { createTracingMixins } from './tracing'; export { vueIntegration } from './integration'; +export type { VueIntegrationOptions } from './integration'; export { createSentryPiniaPlugin } from './pinia'; diff --git a/packages/vue/src/integration.ts b/packages/vue/src/integration.ts index 22f394d72720..5c30a956304b 100644 --- a/packages/vue/src/integration.ts +++ b/packages/vue/src/integration.ts @@ -19,6 +19,8 @@ const DEFAULT_CONFIG: VueOptions = { const INTEGRATION_NAME = 'Vue'; +export type VueIntegrationOptions = Partial; + export const vueIntegration = defineIntegration((integrationOptions: Partial = {}) => { return { name: INTEGRATION_NAME, diff --git a/packages/vue/src/pinia.ts b/packages/vue/src/pinia.ts index 56e38c33bad7..031f0f5f110b 100644 --- a/packages/vue/src/pinia.ts +++ b/packages/vue/src/pinia.ts @@ -1,5 +1,4 @@ -import { addBreadcrumb, getClient, getCurrentScope, getGlobalScope } from '@sentry/core'; -import { addNonEnumerableProperty } from '@sentry/core'; +import { addBreadcrumb, addNonEnumerableProperty, getClient, getCurrentScope, getGlobalScope } from '@sentry/core'; // Inline PiniaPlugin type type PiniaPlugin = (context: { diff --git a/packages/vue/src/router.ts b/packages/vue/src/router.ts index 8e8bf32ac172..73211c6cfc40 100644 --- a/packages/vue/src/router.ts +++ b/packages/vue/src/router.ts @@ -7,7 +7,7 @@ import { getRootSpan, spanToJSON, } from '@sentry/core'; -import type { Span, SpanAttributes, StartSpanOptions, TransactionSource } from '@sentry/types'; +import type { Span, SpanAttributes, StartSpanOptions, TransactionSource } from '@sentry/core'; // The following type is an intersection of the Route type from VueRouter v2, v3, and v4. // This is not great, but kinda necessary to make it work with all versions at the same time. diff --git a/packages/vue/src/sdk.ts b/packages/vue/src/sdk.ts index 54025ea052ee..532da6f350f4 100644 --- a/packages/vue/src/sdk.ts +++ b/packages/vue/src/sdk.ts @@ -1,6 +1,6 @@ import { SDK_VERSION, getDefaultIntegrations, init as browserInit } from '@sentry/browser'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import { vueIntegration } from './integration'; import type { Options, TracingOptions } from './types'; @@ -8,7 +8,14 @@ import type { Options, TracingOptions } from './types'; * Inits the Vue SDK */ export function init( - config: Partial & { tracingOptions: Partial }> = {}, + config: Partial< + Omit & { + /** + * @deprecated Add the `vueIntegration()` and pass the `tracingOptions` there instead. + */ + tracingOptions: Partial; + } + > = {}, ): Client | undefined { const options = { _metadata: { diff --git a/packages/vue/src/tracing.ts b/packages/vue/src/tracing.ts index 8170516eea16..055e46039d66 100644 --- a/packages/vue/src/tracing.ts +++ b/packages/vue/src/tracing.ts @@ -1,6 +1,6 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, getActiveSpan, startInactiveSpan } from '@sentry/browser'; import { logger, timestampInSeconds } from '@sentry/core'; -import type { Span } from '@sentry/types'; +import type { Span } from '@sentry/core'; import { DEFAULT_HOOKS } from './constants'; import { DEBUG_BUILD } from './debug-build'; diff --git a/packages/vue/test/integration/VueIntegration.test.ts b/packages/vue/test/integration/VueIntegration.test.ts index 52445a353d23..9b59ccc18897 100644 --- a/packages/vue/test/integration/VueIntegration.test.ts +++ b/packages/vue/test/integration/VueIntegration.test.ts @@ -5,7 +5,7 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; import { logger } from '@sentry/core'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import { createApp } from 'vue'; import * as Sentry from '../../src'; diff --git a/packages/vue/test/integration/init.test.ts b/packages/vue/test/integration/init.test.ts index 699f99a7057c..4b2e8fbea826 100644 --- a/packages/vue/test/integration/init.test.ts +++ b/packages/vue/test/integration/init.test.ts @@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { createApp } from 'vue'; -import type { Client } from '@sentry/types'; +import type { Client } from '@sentry/core'; import type { Options } from '../../src/types'; import * as Sentry from './../../src'; diff --git a/packages/vue/test/router.test.ts b/packages/vue/test/router.test.ts index 1da5097b11e0..886423b452bb 100644 --- a/packages/vue/test/router.test.ts +++ b/packages/vue/test/router.test.ts @@ -3,7 +3,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'; import * as SentryBrowser from '@sentry/browser'; import * as SentryCore from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; -import type { Span, SpanAttributes } from '@sentry/types'; +import type { Span, SpanAttributes } from '@sentry/core'; import type { Route } from '../src/router'; import { instrumentVueRouter } from '../src/router'; diff --git a/packages/wasm/package.json b/packages/wasm/package.json index 13d5d44d55bf..275356eb9463 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/wasm", - "version": "8.40.0", + "version": "8.42.0", "description": "Support for WASM.", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/wasm", @@ -39,9 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.40.0", - "@sentry/core": "8.40.0", - "@sentry/types": "8.40.0" + "@sentry/browser": "8.42.0", + "@sentry/core": "8.42.0" }, "scripts": { "build": "run-p build:transpile build:bundle build:types", diff --git a/packages/wasm/src/index.ts b/packages/wasm/src/index.ts index 832a7e89b687..adad9fa35480 100644 --- a/packages/wasm/src/index.ts +++ b/packages/wasm/src/index.ts @@ -1,5 +1,5 @@ import { defineIntegration } from '@sentry/core'; -import type { Event, IntegrationFn, StackFrame } from '@sentry/types'; +import type { Event, IntegrationFn, StackFrame } from '@sentry/core'; import { patchWebAssembly } from './patchWebAssembly'; import { getImage, getImages } from './registry'; diff --git a/packages/wasm/src/registry.ts b/packages/wasm/src/registry.ts index 989022901709..aa8c5e313dc4 100644 --- a/packages/wasm/src/registry.ts +++ b/packages/wasm/src/registry.ts @@ -1,4 +1,4 @@ -import type { DebugImage } from '@sentry/types'; +import type { DebugImage } from '@sentry/core'; export const IMAGES: Array = []; diff --git a/scripts/build-types-watch.ts b/scripts/build-types-watch.ts index c94cb62f4063..4c8c2bf4559f 100644 --- a/scripts/build-types-watch.ts +++ b/scripts/build-types-watch.ts @@ -3,7 +3,7 @@ * If `yarn build:types:watch` is run without types files previously having been created, the build will get stuck in an * errored state. This happens because lerna runs all of the packages' `yarn build:types:watch` statements in parallel, * and so packages like `@sentry/browser` will at first be missing types they import from packages like `@sentry/core` - * and `@sentry/types`, causing errors to be thrown. Normally this is fine, because as the dependencies' types get + * and `@sentry/core`, causing errors to be thrown. Normally this is fine, because as the dependencies' types get * built, file changes will be detected and the dependent packages' types will try again to build themselves. There * might be several rounds of this, but in theory, eventually all packages should end up with an error-free build. For * whatever reason, though, at a certain point the process hangs, either because changes stop being detected or because diff --git a/yarn.lock b/yarn.lock index 7bae79772a90..1f76a563cb60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -29704,10 +29704,10 @@ rimraf@^4.4.1: dependencies: glob "^9.2.0" -rimraf@^5.0.0: - version "5.0.9" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.9.tgz#c3baa1b886eadc2ec7981a06a593c3d01134ffe9" - integrity sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA== +rimraf@^5.0.10: + version "5.0.10" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.10.tgz#23b9843d3dc92db71f96e1a2ce92e39fd2a8221c" + integrity sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ== dependencies: glob "^10.3.7" @@ -32548,7 +32548,7 @@ typescript@4.6.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== -typescript@4.9.5, typescript@^4.9.5: +typescript@4.9.5: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==