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/.size-limit.js b/.size-limit.js index dfd1210bc735..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,24 +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', - 'async_hooks', - 'child_process', - 'fs', - 'os', - 'path', - 'inspector', - 'worker_threads', - 'http', - 'stream', - 'zlib', - 'net', - 'tls', - 'module', - ], + ignore: [...builtinModules, ...nodePrefixedBuiltinModules], gzip: true, limit: '180 KB', }, @@ -216,25 +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', - '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', }, 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) 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/MIGRATION.md b/MIGRATION.md index 14e5bdd79a93..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`, @@ -1323,6 +1340,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 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/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-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/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/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/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..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 @@ -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), @@ -101,6 +103,26 @@ 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': 'auto.http.otel.nestjs', + 'sentry.op': 'handler.nestjs', + 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: 'auto.http.otel.nestjs', + op: 'handler.nestjs', + }, ]), transaction: 'GET /test-transaction', type: 'transaction', 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..c05849f443ce 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', }), ]), @@ -44,7 +54,7 @@ describe('express tracing experimental', () => { .ignore('session', 'sessions') .expect({ transaction: { - transaction: 'GET /', + transaction: 'GET /\\/test\\/regex/', transaction_info: { source: 'route', }, @@ -67,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', }, @@ -105,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/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/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/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/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/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/package.json b/package.json index 6abdde7f2de2..78bb0f5d0788 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", @@ -113,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/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-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/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/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/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/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 { 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/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/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/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/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 258216b290d4..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'; /** @@ -110,9 +111,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/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 { }); }); + 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); 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/deno/package.json b/packages/deno/package.json index 59e9cbd42866..e19f4c6b7983 100644 --- a/packages/deno/package.json +++ b/packages/deno/package.json @@ -63,13 +63,6 @@ "extends": "../../package.json" }, "sideEffects": false, - "madge": { - "detectiveOptions": { - "ts": { - "skipTypeImports": true - } - } - }, "nx": { "targets": { "build:transpile": { 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/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 }, )} 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; } > => { 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/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()]; } /** 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/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/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; + } } } diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts index 20c37699bcf1..14cdad42a25e 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; @@ -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); } } 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/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/node/package.json b/packages/node/package.json index c78e767f7920..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": { @@ -59,7 +67,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", @@ -75,7 +83,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/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(); diff --git a/packages/node/src/integrations/anr/index.ts b/packages/node/src/integrations/anr/index.ts index 9d6382de45da..671aae2bad49 100644 --- a/packages/node/src/integrations/anr/index.ts +++ b/packages/node/src/integrations/anr/index.ts @@ -1,9 +1,8 @@ -import { defineIntegration, mergeScopeData } from '@sentry/core'; +import * as inspector from 'node:inspector'; +import { Worker } from 'node:worker_threads'; +import { defineIntegration, getCurrentScope, getGlobalScope, getIsolationScope, 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'; import type { AnrIntegrationOptions, WorkerStartData } from './common'; 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..379af4710794 100644 --- a/packages/node/src/integrations/context.ts +++ b/packages/node/src/integrations/context.ts @@ -1,8 +1,9 @@ -import { execFile } from 'child_process'; -import { readFile, readdir } from 'fs'; -import * as os from 'os'; -import { join } from 'path'; -import { promisify } from 'util'; +/* eslint-disable max-lines */ +import { execFile } from 'node:child_process'; +import { readFile, readdir } from 'node:fs'; +import * as os from 'node:os'; +import { join } from 'node:path'; +import { promisify } from 'node:util'; import { defineIntegration } from '@sentry/core'; import type { AppContext, @@ -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/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..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 '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/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/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 {}; + } } 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/connect.ts b/packages/node/src/integrations/tracing/connect.ts index 9846b6c3dc7e..7d3e5a28137f 100644 --- a/packages/node/src/integrations/tracing/connect.ts +++ b/packages/node/src/integrations/tracing/connect.ts @@ -1,9 +1,15 @@ -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, + spanToJSON, +} from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; -import { consoleSandbox } from '@sentry/utils'; +import type { IntegrationFn, Span } from '@sentry/types'; +import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; type ConnectApp = { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -30,12 +36,38 @@ function connectErrorMiddleware(err: any, req: any, res: any, next: any): void { export const setupConnectErrorHandler = (app: ConnectApp): void => { app.use(connectErrorMiddleware); - 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()`.', - ); + // 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 connect + const client = getClient(); + if (client) { + client.on('spanStart', span => { + addConnectSpanAttributes(span); }); } + + ensureIsWrapped(app.use, 'connect'); }; + +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); + } +} diff --git a/packages/node/src/integrations/tracing/express.ts b/packages/node/src/integrations/tracing/express.ts index 31abf92aca58..cddb9bb7e0e5 100644 --- a/packages/node/src/integrations/tracing/express.ts +++ b/packages/node/src/integrations/tracing/express.ts @@ -1,15 +1,14 @@ -import type * as http from 'http'; +import type * as http from 'node:http'; import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'; -import { defineIntegration, getDefaultIsolationScope, isEnabled } 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 { @@ -19,6 +18,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()) { @@ -118,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 55ccc7b4b72d..6286bd8a0f97 100644 --- a/packages/node/src/integrations/tracing/fastify.ts +++ b/packages/node/src/integrations/tracing/fastify.ts @@ -1,11 +1,37 @@ -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, + spanToJSON, +} from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; -import { consoleSandbox } from '@sentry/utils'; +import type { IntegrationFn, Span } from '@sentry/types'; +import { ensureIsWrapped } from '../../utils/ensureIsWrapped'; -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 +40,7 @@ const _fastifyIntegration = (() => { addOpenTelemetryInstrumentation( new FastifyInstrumentation({ requestHook(span) { - addOriginToSpan(span, 'auto.http.otel.fastify'); + addFastifySpanAttributes(span); }, }), ); @@ -29,27 +55,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,12 +89,39 @@ export function setupFastifyErrorHandler(fastify: Fastify): void { fastify.register(plugin); - 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()`.', - ); + // 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); }); } + + ensureIsWrapped(fastify.addHook, 'fastify'); +} + +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 -> /, '')); + } } 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'); }, diff --git a/packages/node/src/integrations/tracing/hapi/index.ts b/packages/node/src/integrations/tracing/hapi/index.ts index 7f55867c8bf5..ee03cfc34ac6 100644 --- a/packages/node/src/integrations/tracing/hapi/index.ts +++ b/packages/node/src/integrations/tracing/hapi/index.ts @@ -1,20 +1,23 @@ -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 { consoleSandbox, logger } from '@sentry/utils'; +import type { IntegrationFn, Span } from '@sentry/types'; +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 = (() => { @@ -95,13 +98,33 @@ export const hapiErrorPlugin = { export async function setupHapiErrorHandler(server: Server): Promise { await server.register(hapiErrorPlugin); - // 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()`.', - ); + // 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 + ensureIsWrapped(server.register, 'hapi'); +} + +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`, + }); } diff --git a/packages/node/src/integrations/tracing/koa.ts b/packages/node/src/integrations/tracing/koa.ts index ba6c136c5486..7d68afb19efe 100644 --- a/packages/node/src/integrations/tracing/koa.ts +++ b/packages/node/src/integrations/tracing/koa.ts @@ -1,18 +1,40 @@ -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, getIsolationScope, - isEnabled, spanToJSON, } from '@sentry/core'; import { addOpenTelemetryInstrumentation } from '@sentry/opentelemetry'; -import type { IntegrationFn } from '@sentry/types'; -import { consoleSandbox, logger } from '@sentry/utils'; +import type { IntegrationFn, Span } from '@sentry/types'; +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'); + + 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 { @@ -21,6 +43,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'); @@ -51,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/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`, + }); +} 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/sdk/init.ts b/packages/node/src/sdk/init.ts index c03af9ec09d5..82cd26492960 100644 --- a/packages/node/src/sdk/init.ts +++ b/packages/node/src/sdk/init.ts @@ -37,14 +37,11 @@ import { spotlightIntegration } from '../integrations/spotlight'; import { getAutoPerformanceIntegrations } from '../integrations/tracing'; import { makeNodeTransport } from '../transports'; import type { NodeClientOptions, NodeOptions } from '../types'; +import { isCjs } from '../utils/commonjs'; import { defaultStackParser, getSentryRelease } from './api'; import { NodeClient } from './client'; import { initOpenTelemetry } from './initOtel'; -function isCjs(): boolean { - return typeof require !== 'undefined'; -} - function getCjsOnlyIntegrations(): Integration[] { return isCjs() ? [modulesIntegration()] : []; } @@ -142,9 +139,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(() => { @@ -169,6 +170,8 @@ function _init( client.init(); } + logger.log(`Running in ${isCjs() ? 'CommonJS' : 'ESM'} mode.`); + if (options.autoSessionTracking) { startSessionTracking(); } diff --git a/packages/node/src/transports/http.ts b/packages/node/src/transports/http.ts index d4d7435bdc6d..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, @@ -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/node/src/utils/commonjs.ts b/packages/node/src/utils/commonjs.ts new file mode 100644 index 000000000000..9b5e5b531d73 --- /dev/null +++ b/packages/node/src/utils/commonjs.ts @@ -0,0 +1,4 @@ +/** 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..8cf85b39d545 --- /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 './commonjs'; + +/** + * 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/.`, + ); + } + }); + } +} 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/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/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/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/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'; 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-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(); } 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/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: { 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/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 { 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; diff --git a/packages/types/src/event.ts b/packages/types/src/event.ts index da207156b8c8..c8c16b8ce514 100644 --- a/packages/types/src/event.ts +++ b/packages/types/src/event.ts @@ -16,7 +16,7 @@ import type { Thread } from './thread'; import type { TransactionSource } from './transaction'; import type { User } from './user'; -/** JSDoc */ +/** An event to be sent to Sentry. */ export interface Event { event_id?: string; message?: string; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 1ed8ec1755a6..bb4230ea3e5c 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -121,11 +121,10 @@ export type { Stacktrace, StackParser, StackLineParser, StackLineParserFn } from export type { PropagationContext, TracePropagationTargets } from './tracing'; export type { StartSpanOptions } from './startSpanOptions'; export type { - CustomSamplingContext, - SamplingContext, TraceparentData, TransactionSource, } from './transaction'; +export type { CustomSamplingContext, SamplingContext } from './samplingcontext'; export type { DurationUnit, InformationUnit, diff --git a/packages/types/src/options.ts b/packages/types/src/options.ts index 26a043647dcc..8b2dbebdd574 100644 --- a/packages/types/src/options.ts +++ b/packages/types/src/options.ts @@ -1,12 +1,12 @@ import type { Breadcrumb, BreadcrumbHint } from './breadcrumb'; import type { ErrorEvent, EventHint, TransactionEvent } from './event'; import type { Integration } from './integration'; +import type { SamplingContext } from './samplingcontext'; import type { CaptureContext } from './scope'; import type { SdkMetadata } from './sdkmetadata'; import type { SpanJSON } from './span'; import type { StackLineParser, StackParser } from './stacktrace'; import type { TracePropagationTargets } from './tracing'; -import type { SamplingContext } from './transaction'; import type { BaseTransportOptions, Transport } from './transport'; export interface ClientOptions { 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/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/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/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. diff --git a/yarn.lock b/yarn.lock index 9848f21d0b0b..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" @@ -6112,20 +6125,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" - 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" @@ -6133,11 +6132,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 +6139,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" @@ -6155,14 +6154,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== @@ -6209,10 +6208,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" @@ -6328,19 +6327,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.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== @@ -6363,18 +6350,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" @@ -6400,6 +6375,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 +6400,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== @@ -6426,12 +6418,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== @@ -6489,14 +6481,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" @@ -8327,8 +8319,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== @@ -8694,7 +8695,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== @@ -8964,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" @@ -8997,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== @@ -9023,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" @@ -9077,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" @@ -10120,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= @@ -10509,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" @@ -12752,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== @@ -12846,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== @@ -12856,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" @@ -13664,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" @@ -13806,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" @@ -13870,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" - -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= + gonzales-pe "^4.3.0" + node-source-walk "^6.0.1" -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" @@ -15097,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" @@ -15993,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== @@ -16566,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" @@ -16807,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" @@ -17166,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" @@ -17446,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== @@ -17544,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== @@ -17595,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== @@ -17723,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" @@ -18592,16 +18532,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" @@ -18640,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" @@ -19365,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" @@ -21213,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: @@ -22423,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: @@ -23086,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" @@ -25055,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" @@ -25082,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== @@ -25100,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" @@ -25109,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" @@ -25190,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" @@ -25284,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== @@ -25642,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" @@ -25779,8 +25703,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== @@ -25795,6 +25718,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" @@ -26360,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== @@ -26392,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" @@ -26494,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== @@ -26950,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" @@ -28003,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" @@ -28039,8 +27976,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== @@ -28066,6 +28002,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" @@ -28161,7 +28106,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== @@ -28298,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" @@ -28576,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" @@ -29046,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" @@ -29108,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" @@ -29128,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== @@ -29293,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" @@ -29440,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" @@ -30747,8 +30702,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== @@ -30766,6 +30720,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"