From 8fbff594cd18ddcee796fb699b3e9ca6c8eda880 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 17 May 2024 09:19:43 +0200 Subject: [PATCH 01/34] fix(node): Update `@prisma/instrumentation` from 5.13.0 to 5.14.0 (#12081) This mainly bumps transitive dependencies to be better aligned. --- packages/node/package.json | 2 +- yarn.lock | 64 ++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/packages/node/package.json b/packages/node/package.json index c78e767f7920..4f03e9b86b98 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -75,7 +75,7 @@ "@opentelemetry/resources": "^1.23.0", "@opentelemetry/sdk-trace-base": "^1.23.0", "@opentelemetry/semantic-conventions": "^1.23.0", - "@prisma/instrumentation": "5.13.0", + "@prisma/instrumentation": "5.14.0", "@sentry/core": "8.2.1", "@sentry/opentelemetry": "8.2.1", "@sentry/types": "8.2.1", diff --git a/yarn.lock b/yarn.lock index 9848f21d0b0b..9e40ae48d678 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6112,13 +6112,6 @@ dependencies: "@octokit/openapi-types" "^18.0.0" -"@opentelemetry/api-logs@0.50.0": - version "0.50.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.50.0.tgz#d46b76daab0bc18fa92dcdabacfc106c380d19a1" - integrity sha512-JdZuKrhOYggqOpUljAq4WWNi5nB10PmgoF0y2CvedLGXd0kSawb/UBnWT8gg1ND3bHCNHStAIVT0ELlxJJRqrA== - dependencies: - "@opentelemetry/api" "^1.0.0" - "@opentelemetry/api-logs@0.51.0": version "0.51.0" resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.51.0.tgz#71f296661d2215167c748ca044ff184a65d9426b" @@ -6133,11 +6126,6 @@ dependencies: "@opentelemetry/api" "^1.0.0" -"@opentelemetry/api@1.8.0", "@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.6.0", "@opentelemetry/api@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.8.0.tgz#5aa7abb48f23f693068ed2999ae627d2f7d902ec" - integrity sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w== - "@opentelemetry/api@^0.12.0": version "0.12.0" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.12.0.tgz#0359c3926e8f16fdcd8c78f196bd1e9fc4e66777" @@ -6145,6 +6133,11 @@ dependencies: "@opentelemetry/context-base" "^0.12.0" +"@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.6.0", "@opentelemetry/api@^1.8", "@opentelemetry/api@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.8.0.tgz#5aa7abb48f23f693068ed2999ae627d2f7d902ec" + integrity sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w== + "@opentelemetry/context-async-hooks@^1.23.0": version "1.23.0" resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-1.23.0.tgz#4c4627fe2857324459b0a78b5a83cbc64a415d14" @@ -6328,19 +6321,7 @@ "@types/pg" "8.6.1" "@types/pg-pool" "2.0.4" -"@opentelemetry/instrumentation@0.50.0": - version "0.50.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.50.0.tgz#c558cfc64b84c11d304f31ccdf0de312ec60a2c9" - integrity sha512-bhGhbJiZKpuu7wTaSak4hyZcFPlnDeuSF/2vglze8B4w2LubcSbbOnkVTzTs5SXtzh4Xz8eRjaNnAm+u2GYufQ== - dependencies: - "@opentelemetry/api-logs" "0.50.0" - "@types/shimmer" "^1.0.2" - import-in-the-middle "1.7.1" - require-in-the-middle "^7.1.1" - semver "^7.5.2" - shimmer "^1.2.1" - -"@opentelemetry/instrumentation@0.51.1", "@opentelemetry/instrumentation@^0.51.1": +"@opentelemetry/instrumentation@0.51.1", "@opentelemetry/instrumentation@^0.49 || ^0.50 || ^0.51", "@opentelemetry/instrumentation@^0.51.1": version "0.51.1" resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz#46fb2291150ec6923e50b2f094b9407bc726ca9b" integrity sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w== @@ -6400,6 +6381,14 @@ "@opentelemetry/core" "1.23.0" "@opentelemetry/semantic-conventions" "1.23.0" +"@opentelemetry/resources@1.24.1": + version "1.24.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.24.1.tgz#5e2cb84814824f3b1e1017e6caeeee8402e0ad6e" + integrity sha512-cyv0MwAaPF7O86x5hk3NNgenMObeejZFLJJDVuSeSMIsknlsj3oOZzRv3qSzlwYomXsICfBeFFlxwHQte5mGXQ== + dependencies: + "@opentelemetry/core" "1.24.1" + "@opentelemetry/semantic-conventions" "1.24.1" + "@opentelemetry/resources@^0.12.0": version "0.12.0" resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-0.12.0.tgz#5eb287c3032a2bebb2bb9f69b44bd160d2a7d591" @@ -6417,7 +6406,16 @@ "@opentelemetry/resources" "1.23.0" lodash.merge "^4.6.2" -"@opentelemetry/sdk-trace-base@1.23.0", "@opentelemetry/sdk-trace-base@^1.23.0": +"@opentelemetry/sdk-trace-base@^1.22": + version "1.24.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.24.1.tgz#dc2ab89126e75e442913fb5af98803fde67b2536" + integrity sha512-zz+N423IcySgjihl2NfjBf0qw1RWe11XIAWVrTNOSSI6dtSPJiVom2zipFB2AEEtJWpv0Iz6DY6+TjnyTV5pWg== + dependencies: + "@opentelemetry/core" "1.24.1" + "@opentelemetry/resources" "1.24.1" + "@opentelemetry/semantic-conventions" "1.24.1" + +"@opentelemetry/sdk-trace-base@^1.23.0": version "1.23.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.23.0.tgz#ff0a0f8ec47205e0b14b3b765ea2a34de1ad01dd" integrity sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ== @@ -6489,14 +6487,14 @@ resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.9.1.tgz#d92bd2f7f006e0316cb4fda9d73f235965cf2c64" integrity sha512-caSOnG4kxcSkhqC/2ShV7rEoWwd3XrftokxJqOCMVvia4NYV/TPtJlS9C2os3Igxw/Qyxumj9GBQzcStzECvtQ== -"@prisma/instrumentation@5.13.0": - version "5.13.0" - resolved "https://registry.yarnpkg.com/@prisma/instrumentation/-/instrumentation-5.13.0.tgz#6d4a39ad5cf85757426f9a706b08257b05f273db" - integrity sha512-MEJX1aWLsEjS+2iheBkEy1LlzQuUruPgKEzA9HPMwzitCoUUK1qn5o+yIphU7wWs47Le/cED0egYQL7y9/rSsA== +"@prisma/instrumentation@5.14.0": + version "5.14.0" + resolved "https://registry.yarnpkg.com/@prisma/instrumentation/-/instrumentation-5.14.0.tgz#7a51429f644afce24eb154d518b1c65e37456160" + integrity sha512-DeybWvIZzu/mUsOYP9MVd6AyBj+MP7xIMrcuIn25MX8FiQX39QBnET5KhszTAip/ToctUuDwSJ46QkIoyo3RFA== dependencies: - "@opentelemetry/api" "1.8.0" - "@opentelemetry/instrumentation" "0.50.0" - "@opentelemetry/sdk-trace-base" "1.23.0" + "@opentelemetry/api" "^1.8" + "@opentelemetry/instrumentation" "^0.49 || ^0.50 || ^0.51" + "@opentelemetry/sdk-trace-base" "^1.22" "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" From 56570b3b225a8b77ffbf2d1101205ac6ae4bdc6e Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 17 May 2024 09:27:05 +0200 Subject: [PATCH 02/34] fix(core): Add dsn to span envelope header (#12096) This was forgotten/got lost while we migrated this from v7 to v8. Now, adding the dsn again when the tunnel is enabled. Fixes https://github.com/getsentry/sentry-javascript/issues/12094 --- packages/core/src/envelope.ts | 4 ++++ packages/core/test/lib/envelope.test.ts | 26 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/packages/core/src/envelope.ts b/packages/core/src/envelope.ts index 258216b290d4..d0e5148574f2 100644 --- a/packages/core/src/envelope.ts +++ b/packages/core/src/envelope.ts @@ -110,9 +110,13 @@ export function createSpanEnvelope(spans: SentrySpan[], client?: Client): SpanEn // different segments in one envelope const dsc = getDynamicSamplingContextFromSpan(spans[0]); + const dsn = client && client.getDsn(); + const tunnel = client && client.getOptions().tunnel; + const headers: SpanEnvelope[0] = { sent_at: new Date().toISOString(), ...(dscHasRequiredProps(dsc) && { trace: dsc }), + ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }), }; const beforeSendSpan = client && client.getOptions().beforeSendSpan; diff --git a/packages/core/test/lib/envelope.test.ts b/packages/core/test/lib/envelope.test.ts index 7d5a2c5f7740..5652f48a545d 100644 --- a/packages/core/test/lib/envelope.test.ts +++ b/packages/core/test/lib/envelope.test.ts @@ -144,6 +144,32 @@ describe('createSpanEnvelope', () => { }); }); + it('adds `dsn` envelope header if tunnel is enabled', () => { + const options = getDefaultTestClientOptions({ dsn: 'https://username@domain/123', tunnel: 'http://tunnel' }); + const client = new TestClient(options); + + const spanEnvelope = createSpanEnvelope( + [new SentrySpan({ name: 'test', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom' } })], + client, + ); + + const spanEnvelopeHeaders = spanEnvelope[0]; + expect(spanEnvelopeHeaders.dsn).toEqual('https://username@domain/123'); + }); + + it('does not add `dsn` envelope header if tunnel is not enabled', () => { + const options = getDefaultTestClientOptions({ dsn: 'https://username@domain/123' }); + const client = new TestClient(options); + + const spanEnvelope = createSpanEnvelope( + [new SentrySpan({ name: 'test', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom' } })], + client, + ); + + const spanEnvelopeHeaders = spanEnvelope[0]; + expect(spanEnvelopeHeaders.dsn).toBeUndefined(); + }); + it("doesn't add a `trace` envelope header if there's no public key", () => { const options = getDefaultTestClientOptions({ tracesSampleRate: 1, dsn: 'https://domain/123' }); client = new TestClient(options); From 9bbdfe747446039d58bc7eaf56943417b0a38a1a Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 17 May 2024 09:34:02 +0200 Subject: [PATCH 03/34] feat(node): Do not create GraphQL resolver spans by default (#12097) Users can pass `ignoreResolveSpans` and `ignoreTrivalResolveSpans` to the integration now, which is passed to the instrumentation. They default to `true`. This should reduce noise and perf overhead. Closes https://github.com/getsentry/sentry-javascript/issues/12092 --- .../suites/tracing/apollo-graphql/test.ts | 13 ---------- .../node/src/integrations/tracing/graphql.ts | 25 +++++++++++++++++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/test.ts b/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/test.ts index ad32799a5e79..593ccff485fe 100644 --- a/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/test.ts @@ -16,19 +16,6 @@ describe('GraphQL/Apollo Tests', () => { status: 'ok', origin: 'auto.graphql.otel.graphql', }), - expect.objectContaining({ - data: { - 'graphql.field.name': 'hello', - 'graphql.field.path': 'hello', - 'graphql.field.type': 'String', - 'graphql.source': 'hello', - 'otel.kind': 'INTERNAL', - 'sentry.origin': 'manual', - }, - description: 'graphql.resolve hello', - status: 'ok', - origin: 'manual', - }), ]), }; diff --git a/packages/node/src/integrations/tracing/graphql.ts b/packages/node/src/integrations/tracing/graphql.ts index 498da6c35cb2..4f4fdc93dac9 100644 --- a/packages/node/src/integrations/tracing/graphql.ts +++ b/packages/node/src/integrations/tracing/graphql.ts @@ -5,13 +5,34 @@ import type { IntegrationFn } from '@sentry/types'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; -const _graphqlIntegration = (() => { +interface GraphqlOptions { + /** Do not create spans for resolvers. */ + ignoreResolveSpans?: boolean; + + /** + * Don't create spans for the execution of the default resolver on object properties. + * + * When a resolver function is not defined on the schema for a field, graphql will + * use the default resolver which just looks for a property with that name on the object. + * If the property is not a function, it's not very interesting to trace. + * This option can reduce noise and number of spans created. + */ + ignoreTrivalResolveSpans?: boolean; +} + +const _graphqlIntegration = ((_options: GraphqlOptions = {}) => { + const options = { + ignoreResolveSpans: true, + ignoreTrivialResolveSpans: true, + ..._options, + }; + return { name: 'Graphql', setupOnce() { addOpenTelemetryInstrumentation( new GraphQLInstrumentation({ - ignoreTrivialResolveSpans: true, + ...options, responseHook(span) { addOriginToSpan(span, 'auto.graphql.otel.graphql'); }, From 2f88a5fef35ba7dad8510eaba2b1edf565b3c005 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 17 May 2024 10:20:04 +0200 Subject: [PATCH 04/34] chore: Resolve or postpone a random assortment of TODOs (#11977) --- packages/nextjs/src/common/withServerActionInstrumentation.ts | 1 - .../nextjs/test/integration/test/client/tracingFetch.test.ts | 4 ++-- packages/node/src/transports/http.ts | 2 +- packages/types/src/envelope.ts | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index e70e1682aa9c..109743eea01a 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -15,7 +15,6 @@ import { escapeNextjsTracing } from './utils/tracingUtils'; interface Options { formData?: FormData; - // TODO(v8): Whenever we decide to drop support for Next.js <= 12 we can automatically pick up the headers becauase "next/headers" will be resolvable. headers?: Headers; recordResponse?: boolean; } diff --git a/packages/nextjs/test/integration/test/client/tracingFetch.test.ts b/packages/nextjs/test/integration/test/client/tracingFetch.test.ts index debff6001fce..4d7b416a17dd 100644 --- a/packages/nextjs/test/integration/test/client/tracingFetch.test.ts +++ b/packages/nextjs/test/integration/test/client/tracingFetch.test.ts @@ -1,5 +1,5 @@ import { expect, test } from '@playwright/test'; -import { SerializedEvent } from '@sentry/types'; +import { Event } from '@sentry/types'; import { countEnvelopes, getMultipleSentryEnvelopeRequests } from './utils/helpers'; test('should correctly instrument `fetch` for performance tracing', async ({ page }) => { @@ -12,7 +12,7 @@ test('should correctly instrument `fetch` for performance tracing', async ({ pag }); }); - const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { + const transaction = await getMultipleSentryEnvelopeRequests(page, 1, { url: '/fetch', envelopeType: 'transaction', }); diff --git a/packages/node/src/transports/http.ts b/packages/node/src/transports/http.ts index d4d7435bdc6d..d1828b856c5f 100644 --- a/packages/node/src/transports/http.ts +++ b/packages/node/src/transports/http.ts @@ -73,7 +73,7 @@ export function makeNodeTransport(options: NodeTransportOptions): Transport { const nativeHttpModule = isHttps ? https : http; const keepAlive = options.keepAlive === undefined ? false : options.keepAlive; - // TODO(v7): Evaluate if we can set keepAlive to true. This would involve testing for memory leaks in older node + // TODO(v9): Evaluate if we can set keepAlive to true. This would involve testing for memory leaks in older node // versions(>= 8) as they had memory leaks when using it: #2555 const agent = proxy ? (new HttpsProxyAgent(proxy) as http.Agent) diff --git a/packages/types/src/envelope.ts b/packages/types/src/envelope.ts index 358f60ccee18..61d3b7d38a1d 100644 --- a/packages/types/src/envelope.ts +++ b/packages/types/src/envelope.ts @@ -83,7 +83,6 @@ type StatsdItemHeaders = { type: 'statsd'; length: number }; type ProfileItemHeaders = { type: 'profile' }; type SpanItemHeaders = { type: 'span' }; -// TODO (v8): Replace `Event` with `SerializedEvent` export type EventItem = BaseEnvelopeItem; export type AttachmentItem = BaseEnvelopeItem; export type UserFeedbackItem = BaseEnvelopeItem; From dc9ed37d29ebc1168a6a1a967a742de59424a137 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 17 May 2024 10:49:44 +0200 Subject: [PATCH 05/34] test(nestjs): Better e2e test for nest.js (#12075) Our nest e2e test was not fully correct, and did not test the creation of actual nest.js core spans (only http & express spans). This updates the test setup & check to account for this. --- .../node-nestjs/src/instrument.ts | 9 +++++++++ .../test-applications/node-nestjs/src/main.ts | 12 ++++-------- .../node-nestjs/tests/transactions.test.ts | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/node-nestjs/src/instrument.ts diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs/src/instrument.ts b/dev-packages/e2e-tests/test-applications/node-nestjs/src/instrument.ts new file mode 100644 index 000000000000..09376810454f --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/node-nestjs/src/instrument.ts @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/node'; + +Sentry.init({ + environment: 'qa', // dynamic sampling bias to keep transactions + dsn: process.env.E2E_TEST_DSN, + tunnel: `http://localhost:3031/`, // proxy server + tracesSampleRate: 1, + tracePropagationTargets: ['http://localhost:3030', '/external-allowed'], +}); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs/src/main.ts b/dev-packages/e2e-tests/test-applications/node-nestjs/src/main.ts index b168cc19e7c3..39bfec94b507 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs/src/main.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs/src/main.ts @@ -1,3 +1,7 @@ +// Import this first +import './instrument'; + +// Import other modules import { BaseExceptionFilter, HttpAdapterHost, NestFactory } from '@nestjs/core'; import * as Sentry from '@sentry/node'; import { AppModule1, AppModule2 } from './app.module'; @@ -6,14 +10,6 @@ const app1Port = 3030; const app2Port = 3040; async function bootstrap() { - Sentry.init({ - environment: 'qa', // dynamic sampling bias to keep transactions - dsn: process.env.E2E_TEST_DSN, - tunnel: `http://localhost:3031/`, // proxy server - tracesSampleRate: 1, - tracePropagationTargets: ['http://localhost:3030', '/external-allowed'], - }); - const app1 = await NestFactory.create(AppModule1); const { httpAdapter } = app1.get(HttpAdapterHost); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts index 3fe5c1e65263..08a3998d0ecd 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts @@ -101,6 +101,24 @@ test('Sends an API route transaction', async ({ baseURL }) => { trace_id: expect.any(String), origin: 'manual', }, + { + span_id: expect.any(String), + trace_id: expect.any(String), + data: { + 'sentry.origin': 'manual', + component: '@nestjs/core', + 'nestjs.version': expect.any(String), + 'nestjs.type': 'handler', + 'nestjs.callback': 'testTransaction', + 'otel.kind': 'INTERNAL', + }, + description: 'testTransaction', + parent_span_id: expect.any(String), + start_timestamp: expect.any(Number), + timestamp: expect.any(Number), + status: 'ok', + origin: 'manual', + }, ]), transaction: 'GET /test-transaction', type: 'transaction', From b43779e8a06e958deacad33db44f0f325420ba28 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 17 May 2024 12:47:11 +0200 Subject: [PATCH 06/34] docs: Add migration docs to point out that default import does not work (#12100) It was brought up https://github.com/getsentry/sentry-javascript/issues/12013 that importing Sentry as a default import is not working anymore in v8. While this was never officially supported (and also not "removed" on purpose, it just seemed to have worked incidentally before), I do not really consider this a "breaking change", but, as pointed out in the issue, it is still helpful to point this out in the migration docs, for users who incidentally did this before. We should also add this to migration docs on docs.sentry.io. --- MIGRATION.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MIGRATION.md b/MIGRATION.md index 14e5bdd79a93..89aba556534e 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1323,6 +1323,14 @@ export class HeaderComponent { } ``` +## 6. Build Changes + +We now provide a proper ESM output of the SDK. There have also been some other build changes under the hood. One side +effect of this is that importing Sentry as a default import does not work anymore. Note that this was never supported +(even on v7) and this was never intended to work (and also not documented anywhere). However, it seems that for some +configuration combinations, it was still possible to do `import Sentry from '@sentry/browser'`. This is not possible +anymore in v8. Please use `import * as Sentry from '@sentry/browser'` instead. + # Upgrading Sentry Feedback (beta, 7.x to 8.0) For details on upgrading Feedback from the beta 7.x to the release 8.x version, please view the From 531779300c186f89afff0c5bad9f802b2140a325 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 17 May 2024 14:24:38 +0200 Subject: [PATCH 07/34] feat(node): Ensure fastify spans have better data (#12106) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This ensures we have correct op, name & origin for all fastify middleware spans. Sadly, we have no good hook in fastify to handle all spans it emits - only `request_handler` spans are passed to `requestHook` 😬 so I opted to add a `spanStart` hook to handle this. Since it would suck to always register this, even without fastify being used, I put this into the fastify error handler - kind of mixing concerns there but I'd say it's fine for this case (as it just enhances the data). I had some issues running this locally, so I changed the playwright config to not be TS which is IMHO ok and simplifies the setup a bit... --- .../node-fastify/package.json | 2 +- ...wright.config.ts => playwright.config.mjs} | 3 +- .../node-fastify/tests/transactions.test.ts | 136 +++++++++--------- .../node-fastify/tsconfig.json | 2 +- .../node/src/integrations/tracing/fastify.ts | 91 ++++++++---- 5 files changed, 141 insertions(+), 93 deletions(-) rename dev-packages/e2e-tests/test-applications/node-fastify/{playwright.config.ts => playwright.config.mjs} (94%) 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 0293412ba76b..1a35474e1bba 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify/package.json +++ b/dev-packages/e2e-tests/test-applications/node-fastify/package.json @@ -23,7 +23,7 @@ }, "devDependencies": { "@sentry-internal/event-proxy-server": "link:../../../event-proxy-server", - "@playwright/test": "^1.38.1" + "@playwright/test": "^1.44.0" }, "volta": { "extends": "../../package.json" diff --git a/dev-packages/e2e-tests/test-applications/node-fastify/playwright.config.ts b/dev-packages/e2e-tests/test-applications/node-fastify/playwright.config.mjs similarity index 94% rename from dev-packages/e2e-tests/test-applications/node-fastify/playwright.config.ts rename to dev-packages/e2e-tests/test-applications/node-fastify/playwright.config.mjs index 56a882460551..858e6aec7ef2 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify/playwright.config.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify/playwright.config.mjs @@ -1,4 +1,3 @@ -import type { PlaywrightTestConfig } from '@playwright/test'; import { devices } from '@playwright/test'; const fastifyPort = 3030; @@ -7,7 +6,7 @@ const eventProxyPort = 3031; /** * See https://playwright.dev/docs/test-configuration. */ -const config: PlaywrightTestConfig = { +const config = { testDir: './tests', /* Maximum time one test can run for. */ timeout: 150_000, 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 8324a9913d1b..cfc320f3d4dd 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 @@ -55,70 +55,6 @@ test('Sends an API route transaction', async ({ baseURL }) => { expect(transactionEvent).toEqual( expect.objectContaining({ - spans: [ - { - data: { - 'plugin.name': 'fastify -> sentry-fastify-error-handler', - 'fastify.type': 'middleware', - 'hook.name': 'onRequest', - 'otel.kind': 'INTERNAL', - 'sentry.origin': 'manual', - }, - description: 'middleware - fastify -> sentry-fastify-error-handler', - parent_span_id: expect.any(String), - span_id: expect.any(String), - start_timestamp: expect.any(Number), - status: 'ok', - timestamp: expect.any(Number), - trace_id: expect.any(String), - origin: 'manual', - }, - { - data: { - 'plugin.name': 'fastify -> sentry-fastify-error-handler', - 'fastify.type': 'request_handler', - 'http.route': '/test-transaction', - 'otel.kind': 'INTERNAL', - 'sentry.origin': 'auto.http.otel.fastify', - }, - description: 'request handler - fastify -> sentry-fastify-error-handler', - parent_span_id: expect.any(String), - span_id: expect.any(String), - start_timestamp: expect.any(Number), - status: 'ok', - timestamp: expect.any(Number), - trace_id: expect.any(String), - origin: 'auto.http.otel.fastify', - }, - { - data: { - 'otel.kind': 'INTERNAL', - 'sentry.origin': 'manual', - }, - description: 'test-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), - start_timestamp: expect.any(Number), - status: 'ok', - timestamp: expect.any(Number), - trace_id: expect.any(String), - origin: 'manual', - }, - { - data: { - 'otel.kind': 'INTERNAL', - 'sentry.origin': 'manual', - }, - description: 'child-span', - parent_span_id: expect.any(String), - span_id: expect.any(String), - start_timestamp: expect.any(Number), - status: 'ok', - timestamp: expect.any(Number), - trace_id: expect.any(String), - origin: 'manual', - }, - ], transaction: 'GET /test-transaction', type: 'transaction', transaction_info: { @@ -127,6 +63,78 @@ test('Sends an API route transaction', async ({ baseURL }) => { }), ); + const spans = transactionEvent.spans || []; + + expect(spans).toContainEqual({ + data: { + 'plugin.name': 'fastify -> sentry-fastify-error-handler', + 'fastify.type': 'middleware', + 'hook.name': 'onRequest', + 'otel.kind': 'INTERNAL', + 'sentry.origin': 'auto.http.otel.fastify', + 'sentry.op': 'middleware.fastify', + }, + description: 'sentry-fastify-error-handler', + op: 'middleware.fastify', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + origin: 'auto.http.otel.fastify', + }); + + expect(spans).toContainEqual({ + data: { + 'plugin.name': 'fastify -> sentry-fastify-error-handler', + 'fastify.type': 'request_handler', + 'http.route': '/test-transaction', + 'otel.kind': 'INTERNAL', + 'sentry.op': 'request_handler.fastify', + 'sentry.origin': 'auto.http.otel.fastify', + }, + description: 'sentry-fastify-error-handler', + op: 'request_handler.fastify', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + origin: 'auto.http.otel.fastify', + }); + + expect(spans).toContainEqual({ + data: { + 'otel.kind': 'INTERNAL', + 'sentry.origin': 'manual', + }, + description: 'test-span', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + origin: 'manual', + }); + + expect(spans).toContainEqual({ + data: { + 'otel.kind': 'INTERNAL', + 'sentry.origin': 'manual', + }, + description: 'child-span', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + origin: 'manual', + }); + await expect .poll( async () => { diff --git a/dev-packages/e2e-tests/test-applications/node-fastify/tsconfig.json b/dev-packages/e2e-tests/test-applications/node-fastify/tsconfig.json index 17bd2c1f4c00..6b69bfaa593b 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify/tsconfig.json +++ b/dev-packages/e2e-tests/test-applications/node-fastify/tsconfig.json @@ -6,5 +6,5 @@ "strict": true, "outDir": "dist" }, - "include": ["*.ts"] + "include": ["./src/*.ts"] } diff --git a/packages/node/src/integrations/tracing/fastify.ts b/packages/node/src/integrations/tracing/fastify.ts index 55ccc7b4b72d..33f2af3084bd 100644 --- a/packages/node/src/integrations/tracing/fastify.ts +++ b/packages/node/src/integrations/tracing/fastify.ts @@ -1,11 +1,39 @@ import { isWrapped } from '@opentelemetry/core'; import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify'; -import { captureException, defineIntegration, getIsolationScope, isEnabled } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + captureException, + defineIntegration, + getClient, + getIsolationScope, + isEnabled, + spanToJSON, +} from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn, Span } from '@sentry/types'; import { consoleSandbox } from '@sentry/utils'; -import { addOriginToSpan } from '../../utils/addOriginToSpan'; +// We inline the types we care about here +interface Fastify { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + register: (plugin: any) => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + addHook: (hook: string, handler: (request: any, reply: any, error: Error) => void) => void; +} + +/** + * Minimal request type containing properties around route information. + * Works for Fastify 3, 4 and presumably 5. + */ +interface FastifyRequestRouteInfo { + // since fastify@4.10.0 + routeOptions?: { + url?: string; + method?: string; + }; + routerPath?: string; +} const _fastifyIntegration = (() => { return { @@ -14,7 +42,7 @@ const _fastifyIntegration = (() => { addOpenTelemetryInstrumentation( new FastifyInstrumentation({ requestHook(span) { - addOriginToSpan(span, 'auto.http.otel.fastify'); + addFastifySpanAttributes(span); }, }), ); @@ -29,27 +57,6 @@ const _fastifyIntegration = (() => { */ export const fastifyIntegration = defineIntegration(_fastifyIntegration); -// We inline the types we care about here -interface Fastify { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - register: (plugin: any) => void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - addHook: (hook: string, handler: (request: any, reply: any, error: Error) => void) => void; -} - -/** - * Minimal request type containing properties around route information. - * Works for Fastify 3, 4 and presumably 5. - */ -interface FastifyRequestRouteInfo { - // since fastify@4.10.0 - routeOptions?: { - url?: string; - method?: string; - }; - routerPath?: string; -} - /** * Setup an error handler for Fastify. */ @@ -84,6 +91,16 @@ export function setupFastifyErrorHandler(fastify: Fastify): void { fastify.register(plugin); + // Sadly, middleware spans do not go through `requestHook`, so we handle those here + // We register this hook in this method, because if we register it in the integration `setup`, + // it would always run even for users that are not even using fastify + const client = getClient(); + if (client) { + client.on('spanStart', span => { + addFastifySpanAttributes(span); + }); + } + if (!isWrapped(fastify.addHook) && isEnabled()) { consoleSandbox(() => { // eslint-disable-next-line no-console @@ -93,3 +110,27 @@ export function setupFastifyErrorHandler(fastify: Fastify): void { }); } } + +function addFastifySpanAttributes(span: Span): void { + const attributes = spanToJSON(span).data || {}; + + // this is one of: middleware, request_handler + const type = attributes['fastify.type']; + + // If this is already set, or we have no fastify span, no need to process again... + if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) { + return; + } + + span.setAttributes({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.fastify', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.fastify`, + }); + + // Also update the name, we don't need to "middleware - " prefix + const name = attributes['fastify.name'] || attributes['plugin.name'] || attributes['hook.name']; + if (typeof name === 'string') { + // Also remove `fastify -> ` prefix + span.updateName(name.replace(/^fastify -> /, '')); + } +} From de603067d65105b994010cf9b422085c539add47 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 21 May 2024 09:49:45 +0200 Subject: [PATCH 08/34] feat(node): Ensure express spans have better data (#12107) This ensures we have correct op, name & origin for all express middleware spans. I also updated the E2E test to actually check this as well. --- .../tests/server.test.ts | 12 +- .../node-express/package.json | 2 +- .../tests/{error.test.ts => errors.test.ts} | 0 .../node-express/tests/transaction.test.ts | 45 ----- .../node-express/tests/transactions.test.ts | 155 ++++++++++++++++++ .../node-nestjs/tests/transactions.test.ts | 4 +- .../suites/express/tracing/test.ts | 12 +- package.json | 3 +- .../node/src/integrations/tracing/express.ts | 22 ++- 9 files changed, 202 insertions(+), 53 deletions(-) rename dev-packages/e2e-tests/test-applications/node-express/tests/{error.test.ts => errors.test.ts} (100%) delete mode 100644 dev-packages/e2e-tests/test-applications/node-express/tests/transaction.test.ts create mode 100644 dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts 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 3602a3c54623..410ff414f908 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 @@ -68,8 +68,10 @@ test('Should record a transaction for route with parameters', async ({ request } 'http.route': '/', 'otel.kind': 'INTERNAL', 'sentry.origin': 'auto.http.otel.express', + 'sentry.op': 'middleware.express', }, - description: 'middleware - query', + op: 'middleware.express', + description: 'query', origin: 'auto.http.otel.express', parent_span_id: expect.any(String), span_id: expect.any(String), @@ -86,8 +88,10 @@ test('Should record a transaction for route with parameters', async ({ request } 'http.route': '/', 'otel.kind': 'INTERNAL', 'sentry.origin': 'auto.http.otel.express', + 'sentry.op': 'middleware.express', }, - description: 'middleware - expressInit', + op: 'middleware.express', + description: 'expressInit', origin: 'auto.http.otel.express', parent_span_id: expect.any(String), span_id: expect.any(String), @@ -104,8 +108,10 @@ test('Should record a transaction for route with parameters', async ({ request } 'http.route': '/test-transaction/:param', 'otel.kind': 'INTERNAL', 'sentry.origin': 'auto.http.otel.express', + 'sentry.op': 'request_handler.express', }, - description: 'request handler - /test-transaction/:param', + op: 'request_handler.express', + description: '/test-transaction/:param', origin: 'auto.http.otel.express', parent_span_id: expect.any(String), span_id: expect.any(String), 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 b3835693d99d..c59865a69266 100644 --- a/dev-packages/e2e-tests/test-applications/node-express/package.json +++ b/dev-packages/e2e-tests/test-applications/node-express/package.json @@ -20,7 +20,7 @@ "@types/node": "18.15.1", "express": "4.19.2", "typescript": "4.9.5", - "zod": "^3.22.4" + "zod": "~3.22.4" }, "devDependencies": { "@sentry-internal/event-proxy-server": "link:../../../event-proxy-server", diff --git a/dev-packages/e2e-tests/test-applications/node-express/tests/error.test.ts b/dev-packages/e2e-tests/test-applications/node-express/tests/errors.test.ts similarity index 100% rename from dev-packages/e2e-tests/test-applications/node-express/tests/error.test.ts rename to dev-packages/e2e-tests/test-applications/node-express/tests/errors.test.ts diff --git a/dev-packages/e2e-tests/test-applications/node-express/tests/transaction.test.ts b/dev-packages/e2e-tests/test-applications/node-express/tests/transaction.test.ts deleted file mode 100644 index 722418977671..000000000000 --- a/dev-packages/e2e-tests/test-applications/node-express/tests/transaction.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { expect, test } from '@playwright/test'; -import axios, { AxiosError } from 'axios'; - -const authToken = process.env.E2E_TEST_AUTH_TOKEN; -const sentryTestOrgSlug = process.env.E2E_TEST_SENTRY_ORG_SLUG; -const sentryTestProject = process.env.E2E_TEST_SENTRY_TEST_PROJECT; -const EVENT_POLLING_TIMEOUT = 90_000; - -test('Sends transactions to Sentry', async ({ baseURL }) => { - const { data } = await axios.get(`${baseURL}/test-transaction`); - const { transactionIds } = data; - - console.log(`Polling for transaction eventIds: ${JSON.stringify(transactionIds)}`); - - expect(transactionIds.length).toBeGreaterThan(0); - - await Promise.all( - transactionIds.map(async (transactionId: string) => { - const url = `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${transactionId}/`; - - await expect - .poll( - async () => { - try { - const response = await axios.get(url, { headers: { Authorization: `Bearer ${authToken}` } }); - - return response.status; - } catch (e) { - if (e instanceof AxiosError && e.response) { - if (e.response.status !== 404) { - throw e; - } else { - return e.response.status; - } - } else { - throw e; - } - } - }, - { timeout: EVENT_POLLING_TIMEOUT }, - ) - .toBe(200); - }), - ); -}); 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 new file mode 100644 index 000000000000..fcb3913e1fce --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts @@ -0,0 +1,155 @@ +import { expect, test } from '@playwright/test'; +import { waitForTransaction } from '@sentry-internal/event-proxy-server'; +import axios, { AxiosError } from 'axios'; + +const authToken = process.env.E2E_TEST_AUTH_TOKEN; +const sentryTestOrgSlug = process.env.E2E_TEST_SENTRY_ORG_SLUG; +const sentryTestProject = process.env.E2E_TEST_SENTRY_TEST_PROJECT; +const EVENT_POLLING_TIMEOUT = 90_000; + +test('Sends an API route transaction', async ({ baseURL }) => { + const pageloadTransactionEventPromise = waitForTransaction('node-express', transactionEvent => { + return ( + transactionEvent?.contexts?.trace?.op === 'http.server' && + transactionEvent?.transaction === 'GET /test-transaction' + ); + }); + + await axios.get(`${baseURL}/test-transaction`); + + const transactionEvent = await pageloadTransactionEventPromise; + const transactionEventId = transactionEvent.event_id; + + expect(transactionEvent.contexts?.trace).toEqual({ + data: { + 'sentry.source': 'route', + 'sentry.origin': 'auto.http.otel.http', + 'sentry.op': 'http.server', + 'sentry.sample_rate': 1, + url: 'http://localhost:3030/test-transaction', + 'otel.kind': 'SERVER', + 'http.response.status_code': 200, + 'http.url': 'http://localhost:3030/test-transaction', + 'http.host': 'localhost:3030', + 'net.host.name': 'localhost', + 'http.method': 'GET', + 'http.scheme': 'http', + 'http.target': '/test-transaction', + 'http.user_agent': 'axios/1.6.7', + 'http.flavor': '1.1', + 'net.transport': 'ip_tcp', + 'net.host.ip': expect.any(String), + 'net.host.port': expect.any(Number), + 'net.peer.ip': expect.any(String), + 'net.peer.port': expect.any(Number), + 'http.status_code': 200, + 'http.status_text': 'OK', + 'http.route': '/test-transaction', + }, + op: 'http.server', + span_id: expect.any(String), + status: 'ok', + trace_id: expect.any(String), + origin: 'auto.http.otel.http', + }); + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: 'GET /test-transaction', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); + + const spans = transactionEvent.spans || []; + + expect(spans).toContainEqual({ + data: { + 'sentry.origin': 'auto.http.otel.express', + 'sentry.op': 'middleware.express', + 'http.route': '/', + 'express.name': 'query', + 'express.type': 'middleware', + 'otel.kind': 'INTERNAL', + }, + description: 'query', + op: 'middleware.express', + origin: 'auto.http.otel.express', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + }); + + expect(spans).toContainEqual({ + data: { + 'sentry.origin': 'auto.http.otel.express', + 'sentry.op': 'middleware.express', + 'http.route': '/', + 'express.name': 'expressInit', + 'express.type': 'middleware', + 'otel.kind': 'INTERNAL', + }, + description: 'expressInit', + op: 'middleware.express', + origin: 'auto.http.otel.express', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + }); + + expect(spans).toContainEqual({ + data: { + 'sentry.origin': 'auto.http.otel.express', + 'sentry.op': 'request_handler.express', + 'http.route': '/test-transaction', + 'express.name': '/test-transaction', + 'express.type': 'request_handler', + 'otel.kind': 'INTERNAL', + }, + description: '/test-transaction', + op: 'request_handler.express', + origin: 'auto.http.otel.express', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + }); + + await expect + .poll( + async () => { + try { + const response = await axios.get( + `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${transactionEventId}/`, + { headers: { Authorization: `Bearer ${authToken}` } }, + ); + + return response.status; + } catch (e) { + if (e instanceof AxiosError && e.response) { + if (e.response.status !== 404) { + throw e; + } else { + return e.response.status; + } + } else { + throw e; + } + } + }, + { + timeout: EVENT_POLLING_TIMEOUT, + }, + ) + .toBe(200); +}); diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts index 08a3998d0ecd..2739dbe20b07 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts @@ -63,8 +63,10 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'http.route': '/test-transaction', 'otel.kind': 'INTERNAL', 'sentry.origin': 'auto.http.otel.express', + 'sentry.op': 'request_handler.express', }, - description: 'request handler - /test-transaction', + op: 'request_handler.express', + description: '/test-transaction', parent_span_id: expect.any(String), span_id: expect.any(String), start_timestamp: expect.any(Number), 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 337a1166ee64..1c169291f235 100644 --- a/dev-packages/node-integration-tests/suites/express/tracing/test.ts +++ b/dev-packages/node-integration-tests/suites/express/tracing/test.ts @@ -29,7 +29,17 @@ describe('express tracing experimental', () => { 'express.name': 'corsMiddleware', 'express.type': 'middleware', }), - description: 'middleware - corsMiddleware', + description: 'corsMiddleware', + op: 'middleware.express', + origin: 'auto.http.otel.express', + }), + expect.objectContaining({ + data: expect.objectContaining({ + 'express.name': '/test/express', + 'express.type': 'request_handler', + }), + description: '/test/express', + op: 'request_handler.express', origin: 'auto.http.otel.express', }), ]), diff --git a/package.json b/package.json index 6abdde7f2de2..88d43da80039 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "build:watch": "lerna run build:watch", "build:dev:watch": "lerna run build:dev:watch", "build:types:watch": "ts-node scripts/build-types-watch.ts", - "build:tarball": "lerna run build:tarball", + "build:tarball": "run-s clean:tarballs build:tarballs", + "build:tarballs": "lerna run build:tarball", "circularDepCheck": "lerna run circularDepCheck", "clean": "run-s clean:build clean:caches", "clean:build": "lerna run clean", diff --git a/packages/node/src/integrations/tracing/express.ts b/packages/node/src/integrations/tracing/express.ts index 31abf92aca58..8b8ea56ceddd 100644 --- a/packages/node/src/integrations/tracing/express.ts +++ b/packages/node/src/integrations/tracing/express.ts @@ -1,6 +1,12 @@ import type * as http from 'http'; import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; -import { defineIntegration, getDefaultIsolationScope, isEnabled } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + defineIntegration, + getDefaultIsolationScope, + isEnabled, + spanToJSON, +} from '@sentry/core'; import { captureException, getClient, getIsolationScope } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; import type { IntegrationFn } from '@sentry/types'; @@ -19,6 +25,20 @@ const _expressIntegration = (() => { new ExpressInstrumentation({ requestHook(span) { addOriginToSpan(span, 'auto.http.otel.express'); + + const attributes = spanToJSON(span).data || {}; + // this is one of: middleware, request_handler, router + const type = attributes['express.type']; + + if (type) { + span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `${type}.express`); + } + + // Also update the name, we don't need to "middleware - " prefix + const name = attributes['express.name']; + if (typeof name === 'string') { + span.updateName(name); + } }, spanNameHook(info, defaultName) { if (getIsolationScope() === getDefaultIsolationScope()) { From a61eec7fbe164f52a089fc6ea883cd6c2fd1f3c5 Mon Sep 17 00:00:00 2001 From: Ryan Albrecht Date: Tue, 21 May 2024 00:56:04 -0700 Subject: [PATCH 09/34] fix(feedback): Set optionOverrides to be optional in TS definition (#12125) These params are optional, to the TS typedef should align with that. **Before:** SCR-20240520-ltyb **After:** SCR-20240520-ltvg Related to https://github.com/getsentry/sentry-javascript/issues/12015 --- packages/feedback/src/core/integration.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/feedback/src/core/integration.ts b/packages/feedback/src/core/integration.ts index 61c8a83ef016..203b98e0823a 100644 --- a/packages/feedback/src/core/integration.ts +++ b/packages/feedback/src/core/integration.ts @@ -55,9 +55,9 @@ export const buildFeedbackIntegration = ({ getScreenshotIntegration, }: BuilderOptions): IntegrationFn< Integration & { - attachTo(el: Element | string, optionOverrides: OverrideFeedbackConfiguration): Unsubscribe; - createForm(optionOverrides: OverrideFeedbackConfiguration): Promise; - createWidget(optionOverrides: OverrideFeedbackConfiguration): ActorComponent; + attachTo(el: Element | string, optionOverrides?: OverrideFeedbackConfiguration): Unsubscribe; + createForm(optionOverrides?: OverrideFeedbackConfiguration): Promise; + createWidget(optionOverrides?: OverrideFeedbackConfiguration): ActorComponent; remove(): void; } > => { From 53298b99c1b2a2651e44ab4e02d38371e030df1d Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 21 May 2024 10:04:30 +0200 Subject: [PATCH 10/34] feat(node): Ensure koa spans have better data (#12108) This ensures we have correct op, name & origin for all koa middleware spans. I also updated the E2E test to actually check this as well. I also noticed a problem in the instrumentation where the name is sometimes empty here, opened an upstream issue: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2220 to look into this. --- .../node-koa/tests/transactions.test.ts | 16 ++++++----- packages/node/src/integrations/tracing/koa.ts | 27 ++++++++++++++++++- 2 files changed, 36 insertions(+), 7 deletions(-) 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 720c835dcfdd..af70c480fc24 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 @@ -61,10 +61,12 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'koa.name': '', 'koa.type': 'middleware', 'otel.kind': 'INTERNAL', - 'sentry.origin': 'manual', + 'sentry.origin': 'auto.http.otel.koa', + 'sentry.op': 'middleware.koa', }, - origin: 'manual', - description: 'middleware - ', + op: 'middleware.koa', + origin: 'auto.http.otel.koa', + description: '< unknown >', parent_span_id: expect.any(String), span_id: expect.any(String), start_timestamp: expect.any(Number), @@ -78,16 +80,18 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'koa.name': '/test-transaction', 'koa.type': 'router', 'otel.kind': 'INTERNAL', - 'sentry.origin': 'manual', + 'sentry.origin': 'auto.http.otel.koa', + 'sentry.op': 'router.koa', }, - description: 'router - /test-transaction', + op: 'router.koa', + description: '/test-transaction', parent_span_id: expect.any(String), span_id: expect.any(String), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), trace_id: expect.any(String), - origin: 'manual', + origin: 'auto.http.otel.koa', }, { data: { diff --git a/packages/node/src/integrations/tracing/koa.ts b/packages/node/src/integrations/tracing/koa.ts index ba6c136c5486..d6be349e60de 100644 --- a/packages/node/src/integrations/tracing/koa.ts +++ b/packages/node/src/integrations/tracing/koa.ts @@ -2,6 +2,8 @@ import { isWrapped } from '@opentelemetry/core'; import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa'; import { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions'; import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, captureException, defineIntegration, getDefaultIsolationScope, @@ -10,10 +12,31 @@ import { spanToJSON, } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn, Span } from '@sentry/types'; import { consoleSandbox, logger } from '@sentry/utils'; import { DEBUG_BUILD } from '../../debug-build'; +function addKoaSpanAttributes(span: Span): void { + span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.http.otel.koa'); + + const attributes = spanToJSON(span).data || {}; + + // this is one of: middleware, router + const type = attributes['koa.type']; + + if (type) { + span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, `${type}.koa`); + } + + // Also update the name + const name = attributes['koa.name']; + if (typeof name === 'string') { + // Somehow, name is sometimes `''` for middleware spans + // See: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2220 + span.updateName(name || '< unknown >'); + } +} + const _koaIntegration = (() => { return { name: 'Koa', @@ -21,6 +44,8 @@ const _koaIntegration = (() => { addOpenTelemetryInstrumentation( new KoaInstrumentation({ requestHook(span, info) { + addKoaSpanAttributes(span); + if (getIsolationScope() === getDefaultIsolationScope()) { DEBUG_BUILD && logger.warn('Isolation scope is default isolation scope - skipping setting transactionName'); From ad4e9f72ad72841005127c1464e1068c82dde835 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 21 May 2024 02:26:53 -0700 Subject: [PATCH 11/34] fix(nextjs): Don't put `undefined` values in props (#12131) --- .../wrapAppGetInitialPropsWithSentry.ts | 16 +++++++++++--- .../wrapErrorGetInitialPropsWithSentry.ts | 14 ++++++++++-- .../common/wrapGetInitialPropsWithSentry.ts | 14 ++++++++++-- .../wrapGetServerSidePropsWithSentry.ts | 22 +++++++++++++------ 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/packages/nextjs/src/common/wrapAppGetInitialPropsWithSentry.ts b/packages/nextjs/src/common/wrapAppGetInitialPropsWithSentry.ts index 312e1b319fdb..7bd04342c0ab 100644 --- a/packages/nextjs/src/common/wrapAppGetInitialPropsWithSentry.ts +++ b/packages/nextjs/src/common/wrapAppGetInitialPropsWithSentry.ts @@ -56,10 +56,20 @@ export function wrapAppGetInitialPropsWithSentry(origAppGetInitialProps: AppGetI } if (requestSpan) { - appGetInitialProps.pageProps._sentryTraceData = spanToTraceHeader(requestSpan); + const sentryTrace = spanToTraceHeader(requestSpan); + + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (sentryTrace) { + appGetInitialProps.pageProps._sentryTraceData = sentryTrace; + } + const dynamicSamplingContext = getDynamicSamplingContextFromSpan(requestSpan); - appGetInitialProps.pageProps._sentryBaggage = - dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + const baggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (baggage) { + appGetInitialProps.pageProps._sentryBaggage = baggage; + } } return appGetInitialProps; diff --git a/packages/nextjs/src/common/wrapErrorGetInitialPropsWithSentry.ts b/packages/nextjs/src/common/wrapErrorGetInitialPropsWithSentry.ts index 71c8cf9806a5..347283494b38 100644 --- a/packages/nextjs/src/common/wrapErrorGetInitialPropsWithSentry.ts +++ b/packages/nextjs/src/common/wrapErrorGetInitialPropsWithSentry.ts @@ -49,10 +49,20 @@ export function wrapErrorGetInitialPropsWithSentry( const requestSpan = getSpanFromRequest(req) ?? (activeSpan ? getRootSpan(activeSpan) : undefined); if (requestSpan) { - errorGetInitialProps._sentryTraceData = spanToTraceHeader(requestSpan); + const sentryTrace = spanToTraceHeader(requestSpan); + + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (sentryTrace) { + errorGetInitialProps._sentryTraceData = sentryTrace; + } const dynamicSamplingContext = getDynamicSamplingContextFromSpan(requestSpan); - errorGetInitialProps._sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + const baggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (baggage) { + errorGetInitialProps._sentryBaggage = baggage; + } } return errorGetInitialProps; diff --git a/packages/nextjs/src/common/wrapGetInitialPropsWithSentry.ts b/packages/nextjs/src/common/wrapGetInitialPropsWithSentry.ts index 0b5425417913..1a1e351f83ed 100644 --- a/packages/nextjs/src/common/wrapGetInitialPropsWithSentry.ts +++ b/packages/nextjs/src/common/wrapGetInitialPropsWithSentry.ts @@ -45,10 +45,20 @@ export function wrapGetInitialPropsWithSentry(origGetInitialProps: GetInitialPro const requestSpan = getSpanFromRequest(req) ?? (activeSpan ? getRootSpan(activeSpan) : undefined); if (requestSpan) { - initialProps._sentryTraceData = spanToTraceHeader(requestSpan); + const sentryTrace = spanToTraceHeader(requestSpan); + + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (sentryTrace) { + initialProps._sentryTraceData = sentryTrace; + } const dynamicSamplingContext = getDynamicSamplingContextFromSpan(requestSpan); - initialProps._sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + const baggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (baggage) { + initialProps._sentryBaggage = baggage; + } } return initialProps; diff --git a/packages/nextjs/src/common/wrapGetServerSidePropsWithSentry.ts b/packages/nextjs/src/common/wrapGetServerSidePropsWithSentry.ts index d8a14b392462..1be908042b5e 100644 --- a/packages/nextjs/src/common/wrapGetServerSidePropsWithSentry.ts +++ b/packages/nextjs/src/common/wrapGetServerSidePropsWithSentry.ts @@ -38,13 +38,21 @@ export function wrapGetServerSidePropsWithSentry( if (serverSideProps && 'props' in serverSideProps) { const activeSpan = getActiveSpan(); - const requestTransaction = getSpanFromRequest(req) ?? (activeSpan ? getRootSpan(activeSpan) : undefined); - if (requestTransaction) { - (serverSideProps.props as Record)._sentryTraceData = spanToTraceHeader(requestTransaction); - - const dynamicSamplingContext = getDynamicSamplingContextFromSpan(requestTransaction); - (serverSideProps.props as Record)._sentryBaggage = - dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + const requestSpan = getSpanFromRequest(req) ?? (activeSpan ? getRootSpan(activeSpan) : undefined); + if (requestSpan) { + const sentryTrace = spanToTraceHeader(requestSpan); + + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (sentryTrace) { + (serverSideProps.props as Record)._sentryTraceData = sentryTrace; + } + + const dynamicSamplingContext = getDynamicSamplingContextFromSpan(requestSpan); + const baggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext); + // The Next.js serializer throws on undefined values so we need to guard for it (#12102) + if (baggage) { + (serverSideProps.props as Record)._sentryBaggage = baggage; + } } } From 85db0dec0cf87178eed9a2bfca7a1be85abcb854 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 21 May 2024 04:26:38 -0700 Subject: [PATCH 12/34] fix(nextjs): Fix legacy configuration method detection for emitting warning (#12136) --- packages/nextjs/src/config/webpack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 20c37699bcf1..5c06644f3b48 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -420,7 +420,7 @@ function warnAboutDeprecatedConfigFiles(projectDir: string, platform: 'server' | return ( instrumentationHookContent.includes('@sentry/') || - instrumentationHookContent.match(/sentry\.(server|edge)\.config\.(ts|js)/) + instrumentationHookContent.match(/sentry\.(server|edge)\.config(\.(ts|js))?/) ); } catch (e) { return false; From 77ff5d9acb22534a3dad4f9061ec2bfd4cbc2fb8 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 21 May 2024 13:27:09 +0200 Subject: [PATCH 13/34] feat(node): Ensure connect spans have better data (#12130) Ensuring connect spans have correct op & origin. Also streamlining E2E test app for this. --- ...wright.config.ts => playwright.config.mjs} | 3 +- .../node-connect/tests/transactions.test.ts | 8 ++-- .../node-connect/tsconfig.json | 2 +- .../suites/tracing/connect/test.ts | 8 ++-- .../node/src/integrations/tracing/connect.ts | 45 ++++++++++++++++++- 5 files changed, 55 insertions(+), 11 deletions(-) rename dev-packages/e2e-tests/test-applications/node-connect/{playwright.config.ts => playwright.config.mjs} (94%) diff --git a/dev-packages/e2e-tests/test-applications/node-connect/playwright.config.ts b/dev-packages/e2e-tests/test-applications/node-connect/playwright.config.mjs similarity index 94% rename from dev-packages/e2e-tests/test-applications/node-connect/playwright.config.ts rename to dev-packages/e2e-tests/test-applications/node-connect/playwright.config.mjs index dfef5bebe5f8..ba0e0c6eb001 100644 --- a/dev-packages/e2e-tests/test-applications/node-connect/playwright.config.ts +++ b/dev-packages/e2e-tests/test-applications/node-connect/playwright.config.mjs @@ -1,4 +1,3 @@ -import type { PlaywrightTestConfig } from '@playwright/test'; import { devices } from '@playwright/test'; const connectPort = 3030; @@ -7,7 +6,7 @@ const eventProxyPort = 3031; /** * See https://playwright.dev/docs/test-configuration. */ -const config: PlaywrightTestConfig = { +const config = { testDir: './tests', /* Maximum time one test can run for. */ timeout: 150_000, 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 4a9548015422..aef603305b8e 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 @@ -72,20 +72,22 @@ test('Sends an API route transaction', async ({ baseURL }) => { }, { data: { - 'sentry.origin': 'manual', + 'sentry.origin': 'auto.http.otel.connect', + 'sentry.op': 'request_handler.connect', 'http.route': '/test-transaction', 'connect.type': 'request_handler', 'connect.name': '/test-transaction', 'otel.kind': 'INTERNAL', }, - description: 'request handler - /test-transaction', + op: 'request_handler.connect', + description: '/test-transaction', parent_span_id: expect.any(String), span_id: expect.any(String), start_timestamp: expect.any(Number), status: 'ok', timestamp: expect.any(Number), trace_id: expect.any(String), - origin: 'manual', + origin: 'auto.http.otel.connect', }, ], transaction: 'GET /test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-connect/tsconfig.json b/dev-packages/e2e-tests/test-applications/node-connect/tsconfig.json index 90116e3ff023..d1f546d06cd1 100644 --- a/dev-packages/e2e-tests/test-applications/node-connect/tsconfig.json +++ b/dev-packages/e2e-tests/test-applications/node-connect/tsconfig.json @@ -6,5 +6,5 @@ "strict": true, "noEmit": true }, - "include": ["*.ts"] + "include": ["src/*.ts"] } diff --git a/dev-packages/node-integration-tests/suites/tracing/connect/test.ts b/dev-packages/node-integration-tests/suites/tracing/connect/test.ts index 01ea447a1feb..08e96e691c6f 100644 --- a/dev-packages/node-integration-tests/suites/tracing/connect/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/connect/test.ts @@ -16,10 +16,12 @@ describe('connect auto-instrumentation', () => { 'connect.type': 'request_handler', 'http.route': '/', 'otel.kind': 'INTERNAL', - 'sentry.origin': 'manual', + 'sentry.origin': 'auto.http.otel.connect', + 'sentry.op': 'request_handler.connect', }), - description: 'request handler - /', - origin: 'manual', + description: '/', + origin: 'auto.http.otel.connect', + op: 'request_handler.connect', status: 'ok', }), ]), diff --git a/packages/node/src/integrations/tracing/connect.ts b/packages/node/src/integrations/tracing/connect.ts index 9846b6c3dc7e..7dfecef3a482 100644 --- a/packages/node/src/integrations/tracing/connect.ts +++ b/packages/node/src/integrations/tracing/connect.ts @@ -1,8 +1,16 @@ import { isWrapped } from '@opentelemetry/core'; import { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect'; -import { captureException, defineIntegration, isEnabled } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + captureException, + defineIntegration, + getClient, + isEnabled, + spanToJSON, +} from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn, Span } from '@sentry/types'; import { consoleSandbox } from '@sentry/utils'; type ConnectApp = { @@ -30,6 +38,16 @@ function connectErrorMiddleware(err: any, req: any, res: any, next: any): void { export const setupConnectErrorHandler = (app: ConnectApp): void => { app.use(connectErrorMiddleware); + // Sadly, ConnectInstrumentation has no requestHook, so we need to add the attributes here + // We register this hook in this method, because if we register it in the integration `setup`, + // it would always run even for users that are not even using fastify + const client = getClient(); + if (client) { + client.on('spanStart', span => { + addConnectSpanAttributes(span); + }); + } + if (!isWrapped(app.use) && isEnabled()) { consoleSandbox(() => { // eslint-disable-next-line no-console @@ -39,3 +57,26 @@ export const setupConnectErrorHandler = (app: ConnectApp): void => { }); } }; + +function addConnectSpanAttributes(span: Span): void { + const attributes = spanToJSON(span).data || {}; + + // this is one of: middleware, request_handler + const type = attributes['connect.type']; + + // If this is already set, or we have no connect span, no need to process again... + if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) { + return; + } + + span.setAttributes({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.connect', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.connect`, + }); + + // Also update the name, we don't need to "middleware - " prefix + const name = attributes['connect.name']; + if (typeof name === 'string') { + span.updateName(name); + } +} From c8f16614a46c518b31a539c85924c9fd3f3b6e5c Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 21 May 2024 13:27:20 +0200 Subject: [PATCH 14/34] ref(node): Handle failing hook registration gracefully (#12135) Hopefully fixes https://github.com/getsentry/sentry-javascript/issues/12114?? --- packages/node/src/sdk/init.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/node/src/sdk/init.ts b/packages/node/src/sdk/init.ts index c03af9ec09d5..3f8bfd2c1088 100644 --- a/packages/node/src/sdk/init.ts +++ b/packages/node/src/sdk/init.ts @@ -142,9 +142,13 @@ function _init( typeof __IMPORT_META_URL_REPLACEMENT__ !== 'undefined' ? __IMPORT_META_URL_REPLACEMENT__ : undefined; if (!GLOBAL_OBJ._sentryEsmLoaderHookRegistered && importMetaUrl) { - // @ts-expect-error register is available in these versions - moduleModule.register('@opentelemetry/instrumentation/hook.mjs', importMetaUrl); - GLOBAL_OBJ._sentryEsmLoaderHookRegistered = true; + try { + // @ts-expect-error register is available in these versions + moduleModule.register('@opentelemetry/instrumentation/hook.mjs', importMetaUrl); + GLOBAL_OBJ._sentryEsmLoaderHookRegistered = true; + } catch (error) { + logger.warn('Failed to register ESM hook', error); + } } } else { consoleSandbox(() => { From 344cd9d81f0226866171cc43b5aa7ed769b4b6a5 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 21 May 2024 13:28:23 +0200 Subject: [PATCH 15/34] ref(node): Add log for running in ESM/CommonJS mode (#12134) To make debugging etc. easier for us in the future. --- packages/node/src/sdk/init.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/node/src/sdk/init.ts b/packages/node/src/sdk/init.ts index 3f8bfd2c1088..469c9e9e12f7 100644 --- a/packages/node/src/sdk/init.ts +++ b/packages/node/src/sdk/init.ts @@ -173,6 +173,8 @@ function _init( client.init(); } + logger.log(`Running in ${isCjs() ? 'CommonJS' : 'ESM'} mode.`); + if (options.autoSessionTracking) { startSessionTracking(); } From 99351c3a62221a70751e7abeb96a21c4b5169e15 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Tue, 21 May 2024 14:27:18 +0200 Subject: [PATCH 16/34] feat(node): Use `node:` prefix for node built-ins (#11895) Cloudflare workers Node compatibility mode requires that all node built-ins are loaded with the `node:` prefix. `@sentry/node` still wont work in compat mode for now because our dependencies (ie. otel) are not using the prefix, I guess due to their current Node version support. They state that they support Node v14 but v14.18 is required to use the prefix. --- .size-limit.js | 13 +++++++++++++ packages/node/src/integrations/anr/index.ts | 4 ++-- packages/node/src/integrations/anr/worker.ts | 2 +- packages/node/src/integrations/console.ts | 2 +- packages/node/src/integrations/context.ts | 10 +++++----- packages/node/src/integrations/contextlines.ts | 2 +- packages/node/src/integrations/http.ts | 2 +- .../node/src/integrations/local-variables/common.ts | 2 +- .../local-variables/local-variables-async.ts | 2 +- .../local-variables/local-variables-sync.ts | 4 ++-- .../node/src/integrations/local-variables/worker.ts | 4 ++-- packages/node/src/integrations/modules.ts | 4 ++-- packages/node/src/integrations/spotlight.ts | 2 +- packages/node/src/integrations/tracing/express.ts | 2 +- packages/node/src/proxy/base.ts | 8 ++++---- packages/node/src/proxy/helpers.ts | 2 +- packages/node/src/proxy/index.ts | 8 ++++---- packages/node/src/proxy/parse-proxy-response.ts | 4 ++-- packages/node/src/sdk/client.ts | 2 +- packages/node/src/transports/http.ts | 4 ++-- packages/node/src/utils/getRequestUrl.ts | 2 +- packages/node/src/utils/module.ts | 2 +- .../node/test/integrations/contextlines.test.ts | 6 +++--- packages/profiling-node/src/cpu_profiler.ts | 8 ++++---- packages/profiling-node/src/utils.ts | 6 +++--- 25 files changed, 60 insertions(+), 47 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index dfd1210bc735..922d129e050a 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -194,6 +194,19 @@ module.exports = [ 'node:http', 'node:https', 'node:diagnostics_channel', + 'node:perf_hooks', + 'node:worker_threads', + 'node:inspector', + 'node:path', + 'node:fs', + 'node:stream', + 'node:os', + 'node:net', + 'node:zlib', + 'node:child_process', + 'node:tls', + 'node:async_hooks', + 'node:util', 'async_hooks', 'child_process', 'fs', diff --git a/packages/node/src/integrations/anr/index.ts b/packages/node/src/integrations/anr/index.ts index 9d6382de45da..7d75d8e87e15 100644 --- a/packages/node/src/integrations/anr/index.ts +++ b/packages/node/src/integrations/anr/index.ts @@ -1,8 +1,8 @@ +import * as inspector from 'node:inspector'; +import { Worker } from 'node:worker_threads'; import { defineIntegration, mergeScopeData } from '@sentry/core'; import type { Contexts, Event, EventHint, Integration, IntegrationFn, ScopeData } from '@sentry/types'; import { GLOBAL_OBJ, logger } from '@sentry/utils'; -import * as inspector from 'inspector'; -import { Worker } from 'worker_threads'; import { getCurrentScope, getGlobalScope, getIsolationScope } from '../..'; import { NODE_VERSION } from '../../nodeVersion'; import type { NodeClient } from '../../sdk/client'; diff --git a/packages/node/src/integrations/anr/worker.ts b/packages/node/src/integrations/anr/worker.ts index 6acbbe507b01..6f701919c531 100644 --- a/packages/node/src/integrations/anr/worker.ts +++ b/packages/node/src/integrations/anr/worker.ts @@ -1,3 +1,4 @@ +import { parentPort, workerData } from 'node:worker_threads'; import { applyScopeDataToEvent, createEventEnvelope, @@ -15,7 +16,6 @@ import { watchdogTimer, } from '@sentry/utils'; import { Session as InspectorSession } from 'inspector'; -import { parentPort, workerData } from 'worker_threads'; import { makeNodeTransport } from '../../transports'; import { createGetModuleFromFilename } from '../../utils/module'; diff --git a/packages/node/src/integrations/console.ts b/packages/node/src/integrations/console.ts index 0b3d27fe8510..5cd2eb2ce98a 100644 --- a/packages/node/src/integrations/console.ts +++ b/packages/node/src/integrations/console.ts @@ -1,4 +1,4 @@ -import * as util from 'util'; +import * as util from 'node:util'; import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core'; import type { IntegrationFn } from '@sentry/types'; import { addConsoleInstrumentationHandler, severityLevelFromString } from '@sentry/utils'; diff --git a/packages/node/src/integrations/context.ts b/packages/node/src/integrations/context.ts index c33d97e79044..35410effa528 100644 --- a/packages/node/src/integrations/context.ts +++ b/packages/node/src/integrations/context.ts @@ -1,8 +1,8 @@ -import { execFile } from 'child_process'; -import { readFile, readdir } from 'fs'; -import * as os from 'os'; -import { join } from 'path'; -import { promisify } from 'util'; +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, diff --git a/packages/node/src/integrations/contextlines.ts b/packages/node/src/integrations/contextlines.ts index 3755e164e5ea..7f4b78653b6a 100644 --- a/packages/node/src/integrations/contextlines.ts +++ b/packages/node/src/integrations/contextlines.ts @@ -1,4 +1,4 @@ -import { promises } from 'fs'; +import { promises } from 'node:fs'; import { defineIntegration } from '@sentry/core'; import type { Event, IntegrationFn, StackFrame } from '@sentry/types'; import { LRUMap, addContextToFrame } from '@sentry/utils'; diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index 8022227c6c4e..f3e4ea5dd48d 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -1,4 +1,4 @@ -import type { ClientRequest, IncomingMessage, ServerResponse } from 'http'; +import type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http'; import type { Span } from '@opentelemetry/api'; import { SpanKind } from '@opentelemetry/api'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; diff --git a/packages/node/src/integrations/local-variables/common.ts b/packages/node/src/integrations/local-variables/common.ts index 990a3d71b061..67c8d6d43d81 100644 --- a/packages/node/src/integrations/local-variables/common.ts +++ b/packages/node/src/integrations/local-variables/common.ts @@ -1,5 +1,5 @@ +import type { Debugger } from 'node:inspector'; import type { StackFrame, StackParser } from '@sentry/types'; -import type { Debugger } from 'inspector'; export type Variables = Record; 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 24667b3a57e3..944ccca758d9 100644 --- a/packages/node/src/integrations/local-variables/local-variables-async.ts +++ b/packages/node/src/integrations/local-variables/local-variables-async.ts @@ -1,7 +1,7 @@ +import { Worker } from 'node:worker_threads'; import { defineIntegration } from '@sentry/core'; import type { Event, Exception, IntegrationFn } from '@sentry/types'; import { LRUMap, logger } from '@sentry/utils'; -import { Worker } from 'worker_threads'; import type { NodeClient } from '../../sdk/client'; import type { FrameVariables, LocalVariablesIntegrationOptions, LocalVariablesWorkerArgs } from './common'; 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 91fb9005b4c3..66e8eca4d32f 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,8 @@ +import type { Debugger, InspectorNotification, Runtime } from 'node:inspector'; +import { Session } from 'node:inspector'; import { defineIntegration, getClient } from '@sentry/core'; import type { Event, Exception, IntegrationFn, StackParser } from '@sentry/types'; import { LRUMap, logger } from '@sentry/utils'; -import type { Debugger, InspectorNotification, Runtime } from 'inspector'; -import { Session } from 'inspector'; import { NODE_MAJOR } from '../../nodeVersion'; import type { NodeClient } from '../../sdk/client'; diff --git a/packages/node/src/integrations/local-variables/worker.ts b/packages/node/src/integrations/local-variables/worker.ts index 5a104ce74f5b..fee92b10106c 100644 --- a/packages/node/src/integrations/local-variables/worker.ts +++ b/packages/node/src/integrations/local-variables/worker.ts @@ -1,8 +1,8 @@ +import type { Debugger, InspectorNotification, Runtime } from 'node:inspector'; import { Session } from 'node:inspector/promises'; +import { parentPort, workerData } from 'node:worker_threads'; import type { StackParser } from '@sentry/types'; import { createStackParser, nodeStackLineParser } from '@sentry/utils'; -import type { Debugger, InspectorNotification, Runtime } from 'inspector'; -import { parentPort, workerData } from 'worker_threads'; import { createGetModuleFromFilename } from '../../utils/module'; import type { LocalVariablesWorkerArgs, PausedExceptionEvent, RateLimitIncrement, Variables } from './common'; import { createRateLimiter, hashFromStack } from './common'; diff --git a/packages/node/src/integrations/modules.ts b/packages/node/src/integrations/modules.ts index ad30bb4d7a3b..b1b56c6c1fda 100644 --- a/packages/node/src/integrations/modules.ts +++ b/packages/node/src/integrations/modules.ts @@ -1,5 +1,5 @@ -import { existsSync, readFileSync } from 'fs'; -import { dirname, join } from 'path'; +import { existsSync, readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; import { defineIntegration } from '@sentry/core'; import type { IntegrationFn } from '@sentry/types'; diff --git a/packages/node/src/integrations/spotlight.ts b/packages/node/src/integrations/spotlight.ts index 21629ad340ac..bfb9559958f9 100644 --- a/packages/node/src/integrations/spotlight.ts +++ b/packages/node/src/integrations/spotlight.ts @@ -1,4 +1,4 @@ -import * as http from 'http'; +import * as http from 'node:http'; import { defineIntegration } from '@sentry/core'; import type { Client, Envelope, IntegrationFn } from '@sentry/types'; import { logger, serializeEnvelope } from '@sentry/utils'; diff --git a/packages/node/src/integrations/tracing/express.ts b/packages/node/src/integrations/tracing/express.ts index 8b8ea56ceddd..58164f97d5ea 100644 --- a/packages/node/src/integrations/tracing/express.ts +++ b/packages/node/src/integrations/tracing/express.ts @@ -1,4 +1,4 @@ -import type * as http from 'http'; +import type * as http from 'node:http'; import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, diff --git a/packages/node/src/proxy/base.ts b/packages/node/src/proxy/base.ts index e1ef24c3092e..4787538c17bb 100644 --- a/packages/node/src/proxy/base.ts +++ b/packages/node/src/proxy/base.ts @@ -29,10 +29,10 @@ /* eslint-disable @typescript-eslint/explicit-member-accessibility */ /* eslint-disable @typescript-eslint/member-ordering */ /* eslint-disable jsdoc/require-jsdoc */ -import * as http from 'http'; -import type * as net from 'net'; -import type { Duplex } from 'stream'; -import type * as tls from 'tls'; +import * as http from 'node:http'; +import type * as net from 'node:net'; +import type { Duplex } from 'node:stream'; +import type * as tls from 'node:tls'; export * from './helpers'; diff --git a/packages/node/src/proxy/helpers.ts b/packages/node/src/proxy/helpers.ts index 031878511f6c..cb9a37b13305 100644 --- a/packages/node/src/proxy/helpers.ts +++ b/packages/node/src/proxy/helpers.ts @@ -29,7 +29,7 @@ /* eslint-disable jsdoc/require-jsdoc */ import * as http from 'node:http'; import * as https from 'node:https'; -import type { Readable } from 'stream'; +import type { Readable } from 'node:stream'; export type ThenableRequest = http.ClientRequest & { then: Promise['then']; diff --git a/packages/node/src/proxy/index.ts b/packages/node/src/proxy/index.ts index 83f72d56fb4e..07674895379e 100644 --- a/packages/node/src/proxy/index.ts +++ b/packages/node/src/proxy/index.ts @@ -28,10 +28,10 @@ /* eslint-disable @typescript-eslint/explicit-member-accessibility */ /* eslint-disable @typescript-eslint/no-unused-vars */ -import type * as http from 'http'; -import type { OutgoingHttpHeaders } from 'http'; -import * as net from 'net'; -import * as tls from 'tls'; +import type * as http from 'node:http'; +import type { OutgoingHttpHeaders } from 'node:http'; +import * as net from 'node:net'; +import * as tls from 'node:tls'; import { logger } from '@sentry/utils'; import { Agent } from './base'; import type { AgentConnectOpts } from './base'; diff --git a/packages/node/src/proxy/parse-proxy-response.ts b/packages/node/src/proxy/parse-proxy-response.ts index e351945e3c0f..a01e6675b765 100644 --- a/packages/node/src/proxy/parse-proxy-response.ts +++ b/packages/node/src/proxy/parse-proxy-response.ts @@ -28,8 +28,8 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable jsdoc/require-jsdoc */ -import type { IncomingHttpHeaders } from 'http'; -import type { Readable } from 'stream'; +import type { IncomingHttpHeaders } from 'node:http'; +import type { Readable } from 'node:stream'; import { logger } from '@sentry/utils'; function debug(...args: unknown[]): void { diff --git a/packages/node/src/sdk/client.ts b/packages/node/src/sdk/client.ts index 8658ebf3e918..cf1cb3c2023a 100644 --- a/packages/node/src/sdk/client.ts +++ b/packages/node/src/sdk/client.ts @@ -1,4 +1,4 @@ -import * as os from 'os'; +import * as os from 'node:os'; import type { Tracer } from '@opentelemetry/api'; import { trace } from '@opentelemetry/api'; import type { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; diff --git a/packages/node/src/transports/http.ts b/packages/node/src/transports/http.ts index d1828b856c5f..16f42de36d66 100644 --- a/packages/node/src/transports/http.ts +++ b/packages/node/src/transports/http.ts @@ -1,7 +1,7 @@ import * as http from 'node:http'; import * as https from 'node:https'; -import { Readable } from 'stream'; -import { createGzip } from 'zlib'; +import { Readable } from 'node:stream'; +import { createGzip } from 'node:zlib'; import { createTransport, suppressTracing } from '@sentry/core'; import type { BaseTransportOptions, diff --git a/packages/node/src/utils/getRequestUrl.ts b/packages/node/src/utils/getRequestUrl.ts index 1e4dcfb71232..5005224f59e0 100644 --- a/packages/node/src/utils/getRequestUrl.ts +++ b/packages/node/src/utils/getRequestUrl.ts @@ -1,4 +1,4 @@ -import type { RequestOptions } from 'http'; +import type { RequestOptions } from 'node:http'; /** Build a full URL from request options. */ export function getRequestUrl(requestOptions: RequestOptions): string { diff --git a/packages/node/src/utils/module.ts b/packages/node/src/utils/module.ts index d873bf9b2f2e..aad8195d1b1f 100644 --- a/packages/node/src/utils/module.ts +++ b/packages/node/src/utils/module.ts @@ -1,4 +1,4 @@ -import { posix, sep } from 'path'; +import { posix, sep } from 'node:path'; import { dirname } from '@sentry/utils'; /** normalizes Windows paths */ diff --git a/packages/node/test/integrations/contextlines.test.ts b/packages/node/test/integrations/contextlines.test.ts index c4ef1efaa292..3c6394f9ac52 100644 --- a/packages/node/test/integrations/contextlines.test.ts +++ b/packages/node/test/integrations/contextlines.test.ts @@ -1,4 +1,4 @@ -import { promises } from 'fs'; +import { promises } from 'node:fs'; import type { StackFrame } from '@sentry/types'; import { parseStackFrames } from '@sentry/utils'; @@ -6,8 +6,8 @@ import { _contextLinesIntegration, resetFileContentCache } from '../../src/integ import { defaultStackParser } from '../../src/sdk/api'; import { getError } from '../helpers/error'; -jest.mock('fs', () => { - const actual = jest.requireActual('fs'); +jest.mock('node:fs', () => { + const actual = jest.requireActual('node:fs'); return { ...actual, promises: { diff --git a/packages/profiling-node/src/cpu_profiler.ts b/packages/profiling-node/src/cpu_profiler.ts index b31e6f4d25d0..433ade1d4b46 100644 --- a/packages/profiling-node/src/cpu_profiler.ts +++ b/packages/profiling-node/src/cpu_profiler.ts @@ -1,9 +1,9 @@ -import { arch as _arch, platform as _platform } from 'os'; -import { join, resolve } from 'path'; +import { arch as _arch, platform as _platform } from 'node:os'; +import { join, resolve } from 'node:path'; +import { env, versions } from 'node:process'; +import { threadId } from 'node:worker_threads'; import { familySync } from 'detect-libc'; import { getAbi } from 'node-abi'; -import { env, versions } from 'process'; -import { threadId } from 'worker_threads'; import { GLOBAL_OBJ, logger } from '@sentry/utils'; import { DEBUG_BUILD } from './debug-build'; diff --git a/packages/profiling-node/src/utils.ts b/packages/profiling-node/src/utils.ts index ce61fdeef5d9..884e71c3d10e 100644 --- a/packages/profiling-node/src/utils.ts +++ b/packages/profiling-node/src/utils.ts @@ -1,7 +1,7 @@ -import * as os from 'os'; +import * as os from 'node:os'; +import { env, versions } from 'node:process'; +import { isMainThread, threadId } from 'node:worker_threads'; import type { Client, Context, Envelope, Event, StackFrame, StackParser } from '@sentry/types'; -import { env, versions } from 'process'; -import { isMainThread, threadId } from 'worker_threads'; import { GLOBAL_OBJ, forEachEnvelopeItem, logger } from '@sentry/utils'; From 7e59832817f20becb304b82a05bb555a7f315c6e Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 21 May 2024 15:31:51 +0200 Subject: [PATCH 17/34] feat(node): Ensure Nest.js spans have better data (#12139) Ensure op and origin is correctly set. --- .../node-nestjs/tests/transactions.test.ts | 6 ++- .../node/src/integrations/tracing/connect.ts | 2 +- .../node/src/integrations/tracing/nest.ts | 40 ++++++++++++++++++- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts index 2739dbe20b07..9268e777b502 100644 --- a/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-nestjs/tests/transactions.test.ts @@ -107,7 +107,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { span_id: expect.any(String), trace_id: expect.any(String), data: { - 'sentry.origin': 'manual', + 'sentry.origin': 'auto.http.otel.nestjs', + 'sentry.op': 'handler.nestjs', component: '@nestjs/core', 'nestjs.version': expect.any(String), 'nestjs.type': 'handler', @@ -119,7 +120,8 @@ test('Sends an API route transaction', async ({ baseURL }) => { start_timestamp: expect.any(Number), timestamp: expect.any(Number), status: 'ok', - origin: 'manual', + origin: 'auto.http.otel.nestjs', + op: 'handler.nestjs', }, ]), transaction: 'GET /test-transaction', diff --git a/packages/node/src/integrations/tracing/connect.ts b/packages/node/src/integrations/tracing/connect.ts index 7dfecef3a482..60bb9d74448a 100644 --- a/packages/node/src/integrations/tracing/connect.ts +++ b/packages/node/src/integrations/tracing/connect.ts @@ -40,7 +40,7 @@ export const setupConnectErrorHandler = (app: ConnectApp): void => { // Sadly, ConnectInstrumentation has no requestHook, so we need to add the attributes here // We register this hook in this method, because if we register it in the integration `setup`, - // it would always run even for users that are not even using fastify + // it would always run even for users that are not even using connect const client = getClient(); if (client) { client.on('spanStart', span => { diff --git a/packages/node/src/integrations/tracing/nest.ts b/packages/node/src/integrations/tracing/nest.ts index c1a4b9e7a3c0..cc66e745da1d 100644 --- a/packages/node/src/integrations/tracing/nest.ts +++ b/packages/node/src/integrations/tracing/nest.ts @@ -1,7 +1,16 @@ import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core'; -import { captureException, defineIntegration, getDefaultIsolationScope, getIsolationScope } from '@sentry/core'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + captureException, + defineIntegration, + getClient, + getDefaultIsolationScope, + getIsolationScope, + spanToJSON, +} from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn, Span } from '@sentry/types'; import { logger } from '@sentry/utils'; interface MinimalNestJsExecutionContext { @@ -52,6 +61,16 @@ export const nestIntegration = defineIntegration(_nestIntegration); * Setup an error handler for Nest. */ export function setupNestErrorHandler(app: MinimalNestJsApp, baseFilter: NestJsErrorFilter): void { + // Sadly, NestInstrumentation has no requestHook, so we need to add the attributes here + // We register this hook in this method, because if we register it in the integration `setup`, + // it would always run even for users that are not even using Nest.js + const client = getClient(); + if (client) { + client.on('spanStart', span => { + addNestSpanAttributes(span); + }); + } + app.useGlobalInterceptors({ intercept(context, next) { if (getIsolationScope() === getDefaultIsolationScope()) { @@ -86,3 +105,20 @@ export function setupNestErrorHandler(app: MinimalNestJsApp, baseFilter: NestJsE app.useGlobalFilters(wrappedFilter); } + +function addNestSpanAttributes(span: Span): void { + const attributes = spanToJSON(span).data || {}; + + // this is one of: app_creation, request_context, handler + const type = attributes['nestjs.type']; + + // If this is already set, or we have no nest.js span, no need to process again... + if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) { + return; + } + + span.setAttributes({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.nestjs', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.nestjs`, + }); +} From eec0687e1696ac0f9e1ff33521221bee888a1993 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 21 May 2024 16:16:09 +0200 Subject: [PATCH 18/34] feat(node): Ensure Hapi spans have better data (#12140) Ensure we have an op and origin for hapi spans. --- .../node-hapi/tests/transactions.test.ts | 24 ++++++++++++++ .../suites/tracing/hapi/test.ts | 7 ++-- .../src/integrations/tracing/hapi/index.ts | 33 ++++++++++++++++++- 3 files changed, 60 insertions(+), 4 deletions(-) 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 2c07128b6561..0f38cff86e79 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 @@ -56,6 +56,30 @@ test('Sends successful transaction', async ({ baseURL }) => { }, }), ); + + const spans = transactionEvent.spans || []; + + expect(spans).toEqual([ + { + data: { + 'hapi.type': 'router', + 'http.method': 'GET', + 'http.route': '/test-success', + 'otel.kind': 'INTERNAL', + 'sentry.op': 'router.hapi', + 'sentry.origin': 'auto.http.otel.hapi', + }, + description: 'GET /test-success', + op: 'router.hapi', + origin: 'auto.http.otel.hapi', + parent_span_id: expect.any(String), + span_id: expect.any(String), + start_timestamp: expect.any(Number), + status: 'ok', + timestamp: expect.any(Number), + trace_id: expect.any(String), + }, + ]); }); test('Sends parameterized transactions to Sentry', async ({ baseURL }) => { diff --git a/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts b/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts index 10967a6d6be2..903b3b0b6fa8 100644 --- a/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/hapi/test.ts @@ -15,11 +15,12 @@ describe('hapi auto-instrumentation', () => { 'http.route': '/', 'http.method': 'GET', 'hapi.type': 'router', - 'sentry.origin': 'manual', - 'sentry.op': 'http', + 'sentry.origin': 'auto.http.otel.hapi', + 'sentry.op': 'router.hapi', }), description: 'GET /', - op: 'http', + op: 'router.hapi', + origin: 'auto.http.otel.hapi', status: 'ok', }), ]), diff --git a/packages/node/src/integrations/tracing/hapi/index.ts b/packages/node/src/integrations/tracing/hapi/index.ts index 7f55867c8bf5..42da7423ca5b 100644 --- a/packages/node/src/integrations/tracing/hapi/index.ts +++ b/packages/node/src/integrations/tracing/hapi/index.ts @@ -2,17 +2,21 @@ import { isWrapped } from '@opentelemetry/core'; import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi'; import { SDK_VERSION, + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, captureException, defineIntegration, getActiveSpan, + getClient, getDefaultIsolationScope, getIsolationScope, getRootSpan, isEnabled, + spanToJSON, } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; +import type { IntegrationFn, Span } from '@sentry/types'; import { consoleSandbox, logger } from '@sentry/utils'; import { DEBUG_BUILD } from '../../../debug-build'; import type { Boom, RequestEvent, ResponseObject, Server } from './types'; @@ -95,6 +99,16 @@ export const hapiErrorPlugin = { export async function setupHapiErrorHandler(server: Server): Promise { await server.register(hapiErrorPlugin); + // Sadly, middleware spans do not go through `requestHook`, so we handle those here + // We register this hook in this method, because if we register it in the integration `setup`, + // it would always run even for users that are not even using hapi + const client = getClient(); + if (client) { + client.on('spanStart', span => { + addHapiSpanAttributes(span); + }); + } + // eslint-disable-next-line @typescript-eslint/unbound-method if (!isWrapped(server.register) && isEnabled()) { consoleSandbox(() => { @@ -105,3 +119,20 @@ export async function setupHapiErrorHandler(server: Server): Promise { }); } } + +function addHapiSpanAttributes(span: Span): void { + const attributes = spanToJSON(span).data || {}; + + // this is one of: router, plugin, server.ext + const type = attributes['hapi.type']; + + // If this is already set, or we have no Hapi span, no need to process again... + if (attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] || !type) { + return; + } + + span.setAttributes({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.hapi', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `${type}.hapi`, + }); +} From abe31ba40e867baa4ce46aa9351269b6a42d0bee Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 21 May 2024 11:49:07 -0400 Subject: [PATCH 19/34] chore: Align and update MIT license dates (#12143) In https://github.com/getsentry/sentry-python/pull/3029 it was raised that we need to make sure the SDK MIT License has an up-to-date year. We also need to make it a range. In this PR I went ahead and updated the dates accordingly, changed the license to directly reference `Functional Software, Inc. dba Sentry`, and re-aligned all the Licenses of individual packages to have the same format and structure. --- .size-limit.js | 13 +++++++++++ LICENSE | 2 +- packages/angular/LICENSE | 29 +++++++++++++++--------- packages/astro/LICENSE | 29 +++++++++++++++--------- packages/aws-serverless/LICENSE | 29 +++++++++++++++--------- packages/browser-utils/LICENSE | 29 +++++++++++++++--------- packages/browser/LICENSE | 29 +++++++++++++++--------- packages/bun/LICENSE | 29 +++++++++++++++--------- packages/core/LICENSE | 29 +++++++++++++++--------- packages/deno/LICENSE | 29 +++++++++++++++--------- packages/ember/LICENSE | 29 +++++++++++++++--------- packages/eslint-config-sdk/LICENSE | 29 +++++++++++++++--------- packages/eslint-plugin-sdk/LICENSE | 29 +++++++++++++++--------- packages/feedback/LICENSE | 29 +++++++++++++++--------- packages/gatsby/LICENSE | 29 +++++++++++++++--------- packages/google-cloud-serverless/LICENSE | 29 +++++++++++++++--------- packages/integration-shims/LICENSE | 29 +++++++++++++++--------- packages/nextjs/LICENSE | 29 +++++++++++++++--------- packages/node/LICENSE | 29 +++++++++++++++--------- packages/opentelemetry/LICENSE | 29 +++++++++++++++--------- packages/profiling-node/LICENSE | 14 ++++++------ packages/react/LICENSE | 29 +++++++++++++++--------- packages/remix/LICENSE | 29 +++++++++++++++--------- packages/replay-canvas/LICENSE | 29 +++++++++++++++--------- packages/replay-internal/LICENSE | 29 +++++++++++++++--------- packages/replay-worker/LICENSE | 29 +++++++++++++++--------- packages/svelte/LICENSE | 29 +++++++++++++++--------- packages/sveltekit/LICENSE | 29 +++++++++++++++--------- packages/types/LICENSE | 29 +++++++++++++++--------- packages/typescript/LICENSE | 29 +++++++++++++++--------- packages/utils/LICENSE | 29 +++++++++++++++--------- packages/vercel-edge/LICENSE | 29 +++++++++++++++--------- packages/vue/LICENSE | 29 +++++++++++++++--------- packages/wasm/LICENSE | 29 +++++++++++++++--------- 34 files changed, 579 insertions(+), 349 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index 922d129e050a..df7597618d70 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -233,6 +233,19 @@ module.exports = [ 'node:http', 'node:https', 'node:diagnostics_channel', + 'node:perf_hooks', + 'node:worker_threads', + 'node:inspector', + 'node:path', + 'node:fs', + 'node:stream', + 'node:os', + 'node:net', + 'node:zlib', + 'node:child_process', + 'node:tls', + 'node:async_hooks', + 'node:util', 'async_hooks', 'child_process', 'perf_hooks', diff --git a/LICENSE b/LICENSE index 63e7eb28e19c..4e1c2c384991 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Functional Software, Inc. dba Sentry +Copyright (c) 2012-2024 Functional Software, Inc. dba Sentry Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/packages/angular/LICENSE b/packages/angular/LICENSE index ea5e82344f87..63e7eb28e19c 100644 --- a/packages/angular/LICENSE +++ b/packages/angular/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2024 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/astro/LICENSE b/packages/astro/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/astro/LICENSE +++ b/packages/astro/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/aws-serverless/LICENSE b/packages/aws-serverless/LICENSE index 5113ccb2ac3d..5af93a5bdae5 100644 --- a/packages/aws-serverless/LICENSE +++ b/packages/aws-serverless/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2020 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2020-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/browser-utils/LICENSE b/packages/browser-utils/LICENSE index 5113ccb2ac3d..5af93a5bdae5 100644 --- a/packages/browser-utils/LICENSE +++ b/packages/browser-utils/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2020 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2020-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/browser/LICENSE b/packages/browser/LICENSE index 535ef0561e1b..d5b40b7c4219 100644 --- a/packages/browser/LICENSE +++ b/packages/browser/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/bun/LICENSE b/packages/bun/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/bun/LICENSE +++ b/packages/bun/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/core/LICENSE b/packages/core/LICENSE index 535ef0561e1b..d5b40b7c4219 100644 --- a/packages/core/LICENSE +++ b/packages/core/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/deno/LICENSE b/packages/deno/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/deno/LICENSE +++ b/packages/deno/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/ember/LICENSE b/packages/ember/LICENSE index 5113ccb2ac3d..5af93a5bdae5 100644 --- a/packages/ember/LICENSE +++ b/packages/ember/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2020 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2020-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/eslint-config-sdk/LICENSE b/packages/eslint-config-sdk/LICENSE index 5113ccb2ac3d..5af93a5bdae5 100644 --- a/packages/eslint-config-sdk/LICENSE +++ b/packages/eslint-config-sdk/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2020 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2020-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/eslint-plugin-sdk/LICENSE b/packages/eslint-plugin-sdk/LICENSE index 5113ccb2ac3d..5af93a5bdae5 100644 --- a/packages/eslint-plugin-sdk/LICENSE +++ b/packages/eslint-plugin-sdk/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2020 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2020-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/feedback/LICENSE b/packages/feedback/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/feedback/LICENSE +++ b/packages/feedback/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/gatsby/LICENSE b/packages/gatsby/LICENSE index 5113ccb2ac3d..5af93a5bdae5 100644 --- a/packages/gatsby/LICENSE +++ b/packages/gatsby/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2020 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2020-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/google-cloud-serverless/LICENSE b/packages/google-cloud-serverless/LICENSE index ea5e82344f87..63e7eb28e19c 100644 --- a/packages/google-cloud-serverless/LICENSE +++ b/packages/google-cloud-serverless/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2024 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/integration-shims/LICENSE b/packages/integration-shims/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/integration-shims/LICENSE +++ b/packages/integration-shims/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/nextjs/LICENSE b/packages/nextjs/LICENSE index 86440e8fd08d..5b55ec3c5dcb 100644 --- a/packages/nextjs/LICENSE +++ b/packages/nextjs/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2021 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2021-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/node/LICENSE b/packages/node/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/node/LICENSE +++ b/packages/node/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/opentelemetry/LICENSE b/packages/opentelemetry/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/opentelemetry/LICENSE +++ b/packages/opentelemetry/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/profiling-node/LICENSE b/packages/profiling-node/LICENSE index 6031123bdc4c..048dee5adaa8 100644 --- a/packages/profiling-node/LICENSE +++ b/packages/profiling-node/LICENSE @@ -1,13 +1,13 @@ MIT License -Copyright (c) 2022 Sentry +Copyright (c) 2022-2024 Functional Software, Inc. dba Sentry -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. diff --git a/packages/react/LICENSE b/packages/react/LICENSE index 535ef0561e1b..d5b40b7c4219 100644 --- a/packages/react/LICENSE +++ b/packages/react/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/remix/LICENSE b/packages/remix/LICENSE index 4ac873d49f33..048dee5adaa8 100644 --- a/packages/remix/LICENSE +++ b/packages/remix/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2022 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2022-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/replay-canvas/LICENSE b/packages/replay-canvas/LICENSE index ea5e82344f87..63e7eb28e19c 100644 --- a/packages/replay-canvas/LICENSE +++ b/packages/replay-canvas/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2024 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/replay-internal/LICENSE b/packages/replay-internal/LICENSE index 4ac873d49f33..048dee5adaa8 100644 --- a/packages/replay-internal/LICENSE +++ b/packages/replay-internal/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2022 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2022-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/replay-worker/LICENSE b/packages/replay-worker/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/replay-worker/LICENSE +++ b/packages/replay-worker/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/svelte/LICENSE b/packages/svelte/LICENSE index 4ac873d49f33..048dee5adaa8 100644 --- a/packages/svelte/LICENSE +++ b/packages/svelte/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2022 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2022-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/sveltekit/LICENSE b/packages/sveltekit/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/sveltekit/LICENSE +++ b/packages/sveltekit/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/types/LICENSE b/packages/types/LICENSE index 535ef0561e1b..d5b40b7c4219 100644 --- a/packages/types/LICENSE +++ b/packages/types/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/typescript/LICENSE b/packages/typescript/LICENSE index 535ef0561e1b..d5b40b7c4219 100644 --- a/packages/typescript/LICENSE +++ b/packages/typescript/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/utils/LICENSE b/packages/utils/LICENSE index 535ef0561e1b..d5b40b7c4219 100644 --- a/packages/utils/LICENSE +++ b/packages/utils/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/vercel-edge/LICENSE b/packages/vercel-edge/LICENSE index d11896ba1181..6bfafc44539c 100644 --- a/packages/vercel-edge/LICENSE +++ b/packages/vercel-edge/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2023-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/vue/LICENSE b/packages/vue/LICENSE index 535ef0561e1b..d5b40b7c4219 100644 --- a/packages/vue/LICENSE +++ b/packages/vue/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2019 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2019-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/wasm/LICENSE b/packages/wasm/LICENSE index 86440e8fd08d..5b55ec3c5dcb 100644 --- a/packages/wasm/LICENSE +++ b/packages/wasm/LICENSE @@ -1,14 +1,21 @@ -Copyright (c) 2021 Sentry (https://sentry.io) and individual contributors. All rights reserved. +MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2021-2024 Functional Software, Inc. dba Sentry -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From f3c8a86152dd91af39a2bf0c1cd64421bdbc8b43 Mon Sep 17 00:00:00 2001 From: Ryan Albrecht Date: Tue, 21 May 2024 11:53:42 -0700 Subject: [PATCH 20/34] fix(feedback): Improve feedback border color in dark-mode, and prevent auto-dark mode when a theme is picked (#12126) If the developer sets `theme: 'dark'` or `theme: 'light'` in their sentry config, then we should prevent the browser from applying auto-dark mode to the widget. That mode guesses at the correct color to use, and sometimes gets it wrong Also, I've picked a better color for the border in dark mode. There are a few states to test: - OS is light/dark (flows into `prefers-color-scheme` media query) - Emulate Dark true/false - SDK config light/dark which refer to these 2 settings inside the chrome devtools: SCR-20240520-mhiz Note:images show a slightly different border than what's implemented. | OS Config | Emulate Config | SDK Config | Before | After | | --- | --- | --- | --- | --- | | prefers-color-scheme: light | emulate: false | theme: light | before light false light | after light false light | | prefers-color-scheme: light | emulate: false | theme: dark | before light false dark | after light false dark | | prefers-color-scheme: light | emulate: true | theme: light | before light true light | after light true light | | prefers-color-scheme: light | emulate: true | theme: dark | before light true dark | after light true dark | | prefers-color-scheme: dark | emulate: false | theme: light | before dark false light | after dark false light | | prefers-color-scheme: dark | emulate: false | theme: dark | before dark false dark | after dark false dark | | prefers-color-scheme: dark | emulate: true | theme: light | before dark true light | after dark true light | | prefers-color-scheme: dark | emulate: true | theme: dark | before dark true dark | after dark true dark | References: - https://developer.chrome.com/blog/auto-dark-theme - https://developer.chrome.com/docs/devtools/rendering/emulate-css#emulate_css_media_feature_prefers-color-scheme --- packages/feedback/src/core/createMainStyles.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/feedback/src/core/createMainStyles.ts b/packages/feedback/src/core/createMainStyles.ts index 95541ab4b06b..68ac751b8584 100644 --- a/packages/feedback/src/core/createMainStyles.ts +++ b/packages/feedback/src/core/createMainStyles.ts @@ -27,7 +27,7 @@ const DEFAULT_DARK: InternalTheme = { accentBackground: PURPLE, successColor: '#2da98c', errorColor: '#f55459', - border: '1.5px solid rgba(41, 35, 47, 0.5)', + border: '1.5px solid rgba(235, 230, 239, 0.15)', boxShadow: '0px 4px 24px 0px rgba(43, 34, 51, 0.12)', outline: '1px auto var(--accent-background)', interactiveFilter: 'brightness(150%)', @@ -66,6 +66,8 @@ export function createMainStyles({ colorScheme, themeDark, themeLight }: Feedbac font-family: var(--font-family); font-size: var(--font-size); + ${colorScheme !== 'system' ? 'color-scheme: only light;' : ''} + ${getThemedCssVariables( colorScheme === 'dark' ? { ...DEFAULT_DARK, ...themeDark } : { ...DEFAULT_LIGHT, ...themeLight }, )} From 4420844943418a1bc23a6ccad70401d68a8c94a4 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 21 May 2024 18:51:27 -0400 Subject: [PATCH 21/34] feat(node): Add app.free_memory info to events (#12150) Adds support for https://nodejs.org/api/process.html#processavailablememory introduced with Node 22 App Context: https://develop.sentry.dev/sdk/event-payloads/contexts/#app-context ref https://github.com/getsentry/sentry-javascript/issues/11455 --- packages/node/src/integrations/context.ts | 31 +++++++++++++++++-- packages/node/test/helpers/conditional.ts | 19 ++++++++++++ .../node/test/integrations/context.test.ts | 30 ++++++++++++++++-- packages/types/src/context.ts | 1 + 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 packages/node/test/helpers/conditional.ts diff --git a/packages/node/src/integrations/context.ts b/packages/node/src/integrations/context.ts index 35410effa528..379af4710794 100644 --- a/packages/node/src/integrations/context.ts +++ b/packages/node/src/integrations/context.ts @@ -1,3 +1,4 @@ +/* eslint-disable max-lines */ import { execFile } from 'node:child_process'; import { readFile, readdir } from 'node:fs'; import * as os from 'node:os'; @@ -18,6 +19,12 @@ import type { export const readFileAsync = promisify(readFile); export const readDirAsync = promisify(readdir); +// Process enhanced with methods from Node 18, 20, 22 as @types/node +// is on `14.18.0` to match minimum version requirements of the SDK +interface ProcessWithCurrentValues extends NodeJS.Process { + availableMemory?(): number; +} + const INTEGRATION_NAME = 'Context'; interface DeviceContextOptions { @@ -114,10 +121,18 @@ export const nodeContextIntegration = defineIntegration(_nodeContextIntegration) */ function _updateContext(contexts: Contexts): Contexts { // Only update properties if they exist + if (contexts?.app?.app_memory) { contexts.app.app_memory = process.memoryUsage().rss; } + if (contexts?.app?.free_memory && typeof (process as ProcessWithCurrentValues).availableMemory === 'function') { + const freeMemory = (process as ProcessWithCurrentValues).availableMemory?.(); + if (freeMemory != null) { + contexts.app.free_memory = freeMemory; + } + } + if (contexts?.device?.free_memory) { contexts.device.free_memory = os.freemem(); } @@ -183,11 +198,23 @@ function getCultureContext(): CultureContext | undefined { return; } -function getAppContext(): AppContext { +/** + * Get app context information from process + */ +export function getAppContext(): AppContext { const app_memory = process.memoryUsage().rss; const app_start_time = new Date(Date.now() - process.uptime() * 1000).toISOString(); + // https://nodejs.org/api/process.html#processavailablememory + const appContext: AppContext = { app_start_time, app_memory }; + + if (typeof (process as ProcessWithCurrentValues).availableMemory === 'function') { + const freeMemory = (process as ProcessWithCurrentValues).availableMemory?.(); + if (freeMemory != null) { + appContext.free_memory = freeMemory; + } + } - return { app_start_time, app_memory }; + return appContext; } /** diff --git a/packages/node/test/helpers/conditional.ts b/packages/node/test/helpers/conditional.ts new file mode 100644 index 000000000000..7c6ecab77cd7 --- /dev/null +++ b/packages/node/test/helpers/conditional.ts @@ -0,0 +1,19 @@ +import { parseSemver } from '@sentry/utils'; + +const NODE_VERSION = parseSemver(process.versions.node).major; + +/** + * Returns`describe` or `describe.skip` depending on allowed major versions of Node. + * + * @param {{ min?: number; max?: number }} allowedVersion + * @return {*} {jest.Describe} + */ +export const conditionalTest = (allowedVersion: { min?: number; max?: number }): jest.It => { + if (!NODE_VERSION) { + return it.skip; + } + + return NODE_VERSION < (allowedVersion.min || -Infinity) || NODE_VERSION > (allowedVersion.max || Infinity) + ? test.skip + : test; +}; diff --git a/packages/node/test/integrations/context.test.ts b/packages/node/test/integrations/context.test.ts index 519e101187ff..dde182c552ba 100644 --- a/packages/node/test/integrations/context.test.ts +++ b/packages/node/test/integrations/context.test.ts @@ -1,8 +1,34 @@ -import * as os from 'os'; +import * as os from 'node:os'; -import { getDeviceContext } from '../../src/integrations/context'; +import { getAppContext, getDeviceContext } from '../../src/integrations/context'; +import { conditionalTest } from '../helpers/conditional'; describe('Context', () => { + describe('getAppContext', () => { + afterAll(() => { + jest.clearAllMocks(); + }); + + conditionalTest({ max: 18 })('it does not return free_memory on older node versions', () => { + const appContext = getAppContext(); + expect(appContext.free_memory).toBeUndefined(); + }); + + conditionalTest({ min: 22 })( + 'returns free_memory if process.availableMemory is defined and returns a valid value', + () => { + const appContext = getAppContext(); + expect(appContext.free_memory).toEqual(expect.any(Number)); + }, + ); + + conditionalTest({ min: 22 })('returns no free_memory if process.availableMemory ', () => { + jest.spyOn(process as any, 'availableMemory').mockReturnValue(undefined as unknown as number); + const appContext = getAppContext(); + expect(appContext.free_memory).toBeUndefined(); + }); + }); + describe('getDeviceContext', () => { afterAll(() => { jest.clearAllMocks(); diff --git a/packages/types/src/context.ts b/packages/types/src/context.ts index 4f92ff4c1c6a..40d3822d6b3c 100644 --- a/packages/types/src/context.ts +++ b/packages/types/src/context.ts @@ -28,6 +28,7 @@ export interface AppContext extends Record { app_identifier?: string; build_type?: string; app_memory?: number; + free_memory?: number; } export interface DeviceContext extends Record { From 10fbee23d7745228cd6d26f928d2ec6adeadf803 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 22 May 2024 00:19:03 -0700 Subject: [PATCH 22/34] ci: Fix size limit webpack resolving (#12145) --- .size-limit.js | 68 ++++---------------------------------------------- 1 file changed, 5 insertions(+), 63 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index df7597618d70..1747b93aea21 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -1,3 +1,6 @@ +const builtinModules = require('module').builtinModules; +const nodePrefixedBuiltinModules = builtinModules.map(m => `node:${m}`); + module.exports = [ // Browser SDK (ESM) { @@ -190,37 +193,7 @@ module.exports = [ name: '@sentry/node', path: 'packages/node/build/esm/index.js', import: createImport('init'), - ignore: [ - 'node:http', - 'node:https', - 'node:diagnostics_channel', - 'node:perf_hooks', - 'node:worker_threads', - 'node:inspector', - 'node:path', - 'node:fs', - 'node:stream', - 'node:os', - 'node:net', - 'node:zlib', - 'node:child_process', - 'node:tls', - 'node:async_hooks', - 'node:util', - 'async_hooks', - 'child_process', - 'fs', - 'os', - 'path', - 'inspector', - 'worker_threads', - 'http', - 'stream', - 'zlib', - 'net', - 'tls', - 'module', - ], + ignore: [...builtinModules, ...nodePrefixedBuiltinModules], gzip: true, limit: '180 KB', }, @@ -229,38 +202,7 @@ module.exports = [ name: '@sentry/aws-serverless', path: 'packages/aws-serverless/build/npm/esm/index.js', import: createImport('init'), - ignore: [ - 'node:http', - 'node:https', - 'node:diagnostics_channel', - 'node:perf_hooks', - 'node:worker_threads', - 'node:inspector', - 'node:path', - 'node:fs', - 'node:stream', - 'node:os', - 'node:net', - 'node:zlib', - 'node:child_process', - 'node:tls', - 'node:async_hooks', - 'node:util', - 'async_hooks', - 'child_process', - 'perf_hooks', - 'fs', - 'os', - 'path', - 'inspector', - 'worker_threads', - 'http', - 'stream', - 'zlib', - 'net', - 'tls', - 'module', - ], + ignore: [...builtinModules, ...nodePrefixedBuiltinModules], gzip: true, limit: '140 KB', }, From 4786a8340902e346bc8aae75db4c4c716cac42cb Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 22 May 2024 00:21:49 -0700 Subject: [PATCH 23/34] feat(nextjs): Ignore Prisma critical dependency warnings (#12144) --- packages/nextjs/src/config/webpack.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 5c06644f3b48..14cdad42a25e 100644 --- a/packages/nextjs/src/config/webpack.ts +++ b/packages/nextjs/src/config/webpack.ts @@ -660,10 +660,14 @@ function getRequestAsyncStorageModuleLocation( } function addOtelWarningIgnoreRule(newConfig: WebpackConfigObjectWithModuleRules): void { - const ignoreRule = { module: /@opentelemetry\/instrumentation/ }; + const ignoreRules = [ + { module: /@opentelemetry\/instrumentation/, message: /Critical dependency/ }, + { module: /@prisma\/instrumentation/, message: /Critical dependency/ }, + ]; + if (newConfig.ignoreWarnings === undefined) { - newConfig.ignoreWarnings = [ignoreRule]; + newConfig.ignoreWarnings = ignoreRules; } else if (Array.isArray(newConfig.ignoreWarnings)) { - newConfig.ignoreWarnings.push(ignoreRule); + newConfig.ignoreWarnings.push(...ignoreRules); } } From 85158c50fa50ed2311017fbce1e2df5571ffa43f Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 22 May 2024 03:28:37 -0400 Subject: [PATCH 24/34] doc(migration): Add entry for runWithAsyncContext (#12153) Adds https://github.com/getsentry/sentry-javascript/pull/10780 to the migration guide. --- MIGRATION.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 89aba556534e..172d6cb433f3 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -706,10 +706,11 @@ You can import from `@sentry/browser` (or from a respective SDK package like `@s ### Server-side SDKs (Node, Deno, Bun, etc.) -Removed top-level exports: `enableAnrDetection`, `Anr`, `deepReadDirSync` +Removed top-level exports: `enableAnrDetection`, `Anr`, `deepReadDirSync`, `runWithAsyncContext` - [Removal of `enableAnrDetection` and `Anr` class](./MIGRATION.md#removal-of-enableanrdetection-and-anr-class) - [Removal of `deepReadDirSync` method](./MIGRATION.md#removal-of-deepreaddirsync-method) +- [Removal of `runWithAsyncContext` method](./MIGRATION.md#removal-of-runwithasynccontext-method) #### Removal of `enableAnrDetection` and `Anr` class @@ -720,6 +721,22 @@ The `enableAnrDetection` and `Anr` class have been removed. See the The `deepReadDirSync` method has been removed. There is no replacement API. +#### Removal of `runWithAsyncContext` method + +The `runWithAsyncContext` method has been removed in favour of `Sentry.withIsolationScope`. + +```js +// before (v7) +Sentry.runWithAsyncContext(() => { + // Your code here... +}); + +// after (v8) +Sentry.withIsolationScope(() => { + // Your code here... +}); +``` + ### Next.js SDK Removed top-level exports: `withSentryApi`, `withSentryAPI`, `withSentryGetServerSideProps`, `withSentryGetStaticProps`, From f7bd662a97e284598e581bed909dd4a19f403e5c Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 22 May 2024 03:29:10 -0400 Subject: [PATCH 25/34] feat(google-cloud): Expose ESM build (#12149) This exposes the ESM build for `@sentry/google-cloud-serverless`, with the caveat that the performance related instrumentation does not work atm. These need to be ported to use OpenTelemetry instrumentation. --- packages/google-cloud-serverless/package.json | 4 ++++ packages/google-cloud-serverless/src/sdk.ts | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json index 7651eb1408e2..015fcf8153ac 100644 --- a/packages/google-cloud-serverless/package.json +++ b/packages/google-cloud-serverless/package.json @@ -22,6 +22,10 @@ "exports": { "./package.json": "./package.json", ".": { + "import": { + "types": "./build/types/index.d.ts", + "default": "./build/esm/index.js" + }, "require": { "types": "./build/types/index.d.ts", "default": "./build/cjs/index.js" diff --git a/packages/google-cloud-serverless/src/sdk.ts b/packages/google-cloud-serverless/src/sdk.ts index 1d9f1e8fd9e8..96ccd938f66a 100644 --- a/packages/google-cloud-serverless/src/sdk.ts +++ b/packages/google-cloud-serverless/src/sdk.ts @@ -5,13 +5,22 @@ import type { Integration, Options, SdkMetadata } from '@sentry/types'; import { googleCloudGrpcIntegration } from './integrations/google-cloud-grpc'; import { googleCloudHttpIntegration } from './integrations/google-cloud-http'; +function isCjs(): boolean { + return typeof require !== 'undefined'; +} + +function getCjsOnlyIntegrations(): Integration[] { + return isCjs() + ? [ + googleCloudHttpIntegration({ optional: true }), // We mark this integration optional since '@google-cloud/common' module could be missing. + googleCloudGrpcIntegration({ optional: true }), // We mark this integration optional since 'google-gax' module could be missing. + ] + : []; +} + /** Get the default integrations for the GCP SDK. */ export function getDefaultIntegrations(_options: Options): Integration[] { - return [ - ...getDefaultIntegrationsWithoutPerformance(), - googleCloudHttpIntegration({ optional: true }), // We mark this integration optional since '@google-cloud/common' module could be missing. - googleCloudGrpcIntegration({ optional: true }), // We mark this integration optional since 'google-gax' module could be missing. - ]; + return [...getDefaultIntegrationsWithoutPerformance(), ...getCjsOnlyIntegrations()]; } /** From a30fbbca14066d90994c79888b08f69e5f6f95a0 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Wed, 22 May 2024 09:42:42 +0200 Subject: [PATCH 26/34] ref(node): Only show instrumentation warning when tracing is enabled (#12141) Also gives a better warning in ESM mode with a helpful link to the docs. --- .../node/src/integrations/tracing/connect.ts | 13 ++------- .../node/src/integrations/tracing/express.ts | 23 +++------------ .../node/src/integrations/tracing/fastify.ts | 13 ++------- .../src/integrations/tracing/hapi/index.ts | 14 ++-------- packages/node/src/integrations/tracing/koa.ts | 14 ++-------- packages/node/src/sdk/init.ts | 3 +- packages/node/src/utils/ensureIsWrapped.ts | 28 +++++++++++++++++++ 7 files changed, 44 insertions(+), 64 deletions(-) create mode 100644 packages/node/src/utils/ensureIsWrapped.ts diff --git a/packages/node/src/integrations/tracing/connect.ts b/packages/node/src/integrations/tracing/connect.ts index 60bb9d74448a..7d3e5a28137f 100644 --- a/packages/node/src/integrations/tracing/connect.ts +++ b/packages/node/src/integrations/tracing/connect.ts @@ -1,4 +1,3 @@ -import { isWrapped } from '@opentelemetry/core'; import { ConnectInstrumentation } from '@opentelemetry/instrumentation-connect'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, @@ -6,12 +5,11 @@ import { captureException, defineIntegration, getClient, - isEnabled, spanToJSON, } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; import type { IntegrationFn, Span } from '@sentry/types'; -import { consoleSandbox } from '@sentry/utils'; +import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; type ConnectApp = { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -48,14 +46,7 @@ export const setupConnectErrorHandler = (app: ConnectApp): void => { }); } - if (!isWrapped(app.use) && isEnabled()) { - consoleSandbox(() => { - // eslint-disable-next-line no-console - console.warn( - '[Sentry] Connect is not instrumented. This is likely because you required/imported connect before calling `Sentry.init()`.', - ); - }); - } + ensureIsWrapped(app.use, 'connect'); }; function addConnectSpanAttributes(span: Span): void { diff --git a/packages/node/src/integrations/tracing/express.ts b/packages/node/src/integrations/tracing/express.ts index 58164f97d5ea..cddb9bb7e0e5 100644 --- a/packages/node/src/integrations/tracing/express.ts +++ b/packages/node/src/integrations/tracing/express.ts @@ -1,21 +1,14 @@ import type * as http from 'node:http'; import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; -import { - SEMANTIC_ATTRIBUTE_SENTRY_OP, - defineIntegration, - getDefaultIsolationScope, - isEnabled, - spanToJSON, -} from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_OP, defineIntegration, getDefaultIsolationScope, spanToJSON } from '@sentry/core'; import { captureException, getClient, getIsolationScope } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; import type { IntegrationFn } from '@sentry/types'; - -import { isWrapped } from '@opentelemetry/core'; -import { consoleSandbox, logger } from '@sentry/utils'; +import { logger } from '@sentry/utils'; import { DEBUG_BUILD } from '../../debug-build'; import type { NodeClient } from '../../sdk/client'; import { addOriginToSpan } from '../../utils/addOriginToSpan'; +import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; const _expressIntegration = (() => { return { @@ -138,15 +131,7 @@ export function expressErrorHandler(options?: { */ export function setupExpressErrorHandler(app: { use: (middleware: ExpressMiddleware) => unknown }): void { app.use(expressErrorHandler()); - - if (!isWrapped(app.use) && isEnabled()) { - consoleSandbox(() => { - // eslint-disable-next-line no-console - console.warn( - '[Sentry] Express is not instrumented. This is likely because you required/imported express before calling `Sentry.init()`.', - ); - }); - } + ensureIsWrapped(app.use, 'express'); } function getStatusCodeFromResponse(error: MiddlewareError): number { diff --git a/packages/node/src/integrations/tracing/fastify.ts b/packages/node/src/integrations/tracing/fastify.ts index 33f2af3084bd..6286bd8a0f97 100644 --- a/packages/node/src/integrations/tracing/fastify.ts +++ b/packages/node/src/integrations/tracing/fastify.ts @@ -1,4 +1,3 @@ -import { isWrapped } from '@opentelemetry/core'; import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, @@ -7,12 +6,11 @@ import { defineIntegration, getClient, getIsolationScope, - isEnabled, spanToJSON, } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; import type { IntegrationFn, Span } from '@sentry/types'; -import { consoleSandbox } from '@sentry/utils'; +import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; // We inline the types we care about here interface Fastify { @@ -101,14 +99,7 @@ export function setupFastifyErrorHandler(fastify: Fastify): void { }); } - if (!isWrapped(fastify.addHook) && isEnabled()) { - consoleSandbox(() => { - // eslint-disable-next-line no-console - console.warn( - '[Sentry] Fastify is not instrumented. This is likely because you required/imported fastify before calling `Sentry.init()`.', - ); - }); - } + ensureIsWrapped(fastify.addHook, 'fastify'); } function addFastifySpanAttributes(span: Span): void { diff --git a/packages/node/src/integrations/tracing/hapi/index.ts b/packages/node/src/integrations/tracing/hapi/index.ts index 42da7423ca5b..ee03cfc34ac6 100644 --- a/packages/node/src/integrations/tracing/hapi/index.ts +++ b/packages/node/src/integrations/tracing/hapi/index.ts @@ -1,4 +1,3 @@ -import { isWrapped } from '@opentelemetry/core'; import { HapiInstrumentation } from '@opentelemetry/instrumentation-hapi'; import { SDK_VERSION, @@ -12,13 +11,13 @@ import { getDefaultIsolationScope, getIsolationScope, getRootSpan, - isEnabled, spanToJSON, } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; import type { IntegrationFn, Span } from '@sentry/types'; -import { consoleSandbox, logger } from '@sentry/utils'; +import { logger } from '@sentry/utils'; import { DEBUG_BUILD } from '../../../debug-build'; +import { ensureIsWrapped } from '../../../utils/ensureIsWrapped'; import type { Boom, RequestEvent, ResponseObject, Server } from './types'; const _hapiIntegration = (() => { @@ -110,14 +109,7 @@ export async function setupHapiErrorHandler(server: Server): Promise { } // eslint-disable-next-line @typescript-eslint/unbound-method - if (!isWrapped(server.register) && isEnabled()) { - consoleSandbox(() => { - // eslint-disable-next-line no-console - console.warn( - '[Sentry] Hapi is not instrumented. This is likely because you required/imported hapi before calling `Sentry.init()`.', - ); - }); - } + ensureIsWrapped(server.register, 'hapi'); } function addHapiSpanAttributes(span: Span): void { diff --git a/packages/node/src/integrations/tracing/koa.ts b/packages/node/src/integrations/tracing/koa.ts index d6be349e60de..7d68afb19efe 100644 --- a/packages/node/src/integrations/tracing/koa.ts +++ b/packages/node/src/integrations/tracing/koa.ts @@ -1,4 +1,3 @@ -import { isWrapped } from '@opentelemetry/core'; import { KoaInstrumentation } from '@opentelemetry/instrumentation-koa'; import { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions'; import { @@ -8,13 +7,13 @@ import { defineIntegration, getDefaultIsolationScope, getIsolationScope, - isEnabled, spanToJSON, } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; import type { IntegrationFn, Span } from '@sentry/types'; -import { consoleSandbox, logger } from '@sentry/utils'; +import { logger } from '@sentry/utils'; import { DEBUG_BUILD } from '../../debug-build'; +import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; function addKoaSpanAttributes(span: Span): void { span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.http.otel.koa'); @@ -76,12 +75,5 @@ export const setupKoaErrorHandler = (app: { use: (arg0: (ctx: any, next: any) => } }); - if (!isWrapped(app.use) && isEnabled()) { - consoleSandbox(() => { - // eslint-disable-next-line no-console - console.warn( - '[Sentry] Koa is not instrumented. This is likely because you required/imported koa before calling `Sentry.init()`.', - ); - }); - } + ensureIsWrapped(app.use, 'koa'); }; diff --git a/packages/node/src/sdk/init.ts b/packages/node/src/sdk/init.ts index 469c9e9e12f7..be78aa54efa3 100644 --- a/packages/node/src/sdk/init.ts +++ b/packages/node/src/sdk/init.ts @@ -41,7 +41,8 @@ import { defaultStackParser, getSentryRelease } from './api'; import { NodeClient } from './client'; import { initOpenTelemetry } from './initOtel'; -function isCjs(): boolean { +/** Detect CommonJS. */ +export function isCjs(): boolean { return typeof require !== 'undefined'; } diff --git a/packages/node/src/utils/ensureIsWrapped.ts b/packages/node/src/utils/ensureIsWrapped.ts new file mode 100644 index 000000000000..41003e3b7ec3 --- /dev/null +++ b/packages/node/src/utils/ensureIsWrapped.ts @@ -0,0 +1,28 @@ +import { isWrapped } from '@opentelemetry/core'; +import { hasTracingEnabled, isEnabled } from '@sentry/core'; +import { consoleSandbox } from '@sentry/utils'; +import { isCjs } from '../sdk/init'; + +/** + * Checks and warns if a framework isn't wrapped by opentelemetry. + */ +export function ensureIsWrapped( + maybeWrappedModule: unknown, + name: 'express' | 'connect' | 'fastify' | 'hapi' | 'koa', +): void { + if (!isWrapped(maybeWrappedModule) && isEnabled() && hasTracingEnabled()) { + consoleSandbox(() => { + if (isCjs()) { + // eslint-disable-next-line no-console + console.warn( + `[Sentry] ${name} is not instrumented. This is likely because you required/imported ${name} before calling \`Sentry.init()\`.`, + ); + } else { + // eslint-disable-next-line no-console + console.warn( + `[Sentry] ${name} is not instrumented. Please make sure to initialize Sentry in a separate file that you \`--import\` when running node, see: https://docs.sentry.io/platforms/javascript/guides/${name}/install/esm/.`, + ); + } + }); + } +} From a7aa8a0805ed00d05f09975201d885c659801075 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 22 May 2024 10:36:15 +0200 Subject: [PATCH 27/34] fix(node): Ensure fetch/http breadcrumbs are created correctly (#12137) This PR ensures that (node) fetch and http requests generate breadcrumbs correctly, even if tracing is disabled. It also adds tests for this, and ensures we pass the request/response to the hint correctly. Fixes https://github.com/getsentry/sentry-javascript/issues/12132 --- .../requests/fetch-breadcrumbs/scenario.ts | 33 +++++++ .../requests/fetch-breadcrumbs/test.ts | 79 +++++++++++++++++ .../requests/http-breadcrumbs/scenario.ts | 48 ++++++++++ .../tracing/requests/http-breadcrumbs/test.ts | 76 ++++++++++++++++ packages/node/src/integrations/http.ts | 65 ++++++++++---- packages/node/src/integrations/node-fetch.ts | 87 ++++++++++++++----- 6 files changed, 351 insertions(+), 37 deletions(-) create mode 100644 dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/scenario.ts create mode 100644 dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/test.ts create mode 100644 dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/scenario.ts create mode 100644 dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/test.ts diff --git a/dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/scenario.ts new file mode 100644 index 000000000000..eff91b2cd3e4 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/scenario.ts @@ -0,0 +1,33 @@ +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', + tracePropagationTargets: [/\/v0/, 'v1'], + integrations: [], + transport: loggingTransport, + // Ensure this gets a correct hint + beforeBreadcrumb(breadcrumb, hint) { + breadcrumb.data = breadcrumb.data || {}; + const req = hint?.request as { path?: string }; + breadcrumb.data.ADDED_PATH = req?.path; + return breadcrumb; + }, +}); + +async function run(): Promise { + Sentry.addBreadcrumb({ message: 'manual breadcrumb' }); + + // Since fetch is lazy loaded, we need to wait a bit until it's fully instrumented + await new Promise(resolve => setTimeout(resolve, 100)); + await fetch(`${process.env.SERVER_URL}/api/v0`).then(res => res.text()); + await fetch(`${process.env.SERVER_URL}/api/v1`).then(res => res.text()); + await fetch(`${process.env.SERVER_URL}/api/v2`).then(res => res.text()); + await fetch(`${process.env.SERVER_URL}/api/v3`).then(res => res.text()); + + Sentry.captureException(new Error('foo')); +} + +// eslint-disable-next-line @typescript-eslint/no-floating-promises +run(); diff --git a/dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/test.ts b/dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/test.ts new file mode 100644 index 000000000000..f410f8209110 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/tracing/requests/fetch-breadcrumbs/test.ts @@ -0,0 +1,79 @@ +import { conditionalTest } from '../../../../utils'; +import { createRunner } from '../../../../utils/runner'; +import { createTestServer } from '../../../../utils/server'; + +conditionalTest({ min: 18 })('outgoing fetch', () => { + test('outgoing fetch requests create breadcrumbs', done => { + createTestServer(done) + .start() + .then(SERVER_URL => { + createRunner(__dirname, 'scenario.ts') + .withEnv({ SERVER_URL }) + .ensureNoErrorOutput() + .ignore('session', 'sessions') + .expect({ + event: { + breadcrumbs: [ + { + message: 'manual breadcrumb', + timestamp: expect.any(Number), + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v0`, + status_code: 404, + ADDED_PATH: '/api/v0', + }, + timestamp: expect.any(Number), + type: 'http', + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v1`, + status_code: 404, + ADDED_PATH: '/api/v1', + }, + timestamp: expect.any(Number), + type: 'http', + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v2`, + status_code: 404, + ADDED_PATH: '/api/v2', + }, + timestamp: expect.any(Number), + type: 'http', + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v3`, + status_code: 404, + ADDED_PATH: '/api/v3', + }, + timestamp: expect.any(Number), + type: 'http', + }, + ], + exception: { + values: [ + { + type: 'Error', + value: 'foo', + }, + ], + }, + }, + }) + .start(done); + }); + }); +}); diff --git a/dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/scenario.ts new file mode 100644 index 000000000000..d7fb81d22e1f --- /dev/null +++ b/dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/scenario.ts @@ -0,0 +1,48 @@ +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', + tracePropagationTargets: [/\/v0/, 'v1'], + integrations: [], + transport: loggingTransport, + // Ensure this gets a correct hint + beforeBreadcrumb(breadcrumb, hint) { + breadcrumb.data = breadcrumb.data || {}; + const req = hint?.request as { path?: string }; + breadcrumb.data.ADDED_PATH = req?.path; + return breadcrumb; + }, +}); + +import * as http from 'http'; + +async function run(): Promise { + Sentry.addBreadcrumb({ message: 'manual breadcrumb' }); + + 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`); + + Sentry.captureException(new Error('foo')); +} + +// eslint-disable-next-line @typescript-eslint/no-floating-promises +run(); + +function makeHttpRequest(url: string): Promise { + 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-breadcrumbs/test.ts b/dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/test.ts new file mode 100644 index 000000000000..e6f44c7953f8 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/tracing/requests/http-breadcrumbs/test.ts @@ -0,0 +1,76 @@ +import { createRunner } from '../../../../utils/runner'; +import { createTestServer } from '../../../../utils/server'; + +test('outgoing http requests create breadcrumbs', done => { + createTestServer(done) + .start() + .then(SERVER_URL => { + createRunner(__dirname, 'scenario.ts') + .withEnv({ SERVER_URL }) + .ensureNoErrorOutput() + .ignore('session', 'sessions') + .expect({ + event: { + breadcrumbs: [ + { + message: 'manual breadcrumb', + timestamp: expect.any(Number), + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v0`, + status_code: 404, + ADDED_PATH: '/api/v0', + }, + timestamp: expect.any(Number), + type: 'http', + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v1`, + status_code: 404, + ADDED_PATH: '/api/v1', + }, + timestamp: expect.any(Number), + type: 'http', + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v2`, + status_code: 404, + ADDED_PATH: '/api/v2', + }, + timestamp: expect.any(Number), + type: 'http', + }, + { + category: 'http', + data: { + 'http.method': 'GET', + url: `${SERVER_URL}/api/v3`, + status_code: 404, + ADDED_PATH: '/api/v3', + }, + timestamp: expect.any(Number), + type: 'http', + }, + ], + exception: { + values: [ + { + type: 'Error', + value: 'foo', + }, + ], + }, + }, + }) + .start(done); + }); +}); diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index f3e4ea5dd48d..6854751fdcac 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -1,6 +1,5 @@ -import type { ClientRequest, IncomingMessage, ServerResponse } from 'node:http'; +import type { ClientRequest, ServerResponse } from 'node:http'; import type { Span } from '@opentelemetry/api'; -import { SpanKind } from '@opentelemetry/api'; import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; @@ -13,10 +12,10 @@ import { isSentryRequestUrl, setCapturedScopesOnSpan, } from '@sentry/core'; -import { getClient, getRequestSpanData, getSpanKind } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; +import { getClient } from '@sentry/opentelemetry'; +import type { IntegrationFn, SanitizedRequestData } from '@sentry/types'; -import { stripUrlQueryAndFragment } from '@sentry/utils'; +import { getSanitizedUrlString, parseUrl, stripUrlQueryAndFragment } from '@sentry/utils'; import type { NodeClient } from '../sdk/client'; import { setIsolationScope } from '../sdk/scope'; import type { HTTPModuleRequestIncomingMessage } from '../transports/http-module'; @@ -127,11 +126,7 @@ const _httpIntegration = ((options: HttpOptions = {}) => { isolationScope.setTransactionName(bestEffortTransactionName); }, - responseHook: (span, res) => { - if (_breadcrumbs) { - _addRequestBreadcrumb(span, res); - } - + responseHook: () => { const client = getClient(); if (client && client.getOptions().autoSessionTracking) { setImmediate(() => { @@ -139,6 +134,15 @@ const _httpIntegration = ((options: HttpOptions = {}) => { }); } }, + applyCustomAttributesOnSpan: ( + _span: Span, + request: ClientRequest | HTTPModuleRequestIncomingMessage, + response: HTTPModuleRequestIncomingMessage | ServerResponse, + ) => { + if (_breadcrumbs) { + _addRequestBreadcrumb(request, response); + } + }, }), ); }, @@ -152,12 +156,16 @@ const _httpIntegration = ((options: HttpOptions = {}) => { export const httpIntegration = defineIntegration(_httpIntegration); /** Add a breadcrumb for outgoing requests. */ -function _addRequestBreadcrumb(span: Span, response: HTTPModuleRequestIncomingMessage | ServerResponse): void { - if (getSpanKind(span) !== SpanKind.CLIENT) { +function _addRequestBreadcrumb( + request: ClientRequest | HTTPModuleRequestIncomingMessage, + response: HTTPModuleRequestIncomingMessage | ServerResponse, +): void { + // Only generate breadcrumbs for outgoing requests + if (!_isClientRequest(request)) { return; } - const data = getRequestSpanData(span); + const data = getBreadcrumbData(request); addBreadcrumb( { category: 'http', @@ -169,19 +177,42 @@ function _addRequestBreadcrumb(span: Span, response: HTTPModuleRequestIncomingMe }, { event: 'response', - // TODO FN: Do we need access to `request` here? - // If we do, we'll have to use the `applyCustomAttributesOnSpan` hook instead, - // but this has worse context semantics than request/responseHook. + request, response, }, ); } +function getBreadcrumbData(request: ClientRequest): Partial { + try { + // `request.host` does not contain the port, but the host header does + const host = request.getHeader('host') || request.host; + const url = new URL(request.path, `${request.protocol}//${host}`); + const parsedUrl = parseUrl(url.toString()); + + const data: Partial = { + url: getSanitizedUrlString(parsedUrl), + 'http.method': request.method || 'GET', + }; + + if (parsedUrl.search) { + data['http.query'] = parsedUrl.search; + } + if (parsedUrl.hash) { + data['http.fragment'] = parsedUrl.hash; + } + + return data; + } catch { + return {}; + } +} + /** * Determines if @param req is a ClientRequest, meaning the request was created within the express app * and it's an outgoing request. * Checking for properties instead of using `instanceOf` to avoid importing the request classes. */ -function _isClientRequest(req: ClientRequest | IncomingMessage): req is ClientRequest { +function _isClientRequest(req: ClientRequest | HTTPModuleRequestIncomingMessage): req is ClientRequest { return 'outputData' in req && 'outputSize' in req && !('client' in req) && !('statusCode' in req); } diff --git a/packages/node/src/integrations/node-fetch.ts b/packages/node/src/integrations/node-fetch.ts index 6ade560a4835..6150615d1bae 100644 --- a/packages/node/src/integrations/node-fetch.ts +++ b/packages/node/src/integrations/node-fetch.ts @@ -1,10 +1,8 @@ import type { Span } from '@opentelemetry/api'; -import { SpanKind } from '@opentelemetry/api'; import { addBreadcrumb, defineIntegration } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import { getRequestSpanData, getSpanKind } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; -import { logger } from '@sentry/utils'; +import type { IntegrationFn, SanitizedRequestData } from '@sentry/types'; +import { getSanitizedUrlString, logger, parseUrl } from '@sentry/utils'; import { DEBUG_BUILD } from '../debug-build'; import { NODE_MAJOR } from '../nodeVersion'; @@ -12,6 +10,18 @@ import type { FetchInstrumentation } from 'opentelemetry-instrumentation-fetch-n import { addOriginToSpan } from '../utils/addOriginToSpan'; +interface FetchRequest { + method: string; + origin: string; + path: string; + headers: string | string[]; +} + +interface FetchResponse { + headers: Buffer[]; + statusCode: number; +} + interface NodeFetchOptions { /** * Whether breadcrumbs should be recorded for requests. @@ -39,17 +49,26 @@ const _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => { try { const pkg = await import('opentelemetry-instrumentation-fetch-node'); - return new pkg.FetchInstrumentation({ + const { FetchInstrumentation } = pkg; + + class SentryNodeFetchInstrumentation extends FetchInstrumentation { + // We extend this method so we have access to request _and_ response for the breadcrumb + public onHeaders({ request, response }: { request: FetchRequest; response: FetchResponse }): void { + if (_breadcrumbs) { + _addRequestBreadcrumb(request, response); + } + + return super.onHeaders({ request, response }); + } + } + + return new SentryNodeFetchInstrumentation({ ignoreRequestHook: (request: { origin?: string }) => { const url = request.origin; return _ignoreOutgoingRequests && url && _ignoreOutgoingRequests(url); }, onRequest: ({ span }: { span: Span }) => { _updateSpan(span); - - if (_breadcrumbs) { - _addRequestBreadcrumb(span); - } }, // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); @@ -80,17 +99,45 @@ function _updateSpan(span: Span): void { } /** Add a breadcrumb for outgoing requests. */ -function _addRequestBreadcrumb(span: Span): void { - if (getSpanKind(span) !== SpanKind.CLIENT) { - return; - } +function _addRequestBreadcrumb(request: FetchRequest, response: FetchResponse): void { + const data = getBreadcrumbData(request); - const data = getRequestSpanData(span); - addBreadcrumb({ - category: 'http', - data: { - ...data, + addBreadcrumb( + { + category: 'http', + data: { + status_code: response.statusCode, + ...data, + }, + type: 'http', + }, + { + event: 'response', + request, + response, }, - type: 'http', - }); + ); +} + +function getBreadcrumbData(request: FetchRequest): Partial { + try { + const url = new URL(request.path, request.origin); + const parsedUrl = parseUrl(url.toString()); + + const data: Partial = { + url: getSanitizedUrlString(parsedUrl), + 'http.method': request.method || 'GET', + }; + + if (parsedUrl.search) { + data['http.query'] = parsedUrl.search; + } + if (parsedUrl.hash) { + data['http.fragment'] = parsedUrl.hash; + } + + return data; + } catch { + return {}; + } } From 6cb60a32133cb5f776a26dea3afedf05ed76011d Mon Sep 17 00:00:00 2001 From: Peter Boling Date: Wed, 22 May 2024 16:04:07 +0700 Subject: [PATCH 28/34] docs(sveltekit): process.env.SENTRY_AUTH_TOKEN (#12118) Remove quotes around process.env.SENTRY_AUTH_TOKEN --- packages/sveltekit/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sveltekit/README.md b/packages/sveltekit/README.md index 895c8dad23e1..904acfb6abac 100644 --- a/packages/sveltekit/README.md +++ b/packages/sveltekit/README.md @@ -215,7 +215,7 @@ export default { sourceMapsUploadOptions: { org: 'my-org-slug', project: 'my-project-slug', - authToken: 'process.env.SENTRY_AUTH_TOKEN', + authToken: process.env.SENTRY_AUTH_TOKEN, include: ['dist'], cleanArtifacts: true, setCommits: { From b7699d4b2206a8f12ca78d4ebccb1a71070902d4 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 22 May 2024 12:28:24 +0200 Subject: [PATCH 29/34] feat(browser): Ensure `browserProfilingIntegration` is published to CDN (#12158) Closes https://github.com/getsentry/sentry-javascript/issues/12156 --- packages/browser/rollup.bundle.config.mjs | 2 +- packages/browser/src/integrations/browserprofiling.ts | 1 + packages/browser/src/utils/lazyLoadIntegration.ts | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 packages/browser/src/integrations/browserprofiling.ts diff --git a/packages/browser/rollup.bundle.config.mjs b/packages/browser/rollup.bundle.config.mjs index 16c769582050..278b9cdc1b87 100644 --- a/packages/browser/rollup.bundle.config.mjs +++ b/packages/browser/rollup.bundle.config.mjs @@ -2,7 +2,7 @@ import { makeBaseBundleConfig, makeBundleConfigVariants } from '@sentry-internal const builds = []; -const browserPluggableIntegrationFiles = ['contextlines', 'httpclient', 'reportingobserver']; +const browserPluggableIntegrationFiles = ['contextlines', 'httpclient', 'reportingobserver', 'browserprofiling']; const corePluggableIntegrationFiles = [ 'captureconsole', diff --git a/packages/browser/src/integrations/browserprofiling.ts b/packages/browser/src/integrations/browserprofiling.ts new file mode 100644 index 000000000000..9a6212337f2e --- /dev/null +++ b/packages/browser/src/integrations/browserprofiling.ts @@ -0,0 +1 @@ +export { browserProfilingIntegration } from '../profiling/integration'; diff --git a/packages/browser/src/utils/lazyLoadIntegration.ts b/packages/browser/src/utils/lazyLoadIntegration.ts index f8d12abd93c0..c09bdfa45eae 100644 --- a/packages/browser/src/utils/lazyLoadIntegration.ts +++ b/packages/browser/src/utils/lazyLoadIntegration.ts @@ -20,6 +20,7 @@ const LazyLoadableIntegrations = { reportingObserverIntegration: 'reportingobserver', rewriteFramesIntegration: 'rewriteframes', sessionTimingIntegration: 'sessiontiming', + browserProfilingIntegration: 'browserprofiling', } as const; const WindowWithMaybeIntegration = WINDOW as { From 37a83ef61ec8b7bab0c50a14d69c64d7bb28dc4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 May 2024 14:18:29 +0200 Subject: [PATCH 30/34] feat(deps): Bump @opentelemetry/instrumentation-express from 0.38.0 to 0.39.0 (#12079) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@opentelemetry/instrumentation-express](https://github.com/open-telemetry/opentelemetry-js-contrib) from 0.38.0 to 0.39.0.
Release notes

Sourced from @​opentelemetry/instrumentation-express's releases.

instrumentation-express: v0.39.0

0.39.0 (2024-05-15)

Features

  • instrumentation-express: Support non-string routes (#2008) (525bbba)

instrumentation-pino: v0.39.0

0.39.0 (2024-05-02)

Features

instrumentation-mysql: v0.38.1

0.38.1 (2024-05-02)

Bug Fixes

  • remove unuseful patch message from instrumentations (#2161) (34f56e0)
Commits
  • b31df37 chore: release main (#2083)
  • f3406ea chore: remove patch and unpatch diag from instrumentations (#2107)
  • 73e01f2 chore(examples/graphql): use exported strings for attributes (#2122)
  • 80cbee7 chore: experimental 0.51.0, remove instrumentations generic type to align wit...
  • 46b6775 test(instr-document-load): fix test to allow missing network span events (#2145)
  • 931318c refactor(instr-aws-sdk): use exported strings for attributes (#2142)
  • 77452c1 chore(examples/connect): use exported strings for attributes (#2120)
  • 5f1910b chore(examples/web): use exported strings for attributes (#2129)
  • 0d38081 docs: remove key column on readme (#2132)
  • 2d709ec chore(instrumentation-fs): remove unused semconv package (#2141)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@opentelemetry/instrumentation-express&package-manager=npm_and_yarn&previous-version=0.38.0&new-version=0.39.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Francesco Novy --- .../suites/express/tracing/test.ts | 10 +- packages/node/package.json | 2 +- yarn.lock | 113 ++++++++++-------- 3 files changed, 71 insertions(+), 54 deletions(-) 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 1c169291f235..c05849f443ce 100644 --- a/dev-packages/node-integration-tests/suites/express/tracing/test.ts +++ b/dev-packages/node-integration-tests/suites/express/tracing/test.ts @@ -54,7 +54,7 @@ describe('express tracing experimental', () => { .ignore('session', 'sessions') .expect({ transaction: { - transaction: 'GET /', + transaction: 'GET /\\/test\\/regex/', transaction_info: { source: 'route', }, @@ -77,13 +77,13 @@ describe('express tracing experimental', () => { }); test.each([['array1'], ['array5']])( - 'should set a correct transaction name for routes consisting of arrays of routes', + 'should set a correct transaction name for routes consisting of arrays of routes for %p', ((segment: string, done: () => void) => { createRunner(__dirname, 'server.js') .ignore('session', 'sessions') .expect({ transaction: { - transaction: 'GET /', + transaction: 'GET /test/array1,/\\/test\\/array[2-9]/', transaction_info: { source: 'route', }, @@ -115,12 +115,12 @@ describe('express tracing experimental', () => { ['arr55/required/lastParam'], ['arr/requiredPath/optionalPath/'], ['arr/requiredPath/optionalPath/lastParam'], - ])('should handle more complex regexes in route arrays correctly', ((segment: string, done: () => void) => { + ])('should handle more complex regexes in route arrays correctly for %p', ((segment: string, done: () => void) => { createRunner(__dirname, 'server.js') .ignore('session', 'sessions') .expect({ transaction: { - transaction: 'GET /', + transaction: 'GET /test/arr/:id,/\\/test\\/arr[0-9]*\\/required(path)?(\\/optionalPath)?\\/(lastParam)?/', transaction_info: { source: 'route', }, diff --git a/packages/node/package.json b/packages/node/package.json index 4f03e9b86b98..d8fe5db00400 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -59,7 +59,7 @@ "@opentelemetry/core": "^1.24.1", "@opentelemetry/instrumentation": "^0.51.1", "@opentelemetry/instrumentation-connect": "0.36.0", - "@opentelemetry/instrumentation-express": "0.38.0", + "@opentelemetry/instrumentation-express": "0.39.0", "@opentelemetry/instrumentation-fastify": "0.36.1", "@opentelemetry/instrumentation-graphql": "0.40.0", "@opentelemetry/instrumentation-hapi": "0.38.0", diff --git a/yarn.lock b/yarn.lock index 9e40ae48d678..34d7cf722fb5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6112,13 +6112,6 @@ dependencies: "@octokit/openapi-types" "^18.0.0" -"@opentelemetry/api-logs@0.51.0": - version "0.51.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.51.0.tgz#71f296661d2215167c748ca044ff184a65d9426b" - integrity sha512-m/jtfBPEIXS1asltl8fPQtO3Sb1qMpuL61unQajUmM8zIxeMF1AlqzWXM3QedcYgTTFiJCew5uJjyhpmqhc0+g== - dependencies: - "@opentelemetry/api" "^1.0.0" - "@opentelemetry/api-logs@0.51.1": version "0.51.1" resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.51.1.tgz#ded1874c04516c2b8cb24828eef3d6c3d1f75343" @@ -6148,14 +6141,14 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.12.0.tgz#4906ae27359d3311e3dea1b63770a16f60848550" integrity sha512-UXwSsXo3F3yZ1dIBOG9ID8v2r9e+bqLWoizCtTb8rXtwF+N5TM7hzzvQz72o3nBU+zrI/D5e+OqAYK8ZgDd3DA== -"@opentelemetry/core@1.23.0", "@opentelemetry/core@^1.0.0", "@opentelemetry/core@^1.1.0", "@opentelemetry/core@^1.8.0": +"@opentelemetry/core@1.23.0": version "1.23.0" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.23.0.tgz#f2e7ada7f35750f3c1674aef1e52c879005c0731" integrity sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ== dependencies: "@opentelemetry/semantic-conventions" "1.23.0" -"@opentelemetry/core@1.24.1", "@opentelemetry/core@^1.24.1": +"@opentelemetry/core@1.24.1", "@opentelemetry/core@^1.0.0", "@opentelemetry/core@^1.1.0", "@opentelemetry/core@^1.24.1", "@opentelemetry/core@^1.8.0": version "1.24.1" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.24.1.tgz#35ab9d2ac9ca938e0ffbdfa40c49c169ac8ba80d" integrity sha512-wMSGfsdmibI88K9wB498zXY04yThPexo8jvwNNlm542HZB7XrrMRBbAyKJqG8qDRJwIBdBrPMi4V9ZPW/sqrcg== @@ -6202,10 +6195,10 @@ "@opentelemetry/semantic-conventions" "^1.0.0" "@types/connect" "3.4.36" -"@opentelemetry/instrumentation-express@0.38.0": - version "0.38.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-express/-/instrumentation-express-0.38.0.tgz#484de28d72ca259f56f60b488c7d14dd64590f30" - integrity sha512-izId/qcgMgfWV292ZI9b9E7HdV9446vi0Z5zu5fSlt4MF+R6LZXbZLTQAaboJ4Y2+JbtH7apvko1DF93qTFtqw== +"@opentelemetry/instrumentation-express@0.39.0": + version "0.39.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-express/-/instrumentation-express-0.39.0.tgz#2e7452645431c24b7a878a7919ce6dbc215f9def" + integrity sha512-AG8U7z7D0JcBu/7dDcwb47UMEzj9/FMiJV2iQZqrsZnxR3FjB9J9oIH2iszJYci2eUdp2WbdvtpD9RV/zmME5A== dependencies: "@opentelemetry/core" "^1.8.0" "@opentelemetry/instrumentation" "^0.51.0" @@ -6321,7 +6314,7 @@ "@types/pg" "8.6.1" "@types/pg-pool" "2.0.4" -"@opentelemetry/instrumentation@0.51.1", "@opentelemetry/instrumentation@^0.49 || ^0.50 || ^0.51", "@opentelemetry/instrumentation@^0.51.1": +"@opentelemetry/instrumentation@0.51.1", "@opentelemetry/instrumentation@^0.49 || ^0.50 || ^0.51", "@opentelemetry/instrumentation@^0.51.0", "@opentelemetry/instrumentation@^0.51.1": version "0.51.1" resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.51.1.tgz#46fb2291150ec6923e50b2f094b9407bc726ca9b" integrity sha512-JIrvhpgqY6437QIqToyozrUG1h5UhwHkaGK/WAX+fkrpyPtc+RO5FkRtUd9BH0MibabHHvqsnBGKfKVijbmp8w== @@ -6344,18 +6337,6 @@ semver "^7.5.2" shimmer "^1.2.1" -"@opentelemetry/instrumentation@^0.51.0": - version "0.51.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.51.0.tgz#93dbe96c87da539081d0ccd07475cfc0b0c61233" - integrity sha512-Eg/+Od5bEvzpvZQGhvMyKIkrzB9S7jW+6z9LHEI2VXhl/GrqQ3oBqlzJt4tA6pGtxRmqQWKWGM1wAbwDdW/gUA== - dependencies: - "@opentelemetry/api-logs" "0.51.0" - "@types/shimmer" "^1.0.2" - import-in-the-middle "1.7.1" - require-in-the-middle "^7.1.1" - semver "^7.5.2" - shimmer "^1.2.1" - "@opentelemetry/propagation-utils@^0.30.9": version "0.30.9" resolved "https://registry.yarnpkg.com/@opentelemetry/propagation-utils/-/propagation-utils-0.30.9.tgz#9d5a5cb74cb493193fa23012cd839d6bbd0d4957" @@ -6424,12 +6405,12 @@ "@opentelemetry/resources" "1.23.0" "@opentelemetry/semantic-conventions" "1.23.0" -"@opentelemetry/semantic-conventions@1.23.0", "@opentelemetry/semantic-conventions@^1.0.0", "@opentelemetry/semantic-conventions@^1.17.0", "@opentelemetry/semantic-conventions@^1.22.0", "@opentelemetry/semantic-conventions@^1.23.0": +"@opentelemetry/semantic-conventions@1.23.0": version "1.23.0" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.23.0.tgz#627f2721b960fe586b7f72a07912cb7699f06eef" integrity sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg== -"@opentelemetry/semantic-conventions@1.24.1": +"@opentelemetry/semantic-conventions@1.24.1", "@opentelemetry/semantic-conventions@^1.0.0", "@opentelemetry/semantic-conventions@^1.17.0", "@opentelemetry/semantic-conventions@^1.22.0", "@opentelemetry/semantic-conventions@^1.23.0": version "1.24.1" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz#d4bcebda1cb5146d47a2a53daaa7922f8e084dfb" integrity sha512-VkliWlS4/+GHLLW7J/rVBA00uXus1SWvwFvcUDxDwmFxYfg/2VI6ekwdXS28cjI8Qz2ky2BzG8OUHo+WeYIWqw== @@ -8325,8 +8306,17 @@ dependencies: "@types/unist" "*" -"@types/history-4@npm:@types/history@4.7.8", "@types/history-5@npm:@types/history@4.7.8", "@types/history@*": - name "@types/history-4" +"@types/history-4@npm:@types/history@4.7.8": + version "4.7.8" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" + integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== + +"@types/history-5@npm:@types/history@4.7.8": + version "4.7.8" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" + integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== + +"@types/history@*": version "4.7.8" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== @@ -8692,7 +8682,15 @@ "@types/history" "^3" "@types/react" "*" -"@types/react-router-4@npm:@types/react-router@5.1.14", "@types/react-router-5@npm:@types/react-router@5.1.14": +"@types/react-router-4@npm:@types/react-router@5.1.14": + version "5.1.14" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.14.tgz#e0442f4eb4c446541ad7435d44a97f8fe6df40da" + integrity sha512-LAJpqYUaCTMT2anZheoidiIymt8MuX286zoVFPM3DVb23aQBH0mAkFvzpd4LKqiolV8bBtZWT5Qp7hClCNDENw== + dependencies: + "@types/history" "*" + "@types/react" "*" + +"@types/react-router-5@npm:@types/react-router@5.1.14": version "5.1.14" resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.14.tgz#e0442f4eb4c446541ad7435d44a97f8fe6df40da" integrity sha512-LAJpqYUaCTMT2anZheoidiIymt8MuX286zoVFPM3DVb23aQBH0mAkFvzpd4LKqiolV8bBtZWT5Qp7hClCNDENw== @@ -18590,16 +18588,6 @@ import-in-the-middle@1.4.2: cjs-module-lexer "^1.2.2" module-details-from-path "^1.0.3" -import-in-the-middle@1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.7.1.tgz#3e111ff79c639d0bde459bd7ba29dd9fdf357364" - integrity sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg== - dependencies: - acorn "^8.8.2" - acorn-import-assertions "^1.9.0" - cjs-module-lexer "^1.2.2" - module-details-from-path "^1.0.3" - import-in-the-middle@1.7.4: version "1.7.4" resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.7.4.tgz#508da6e91cfa84f210dcdb6c0a91ab0c9e8b3ebc" @@ -25777,8 +25765,7 @@ react-is@^18.0.0: dependencies: "@remix-run/router" "1.0.2" -"react-router-6@npm:react-router@6.3.0", react-router@6.3.0: - name react-router-6 +"react-router-6@npm:react-router@6.3.0": version "6.3.0" resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== @@ -25793,6 +25780,13 @@ react-router-dom@^6.2.2: history "^5.2.0" react-router "6.3.0" +react-router@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.3.0.tgz#3970cc64b4cb4eae0c1ea5203a80334fdd175557" + integrity sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ== + dependencies: + history "^5.2.0" + react@^18.0.0: version "18.0.0" resolved "https://registry.yarnpkg.com/react/-/react-18.0.0.tgz#b468736d1f4a5891f38585ba8e8fb29f91c3cb96" @@ -28037,8 +28031,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: - name string-width-cjs +"string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -28064,6 +28057,15 @@ string-width@^2.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -28159,7 +28161,14 @@ stringify-object@^3.2.1: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -30745,8 +30754,7 @@ workerpool@^6.4.0: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.4.0.tgz#f8d5cfb45fde32fa3b7af72ad617c3369567a462" integrity sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - name wrap-ansi-cjs +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -30764,6 +30772,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 88e002db8d6c27e1153325199427ab7180745c41 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Wed, 22 May 2024 15:42:05 +0200 Subject: [PATCH 31/34] feat(node): No-code init via `--import=@sentry/node/init` (#11999) --- .../suites/no-code/app.js | 3 ++ .../suites/no-code/app.mjs | 3 ++ .../suites/no-code/test.ts | 37 +++++++++++++++++++ packages/node/package.json | 8 ++++ packages/node/rollup.npm.config.mjs | 1 + packages/node/src/init.ts | 9 +++++ 6 files changed, 61 insertions(+) create mode 100644 dev-packages/node-integration-tests/suites/no-code/app.js create mode 100644 dev-packages/node-integration-tests/suites/no-code/app.mjs create mode 100644 dev-packages/node-integration-tests/suites/no-code/test.ts create mode 100644 packages/node/src/init.ts diff --git a/dev-packages/node-integration-tests/suites/no-code/app.js b/dev-packages/node-integration-tests/suites/no-code/app.js new file mode 100644 index 000000000000..cb1937007297 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/no-code/app.js @@ -0,0 +1,3 @@ +setTimeout(() => { + throw new Error('Test error'); +}, 1000); diff --git a/dev-packages/node-integration-tests/suites/no-code/app.mjs b/dev-packages/node-integration-tests/suites/no-code/app.mjs new file mode 100644 index 000000000000..cb1937007297 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/no-code/app.mjs @@ -0,0 +1,3 @@ +setTimeout(() => { + throw new Error('Test error'); +}, 1000); diff --git a/dev-packages/node-integration-tests/suites/no-code/test.ts b/dev-packages/node-integration-tests/suites/no-code/test.ts new file mode 100644 index 000000000000..dfaae9de7cdc --- /dev/null +++ b/dev-packages/node-integration-tests/suites/no-code/test.ts @@ -0,0 +1,37 @@ +import { conditionalTest } from '../../utils'; +import { cleanupChildProcesses, createRunner } from '../../utils/runner'; + +const EVENT = { + exception: { + values: [ + { + type: 'Error', + value: 'Test error', + }, + ], + }, +}; + +describe('no-code init', () => { + afterAll(() => { + cleanupChildProcesses(); + }); + + test('CJS', done => { + createRunner(__dirname, 'app.js') + .withFlags('--require=@sentry/node/init') + .withMockSentryServer() + .expect({ event: EVENT }) + .start(done); + }); + + conditionalTest({ min: 18 })('--import', () => { + test('ESM', done => { + createRunner(__dirname, 'app.mjs') + .withFlags('--import=@sentry/node/init') + .withMockSentryServer() + .expect({ event: EVENT }) + .start(done); + }); + }); +}); diff --git a/packages/node/package.json b/packages/node/package.json index d8fe5db00400..fac4f640102b 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -41,6 +41,14 @@ "import": { "default": "./build/loader-hook.mjs" } + }, + "./init":{ + "import": { + "default": "./build/esm/init.js" + }, + "require": { + "default": "./build/cjs/init.js" + } } }, "typesVersions": { diff --git a/packages/node/rollup.npm.config.mjs b/packages/node/rollup.npm.config.mjs index f9adb7d91ca5..8e18333836ef 100644 --- a/packages/node/rollup.npm.config.mjs +++ b/packages/node/rollup.npm.config.mjs @@ -19,6 +19,7 @@ export default [ localVariablesWorkerConfig, ...makeNPMConfigVariants( makeBaseNPMConfig({ + entrypoints: ['src/index.ts', 'src/init.ts'], packageSpecificConfig: { output: { // set exports to 'named' or 'auto' so that rollup doesn't warn diff --git a/packages/node/src/init.ts b/packages/node/src/init.ts new file mode 100644 index 000000000000..245ae8573afa --- /dev/null +++ b/packages/node/src/init.ts @@ -0,0 +1,9 @@ +import { init } from './sdk/init'; + +/** + * The @sentry/node/init export can be used with the node --import and --require args to initialize the SDK entirely via + * environment variables. + * + * > SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 SENTRY_TRACES_SAMPLE_RATE=1.0 node --import=@sentry/node/init app.mjs + */ +init(); From 772269a0480ca09a604ccc75c3d84d56956b0c81 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Wed, 22 May 2024 11:15:36 -0230 Subject: [PATCH 32/34] feat(replay): Use unwrapped `setTimeout` to avoid e.g. angular change detection (#11924) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR makes sure we use the native, unwrapped `setTimeout` implementation of the browser. Some environments, e.g. Angular, monkey patch this for their change detection, leading to performance issues (possibly). We have already changed this in rrweb, but we also have some usage of this in replay itself. This PR _should_ work fine, however all test fail today because we heavily use `jest.useFakeTimers()`, which basically monkey patches fetch too. So with this change, we do not use the patched timers, leading to everything blowing up 🤯 Based on https://github.com/getsentry/sentry-javascript/pull/11864 Depends on https://github.com/getsentry/sentry-javascript/pull/11899 --------- Co-authored-by: Francesco Novy --- .../src/getNativeImplementation.ts | 131 ++++++++++++++++++ packages/browser-utils/src/index.ts | 7 +- packages/browser-utils/src/instrument/dom.ts | 2 +- .../browser-utils/src/instrument/history.ts | 2 +- packages/browser-utils/src/instrument/xhr.ts | 2 +- .../src/metrics/browserMetrics.ts | 2 +- packages/browser-utils/src/metrics/utils.ts | 2 +- .../src/metrics/web-vitals/getINP.ts | 2 +- .../src/metrics/web-vitals/getLCP.ts | 2 +- .../web-vitals/lib/getNavigationEntry.ts | 2 +- .../web-vitals/lib/getVisibilityWatcher.ts | 2 +- .../src/metrics/web-vitals/lib/initMetric.ts | 2 +- .../src/metrics/web-vitals/lib/onHidden.ts | 2 +- .../metrics/web-vitals/lib/whenActivated.ts | 2 +- .../src/metrics/web-vitals/onTTFB.ts | 2 +- .../browser-utils/src/{metrics => }/types.ts | 0 .../test/browser/browserMetrics.test.ts | 2 +- packages/browser/.eslintrc.js | 2 +- packages/browser/src/transports/fetch.ts | 10 +- packages/browser/src/transports/utils.ts | 91 ------------ packages/browser/{src => test}/loader.js | 0 .../test/unit/transports/fetch.test.ts | 13 +- packages/browser/tsconfig.json | 2 +- .../src/coreHandlers/handleAfterSendEvent.ts | 1 + .../src/coreHandlers/handleClick.ts | 1 + .../src/coreHandlers/util/fetchUtils.ts | 1 + packages/replay-internal/src/util/debounce.ts | 2 + packages/replay-internal/src/util/log.ts | 1 + .../replay-internal/src/util/sendReplay.ts | 1 + .../coreHandlers/handleAfterSendEvent.test.ts | 5 +- .../test/integration/flush.test.ts | 7 +- .../unit/coreHandlers/handleClick.test.ts | 7 +- .../handleNetworkBreadcrumbs.test.ts | 3 +- .../util/addBreadcrumbEvent.test.ts | 9 +- .../unit/coreHandlers/util/fetchUtils.test.ts | 27 ++-- .../coreHandlers/util/networkUtils.test.ts | 5 +- .../unit/util/createPerformanceEntry.test.ts | 4 +- .../test/unit/util/debounce.test.ts | 7 +- .../test/unit/util/throttle.test.ts | 3 +- .../test/utils/use-fake-timers.ts | 7 + 40 files changed, 221 insertions(+), 154 deletions(-) create mode 100644 packages/browser-utils/src/getNativeImplementation.ts rename packages/browser-utils/src/{metrics => }/types.ts (100%) delete mode 100644 packages/browser/src/transports/utils.ts rename packages/browser/{src => test}/loader.js (100%) diff --git a/packages/browser-utils/src/getNativeImplementation.ts b/packages/browser-utils/src/getNativeImplementation.ts new file mode 100644 index 000000000000..e06fb69f561e --- /dev/null +++ b/packages/browser-utils/src/getNativeImplementation.ts @@ -0,0 +1,131 @@ +import { logger } from '@sentry/utils'; +import { DEBUG_BUILD } from './debug-build'; +import { WINDOW } from './types'; + +/** + * We generally want to use window.fetch / window.setTimeout. + * However, in some cases this may be wrapped (e.g. by Zone.js for Angular), + * so we try to get an unpatched version of this from a sandboxed iframe. + */ + +interface CacheableImplementations { + setTimeout: typeof WINDOW.setTimeout; + fetch: typeof WINDOW.fetch; +} + +const cachedImplementations: Partial = {}; + +/** + * isNative checks if the given function is a native implementation + */ +// eslint-disable-next-line @typescript-eslint/ban-types +function isNative(func: Function): boolean { + return func && /^function\s+\w+\(\)\s+\{\s+\[native code\]\s+\}$/.test(func.toString()); +} + +/** + * Get the native implementation of a browser function. + * + * This can be used to ensure we get an unwrapped version of a function, in cases where a wrapped function can lead to problems. + * + * The following methods can be retrieved: + * - `setTimeout`: This can be wrapped by e.g. Angular, causing change detection to be triggered. + * - `fetch`: This can be wrapped by e.g. ad-blockers, causing an infinite loop when a request is blocked. + */ +export function getNativeImplementation( + name: T, +): CacheableImplementations[T] { + const cached = cachedImplementations[name]; + if (cached) { + return cached; + } + + let impl = WINDOW[name] as CacheableImplementations[T]; + + // Fast path to avoid DOM I/O + if (isNative(impl)) { + return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]); + } + + const document = WINDOW.document; + // eslint-disable-next-line deprecation/deprecation + if (document && typeof document.createElement === 'function') { + try { + const sandbox = document.createElement('iframe'); + sandbox.hidden = true; + document.head.appendChild(sandbox); + const contentWindow = sandbox.contentWindow; + if (contentWindow && contentWindow[name]) { + impl = contentWindow[name] as CacheableImplementations[T]; + } + document.head.removeChild(sandbox); + } catch (e) { + // Could not create sandbox iframe, just use window.xxx + DEBUG_BUILD && logger.warn(`Could not create sandbox iframe for ${name} check, bailing to window.${name}: `, e); + } + } + + // Sanity check: This _should_ not happen, but if it does, we just skip caching... + // This can happen e.g. in tests where fetch may not be available in the env, or similar. + if (!impl) { + return impl; + } + + return (cachedImplementations[name] = impl.bind(WINDOW) as CacheableImplementations[T]); +} + +/** Clear a cached implementation. */ +export function clearCachedImplementation(name: keyof CacheableImplementations): void { + cachedImplementations[name] = undefined; +} + +/** + * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers. + * Whenever someone wraps the Fetch API and returns the wrong promise chain, + * this chain becomes orphaned and there is no possible way to capture it's rejections + * other than allowing it bubble up to this very handler. eg. + * + * const f = window.fetch; + * window.fetch = function () { + * const p = f.apply(this, arguments); + * + * p.then(function() { + * console.log('hi.'); + * }); + * + * return p; + * } + * + * `p.then(function () { ... })` is producing a completely separate promise chain, + * however, what's returned is `p` - the result of original `fetch` call. + * + * This mean, that whenever we use the Fetch API to send our own requests, _and_ + * some ad-blocker blocks it, this orphaned chain will _always_ reject, + * effectively causing another event to be captured. + * This makes a whole process become an infinite loop, which we need to somehow + * deal with, and break it in one way or another. + * + * To deal with this issue, we are making sure that we _always_ use the real + * browser Fetch API, instead of relying on what `window.fetch` exposes. + * The only downside to this would be missing our own requests as breadcrumbs, + * but because we are already not doing this, it should be just fine. + * + * Possible failed fetch error messages per-browser: + * + * Chrome: Failed to fetch + * Edge: Failed to Fetch + * Firefox: NetworkError when attempting to fetch resource + * Safari: resource blocked by content blocker + */ +export function fetch(...rest: Parameters): ReturnType { + return getNativeImplementation('fetch')(...rest); +} + +/** + * Get an unwrapped `setTimeout` method. + * This ensures that even if e.g. Angular wraps `setTimeout`, we get the native implementation, + * avoiding triggering change detection. + */ +export function setTimeout(...rest: Parameters): ReturnType { + return getNativeImplementation('setTimeout')(...rest); +} diff --git a/packages/browser-utils/src/index.ts b/packages/browser-utils/src/index.ts index 53e2f24068d6..7e7c4d0a387a 100644 --- a/packages/browser-utils/src/index.ts +++ b/packages/browser-utils/src/index.ts @@ -18,7 +18,6 @@ export { addClickKeypressInstrumentationHandler } from './instrument/dom'; export { addHistoryInstrumentationHandler } from './instrument/history'; -export { - addXhrInstrumentationHandler, - SENTRY_XHR_DATA_KEY, -} from './instrument/xhr'; +export { fetch, setTimeout, clearCachedImplementation, getNativeImplementation } from './getNativeImplementation'; + +export { addXhrInstrumentationHandler, SENTRY_XHR_DATA_KEY } from './instrument/xhr'; diff --git a/packages/browser-utils/src/instrument/dom.ts b/packages/browser-utils/src/instrument/dom.ts index 5e813f23eb67..d08350a48766 100644 --- a/packages/browser-utils/src/instrument/dom.ts +++ b/packages/browser-utils/src/instrument/dom.ts @@ -1,7 +1,7 @@ import type { HandlerDataDom } from '@sentry/types'; import { addHandler, addNonEnumerableProperty, fill, maybeInstrument, triggerHandlers, uuid4 } from '@sentry/utils'; -import { WINDOW } from '../metrics/types'; +import { WINDOW } from '../types'; type SentryWrappedTarget = HTMLElement & { _sentryId?: string }; diff --git a/packages/browser-utils/src/instrument/history.ts b/packages/browser-utils/src/instrument/history.ts index f791bcef5389..acb31dfc455d 100644 --- a/packages/browser-utils/src/instrument/history.ts +++ b/packages/browser-utils/src/instrument/history.ts @@ -1,6 +1,6 @@ import type { HandlerDataHistory } from '@sentry/types'; import { addHandler, fill, maybeInstrument, supportsHistory, triggerHandlers } from '@sentry/utils'; -import { WINDOW } from '../metrics/types'; +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 c3fa2ec6a62c..5b7a9c261092 100644 --- a/packages/browser-utils/src/instrument/xhr.ts +++ b/packages/browser-utils/src/instrument/xhr.ts @@ -1,7 +1,7 @@ import type { HandlerDataXhr, SentryWrappedXMLHttpRequest, WrappedFunction } from '@sentry/types'; import { addHandler, fill, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/utils'; -import { WINDOW } from '../metrics/types'; +import { WINDOW } from '../types'; export const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__'; diff --git a/packages/browser-utils/src/metrics/browserMetrics.ts b/packages/browser-utils/src/metrics/browserMetrics.ts index deca3765e404..877b0612fb06 100644 --- a/packages/browser-utils/src/metrics/browserMetrics.ts +++ b/packages/browser-utils/src/metrics/browserMetrics.ts @@ -6,6 +6,7 @@ import { browserPerformanceTimeOrigin, getComponentName, htmlTreeAsString, logge import { spanToJSON } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; +import { WINDOW } from '../types'; import { addClsInstrumentationHandler, addFidInstrumentationHandler, @@ -13,7 +14,6 @@ import { addPerformanceInstrumentationHandler, addTtfbInstrumentationHandler, } from './instrument'; -import { WINDOW } from './types'; import { getBrowserPerformanceAPI, isMeasurementValue, msToSec, startAndEndSpan } from './utils'; import { getNavigationEntry } from './web-vitals/lib/getNavigationEntry'; import { getVisibilityWatcher } from './web-vitals/lib/getVisibilityWatcher'; diff --git a/packages/browser-utils/src/metrics/utils.ts b/packages/browser-utils/src/metrics/utils.ts index 1927f0e9a971..d46cb2cfe35c 100644 --- a/packages/browser-utils/src/metrics/utils.ts +++ b/packages/browser-utils/src/metrics/utils.ts @@ -1,7 +1,7 @@ import type { SentrySpan } from '@sentry/core'; import { spanToJSON, startInactiveSpan, withActiveSpan } from '@sentry/core'; import type { Span, SpanTimeInput, StartSpanOptions } from '@sentry/types'; -import { WINDOW } from './types'; +import { WINDOW } from '../types'; /** * Checks if a given value is a valid measurement value. diff --git a/packages/browser-utils/src/metrics/web-vitals/getINP.ts b/packages/browser-utils/src/metrics/web-vitals/getINP.ts index 5c4a185aa92f..fa2d90da3371 100644 --- a/packages/browser-utils/src/metrics/web-vitals/getINP.ts +++ b/packages/browser-utils/src/metrics/web-vitals/getINP.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../types'; +import { WINDOW } from '../../types'; import { bindReporter } from './lib/bindReporter'; import { initMetric } from './lib/initMetric'; import { observe } from './lib/observe'; diff --git a/packages/browser-utils/src/metrics/web-vitals/getLCP.ts b/packages/browser-utils/src/metrics/web-vitals/getLCP.ts index db1bd90fb71d..b50358c98d61 100644 --- a/packages/browser-utils/src/metrics/web-vitals/getLCP.ts +++ b/packages/browser-utils/src/metrics/web-vitals/getLCP.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../types'; +import { WINDOW } from '../../types'; import { bindReporter } from './lib/bindReporter'; import { getActivationStart } from './lib/getActivationStart'; import { getVisibilityWatcher } from './lib/getVisibilityWatcher'; 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 2fa455e3fbba..63cfa04b3ad4 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/getNavigationEntry.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../../types'; +import { WINDOW } from '../../../types'; import type { NavigationTimingPolyfillEntry } from '../types'; export const getNavigationEntry = (): PerformanceNavigationTiming | NavigationTimingPolyfillEntry | undefined => { 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 6fe3755f6f59..c254ad1259d9 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/getVisibilityWatcher.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../../types'; +import { WINDOW } from '../../../types'; let firstHiddenTime = -1; diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/initMetric.ts b/packages/browser-utils/src/metrics/web-vitals/lib/initMetric.ts index 386333b7eb2d..fee96d83bf33 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/initMetric.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/initMetric.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../../types'; +import { WINDOW } from '../../../types'; import type { MetricType } from '../types'; import { generateUniqueID } from './generateUniqueID'; import { getActivationStart } from './getActivationStart'; 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 9f81c7369007..9f65196d27a2 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/onHidden.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../../types'; +import { WINDOW } from '../../../types'; export interface OnHiddenCallback { (event: Event): void; diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/whenActivated.ts b/packages/browser-utils/src/metrics/web-vitals/lib/whenActivated.ts index 183a8566aeb4..8463a1d199ef 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/whenActivated.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/whenActivated.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../../types'; +import { WINDOW } from '../../../types'; export const whenActivated = (callback: () => void) => { if (WINDOW.document && WINDOW.document.prerendering) { diff --git a/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts b/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts index 993af7ca074e..85f9b99bc0f4 100644 --- a/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts +++ b/packages/browser-utils/src/metrics/web-vitals/onTTFB.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { WINDOW } from '../types'; +import { WINDOW } from '../../types'; import { bindReporter } from './lib/bindReporter'; import { getActivationStart } from './lib/getActivationStart'; import { getNavigationEntry } from './lib/getNavigationEntry'; diff --git a/packages/browser-utils/src/metrics/types.ts b/packages/browser-utils/src/types.ts similarity index 100% rename from packages/browser-utils/src/metrics/types.ts rename to packages/browser-utils/src/types.ts diff --git a/packages/browser-utils/test/browser/browserMetrics.test.ts b/packages/browser-utils/test/browser/browserMetrics.test.ts index b6d6aaa087aa..555dfde1c92f 100644 --- a/packages/browser-utils/test/browser/browserMetrics.test.ts +++ b/packages/browser-utils/test/browser/browserMetrics.test.ts @@ -11,7 +11,7 @@ import { import type { Span } from '@sentry/types'; import type { ResourceEntry } from '../../src/metrics/browserMetrics'; import { _addMeasureSpans, _addResourceSpans } from '../../src/metrics/browserMetrics'; -import { WINDOW } from '../../src/metrics/types'; +import { WINDOW } from '../../src/types'; import { TestClient, getDefaultClientOptions } from '../utils/TestClient'; const mockWindowLocation = { diff --git a/packages/browser/.eslintrc.js b/packages/browser/.eslintrc.js index 765edcb14960..fec08079889a 100644 --- a/packages/browser/.eslintrc.js +++ b/packages/browser/.eslintrc.js @@ -2,6 +2,6 @@ module.exports = { env: { browser: true, }, - ignorePatterns: ['test/integration/**', 'src/loader.js'], + ignorePatterns: ['test/integration/**', 'test/loader.js'], extends: ['../../.eslintrc.js'], }; diff --git a/packages/browser/src/transports/fetch.ts b/packages/browser/src/transports/fetch.ts index 305afb9fc0ec..52ba6d71154c 100644 --- a/packages/browser/src/transports/fetch.ts +++ b/packages/browser/src/transports/fetch.ts @@ -1,17 +1,17 @@ +import { clearCachedImplementation, getNativeImplementation } from '@sentry-internal/browser-utils'; import { createTransport } from '@sentry/core'; import type { Transport, TransportMakeRequestResponse, TransportRequest } from '@sentry/types'; import { rejectedSyncPromise } from '@sentry/utils'; +import type { WINDOW } from '../helpers'; import type { BrowserTransportOptions } from './types'; -import type { FetchImpl } from './utils'; -import { clearCachedFetchImplementation, getNativeFetchImplementation } from './utils'; /** * Creates a Transport that uses the Fetch API to send events to Sentry. */ export function makeFetchTransport( options: BrowserTransportOptions, - nativeFetch: FetchImpl | undefined = getNativeFetchImplementation(), + nativeFetch: typeof WINDOW.fetch | undefined = getNativeImplementation('fetch'), ): Transport { let pendingBodySize = 0; let pendingCount = 0; @@ -42,7 +42,7 @@ export function makeFetchTransport( }; if (!nativeFetch) { - clearCachedFetchImplementation(); + clearCachedImplementation('fetch'); return rejectedSyncPromise('No fetch implementation available'); } @@ -59,7 +59,7 @@ export function makeFetchTransport( }; }); } catch (e) { - clearCachedFetchImplementation(); + clearCachedImplementation('fetch'); pendingBodySize -= requestSize; pendingCount--; return rejectedSyncPromise(e); diff --git a/packages/browser/src/transports/utils.ts b/packages/browser/src/transports/utils.ts deleted file mode 100644 index 053a0d0dd483..000000000000 --- a/packages/browser/src/transports/utils.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { isNativeFetch, logger } from '@sentry/utils'; - -import { DEBUG_BUILD } from '../debug-build'; -import { WINDOW } from '../helpers'; - -let cachedFetchImpl: FetchImpl | undefined = undefined; - -export type FetchImpl = typeof fetch; - -/** - * A special usecase for incorrectly wrapped Fetch APIs in conjunction with ad-blockers. - * Whenever someone wraps the Fetch API and returns the wrong promise chain, - * this chain becomes orphaned and there is no possible way to capture it's rejections - * other than allowing it bubble up to this very handler. eg. - * - * const f = window.fetch; - * window.fetch = function () { - * const p = f.apply(this, arguments); - * - * p.then(function() { - * console.log('hi.'); - * }); - * - * return p; - * } - * - * `p.then(function () { ... })` is producing a completely separate promise chain, - * however, what's returned is `p` - the result of original `fetch` call. - * - * This mean, that whenever we use the Fetch API to send our own requests, _and_ - * some ad-blocker blocks it, this orphaned chain will _always_ reject, - * effectively causing another event to be captured. - * This makes a whole process become an infinite loop, which we need to somehow - * deal with, and break it in one way or another. - * - * To deal with this issue, we are making sure that we _always_ use the real - * browser Fetch API, instead of relying on what `window.fetch` exposes. - * The only downside to this would be missing our own requests as breadcrumbs, - * but because we are already not doing this, it should be just fine. - * - * Possible failed fetch error messages per-browser: - * - * Chrome: Failed to fetch - * Edge: Failed to Fetch - * Firefox: NetworkError when attempting to fetch resource - * Safari: resource blocked by content blocker - */ -export function getNativeFetchImplementation(): FetchImpl | undefined { - if (cachedFetchImpl) { - return cachedFetchImpl; - } - - /* eslint-disable @typescript-eslint/unbound-method */ - - // Fast path to avoid DOM I/O - if (isNativeFetch(WINDOW.fetch)) { - return (cachedFetchImpl = WINDOW.fetch.bind(WINDOW)); - } - - const document = WINDOW.document; - let fetchImpl = WINDOW.fetch; - // eslint-disable-next-line deprecation/deprecation - if (document && typeof document.createElement === 'function') { - try { - const sandbox = document.createElement('iframe'); - sandbox.hidden = true; - document.head.appendChild(sandbox); - const contentWindow = sandbox.contentWindow; - if (contentWindow && contentWindow.fetch) { - fetchImpl = contentWindow.fetch; - } - document.head.removeChild(sandbox); - } catch (e) { - DEBUG_BUILD && logger.warn('Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ', e); - } - } - - try { - return (cachedFetchImpl = fetchImpl.bind(WINDOW)); - } catch (e) { - // empty - } - - return undefined; - /* eslint-enable @typescript-eslint/unbound-method */ -} - -/** Clears cached fetch impl */ -export function clearCachedFetchImplementation(): void { - cachedFetchImpl = undefined; -} diff --git a/packages/browser/src/loader.js b/packages/browser/test/loader.js similarity index 100% rename from packages/browser/src/loader.js rename to packages/browser/test/loader.js diff --git a/packages/browser/test/unit/transports/fetch.test.ts b/packages/browser/test/unit/transports/fetch.test.ts index c80688eb11c3..ae8a5d43a6e0 100644 --- a/packages/browser/test/unit/transports/fetch.test.ts +++ b/packages/browser/test/unit/transports/fetch.test.ts @@ -3,7 +3,6 @@ import { createEnvelope, serializeEnvelope } from '@sentry/utils'; import { makeFetchTransport } from '../../../src/transports/fetch'; import type { BrowserTransportOptions } from '../../../src/transports/types'; -import type { FetchImpl } from '../../../src/transports/utils'; const DEFAULT_FETCH_TRANSPORT_OPTIONS: BrowserTransportOptions = { url: 'https://sentry.io/api/42/store/?sentry_key=123&sentry_version=7', @@ -37,7 +36,7 @@ describe('NewFetchTransport', () => { status: 200, text: () => Promise.resolve({}), }), - ) as unknown as FetchImpl; + ) as unknown as typeof window.fetch; const transport = makeFetchTransport(DEFAULT_FETCH_TRANSPORT_OPTIONS, mockFetch); expect(mockFetch).toHaveBeenCalledTimes(0); @@ -63,7 +62,7 @@ describe('NewFetchTransport', () => { status: 200, text: () => Promise.resolve({}), }), - ) as unknown as FetchImpl; + ) as unknown as typeof window.fetch; const transport = makeFetchTransport(DEFAULT_FETCH_TRANSPORT_OPTIONS, mockFetch); expect(headers.get).toHaveBeenCalledTimes(0); @@ -81,7 +80,7 @@ describe('NewFetchTransport', () => { status: 200, text: () => Promise.resolve({}), }), - ) as unknown as FetchImpl; + ) as unknown as typeof window.fetch; const REQUEST_OPTIONS: RequestInit = { referrerPolicy: 'strict-origin', @@ -102,8 +101,8 @@ describe('NewFetchTransport', () => { }); }); - it('handles when `getNativeFetchImplementation` is undefined', async () => { - const mockFetch = jest.fn(() => undefined) as unknown as FetchImpl; + it('handles when `getNativetypeof window.fetchementation` is undefined', async () => { + const mockFetch = jest.fn(() => undefined) as unknown as typeof window.fetch; const transport = makeFetchTransport(DEFAULT_FETCH_TRANSPORT_OPTIONS, mockFetch); expect(mockFetch).toHaveBeenCalledTimes(0); @@ -118,7 +117,7 @@ describe('NewFetchTransport', () => { status: 200, text: () => Promise.resolve({}), }), - ) as unknown as FetchImpl; + ) as unknown as typeof window.fetch; const REQUEST_OPTIONS: RequestInit = { referrerPolicy: 'strict-origin', diff --git a/packages/browser/tsconfig.json b/packages/browser/tsconfig.json index bf45a09f2d71..f88d8939acf7 100644 --- a/packages/browser/tsconfig.json +++ b/packages/browser/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.json", - "include": ["src/**/*"], + "include": ["src/**/*", "test/loader.js"], "compilerOptions": { // package-specific options diff --git a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts index 14e92d404fc7..74a4f8869d0f 100644 --- a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts +++ b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts @@ -1,3 +1,4 @@ +import { setTimeout } from '@sentry-internal/browser-utils'; import type { ErrorEvent, Event, TransactionEvent, TransportMakeRequestResponse } from '@sentry/types'; import type { ReplayContainer } from '../types'; diff --git a/packages/replay-internal/src/coreHandlers/handleClick.ts b/packages/replay-internal/src/coreHandlers/handleClick.ts index dab5d04657fc..da07474deebb 100644 --- a/packages/replay-internal/src/coreHandlers/handleClick.ts +++ b/packages/replay-internal/src/coreHandlers/handleClick.ts @@ -1,3 +1,4 @@ +import { setTimeout } from '@sentry-internal/browser-utils'; import { IncrementalSource, MouseInteractions, record } from '@sentry-internal/rrweb'; import type { Breadcrumb } from '@sentry/types'; diff --git a/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts b/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts index 399206ad659a..b5c2c3c36305 100644 --- a/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts +++ b/packages/replay-internal/src/coreHandlers/util/fetchUtils.ts @@ -1,3 +1,4 @@ +import { setTimeout } from '@sentry-internal/browser-utils'; import type { Breadcrumb, FetchBreadcrumbData } from '@sentry/types'; import { logger } from '@sentry/utils'; diff --git a/packages/replay-internal/src/util/debounce.ts b/packages/replay-internal/src/util/debounce.ts index 88057c14a4c5..78437b7d9403 100644 --- a/packages/replay-internal/src/util/debounce.ts +++ b/packages/replay-internal/src/util/debounce.ts @@ -1,3 +1,5 @@ +import { setTimeout } from '@sentry-internal/browser-utils'; + type DebouncedCallback = { (): void | unknown; flush: () => void | unknown; diff --git a/packages/replay-internal/src/util/log.ts b/packages/replay-internal/src/util/log.ts index 3d16137bbbc0..c847a093f02f 100644 --- a/packages/replay-internal/src/util/log.ts +++ b/packages/replay-internal/src/util/log.ts @@ -1,3 +1,4 @@ +import { setTimeout } from '@sentry-internal/browser-utils'; import { addBreadcrumb } from '@sentry/core'; import { logger } from '@sentry/utils'; diff --git a/packages/replay-internal/src/util/sendReplay.ts b/packages/replay-internal/src/util/sendReplay.ts index 18c256987453..973c3fb9a556 100644 --- a/packages/replay-internal/src/util/sendReplay.ts +++ b/packages/replay-internal/src/util/sendReplay.ts @@ -1,3 +1,4 @@ +import { setTimeout } from '@sentry-internal/browser-utils'; import { captureException, setContext } from '@sentry/core'; import { RETRY_BASE_INTERVAL, RETRY_MAX_COUNT, UNABLE_TO_SEND_REPLAY } from '../constants'; diff --git a/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts b/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts index afab6ac6030a..8edc813aaad2 100644 --- a/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts +++ b/packages/replay-internal/test/integration/coreHandlers/handleAfterSendEvent.test.ts @@ -1,5 +1,8 @@ import { vi } from 'vitest'; import type { MockInstance } from 'vitest'; +import { useFakeTimers } from '../../utils/use-fake-timers'; + +useFakeTimers(); import { getClient } from '@sentry/core'; import type { ErrorEvent, Event } from '@sentry/types'; @@ -10,9 +13,7 @@ import type { ReplayContainer } from '../../../src/replay'; import { Error } from '../../fixtures/error'; import { Transaction } from '../../fixtures/transaction'; import { resetSdkMock } from '../../mocks/resetSdkMock'; -import { useFakeTimers } from '../../utils/use-fake-timers'; -useFakeTimers(); let replay: ReplayContainer; describe('Integration | coreHandlers | handleAfterSendEvent', () => { diff --git a/packages/replay-internal/test/integration/flush.test.ts b/packages/replay-internal/test/integration/flush.test.ts index bb00da732df3..31fd8a91a5e2 100644 --- a/packages/replay-internal/test/integration/flush.test.ts +++ b/packages/replay-internal/test/integration/flush.test.ts @@ -1,6 +1,10 @@ import { vi } from 'vitest'; import type { MockedFunction } from 'vitest'; +import { useFakeTimers } from '../utils/use-fake-timers'; + +useFakeTimers(); + import * as SentryBrowserUtils from '@sentry-internal/browser-utils'; import * as SentryUtils from '@sentry/utils'; @@ -14,9 +18,6 @@ import * as SendReplay from '../../src/util/sendReplay'; import { BASE_TIMESTAMP, mockRrweb, mockSdk } from '../index'; import type { DomHandler } from '../types'; import { getTestEventCheckout } from '../utils/getTestEvent'; -import { useFakeTimers } from '../utils/use-fake-timers'; - -useFakeTimers(); type MockSendReplay = MockedFunction; type MockAddPerformanceEntries = MockedFunction; diff --git a/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts b/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts index 07ef281800c1..d143eaa5a5a7 100644 --- a/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/handleClick.test.ts @@ -1,11 +1,12 @@ +import { useFakeTimers } from '../../utils/use-fake-timers'; + +useFakeTimers(); + import type { Breadcrumb } from '@sentry/types'; import { BASE_TIMESTAMP } from '../..'; import { ClickDetector, ignoreElement } from '../../../src/coreHandlers/handleClick'; import type { ReplayContainer } from '../../../src/types'; - -vi.useFakeTimers(); - describe('Unit | coreHandlers | handleClick', () => { describe('ClickDetector', () => { beforeEach(() => { diff --git a/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts b/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts index ef81feef3a8e..ddf638c8498f 100644 --- a/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts @@ -13,8 +13,9 @@ import { beforeAddNetworkBreadcrumb } from '../../../src/coreHandlers/handleNetw import type { EventBufferArray } from '../../../src/eventBuffer/EventBufferArray'; import type { ReplayContainer, ReplayNetworkOptions } from '../../../src/types'; import { setupReplayContainer } from '../../utils/setupReplayContainer'; +import { useFakeTimers } from '../../utils/use-fake-timers'; -vi.useFakeTimers(); +useFakeTimers(); async function waitForReplayEventBuffer() { // Need one Promise.resolve() per await in the util functions diff --git a/packages/replay-internal/test/unit/coreHandlers/util/addBreadcrumbEvent.test.ts b/packages/replay-internal/test/unit/coreHandlers/util/addBreadcrumbEvent.test.ts index 1979556b3dc9..d82eb5f183c6 100644 --- a/packages/replay-internal/test/unit/coreHandlers/util/addBreadcrumbEvent.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/util/addBreadcrumbEvent.test.ts @@ -2,8 +2,9 @@ import { BASE_TIMESTAMP } from '../../..'; import { addBreadcrumbEvent } from '../../../../src/coreHandlers/util/addBreadcrumbEvent'; import type { EventBufferArray } from '../../../../src/eventBuffer/EventBufferArray'; import { setupReplayContainer } from '../../../utils/setupReplayContainer'; +import { useFakeTimers } from '../../../utils/use-fake-timers'; -vi.useFakeTimers(); +useFakeTimers(); describe('Unit | coreHandlers | util | addBreadcrumbEvent', function () { beforeEach(function () { @@ -23,12 +24,6 @@ describe('Unit | coreHandlers | util | addBreadcrumbEvent', function () { const replay = setupReplayContainer(); addBreadcrumbEvent(replay, breadcrumb); - await undefined; - await undefined; - await undefined; - await undefined; - await undefined; - expect((replay.eventBuffer as EventBufferArray).events).toEqual([ { type: 5, diff --git a/packages/replay-internal/test/unit/coreHandlers/util/fetchUtils.test.ts b/packages/replay-internal/test/unit/coreHandlers/util/fetchUtils.test.ts index 6d78a2583774..73a23e00babe 100644 --- a/packages/replay-internal/test/unit/coreHandlers/util/fetchUtils.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/util/fetchUtils.test.ts @@ -1,3 +1,9 @@ +import { useFakeTimers } from '../../../utils/use-fake-timers'; + +useFakeTimers(); + +import { vi } from 'vitest'; + import { _getResponseInfo } from '../../../../src/coreHandlers/util/fetchUtils'; describe('Unit | coreHandlers | util | fetchUtils', () => { @@ -112,15 +118,18 @@ describe('Unit | coreHandlers | util | fetchUtils', () => { text: () => new Promise(resolve => setTimeout(() => resolve('text body'), 1000)), } as unknown as Response; - const res = await _getResponseInfo( - true, - { - networkCaptureBodies: true, - networkResponseHeaders: [], - }, - response, - undefined, - ); + const [res] = await Promise.all([ + _getResponseInfo( + true, + { + networkCaptureBodies: true, + networkResponseHeaders: [], + }, + response, + undefined, + ), + vi.runAllTimersAsync(), + ]); expect(res).toEqual({ _meta: { warnings: ['BODY_PARSE_ERROR'] }, diff --git a/packages/replay-internal/test/unit/coreHandlers/util/networkUtils.test.ts b/packages/replay-internal/test/unit/coreHandlers/util/networkUtils.test.ts index 4a330081507a..33ea345ec609 100644 --- a/packages/replay-internal/test/unit/coreHandlers/util/networkUtils.test.ts +++ b/packages/replay-internal/test/unit/coreHandlers/util/networkUtils.test.ts @@ -1,5 +1,3 @@ -import { vi } from 'vitest'; - import { NETWORK_BODY_MAX_SIZE } from '../../../../src/constants'; import { buildNetworkRequestOrResponse, @@ -8,8 +6,9 @@ import { getFullUrl, parseContentLengthHeader, } from '../../../../src/coreHandlers/util/networkUtils'; +import { useFakeTimers } from '../../../utils/use-fake-timers'; -vi.useFakeTimers(); +useFakeTimers(); describe('Unit | coreHandlers | util | networkUtils', () => { describe('parseContentLengthHeader()', () => { diff --git a/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts b/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts index fd086eea6fa0..176de1c2d32e 100644 --- a/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts +++ b/packages/replay-internal/test/unit/util/createPerformanceEntry.test.ts @@ -1,6 +1,8 @@ import { vi } from 'vitest'; -vi.useFakeTimers(); +import { useFakeTimers } from '../../utils/use-fake-timers'; + +useFakeTimers(); vi.setSystemTime(new Date('2023-01-01')); vi.mock('@sentry/utils', async () => ({ diff --git a/packages/replay-internal/test/unit/util/debounce.test.ts b/packages/replay-internal/test/unit/util/debounce.test.ts index 59eb9e2a84fa..ae8ad4262053 100644 --- a/packages/replay-internal/test/unit/util/debounce.test.ts +++ b/packages/replay-internal/test/unit/util/debounce.test.ts @@ -1,7 +1,12 @@ +import { useFakeTimers } from '../../utils/use-fake-timers'; + +useFakeTimers(); + +import { vi } from 'vitest'; + import { debounce } from '../../../src/util/debounce'; describe('Unit | util | debounce', () => { - vi.useFakeTimers(); it('delay the execution of the passed callback function by the passed minDelay', () => { const callback = vi.fn(); const debouncedCallback = debounce(callback, 100); diff --git a/packages/replay-internal/test/unit/util/throttle.test.ts b/packages/replay-internal/test/unit/util/throttle.test.ts index 797558dea904..00d394d5b769 100644 --- a/packages/replay-internal/test/unit/util/throttle.test.ts +++ b/packages/replay-internal/test/unit/util/throttle.test.ts @@ -1,7 +1,8 @@ import { BASE_TIMESTAMP } from '../..'; import { SKIPPED, THROTTLED, throttle } from '../../../src/util/throttle'; +import { useFakeTimers } from '../../utils/use-fake-timers'; -vi.useFakeTimers(); +useFakeTimers(); describe('Unit | util | throttle', () => { it('executes when not hitting the limit', () => { diff --git a/packages/replay-internal/test/utils/use-fake-timers.ts b/packages/replay-internal/test/utils/use-fake-timers.ts index 57fda295cb59..2d5d43bdf338 100644 --- a/packages/replay-internal/test/utils/use-fake-timers.ts +++ b/packages/replay-internal/test/utils/use-fake-timers.ts @@ -1,5 +1,12 @@ import { vi } from 'vitest'; +vi.mock('@sentry-internal/browser-utils', async () => ({ + ...(await vi.importActual('@sentry-internal/browser-utils')), + setTimeout: (...args) => { + return setTimeout.call(global, ...args); + }, +})); + export function useFakeTimers(): void { vi.useFakeTimers(); } From 53d814bae805140b8e95fd290c36143066f446e4 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 22 May 2024 15:54:27 +0200 Subject: [PATCH 33/34] ref: Fix circular dependency checks & setup (#12159) I noticed we were getting some build warnings for circular dependency issues, which indicated that madge was not correctly capturing all issues. So I went ahead and updated madge to latest, and aligned the setup, which actually surfaced problems again more correctly. I also fixed all the circular dep issues that were raised there. We still have a bunch of types-related circular deps but these are hard to solve, so let's ignore this for now. --- .madgerc | 7 + package.json | 2 +- packages/bun/package.json | 9 +- packages/core/package.json | 7 - .../core/src/asyncContext/stackStrategy.ts | 2 +- packages/core/src/currentScopes.ts | 10 - packages/core/src/defaultScopes.ts | 13 + packages/core/src/envelope.ts | 3 +- packages/core/src/index.ts | 5 +- .../src/tracing/dynamicSamplingContext.ts | 14 +- packages/core/src/tracing/index.ts | 6 +- packages/core/src/utils/spanUtils.ts | 10 - packages/deno/package.json | 7 - packages/node/src/integrations/anr/index.ts | 3 +- packages/node/src/sdk/init.ts | 6 +- packages/node/src/utils/commonjs.ts | 4 + packages/node/src/utils/ensureIsWrapped.ts | 2 +- packages/types/src/event.ts | 2 +- packages/types/src/index.ts | 3 +- packages/types/src/options.ts | 2 +- packages/types/src/samplingcontext.ts | 47 ++ packages/types/src/transaction.ts | 48 -- packages/vercel-edge/package.json | 9 +- yarn.lock | 520 ++++++++---------- 24 files changed, 338 insertions(+), 403 deletions(-) create mode 100644 .madgerc create mode 100644 packages/core/src/defaultScopes.ts create mode 100644 packages/node/src/utils/commonjs.ts create mode 100644 packages/types/src/samplingcontext.ts diff --git a/.madgerc b/.madgerc new file mode 100644 index 000000000000..b407c6b4b14f --- /dev/null +++ b/.madgerc @@ -0,0 +1,7 @@ +{ + "detectiveOptions": { + "ts": { + "skipTypeImports": true + } + } +} diff --git a/package.json b/package.json index 88d43da80039..78bb0f5d0788 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "jest-environment-node": "^27.5.1", "jsdom": "^21.1.2", "lerna": "7.1.1", - "madge": "4.0.2", + "madge": "7.0.0", "nodemon": "^2.0.16", "npm-run-all": "^4.1.5", "prettier": "^3.1.1", diff --git a/packages/bun/package.json b/packages/bun/package.json index e522eb3ed4bb..e24277a9dda7 100644 --- a/packages/bun/package.json +++ b/packages/bun/package.json @@ -76,12 +76,5 @@ "volta": { "extends": "../../package.json" }, - "sideEffects": false, - "madge": { - "detectiveOptions": { - "ts": { - "skipTypeImports": true - } - } - } + "sideEffects": false } diff --git a/packages/core/package.json b/packages/core/package.json index 13b975c8458e..40381cc7b042 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -69,12 +69,5 @@ "volta": { "extends": "../../package.json" }, - "madge": { - "detectiveOptions": { - "ts": { - "skipTypeImports": true - } - } - }, "sideEffects": false } diff --git a/packages/core/src/asyncContext/stackStrategy.ts b/packages/core/src/asyncContext/stackStrategy.ts index 05160d685e89..aa075b644e85 100644 --- a/packages/core/src/asyncContext/stackStrategy.ts +++ b/packages/core/src/asyncContext/stackStrategy.ts @@ -1,6 +1,6 @@ import type { Client, Scope as ScopeInterface } from '@sentry/types'; import { isThenable } from '@sentry/utils'; -import { getDefaultCurrentScope, getDefaultIsolationScope } from '../currentScopes'; +import { getDefaultCurrentScope, getDefaultIsolationScope } from '../defaultScopes'; import { Scope } from '../scope'; import { getMainCarrier, getSentryCarrier } from './../carrier'; diff --git a/packages/core/src/currentScopes.ts b/packages/core/src/currentScopes.ts index 86978759252b..9472d48b71bf 100644 --- a/packages/core/src/currentScopes.ts +++ b/packages/core/src/currentScopes.ts @@ -5,16 +5,6 @@ import { getAsyncContextStrategy } from './asyncContext'; import { getMainCarrier } from './carrier'; import { Scope as ScopeClass } from './scope'; -/** Get the default current scope. */ -export function getDefaultCurrentScope(): Scope { - return getGlobalSingleton('defaultCurrentScope', () => new ScopeClass()); -} - -/** Get the default isolation scope. */ -export function getDefaultIsolationScope(): Scope { - return getGlobalSingleton('defaultIsolationScope', () => new ScopeClass()); -} - /** * Get the currently active scope. */ diff --git a/packages/core/src/defaultScopes.ts b/packages/core/src/defaultScopes.ts new file mode 100644 index 000000000000..d346ca7ad4dc --- /dev/null +++ b/packages/core/src/defaultScopes.ts @@ -0,0 +1,13 @@ +import type { Scope } from '@sentry/types'; +import { getGlobalSingleton } from '@sentry/utils'; +import { Scope as ScopeClass } from './scope'; + +/** Get the default current scope. */ +export function getDefaultCurrentScope(): Scope { + return getGlobalSingleton('defaultCurrentScope', () => new ScopeClass()); +} + +/** Get the default isolation scope. */ +export function getDefaultIsolationScope(): Scope { + return getGlobalSingleton('defaultIsolationScope', () => new ScopeClass()); +} diff --git a/packages/core/src/envelope.ts b/packages/core/src/envelope.ts index d0e5148574f2..dd0b814d0b07 100644 --- a/packages/core/src/envelope.ts +++ b/packages/core/src/envelope.ts @@ -22,7 +22,8 @@ import { getSdkMetadataForEnvelopeHeader, } from '@sentry/utils'; import { createSpanEnvelopeItem } from '@sentry/utils'; -import { type SentrySpan, getDynamicSamplingContextFromSpan } from './tracing'; +import { getDynamicSamplingContextFromSpan } from './tracing/dynamicSamplingContext'; +import type { SentrySpan } from './tracing/sentrySpan'; import { spanToJSON } from './utils/spanUtils'; /** diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e1bd05018031..f193f75bfe60 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -38,9 +38,11 @@ export { withScope, withIsolationScope, getClient, +} from './currentScopes'; +export { getDefaultCurrentScope, getDefaultIsolationScope, -} from './currentScopes'; +} from './defaultScopes'; export { setAsyncContextStrategy } from './asyncContext'; export { getMainCarrier } from './carrier'; export { makeSession, closeSession, updateSession } from './session'; @@ -69,7 +71,6 @@ export { handleCallbackErrors } from './utils/handleCallbackErrors'; export { parameterize } from './utils/parameterize'; export { spanToTraceHeader, - spanToBaggageHeader, spanToJSON, spanIsSampled, spanToTraceContext, diff --git a/packages/core/src/tracing/dynamicSamplingContext.ts b/packages/core/src/tracing/dynamicSamplingContext.ts index 2f69e9db6a2e..15486950649c 100644 --- a/packages/core/src/tracing/dynamicSamplingContext.ts +++ b/packages/core/src/tracing/dynamicSamplingContext.ts @@ -1,5 +1,9 @@ import type { Client, DynamicSamplingContext, Span } from '@sentry/types'; -import { addNonEnumerableProperty, dropUndefinedKeys } from '@sentry/utils'; +import { + addNonEnumerableProperty, + dropUndefinedKeys, + dynamicSamplingContextToSentryBaggageHeader, +} from '@sentry/utils'; import { DEFAULT_ENVIRONMENT } from '../constants'; import { getClient } from '../currentScopes'; @@ -93,3 +97,11 @@ export function getDynamicSamplingContextFromSpan(span: Span): Readonly { diff --git a/packages/types/src/samplingcontext.ts b/packages/types/src/samplingcontext.ts new file mode 100644 index 000000000000..ecce87d7fbc7 --- /dev/null +++ b/packages/types/src/samplingcontext.ts @@ -0,0 +1,47 @@ +import type { ExtractedNodeRequestData, WorkerLocation } from './misc'; +import type { SpanAttributes } from './span'; + +/** + * Context data passed by the user when starting a transaction, to be used by the tracesSampler method. + */ +export interface CustomSamplingContext { + [key: string]: any; +} + +/** + * Data passed to the `tracesSampler` function, which forms the basis for whatever decisions it might make. + * + * Adds default data to data provided by the user. See {@link Hub.startTransaction} + */ +export interface SamplingContext extends CustomSamplingContext { + /** + * Context data with which transaction being sampled was created. + * @deprecated This is duplicate data and will be removed eventually. + */ + transactionContext: { + name: string; + parentSampled?: boolean | undefined; + }; + + /** + * Sampling decision from the parent transaction, if any. + */ + parentSampled?: boolean; + + /** + * Object representing the URL of the current page or worker script. Passed by default when using the `BrowserTracing` + * integration. + */ + location?: WorkerLocation; + + /** + * Object representing the incoming request to a node server. Passed by default when using the TracingHandler. + */ + request?: ExtractedNodeRequestData; + + /** The name of the span being sampled. */ + name: string; + + /** Initial attributes that have been passed to the span being sampled. */ + attributes?: SpanAttributes; +} diff --git a/packages/types/src/transaction.ts b/packages/types/src/transaction.ts index 8f5109b44ba0..d21990941ae7 100644 --- a/packages/types/src/transaction.ts +++ b/packages/types/src/transaction.ts @@ -1,6 +1,3 @@ -import type { ExtractedNodeRequestData, WorkerLocation } from './misc'; -import type { SpanAttributes } from './span'; - /** * Data pulled from a `sentry-trace` header */ @@ -21,51 +18,6 @@ export interface TraceparentData { parentSampled?: boolean | undefined; } -/** - * Context data passed by the user when starting a transaction, to be used by the tracesSampler method. - */ -export interface CustomSamplingContext { - [key: string]: any; -} - -/** - * Data passed to the `tracesSampler` function, which forms the basis for whatever decisions it might make. - * - * Adds default data to data provided by the user. See {@link Hub.startTransaction} - */ -export interface SamplingContext extends CustomSamplingContext { - /** - * Context data with which transaction being sampled was created. - * @deprecated This is duplicate data and will be removed eventually. - */ - transactionContext: { - name: string; - parentSampled?: boolean | undefined; - }; - - /** - * Sampling decision from the parent transaction, if any. - */ - parentSampled?: boolean; - - /** - * Object representing the URL of the current page or worker script. Passed by default when using the `BrowserTracing` - * integration. - */ - location?: WorkerLocation; - - /** - * Object representing the incoming request to a node server. Passed by default when using the TracingHandler. - */ - request?: ExtractedNodeRequestData; - - /** The name of the span being sampled. */ - name: string; - - /** Initial attributes that have been passed to the span being sampled. */ - attributes?: SpanAttributes; -} - /** * Contains information about how the name of the transaction was determined. This will be used by the server to decide * whether or not to scrub identifiers from the transaction name, or replace the entire name with a placeholder. diff --git a/packages/vercel-edge/package.json b/packages/vercel-edge/package.json index 237e28c10c7c..b21bffb3ebba 100644 --- a/packages/vercel-edge/package.json +++ b/packages/vercel-edge/package.json @@ -73,12 +73,5 @@ "volta": { "extends": "../../package.json" }, - "sideEffects": false, - "madge": { - "detectiveOptions": { - "ts": { - "skipTypeImports": true - } - } - } + "sideEffects": false } diff --git a/yarn.lock b/yarn.lock index 34d7cf722fb5..9486c769c2c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1875,7 +1875,7 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.4", "@babel/parser@^7.18.10", "@babel/parser@^7.20.2", "@babel/parser@^7.4.5", "@babel/parser@^7.7.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.4", "@babel/parser@^7.18.10", "@babel/parser@^7.20.2", "@babel/parser@^7.4.5", "@babel/parser@^7.7.0": version "7.20.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2" integrity sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg== @@ -1890,6 +1890,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.15.tgz#eec9f36d8eaf0948bb88c87a46784b5ee9fd0c89" integrity sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg== +"@babel/parser@^7.21.8": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" + integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== + "@babel/parser@^7.21.9": version "7.22.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.4.tgz#a770e98fd785c231af9d93f6459d36770993fb32" @@ -3721,6 +3726,14 @@ enabled "2.0.x" kuler "^2.0.0" +"@dependents/detective-less@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@dependents/detective-less/-/detective-less-4.1.0.tgz#4a979ee7a6a79eb33602862d6a1263e30f98002e" + integrity sha512-KrkT6qO5NxqNfy68sBl6CTSoJ4SNDIS5iQArkibhlbGU4LaDukZ3q2HIkh8aUKDio6o4itU4xDR7t82Y2eP1Bg== + dependencies: + gonzales-pe "^4.3.0" + node-source-walk "^6.0.1" + "@discoveryjs/json-ext@0.5.7": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -8960,11 +8973,6 @@ debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.23.0.tgz#da1654c8a5332f4d1645b2d9a1c64193cae3aa3b" - integrity sha512-oqkNWyG2SLS7uTWLZf6Sr7Dm02gA5yxiz1RP87tvsmDsguVATdpVguHr4HoGOcFOpCvx9vtCSCyQUGfzq28YCw== - "@typescript-eslint/types@5.48.0": version "5.48.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.0.tgz#d725da8dfcff320aab2ac6f65c97b0df30058449" @@ -8993,7 +9001,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.62.0": +"@typescript-eslint/typescript-estree@5.62.0", "@typescript-eslint/typescript-estree@^5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== @@ -9019,19 +9027,6 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@^4.8.2": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.23.0.tgz#0753b292097523852428a6f5a1aa8ccc1aae6cd9" - integrity sha512-5Sty6zPEVZF5fbvrZczfmLCOcby3sfrSPu30qKoY1U3mca5/jvU5cwsPb/CO6Q3ByRjixTMIVsDkqwIxCf/dMw== - dependencies: - "@typescript-eslint/types" "4.23.0" - "@typescript-eslint/visitor-keys" "4.23.0" - debug "^4.1.1" - globby "^11.0.1" - is-glob "^4.0.1" - semver "^7.3.2" - tsutils "^3.17.1" - "@typescript-eslint/utils@5.48.0": version "5.48.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.0.tgz#eee926af2733f7156ad8d15e51791e42ce300273" @@ -9073,14 +9068,6 @@ "@typescript-eslint/typescript-estree" "6.7.4" semver "^7.5.4" -"@typescript-eslint/visitor-keys@4.23.0": - version "4.23.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz#7215cc977bd3b4ef22467b9023594e32f9e4e455" - integrity sha512-5PNe5cmX9pSifit0H+nPoQBXdbNzi5tOEec+3riK+ku4e3er37pKxMKDH5Ct5Y4fhWxcD4spnlYjxi9vXbSpwg== - dependencies: - "@typescript-eslint/types" "4.23.0" - eslint-visitor-keys "^2.0.0" - "@typescript-eslint/visitor-keys@5.48.0": version "5.48.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz#4446d5e7f6cadde7140390c0e284c8702d944904" @@ -10116,7 +10103,7 @@ ansicolors@~0.2.1: resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" integrity sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8= -any-promise@^1.0.0: +any-promise@^1.0.0, any-promise@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= @@ -10505,10 +10492,10 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-module-types@^2.3.2, ast-module-types@^2.4.0, ast-module-types@^2.7.0, ast-module-types@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/ast-module-types/-/ast-module-types-2.7.1.tgz#3f7989ef8dfa1fdb82dfe0ab02bdfc7c77a57dd3" - integrity sha512-Rnnx/4Dus6fn7fTqdeLEAn5vUll5w7/vts0RN608yFa6si/rDOUonlIIiwugHBFWjylHjxm9owoSZn71KwG4gw== +ast-module-types@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ast-module-types/-/ast-module-types-5.0.0.tgz#32b2b05c56067ff38e95df66f11d6afd6c9ba16b" + integrity sha512-JvqziE0Wc0rXQfma0HZC/aY7URXHFuZV84fJRtP8u+lhp0JYCNd5wJzVXP45t0PH0Mej3ynlzvdyITYIu0G4LQ== ast-types@0.13.3: version "0.13.3" @@ -12748,7 +12735,7 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0, color-name@~1.1.4: +color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== @@ -12842,7 +12829,12 @@ commander@7.2.0, commander@^7.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== -commander@^2.16.0, commander@^2.20.0, commander@^2.20.3, commander@^2.6.0, commander@^2.8.1: +commander@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0, commander@^2.20.3, commander@^2.6.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -12852,11 +12844,6 @@ commander@^4.0.0, commander@^4.1.1: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - commander@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" @@ -13660,13 +13647,6 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== -decomment@^0.9.3: - version "0.9.4" - resolved "https://registry.yarnpkg.com/decomment/-/decomment-0.9.4.tgz#fa40335bd90e3826d5c1984276e390525ff856d5" - integrity sha512-8eNlhyI5cSU4UbBlrtagWpR03dqXcE5IR9zpe7PnO6UzReXDskucsD8usgrzUmQ6qJ3N82aws/p/mu/jqbURWw== - dependencies: - esprima "4.0.1" - decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" @@ -13802,16 +13782,15 @@ dependency-graph@^0.11.0: resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== -dependency-tree@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/dependency-tree/-/dependency-tree-8.1.0.tgz#1b896a0418bd7ba3e6d55c39bb664452a001579f" - integrity sha512-YKFK+1KXJOqVpsW6MkrIl/DyiW+KVG25V8NfRs27ANe+oSeCkQx2ROW1mBpp1bcm++5zj3Xv8wyFxHgX6TbM1w== +dependency-tree@^10.0.9: + version "10.0.9" + resolved "https://registry.yarnpkg.com/dependency-tree/-/dependency-tree-10.0.9.tgz#0c6c0dbeb0c5ec2cf83bf755f30e9cb12e7b4ac7" + integrity sha512-dwc59FRIsht+HfnTVM0BCjJaEWxdq2YAvEDy4/Hn6CwS3CBWMtFnL3aZGAkQn3XCYxk/YcTDE4jX2Q7bFTwCjA== dependencies: - commander "^2.20.3" - debug "^4.3.1" - filing-cabinet "^3.0.0" - precinct "^7.0.0" - typescript "^3.9.7" + commander "^10.0.1" + filing-cabinet "^4.1.6" + precinct "^11.0.5" + typescript "^5.0.4" deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" @@ -13866,92 +13845,70 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== -detective-amd@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detective-amd/-/detective-amd-3.1.0.tgz#92daee3214a0ca4522646cf333cac90a3fca6373" - integrity sha512-G7wGWT6f0VErjUkE2utCm7IUshT7nBh7aBBH2VBOiY9Dqy2DMens5iiOvYCuhstoIxRKLrnOvVAz4/EyPIAjnw== +detective-amd@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/detective-amd/-/detective-amd-5.0.2.tgz#579900f301c160efe037a6377ec7e937434b2793" + integrity sha512-XFd/VEQ76HSpym80zxM68ieB77unNuoMwopU2TFT/ErUk5n4KvUTwW4beafAVUugrjV48l4BmmR0rh2MglBaiA== dependencies: - ast-module-types "^2.7.0" + ast-module-types "^5.0.0" escodegen "^2.0.0" - get-amd-module-type "^3.0.0" - node-source-walk "^4.0.0" + get-amd-module-type "^5.0.1" + node-source-walk "^6.0.1" -detective-cjs@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/detective-cjs/-/detective-cjs-3.1.1.tgz#18da3e39a002d2098a1123d45ce1de1b0d9045a0" - integrity sha512-JQtNTBgFY6h8uT6pgph5QpV3IyxDv+z3qPk/FZRDT9TlFfm5dnRtpH39WtQEr1khqsUxVqXzKjZHpdoQvQbllg== - dependencies: - ast-module-types "^2.4.0" - node-source-walk "^4.0.0" - -detective-es6@^2.1.0, detective-es6@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/detective-es6/-/detective-es6-2.2.0.tgz#8f2baba3f8cd90a5cfd748f5ac436f0158ed2585" - integrity sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ== +detective-cjs@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/detective-cjs/-/detective-cjs-5.0.1.tgz#836ad51c6de4863efc7c419ec243694f760ff8b2" + integrity sha512-6nTvAZtpomyz/2pmEmGX1sXNjaqgMplhQkskq2MLrar0ZAIkHMrDhLXkRiK2mvbu9wSWr0V5/IfiTrZqAQMrmQ== dependencies: - node-source-walk "^4.0.0" + ast-module-types "^5.0.0" + node-source-walk "^6.0.0" -detective-less@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/detective-less/-/detective-less-1.0.2.tgz#a68af9ca5f69d74b7d0aa190218b211d83b4f7e3" - integrity sha512-Rps1xDkEEBSq3kLdsdnHZL1x2S4NGDcbrjmd4q+PykK5aJwDdP5MBgrJw1Xo+kyUHuv3JEzPqxr+Dj9ryeDRTA== +detective-es6@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/detective-es6/-/detective-es6-4.0.1.tgz#38d5d49a6d966e992ef8f2d9bffcfe861a58a88a" + integrity sha512-k3Z5tB4LQ8UVHkuMrFOlvb3GgFWdJ9NqAa2YLUU/jTaWJIm+JJnEh4PsMc+6dfT223Y8ACKOaC0qcj7diIhBKw== dependencies: - debug "^4.0.0" - gonzales-pe "^4.2.3" - node-source-walk "^4.0.0" + node-source-walk "^6.0.1" -detective-postcss@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detective-postcss/-/detective-postcss-4.0.0.tgz#24e69b465e5fefe7a6afd05f7e894e34595dbf51" - integrity sha512-Fwc/g9VcrowODIAeKRWZfVA/EufxYL7XfuqJQFroBKGikKX83d2G7NFw6kDlSYGG3LNQIyVa+eWv1mqre+v4+A== +detective-postcss@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/detective-postcss/-/detective-postcss-6.1.3.tgz#51a2d4419327ad85d0af071c7054c79fafca7e73" + integrity sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw== dependencies: - debug "^4.1.1" is-url "^1.2.4" - postcss "^8.1.7" - postcss-values-parser "^2.0.1" + postcss "^8.4.23" + postcss-values-parser "^6.0.2" -detective-sass@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/detective-sass/-/detective-sass-3.0.1.tgz#496b819efd1f5c4dd3f0e19b43a8634bdd6927c4" - integrity sha512-oSbrBozRjJ+QFF4WJFbjPQKeakoaY1GiR380NPqwdbWYd5wfl5cLWv0l6LsJVqrgWfFN1bjFqSeo32Nxza8Lbw== +detective-sass@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/detective-sass/-/detective-sass-5.0.3.tgz#63e54bc9b32f4bdbd9d5002308f9592a3d3a508f" + integrity sha512-YsYT2WuA8YIafp2RVF5CEfGhhyIVdPzlwQgxSjK+TUm3JoHP+Tcorbk3SfG0cNZ7D7+cYWa0ZBcvOaR0O8+LlA== dependencies: - debug "^4.1.1" - gonzales-pe "^4.2.3" - node-source-walk "^4.0.0" + gonzales-pe "^4.3.0" + node-source-walk "^6.0.1" -detective-scss@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detective-scss/-/detective-scss-2.0.1.tgz#06f8c21ae6dedad1fccc26d544892d968083eaf8" - integrity sha512-VveyXW4WQE04s05KlJ8K0bG34jtHQVgTc9InspqoQxvnelj/rdgSAy7i2DXAazyQNFKlWSWbS+Ro2DWKFOKTPQ== +detective-scss@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/detective-scss/-/detective-scss-4.0.3.tgz#79758baa0158f72bfc4481eb7e21cc3b5f1ea6eb" + integrity sha512-VYI6cHcD0fLokwqqPFFtDQhhSnlFWvU614J42eY6G0s8c+MBhi9QAWycLwIOGxlmD8I/XvGSOUV1kIDhJ70ZPg== dependencies: - debug "^4.1.1" - gonzales-pe "^4.2.3" - node-source-walk "^4.0.0" + gonzales-pe "^4.3.0" + node-source-walk "^6.0.1" -detective-stylus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detective-stylus/-/detective-stylus-1.0.0.tgz#50aee7db8babb990381f010c63fabba5b58e54cd" - integrity sha1-UK7n24uruZA4HwEMY/q7pbWOVM0= - -detective-typescript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/detective-typescript/-/detective-typescript-6.0.0.tgz#394062118d7c7da53425647ca41e0081169aa2b3" - integrity sha512-vTidcSDK3QostdbrH2Rwf9FhvrgJ4oIaVw5jbolgruTejexk6nNa9DShGpuS8CFVDb1IP86jct5BaZt1wSxpkA== - dependencies: - "@typescript-eslint/typescript-estree" "^4.8.2" - ast-module-types "^2.7.1" - node-source-walk "^4.2.0" - typescript "^3.9.7" +detective-stylus@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detective-stylus/-/detective-stylus-4.0.0.tgz#ce97b6499becdc291de7b3c11df8c352c1eee46e" + integrity sha512-TfPotjhszKLgFBzBhTOxNHDsutIxx9GTWjrL5Wh7Qx/ydxKhwUrlSFeLIn+ZaHPF+h0siVBkAQSuy6CADyTxgQ== -detective-typescript@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/detective-typescript/-/detective-typescript-7.0.0.tgz#8c8917f2e51d9e4ee49821abf759ff512dd897f2" - integrity sha512-y/Ev98AleGvl43YKTNcA2Q+lyFmsmCfTTNWy4cjEJxoLkbobcXtRS0Kvx06daCgr2GdtlwLfNzL553BkktfJoA== +detective-typescript@^11.1.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/detective-typescript/-/detective-typescript-11.2.0.tgz#5b1450b518cb84b6cfb98ea72d5edd9660668e1b" + integrity sha512-ARFxjzizOhPqs1fYC/2NMC3N4jrQ6HvVflnXBTRqNEqJuXwyKLRr9CrJwkRcV/SnZt1sNXgsF6FPm0x57Tq0rw== dependencies: - "@typescript-eslint/typescript-estree" "^4.8.2" - ast-module-types "^2.7.1" - node-source-walk "^4.2.0" - typescript "^3.9.7" + "@typescript-eslint/typescript-estree" "^5.62.0" + ast-module-types "^5.0.0" + node-source-walk "^6.0.2" + typescript "^5.4.4" deterministic-object-hash@^1.3.1: version "1.3.1" @@ -15093,18 +15050,18 @@ enhanced-resolve@^5.10.0, enhanced-resolve@^5.16.0: graceful-fs "^4.2.4" tapable "^2.2.0" -enhanced-resolve@^5.15.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== +enhanced-resolve@^5.14.1: + version "5.16.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz#e8bc63d51b826d6f1cbc0a150ecb5a8b0c62e567" + integrity sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" -enhanced-resolve@^5.3.2: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== +enhanced-resolve@^5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -15989,7 +15946,7 @@ espree@^7.3.0, espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" -esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: +esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -16562,24 +16519,23 @@ filesize@^9.0.11: resolved "https://registry.yarnpkg.com/filesize/-/filesize-9.0.11.tgz#4ac3a42c084232dd9b2a1da0107f32d42fcfa5e4" integrity sha512-gTAiTtI0STpKa5xesyTA9hA3LX4ga8sm2nWRcffEa1L/5vQwb4mj2MdzMkoHoGv4QzfDshQZuYscQSf8c4TKOA== -filing-cabinet@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/filing-cabinet/-/filing-cabinet-3.0.0.tgz#08f9ceec5134f4a662926dd45b8a26eca1b5f622" - integrity sha512-o8Qac5qxZ1uVidR4Sd7ZQbbqObFZlqXU4xu1suAYg9PQPcQFNTzOmxQa/MehIDMgIvXHTb42mWPNV9l3eHBPSw== +filing-cabinet@^4.1.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/filing-cabinet/-/filing-cabinet-4.2.0.tgz#bd81241edce6e0c051882bef7b69ffa4c017baf9" + integrity sha512-YZ21ryzRcyqxpyKggdYSoXx//d3sCJzM3lsYoaeg/FyXdADGJrUl+BW1KIglaVLJN5BBcMtWylkygY8zBp2MrQ== dependencies: app-module-path "^2.2.0" - commander "^2.20.3" - debug "^4.3.1" - decomment "^0.9.3" - enhanced-resolve "^5.3.2" + commander "^10.0.1" + enhanced-resolve "^5.14.1" is-relative-path "^1.0.2" - module-definition "^3.3.1" - module-lookup-amd "^7.0.0" - resolve "^1.19.0" - resolve-dependency-path "^2.0.0" - sass-lookup "^3.0.0" - stylus-lookup "^3.0.1" - typescript "^3.9.7" + module-definition "^5.0.1" + module-lookup-amd "^8.0.5" + resolve "^1.22.3" + resolve-dependency-path "^3.0.2" + sass-lookup "^5.0.1" + stylus-lookup "^5.0.1" + tsconfig-paths "^4.2.0" + typescript "^5.0.4" fill-range@^4.0.0: version "4.0.0" @@ -16803,11 +16759,6 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -flatten@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" - integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== - flush-write-stream@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -17162,13 +17113,13 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-amd-module-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-amd-module-type/-/get-amd-module-type-3.0.0.tgz#bb334662fa04427018c937774570de495845c288" - integrity sha512-99Q7COuACPfVt18zH9N4VAMyb81S6TUgJm2NgV6ERtkh9VIkAaByZkW530wl3lLN5KTtSrK9jVLxYsoP5hQKsw== +get-amd-module-type@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-amd-module-type/-/get-amd-module-type-5.0.1.tgz#bef38ea3674e1aa1bda9c59c8b0da598582f73f2" + integrity sha512-jb65zDeHyDjFR1loOVk0HQGM5WNwoGB8aLWy3LKCieMKol0/ProHkhO2X1JxojuN10vbz1qNn09MJ7tNp7qMzw== dependencies: - ast-module-types "^2.3.2" - node-source-walk "^4.0.0" + ast-module-types "^5.0.0" + node-source-walk "^6.0.1" get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" @@ -17442,7 +17393,7 @@ glob@^5.0.10: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.0.4, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@~7.2.0: +glob@^7.0.0, glob@^7.0.4, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@^7.2.3, glob@~7.2.0: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -17540,7 +17491,7 @@ globby@10.0.0: merge2 "^1.2.3" slash "^3.0.0" -globby@11, globby@11.1.0, globby@^11.0.1, globby@^11.0.3, globby@^11.1.0: +globby@11, globby@11.1.0, globby@^11.0.3, globby@^11.1.0: version "11.1.0" resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -17591,7 +17542,7 @@ globrex@^0.1.2: resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== -gonzales-pe@^4.2.3: +gonzales-pe@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ== @@ -17719,13 +17670,6 @@ graphql@^16.3.0: resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07" integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw== -graphviz@0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/graphviz/-/graphviz-0.0.9.tgz#0bbf1df588c6a92259282da35323622528c4bbc4" - integrity sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg== - dependencies: - temp "~0.4.0" - gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" @@ -18626,11 +18570,6 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -19351,6 +19290,11 @@ is-unicode-supported@^1.1.0, is-unicode-supported@^1.3.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714" integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== +is-url-superb@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-url-superb/-/is-url-superb-4.0.0.tgz#b54d1d2499bb16792748ac967aa3ecb41a33a8c2" + integrity sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA== + is-url@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" @@ -21199,32 +21143,23 @@ lz-string@^1.4.4: resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= -madge@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/madge/-/madge-4.0.2.tgz#56a3aff8021a5844f8713e0789f6ee94095f2f41" - integrity sha512-l5bnA2dvyk0azLKDbOTCI+wDZ6nB007PhvPdmiYlPmqwVi49JPbhQrH/t4u8E6Akp3gwji1GZuA+v/F5q6yoWQ== +madge@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/madge/-/madge-7.0.0.tgz#64b1762033b0f969caa7e5853004b6850e8430bb" + integrity sha512-x9eHkBWoCJ2B8yGesWf8LRucarkbH5P3lazqgvmxe4xn5U2Meyfu906iG9mBB1RnY/f4D+gtELWdiz1k6+jAZA== dependencies: - chalk "^4.1.0" - commander "^6.2.1" + chalk "^4.1.2" + commander "^7.2.0" commondir "^1.0.1" - debug "^4.0.1" - dependency-tree "^8.0.0" - detective-amd "^3.0.1" - detective-cjs "^3.1.1" - detective-es6 "^2.1.0" - detective-less "^1.0.2" - detective-postcss "^4.0.0" - detective-sass "^3.0.1" - detective-scss "^2.0.1" - detective-stylus "^1.0.0" - detective-typescript "^7.0.0" - graphviz "0.0.9" - ora "^5.1.0" + debug "^4.3.4" + dependency-tree "^10.0.9" + ora "^5.4.1" pluralize "^8.0.0" - precinct "^7.0.0" - pretty-ms "^7.0.0" - rc "^1.2.7" - typescript "^3.9.5" + precinct "^11.0.5" + pretty-ms "^7.0.1" + rc "^1.2.8" + stream-to-array "^2.3.0" + ts-graphviz "^1.8.1" walkdir "^0.4.1" magic-string@0.26.2: @@ -22409,28 +22344,27 @@ modify-values@^1.0.1: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -module-definition@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/module-definition/-/module-definition-3.3.1.tgz#fedef71667713e36988b93d0626a4fe7b35aebfc" - integrity sha512-kLidGPwQ2yq484nSD+D3JoJp4Etc0Ox9P0L34Pu/cU4X4HcG7k7p62XI5BBuvURWMRX3RPyuhOcBHbKus+UH4A== +module-definition@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/module-definition/-/module-definition-5.0.1.tgz#62d1194e5d5ea6176b7dc7730f818f466aefa32f" + integrity sha512-kvw3B4G19IXk+BOXnYq/D/VeO9qfHaapMeuS7w7sNUqmGaA6hywdFHMi+VWeR9wUScXM7XjoryTffCZ5B0/8IA== dependencies: - ast-module-types "^2.7.1" - node-source-walk "^4.0.0" + ast-module-types "^5.0.0" + node-source-walk "^6.0.1" module-details-from-path@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== -module-lookup-amd@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/module-lookup-amd/-/module-lookup-amd-7.0.1.tgz#d67c1a93f2ff8e38b8774b99a638e9a4395774b2" - integrity sha512-w9mCNlj0S8qviuHzpakaLVc+/7q50jl9a/kmJ/n8bmXQZgDPkQHnPBb8MUOYh3WpAYkXuNc2c+khsozhIp/amQ== +module-lookup-amd@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/module-lookup-amd/-/module-lookup-amd-8.0.5.tgz#aaeea41979105b49339380ca3f7d573db78c32a5" + integrity sha512-vc3rYLjDo5Frjox8NZpiyLXsNWJ5BWshztc/5KSOMzpg9k5cHH652YsJ7VKKmtM4SvaxuE9RkrYGhiSjH3Ehow== dependencies: - commander "^2.8.1" - debug "^4.1.0" - glob "^7.1.6" - requirejs "^2.3.5" + commander "^10.0.1" + glob "^7.2.3" + requirejs "^2.3.6" requirejs-config-file "^4.0.0" moment@~2.30.1: @@ -23072,12 +23006,12 @@ node-schedule@^2.1.1: long-timeout "0.1.1" sorted-array-functions "^1.3.0" -node-source-walk@^4.0.0, node-source-walk@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-4.2.0.tgz#c2efe731ea8ba9c03c562aa0a9d984e54f27bc2c" - integrity sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA== +node-source-walk@^6.0.0, node-source-walk@^6.0.1, node-source-walk@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-6.0.2.tgz#ba81bc4bc0f6f05559b084bea10be84c3f87f211" + integrity sha512-jn9vOIK/nfqoFCcpK89/VCVaLg1IHE6UVfDOzvqmANaJ/rWCTEdH8RZ1V278nv2jr36BJdyQXIAavBLXpzdlag== dependencies: - "@babel/parser" "^7.0.0" + "@babel/parser" "^7.21.8" node-watch@0.7.3: version "0.7.3" @@ -25041,14 +24975,14 @@ postcss-value-parser@^4.1.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss-values-parser@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" - integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== +postcss-values-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz#636edc5b86c953896f1bb0d7a7a6615df00fb76f" + integrity sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw== dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" + color-name "^1.1.4" + is-url-superb "^4.0.0" + quote-unquote "^1.0.0" postcss@8.4.14: version "8.4.14" @@ -25068,7 +25002,7 @@ postcss@8.4.31, postcss@^8.4.27: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.1.10, postcss@^8.1.7, postcss@^8.2.15, postcss@^8.3.7: +postcss@^8.1.10, postcss@^8.2.15, postcss@^8.3.7: version "8.4.24" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df" integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== @@ -25086,6 +25020,15 @@ postcss@^8.2.14, postcss@^8.4.7, postcss@^8.4.8: picocolors "^1.0.0" source-map-js "^1.1.0" +postcss@^8.4.23, postcss@^8.4.36: + version "8.4.38" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + postcss@^8.4.32: version "8.4.32" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9" @@ -25095,15 +25038,6 @@ postcss@^8.4.32: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.4.36: - version "8.4.38" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" - integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.2.0" - postgres-array@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" @@ -25176,24 +25110,23 @@ prebuild-install@^7.1.1: tar-fs "^2.0.0" tunnel-agent "^0.6.0" -precinct@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/precinct/-/precinct-7.1.0.tgz#a0311e0b59029647eaf57c2d30b8efa9c85d129a" - integrity sha512-I1RkW5PX51/q6Xl39//D7x9NgaKNGHpR5DCNaoxP/b2+KbzzXDNhauJUMV17KSYkJA41CSpwYUPRtRoNxbshWA== - dependencies: - commander "^2.20.3" - debug "^4.3.1" - detective-amd "^3.0.1" - detective-cjs "^3.1.1" - detective-es6 "^2.2.0" - detective-less "^1.0.2" - detective-postcss "^4.0.0" - detective-sass "^3.0.1" - detective-scss "^2.0.1" - detective-stylus "^1.0.0" - detective-typescript "^6.0.0" - module-definition "^3.3.1" - node-source-walk "^4.2.0" +precinct@^11.0.5: + version "11.0.5" + resolved "https://registry.yarnpkg.com/precinct/-/precinct-11.0.5.tgz#3e15b3486670806f18addb54b8533e23596399ff" + integrity sha512-oHSWLC8cL/0znFhvln26D14KfCQFFn4KOLSw6hmLhd+LQ2SKt9Ljm89but76Pc7flM9Ty1TnXyrA2u16MfRV3w== + dependencies: + "@dependents/detective-less" "^4.1.0" + commander "^10.0.1" + detective-amd "^5.0.2" + detective-cjs "^5.0.1" + detective-es6 "^4.0.1" + detective-postcss "^6.1.3" + detective-sass "^5.0.3" + detective-scss "^4.0.3" + detective-stylus "^4.0.0" + detective-typescript "^11.1.0" + module-definition "^5.0.1" + node-source-walk "^6.0.2" preferred-pm@^3.1.2: version "3.1.2" @@ -25270,7 +25203,7 @@ pretty-format@^29.7.0: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-ms@^7.0.0: +pretty-ms@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-7.0.1.tgz#7d903eaab281f7d8e03c66f867e239dc32fb73e8" integrity sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q== @@ -25628,6 +25561,11 @@ qunit@~2.19.2: node-watch "0.7.3" tiny-glob "0.2.9" +quote-unquote@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/quote-unquote/-/quote-unquote-1.0.0.tgz#67a9a77148effeaf81a4d428404a710baaac8a0b" + integrity sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg== + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -26352,7 +26290,7 @@ requirejs-config-file@^4.0.0: esprima "^4.0.0" stringify-object "^3.2.1" -requirejs@^2.3.5: +requirejs@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9" integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== @@ -26384,10 +26322,10 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" -resolve-dependency-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz#11700e340717b865d216c66cabeb4a2a3c696736" - integrity sha512-DIgu+0Dv+6v2XwRaNWnumKu7GPufBBOr5I1gRPJHkvghrfCGOooJODFvgFimX/KRxk9j0whD2MnKHzM1jYvk9w== +resolve-dependency-path@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/resolve-dependency-path/-/resolve-dependency-path-3.0.2.tgz#012816717bcbe8b846835da11af9d2beb5acef50" + integrity sha512-Tz7zfjhLfsvR39ADOSk9us4421J/1ztVBo4rWUkF38hgHK5m0OCZ3NxFVpqHRkjctnwVa15igEUHFJp8MCS7vA== resolve-dir@^1.0.0, resolve-dir@^1.0.1: version "1.0.1" @@ -26486,7 +26424,7 @@ resolve@1.22.1, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.1 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@1.22.8, resolve@^1.22.8: +resolve@1.22.8, resolve@^1.22.3, resolve@^1.22.8: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -26942,12 +26880,12 @@ sass-loader@13.0.2: klona "^2.0.4" neo-async "^2.6.2" -sass-lookup@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/sass-lookup/-/sass-lookup-3.0.0.tgz#3b395fa40569738ce857bc258e04df2617c48cac" - integrity sha512-TTsus8CfFRn1N44bvdEai1no6PqdmDiQUiqW5DlpmtT+tYnIt1tXtDIph5KA1efC+LmioJXSnCtUVpcK9gaKIg== +sass-lookup@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/sass-lookup/-/sass-lookup-5.0.1.tgz#1f01d7ff21e09d8c9dcf8d05b3fca28f2f96e6ed" + integrity sha512-t0X5PaizPc2H4+rCwszAqHZRtr4bugo4pgiCvrBFvIX0XFxnr29g77LJcpyj9A0DcKf7gXMLcgvRjsonYI6x4g== dependencies: - commander "^2.16.0" + commander "^10.0.1" sass@1.54.4: version "1.54.4" @@ -27995,6 +27933,13 @@ stream-slice@^0.1.2: resolved "https://registry.yarnpkg.com/stream-slice/-/stream-slice-0.1.2.tgz#2dc4f4e1b936fb13f3eb39a2def1932798d07a4b" integrity sha1-LcT04bk2+xPz6zmi3vGTJ5jQeks= +stream-to-array@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" + integrity sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA== + dependencies: + any-promise "^1.1.0" + streamsearch@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" @@ -28305,13 +28250,12 @@ stylus-loader@7.0.0: klona "^2.0.5" normalize-path "^3.0.0" -stylus-lookup@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd" - integrity sha512-oEQGHSjg/AMaWlKe7gqsnYzan8DLcGIHe0dUaFkucZZ14z4zjENRlQMCHT4FNsiWnJf17YN9OvrCfCoi7VvOyg== +stylus-lookup@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-5.0.1.tgz#3c4d116c3b1e8e1a8169c0d9cd20e608595560f4" + integrity sha512-tLtJEd5AGvnVy4f9UHQMw4bkJJtaAcmo54N+ovQBjDY3DuWyK9Eltxzr5+KG0q4ew6v2EHyuWWNnHeiw/Eo7rQ== dependencies: - commander "^2.8.1" - debug "^4.1.0" + commander "^10.0.1" stylus@0.59.0, stylus@^0.59.0: version "0.59.0" @@ -28583,11 +28527,6 @@ temp@0.9.4: mkdirp "^0.5.1" rimraf "~2.6.2" -temp@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.4.0.tgz#671ad63d57be0fe9d7294664b3fc400636678a60" - integrity sha1-ZxrWPVe+D+nXKUZks/xABjZnimA= - terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -29053,6 +28992,11 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== +ts-graphviz@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/ts-graphviz/-/ts-graphviz-1.8.2.tgz#6c4768d05f8a36e37abe34855ffe89a4c4bd96cc" + integrity sha512-5YhbFoHmjxa7pgQLkB07MtGnGJ/yhvjmc9uhsnDBEICME6gkPf83SBwLDQqGDoCa3XzUMWLk1AU2Wn1u1naDtA== + ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" @@ -29115,6 +29059,15 @@ tsconfig-paths@^4.1.2: minimist "^1.2.6" strip-bom "^3.0.0" +tsconfig-paths@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + tslib@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" @@ -29135,7 +29088,7 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3 resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.2.tgz#1b6f07185c881557b0ffa84b111a0106989e8338" integrity sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA== -tsutils@^3.17.1, tsutils@^3.21.0: +tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== @@ -29300,10 +29253,10 @@ typescript@4.9.5, typescript@^4.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== -typescript@^3.9.5, typescript@^3.9.7: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== +typescript@^5.0.4, typescript@^5.4.4: + version "5.4.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" + integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== typescript@next: version "5.2.0-dev.20230530" @@ -29447,11 +29400,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" From 14d1c945320069f03871593caf2bc36b5cdeb368 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 22 May 2024 14:39:23 +0200 Subject: [PATCH 34/34] meta(changelog): Update changelog for v8.3.0 --- CHANGELOG.md | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ee1edd5991c..e4a883477367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,63 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +## 8.3.0 + +### Important Changes + +- **Better Node Framework Span Data** + +This release improves data quality of spans emitted by Express, Fastify, Connect, Koa, Nest.js and Hapi. + +- feat(node): Ensure connect spans have better data (#12130) +- feat(node): Ensure express spans have better data (#12107) +- feat(node): Ensure fastify spans have better data (#12106) +- feat(node): Ensure hapi spans have better data (#12140) +- feat(node): Ensure koa spans have better data (#12108) +- feat(node): Ensure Nest.js spans have better data (#12139) +- feat(deps): Bump @opentelemetry/instrumentation-express from 0.38.0 to 0.39.0 (#12079) + +- **feat(node): No-code init via `--import=@sentry/node/init` (#11999)** + +When using Sentry in ESM mode, you can now use Sentry without manually calling init like this: + +```bash + SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 node --import=@sentry/node/init app.mjs +``` + +When using CommonJS, you can do: + +```bash + SENTRY_DSN=https://examplePublicKey@o0.ingest.sentry.io/0 node --require=@sentry/node/init app.js +``` + +### Other Changes + +- chore: Align and update MIT license dates (#12143) +- chore: Resolve or postpone a random assortment of TODOs (#11977) +- doc(migration): Add entry for runWithAsyncContext (#12153) +- docs: Add migration docs to point out that default import does not work (#12100) +- docs(sveltekit): process.env.SENTRY_AUTH_TOKEN (#12118) +- feat(browser): Ensure `browserProfilingIntegration` is published to CDN (#12158) +- feat(google-cloud): Expose ESM build (#12149) +- feat(nextjs): Ignore Prisma critical dependency warnings (#12144) +- feat(node): Add app.free_memory info to events (#12150) +- feat(node): Do not create GraphQL resolver spans by default (#12097) +- feat(node): Use `node:` prefix for node built-ins (#11895) +- feat(replay): Use unwrapped `setTimeout` to avoid e.g. angular change detection (#11924) +- fix(core): Add dsn to span envelope header (#12096) +- fix(feedback): Improve feedback border color in dark-mode, and prevent auto-dark mode when a theme is picked (#12126) +- fix(feedback): Set optionOverrides to be optional in TS definition (#12125) +- fix(nextjs): Don't put `undefined` values in props (#12131) +- fix(nextjs): Fix legacy configuration method detection for emitting warning (#12136) +- fix(node): Ensure fetch/http breadcrumbs are created correctly (#12137) +- fix(node): Update `@prisma/instrumentation` from 5.13.0 to 5.14.0 (#12081) +- ref(node): Add log for running in ESM/CommonJS mode (#12134) +- ref(node): Handle failing hook registration gracefully (#12135) +- ref(node): Only show instrumentation warning when tracing is enabled (#12141) + +Work in this release contributed by @pboling. Thank you for your contribution! + ## 8.2.1 - fix(aws-serverless): Fix build of lambda layer (#12083)