diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 0b254d24022b..a5523a861eee 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -179,7 +179,7 @@ jobs:
key: ${{ steps.compute_lockfile_hash.outputs.hash }}
- name: Install dependencies
- if: steps.cache_dependencies.outputs.cache_hit != 'true'
+ if: steps.cache_dependencies.outputs.cache-hit != 'true'
run: yarn install --ignore-engines --frozen-lockfile
outputs:
dependency_cache_key: ${{ steps.compute_lockfile_hash.outputs.hash }}
@@ -661,7 +661,7 @@ jobs:
needs: [job_get_metadata, job_build]
if: needs.job_get_metadata.outputs.changed_node == 'true' || github.event_name != 'pull_request'
runs-on: ubuntu-20.04
- timeout-minutes: 10
+ timeout-minutes: 15
strategy:
fail-fast: false
matrix:
@@ -738,11 +738,11 @@ jobs:
github.actor != 'dependabot[bot]'
needs: [job_get_metadata, job_build]
runs-on: ubuntu-20.04
- timeout-minutes: 20
+ timeout-minutes: 30
strategy:
fail-fast: false
matrix:
- shard: [1, 2, 3]
+ shard: [1, 2, 3, 4]
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
@@ -773,7 +773,7 @@ jobs:
E2E_TEST_SENTRY_ORG_SLUG: 'sentry-javascript-sdks'
E2E_TEST_SENTRY_TEST_PROJECT: 'sentry-javascript-e2e-tests'
E2E_TEST_SHARD: ${{ matrix.shard }}
- E2E_TEST_SHARD_AMOUNT: 3
+ E2E_TEST_SHARD_AMOUNT: 4
run: |
cd packages/e2e-tests
yarn test:e2e
diff --git a/.gitignore b/.gitignore
index 8574a81de0a4..777b23658572 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,6 @@ build/
dist/
coverage/
scratch/
-*.d.ts
*.js.map
*.pyc
*.tsbuildinfo
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2b1e7168f88..8d53c9fa7fc4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,64 @@
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
+## 7.58.0
+
+### Important Changes
+
+- **Performance Monitoring not required for Distributed Tracing**
+
+This release adds support for [distributed tracing](https://docs.sentry.io/platforms/javascript/usage/distributed-tracing/) without requiring performance monitoring to be active on the JavaScript SDKs (browser and node). This means even if there is no sampled transaction/span, the SDK will still propagate traces to downstream services. Distributed Tracing can be configured with the `tracePropagationTargets` option, which controls what requests to attach the `sentry-trace` and `baggage` HTTP headers to (which is what propagates tracing information).
+
+```js
+Sentry.init({
+ tracePropagationTargets: ["third-party-site.com", /^https:\/\/yourserver\.io\/api/],
+});
+```
+
+- feat(tracing): Add tracing without performance to browser and client Sveltekit (#8458)
+- feat(node): Add tracing without performance to Node http integration (#8450)
+- feat(node): Add tracing without performance to Node Undici (#8449)
+- feat(node): Populate propagation context using env variables (#8422)
+
+- **feat(core): Support `AggregateErrors` in `LinkedErrors` integration (#8463)**
+
+This release adds support for [`AggregateErrors`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError). AggregateErrors are considered as Exception Groups by Sentry, and will be visualized and grouped differently. See the [Exception Groups Changelog Post](https://changelog.getsentry.com/announcements/exception-groups-now-supported-for-python-and-net) for more details.
+
+Exception Group support requires Self-Hosted Sentry [version 23.5.1](https://github.com/getsentry/self-hosted/releases/tag/23.5.1) or newer.
+
+- **feat(replay): Add a new option `networkDetailDenyUrls` (#8439)**
+
+This release adds a new option `networkDetailDenyUrls` to the `Replay` integration. This option allows you to specify a list of URLs that should not be captured by the `Replay` integration, which can be used alongside the existing `networkDetailAllowUrls` for finely grained control of which URLs should have network details captured.
+
+```js
+Sentry.init({
+ integrations: [
+ new Sentry.Integrations.Replay({
+ networkDetailDenyUrls: [/^http:\/\/example.com\/test$/],
+ }),
+ ],
+});
+```
+
+### Other Changes
+
+- feat(core): Add helpers to get module metadata from injected code (#8438)
+- feat(core): Add sampling decision to trace envelope header (#8483)
+- feat(node): Add trace context to checkin (#8503)
+- feat(node): Export `getModule` for Electron SDK (#8488)
+- feat(types): Allow `user.id` to be a number (#8330)
+- fix(browser): Set anonymous `crossorigin` attribute on report dialog (#8424)
+- fix(nextjs): Ignore `tunnelRoute` when doing static exports (#8471)
+- fix(nextjs): Use `basePath` option for `tunnelRoute` (#8454)
+- fix(node): Apply source context to linked errors even when it is uncached (#8453)
+- fix(node): report errorMiddleware errors as unhandled (#8048)
+- fix(react): Add support for `basename` option of `createBrowserRouter` (#8457)
+- fix(remix): Add explicit `@sentry/node` exports. (#8509)
+- fix(remix): Don't inject trace/baggage to `redirect` and `catch` responses (#8467)
+- fix(replay): Adjust slow/multi click handling (#8380)
+
+Work in this release contributed by @mrdulin, @donaldxdonald & @ziyad-elabid-nw. Thank you for your contributions!
+
## 7.57.0
### Important Changes
diff --git a/LICENSE b/LICENSE
index 689ce9d5572b..293314012679 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,14 +1,21 @@
-Copyright (c) 2018 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 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/lerna.json b/lerna.json
index 90686ec37d8a..71aa98569aca 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,6 +1,5 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "7.57.0",
- "npmClient": "yarn",
- "useWorkspaces": true
+ "npmClient": "yarn"
}
diff --git a/nx.json b/nx.json
index 2341174dd956..c25aeaa1f0e7 100644
--- a/nx.json
+++ b/nx.json
@@ -3,65 +3,35 @@
"default": {
"runner": "nx/tasks-runners/default",
"options": {
- "cacheableOperations": [
- "build:bundle",
- "build:transpile",
- "build:types",
- "lint:eslint",
- "test:unit"
- ],
+ "cacheableOperations": ["build:bundle", "build:transpile", "build:types", "lint:eslint", "test:unit"],
"cacheDirectory": ".nxcache"
}
}
},
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
- "sharedGlobals": [
- "{workspaceRoot}/*.js",
- "{workspaceRoot}/*.json"
- ],
- "production": [
- "default",
- "!{projectRoot}/test/**/*",
- "!{projectRoot}/**/*.md"
- ]
+ "sharedGlobals": ["{workspaceRoot}/*.js", "{workspaceRoot}/*.json"],
+ "production": ["default", "!{projectRoot}/test/**/*", "!{projectRoot}/**/*.md"]
},
"targetDefaults": {
"build:bundle": {
"inputs": ["production", "^production"],
- "dependsOn": [
- "build:transpile"
- ],
- "outputs": [
- "{projectRoot}/build/bundles"
- ]
+ "dependsOn": ["build:transpile"],
+ "outputs": ["{projectRoot}/build/bundles"]
},
"build:tarball": {
"inputs": ["production", "^production"],
- "dependsOn": [
- "build:transpile",
- "build:types"
- ],
+ "dependsOn": ["build:transpile", "build:types"],
"outputs": []
},
"build:transpile": {
"inputs": ["production", "^production"],
- "dependsOn": [
- "^build:transpile:uncached",
- "^build:transpile",
- "build:transpile:uncached"
- ],
- "outputs": [
- "{projectRoot}/build/npm",
- "{projectRoot}/build/esm",
- "{projectRoot}/build/cjs"
- ]
+ "dependsOn": ["^build:transpile:uncached", "^build:transpile", "build:transpile:uncached"],
+ "outputs": ["{projectRoot}/build/npm", "{projectRoot}/build/esm", "{projectRoot}/build/cjs"]
},
"build:types": {
"inputs": ["production", "^production"],
- "dependsOn": [
- "^build:types"
- ],
+ "dependsOn": ["^build:types"],
"outputs": [
"{projectRoot}/build/types",
"{projectRoot}/build/types-ts3.8",
@@ -78,5 +48,6 @@
"inputs": ["default"],
"outputs": ["{projectRoot}/coverage"]
}
- }
+ },
+ "$schema": "./node_modules/nx/schemas/nx-schema.json"
}
diff --git a/package.json b/package.json
index feb5be7839d0..0d800adc7824 100644
--- a/package.json
+++ b/package.json
@@ -25,9 +25,9 @@
"lint:eslint": "lerna run lint:eslint",
"validate:es5": "lerna run validate:es5",
"postpublish": "lerna run --stream --concurrency 1 postpublish",
- "test": "lerna run --ignore @sentry-internal/* test",
- "test:unit": "lerna run --ignore @sentry-internal/* test:unit",
- "test-ci-browser": "lerna run test --ignore \"@sentry/{node,opentelemetry-node,serverless,nextjs,remix,gatsby,sveltekit}\" --ignore @sentry-internal/*",
+ "test": "lerna run --ignore \"@sentry-internal/{browser-integration-tests,e2e-tests,integration-shims,node-integration-tests,overhead-metrics}\" test",
+ "test:unit": "lerna run --ignore \"@sentry-internal/{browser-integration-tests,e2e-tests,integration-shims,node-integration-tests,overhead-metrics}\" test:unit",
+ "test-ci-browser": "lerna run test --ignore \"@sentry/{node,opentelemetry-node,serverless,nextjs,remix,gatsby,sveltekit}\" --ignore \"@sentry-internal/{browser-integration-tests,e2e-tests,integration-shims,node-integration-tests,overhead-metrics}\"",
"test-ci-node": "ts-node ./scripts/node-unit-tests.ts",
"test:update-snapshots": "lerna run test:update-snapshots",
"yalc:publish": "lerna run yalc:publish"
@@ -98,7 +98,7 @@
"jsdom": "^19.0.0",
"karma-browserstack-launcher": "^1.5.1",
"karma-firefox-launcher": "^1.1.0",
- "lerna": "6.5.0-alpha.2",
+ "lerna": "7.1.1",
"madge": "4.0.2",
"mocha": "^6.1.4",
"nodemon": "^2.0.16",
diff --git a/packages/angular-ivy/README.md b/packages/angular-ivy/README.md
index f70931554059..9546888170e6 100644
--- a/packages/angular-ivy/README.md
+++ b/packages/angular-ivy/README.md
@@ -175,7 +175,7 @@ import { TraceModule } from '@sentry/angular-ivy';
export class AppModule {}
```
-Then inside your components template (keep in mind that directive name attribute is required):
+Then, inside your component's template (keep in mind that the directive's name attribute is required):
```html
diff --git a/packages/angular/README.md b/packages/angular/README.md
index 9ec22b82313b..aa18724839a4 100644
--- a/packages/angular/README.md
+++ b/packages/angular/README.md
@@ -21,7 +21,7 @@
If you're using Angular 12 or newer, we recommend using `@sentry/angular-ivy` for native support with Angular's rendering engine Ivy.
-This SDK stilll officially supports Angular 10-15. If you are using an older version of Angular and experience problems with the Angular SDK, we recommend downgrading the SDK to version 6.x.
+This SDK still officially supports Angular 10-15. If you are using an older version of Angular and experience problems with the Angular SDK, we recommend downgrading the SDK to version 6.x.
## General
@@ -175,7 +175,7 @@ import { TraceModule } from '@sentry/angular';
export class AppModule {}
```
-Then inside your components template (keep in mind that directive name attribute is required):
+Then, inside your component's template (keep in mind that the directive's name attribute is required):
```html
diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts
index 6940e0cc8cc1..d9b4db07ff9d 100644
--- a/packages/angular/src/errorhandler.ts
+++ b/packages/angular/src/errorhandler.ts
@@ -69,7 +69,6 @@ function isErrorOrErrorLikeObject(value: unknown): value is Error {
const candidate = value as ErrorCandidate;
return (
- isString(candidate.name) &&
isString(candidate.name) &&
isString(candidate.message) &&
(undefined === candidate.stack || isString(candidate.stack))
diff --git a/packages/angular/tsconfig.json b/packages/angular/tsconfig.json
index ed785543d690..2f88305e15e5 100644
--- a/packages/angular/tsconfig.json
+++ b/packages/angular/tsconfig.json
@@ -5,6 +5,10 @@
"compilerOptions": {
// package-specific options
- "experimentalDecorators": true
+ "experimentalDecorators": true,
+ // Avoid loading all @types/... packages as they may not be TS 4.0 compatible
+ // We have no types packages here we directly depend on,
+ // if we ever add some we need to allowlist them here
+ "types": []
}
}
diff --git a/packages/browser-integration-tests/suites/replay/captureReplay/test.ts b/packages/browser-integration-tests/suites/replay/captureReplay/test.ts
index 72cbc47efe99..421e725bb3e4 100644
--- a/packages/browser-integration-tests/suites/replay/captureReplay/test.ts
+++ b/packages/browser-integration-tests/suites/replay/captureReplay/test.ts
@@ -56,7 +56,6 @@ sentryTest('should capture replays (@sentry/browser export)', async ({ getLocalT
version: SDK_VERSION,
name: 'sentry.javascript.browser',
},
- sdkProcessingMetadata: {},
request: {
url: expect.stringContaining('/dist/index.html'),
headers: {
@@ -94,7 +93,6 @@ sentryTest('should capture replays (@sentry/browser export)', async ({ getLocalT
version: SDK_VERSION,
name: 'sentry.javascript.browser',
},
- sdkProcessingMetadata: {},
request: {
url: expect.stringContaining('/dist/index.html'),
headers: {
diff --git a/packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts b/packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts
index 6caf1e4ea57c..c42bfc692018 100644
--- a/packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts
+++ b/packages/browser-integration-tests/suites/replay/captureReplayFromReplayPackage/test.ts
@@ -56,7 +56,6 @@ sentryTest('should capture replays (@sentry/replay export)', async ({ getLocalTe
version: SDK_VERSION,
name: 'sentry.javascript.browser',
},
- sdkProcessingMetadata: {},
request: {
url: expect.stringContaining('/dist/index.html'),
headers: {
@@ -94,7 +93,6 @@ sentryTest('should capture replays (@sentry/replay export)', async ({ getLocalTe
version: SDK_VERSION,
name: 'sentry.javascript.browser',
},
- sdkProcessingMetadata: {},
request: {
url: expect.stringContaining('/dist/index.html'),
headers: {
diff --git a/packages/browser-integration-tests/suites/replay/dsc/test.ts b/packages/browser-integration-tests/suites/replay/dsc/test.ts
index 54de1ee7db81..ffd2cf1877da 100644
--- a/packages/browser-integration-tests/suites/replay/dsc/test.ts
+++ b/packages/browser-integration-tests/suites/replay/dsc/test.ts
@@ -49,6 +49,7 @@ sentryTest(
trace_id: expect.any(String),
public_key: 'public',
replay_id: replay.session?.id,
+ sampled: 'true',
});
},
);
@@ -93,6 +94,7 @@ sentryTest(
sample_rate: '1',
trace_id: expect.any(String),
public_key: 'public',
+ sampled: 'true',
});
},
);
@@ -152,6 +154,7 @@ sentryTest(
trace_id: expect.any(String),
public_key: 'public',
replay_id: replay.session?.id,
+ sampled: 'true',
});
},
);
@@ -199,6 +202,7 @@ sentryTest(
sample_rate: '1',
trace_id: expect.any(String),
public_key: 'public',
+ sampled: 'true',
});
},
);
diff --git a/packages/browser-integration-tests/suites/replay/slowClick/multiClick/test.ts b/packages/browser-integration-tests/suites/replay/slowClick/multiClick/test.ts
index 2d84eeb29ac3..82bc436f714e 100644
--- a/packages/browser-integration-tests/suites/replay/slowClick/multiClick/test.ts
+++ b/packages/browser-integration-tests/suites/replay/slowClick/multiClick/test.ts
@@ -1,7 +1,12 @@
import { expect } from '@playwright/test';
import { sentryTest } from '../../../../utils/fixtures';
-import { getCustomRecordingEvents, shouldSkipReplayTest, waitForReplayRequest } from '../../../../utils/replayHelpers';
+import {
+ getCustomRecordingEvents,
+ shouldSkipReplayTest,
+ waitForReplayRequest,
+ waitForReplayRequests,
+} from '../../../../utils/replayHelpers';
sentryTest('captures multi click when not detecting slow click', async ({ getLocalTestUrl, page }) => {
if (shouldSkipReplayTest()) {
@@ -58,3 +63,97 @@ sentryTest('captures multi click when not detecting slow click', async ({ getLoc
},
]);
});
+
+sentryTest('captures multiple multi clicks', async ({ getLocalTestUrl, page, forceFlushReplay }) => {
+ if (shouldSkipReplayTest()) {
+ sentryTest.skip();
+ }
+
+ const reqPromise0 = waitForReplayRequest(page, 0);
+
+ await page.route('https://dsn.ingest.sentry.io/**/*', route => {
+ return route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({ id: 'test-id' }),
+ });
+ });
+
+ const url = await getLocalTestUrl({ testDir: __dirname });
+
+ await page.goto(url);
+ await reqPromise0;
+
+ let multiClickBreadcrumbCount = 0;
+
+ const reqsPromise = waitForReplayRequests(page, (_event, res) => {
+ const { breadcrumbs } = getCustomRecordingEvents(res);
+ const count = breadcrumbs.filter(breadcrumb => breadcrumb.category === 'ui.multiClick').length;
+
+ multiClickBreadcrumbCount += count;
+
+ if (multiClickBreadcrumbCount === 2) {
+ return true;
+ }
+
+ return false;
+ });
+
+ await page.click('#mutationButtonImmediately', { clickCount: 4 });
+ await forceFlushReplay();
+
+ // Ensure we waited at least 1s, which is the threshold to create a new ui.click breadcrumb
+ await new Promise(resolve => setTimeout(resolve, 1001));
+
+ await page.click('#mutationButtonImmediately', { clickCount: 2 });
+ await forceFlushReplay();
+
+ const responses = await reqsPromise;
+
+ const slowClickBreadcrumbs = responses
+ .flatMap(res => getCustomRecordingEvents(res).breadcrumbs)
+ .filter(breadcrumb => breadcrumb.category === 'ui.multiClick');
+
+ expect(slowClickBreadcrumbs).toEqual([
+ {
+ category: 'ui.multiClick',
+ type: 'default',
+ data: {
+ clickCount: 6,
+ metric: true,
+ node: {
+ attributes: {
+ id: 'mutationButtonImmediately',
+ },
+ id: expect.any(Number),
+ tagName: 'button',
+ textContent: '******* ******** ***********',
+ },
+ nodeId: expect.any(Number),
+ url: 'http://sentry-test.io/index.html',
+ },
+ message: 'body > button#mutationButtonImmediately',
+ timestamp: expect.any(Number),
+ },
+ {
+ category: 'ui.multiClick',
+ type: 'default',
+ data: {
+ clickCount: 2,
+ metric: true,
+ node: {
+ attributes: {
+ id: 'mutationButtonImmediately',
+ },
+ id: expect.any(Number),
+ tagName: 'button',
+ textContent: '******* ******** ***********',
+ },
+ nodeId: expect.any(Number),
+ url: 'http://sentry-test.io/index.html',
+ },
+ message: 'body > button#mutationButtonImmediately',
+ timestamp: expect.any(Number),
+ },
+ ]);
+});
diff --git a/packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts b/packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts
index bc94930e0be5..b244768f7f82 100644
--- a/packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts
+++ b/packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/test.ts
@@ -27,6 +27,7 @@ sentryTest(
transaction: expect.stringContaining('/index.html'),
trace_id: expect.any(String),
public_key: 'public',
+ sampled: 'true',
});
},
);
diff --git a/packages/browser-integration-tests/suites/tracing/envelope-header/test.ts b/packages/browser-integration-tests/suites/tracing/envelope-header/test.ts
index b8df56e72f7c..71adc007385c 100644
--- a/packages/browser-integration-tests/suites/tracing/envelope-header/test.ts
+++ b/packages/browser-integration-tests/suites/tracing/envelope-header/test.ts
@@ -30,6 +30,7 @@ sentryTest(
sample_rate: '1',
trace_id: expect.any(String),
public_key: 'public',
+ sampled: 'true',
});
},
);
diff --git a/packages/browser-integration-tests/utils/replayEventTemplates.ts b/packages/browser-integration-tests/utils/replayEventTemplates.ts
index d88fbd1bf0e5..46208b39af00 100644
--- a/packages/browser-integration-tests/utils/replayEventTemplates.ts
+++ b/packages/browser-integration-tests/utils/replayEventTemplates.ts
@@ -30,7 +30,6 @@ const DEFAULT_REPLAY_EVENT = {
version: SDK_VERSION,
name: 'sentry.javascript.browser',
},
- sdkProcessingMetadata: {},
request: {
url: expect.stringContaining('/dist/index.html'),
headers: {
diff --git a/packages/browser-integration-tests/utils/replayHelpers.ts b/packages/browser-integration-tests/utils/replayHelpers.ts
index bf070b395cf6..cb05baffb62b 100644
--- a/packages/browser-integration-tests/utils/replayHelpers.ts
+++ b/packages/browser-integration-tests/utils/replayHelpers.ts
@@ -101,6 +101,46 @@ export function waitForReplayRequest(
);
}
+/**
+ * Wait until a callback returns true, collecting all replay responses along the way.
+ * This can be useful when you don't know if stuff will be in one or multiple replay requests.
+ */
+export function waitForReplayRequests(
+ page: Page,
+ callback: (event: ReplayEvent, res: Response) => boolean,
+ timeout?: number,
+): Promise {
+ const responses: Response[] = [];
+
+ return new Promise(resolve => {
+ void page.waitForResponse(
+ res => {
+ const req = res.request();
+
+ const event = getReplayEventFromRequest(req);
+
+ if (!event) {
+ return false;
+ }
+
+ responses.push(res);
+
+ try {
+ if (callback(event, res)) {
+ resolve(responses);
+ return true;
+ }
+
+ return false;
+ } catch {
+ return false;
+ }
+ },
+ timeout ? { timeout } : undefined,
+ );
+ });
+}
+
export function isReplayEvent(event: Event): event is ReplayEvent {
return event.type === 'replay_event';
}
diff --git a/packages/browser/src/integrations/linkederrors.ts b/packages/browser/src/integrations/linkederrors.ts
index bb53d0210f96..08581fecb9b3 100644
--- a/packages/browser/src/integrations/linkederrors.ts
+++ b/packages/browser/src/integrations/linkederrors.ts
@@ -1,8 +1,6 @@
-import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core';
-import type { Event, EventHint, Exception, ExtendedError, Integration, StackParser } from '@sentry/types';
-import { isInstanceOf } from '@sentry/utils';
+import type { Event, EventHint, EventProcessor, Hub, Integration } from '@sentry/types';
+import { applyAggregateErrorsToEvent } from '@sentry/utils';
-import type { BrowserClient } from '../client';
import { exceptionFromError } from '../eventbuilder';
const DEFAULT_KEY = 'cause';
@@ -46,49 +44,26 @@ export class LinkedErrors implements Integration {
/**
* @inheritDoc
*/
- public setupOnce(): void {
- const client = getCurrentHub().getClient();
- if (!client) {
- return;
- }
+ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
addGlobalEventProcessor((event: Event, hint?: EventHint) => {
- const self = getCurrentHub().getIntegration(LinkedErrors);
- return self ? _handler(client.getOptions().stackParser, self._key, self._limit, event, hint) : event;
- });
- }
-}
+ const hub = getCurrentHub();
+ const client = hub.getClient();
+ const self = hub.getIntegration(LinkedErrors);
-/**
- * @inheritDoc
- */
-export function _handler(
- parser: StackParser,
- key: string,
- limit: number,
- event: Event,
- hint?: EventHint,
-): Event | null {
- if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
- return event;
- }
- const linkedErrors = _walkErrorTree(parser, limit, hint.originalException as ExtendedError, key);
- event.exception.values = [...linkedErrors, ...event.exception.values];
- return event;
-}
+ if (!client || !self) {
+ return event;
+ }
+
+ applyAggregateErrorsToEvent(
+ exceptionFromError,
+ client.getOptions().stackParser,
+ self._key,
+ self._limit,
+ event,
+ hint,
+ );
-/**
- * JSDOC
- */
-export function _walkErrorTree(
- parser: StackParser,
- limit: number,
- error: ExtendedError,
- key: string,
- stack: Exception[] = [],
-): Exception[] {
- if (!isInstanceOf(error[key], Error) || stack.length + 1 >= limit) {
- return stack;
+ return event;
+ });
}
- const exception = exceptionFromError(parser, error[key]);
- return _walkErrorTree(parser, limit, error[key], key, [exception, ...stack]);
}
diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts
index d58888260e3e..17fbfc159549 100644
--- a/packages/browser/src/sdk.ts
+++ b/packages/browser/src/sdk.ts
@@ -164,6 +164,7 @@ export function showReportDialog(options: ReportDialogOptions = {}, hub: Hub = g
const script = WINDOW.document.createElement('script');
script.async = true;
+ script.crossOrigin = 'anonymous';
script.src = getReportDialogEndpoint(dsn, options);
if (options.onLoad) {
diff --git a/packages/browser/test/unit/integrations/linkederrors.test.ts b/packages/browser/test/unit/integrations/linkederrors.test.ts
deleted file mode 100644
index 40738ca2af09..000000000000
--- a/packages/browser/test/unit/integrations/linkederrors.test.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-import type { Event as SentryEvent, Exception, ExtendedError } from '@sentry/types';
-
-import { BrowserClient } from '../../../src/client';
-import * as LinkedErrorsModule from '../../../src/integrations/linkederrors';
-import { defaultStackParser as parser } from '../../../src/stack-parsers';
-import { getDefaultBrowserClientOptions } from '../helper/browser-client-options';
-
-type EventWithException = SentryEvent & {
- exception: {
- values: Exception[];
- };
-};
-
-describe('LinkedErrors', () => {
- describe('handler', () => {
- it('should bail out if event does not contain exception', () => {
- const event = {
- message: 'foo',
- };
- const result = LinkedErrorsModule._handler(parser, 'cause', 5, event);
- expect(result).toEqual(event);
- });
-
- it('should bail out if event contains exception, but no hint', () => {
- const event = {
- exception: {
- values: [],
- },
- message: 'foo',
- };
- const result = LinkedErrorsModule._handler(parser, 'cause', 5, event);
- expect(result).toEqual(event);
- });
-
- it('should recursively walk error to find linked exceptions and assign them to the event', async () => {
- const three: ExtendedError = new SyntaxError('three');
-
- const two: ExtendedError = new TypeError('two');
- two.cause = three;
-
- const one: ExtendedError = new Error('one');
- one.cause = two;
-
- const originalException = one;
- const options = getDefaultBrowserClientOptions({ stackParser: parser });
- const client = new BrowserClient(options);
- return client.eventFromException(originalException).then(event => {
- const result = LinkedErrorsModule._handler(parser, 'cause', 5, event, {
- originalException,
- }) as EventWithException;
-
- // It shouldn't include root exception, as it's already processed in the event by the main error handler
- expect(result.exception.values.length).toBe(3);
- expect(result.exception.values[0].type).toBe('SyntaxError');
- expect(result.exception.values[0].value).toBe('three');
- expect(result.exception.values[0].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[1].type).toBe('TypeError');
- expect(result.exception.values[1].value).toBe('two');
- expect(result.exception.values[1].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[2].type).toBe('Error');
- expect(result.exception.values[2].value).toBe('one');
- expect(result.exception.values[2].stacktrace).toHaveProperty('frames');
- });
- });
-
- it('should allow to change walk key', async () => {
- const three: ExtendedError = new SyntaxError('three');
-
- const two: ExtendedError = new TypeError('two');
- two.reason = three;
-
- const one: ExtendedError = new Error('one');
- one.reason = two;
-
- const originalException = one;
- const options = getDefaultBrowserClientOptions({ stackParser: parser });
- const client = new BrowserClient(options);
- return client.eventFromException(originalException).then(event => {
- const result = LinkedErrorsModule._handler(parser, 'reason', 5, event, {
- originalException,
- }) as EventWithException;
-
- expect(result.exception.values.length).toBe(3);
- expect(result.exception.values[0].type).toBe('SyntaxError');
- expect(result.exception.values[0].value).toBe('three');
- expect(result.exception.values[0].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[1].type).toBe('TypeError');
- expect(result.exception.values[1].value).toBe('two');
- expect(result.exception.values[1].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[2].type).toBe('Error');
- expect(result.exception.values[2].value).toBe('one');
- expect(result.exception.values[2].stacktrace).toHaveProperty('frames');
- });
- });
-
- it('should allow to change stack size limit', async () => {
- const one: ExtendedError = new Error('one');
- const two: ExtendedError = new TypeError('two');
- const three: ExtendedError = new SyntaxError('three');
- one.cause = two;
- two.cause = three;
-
- const options = getDefaultBrowserClientOptions({ stackParser: parser });
- const client = new BrowserClient(options);
- const originalException = one;
- return client.eventFromException(originalException).then(event => {
- const result = LinkedErrorsModule._handler(parser, 'cause', 2, event, {
- originalException,
- }) as EventWithException;
-
- expect(result.exception.values.length).toBe(2);
- expect(result.exception.values[0].type).toBe('TypeError');
- expect(result.exception.values[0].value).toBe('two');
- expect(result.exception.values[0].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[1].type).toBe('Error');
- expect(result.exception.values[1].value).toBe('one');
- expect(result.exception.values[1].stacktrace).toHaveProperty('frames');
- });
- });
- });
-});
diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts
index 9a1312a131ac..52c4301f94ee 100644
--- a/packages/core/src/baseclient.ts
+++ b/packages/core/src/baseclient.ts
@@ -15,6 +15,7 @@ import type {
Integration,
IntegrationClass,
Outcome,
+ PropagationContext,
SdkMetadata,
Session,
SessionAggregates,
@@ -46,6 +47,7 @@ import type { IntegrationIndex } from './integration';
import { setupIntegration, setupIntegrations } from './integration';
import type { Scope } from './scope';
import { updateSession } from './session';
+import { getDynamicSamplingContextFromClient } from './tracing/dynamicSamplingContext';
import { prepareEvent } from './utils/prepareEvent';
const ALREADY_SEEN_ERROR = "Not capturing exception because it's already been captured.";
@@ -507,7 +509,36 @@ export abstract class BaseClient implements Client {
if (!hint.integrations && integrations.length > 0) {
hint.integrations = integrations;
}
- return prepareEvent(options, event, hint, scope);
+ return prepareEvent(options, event, hint, scope).then(evt => {
+ if (evt === null) {
+ return evt;
+ }
+
+ // If a trace context is not set on the event, we use the propagationContext set on the event to
+ // generate a trace context. If the propagationContext does not have a dynamic sampling context, we
+ // also generate one for it.
+ const { propagationContext } = evt.sdkProcessingMetadata || {};
+ const trace = evt.contexts && evt.contexts.trace;
+ if (!trace && propagationContext) {
+ const { traceId: trace_id, spanId, parentSpanId, dsc } = propagationContext as PropagationContext;
+ evt.contexts = {
+ trace: {
+ trace_id,
+ span_id: spanId,
+ parent_span_id: parentSpanId,
+ },
+ ...evt.contexts,
+ };
+
+ const dynamicSamplingContext = dsc ? dsc : getDynamicSamplingContextFromClient(trace_id, this, scope);
+
+ evt.sdkProcessingMetadata = {
+ dynamicSamplingContext,
+ ...evt.sdkProcessingMetadata,
+ };
+ }
+ return evt;
+ });
}
/**
diff --git a/packages/core/src/checkin.ts b/packages/core/src/checkin.ts
index 2417736bcdae..e7dd6c906f4c 100644
--- a/packages/core/src/checkin.ts
+++ b/packages/core/src/checkin.ts
@@ -1,26 +1,42 @@
-import type { CheckInEvelope, CheckInItem, DsnComponents, SdkMetadata, SerializedCheckIn } from '@sentry/types';
-import { createEnvelope, dsnToString } from '@sentry/utils';
+import type {
+ CheckInEvelope,
+ CheckInItem,
+ DsnComponents,
+ DynamicSamplingContext,
+ SdkMetadata,
+ SerializedCheckIn,
+} from '@sentry/types';
+import { createEnvelope, dropUndefinedKeys, dsnToString } from '@sentry/utils';
/**
* Create envelope from check in item.
*/
export function createCheckInEnvelope(
checkIn: SerializedCheckIn,
+ dynamicSamplingContext?: Partial,
metadata?: SdkMetadata,
tunnel?: string,
dsn?: DsnComponents,
): CheckInEvelope {
const headers: CheckInEvelope[0] = {
sent_at: new Date().toISOString(),
- ...(metadata &&
- metadata.sdk && {
- sdk: {
- name: metadata.sdk.name,
- version: metadata.sdk.version,
- },
- }),
- ...(!!tunnel && !!dsn && { dsn: dsnToString(dsn) }),
};
+
+ if (metadata && metadata.sdk) {
+ headers.sdk = {
+ name: metadata.sdk.name,
+ version: metadata.sdk.version,
+ };
+ }
+
+ if (!!tunnel && !!dsn) {
+ headers.dsn = dsnToString(dsn);
+ }
+
+ if (dynamicSamplingContext) {
+ headers.trace = dropUndefinedKeys(dynamicSamplingContext) as DynamicSamplingContext;
+ }
+
const item = createCheckInEnvelopeItem(checkIn);
return createEnvelope(headers, [item]);
}
diff --git a/packages/core/src/exports.ts b/packages/core/src/exports.ts
index ba283914fbbd..ad3d33013253 100644
--- a/packages/core/src/exports.ts
+++ b/packages/core/src/exports.ts
@@ -196,13 +196,15 @@ export function startTransaction(
* to create a monitor automatically when sending a check in.
*/
export function captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorConfig): string {
- const client = getCurrentHub().getClient();
+ const hub = getCurrentHub();
+ const scope = hub.getScope();
+ const client = hub.getClient();
if (!client) {
__DEBUG_BUILD__ && logger.warn('Cannot capture check-in. No client defined.');
} else if (!client.captureCheckIn) {
__DEBUG_BUILD__ && logger.warn('Cannot capture check-in. Client does not support sending check-ins.');
} else {
- return client.captureCheckIn(checkIn, upsertMonitorConfig);
+ return client.captureCheckIn(checkIn, upsertMonitorConfig, scope);
}
return uuid4();
diff --git a/packages/core/src/metadata.ts b/packages/core/src/metadata.ts
new file mode 100644
index 000000000000..d1ebac6e90e5
--- /dev/null
+++ b/packages/core/src/metadata.ts
@@ -0,0 +1,97 @@
+import type { Event, StackParser } from '@sentry/types';
+import { GLOBAL_OBJ } from '@sentry/utils';
+
+/** Keys are source filename/url, values are metadata objects. */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+const filenameMetadataMap = new Map();
+/** Set of stack strings that have already been parsed. */
+const parsedStacks = new Set();
+
+function ensureMetadataStacksAreParsed(parser: StackParser): void {
+ if (!GLOBAL_OBJ._sentryModuleMetadata) {
+ return;
+ }
+
+ for (const stack of Object.keys(GLOBAL_OBJ._sentryModuleMetadata)) {
+ const metadata = GLOBAL_OBJ._sentryModuleMetadata[stack];
+
+ if (parsedStacks.has(stack)) {
+ continue;
+ }
+
+ // Ensure this stack doesn't get parsed again
+ parsedStacks.add(stack);
+
+ const frames = parser(stack);
+
+ // Go through the frames starting from the top of the stack and find the first one with a filename
+ for (const frame of frames.reverse()) {
+ if (frame.filename) {
+ // Save the metadata for this filename
+ filenameMetadataMap.set(frame.filename, metadata);
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * Retrieve metadata for a specific JavaScript file URL.
+ *
+ * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option.
+ */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export function getMetadataForUrl(parser: StackParser, filename: string): any | undefined {
+ ensureMetadataStacksAreParsed(parser);
+ return filenameMetadataMap.get(filename);
+}
+
+/**
+ * Adds metadata to stack frames.
+ *
+ * Metadata is injected by the Sentry bundler plugins using the `_experiments.moduleMetadata` config option.
+ */
+export function addMetadataToStackFrames(parser: StackParser, event: Event): void {
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ event.exception!.values!.forEach(exception => {
+ if (!exception.stacktrace) {
+ return;
+ }
+
+ for (const frame of exception.stacktrace.frames || []) {
+ if (!frame.filename) {
+ continue;
+ }
+
+ const metadata = getMetadataForUrl(parser, frame.filename);
+
+ if (metadata) {
+ frame.module_metadata = metadata;
+ }
+ }
+ });
+ } catch (_) {
+ // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
+ }
+}
+
+/**
+ * Strips metadata from stack frames.
+ */
+export function stripMetadataFromStackFrames(event: Event): void {
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ event.exception!.values!.forEach(exception => {
+ if (!exception.stacktrace) {
+ return;
+ }
+
+ for (const frame of exception.stacktrace.frames || []) {
+ delete frame.module_metadata;
+ }
+ });
+ } catch (_) {
+ // To save bundle size we're just try catching here instead of checking for the existence of all the different objects.
+ }
+}
diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts
index 40a1fa135417..b72defc56016 100644
--- a/packages/core/src/scope.ts
+++ b/packages/core/src/scope.ts
@@ -11,6 +11,7 @@ import type {
Extra,
Extras,
Primitive,
+ PropagationContext,
RequestSession,
Scope as ScopeInterface,
ScopeContext,
@@ -29,6 +30,7 @@ import {
isThenable,
logger,
SyncPromise,
+ uuid4,
} from '@sentry/utils';
import { updateSession } from './session';
@@ -70,6 +72,9 @@ export class Scope implements ScopeInterface {
/** Attachments */
protected _attachments: Attachment[];
+ /** Propagation Context for distributed tracing */
+ protected _propagationContext: PropagationContext;
+
/**
* A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
* sent to Sentry
@@ -108,6 +113,7 @@ export class Scope implements ScopeInterface {
this._extra = {};
this._contexts = {};
this._sdkProcessingMetadata = {};
+ this._propagationContext = generatePropagationContext();
}
/**
@@ -131,6 +137,7 @@ export class Scope implements ScopeInterface {
newScope._requestSession = scope._requestSession;
newScope._attachments = [...scope._attachments];
newScope._sdkProcessingMetadata = { ...scope._sdkProcessingMetadata };
+ newScope._propagationContext = { ...scope._propagationContext };
}
return newScope;
}
@@ -347,6 +354,9 @@ export class Scope implements ScopeInterface {
if (captureContext._requestSession) {
this._requestSession = captureContext._requestSession;
}
+ if (captureContext._propagationContext) {
+ this._propagationContext = captureContext._propagationContext;
+ }
} else if (isPlainObject(captureContext)) {
// eslint-disable-next-line no-param-reassign
captureContext = captureContext as ScopeContext;
@@ -365,6 +375,9 @@ export class Scope implements ScopeInterface {
if (captureContext.requestSession) {
this._requestSession = captureContext.requestSession;
}
+ if (captureContext.propagationContext) {
+ this._propagationContext = captureContext.propagationContext;
+ }
}
return this;
@@ -387,6 +400,7 @@ export class Scope implements ScopeInterface {
this._session = undefined;
this._notifyScopeListeners();
this._attachments = [];
+ this._propagationContext = generatePropagationContext();
return this;
}
@@ -500,7 +514,11 @@ export class Scope implements ScopeInterface {
event.breadcrumbs = [...(event.breadcrumbs || []), ...this._breadcrumbs];
event.breadcrumbs = event.breadcrumbs.length > 0 ? event.breadcrumbs : undefined;
- event.sdkProcessingMetadata = { ...event.sdkProcessingMetadata, ...this._sdkProcessingMetadata };
+ event.sdkProcessingMetadata = {
+ ...event.sdkProcessingMetadata,
+ ...this._sdkProcessingMetadata,
+ propagationContext: this._propagationContext,
+ };
return this._notifyEventProcessors([...getGlobalEventProcessors(), ...this._eventProcessors], event, hint);
}
@@ -514,6 +532,21 @@ export class Scope implements ScopeInterface {
return this;
}
+ /**
+ * @inheritDoc
+ */
+ public setPropagationContext(context: PropagationContext): this {
+ this._propagationContext = context;
+ return this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public getPropagationContext(): PropagationContext {
+ return this._propagationContext;
+ }
+
/**
* This will be called after {@link applyToEvent} is finished.
*/
@@ -598,3 +631,11 @@ function getGlobalEventProcessors(): EventProcessor[] {
export function addGlobalEventProcessor(callback: EventProcessor): void {
getGlobalEventProcessors().push(callback);
}
+
+function generatePropagationContext(): PropagationContext {
+ return {
+ traceId: uuid4(),
+ spanId: uuid4().substring(16),
+ sampled: false,
+ };
+}
diff --git a/packages/core/src/tracing/dynamicSamplingContext.ts b/packages/core/src/tracing/dynamicSamplingContext.ts
new file mode 100644
index 000000000000..f8e8cd107c87
--- /dev/null
+++ b/packages/core/src/tracing/dynamicSamplingContext.ts
@@ -0,0 +1,32 @@
+import type { Client, DynamicSamplingContext, Scope } from '@sentry/types';
+import { dropUndefinedKeys } from '@sentry/utils';
+
+import { DEFAULT_ENVIRONMENT } from '../constants';
+
+/**
+ * Creates a dynamic sampling context from a client.
+ *
+ * Dispatchs the `createDsc` lifecycle hook as a side effect.
+ */
+export function getDynamicSamplingContextFromClient(
+ trace_id: string,
+ client: Client,
+ scope?: Scope,
+): DynamicSamplingContext {
+ const options = client.getOptions();
+
+ const { publicKey: public_key } = client.getDsn() || {};
+ const { segment: user_segment } = (scope && scope.getUser()) || {};
+
+ const dsc = dropUndefinedKeys({
+ environment: options.environment || DEFAULT_ENVIRONMENT,
+ release: options.release,
+ user_segment,
+ public_key,
+ trace_id,
+ }) as DynamicSamplingContext;
+
+ client.emit && client.emit('createDsc', dsc);
+
+ return dsc;
+}
diff --git a/packages/core/src/tracing/index.ts b/packages/core/src/tracing/index.ts
index a0d2716fda49..7a1f5336fe1c 100644
--- a/packages/core/src/tracing/index.ts
+++ b/packages/core/src/tracing/index.ts
@@ -7,3 +7,4 @@ export { extractTraceparentData, getActiveTransaction } from './utils';
export { SpanStatus } from './spanstatus';
export type { SpanStatusType } from './span';
export { trace } from './trace';
+export { getDynamicSamplingContextFromClient } from './dynamicSamplingContext';
diff --git a/packages/core/src/tracing/span.ts b/packages/core/src/tracing/span.ts
index 59a8ed11d68a..617dc7eaa52c 100644
--- a/packages/core/src/tracing/span.ts
+++ b/packages/core/src/tracing/span.ts
@@ -7,7 +7,7 @@ import type {
TraceContext,
Transaction,
} from '@sentry/types';
-import { dropUndefinedKeys, logger, timestampInSeconds, uuid4 } from '@sentry/utils';
+import { dropUndefinedKeys, generateSentryTraceHeader, logger, timestampInSeconds, uuid4 } from '@sentry/utils';
/**
* Keeps track of finished spans for a given transaction
@@ -265,11 +265,7 @@ export class Span implements SpanInterface {
* @inheritDoc
*/
public toTraceparent(): string {
- let sampledString = '';
- if (this.sampled !== undefined) {
- sampledString = this.sampled ? '-1' : '-0';
- }
- return `${this.traceId}-${this.spanId}${sampledString}`;
+ return generateSentryTraceHeader(this.traceId, this.spanId, this.sampled);
}
/**
diff --git a/packages/core/src/tracing/transaction.ts b/packages/core/src/tracing/transaction.ts
index d62f4c3b2833..71e6279eab80 100644
--- a/packages/core/src/tracing/transaction.ts
+++ b/packages/core/src/tracing/transaction.ts
@@ -11,9 +11,9 @@ import type {
} from '@sentry/types';
import { dropUndefinedKeys, logger } from '@sentry/utils';
-import { DEFAULT_ENVIRONMENT } from '../constants';
import type { Hub } from '../hub';
import { getCurrentHub } from '../hub';
+import { getDynamicSamplingContextFromClient } from './dynamicSamplingContext';
import { Span as SpanClass, SpanRecorder } from './span';
/** JSDoc */
@@ -245,39 +245,32 @@ export class Transaction extends SpanClass implements TransactionInterface {
return this._frozenDynamicSamplingContext;
}
- const hub: Hub = this._hub || getCurrentHub();
- const client = hub && hub.getClient();
+ const hub = this._hub || getCurrentHub();
+ const client = hub.getClient();
if (!client) return {};
- const { environment, release } = client.getOptions() || {};
- const { publicKey: public_key } = client.getDsn() || {};
+ const scope = hub.getScope();
+ const dsc = getDynamicSamplingContextFromClient(this.traceId, client, scope);
const maybeSampleRate = this.metadata.sampleRate;
- const sample_rate = maybeSampleRate !== undefined ? maybeSampleRate.toString() : undefined;
-
- const { segment: user_segment } = hub.getScope().getUser() || {};
+ if (maybeSampleRate !== undefined) {
+ dsc.sample_rate = `${maybeSampleRate}`;
+ }
+ // We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
const source = this.metadata.source;
+ if (source && source !== 'url') {
+ dsc.transaction = this.name;
+ }
- // We don't want to have a transaction name in the DSC if the source is "url" because URLs might contain PII
- const transaction = source && source !== 'url' ? this.name : undefined;
-
- const dsc = dropUndefinedKeys({
- environment: environment || DEFAULT_ENVIRONMENT,
- release,
- transaction,
- user_segment,
- public_key,
- trace_id: this.traceId,
- sample_rate,
- });
+ if (this.sampled !== undefined) {
+ dsc.sampled = String(this.sampled);
+ }
// Uncomment if we want to make DSC immutable
// this._frozenDynamicSamplingContext = dsc;
- client.emit && client.emit('createDsc', dsc);
-
return dsc;
}
diff --git a/packages/core/test/lib/base.test.ts b/packages/core/test/lib/base.test.ts
index aca8784ad511..162b53e4bb51 100644
--- a/packages/core/test/lib/base.test.ts
+++ b/packages/core/test/lib/base.test.ts
@@ -492,6 +492,28 @@ describe('BaseClient', () => {
);
});
+ test('it adds a trace context all events', () => {
+ expect.assertions(1);
+
+ const options = getDefaultTestClientOptions({ dsn: PUBLIC_DSN });
+ const client = new TestClient(options);
+ const scope = new Scope();
+
+ client.captureEvent({ message: 'message' }, { event_id: 'wat' }, scope);
+
+ expect(TestClient.instance!.event!).toEqual(
+ expect.objectContaining({
+ contexts: {
+ trace: {
+ parent_span_id: undefined,
+ span_id: expect.any(String),
+ trace_id: expect.any(String),
+ },
+ },
+ }),
+ );
+ });
+
test('adds `event_id` from hint if available', () => {
expect.assertions(1);
diff --git a/packages/core/test/lib/checkin.test.ts b/packages/core/test/lib/checkin.test.ts
index 38a8fce56e95..5ae6bac6b5f3 100644
--- a/packages/core/test/lib/checkin.test.ts
+++ b/packages/core/test/lib/checkin.test.ts
@@ -10,6 +10,10 @@ describe('createCheckInEnvelope', () => {
monitor_slug: 'b7645b8e-b47d-4398-be9a-d16b0dac31cb',
status: 'in_progress',
},
+ {
+ trace_id: '86f39e84263a4de99c326acab3bfe3bd',
+ public_key: 'testPublicKey',
+ },
{
sdk: {
name: 'testSdkName',
@@ -30,6 +34,10 @@ describe('createCheckInEnvelope', () => {
name: 'testSdkName',
version: 'testSdkVersion',
},
+ trace: {
+ trace_id: '86f39e84263a4de99c326acab3bfe3bd',
+ public_key: 'testPublicKey',
+ },
sent_at: expect.any(String),
});
});
diff --git a/packages/core/test/lib/metadata.test.ts b/packages/core/test/lib/metadata.test.ts
new file mode 100644
index 000000000000..64b3fd7310ad
--- /dev/null
+++ b/packages/core/test/lib/metadata.test.ts
@@ -0,0 +1,97 @@
+import type { Event } from '@sentry/types';
+import { createStackParser, GLOBAL_OBJ, nodeStackLineParser } from '@sentry/utils';
+
+import { addMetadataToStackFrames, getMetadataForUrl, stripMetadataFromStackFrames } from '../../src/metadata';
+
+const parser = createStackParser(nodeStackLineParser());
+
+const stack = new Error().stack || '';
+
+const event: Event = {
+ exception: {
+ values: [
+ {
+ stacktrace: {
+ frames: [
+ {
+ filename: '',
+ function: 'new Promise',
+ },
+ {
+ filename: '/tmp/utils.js',
+ function: 'Promise.then.completed',
+ lineno: 391,
+ colno: 28,
+ },
+ {
+ filename: __filename,
+ function: 'Object.',
+ lineno: 9,
+ colno: 19,
+ },
+ ],
+ },
+ },
+ ],
+ },
+};
+
+describe('Metadata', () => {
+ beforeEach(() => {
+ GLOBAL_OBJ._sentryModuleMetadata = GLOBAL_OBJ._sentryModuleMetadata || {};
+ GLOBAL_OBJ._sentryModuleMetadata[stack] = { team: 'frontend' };
+ });
+
+ it('is parsed', () => {
+ const metadata = getMetadataForUrl(parser, __filename);
+
+ expect(metadata).toEqual({ team: 'frontend' });
+ });
+
+ it('is added and stripped from stack frames', () => {
+ addMetadataToStackFrames(parser, event);
+
+ expect(event.exception?.values?.[0].stacktrace?.frames).toEqual([
+ {
+ filename: '',
+ function: 'new Promise',
+ },
+ {
+ filename: '/tmp/utils.js',
+ function: 'Promise.then.completed',
+ lineno: 391,
+ colno: 28,
+ },
+ {
+ filename: __filename,
+ function: 'Object.',
+ lineno: 9,
+ colno: 19,
+ module_metadata: {
+ team: 'frontend',
+ },
+ },
+ ]);
+
+ stripMetadataFromStackFrames(event);
+
+ expect(event.exception?.values?.[0].stacktrace?.frames).toEqual([
+ {
+ filename: '',
+ function: 'new Promise',
+ },
+ {
+ filename: '/tmp/utils.js',
+ function: 'Promise.then.completed',
+ lineno: 391,
+ colno: 28,
+ },
+ {
+ filename: __filename,
+ function: 'Object.',
+ lineno: 9,
+ colno: 19,
+ },
+ ]);
+ });
+});
diff --git a/packages/e2e-tests/lib/types.ts b/packages/e2e-tests/lib/types.ts
index a86c748ef6d0..f06094ce0426 100644
--- a/packages/e2e-tests/lib/types.ts
+++ b/packages/e2e-tests/lib/types.ts
@@ -47,4 +47,4 @@ export interface RecipeTestResult extends RecipeInstance {
tests: TestResult[];
}
-export type Env = Record;
+export type Env = Record;
diff --git a/packages/e2e-tests/lib/utils.ts b/packages/e2e-tests/lib/utils.ts
index 0c786a34f520..ef6d65dc84dc 100644
--- a/packages/e2e-tests/lib/utils.ts
+++ b/packages/e2e-tests/lib/utils.ts
@@ -17,22 +17,50 @@ interface SpawnAsync {
status: number | null;
}
-export function spawnAsync(
- cmd: string,
- options?:
- | childProcess.SpawnOptionsWithoutStdio
- | childProcess.SpawnOptionsWithStdioTuple,
- input?: string,
-): Promise {
- const start = Date.now();
+interface SpawnOptions {
+ timeout?: number;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ env?: any;
+ cwd?: string;
+}
+
+export function spawnAsync(cmd: string, options?: SpawnOptions, input?: string): Promise {
+ const timeoutMs = options?.timeout || 60_000 * 5;
return new Promise(resolve => {
const cp = childProcess.spawn(cmd, { shell: true, ...options });
+ // Ensure we properly time out after max. 5 min per command
+ let timeout: ReturnType | undefined = setTimeout(() => {
+ console.log(`Command "${cmd}" timed out after 5 minutes.`);
+ cp.kill();
+ end(null, `ETDIMEDOUT: Process timed out after ${timeoutMs} ms.`);
+ }, timeoutMs);
+
const stderr: unknown[] = [];
const stdout: string[] = [];
let error: Error | undefined;
+ function end(status: number | null, errorMessage?: string): void {
+ // This means we already ended
+ if (!timeout) {
+ return;
+ }
+
+ if (!error && errorMessage) {
+ error = new Error(errorMessage);
+ }
+
+ clearTimeout(timeout);
+ timeout = undefined;
+ resolve({
+ stdout: stdout.join(''),
+ stderr: stderr.join(''),
+ error: error || (status !== 0 ? new Error(`Process exited with status ${status}`) : undefined),
+ status,
+ });
+ }
+
cp.stdout.on('data', data => {
stdout.push(data ? (data as object).toString() : '');
});
@@ -46,19 +74,7 @@ export function spawnAsync(
});
cp.on('close', status => {
- const end = Date.now();
-
- // We manually mark this as timed out if the process takes too long
- if (!error && status === 1 && options?.timeout && end >= start + options.timeout) {
- error = new Error(`ETDIMEDOUT: Process timed out after ${options.timeout} ms.`);
- }
-
- resolve({
- stdout: stdout.join(''),
- stderr: stderr.join(''),
- error: error || (status !== 0 ? new Error(`Process exited with status ${status}`) : undefined),
- status,
- });
+ end(status);
});
if (input) {
diff --git a/packages/e2e-tests/package.json b/packages/e2e-tests/package.json
index 21a8f0e42552..c8b4473d24e4 100644
--- a/packages/e2e-tests/package.json
+++ b/packages/e2e-tests/package.json
@@ -10,9 +10,10 @@
"fix": "run-s fix:eslint fix:prettier",
"fix:eslint": "eslint . --format stylish --fix",
"fix:prettier": "prettier --config ../../.prettierrc.json --write . ",
- "lint": "run-s lint:prettier lint:eslint",
+ "lint": "run-s lint:prettier lint:eslint lint:ts",
"lint:eslint": "eslint . --format stylish",
"lint:prettier": "prettier --config ../../.prettierrc.json --check .",
+ "lint:ts": "tsc --noEmit",
"test:e2e": "run-s test:validate-configuration test:validate-test-app-setups test:run",
"test:run": "ts-node run.ts",
"test:validate-configuration": "ts-node validate-verdaccio-configuration.ts",
diff --git a/packages/e2e-tests/run.ts b/packages/e2e-tests/run.ts
index a062f51aab6c..658b4ffaa97f 100644
--- a/packages/e2e-tests/run.ts
+++ b/packages/e2e-tests/run.ts
@@ -17,6 +17,7 @@ async function run(): Promise {
const envVarsToInject = {
REACT_APP_E2E_TEST_DSN: process.env.E2E_TEST_DSN,
+ REMIX_APP_E2E_TEST_DSN: process.env.E2E_TEST_DSN,
NEXT_PUBLIC_E2E_TEST_DSN: process.env.E2E_TEST_DSN,
PUBLIC_E2E_TEST_DSN: process.env.E2E_TEST_DSN,
BASE_PORT: '27496', // just some random port
diff --git a/packages/e2e-tests/test-applications/create-remix-app/.eslintrc.js b/packages/e2e-tests/test-applications/create-remix-app/.eslintrc.js
new file mode 100644
index 000000000000..f2faf1470fd8
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/.eslintrc.js
@@ -0,0 +1,4 @@
+/** @type {import('eslint').Linter.Config} */
+module.exports = {
+ extends: ['@remix-run/eslint-config', '@remix-run/eslint-config/node'],
+};
diff --git a/packages/e2e-tests/test-applications/create-remix-app/.gitignore b/packages/e2e-tests/test-applications/create-remix-app/.gitignore
new file mode 100644
index 000000000000..3f7bf98da3e1
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/.gitignore
@@ -0,0 +1,6 @@
+node_modules
+
+/.cache
+/build
+/public/build
+.env
diff --git a/packages/e2e-tests/test-applications/create-remix-app/.npmrc b/packages/e2e-tests/test-applications/create-remix-app/.npmrc
new file mode 100644
index 000000000000..c6b3ef9b3eaa
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/.npmrc
@@ -0,0 +1,2 @@
+@sentry:registry=http://localhost:4873
+@sentry-internal:registry=http://localhost:4873
diff --git a/packages/e2e-tests/test-applications/create-remix-app/app/entry.client.tsx b/packages/e2e-tests/test-applications/create-remix-app/app/entry.client.tsx
new file mode 100644
index 000000000000..edb18224d6c6
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/app/entry.client.tsx
@@ -0,0 +1,34 @@
+/**
+ * By default, Remix will handle hydrating your app on the client for you.
+ * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
+ * For more information, see https://remix.run/file-conventions/entry.client
+ */
+
+import { RemixBrowser, useLocation, useMatches } from '@remix-run/react';
+import { startTransition, StrictMode, useEffect } from 'react';
+import { hydrateRoot } from 'react-dom/client';
+import * as Sentry from '@sentry/remix';
+
+Sentry.init({
+ dsn: process.env.REMIX_APP_E2E_TEST_DSN,
+ integrations: [
+ new Sentry.BrowserTracing({
+ routingInstrumentation: Sentry.remixRouterInstrumentation(useEffect, useLocation, useMatches),
+ }),
+ new Sentry.Replay(),
+ ],
+ // Performance Monitoring
+ tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production!
+ // Session Replay
+ replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
+ replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
+});
+
+startTransition(() => {
+ hydrateRoot(
+ document,
+
+
+ ,
+ );
+});
diff --git a/packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx b/packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx
new file mode 100644
index 000000000000..c9975e940e21
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/app/entry.server.tsx
@@ -0,0 +1,110 @@
+/**
+ * By default, Remix will handle generating the HTTP Response for you.
+ * You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
+ * For more information, see https://remix.run/file-conventions/entry.server
+ */
+
+import { PassThrough } from 'node:stream';
+
+import type { AppLoadContext, EntryContext } from '@remix-run/node';
+import { Response } from '@remix-run/node';
+import { RemixServer } from '@remix-run/react';
+import isbot from 'isbot';
+import { renderToPipeableStream } from 'react-dom/server';
+import * as Sentry from '@sentry/remix';
+
+const ABORT_DELAY = 5_000;
+
+Sentry.init({
+ dsn: process.env.REMIX_APP_E2E_TEST_DSN,
+ // Performance Monitoring
+ tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production!
+});
+
+export default function handleRequest(
+ request: Request,
+ responseStatusCode: number,
+ responseHeaders: Headers,
+ remixContext: EntryContext,
+ loadContext: AppLoadContext,
+) {
+ return isbot(request.headers.get('user-agent'))
+ ? handleBotRequest(request, responseStatusCode, responseHeaders, remixContext)
+ : handleBrowserRequest(request, responseStatusCode, responseHeaders, remixContext);
+}
+
+function handleBotRequest(
+ request: Request,
+ responseStatusCode: number,
+ responseHeaders: Headers,
+ remixContext: EntryContext,
+) {
+ return new Promise((resolve, reject) => {
+ const { pipe, abort } = renderToPipeableStream(
+ ,
+ {
+ onAllReady() {
+ const body = new PassThrough();
+
+ responseHeaders.set('Content-Type', 'text/html');
+
+ resolve(
+ new Response(body, {
+ headers: responseHeaders,
+ status: responseStatusCode,
+ }),
+ );
+
+ pipe(body);
+ },
+ onShellError(error: unknown) {
+ reject(error);
+ },
+ onError(error: unknown) {
+ responseStatusCode = 500;
+ console.error(error);
+ },
+ },
+ );
+
+ setTimeout(abort, ABORT_DELAY);
+ });
+}
+
+function handleBrowserRequest(
+ request: Request,
+ responseStatusCode: number,
+ responseHeaders: Headers,
+ remixContext: EntryContext,
+) {
+ return new Promise((resolve, reject) => {
+ const { pipe, abort } = renderToPipeableStream(
+ ,
+ {
+ onShellReady() {
+ const body = new PassThrough();
+
+ responseHeaders.set('Content-Type', 'text/html');
+
+ resolve(
+ new Response(body, {
+ headers: responseHeaders,
+ status: responseStatusCode,
+ }),
+ );
+
+ pipe(body);
+ },
+ onShellError(error: unknown) {
+ reject(error);
+ },
+ onError(error: unknown) {
+ console.error(error);
+ responseStatusCode = 500;
+ },
+ },
+ );
+
+ setTimeout(abort, ABORT_DELAY);
+ });
+}
diff --git a/packages/e2e-tests/test-applications/create-remix-app/app/root.tsx b/packages/e2e-tests/test-applications/create-remix-app/app/root.tsx
new file mode 100644
index 000000000000..0f3d1a16e8a8
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/app/root.tsx
@@ -0,0 +1,27 @@
+import { cssBundleHref } from '@remix-run/css-bundle';
+import type { LinksFunction } from '@remix-run/node';
+import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';
+import { withSentry } from '@sentry/remix';
+
+export const links: LinksFunction = () => [...(cssBundleHref ? [{ rel: 'stylesheet', href: cssBundleHref }] : [])];
+
+function App() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default withSentry(App);
diff --git a/packages/e2e-tests/test-applications/create-remix-app/app/routes/_index.tsx b/packages/e2e-tests/test-applications/create-remix-app/app/routes/_index.tsx
new file mode 100644
index 000000000000..e279d69b17b3
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/app/routes/_index.tsx
@@ -0,0 +1,30 @@
+import type { V2_MetaFunction } from '@remix-run/node';
+
+export const meta: V2_MetaFunction = () => {
+ return [{ title: 'New Remix App' }, { name: 'description', content: 'Welcome to Remix!' }];
+};
+
+export default function Index() {
+ return (
+
+ );
+}
diff --git a/packages/e2e-tests/test-applications/create-remix-app/package.json b/packages/e2e-tests/test-applications/create-remix-app/package.json
new file mode 100644
index 000000000000..080bc7de0446
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/package.json
@@ -0,0 +1,31 @@
+{
+ "private": true,
+ "sideEffects": false,
+ "scripts": {
+ "build": "remix build",
+ "dev": "remix dev",
+ "start": "remix-serve build",
+ "typecheck": "tsc"
+ },
+ "dependencies": {
+ "@sentry/remix": "*",
+ "@remix-run/css-bundle": "^1.16.1",
+ "@remix-run/node": "^1.16.1",
+ "@remix-run/react": "^1.16.1",
+ "@remix-run/serve": "^1.16.1",
+ "isbot": "^3.6.8",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@remix-run/dev": "^1.16.1",
+ "@remix-run/eslint-config": "^1.16.1",
+ "@types/react": "^18.0.35",
+ "@types/react-dom": "^18.0.11",
+ "eslint": "^8.38.0",
+ "typescript": "^5.0.4"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+}
diff --git a/packages/e2e-tests/test-applications/create-remix-app/remix.config.js b/packages/e2e-tests/test-applications/create-remix-app/remix.config.js
new file mode 100644
index 000000000000..1203199a8d5f
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/remix.config.js
@@ -0,0 +1,15 @@
+/** @type {import('@remix-run/dev').AppConfig} */
+module.exports = {
+ ignoredRouteFiles: ['**/.*'],
+ // appDirectory: "app",
+ // assetsBuildDirectory: "public/build",
+ // serverBuildPath: "build/index.js",
+ // publicPath: "/build/",
+ serverModuleFormat: 'cjs',
+ future: {
+ v2_errorBoundary: true,
+ v2_meta: true,
+ v2_normalizeFormMethod: true,
+ v2_routeConvention: true,
+ },
+};
diff --git a/packages/e2e-tests/test-applications/create-remix-app/test-recipe.json b/packages/e2e-tests/test-applications/create-remix-app/test-recipe.json
new file mode 100644
index 000000000000..dc16b21af54c
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/test-recipe.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "../../test-recipe-schema.json",
+ "testApplicationName": "create-remix-app",
+ "buildCommand": "pnpm install && pnpm build",
+ "tests": []
+}
diff --git a/packages/e2e-tests/test-applications/create-remix-app/tsconfig.json b/packages/e2e-tests/test-applications/create-remix-app/tsconfig.json
new file mode 100644
index 000000000000..20f8a386a6c4
--- /dev/null
+++ b/packages/e2e-tests/test-applications/create-remix-app/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
+ "compilerOptions": {
+ "lib": ["DOM", "DOM.Iterable", "ES2019"],
+ "isolatedModules": true,
+ "esModuleInterop": true,
+ "jsx": "react-jsx",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "target": "ES2019",
+ "strict": true,
+ "allowJs": true,
+ "forceConsistentCasingInFileNames": true,
+ "baseUrl": ".",
+ "paths": {
+ "~/*": ["./app/*"]
+ },
+
+ // Remix takes care of building everything in `remix build`.
+ "noEmit": true
+ }
+}
diff --git a/packages/e2e-tests/tsconfig.json b/packages/e2e-tests/tsconfig.json
index 2e051315981a..026669f596c0 100644
--- a/packages/e2e-tests/tsconfig.json
+++ b/packages/e2e-tests/tsconfig.json
@@ -1,5 +1,6 @@
{
"extends": "../../tsconfig.json",
+ "exclude": ["node_modules", "test-applications"],
"compilerOptions": {
"types": ["node"]
}
diff --git a/packages/gatsby/.gitignore b/packages/gatsby/.gitignore
new file mode 100644
index 000000000000..c318d0bec1a6
--- /dev/null
+++ b/packages/gatsby/.gitignore
@@ -0,0 +1,2 @@
+gatsby-browser.d.ts
+gatsby-node.d.ts
diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts
index 6571cd3122b4..982cba766a87 100644
--- a/packages/hub/test/scope.test.ts
+++ b/packages/hub/test/scope.test.ts
@@ -12,6 +12,21 @@ describe('Scope', () => {
GLOBAL_OBJ.__SENTRY__.globalEventProcessors = undefined;
});
+ describe('init', () => {
+ test('it creates a propagation context', () => {
+ const scope = new Scope();
+
+ // @ts-ignore asserting on private properties
+ expect(scope._propagationContext).toEqual({
+ traceId: expect.any(String),
+ spanId: expect.any(String),
+ sampled: false,
+ dsc: undefined,
+ parentSpanId: undefined,
+ });
+ });
+ });
+
describe('attributes modification', () => {
test('setFingerprint', () => {
const scope = new Scope();
@@ -137,6 +152,22 @@ describe('Scope', () => {
expect((scope as any)._sdkProcessingMetadata.dogs).toEqual('are great!');
});
+ test('set and get propagation context', () => {
+ const scope = new Scope();
+ const oldPropagationContext = scope.getPropagationContext();
+ scope.setPropagationContext({
+ traceId: '86f39e84263a4de99c326acab3bfe3bd',
+ spanId: '6e0c63257de34c92',
+ sampled: true,
+ });
+ expect(scope.getPropagationContext()).not.toEqual(oldPropagationContext);
+ expect(scope.getPropagationContext()).toEqual({
+ traceId: '86f39e84263a4de99c326acab3bfe3bd',
+ spanId: '6e0c63257de34c92',
+ sampled: true,
+ });
+ });
+
test('chaining', () => {
const scope = new Scope();
scope.setLevel('fatal').setUser({ id: '1' });
@@ -193,6 +224,14 @@ describe('Scope', () => {
expect(parentScope.getRequestSession()).toEqual({ status: 'ok' });
expect(scope.getRequestSession()).toEqual({ status: 'ok' });
});
+
+ test('should clone propagation context', () => {
+ const parentScope = new Scope();
+ const scope = Scope.clone(parentScope);
+
+ // @ts-ignore accessing private property for test
+ expect(scope._propagationContext).toEqual(parentScope._propagationContext);
+ });
});
describe('applyToEvent', () => {
@@ -220,7 +259,11 @@ describe('Scope', () => {
expect(processedEvent!.transaction).toEqual('/abc');
expect(processedEvent!.breadcrumbs![0]).toHaveProperty('message', 'test');
expect(processedEvent!.contexts).toEqual({ os: { id: '1' } });
- expect(processedEvent!.sdkProcessingMetadata).toEqual({ dogs: 'are great!' });
+ expect(processedEvent!.sdkProcessingMetadata).toEqual({
+ dogs: 'are great!',
+ // @ts-expect-error accessing private property for test
+ propagationContext: scope._propagationContext,
+ });
});
});
@@ -339,7 +382,7 @@ describe('Scope', () => {
scope.setSpan(span);
const event: Event = {
contexts: {
- trace: { a: 'c' },
+ trace: { a: 'c' } as any,
},
};
return scope.applyToEvent(event).then(processedEvent => {
@@ -383,6 +426,8 @@ describe('Scope', () => {
test('clear', () => {
const scope = new Scope();
+ // @ts-expect-error accessing private property
+ const oldPropagationContext = scope._propagationContext;
scope.setExtra('a', 2);
scope.setTag('a', 'b');
scope.setUser({ id: '1' });
@@ -393,6 +438,14 @@ describe('Scope', () => {
scope.clear();
expect((scope as any)._extra).toEqual({});
expect((scope as any)._requestSession).toEqual(undefined);
+ // @ts-expect-error accessing private property
+ expect(scope._propagationContext).toEqual({
+ traceId: expect.any(String),
+ spanId: expect.any(String),
+ sampled: false,
+ });
+ // @ts-expect-error accessing private property
+ expect(scope._propagationContext).not.toEqual(oldPropagationContext);
});
test('clearBreadcrumbs', () => {
@@ -486,6 +539,8 @@ describe('Scope', () => {
expect(updatedScope._level).toEqual('warning');
expect(updatedScope._fingerprint).toEqual(['bar']);
expect(updatedScope._requestSession.status).toEqual('ok');
+ // @ts-ignore accessing private property for test
+ expect(updatedScope._propagationContext).toEqual(localScope._propagationContext);
});
test('given an empty instance of Scope, it should preserve all the original scope data', () => {
@@ -518,7 +573,13 @@ describe('Scope', () => {
tags: { bar: '3', baz: '4' },
user: { id: '42' },
requestSession: { status: 'errored' as RequestSessionStatus },
+ propagationContext: {
+ traceId: '8949daf83f4a4a70bee4c1eb9ab242ed',
+ spanId: 'a024ad8fea82680e',
+ sampled: true,
+ },
};
+
const updatedScope = scope.update(localAttributes) as any;
expect(updatedScope._tags).toEqual({
@@ -540,6 +601,11 @@ describe('Scope', () => {
expect(updatedScope._level).toEqual('warning');
expect(updatedScope._fingerprint).toEqual(['bar']);
expect(updatedScope._requestSession).toEqual({ status: 'errored' });
+ expect(updatedScope._propagationContext).toEqual({
+ traceId: '8949daf83f4a4a70bee4c1eb9ab242ed',
+ spanId: 'a024ad8fea82680e',
+ sampled: true,
+ });
});
});
diff --git a/packages/nextjs/src/client/performance.ts b/packages/nextjs/src/client/performance.ts
index 0dd0b109408f..fd5f979a08b0 100644
--- a/packages/nextjs/src/client/performance.ts
+++ b/packages/nextjs/src/client/performance.ts
@@ -1,12 +1,7 @@
import { getCurrentHub } from '@sentry/core';
import { WINDOW } from '@sentry/react';
-import type { Primitive, TraceparentData, Transaction, TransactionContext, TransactionSource } from '@sentry/types';
-import {
- baggageHeaderToDynamicSamplingContext,
- extractTraceparentData,
- logger,
- stripUrlQueryAndFragment,
-} from '@sentry/utils';
+import type { Primitive, Transaction, TransactionContext, TransactionSource } from '@sentry/types';
+import { logger, stripUrlQueryAndFragment, tracingContextFromHeaders } from '@sentry/utils';
import type { NEXT_DATA as NextData } from 'next/dist/next-server/lib/utils';
import { default as Router } from 'next/router';
import type { ParsedUrlQuery } from 'querystring';
@@ -37,9 +32,9 @@ interface SentryEnhancedNextData extends NextData {
interface NextDataTagInfo {
route?: string;
- traceParentData?: TraceparentData;
- baggage?: string;
params?: ParsedUrlQuery;
+ sentryTrace?: string;
+ baggage?: string;
}
/**
@@ -83,13 +78,8 @@ function extractNextDataTagInformation(): NextDataTagInfo {
nextDataTagInfo.params = query;
if (props && props.pageProps) {
- if (props.pageProps._sentryBaggage) {
- nextDataTagInfo.baggage = props.pageProps._sentryBaggage;
- }
-
- if (props.pageProps._sentryTraceData) {
- nextDataTagInfo.traceParentData = extractTraceparentData(props.pageProps._sentryTraceData);
- }
+ nextDataTagInfo.sentryTrace = props.pageProps._sentryTraceData;
+ nextDataTagInfo.baggage = props.pageProps._sentryBaggage;
}
return nextDataTagInfo;
@@ -121,22 +111,26 @@ export function nextRouterInstrumentation(
startTransactionOnPageLoad: boolean = true,
startTransactionOnLocationChange: boolean = true,
): void {
- const { route, traceParentData, baggage, params } = extractNextDataTagInformation();
+ const { route, params, sentryTrace, baggage } = extractNextDataTagInformation();
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
+
+ getCurrentHub().getScope().setPropagationContext(propagationContext);
prevLocationName = route || globalObject.location.pathname;
if (startTransactionOnPageLoad) {
const source = route ? 'route' : 'url';
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggage);
-
activeTransaction = startTransactionCb({
name: prevLocationName,
op: 'pageload',
tags: DEFAULT_TAGS,
...(params && client && client.getOptions().sendDefaultPii && { data: params }),
- ...traceParentData,
+ ...traceparentData,
metadata: {
source,
- dynamicSamplingContext: traceParentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
+ dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
},
});
}
diff --git a/packages/nextjs/src/config/types.ts b/packages/nextjs/src/config/types.ts
index 28f70d62dc05..5bab88555056 100644
--- a/packages/nextjs/src/config/types.ts
+++ b/packages/nextjs/src/config/types.ts
@@ -49,6 +49,8 @@ export type NextConfigObject = {
publicRuntimeConfig?: { [key: string]: unknown };
// File extensions that count as pages in the `pages/` directory
pageExtensions?: string[];
+ // Whether Next.js should do a static export
+ output?: string;
// Paths to reroute when requested
rewrites?: () => Promise<
| NextRewrite[]
diff --git a/packages/nextjs/src/config/webpack.ts b/packages/nextjs/src/config/webpack.ts
index bb5ef56ce4ad..fd5b36f9a789 100644
--- a/packages/nextjs/src/config/webpack.ts
+++ b/packages/nextjs/src/config/webpack.ts
@@ -865,7 +865,10 @@ function addValueInjectionLoader(
const isomorphicValues = {
// `rewritesTunnel` set by the user in Next.js config
- __sentryRewritesTunnelPath__: userSentryOptions.tunnelRoute,
+ __sentryRewritesTunnelPath__:
+ userSentryOptions.tunnelRoute !== undefined && userNextConfig.output !== 'export'
+ ? `${userNextConfig.basePath ?? ''}${userSentryOptions.tunnelRoute}`
+ : undefined,
// The webpack plugin's release injection breaks the `app` directory so we inject the release manually here instead.
// Having a release defined in dev-mode spams releases in Sentry so we only set one in non-dev mode
diff --git a/packages/nextjs/src/config/withSentryConfig.ts b/packages/nextjs/src/config/withSentryConfig.ts
index c35e069eea1e..86f8c5a67031 100644
--- a/packages/nextjs/src/config/withSentryConfig.ts
+++ b/packages/nextjs/src/config/withSentryConfig.ts
@@ -8,6 +8,8 @@ import type {
} from './types';
import { constructWebpackConfigFunction } from './webpack';
+let showedExportModeTunnelWarning = false;
+
/**
* Add Sentry options to the config to be exported from the user's `next.config.js` file.
*
@@ -48,7 +50,17 @@ function getFinalConfigObject(
delete incomingUserNextConfigObject.sentry;
if (userSentryOptions?.tunnelRoute) {
- setUpTunnelRewriteRules(incomingUserNextConfigObject, userSentryOptions.tunnelRoute);
+ if (incomingUserNextConfigObject.output === 'export') {
+ if (!showedExportModeTunnelWarning) {
+ showedExportModeTunnelWarning = true;
+ // eslint-disable-next-line no-console
+ console.warn(
+ '[@sentry/nextjs] The Sentry Next.js SDK `tunnelRoute` option will not work in combination with Next.js static exports. The `tunnelRoute` option uses serverside features that cannot be accessed in export mode. If you still want to tunnel Sentry events, set up your own tunnel: https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option',
+ );
+ }
+ } else {
+ setUpTunnelRewriteRules(incomingUserNextConfigObject, userSentryOptions.tunnelRoute);
+ }
}
return {
diff --git a/packages/nextjs/src/edge/edgeclient.ts b/packages/nextjs/src/edge/edgeclient.ts
index ce13d6666448..39b795c81a53 100644
--- a/packages/nextjs/src/edge/edgeclient.ts
+++ b/packages/nextjs/src/edge/edgeclient.ts
@@ -1,14 +1,22 @@
import type { Scope } from '@sentry/core';
-import { addTracingExtensions, BaseClient, createCheckInEnvelope, SDK_VERSION } from '@sentry/core';
+import {
+ addTracingExtensions,
+ BaseClient,
+ createCheckInEnvelope,
+ getDynamicSamplingContextFromClient,
+ SDK_VERSION,
+} from '@sentry/core';
import type {
CheckIn,
ClientOptions,
+ DynamicSamplingContext,
Event,
EventHint,
MonitorConfig,
SerializedCheckIn,
Severity,
SeverityLevel,
+ TraceContext,
} from '@sentry/types';
import { logger, uuid4 } from '@sentry/utils';
@@ -72,7 +80,7 @@ export class EdgeClient extends BaseClient {
* @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
* to create a monitor automatically when sending a check in.
*/
- public captureCheckIn(checkIn: CheckIn, monitorConfig?: MonitorConfig): string {
+ public captureCheckIn(checkIn: CheckIn, monitorConfig?: MonitorConfig, scope?: Scope): string {
const id = checkIn.status !== 'in_progress' && checkIn.checkInId ? checkIn.checkInId : uuid4();
if (!this._isEnabled()) {
__DEBUG_BUILD__ && logger.warn('SDK not enabled, will not capture checkin.');
@@ -103,7 +111,20 @@ export class EdgeClient extends BaseClient {
};
}
- const envelope = createCheckInEnvelope(serializedCheckIn, this.getSdkMetadata(), tunnel, this.getDsn());
+ const [dynamicSamplingContext, traceContext] = this._getTraceInfoFromScope(scope);
+ if (traceContext) {
+ serializedCheckIn.contexts = {
+ trace: traceContext,
+ };
+ }
+
+ const envelope = createCheckInEnvelope(
+ serializedCheckIn,
+ dynamicSamplingContext,
+ this.getSdkMetadata(),
+ tunnel,
+ this.getDsn(),
+ );
__DEBUG_BUILD__ && logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status);
void this._sendEnvelope(envelope);
@@ -124,4 +145,30 @@ export class EdgeClient extends BaseClient {
event.server_name = event.server_name || process.env.SENTRY_NAME;
return super._prepareEvent(event, hint, scope);
}
+
+ /** Extract trace information from scope */
+ private _getTraceInfoFromScope(
+ scope: Scope | undefined,
+ ): [dynamicSamplingContext: Partial | undefined, traceContext: TraceContext | undefined] {
+ if (!scope) {
+ return [undefined, undefined];
+ }
+
+ const span = scope.getSpan();
+ if (span) {
+ return [span?.transaction?.getDynamicSamplingContext(), span?.getTraceContext()];
+ }
+
+ const { traceId, spanId, parentSpanId, dsc } = scope.getPropagationContext();
+ const traceContext: TraceContext = {
+ trace_id: traceId,
+ span_id: spanId,
+ parent_span_id: parentSpanId,
+ };
+ if (dsc) {
+ return [dsc, traceContext];
+ }
+
+ return [getDynamicSamplingContextFromClient(traceId, this, scope), traceContext];
+ }
}
diff --git a/packages/nextjs/src/edge/utils/edgeWrapperUtils.ts b/packages/nextjs/src/edge/utils/edgeWrapperUtils.ts
index 384074e317bd..256499c97185 100644
--- a/packages/nextjs/src/edge/utils/edgeWrapperUtils.ts
+++ b/packages/nextjs/src/edge/utils/edgeWrapperUtils.ts
@@ -1,12 +1,6 @@
import { captureException, getCurrentHub, hasTracingEnabled, startTransaction } from '@sentry/core';
import type { Span } from '@sentry/types';
-import {
- addExceptionMechanism,
- baggageHeaderToDynamicSamplingContext,
- extractTraceparentData,
- logger,
- objectify,
-} from '@sentry/utils';
+import { addExceptionMechanism, logger, objectify, tracingContextFromHeaders } from '@sentry/utils';
import type { EdgeRouteHandler } from '../types';
import { flush } from './flush';
@@ -32,17 +26,17 @@ export function withEdgeWrapping(
op: options.spanOp,
});
} else if (req instanceof Request) {
- // If there is a trace header set, extract the data from it (parentSpanId, traceId, and sampling decision)
- let traceparentData;
-
- const sentryTraceHeader = req.headers.get('sentry-trace');
- if (sentryTraceHeader) {
- traceparentData = extractTraceparentData(sentryTraceHeader);
- __DEBUG_BUILD__ && logger.log(`[Tracing] Continuing trace ${traceparentData?.traceId}.`);
+ const sentryTrace = req.headers.get('sentry-trace') || '';
+ const baggage = req.headers.get('baggage');
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
+ currentScope.setPropagationContext(propagationContext);
+ if (traceparentData) {
+ __DEBUG_BUILD__ && logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`);
}
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(req.headers.get('baggage'));
-
span = startTransaction({
name: options.spanDescription,
op: options.spanOp,
diff --git a/packages/nextjs/src/server/utils/wrapperUtils.ts b/packages/nextjs/src/server/utils/wrapperUtils.ts
index c0fb4037c58b..a3cf13736900 100644
--- a/packages/nextjs/src/server/utils/wrapperUtils.ts
+++ b/packages/nextjs/src/server/utils/wrapperUtils.ts
@@ -6,7 +6,7 @@ import {
startTransaction,
} from '@sentry/core';
import type { Span, Transaction } from '@sentry/types';
-import { baggageHeaderToDynamicSamplingContext, extractTraceparentData } from '@sentry/utils';
+import { isString, tracingContextFromHeaders } from '@sentry/utils';
import type { IncomingMessage, ServerResponse } from 'http';
import { platformSupportsStreaming } from './platformSupportsStreaming';
@@ -38,6 +38,7 @@ function setTransactionOnRequest(transaction: Transaction, req: IncomingMessage)
*
* Note: This function turns the wrapped function into an asynchronous one.
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function withErrorInstrumentation any>(
origFunction: F,
): (...params: Parameters) => Promise> {
@@ -66,6 +67,7 @@ export function withErrorInstrumentation any>(
* @param options Options providing details for the created transaction and span.
* @returns what the data fetching method call returned.
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function withTracedServerSideDataFetcher Promise | any>(
origDataFetcher: F,
req: IncomingMessage,
@@ -86,12 +88,14 @@ export function withTracedServerSideDataFetcher Pr
const previousSpan: Span | undefined = getTransactionFromRequest(req) ?? scope.getSpan();
let dataFetcherSpan;
- const sentryTraceHeader = req.headers['sentry-trace'];
- const rawBaggageString = req.headers && req.headers.baggage;
- const traceparentData =
- typeof sentryTraceHeader === 'string' ? extractTraceparentData(sentryTraceHeader) : undefined;
-
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(rawBaggageString);
+ const sentryTrace =
+ req.headers && isString(req.headers['sentry-trace']) ? req.headers['sentry-trace'] : undefined;
+ const baggage = req.headers?.baggage;
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
+ scope.setPropagationContext(propagationContext);
if (platformSupportsStreaming()) {
let spanToContinue: Span;
diff --git a/packages/nextjs/src/server/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/server/wrapApiHandlerWithSentry.ts
index 9aecbd9a6c6b..524e29fa0ca0 100644
--- a/packages/nextjs/src/server/wrapApiHandlerWithSentry.ts
+++ b/packages/nextjs/src/server/wrapApiHandlerWithSentry.ts
@@ -3,12 +3,11 @@ import { captureException, startTransaction } from '@sentry/node';
import type { Transaction } from '@sentry/types';
import {
addExceptionMechanism,
- baggageHeaderToDynamicSamplingContext,
- extractTraceparentData,
isString,
logger,
objectify,
stripUrlQueryAndFragment,
+ tracingContextFromHeaders,
} from '@sentry/utils';
import type { AugmentedNextApiRequest, AugmentedNextApiResponse, NextApiHandler } from './types';
@@ -73,15 +72,18 @@ export function withSentry(apiHandler: NextApiHandler, parameterizedRoute?: stri
currentScope.setSDKProcessingMetadata({ request: req });
if (hasTracingEnabled(options) && options?.instrumenter === 'sentry') {
- // If there is a trace header set, extract the data from it (parentSpanId, traceId, and sampling decision)
- let traceparentData;
- if (req.headers && isString(req.headers['sentry-trace'])) {
- traceparentData = extractTraceparentData(req.headers['sentry-trace']);
- __DEBUG_BUILD__ && logger.log(`[Tracing] Continuing trace ${traceparentData?.traceId}.`);
- }
+ const sentryTrace =
+ req.headers && isString(req.headers['sentry-trace']) ? req.headers['sentry-trace'] : undefined;
+ const baggage = req.headers?.baggage;
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
+ hub.getScope().setPropagationContext(propagationContext);
- const baggageHeader = req.headers && req.headers.baggage;
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggageHeader);
+ if (__DEBUG_BUILD__ && traceparentData) {
+ logger.log(`[Tracing] Continuing trace ${traceparentData.traceId}.`);
+ }
// prefer the parameterized route, if we have it (which we will if we've auto-wrapped the route handler)
let reqPath = parameterizedRoute;
diff --git a/packages/nextjs/src/server/wrapServerComponentWithSentry.ts b/packages/nextjs/src/server/wrapServerComponentWithSentry.ts
index 8b0f1d8f2d79..81f030fa824c 100644
--- a/packages/nextjs/src/server/wrapServerComponentWithSentry.ts
+++ b/packages/nextjs/src/server/wrapServerComponentWithSentry.ts
@@ -5,7 +5,7 @@ import {
runWithAsyncContext,
startTransaction,
} from '@sentry/core';
-import { baggageHeaderToDynamicSamplingContext, extractTraceparentData } from '@sentry/utils';
+import { tracingContextFromHeaders } from '@sentry/utils';
import { isNotFoundNavigationError, isRedirectNavigationError } from '../common/nextNavigationErrorUtils';
import type { ServerComponentContext } from '../common/types';
@@ -13,6 +13,7 @@ import type { ServerComponentContext } from '../common/types';
/**
* Wraps an `app` directory server component with Sentry error instrumentation.
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapServerComponentWithSentry any>(
appDirComponent: F,
context: ServerComponentContext,
@@ -28,14 +29,15 @@ export function wrapServerComponentWithSentry any>
apply: (originalFunction, thisArg, args) => {
return runWithAsyncContext(() => {
const hub = getCurrentHub();
+ const currentScope = hub.getScope();
let maybePromiseResult;
- const traceparentData = context.sentryTraceHeader
- ? extractTraceparentData(context.sentryTraceHeader)
- : undefined;
-
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(context.baggageHeader);
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ context.sentryTraceHeader,
+ context.baggageHeader,
+ );
+ currentScope.setPropagationContext(propagationContext);
const transaction = startTransaction({
op: 'function.nextjs',
@@ -48,7 +50,6 @@ export function wrapServerComponentWithSentry any>
},
});
- const currentScope = hub.getScope();
if (currentScope) {
currentScope.setSpan(transaction);
}
diff --git a/packages/nextjs/test/buildProcess/testApp/yarn.lock b/packages/nextjs/test/buildProcess/testApp/yarn.lock
index 6d3ceaa61296..cbe67329d3d6 100644
--- a/packages/nextjs/test/buildProcess/testApp/yarn.lock
+++ b/packages/nextjs/test/buildProcess/testApp/yarn.lock
@@ -2,6 +2,11 @@
# yarn lockfile v1
+"@jridgewell/sourcemap-codec@^1.4.13":
+ version "1.4.15"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
+ integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
+
"@mapbox/node-pre-gyp@^1.0.5":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
@@ -87,36 +92,48 @@
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.1.tgz#469dde61519f6a310874af93ee5969f1d5ff6d03"
integrity sha512-t/0G33t/6VGWZUGCOT7rG42qqvf/x+MrFp1CU+8CN6PrjSSL57R5bqkXfubV9t4eCEnUxVP+5Hn3MoEXEebtEw==
-"@rollup/plugin-sucrase@4.0.4":
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-sucrase/-/plugin-sucrase-4.0.4.tgz#0a3b3d97cdc239ec3399f5a10711f751e9f95d98"
- integrity sha512-YH4J8yoJb5EVnLhAwWxYAQNh2SJOR+SdZ6XdgoKEv6Kxm33riYkM8MlMaggN87UoISP52qAFyZ5ey56wu6umGg==
- dependencies:
- "@rollup/pluginutils" "^4.1.1"
- sucrase "^3.20.0"
-
-"@rollup/plugin-virtual@3.0.0":
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/@rollup/plugin-virtual/-/plugin-virtual-3.0.0.tgz#8c3f54b4ab4b267d9cd3dcbaedc58d4fd1deddca"
- integrity sha512-K9KORe1myM62o0lKkNR4MmCxjwuAXsZEtIHpaILfv4kILXTOrXt/R2ha7PzMcCHPYdnkWPiBZK8ed4Zr3Ll5lQ==
+"@rollup/plugin-commonjs@24.0.0":
+ version "24.0.0"
+ resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.0.tgz#fb7cf4a6029f07ec42b25daa535c75b05a43f75c"
+ integrity sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==
+ dependencies:
+ "@rollup/pluginutils" "^5.0.1"
+ commondir "^1.0.1"
+ estree-walker "^2.0.2"
+ glob "^8.0.3"
+ is-reference "1.2.1"
+ magic-string "^0.27.0"
+
+"@rollup/pluginutils@^5.0.1":
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33"
+ integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==
+ dependencies:
+ "@types/estree" "^1.0.0"
+ estree-walker "^2.0.2"
+ picomatch "^2.3.1"
-"@rollup/pluginutils@^4.1.1":
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d"
- integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==
+"@sentry-internal/tracing@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.57.0.tgz#cb761931b635f8f24c84be0eecfacb8516b20551"
+ integrity sha512-tpViyDd8AhQGYYhI94xi2aaDopXOPfL2Apwrtb3qirWkomIQ2K86W1mPmkce+B0cFOnW2Dxv/ZTFKz6ghjK75A==
dependencies:
- estree-walker "^2.0.1"
- picomatch "^2.2.2"
+ "@sentry/core" "7.57.0"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
+ tslib "^2.4.1 || ^1.9.3"
-"@sentry/browser@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.20.0.tgz#e917cab48d3bba2fe8a2e3a8987b0bd9b9149db8"
- integrity sha512-L84CdB7DPQ2ohVcWh/KivemndWSZyXRvBZBr+tHFlQchzcaZZ/8lIPvjwvb8OJhzhecDq6JCAyUxaZwyItdyAg==
+"@sentry/browser@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.57.0.tgz#6e724c9eac680dba99ced0fdf81be8d1e3b3bceb"
+ integrity sha512-E0HaYYlaqHFiIRZXxcvOO8Odvlt+TR1vFFXzqUWXPOvDRxURglTOCQ3EN/u6bxtAGJ6y/Zc2obgihTtypuel/w==
dependencies:
- "@sentry/core" "7.20.0"
- "@sentry/types" "7.20.0"
- "@sentry/utils" "7.20.0"
- tslib "^1.9.3"
+ "@sentry-internal/tracing" "7.57.0"
+ "@sentry/core" "7.57.0"
+ "@sentry/replay" "7.57.0"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
+ tslib "^2.4.1 || ^1.9.3"
"@sentry/cli@^1.74.6":
version "1.74.6"
@@ -131,88 +148,87 @@
proxy-from-env "^1.1.0"
which "^2.0.2"
-"@sentry/core@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.20.0.tgz#7becd848c982d5422627f69c4061d5914946c54a"
- integrity sha512-8dIHk8niyEyVayUQpgECHnV2p444nPBjIyuQrtkdTxL7sBLC5+Y0DhRjxg9cJyZe/bZnXVerGkgcA7niKW4W8A==
+"@sentry/core@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.57.0.tgz#65093d739c04f320a54395a21be955fcbe326acb"
+ integrity sha512-l014NudPH0vQlzybtXajPxYFfs9w762NoarjObC3gu76D1jzBBFzhdRelkGpDbSLNTIsKhEDDRpgAjBWJ9icfw==
dependencies:
- "@sentry/types" "7.20.0"
- "@sentry/utils" "7.20.0"
- tslib "^1.9.3"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
+ tslib "^2.4.1 || ^1.9.3"
-"@sentry/integrations@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.20.0.tgz#78fc544847c5516acb86fc507d0bfdaedb295fd8"
- integrity sha512-wT00rtdKiVOZm/2fGEotIQ2ItCU9xTODz3KveQLq2X2nI5Jg4opkDOY2NorEnuOfBNg6BncBxaC8TG8ujvRyfw==
+"@sentry/integrations@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.57.0.tgz#298085b3a2fe862cc70bc7f2143aa0fbc617322c"
+ integrity sha512-C3WZo5AGI2L0dj+mIjeZpdAwDEG2nDYvZbTzq5J9hVoHFdP3t7fOWBHSPkSFVtTdMaJrv+82aKnUefVCeAjxGg==
dependencies:
- "@sentry/types" "7.20.0"
- "@sentry/utils" "7.20.0"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
localforage "^1.8.1"
- tslib "^1.9.3"
+ tslib "^2.4.1 || ^1.9.3"
"@sentry/nextjs@file:../../..":
- version "7.20.0"
- dependencies:
- "@rollup/plugin-sucrase" "4.0.4"
- "@rollup/plugin-virtual" "3.0.0"
- "@sentry/core" "7.20.0"
- "@sentry/integrations" "7.20.0"
- "@sentry/node" "7.20.0"
- "@sentry/react" "7.20.0"
- "@sentry/tracing" "7.20.0"
- "@sentry/types" "7.20.0"
- "@sentry/utils" "7.20.0"
+ version "7.57.0"
+ dependencies:
+ "@rollup/plugin-commonjs" "24.0.0"
+ "@sentry/core" "7.57.0"
+ "@sentry/integrations" "7.57.0"
+ "@sentry/node" "7.57.0"
+ "@sentry/react" "7.57.0"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
"@sentry/webpack-plugin" "1.20.0"
chalk "3.0.0"
rollup "2.78.0"
- tslib "^1.9.3"
-
-"@sentry/node@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.20.0.tgz#a32e37b2c93607e8b8d7f3741f60418ec2d99ddb"
- integrity sha512-aB0VSueCiWPg53DIevnKNYSu2OGsPweWO1eKhMhu1uJNbL+ZYAFRczdcLdkWCqa38X5jjqO82GKuIZYpXUGX+A==
- dependencies:
- "@sentry/core" "7.20.0"
- "@sentry/types" "7.20.0"
- "@sentry/utils" "7.20.0"
+ stacktrace-parser "^0.1.10"
+ tslib "^2.4.1 || ^1.9.3"
+
+"@sentry/node@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.57.0.tgz#31052f5988ed4496d7f3ff925240cf9b02d09941"
+ integrity sha512-63mjyUVM6sfJFVQ5TGVRVGUsoEfESl5ABzIW1W0s9gUiQPaG8SOdaQJglb2VNrkMYxnRHgD8Q9LUh/qcmUyPGw==
+ dependencies:
+ "@sentry-internal/tracing" "7.57.0"
+ "@sentry/core" "7.57.0"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
cookie "^0.4.1"
https-proxy-agent "^5.0.0"
lru_map "^0.3.3"
- tslib "^1.9.3"
+ tslib "^2.4.1 || ^1.9.3"
-"@sentry/react@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.20.0.tgz#41e1edb5a7330bf15ab06e0c0b3e0be7cf36a7d3"
- integrity sha512-hXPObzl4I7TgeCGEb3b03yLI7zF/oYQ5NoGz65fmhUainOGuW+S8KSyCWmAvaHXZ1cZao+sLfQSxl29sVVQyww==
+"@sentry/react@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.57.0.tgz#cf91f0115bcd2a8306d6c8a39d8e8b53d4b21814"
+ integrity sha512-XGNTjIoCG3naSmCU8qObd+y+CqAB6NQkGWOp2yyBwp2inyKF2ehJvDh6bIQloBYq2TmOJDa4NfXdMrkilxaLFQ==
dependencies:
- "@sentry/browser" "7.20.0"
- "@sentry/types" "7.20.0"
- "@sentry/utils" "7.20.0"
+ "@sentry/browser" "7.57.0"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
hoist-non-react-statics "^3.3.2"
- tslib "^1.9.3"
+ tslib "^2.4.1 || ^1.9.3"
-"@sentry/tracing@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.20.0.tgz#346bf72bc5574ac78de43bd8ab6f6027f8b64cbd"
- integrity sha512-qg3sMvjuMQl/NEaF8I2IpvUcJ4HGGVIwEqqqZ6hkeHXIKt02p6f+nls45pVhluMiNHAaQJ+vefMTUc3E1yZwDA==
+"@sentry/replay@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.57.0.tgz#c8f7eae7b7edc9d32c3d2955b337f3b3c76dff39"
+ integrity sha512-pN4ryNS3J5EYbkXvR+O/+hseAJha7XDl8mPFtK0OGTHG10JzCi4tQJazblHQdpb5QBaMMPCeZ+isyfoQLDNXnw==
dependencies:
- "@sentry/core" "7.20.0"
- "@sentry/types" "7.20.0"
- "@sentry/utils" "7.20.0"
- tslib "^1.9.3"
+ "@sentry/core" "7.57.0"
+ "@sentry/types" "7.57.0"
+ "@sentry/utils" "7.57.0"
-"@sentry/types@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.20.0.tgz#ace232e00407355dccedf65e27471635b4331265"
- integrity sha512-x17ddduGWqW95neBFVvxzmInb5WXVw+2PcNASHXpGFhi7v2gz2a7/w2CcIKxsqODNnc+z/k1t0Y+uy9B6aH6ag==
+"@sentry/types@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.57.0.tgz#4fdb80cbd49ba034dd8d9be0c0005a016d5db3ce"
+ integrity sha512-D7ifoUfxuVCUyktIr5Gc+jXUbtcUMmfHdTtTbf1XCZHua5mJceK9wtl3YCg3eq/HK2Ppd52BKnTzEcS5ZKQM+w==
-"@sentry/utils@7.20.0":
- version "7.20.0"
- resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.20.0.tgz#cca09e2256b64bfb41a78c89af3c88fcc7ca84c2"
- integrity sha512-4lc122TFgkaCAvoPRy+uc5vgOCumTa/2nPkzCSxVsezQs+ebHxyMJQK7GWBLI6P+EzKfEjlgyMzRWaPJ3iJatA==
+"@sentry/utils@7.57.0":
+ version "7.57.0"
+ resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.57.0.tgz#8253c6fcf35138b4c424234b8da1596e11b98ad8"
+ integrity sha512-YXrkMCiNklqkXctn4mKYkrzNCf/dfVcRUQrkXjeBC+PHXbcpPyaJgInNvztR7Skl8lE3JPGPN4v5XhLxK1bUUg==
dependencies:
- "@sentry/types" "7.20.0"
- tslib "^1.9.3"
+ "@sentry/types" "7.57.0"
+ tslib "^2.4.1 || ^1.9.3"
"@sentry/webpack-plugin@1.20.0":
version "1.20.0"
@@ -229,6 +245,11 @@
dependencies:
tslib "^2.4.0"
+"@types/estree@*", "@types/estree@^1.0.0":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194"
+ integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==
+
"@vercel/nft@latest":
version "0.22.1"
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.22.1.tgz#0d91d2a21e3a7f0b23ce1550da9870eac4942828"
@@ -280,11 +301,6 @@ ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
-any-promise@^1.0.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
- integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
-
aproba@^1.0.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -336,6 +352,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
+brace-expansion@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
+ integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
+ dependencies:
+ balanced-match "^1.0.0"
+
braces@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@@ -388,10 +411,10 @@ color-support@^1.1.2:
resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
-commander@^4.0.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
- integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
+commondir@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+ integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
concat-map@0.0.1:
version "0.0.1"
@@ -435,7 +458,7 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-estree-walker@2.0.2, estree-walker@^2.0.1:
+estree-walker@2.0.2, estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
@@ -503,29 +526,28 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
-glob@7.1.6:
- version "7.1.6"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
- integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
+glob@^7.1.3:
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
+ integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
- minimatch "^3.0.4"
+ minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
-glob@^7.1.3:
- version "7.2.3"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
- integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
+glob@^8.0.3:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
+ integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
- minimatch "^3.1.1"
+ minimatch "^5.0.1"
once "^1.3.0"
- path-is-absolute "^1.0.0"
graceful-fs@^4.2.9:
version "4.2.10"
@@ -592,6 +614,13 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+is-reference@1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
+ integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
+ dependencies:
+ "@types/estree" "*"
+
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@@ -614,11 +643,6 @@ lie@3.1.1:
dependencies:
immediate "~3.0.5"
-lines-and-columns@^1.1.6:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
- integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
-
localforage@^1.8.1:
version "1.10.0"
resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4"
@@ -645,6 +669,13 @@ lru_map@^0.3.3:
resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd"
integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==
+magic-string@^0.27.0:
+ version "0.27.0"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
+ integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.4.13"
+
make-dir@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
@@ -660,13 +691,20 @@ micromatch@^4.0.2:
braces "^3.0.2"
picomatch "^2.3.1"
-minimatch@^3.0.4, minimatch@^3.1.1:
+minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
+minimatch@^5.0.1:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
+ integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
+ dependencies:
+ brace-expansion "^2.0.1"
+
minimist@^1.2.6:
version "1.2.7"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
@@ -704,15 +742,6 @@ ms@2.1.2:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-mz@^2.7.0:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
- integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
- dependencies:
- any-promise "^1.0.0"
- object-assign "^4.0.1"
- thenify-all "^1.0.0"
-
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
@@ -788,7 +817,7 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
-object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
+object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@@ -810,16 +839,11 @@ picocolors@^1.0.0:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
-picomatch@^2.2.2, picomatch@^2.3.1:
+picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-pirates@^4.0.1:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b"
- integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==
-
postcss@8.4.14:
version "8.4.14"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf"
@@ -930,14 +954,14 @@ scheduler@^0.23.0:
loose-envify "^1.1.0"
semver@^6.0.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.5:
- version "7.3.8"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
- integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
+ version "7.5.4"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
+ integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
@@ -956,6 +980,13 @@ source-map-js@^1.0.2:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+stacktrace-parser@^0.1.10:
+ version "0.1.10"
+ resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a"
+ integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==
+ dependencies:
+ type-fest "^0.7.1"
+
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -1009,18 +1040,6 @@ styled-jsx@5.1.0:
dependencies:
client-only "0.0.1"
-sucrase@^3.20.0:
- version "3.29.0"
- resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.29.0.tgz#3207c5bc1b980fdae1e539df3f8a8a518236da7d"
- integrity sha512-bZPAuGA5SdFHuzqIhTAqt9fvNEo9rESqXIG3oiKdF8K4UmkQxC4KlNL3lVyAErXp+mPvUqZ5l13qx6TrDIGf3A==
- dependencies:
- commander "^4.0.0"
- glob "7.1.6"
- lines-and-columns "^1.1.6"
- mz "^2.7.0"
- pirates "^4.0.1"
- ts-interface-checker "^0.1.9"
-
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
@@ -1040,20 +1059,6 @@ tar@^6.1.11:
mkdirp "^1.0.3"
yallist "^4.0.0"
-thenify-all@^1.0.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
- integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==
- dependencies:
- thenify ">= 3.1.0 < 4"
-
-"thenify@>= 3.1.0 < 4":
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
- integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
- dependencies:
- any-promise "^1.0.0"
-
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
@@ -1066,21 +1071,21 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
-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"
- integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
-
-tslib@^1.9.3:
- version "1.14.1"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
- integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-
tslib@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
+"tslib@^2.4.1 || ^1.9.3":
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3"
+ integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==
+
+type-fest@^0.7.1:
+ version "0.7.1"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48"
+ integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==
+
use-sync-external-store@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
diff --git a/packages/nextjs/test/integration/sentry.client.config.js b/packages/nextjs/test/integration/sentry.client.config.js
index e8da7a90914b..dbb6e760ea8d 100644
--- a/packages/nextjs/test/integration/sentry.client.config.js
+++ b/packages/nextjs/test/integration/sentry.client.config.js
@@ -3,7 +3,7 @@ import { Integrations } from '@sentry/tracing';
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
- tracesSampleRate: 1,
+ tracesSampler: () => true,
debug: process.env.SDK_DEBUG,
integrations: [
diff --git a/packages/nextjs/test/integration/sentry.edge.config.js b/packages/nextjs/test/integration/sentry.edge.config.js
index 8d83922b637d..36600e702048 100644
--- a/packages/nextjs/test/integration/sentry.edge.config.js
+++ b/packages/nextjs/test/integration/sentry.edge.config.js
@@ -2,6 +2,7 @@ import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
- tracesSampleRate: 1,
+ tracesSampleRate: 1.0,
+ tracePropagationTargets: ['http://example.com'],
debug: process.env.SDK_DEBUG,
});
diff --git a/packages/nextjs/test/integration/sentry.server.config.js b/packages/nextjs/test/integration/sentry.server.config.js
index da0759f4475e..54c5db73a1a2 100644
--- a/packages/nextjs/test/integration/sentry.server.config.js
+++ b/packages/nextjs/test/integration/sentry.server.config.js
@@ -2,7 +2,8 @@ import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
- tracesSampleRate: 1,
+ tracesSampleRate: 1.0,
+ tracePropagationTargets: ['http://example.com'],
debug: process.env.SDK_DEBUG,
integrations: defaults => [
diff --git a/packages/node-integration-tests/suites/express/handle-error/test.ts b/packages/node-integration-tests/suites/express/handle-error/test.ts
index e8be4081203c..d9eb59a72785 100644
--- a/packages/node-integration-tests/suites/express/handle-error/test.ts
+++ b/packages/node-integration-tests/suites/express/handle-error/test.ts
@@ -11,8 +11,8 @@ test('should capture and send Express controller error.', async () => {
values: [
{
mechanism: {
- type: 'generic',
- handled: true,
+ type: 'middleware',
+ handled: false,
},
type: 'Error',
value: 'test_error',
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-assign/test.ts b/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-assign/test.ts
index 65aea16c60a1..79b98772fe39 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-assign/test.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-assign/test.ts
@@ -76,8 +76,8 @@ test('Should populate and propagate sentry baggage if sentry-trace header does n
test_data: {
host: 'somewhere.not.sentry',
// TraceId changes, hence we only expect that the string contains the traceid key
- baggage: expect.stringContaining(
- 'sentry-environment=prod,sentry-release=1.0,sentry-transaction=GET%20%2Ftest%2Fexpress,sentry-public_key=public,sentry-trace_id=',
+ baggage: expect.stringMatching(
+ /sentry-environment=prod,sentry-release=1.0,sentry-public_key=public,sentry-trace_id=[\S]*,sentry-sample_rate=1,sentry-transaction=GET%20%2Ftest%2Fexpress/,
),
},
});
@@ -95,8 +95,8 @@ test('Should populate Sentry and ignore 3rd party content if sentry-trace header
test_data: {
host: 'somewhere.not.sentry',
// TraceId changes, hence we only expect that the string contains the traceid key
- baggage: expect.stringContaining(
- 'sentry-environment=prod,sentry-release=1.0,sentry-transaction=GET%20%2Ftest%2Fexpress,sentry-public_key=public,sentry-trace_id=',
+ baggage: expect.stringMatching(
+ /sentry-environment=prod,sentry-release=1.0,sentry-public_key=public,sentry-trace_id=[\S]*,sentry-sample_rate=1,sentry-transaction=GET%20%2Ftest%2Fexpress/,
),
},
});
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts b/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts
index f582288f8314..750f49b40210 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts
@@ -12,6 +12,7 @@ Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
environment: 'prod',
+ tracePropagationTargets: [/^(?!.*express).*$/],
// eslint-disable-next-line deprecation/deprecation
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
tracesSampleRate: 1.0,
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/test.ts b/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/test.ts
index 71defa704bba..4a3303af9863 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/test.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/test.ts
@@ -13,8 +13,9 @@ test('should attach a `baggage` header to an outgoing request.', async () => {
test_data: {
host: 'somewhere.not.sentry',
baggage:
- 'sentry-environment=prod,sentry-release=1.0,sentry-transaction=GET%20%2Ftest%2Fexpress,sentry-user_segment=SegmentA' +
- ',sentry-public_key=public,sentry-trace_id=86f39e84263a4de99c326acab3bfe3bd,sentry-sample_rate=1',
+ 'sentry-environment=prod,sentry-release=1.0,sentry-user_segment=SegmentA,sentry-public_key=public' +
+ ',sentry-trace_id=86f39e84263a4de99c326acab3bfe3bd,sentry-sample_rate=1,sentry-transaction=GET%20%2Ftest%2Fexpress' +
+ ',sentry-sampled=true',
},
});
});
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts b/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts
index 6674e2a1bb77..93738d4c0a12 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts
@@ -12,6 +12,8 @@ Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
environment: 'prod',
+ // disable requests to /express
+ tracePropagationTargets: [/^(?!.*express).*$/],
// eslint-disable-next-line deprecation/deprecation
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
tracesSampleRate: 1.0,
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/test.ts b/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/test.ts
index 0c2c2d39c606..c20354944a6d 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/test.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/test.ts
@@ -35,7 +35,7 @@ test('should ignore sentry-values in `baggage` header of a third party vendor an
baggage: [
'other=vendor,foo=bar,third=party,sentry-release=9.9.9,sentry-environment=staging,sentry-sample_rate=0.54,last=item',
expect.stringMatching(
- /sentry-environment=prod,sentry-release=1\.0,sentry-transaction=GET%20%2Ftest%2Fexpress,sentry-public_key=public,sentry-trace_id=[0-9a-f]{32},sentry-sample_rate=1/,
+ /sentry-environment=prod,sentry-release=1\.0,sentry-public_key=public,sentry-trace_id=[0-9a-f]{32},sentry-sample_rate=1,sentry-transaction=GET%20%2Ftest%2Fexpress/,
),
],
},
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts b/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts
index 86cfa033b79e..867bb0e6131e 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts
@@ -12,6 +12,8 @@ Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
environment: 'prod',
+ // disable requests to /express
+ tracePropagationTargets: [/^(?!.*express).*$/],
// eslint-disable-next-line deprecation/deprecation
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
tracesSampleRate: 1.0,
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts b/packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts
index 78e24ffa9f10..21738f3b3fb8 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts
@@ -12,6 +12,8 @@ Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
environment: 'prod',
+ // disable requests to /express
+ tracePropagationTargets: [/^(?!.*express).*$/],
// eslint-disable-next-line deprecation/deprecation
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
tracesSampleRate: 1.0,
diff --git a/packages/node-integration-tests/suites/express/sentry-trace/server.ts b/packages/node-integration-tests/suites/express/sentry-trace/server.ts
index 76bb399e3bc0..1cfc02648f02 100644
--- a/packages/node-integration-tests/suites/express/sentry-trace/server.ts
+++ b/packages/node-integration-tests/suites/express/sentry-trace/server.ts
@@ -12,6 +12,7 @@ Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
environment: 'prod',
+ tracePropagationTargets: [/^(?!.*express).*$/],
// eslint-disable-next-line deprecation/deprecation
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
tracesSampleRate: 1.0,
diff --git a/packages/node-integration-tests/suites/express/tracing/server.ts b/packages/node-integration-tests/suites/express/tracing/server.ts
index e857621ad22e..1c56a81fef98 100644
--- a/packages/node-integration-tests/suites/express/tracing/server.ts
+++ b/packages/node-integration-tests/suites/express/tracing/server.ts
@@ -7,6 +7,8 @@ const app = express();
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
+ // disable attaching headers to /test/* endpoints
+ tracePropagationTargets: [/^(?!.*test).*$/],
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })],
tracesSampleRate: 1.0,
});
diff --git a/packages/node-integration-tests/utils/index.ts b/packages/node-integration-tests/utils/index.ts
index cde2cb745cd9..88120853ee69 100644
--- a/packages/node-integration-tests/utils/index.ts
+++ b/packages/node-integration-tests/utils/index.ts
@@ -202,11 +202,11 @@ export class TestEnv {
*/
public async getAPIResponse(
url?: string,
- headers?: Record,
+ headers: Record = {},
endServer: boolean = true,
): Promise {
try {
- const { data } = await axios.get(url || this.url, { headers: headers || {} });
+ const { data } = await axios.get(url || this.url, { headers });
return data;
} finally {
await Sentry.flush();
diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts
index ccdbeda279e1..50af36448046 100644
--- a/packages/node/src/client.ts
+++ b/packages/node/src/client.ts
@@ -1,13 +1,22 @@
import type { Scope } from '@sentry/core';
-import { addTracingExtensions, BaseClient, createCheckInEnvelope, SDK_VERSION, SessionFlusher } from '@sentry/core';
+import {
+ addTracingExtensions,
+ BaseClient,
+ createCheckInEnvelope,
+ getDynamicSamplingContextFromClient,
+ SDK_VERSION,
+ SessionFlusher,
+} from '@sentry/core';
import type {
CheckIn,
+ DynamicSamplingContext,
Event,
EventHint,
MonitorConfig,
SerializedCheckIn,
Severity,
SeverityLevel,
+ TraceContext,
} from '@sentry/types';
import { logger, resolvedSyncPromise, uuid4 } from '@sentry/utils';
import * as os from 'os';
@@ -154,7 +163,7 @@ export class NodeClient extends BaseClient {
* to create a monitor automatically when sending a check in.
* @returns A string representing the id of the check in.
*/
- public captureCheckIn(checkIn: CheckIn, monitorConfig?: MonitorConfig): string {
+ public captureCheckIn(checkIn: CheckIn, monitorConfig?: MonitorConfig, scope?: Scope): string {
const id = checkIn.status !== 'in_progress' && checkIn.checkInId ? checkIn.checkInId : uuid4();
if (!this._isEnabled()) {
__DEBUG_BUILD__ && logger.warn('SDK not enabled, will not capture checkin.');
@@ -185,7 +194,20 @@ export class NodeClient extends BaseClient {
};
}
- const envelope = createCheckInEnvelope(serializedCheckIn, this.getSdkMetadata(), tunnel, this.getDsn());
+ const [dynamicSamplingContext, traceContext] = this._getTraceInfoFromScope(scope);
+ if (traceContext) {
+ serializedCheckIn.contexts = {
+ trace: traceContext,
+ };
+ }
+
+ const envelope = createCheckInEnvelope(
+ serializedCheckIn,
+ dynamicSamplingContext,
+ this.getSdkMetadata(),
+ tunnel,
+ this.getDsn(),
+ );
__DEBUG_BUILD__ && logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status);
void this._sendEnvelope(envelope);
@@ -220,4 +242,30 @@ export class NodeClient extends BaseClient {
this._sessionFlusher.incrementSessionStatusCount();
}
}
+
+ /** Extract trace information from scope */
+ private _getTraceInfoFromScope(
+ scope: Scope | undefined,
+ ): [dynamicSamplingContext: Partial | undefined, traceContext: TraceContext | undefined] {
+ if (!scope) {
+ return [undefined, undefined];
+ }
+
+ const span = scope.getSpan();
+ if (span) {
+ return [span?.transaction?.getDynamicSamplingContext(), span?.getTraceContext()];
+ }
+
+ const { traceId, spanId, parentSpanId, dsc } = scope.getPropagationContext();
+ const traceContext: TraceContext = {
+ trace_id: traceId,
+ span_id: spanId,
+ parent_span_id: parentSpanId,
+ };
+ if (dsc) {
+ return [dsc, traceContext];
+ }
+
+ return [getDynamicSamplingContextFromClient(traceId, this, scope), traceContext];
+ }
}
diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts
index 95a4cfe65e38..6d2545c3bf9d 100644
--- a/packages/node/src/handlers.ts
+++ b/packages/node/src/handlers.ts
@@ -10,14 +10,14 @@ import {
import type { Span } from '@sentry/types';
import type { AddRequestDataToEventOptions } from '@sentry/utils';
import {
+ addExceptionMechanism,
addRequestDataToTransaction,
- baggageHeaderToDynamicSamplingContext,
dropUndefinedKeys,
extractPathForTransaction,
- extractTraceparentData,
isString,
logger,
normalize,
+ tracingContextFromHeaders,
} from '@sentry/utils';
import type * as http from 'http';
@@ -62,11 +62,13 @@ export function tracingHandler(): (
return next();
}
- // If there is a trace header set, we extract the data from it (parentSpanId, traceId, and sampling decision)
- const traceparentData =
- req.headers && isString(req.headers['sentry-trace']) && extractTraceparentData(req.headers['sentry-trace']);
- const incomingBaggageHeaders = req.headers?.baggage;
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(incomingBaggageHeaders);
+ const sentryTrace = req.headers && isString(req.headers['sentry-trace']) ? req.headers['sentry-trace'] : undefined;
+ const baggage = req.headers?.baggage;
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
+ hub.getScope().setPropagationContext(propagationContext);
const [name, source] = extractPathForTransaction(req, { path: true, method: true });
const transaction = startTransaction(
@@ -304,6 +306,11 @@ export function errorHandler(options?: {
}
}
+ _scope.addEventProcessor(event => {
+ addExceptionMechanism(event, { type: 'middleware', handled: false });
+ return event;
+ });
+
const eventId = captureException(error);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
(res as any).sentry = eventId;
diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts
index 0e57936a02a9..1dd778e21199 100644
--- a/packages/node/src/index.ts
+++ b/packages/node/src/index.ts
@@ -60,6 +60,7 @@ export { makeNodeTransport } from './transports';
export { defaultIntegrations, init, defaultStackParser, lastEventId, flush, close, getSentryRelease } from './sdk';
export { addRequestDataToEvent, DEFAULT_USER_INCLUDES, extractRequestData } from './requestdata';
export { deepReadDirSync } from './utils';
+export { getModuleFromFilename } from './module';
import { Integrations as CoreIntegrations } from '@sentry/core';
diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts
index 54d761861348..b210500e90e0 100644
--- a/packages/node/src/integrations/http.ts
+++ b/packages/node/src/integrations/http.ts
@@ -1,14 +1,26 @@
import type { Hub } from '@sentry/core';
-import { getCurrentHub } from '@sentry/core';
-import type { EventProcessor, Integration, SanitizedRequestData, Span, TracePropagationTargets } from '@sentry/types';
-import { dynamicSamplingContextToSentryBaggageHeader, fill, logger, stringMatchesSomePattern } from '@sentry/utils';
+import { getCurrentHub, getDynamicSamplingContextFromClient } from '@sentry/core';
+import type {
+ DynamicSamplingContext,
+ EventProcessor,
+ Integration,
+ SanitizedRequestData,
+ TracePropagationTargets,
+} from '@sentry/types';
+import {
+ dynamicSamplingContextToSentryBaggageHeader,
+ fill,
+ generateSentryTraceHeader,
+ logger,
+ stringMatchesSomePattern,
+} from '@sentry/utils';
import type * as http from 'http';
import type * as https from 'https';
import { LRUMap } from 'lru_map';
import type { NodeClient } from '../client';
import { NODE_VERSION } from '../nodeVersion';
-import type { RequestMethod, RequestMethodArgs } from './utils/http';
+import type { RequestMethod, RequestMethodArgs, RequestOptions } from './utils/http';
import { cleanSpanDescription, extractRawUrl, extractUrl, isSentryRequest, normalizeRequestArgs } from './utils/http';
interface TracingOptions {
@@ -96,13 +108,20 @@ export class Http implements Integration {
return;
}
- // TODO (v8): `tracePropagationTargets` and `shouldCreateSpanForRequest` will be removed from clientOptions
- // and we will no longer have to do this optional merge, we can just pass `this._tracing` directly.
- const tracingOptions = this._tracing ? { ...clientOptions, ...this._tracing } : undefined;
+ const shouldCreateSpanForRequest =
+ // eslint-disable-next-line deprecation/deprecation
+ this._tracing?.shouldCreateSpanForRequest || clientOptions?.shouldCreateSpanForRequest;
+ // eslint-disable-next-line deprecation/deprecation
+ const tracePropagationTargets = clientOptions?.tracePropagationTargets || this._tracing?.tracePropagationTargets;
// eslint-disable-next-line @typescript-eslint/no-var-requires
const httpModule = require('http');
- const wrappedHttpHandlerMaker = _createWrappedRequestMethodFactory(this._breadcrumbs, tracingOptions, httpModule);
+ const wrappedHttpHandlerMaker = _createWrappedRequestMethodFactory(
+ httpModule,
+ this._breadcrumbs,
+ shouldCreateSpanForRequest,
+ tracePropagationTargets,
+ );
fill(httpModule, 'get', wrappedHttpHandlerMaker);
fill(httpModule, 'request', wrappedHttpHandlerMaker);
@@ -113,9 +132,10 @@ export class Http implements Integration {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const httpsModule = require('https');
const wrappedHttpsHandlerMaker = _createWrappedRequestMethodFactory(
- this._breadcrumbs,
- tracingOptions,
httpsModule,
+ this._breadcrumbs,
+ shouldCreateSpanForRequest,
+ tracePropagationTargets,
);
fill(httpsModule, 'get', wrappedHttpsHandlerMaker);
fill(httpsModule, 'request', wrappedHttpsHandlerMaker);
@@ -138,16 +158,17 @@ type WrappedRequestMethodFactory = (original: OriginalRequestMethod) => WrappedR
* @returns A function which accepts the exiting handler and returns a wrapped handler
*/
function _createWrappedRequestMethodFactory(
- breadcrumbsEnabled: boolean,
- tracingOptions: TracingOptions | undefined,
httpModule: typeof http | typeof https,
+ breadcrumbsEnabled: boolean,
+ shouldCreateSpanForRequest: ((url: string) => boolean) | undefined,
+ tracePropagationTargets: TracePropagationTargets | undefined,
): WrappedRequestMethodFactory {
// We're caching results so we don't have to recompute regexp every time we create a request.
const createSpanUrlMap = new LRUMap(100);
const headersUrlMap = new LRUMap(100);
const shouldCreateSpan = (url: string): boolean => {
- if (tracingOptions?.shouldCreateSpanForRequest === undefined) {
+ if (shouldCreateSpanForRequest === undefined) {
return true;
}
@@ -156,14 +177,13 @@ function _createWrappedRequestMethodFactory(
return cachedDecision;
}
- const decision = tracingOptions.shouldCreateSpanForRequest(url);
+ const decision = shouldCreateSpanForRequest(url);
createSpanUrlMap.set(url, decision);
return decision;
};
const shouldAttachTraceData = (url: string): boolean => {
- // eslint-disable-next-line deprecation/deprecation
- if (tracingOptions?.tracePropagationTargets === undefined) {
+ if (tracePropagationTargets === undefined) {
return true;
}
@@ -172,12 +192,41 @@ function _createWrappedRequestMethodFactory(
return cachedDecision;
}
- // eslint-disable-next-line deprecation/deprecation
- const decision = stringMatchesSomePattern(url, tracingOptions.tracePropagationTargets);
+ const decision = stringMatchesSomePattern(url, tracePropagationTargets);
headersUrlMap.set(url, decision);
return decision;
};
+ /**
+ * Captures Breadcrumb based on provided request/response pair
+ */
+ function addRequestBreadcrumb(
+ event: string,
+ requestSpanData: SanitizedRequestData,
+ req: http.ClientRequest,
+ res?: http.IncomingMessage,
+ ): void {
+ if (!getCurrentHub().getIntegration(Http)) {
+ return;
+ }
+
+ getCurrentHub().addBreadcrumb(
+ {
+ category: 'http',
+ data: {
+ status_code: res && res.statusCode,
+ ...requestSpanData,
+ },
+ type: 'http',
+ },
+ {
+ event,
+ request: req,
+ response: res,
+ },
+ );
+ }
+
return function wrappedRequestMethodFactory(originalRequestMethod: OriginalRequestMethod): WrappedRequestMethod {
return function wrappedMethod(this: unknown, ...args: RequestMethodArgs): http.ClientRequest {
const requestArgs = normalizeRequestArgs(httpModule, args);
@@ -191,74 +240,38 @@ function _createWrappedRequestMethodFactory(
return originalRequestMethod.apply(httpModule, requestArgs);
}
- let requestSpan: Span | undefined;
- const parentSpan = getCurrentHub().getScope().getSpan();
-
- const method = requestOptions.method || 'GET';
- const requestSpanData: SanitizedRequestData = {
- url: requestUrl,
- 'http.method': method,
- };
- if (requestOptions.hash) {
- // strip leading "#"
- requestSpanData['http.fragment'] = requestOptions.hash.substring(1);
- }
- if (requestOptions.search) {
- // strip leading "?"
- requestSpanData['http.query'] = requestOptions.search.substring(1);
- }
+ const hub = getCurrentHub();
+ const scope = hub.getScope();
+ const parentSpan = scope.getSpan();
- if (tracingOptions && shouldCreateSpan(rawRequestUrl)) {
- if (parentSpan) {
- requestSpan = parentSpan.startChild({
- description: `${method} ${requestSpanData.url}`,
+ const data = getRequestSpanData(requestUrl, requestOptions);
+
+ const requestSpan = shouldCreateSpan(rawRequestUrl)
+ ? parentSpan?.startChild({
op: 'http.client',
- data: requestSpanData,
- });
-
- if (shouldAttachTraceData(rawRequestUrl)) {
- const sentryTraceHeader = requestSpan.toTraceparent();
- __DEBUG_BUILD__ &&
- logger.log(
- `[Tracing] Adding sentry-trace header ${sentryTraceHeader} to outgoing request to "${requestUrl}": `,
- );
-
- requestOptions.headers = {
- ...requestOptions.headers,
- 'sentry-trace': sentryTraceHeader,
- };
-
- if (parentSpan.transaction) {
- const dynamicSamplingContext = parentSpan.transaction.getDynamicSamplingContext();
- const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
-
- let newBaggageHeaderField;
- if (!requestOptions.headers || !requestOptions.headers.baggage) {
- newBaggageHeaderField = sentryBaggageHeader;
- } else if (!sentryBaggageHeader) {
- newBaggageHeaderField = requestOptions.headers.baggage;
- } else if (Array.isArray(requestOptions.headers.baggage)) {
- newBaggageHeaderField = [...requestOptions.headers.baggage, sentryBaggageHeader];
- } else {
- // Type-cast explanation:
- // Technically this the following could be of type `(number | string)[]` but for the sake of simplicity
- // we say this is undefined behaviour, since it would not be baggage spec conform if the user did this.
- newBaggageHeaderField = [requestOptions.headers.baggage, sentryBaggageHeader] as string[];
- }
-
- requestOptions.headers = {
- ...requestOptions.headers,
- // Setting a hader to `undefined` will crash in node so we only set the baggage header when it's defined
- ...(newBaggageHeaderField && { baggage: newBaggageHeaderField }),
- };
- }
- } else {
- __DEBUG_BUILD__ &&
- logger.log(
- `[Tracing] Not adding sentry-trace header to outgoing request (${requestUrl}) due to mismatching tracePropagationTargets option.`,
- );
- }
+ description: `${data['http.method']} ${data.url}`,
+ data,
+ })
+ : undefined;
+
+ if (shouldAttachTraceData(rawRequestUrl)) {
+ if (requestSpan) {
+ const sentryTraceHeader = requestSpan.toTraceparent();
+ const dynamicSamplingContext = requestSpan?.transaction?.getDynamicSamplingContext();
+ addHeadersToRequestOptions(requestOptions, requestUrl, sentryTraceHeader, dynamicSamplingContext);
+ } else {
+ const client = hub.getClient();
+ const { traceId, sampled, dsc } = scope.getPropagationContext();
+ const sentryTraceHeader = generateSentryTraceHeader(traceId, undefined, sampled);
+ const dynamicSamplingContext =
+ dsc || (client ? getDynamicSamplingContextFromClient(traceId, client, scope) : undefined);
+ addHeadersToRequestOptions(requestOptions, requestUrl, sentryTraceHeader, dynamicSamplingContext);
}
+ } else {
+ __DEBUG_BUILD__ &&
+ logger.log(
+ `[Tracing] Not adding sentry-trace header to outgoing request (${requestUrl}) due to mismatching tracePropagationTargets option.`,
+ );
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -268,7 +281,7 @@ function _createWrappedRequestMethodFactory(
// eslint-disable-next-line @typescript-eslint/no-this-alias
const req = this;
if (breadcrumbsEnabled) {
- addRequestBreadcrumb('response', requestSpanData, req, res);
+ addRequestBreadcrumb('response', data, req, res);
}
if (requestSpan) {
if (res.statusCode) {
@@ -283,7 +296,7 @@ function _createWrappedRequestMethodFactory(
const req = this;
if (breadcrumbsEnabled) {
- addRequestBreadcrumb('error', requestSpanData, req);
+ addRequestBreadcrumb('error', data, req);
}
if (requestSpan) {
requestSpan.setHttpStatus(500);
@@ -295,32 +308,55 @@ function _createWrappedRequestMethodFactory(
};
}
-/**
- * Captures Breadcrumb based on provided request/response pair
- */
-function addRequestBreadcrumb(
- event: string,
- requestSpanData: SanitizedRequestData,
- req: http.ClientRequest,
- res?: http.IncomingMessage,
+function addHeadersToRequestOptions(
+ requestOptions: RequestOptions,
+ requestUrl: string,
+ sentryTraceHeader: string,
+ dynamicSamplingContext: Partial | undefined,
): void {
- if (!getCurrentHub().getIntegration(Http)) {
- return;
+ __DEBUG_BUILD__ &&
+ logger.log(`[Tracing] Adding sentry-trace header ${sentryTraceHeader} to outgoing request to "${requestUrl}": `);
+ const sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
+ const sentryBaggageHeader = normalizeBaggageHeader(requestOptions, sentryBaggage);
+ requestOptions.headers = {
+ ...requestOptions.headers,
+ 'sentry-trace': sentryTraceHeader,
+ // Setting a header to `undefined` will crash in node so we only set the baggage header when it's defined
+ ...(sentryBaggageHeader && { baggage: sentryBaggageHeader }),
+ };
+}
+
+function getRequestSpanData(requestUrl: string, requestOptions: RequestOptions): SanitizedRequestData {
+ const method = requestOptions.method || 'GET';
+ const data: SanitizedRequestData = {
+ url: requestUrl,
+ 'http.method': method,
+ };
+ if (requestOptions.hash) {
+ // strip leading "#"
+ data['http.fragment'] = requestOptions.hash.substring(1);
+ }
+ if (requestOptions.search) {
+ // strip leading "?"
+ data['http.query'] = requestOptions.search.substring(1);
}
+ return data;
+}
- getCurrentHub().addBreadcrumb(
- {
- category: 'http',
- data: {
- status_code: res && res.statusCode,
- ...requestSpanData,
- },
- type: 'http',
- },
- {
- event,
- request: req,
- response: res,
- },
- );
+function normalizeBaggageHeader(
+ requestOptions: RequestOptions,
+ sentryBaggageHeader: string | undefined,
+): string | string[] | undefined {
+ if (!requestOptions.headers || !requestOptions.headers.baggage) {
+ return sentryBaggageHeader;
+ } else if (!sentryBaggageHeader) {
+ return requestOptions.headers.baggage as string | string[];
+ } else if (Array.isArray(requestOptions.headers.baggage)) {
+ return [...requestOptions.headers.baggage, sentryBaggageHeader];
+ }
+
+ // Type-cast explanation:
+ // Technically this the following could be of type `(number | string)[]` but for the sake of simplicity
+ // we say this is undefined behaviour, since it would not be baggage spec conform if the user did this.
+ return [requestOptions.headers.baggage, sentryBaggageHeader] as string[];
}
diff --git a/packages/node/src/integrations/linkederrors.ts b/packages/node/src/integrations/linkederrors.ts
index e2894a128be5..d6a130ce5d54 100644
--- a/packages/node/src/integrations/linkederrors.ts
+++ b/packages/node/src/integrations/linkederrors.ts
@@ -1,8 +1,6 @@
-import { addGlobalEventProcessor, getCurrentHub } from '@sentry/core';
-import type { Event, EventHint, Exception, ExtendedError, Integration, StackParser } from '@sentry/types';
-import { isInstanceOf, resolvedSyncPromise, SyncPromise } from '@sentry/utils';
+import type { Event, EventHint, EventProcessor, Hub, Integration } from '@sentry/types';
+import { applyAggregateErrorsToEvent } from '@sentry/utils';
-import type { NodeClient } from '../client';
import { exceptionFromError } from '../eventbuilder';
import { ContextLines } from './contextlines';
@@ -42,68 +40,33 @@ export class LinkedErrors implements Integration {
/**
* @inheritDoc
*/
- public setupOnce(): void {
- addGlobalEventProcessor(async (event: Event, hint: EventHint) => {
+ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
+ addGlobalEventProcessor(async (event: Event, hint?: EventHint) => {
const hub = getCurrentHub();
+ const client = hub.getClient();
const self = hub.getIntegration(LinkedErrors);
- const client = hub.getClient();
- if (client && self && self._handler && typeof self._handler === 'function') {
- await self._handler(client.getOptions().stackParser, event, hint);
- }
- return event;
- });
- }
- /**
- * @inheritDoc
- */
- private _handler(stackParser: StackParser, event: Event, hint: EventHint): PromiseLike {
- if (!event.exception || !event.exception.values || !isInstanceOf(hint.originalException, Error)) {
- return resolvedSyncPromise(event);
- }
-
- return new SyncPromise(resolve => {
- void this._walkErrorTree(stackParser, hint.originalException as Error, this._key)
- .then((linkedErrors: Exception[]) => {
- if (event && event.exception && event.exception.values) {
- event.exception.values = [...linkedErrors, ...event.exception.values];
- }
- resolve(event);
- })
- .then(null, () => {
- resolve(event);
- });
- });
- }
-
- /**
- * @inheritDoc
- */
- private async _walkErrorTree(
- stackParser: StackParser,
- error: ExtendedError,
- key: string,
- stack: Exception[] = [],
- ): Promise {
- if (!isInstanceOf(error[key], Error) || stack.length + 1 >= this._limit) {
- return Promise.resolve(stack);
- }
+ if (!client || !self) {
+ return event;
+ }
- const exception = exceptionFromError(stackParser, error[key]);
+ applyAggregateErrorsToEvent(
+ exceptionFromError,
+ client.getOptions().stackParser,
+ self._key,
+ self._limit,
+ event,
+ hint,
+ );
- // If the ContextLines integration is enabled, we add source code context to linked errors
- // because we can't guarantee the order that integrations are run.
- const contextLines = getCurrentHub().getIntegration(ContextLines);
- if (contextLines && exception.stacktrace?.frames) {
- await contextLines.addSourceContextToFrames(exception.stacktrace.frames);
- }
+ // If the ContextLines integration is enabled, we add source code context to linked errors
+ // because we can't guarantee the order that integrations are run.
+ const contextLines = getCurrentHub().getIntegration(ContextLines);
+ if (contextLines) {
+ await contextLines.addSourceContext(event);
+ }
- return new Promise((resolve, reject) => {
- void this._walkErrorTree(stackParser, error[key], key, [exception, ...stack])
- .then(resolve)
- .then(null, () => {
- reject();
- });
+ return event;
});
}
}
diff --git a/packages/node/src/integrations/undici/index.ts b/packages/node/src/integrations/undici/index.ts
index 38f920283b7e..0c69dec37d3f 100644
--- a/packages/node/src/integrations/undici/index.ts
+++ b/packages/node/src/integrations/undici/index.ts
@@ -1,8 +1,9 @@
-import type { Hub } from '@sentry/core';
-import type { EventProcessor, Integration } from '@sentry/types';
+import { getCurrentHub, getDynamicSamplingContextFromClient } from '@sentry/core';
+import type { EventProcessor, Integration, Span } from '@sentry/types';
import {
dynamicRequire,
dynamicSamplingContextToSentryBaggageHeader,
+ generateSentryTraceHeader,
getSanitizedUrlString,
parseUrl,
stringMatchesSomePattern,
@@ -12,7 +13,13 @@ import { LRUMap } from 'lru_map';
import type { NodeClient } from '../../client';
import { NODE_VERSION } from '../../nodeVersion';
import { isSentryRequest } from '../utils/http';
-import type { DiagnosticsChannel, RequestCreateMessage, RequestEndMessage, RequestErrorMessage } from './types';
+import type {
+ DiagnosticsChannel,
+ RequestCreateMessage,
+ RequestEndMessage,
+ RequestErrorMessage,
+ RequestWithSentry,
+} from './types';
export enum ChannelName {
// https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md#undicirequestcreate
@@ -81,7 +88,7 @@ export class Undici implements Integration {
/**
* @inheritDoc
*/
- public setupOnce(_addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
+ public setupOnce(_addGlobalEventProcessor: (callback: EventProcessor) => void): void {
// Requires Node 16+ to use the diagnostics_channel API.
if (NODE_VERSION.major && NODE_VERSION.major < 16) {
return;
@@ -99,169 +106,205 @@ export class Undici implements Integration {
return;
}
- const shouldCreateSpan = (url: string): boolean => {
- if (this._options.shouldCreateSpanForRequest === undefined) {
+ // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md
+ ds.subscribe(ChannelName.RequestCreate, this._onRequestCreate);
+ ds.subscribe(ChannelName.RequestEnd, this._onRequestEnd);
+ ds.subscribe(ChannelName.RequestError, this._onRequestError);
+ }
+
+ /** Helper that wraps shouldCreateSpanForRequest option */
+ private _shouldCreateSpan(url: string): boolean {
+ if (this._options.shouldCreateSpanForRequest === undefined) {
+ return true;
+ }
+
+ const cachedDecision = this._createSpanUrlMap.get(url);
+ if (cachedDecision !== undefined) {
+ return cachedDecision;
+ }
+
+ const decision = this._options.shouldCreateSpanForRequest(url);
+ this._createSpanUrlMap.set(url, decision);
+ return decision;
+ }
+
+ private _onRequestCreate = (message: unknown): void => {
+ const hub = getCurrentHub();
+ if (!hub.getIntegration(Undici)) {
+ return;
+ }
+
+ const { request } = message as RequestCreateMessage;
+
+ const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
+
+ if (isSentryRequest(stringUrl) || request.__sentry_span__ !== undefined) {
+ return;
+ }
+
+ const client = hub.getClient();
+ if (!client) {
+ return;
+ }
+
+ const clientOptions = client.getOptions();
+ const scope = hub.getScope();
+
+ const parentSpan = scope.getSpan();
+
+ const span = this._shouldCreateSpan(stringUrl) ? createRequestSpan(parentSpan, request, stringUrl) : undefined;
+ if (span) {
+ request.__sentry_span__ = span;
+ }
+
+ const shouldAttachTraceData = (url: string): boolean => {
+ if (clientOptions.tracePropagationTargets === undefined) {
return true;
}
- const cachedDecision = this._createSpanUrlMap.get(url);
+ const cachedDecision = this._headersUrlMap.get(url);
if (cachedDecision !== undefined) {
return cachedDecision;
}
- const decision = this._options.shouldCreateSpanForRequest(url);
- this._createSpanUrlMap.set(url, decision);
+ const decision = stringMatchesSomePattern(url, clientOptions.tracePropagationTargets);
+ this._headersUrlMap.set(url, decision);
return decision;
};
- // https://github.com/nodejs/undici/blob/e6fc80f809d1217814c044f52ed40ef13f21e43c/docs/api/DiagnosticsChannel.md
- ds.subscribe(ChannelName.RequestCreate, message => {
- const hub = getCurrentHub();
- if (!hub.getIntegration(Undici)) {
- return;
+ if (shouldAttachTraceData(stringUrl)) {
+ if (span) {
+ const dynamicSamplingContext = span?.transaction?.getDynamicSamplingContext();
+ const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
+
+ setHeadersOnRequest(request, span.toTraceparent(), sentryBaggageHeader);
+ } else {
+ const { traceId, sampled, dsc } = scope.getPropagationContext();
+ const sentryTrace = generateSentryTraceHeader(traceId, undefined, sampled);
+ const dynamicSamplingContext = dsc || getDynamicSamplingContextFromClient(traceId, client, scope);
+ const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
+ setHeadersOnRequest(request, sentryTrace, sentryBaggageHeader);
}
+ }
+ };
- const { request } = message as RequestCreateMessage;
+ private _onRequestEnd = (message: unknown): void => {
+ const hub = getCurrentHub();
+ if (!hub.getIntegration(Undici)) {
+ return;
+ }
- const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
- const url = parseUrl(stringUrl);
+ const { request, response } = message as RequestEndMessage;
- if (isSentryRequest(stringUrl) || request.__sentry__ !== undefined) {
- return;
- }
+ const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
- const client = hub.getClient();
- const scope = hub.getScope();
-
- const activeSpan = scope.getSpan();
-
- if (activeSpan && client) {
- const clientOptions = client.getOptions();
-
- if (shouldCreateSpan(stringUrl)) {
- const method = request.method || 'GET';
- const data: Record = {
- 'http.method': method,
- };
- if (url.search) {
- data['http.query'] = url.search;
- }
- if (url.hash) {
- data['http.fragment'] = url.hash;
- }
- const span = activeSpan.startChild({
- op: 'http.client',
- description: `${method} ${getSanitizedUrlString(url)}`,
- data,
- });
- request.__sentry__ = span;
-
- const shouldAttachTraceData = (url: string): boolean => {
- if (clientOptions.tracePropagationTargets === undefined) {
- return true;
- }
-
- const cachedDecision = this._headersUrlMap.get(url);
- if (cachedDecision !== undefined) {
- return cachedDecision;
- }
-
- const decision = stringMatchesSomePattern(url, clientOptions.tracePropagationTargets);
- this._headersUrlMap.set(url, decision);
- return decision;
- };
-
- if (shouldAttachTraceData(stringUrl)) {
- request.addHeader('sentry-trace', span.toTraceparent());
- if (span.transaction) {
- const dynamicSamplingContext = span.transaction.getDynamicSamplingContext();
- const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
- if (sentryBaggageHeader) {
- request.addHeader('baggage', sentryBaggageHeader);
- }
- }
- }
- }
- }
- });
+ if (isSentryRequest(stringUrl)) {
+ return;
+ }
- ds.subscribe(ChannelName.RequestEnd, message => {
- const hub = getCurrentHub();
- if (!hub.getIntegration(Undici)) {
- return;
- }
+ const span = request.__sentry_span__;
+ if (span) {
+ span.setHttpStatus(response.statusCode);
+ span.finish();
+ }
- const { request, response } = message as RequestEndMessage;
+ if (this._options.breadcrumbs) {
+ hub.addBreadcrumb(
+ {
+ category: 'http',
+ data: {
+ method: request.method,
+ status_code: response.statusCode,
+ url: stringUrl,
+ },
+ type: 'http',
+ },
+ {
+ event: 'response',
+ request,
+ response,
+ },
+ );
+ }
+ };
- const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
+ private _onRequestError = (message: unknown): void => {
+ const hub = getCurrentHub();
+ if (!hub.getIntegration(Undici)) {
+ return;
+ }
- if (isSentryRequest(stringUrl)) {
- return;
- }
+ const { request } = message as RequestErrorMessage;
- const span = request.__sentry__;
- if (span) {
- span.setHttpStatus(response.statusCode);
- span.finish();
- }
+ const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
- if (this._options.breadcrumbs) {
- hub.addBreadcrumb(
- {
- category: 'http',
- data: {
- method: request.method,
- status_code: response.statusCode,
- url: stringUrl,
- },
- type: 'http',
- },
- {
- event: 'response',
- request,
- response,
- },
- );
- }
- });
+ if (isSentryRequest(stringUrl)) {
+ return;
+ }
- ds.subscribe(ChannelName.RequestError, message => {
- const hub = getCurrentHub();
- if (!hub.getIntegration(Undici)) {
- return;
- }
+ const span = request.__sentry_span__;
+ if (span) {
+ span.setStatus('internal_error');
+ span.finish();
+ }
- const { request } = message as RequestErrorMessage;
+ if (this._options.breadcrumbs) {
+ hub.addBreadcrumb(
+ {
+ category: 'http',
+ data: {
+ method: request.method,
+ url: stringUrl,
+ },
+ level: 'error',
+ type: 'http',
+ },
+ {
+ event: 'error',
+ request,
+ },
+ );
+ }
+ };
+}
- const stringUrl = request.origin ? request.origin.toString() + request.path : request.path;
+function setHeadersOnRequest(
+ request: RequestWithSentry,
+ sentryTrace: string,
+ sentryBaggageHeader: string | undefined,
+): void {
+ if (request.__sentry_has_headers__) {
+ return;
+ }
- if (isSentryRequest(stringUrl)) {
- return;
- }
+ request.addHeader('sentry-trace', sentryTrace);
+ if (sentryBaggageHeader) {
+ request.addHeader('baggage', sentryBaggageHeader);
+ }
- const span = request.__sentry__;
- if (span) {
- span.setStatus('internal_error');
- span.finish();
- }
+ request.__sentry_has_headers__ = true;
+}
- if (this._options.breadcrumbs) {
- hub.addBreadcrumb(
- {
- category: 'http',
- data: {
- method: request.method,
- url: stringUrl,
- },
- level: 'error',
- type: 'http',
- },
- {
- event: 'error',
- request,
- },
- );
- }
- });
+function createRequestSpan(
+ activeSpan: Span | undefined,
+ request: RequestWithSentry,
+ stringUrl: string,
+): Span | undefined {
+ const url = parseUrl(stringUrl);
+
+ const method = request.method || 'GET';
+ const data: Record = {
+ 'http.method': method,
+ };
+ if (url.search) {
+ data['http.query'] = url.search;
+ }
+ if (url.hash) {
+ data['http.fragment'] = url.hash;
}
+ return activeSpan?.startChild({
+ op: 'http.client',
+ description: `${method} ${getSanitizedUrlString(url)}`,
+ data,
+ });
}
diff --git a/packages/node/src/integrations/undici/types.ts b/packages/node/src/integrations/undici/types.ts
index c2d2db125195..f56e708f456c 100644
--- a/packages/node/src/integrations/undici/types.ts
+++ b/packages/node/src/integrations/undici/types.ts
@@ -234,7 +234,8 @@ export interface UndiciResponse {
}
export interface RequestWithSentry extends UndiciRequest {
- __sentry__?: Span;
+ __sentry_span__?: Span;
+ __sentry_has_headers__?: boolean;
}
export interface RequestCreateMessage {
diff --git a/packages/node/src/module.ts b/packages/node/src/module.ts
index 595ee09bbe49..44bff87a02d2 100644
--- a/packages/node/src/module.ts
+++ b/packages/node/src/module.ts
@@ -10,7 +10,7 @@ function normalizeWindowsPath(path: string): string {
}
/** Gets the module from a filename */
-export function getModule(
+export function getModuleFromFilename(
filename: string | undefined,
normalizeWindowsPathSeparator: boolean = isWindowsPlatform,
): string | undefined {
diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts
index 9e55fd4b5a84..06be10d848b6 100644
--- a/packages/node/src/sdk.ts
+++ b/packages/node/src/sdk.ts
@@ -13,6 +13,7 @@ import {
logger,
nodeStackLineParser,
stackParserFromStackParserOptions,
+ tracingContextFromHeaders,
} from '@sentry/utils';
import { setNodeAsyncContextStrategy } from './async';
@@ -30,7 +31,7 @@ import {
RequestData,
Undici,
} from './integrations';
-import { getModule } from './module';
+import { getModuleFromFilename } from './module';
import { makeNodeTransport } from './transports';
import type { NodeClientOptions, NodeOptions } from './types';
@@ -129,8 +130,9 @@ export function init(options: NodeOptions = {}): void {
options.dsn = process.env.SENTRY_DSN;
}
- if (options.tracesSampleRate === undefined && process.env.SENTRY_TRACES_SAMPLE_RATE) {
- const tracesSampleRate = parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE);
+ const sentryTracesSampleRate = process.env.SENTRY_TRACES_SAMPLE_RATE;
+ if (options.tracesSampleRate === undefined && sentryTracesSampleRate) {
+ const tracesSampleRate = parseFloat(sentryTracesSampleRate);
if (isFinite(tracesSampleRate)) {
options.tracesSampleRate = tracesSampleRate;
}
@@ -171,6 +173,8 @@ export function init(options: NodeOptions = {}): void {
if (options.autoSessionTracking) {
startSessionTracking();
}
+
+ updateScopeFromEnvVariables();
}
/**
@@ -263,7 +267,7 @@ export function getSentryRelease(fallback?: string): string | undefined {
}
/** Node.js stack parser */
-export const defaultStackParser: StackParser = createStackParser(nodeStackLineParser(getModule));
+export const defaultStackParser: StackParser = createStackParser(nodeStackLineParser(getModuleFromFilename));
/**
* Enable automatic Session Tracking for the node process.
@@ -285,3 +289,19 @@ function startSessionTracking(): void {
if (session && !terminalStates.includes(session.status)) hub.endSession();
});
}
+
+/**
+ * Update scope and propagation context based on environmental variables.
+ *
+ * See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md
+ * for more details.
+ */
+function updateScopeFromEnvVariables(): void {
+ const sentryUseEnvironment = (process.env.SENTRY_USE_ENVIRONMENT || '').toLowerCase();
+ if (!['false', 'n', 'no', 'off', '0'].includes(sentryUseEnvironment)) {
+ const sentryTraceEnv = process.env.SENTRY_TRACE;
+ const baggageEnv = process.env.SENTRY_BAGGAGE;
+ const { propagationContext } = tracingContextFromHeaders(sentryTraceEnv, baggageEnv);
+ getCurrentHub().getScope().setPropagationContext(propagationContext);
+ }
+}
diff --git a/packages/node/test/async/domain.test.ts b/packages/node/test/async/domain.test.ts
index 84c3362b9882..8794a938ce50 100644
--- a/packages/node/test/async/domain.test.ts
+++ b/packages/node/test/async/domain.test.ts
@@ -1,5 +1,5 @@
-import { getCurrentHub, Hub, runWithAsyncContext, setAsyncContextStrategy } from '@sentry/core';
-import * as domain from 'domain';
+import type { Hub } from '@sentry/core';
+import { getCurrentHub, runWithAsyncContext, setAsyncContextStrategy } from '@sentry/core';
import { setDomainAsyncContextStrategy } from '../../src/async/domain';
@@ -9,13 +9,6 @@ describe('domains', () => {
setAsyncContextStrategy(undefined);
});
- test('without domain', () => {
- // @ts-ignore property active does not exist on domain
- expect(domain.active).toBeFalsy();
- const hub = getCurrentHub();
- expect(hub).toEqual(new Hub());
- });
-
test('hub scope inheritance', () => {
setDomainAsyncContextStrategy();
diff --git a/packages/node/test/async/hooks.test.ts b/packages/node/test/async/hooks.test.ts
index 8c4c5decab76..a08271230579 100644
--- a/packages/node/test/async/hooks.test.ts
+++ b/packages/node/test/async/hooks.test.ts
@@ -1,4 +1,5 @@
-import { getCurrentHub, Hub, runWithAsyncContext, setAsyncContextStrategy } from '@sentry/core';
+import type { Hub } from '@sentry/core';
+import { getCurrentHub, runWithAsyncContext, setAsyncContextStrategy } from '@sentry/core';
import { setHooksAsyncContextStrategy } from '../../src/async/hooks';
import { conditionalTest } from '../utils';
@@ -9,11 +10,6 @@ conditionalTest({ min: 12 })('async_hooks', () => {
setAsyncContextStrategy(undefined);
});
- test('without context', () => {
- const hub = getCurrentHub();
- expect(hub).toEqual(new Hub());
- });
-
test('without strategy hubs should be equal', () => {
runWithAsyncContext(() => {
const hub1 = getCurrentHub();
diff --git a/packages/node/test/context-lines.test.ts b/packages/node/test/context-lines.test.ts
index b469796214b1..cfdd44e8b840 100644
--- a/packages/node/test/context-lines.test.ts
+++ b/packages/node/test/context-lines.test.ts
@@ -107,7 +107,8 @@ describe('ContextLines', () => {
expect(readFileSpy).toHaveBeenCalledTimes(0);
});
});
- test.only('does not attempt to readfile multiple times if it fails', async () => {
+
+ test('does not attempt to readfile multiple times if it fails', async () => {
expect.assertions(1);
contextLines = new ContextLines({});
diff --git a/packages/node/test/handlers.test.ts b/packages/node/test/handlers.test.ts
index 298d61cf1aac..d464342fe396 100644
--- a/packages/node/test/handlers.test.ts
+++ b/packages/node/test/handlers.test.ts
@@ -1,7 +1,7 @@
import type { Hub } from '@sentry/core';
import * as sentryCore from '@sentry/core';
import { setAsyncContextStrategy, Transaction } from '@sentry/core';
-import type { Event } from '@sentry/types';
+import type { Event, PropagationContext } from '@sentry/types';
import { SentryError } from '@sentry/utils';
import * as http from 'http';
@@ -209,6 +209,11 @@ describe('tracingHandler', () => {
jest.restoreAllMocks();
});
+ function getPropagationContext(): PropagationContext {
+ // @ts-expect-error accesing private property for test
+ return hub.getScope()._propagationContext;
+ }
+
it('creates a transaction when handling a request', () => {
const startTransaction = jest.spyOn(sentryCore, 'startTransaction');
@@ -251,6 +256,13 @@ describe('tracingHandler', () => {
const transaction = (res as any).__sentry_transaction;
+ expect(getPropagationContext()).toEqual({
+ traceId: '12312012123120121231201212312012',
+ parentSpanId: '1121201211212012',
+ spanId: expect.any(String),
+ sampled: false,
+ });
+
// since we have no tracesSampler defined, the default behavior (inherit if possible) applies
expect(transaction.traceId).toEqual('12312012123120121231201212312012');
expect(transaction.parentSpanId).toEqual('1121201211212012');
@@ -260,18 +272,26 @@ describe('tracingHandler', () => {
it("pulls parent's data from tracing and baggage headers on the request", () => {
req.headers = {
- 'sentry-trace': '12312012123120121231201212312012-1121201211212012-0',
+ 'sentry-trace': '12312012123120121231201212312012-1121201211212012-1',
baggage: 'sentry-version=1.0,sentry-environment=production',
};
sentryTracingMiddleware(req, res, next);
+ expect(getPropagationContext()).toEqual({
+ traceId: '12312012123120121231201212312012',
+ parentSpanId: '1121201211212012',
+ spanId: expect.any(String),
+ sampled: true,
+ dsc: { version: '1.0', environment: 'production' },
+ });
+
const transaction = (res as any).__sentry_transaction;
// since we have no tracesSampler defined, the default behavior (inherit if possible) applies
expect(transaction.traceId).toEqual('12312012123120121231201212312012');
expect(transaction.parentSpanId).toEqual('1121201211212012');
- expect(transaction.sampled).toEqual(false);
+ expect(transaction.sampled).toEqual(true);
expect(transaction.metadata?.dynamicSamplingContext).toStrictEqual({ version: '1.0', environment: 'production' });
});
@@ -283,6 +303,8 @@ describe('tracingHandler', () => {
sentryTracingMiddleware(req, res, next);
+ expect(getPropagationContext().dsc).toEqual({ version: '1.0', environment: 'production' });
+
const transaction = (res as any).__sentry_transaction;
expect(transaction.metadata?.dynamicSamplingContext).toStrictEqual({ version: '1.0', environment: 'production' });
});
diff --git a/packages/node/test/index.test.ts b/packages/node/test/index.test.ts
index ab9bd41adaf9..60b37b44acb1 100644
--- a/packages/node/test/index.test.ts
+++ b/packages/node/test/index.test.ts
@@ -488,4 +488,47 @@ describe('SentryNode initialization', () => {
expect(instrumenter).toEqual('otel');
});
});
+
+ describe('propagation context', () => {
+ beforeEach(() => {
+ process.env.SENTRY_TRACE = '12312012123120121231201212312012-1121201211212012-0';
+ process.env.SENTRY_BAGGAGE = 'sentry-release=1.0.0,sentry-environment=production';
+
+ getCurrentHub().getScope().clear();
+ });
+
+ afterEach(() => {
+ delete process.env.SENTRY_TRACE;
+ delete process.env.SENTRY_BAGGAGE;
+ });
+
+ it('reads from environmental variables', () => {
+ init({ dsn });
+
+ // @ts-expect-error accessing private method for test
+ expect(getCurrentHub().getScope()._propagationContext).toEqual({
+ traceId: '12312012123120121231201212312012',
+ parentSpanId: '1121201211212012',
+ spanId: expect.any(String),
+ sampled: false,
+ dsc: {
+ release: '1.0.0',
+ environment: 'production',
+ },
+ });
+ });
+
+ it.each(['false', 'False', 'FALSE', 'n', 'no', 'No', 'NO', 'off', 'Off', 'OFF', '0'])(
+ 'does not read from environmental variable if SENTRY_USE_ENVIRONMENT is set to %s',
+ useEnvValue => {
+ process.env.SENTRY_USE_ENVIRONMENT = useEnvValue;
+ init({ dsn });
+
+ // @ts-expect-error accessing private method for test
+ expect(getCurrentHub().getScope()._propagationContext.traceId).not.toEqual('12312012123120121231201212312012');
+
+ delete process.env.SENTRY_USE_ENVIRONMENT;
+ },
+ );
+ });
});
diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts
index 3f5a87d15363..5cbea24a9b01 100644
--- a/packages/node/test/integrations/http.test.ts
+++ b/packages/node/test/integrations/http.test.ts
@@ -54,6 +54,21 @@ describe('tracing', () => {
return transaction;
}
+ function getHub(customOptions: Partial = {}) {
+ const options = getDefaultNodeClientOptions({
+ dsn: 'https://dogsarebadatkeepingsecrets@squirrelchasers.ingest.sentry.io/12312012',
+ tracesSampleRate: 1.0,
+ integrations: [new HttpIntegration({ tracing: true })],
+ release: '1.0.0',
+ environment: 'production',
+ ...customOptions,
+ });
+ const hub = new Hub(new NodeClient(options));
+ jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub);
+
+ return hub;
+ }
+
it("creates a span for each outgoing non-sentry request when there's a transaction on the scope", () => {
nock('http://dogs.are.great').get('/').reply(200);
@@ -114,9 +129,10 @@ describe('tracing', () => {
const baggageHeader = request.getHeader('baggage') as string;
expect(baggageHeader).toEqual(
- 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=dogpark,' +
+ 'sentry-environment=production,sentry-release=1.0.0,' +
'sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,' +
- 'sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1',
+ 'sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1,' +
+ 'sentry-transaction=dogpark,sentry-sampled=true',
);
});
@@ -128,10 +144,10 @@ describe('tracing', () => {
const request = http.get({ host: 'http://dogs.are.great/', headers: { baggage: 'dog=great' } });
const baggageHeader = request.getHeader('baggage') as string;
- expect(baggageHeader).toEqual([
- 'dog=great',
- 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=dogpark,sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1',
- ]);
+ expect(baggageHeader[0]).toEqual('dog=great');
+ expect(baggageHeader[1]).toEqual(
+ 'sentry-environment=production,sentry-release=1.0.0,sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1,sentry-transaction=dogpark,sentry-sampled=true',
+ );
});
it('adds the transaction name to the the baggage header if a valid transaction source is set', async () => {
@@ -144,7 +160,7 @@ describe('tracing', () => {
expect(baggageHeader).toEqual([
'dog=great',
- 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=dogpark,sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1',
+ 'sentry-environment=production,sentry-release=1.0.0,sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1,sentry-transaction=dogpark,sentry-sampled=true',
]);
});
@@ -158,10 +174,55 @@ describe('tracing', () => {
expect(baggageHeader).toEqual([
'dog=great',
- 'sentry-environment=production,sentry-release=1.0.0,sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1',
+ 'sentry-environment=production,sentry-release=1.0.0,sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1,sentry-sampled=true',
]);
});
+ it('generates and uses propagation context to attach baggage and sentry-trace header', async () => {
+ nock('http://dogs.are.great').get('/').reply(200);
+
+ const request = http.get('http://dogs.are.great/');
+ const sentryTraceHeader = request.getHeader('sentry-trace') as string;
+ const baggageHeader = request.getHeader('baggage') as string;
+
+ const parts = sentryTraceHeader.split('-');
+ expect(parts.length).toEqual(3);
+ expect(parts[0]).toEqual('12312012123120121231201212312012');
+ expect(parts[1]).toEqual(expect.any(String));
+ expect(parts[2]).toEqual('1');
+
+ expect(baggageHeader).toEqual(
+ 'sentry-environment=production,sentry-release=1.0.0,sentry-user_segment=segmentA,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=12312012123120121231201212312012,sentry-sample_rate=1,sentry-sampled=true',
+ );
+ });
+
+ it('uses incoming propagation context to attach baggage and sentry-trace', async () => {
+ nock('http://dogs.are.great').get('/').reply(200);
+
+ const hub = getHub();
+ hub.getScope().setPropagationContext({
+ traceId: '86f39e84263a4de99c326acab3bfe3bd',
+ spanId: '86f39e84263a4de9',
+ sampled: true,
+ dsc: {
+ trace_id: '86f39e84263a4de99c326acab3bfe3bd',
+ public_key: 'test-public-key',
+ },
+ });
+
+ const request = http.get('http://dogs.are.great/');
+ const sentryTraceHeader = request.getHeader('sentry-trace') as string;
+ const baggageHeader = request.getHeader('baggage') as string;
+
+ const parts = sentryTraceHeader.split('-');
+ expect(parts.length).toEqual(3);
+ expect(parts[0]).toEqual('86f39e84263a4de99c326acab3bfe3bd');
+ expect(parts[1]).toEqual(expect.any(String));
+ expect(parts[2]).toEqual('1');
+
+ expect(baggageHeader).toEqual('sentry-trace_id=86f39e84263a4de99c326acab3bfe3bd,sentry-public_key=test-public-key');
+ });
+
it("doesn't attach the sentry-trace header to outgoing sentry requests", () => {
nock('http://squirrelchasers.ingest.sentry.io').get('/api/12312012/store/').reply(200);
@@ -270,9 +331,8 @@ describe('tracing', () => {
return transaction;
}
- // TODO (v8): These can be removed once we remove these properties from client options
describe('as client options', () => {
- it("doesn't create span if shouldCreateSpanForRequest returns false", () => {
+ it('creates span with propagation context if shouldCreateSpanForRequest returns false', () => {
const url = 'http://dogs.are.great/api/v1/index/';
nock(url).get(/.*/).reply(200);
@@ -295,8 +355,15 @@ describe('tracing', () => {
expect(httpSpans.length).toBe(0);
// And headers are not attached without span creation
- expect(request.getHeader('sentry-trace')).toBeUndefined();
- expect(request.getHeader('baggage')).toBeUndefined();
+ expect(request.getHeader('sentry-trace')).toBeDefined();
+ expect(request.getHeader('baggage')).toBeDefined();
+
+ const propagationContext = hub.getScope().getPropagationContext();
+
+ expect((request.getHeader('sentry-trace') as string).includes(propagationContext.traceId)).toBe(true);
+ expect(request.getHeader('baggage')).toEqual(
+ `sentry-environment=production,sentry-release=1.0.0,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=${propagationContext.traceId}`,
+ );
});
it.each([
@@ -366,7 +433,7 @@ describe('tracing', () => {
});
describe('as Http integration constructor options', () => {
- it("doesn't create span if shouldCreateSpanForRequest returns false", () => {
+ it('creates span with propagation context if shouldCreateSpanForRequest returns false', () => {
const url = 'http://dogs.are.great/api/v1/index/';
nock(url).get(/.*/).reply(200);
@@ -393,8 +460,15 @@ describe('tracing', () => {
expect(httpSpans.length).toBe(0);
// And headers are not attached without span creation
- expect(request.getHeader('sentry-trace')).toBeUndefined();
- expect(request.getHeader('baggage')).toBeUndefined();
+ expect(request.getHeader('sentry-trace')).toBeDefined();
+ expect(request.getHeader('baggage')).toBeDefined();
+
+ const propagationContext = hub.getScope().getPropagationContext();
+
+ expect((request.getHeader('sentry-trace') as string).includes(propagationContext.traceId)).toBe(true);
+ expect(request.getHeader('baggage')).toEqual(
+ `sentry-environment=production,sentry-release=1.0.0,sentry-public_key=dogsarebadatkeepingsecrets,sentry-trace_id=${propagationContext.traceId}`,
+ );
});
it.each([
diff --git a/packages/node/test/integrations/linkederrors.test.ts b/packages/node/test/integrations/linkederrors.test.ts
deleted file mode 100644
index 6582c0f6e9e5..000000000000
--- a/packages/node/test/integrations/linkederrors.test.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import type { ExtendedError } from '@sentry/types';
-
-import type { Event } from '../../src';
-import { NodeClient } from '../../src';
-import { LinkedErrors } from '../../src/integrations/linkederrors';
-import { defaultStackParser as stackParser } from '../../src/sdk';
-import { getDefaultNodeClientOptions } from '../helper/node-client-options';
-
-let linkedErrors: any;
-
-describe('LinkedErrors', () => {
- beforeEach(() => {
- linkedErrors = new LinkedErrors();
- });
-
- describe('handler', () => {
- it('should bail out if event doesnt contain exception', async () => {
- expect.assertions(2);
- const spy = jest.spyOn(linkedErrors, '_walkErrorTree');
- const event = {
- message: 'foo',
- };
- return linkedErrors._handler(stackParser, event, {}).then((result: any) => {
- expect(spy.mock.calls.length).toEqual(0);
- expect(result).toEqual(event);
- });
- });
-
- it('should bail out if event contains exception, but no hint', async () => {
- expect.assertions(2);
- const spy = jest.spyOn(linkedErrors, '_walkErrorTree');
- const one = new Error('originalException');
- const options = getDefaultNodeClientOptions({ stackParser });
- const client = new NodeClient(options);
- let event: Event | undefined;
- return client
- .eventFromException(one)
- .then(eventFromException => {
- event = eventFromException;
- return linkedErrors._handler(stackParser, eventFromException, {});
- })
- .then(result => {
- expect(spy.mock.calls.length).toEqual(0);
- expect(result).toEqual(event);
- });
- });
-
- it('should call walkErrorTree if event contains exception and hint with originalException', async () => {
- expect.assertions(1);
- const spy = jest.spyOn(linkedErrors, '_walkErrorTree').mockImplementation(
- async () =>
- new Promise<[]>(resolve => {
- resolve([]);
- }),
- );
- const one = new Error('originalException');
- const options = getDefaultNodeClientOptions({ stackParser });
- const client = new NodeClient(options);
- return client.eventFromException(one).then(event =>
- linkedErrors
- ._handler(stackParser, event, {
- originalException: one,
- })
- .then((_: any) => {
- expect(spy.mock.calls.length).toEqual(1);
- }),
- );
- });
-
- it('should recursively walk error to find linked exceptions and assign them to the event', async () => {
- expect.assertions(10);
- const one: ExtendedError = new Error('one');
- const two: ExtendedError = new TypeError('two');
- const three: ExtendedError = new SyntaxError('three');
- one.cause = two;
- two.cause = three;
-
- const options = getDefaultNodeClientOptions({ stackParser });
- const client = new NodeClient(options);
- return client.eventFromException(one).then(event =>
- linkedErrors
- ._handler(stackParser, event, {
- originalException: one,
- })
- .then((result: any) => {
- expect(result.exception.values.length).toEqual(3);
- expect(result.exception.values[0].type).toEqual('SyntaxError');
- expect(result.exception.values[0].value).toEqual('three');
- expect(result.exception.values[0].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[1].type).toEqual('TypeError');
- expect(result.exception.values[1].value).toEqual('two');
- expect(result.exception.values[1].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[2].type).toEqual('Error');
- expect(result.exception.values[2].value).toEqual('one');
- expect(result.exception.values[2].stacktrace).toHaveProperty('frames');
- }),
- );
- });
-
- it('should allow to change walk key', async () => {
- expect.assertions(10);
- linkedErrors = new LinkedErrors({
- key: 'reason',
- });
-
- const one: ExtendedError = new Error('one');
- const two: ExtendedError = new TypeError('two');
- const three: ExtendedError = new SyntaxError('three');
- one.reason = two;
- two.reason = three;
-
- const options = getDefaultNodeClientOptions({ stackParser });
- const client = new NodeClient(options);
- return client.eventFromException(one).then(event =>
- linkedErrors
- ._handler(stackParser, event, {
- originalException: one,
- })
- .then((result: any) => {
- expect(result.exception.values.length).toEqual(3);
- expect(result.exception.values[0].type).toEqual('SyntaxError');
- expect(result.exception.values[0].value).toEqual('three');
- expect(result.exception.values[0].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[1].type).toEqual('TypeError');
- expect(result.exception.values[1].value).toEqual('two');
- expect(result.exception.values[1].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[2].type).toEqual('Error');
- expect(result.exception.values[2].value).toEqual('one');
- expect(result.exception.values[2].stacktrace).toHaveProperty('frames');
- }),
- );
- });
-
- it('should allow to change stack size limit', async () => {
- expect.assertions(7);
- linkedErrors = new LinkedErrors({
- limit: 2,
- });
-
- const one: ExtendedError = new Error('one');
- const two: ExtendedError = new TypeError('two');
- const three: ExtendedError = new SyntaxError('three');
- one.cause = two;
- two.cause = three;
-
- const options = getDefaultNodeClientOptions({ stackParser });
- const client = new NodeClient(options);
- return client.eventFromException(one).then(event =>
- linkedErrors
- ._handler(stackParser, event, {
- originalException: one,
- })
- .then((result: any) => {
- expect(result.exception.values.length).toEqual(2);
- expect(result.exception.values[0].type).toEqual('TypeError');
- expect(result.exception.values[0].value).toEqual('two');
- expect(result.exception.values[0].stacktrace).toHaveProperty('frames');
- expect(result.exception.values[1].type).toEqual('Error');
- expect(result.exception.values[1].value).toEqual('one');
- expect(result.exception.values[1].stacktrace).toHaveProperty('frames');
- }),
- );
- });
- });
-});
diff --git a/packages/node/test/integrations/undici.test.ts b/packages/node/test/integrations/undici.test.ts
index 46756cbe88cd..b30ac92c0695 100644
--- a/packages/node/test/integrations/undici.test.ts
+++ b/packages/node/test/integrations/undici.test.ts
@@ -1,5 +1,5 @@
import type { Transaction } from '@sentry/core';
-import { Hub, makeMain } from '@sentry/core';
+import { Hub, makeMain, runWithAsyncContext } from '@sentry/core';
import * as http from 'http';
import type { fetch as FetchType } from 'undici';
@@ -15,8 +15,8 @@ let hub: Hub;
let fetch: typeof FetchType;
beforeAll(async () => {
- await setupTestServer();
try {
+ await setupTestServer();
// need to conditionally require `undici` because it's not available in Node 10
// eslint-disable-next-line @typescript-eslint/no-var-requires
fetch = require('undici').fetch;
@@ -28,7 +28,7 @@ beforeAll(async () => {
const DEFAULT_OPTIONS = getDefaultNodeClientOptions({
dsn: SENTRY_DSN,
- tracesSampleRate: 1,
+ tracesSampler: () => true,
integrations: [new Undici()],
});
@@ -51,10 +51,10 @@ conditionalTest({ min: 16 })('Undici integration', () => {
it.each([
[
'simple url',
- 'http://localhost:18099',
+ 'http://localhost:18100',
undefined,
{
- description: 'GET http://localhost:18099/',
+ description: 'GET http://localhost:18100/',
op: 'http.client',
data: expect.objectContaining({
'http.method': 'GET',
@@ -63,10 +63,10 @@ conditionalTest({ min: 16 })('Undici integration', () => {
],
[
'url with query',
- 'http://localhost:18099?foo=bar',
+ 'http://localhost:18100?foo=bar',
undefined,
{
- description: 'GET http://localhost:18099/',
+ description: 'GET http://localhost:18100/',
op: 'http.client',
data: expect.objectContaining({
'http.method': 'GET',
@@ -76,10 +76,10 @@ conditionalTest({ min: 16 })('Undici integration', () => {
],
[
'url with POST method',
- 'http://localhost:18099',
+ 'http://localhost:18100',
{ method: 'POST' },
{
- description: 'POST http://localhost:18099/',
+ description: 'POST http://localhost:18100/',
data: expect.objectContaining({
'http.method': 'POST',
}),
@@ -87,10 +87,10 @@ conditionalTest({ min: 16 })('Undici integration', () => {
],
[
'url with POST method',
- 'http://localhost:18099',
+ 'http://localhost:18100',
{ method: 'POST' },
{
- description: 'POST http://localhost:18099/',
+ description: 'POST http://localhost:18100/',
data: expect.objectContaining({
'http.method': 'POST',
}),
@@ -98,10 +98,10 @@ conditionalTest({ min: 16 })('Undici integration', () => {
],
[
'url with GET as default',
- 'http://localhost:18099',
+ 'http://localhost:18100',
{ method: undefined },
{
- description: 'GET http://localhost:18099/',
+ description: 'GET http://localhost:18100/',
},
],
])('creates a span with a %s', async (_: string, request, requestInit, expected) => {
@@ -180,54 +180,86 @@ conditionalTest({ min: 16 })('Undici integration', () => {
const transaction = hub.startTransaction({ name: 'test-transaction' }) as Transaction;
hub.getScope().setSpan(transaction);
- const undoPatch = patchUndici(hub, { shouldCreateSpanForRequest: url => url.includes('yes') });
+ const undoPatch = patchUndici({ shouldCreateSpanForRequest: url => url.includes('yes') });
- await fetch('http://localhost:18099/no', { method: 'POST' });
+ await fetch('http://localhost:18100/no', { method: 'POST' });
expect(transaction.spanRecorder?.spans.length).toBe(1);
- await fetch('http://localhost:18099/yes', { method: 'POST' });
+ await fetch('http://localhost:18100/yes', { method: 'POST' });
expect(transaction.spanRecorder?.spans.length).toBe(2);
undoPatch();
});
- it('attaches the sentry trace and baggage headers', async () => {
- const transaction = hub.startTransaction({ name: 'test-transaction' }) as Transaction;
- hub.getScope().setSpan(transaction);
+ // This flakes on CI for some reason: https://github.com/getsentry/sentry-javascript/pull/8449
+ it.skip('attaches the sentry trace and baggage headers if there is an active span', async () => {
+ expect.assertions(3);
- await fetch('http://localhost:18099', { method: 'POST' });
+ await runWithAsyncContext(async () => {
+ const transaction = hub.startTransaction({ name: 'test-transaction' }) as Transaction;
+ hub.getScope().setSpan(transaction);
- expect(transaction.spanRecorder?.spans.length).toBe(2);
- const span = transaction.spanRecorder?.spans[1];
+ await fetch('http://localhost:18100', { method: 'POST' });
+
+ expect(transaction.spanRecorder?.spans.length).toBe(2);
+ const span = transaction.spanRecorder?.spans[1];
+
+ expect(requestHeaders['sentry-trace']).toEqual(span?.toTraceparent());
+ expect(requestHeaders['baggage']).toEqual(
+ `sentry-environment=production,sentry-public_key=0,sentry-trace_id=${transaction.traceId},sentry-sample_rate=1,sentry-transaction=test-transaction`,
+ );
+ });
+ });
+
+ // This flakes on CI for some reason: https://github.com/getsentry/sentry-javascript/pull/8449
+ it.skip('attaches the sentry trace and baggage headers if there is no active span', async () => {
+ const scope = hub.getScope();
- expect(requestHeaders['sentry-trace']).toEqual(span?.toTraceparent());
+ await fetch('http://localhost:18100', { method: 'POST' });
+
+ const propagationContext = scope.getPropagationContext();
+
+ expect(requestHeaders['sentry-trace'].includes(propagationContext.traceId)).toBe(true);
expect(requestHeaders['baggage']).toEqual(
- `sentry-environment=production,sentry-transaction=test-transaction,sentry-public_key=0,sentry-trace_id=${transaction.traceId},sentry-sample_rate=1`,
+ `sentry-environment=production,sentry-public_key=0,sentry-trace_id=${propagationContext.traceId},sentry-sample_rate=1,sentry-transaction=test-transaction,sentry-sampled=true`,
);
});
- it('does not attach headers if `shouldCreateSpanForRequest` does not create a span', async () => {
+ // This flakes on CI for some reason: https://github.com/getsentry/sentry-javascript/pull/8449
+ it.skip('attaches headers if `shouldCreateSpanForRequest` does not create a span using propagation context', async () => {
const transaction = hub.startTransaction({ name: 'test-transaction' }) as Transaction;
- hub.getScope().setSpan(transaction);
+ const scope = hub.getScope();
+ const propagationContext = scope.getPropagationContext();
- const undoPatch = patchUndici(hub, { shouldCreateSpanForRequest: url => url.includes('yes') });
+ scope.setSpan(transaction);
- await fetch('http://localhost:18099/no', { method: 'POST' });
+ const undoPatch = patchUndici({ shouldCreateSpanForRequest: url => url.includes('yes') });
- expect(requestHeaders['sentry-trace']).toBeUndefined();
- expect(requestHeaders['baggage']).toBeUndefined();
+ await fetch('http://localhost:18100/no', { method: 'POST' });
+
+ expect(requestHeaders['sentry-trace']).toBeDefined();
+ expect(requestHeaders['baggage']).toBeDefined();
+
+ expect(requestHeaders['sentry-trace'].includes(propagationContext.traceId)).toBe(true);
+ const firstSpanId = requestHeaders['sentry-trace'].split('-')[1];
- await fetch('http://localhost:18099/yes', { method: 'POST' });
+ await fetch('http://localhost:18100/yes', { method: 'POST' });
expect(requestHeaders['sentry-trace']).toBeDefined();
expect(requestHeaders['baggage']).toBeDefined();
+ expect(requestHeaders['sentry-trace'].includes(propagationContext.traceId)).toBe(false);
+
+ const secondSpanId = requestHeaders['sentry-trace'].split('-')[1];
+ expect(firstSpanId).not.toBe(secondSpanId);
+
undoPatch();
});
- it('uses tracePropagationTargets', async () => {
+ // This flakes on CI for some reason: https://github.com/getsentry/sentry-javascript/pull/8449
+ it.skip('uses tracePropagationTargets', async () => {
const transaction = hub.startTransaction({ name: 'test-transaction' }) as Transaction;
hub.getScope().setSpan(transaction);
@@ -236,14 +268,14 @@ conditionalTest({ min: 16 })('Undici integration', () => {
expect(transaction.spanRecorder?.spans.length).toBe(1);
- await fetch('http://localhost:18099/no', { method: 'POST' });
+ await fetch('http://localhost:18100/no', { method: 'POST' });
expect(transaction.spanRecorder?.spans.length).toBe(2);
expect(requestHeaders['sentry-trace']).toBeUndefined();
expect(requestHeaders['baggage']).toBeUndefined();
- await fetch('http://localhost:18099/yes', { method: 'POST' });
+ await fetch('http://localhost:18100/yes', { method: 'POST' });
expect(transaction.spanRecorder?.spans.length).toBe(3);
@@ -262,7 +294,7 @@ conditionalTest({ min: 16 })('Undici integration', () => {
data: {
method: 'POST',
status_code: 200,
- url: 'http://localhost:18099/',
+ url: 'http://localhost:18100/',
},
type: 'http',
timestamp: expect.any(Number),
@@ -272,7 +304,7 @@ conditionalTest({ min: 16 })('Undici integration', () => {
});
hub.bindClient(client);
- await fetch('http://localhost:18099', { method: 'POST' });
+ await fetch('http://localhost:18100', { method: 'POST' });
});
it('adds a breadcrumb on errored request', async () => {
@@ -306,9 +338,9 @@ conditionalTest({ min: 16 })('Undici integration', () => {
it('does not add a breadcrumb if disabled', async () => {
expect.assertions(0);
- const undoPatch = patchUndici(hub, { breadcrumbs: false });
+ const undoPatch = patchUndici({ breadcrumbs: false });
- await fetch('http://localhost:18099', { method: 'POST' });
+ await fetch('http://localhost:18100', { method: 'POST' });
undoPatch();
});
@@ -351,37 +383,34 @@ function setupTestServer() {
res.end();
// also terminate socket because keepalive hangs connection a bit
- res.connection.end();
+ res.connection?.end();
});
- testServer.listen(18099, 'localhost');
+ testServer?.listen(18100);
return new Promise(resolve => {
testServer?.on('listening', resolve);
});
}
-function patchUndici(hub: Hub, userOptions: Partial): () => void {
- let options: any = {};
- const client = hub.getClient();
- if (client) {
- const undici = client.getIntegration(Undici);
- if (undici) {
- // @ts-ignore need to access private property
- options = { ...undici._options };
- // @ts-ignore need to access private property
- undici._options = Object.assign(undici._options, userOptions);
- }
+function patchUndici(userOptions: Partial): () => void {
+ try {
+ const undici = hub.getClient()!.getIntegration(Undici);
+ // @ts-ignore need to access private property
+ options = { ...undici._options };
+ // @ts-ignore need to access private property
+ undici._options = Object.assign(undici._options, userOptions);
+ } catch (_) {
+ throw new Error('Could not undo patching of undici');
}
return () => {
- const client = hub.getClient();
- if (client) {
- const undici = client.getIntegration(Undici);
- if (undici) {
- // @ts-ignore need to access private property
- undici._options = { ...options };
- }
+ try {
+ const undici = hub.getClient()!.getIntegration(Undici);
+ // @ts-expect-error Need to override readonly property
+ undici!['_options'] = { ...options };
+ } catch (_) {
+ throw new Error('Could not undo patching of undici');
}
};
}
diff --git a/packages/node/test/manual/apm-transaction/main.js b/packages/node/test/manual/apm-transaction/main.js
deleted file mode 100644
index 0584177e8b10..000000000000
--- a/packages/node/test/manual/apm-transaction/main.js
+++ /dev/null
@@ -1,113 +0,0 @@
-const http = require('http');
-const express = require('express');
-const app = express();
-const Sentry = require('../../../build/cjs');
-
-Sentry.init({
- debug: true,
- dsn: 'http://test@example.com/1337',
- beforeSend(event) {
- console.log(JSON.stringify(event, null, 2));
- return null;
- },
-});
-
-function hasSentryTraceHeader(req) {
- return req.headers && typeof req.headers['sentry-trace'] === 'string';
-}
-
-class Tracing {
- static start() {
- return (req, _res, next) => {
- const transaction = `${req.method.toUpperCase()} ${req.originalUrl}`;
- const span = hasSentryTraceHeader(req)
- ? Span.fromTraceparent(req.headers['sentry-trace'], {
- transaction,
- })
- : Sentry.startTransaction({
- name: transaction,
- });
-
- Sentry.getCurrentHub().configureScope(scope => {
- scope.setSpan(span);
- });
-
- next();
- };
- }
-
- static finish() {
- return (_req, _res, next) => {
- const scope = Sentry.getCurrentHub().getScope();
- if (!scope) {
- return next();
- }
- const span = scope.getSpan();
- if (!span) {
- return next();
- }
- Sentry.getCurrentHub().finishSpan(span);
- next();
- };
- }
-}
-
-async function databaseCall(_query) {
- const span = Sentry.getCurrentHub().startSpan({
- op: 'db',
- });
-
- return new Promise(resolve => {
- setTimeout(() => {
- Sentry.getCurrentHub().finishSpan(span);
- resolve('http://whatever.com/raw');
- }, Math.random() * 100);
- });
-}
-
-async function httpCall(_url) {
- const span = Sentry.getCurrentHub().startSpan({
- op: 'http',
- });
-
- return new Promise(resolve => {
- setTimeout(() => {
- Sentry.getCurrentHub().finishSpan(span);
- resolve('httpCall');
- }, Math.random() * 100);
- });
-}
-
-async function encodeData(_data) {
- const span = Sentry.getCurrentHub().startSpan({
- op: 'encode',
- });
-
- return new Promise(resolve => {
- setTimeout(() => {
- Sentry.getCurrentHub().finishSpan(span);
- resolve('encodedData');
- }, Math.random() * 100);
- });
-}
-
-app.use(Sentry.Handlers.requestHandler());
-app.use(Tracing.start());
-
-app.get('/trace', async (_req, res, next) => {
- const url = await databaseCall('SELECT url FROM queue WHERE processed = 0 LIMIT 1');
- const raw = await httpCall(url);
- const encoded = await encodeData(raw);
- res.status(200).send(encoded);
- next();
-});
-
-app.use(Tracing.finish());
-app.use(Sentry.Handlers.errorHandler());
-
-const server = app.listen(0, () => {
- const port = server.address().port;
- http.get(`http://localhost:${port}/trace`, res => {
- server.close();
- });
-});
diff --git a/packages/node/test/manual/webpack-async-context/yarn.lock b/packages/node/test/manual/webpack-async-context/yarn.lock
index 79d15b238de4..984f2cbbf55e 100644
--- a/packages/node/test/manual/webpack-async-context/yarn.lock
+++ b/packages/node/test/manual/webpack-async-context/yarn.lock
@@ -2112,9 +2112,9 @@ schema-utils@^1.0.0:
ajv-keywords "^3.1.0"
semver@^5.5.0, semver@^5.6.0:
- version "5.7.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
- integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
+ version "5.7.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
+ integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
serialize-javascript@^2.1.2:
version "2.1.2"
diff --git a/packages/node/test/module.test.ts b/packages/node/test/module.test.ts
index 39f1e9758f46..e27f1482ff90 100644
--- a/packages/node/test/module.test.ts
+++ b/packages/node/test/module.test.ts
@@ -1,4 +1,4 @@
-import { getModule } from '../src/module';
+import { getModuleFromFilename } from '../src/module';
function withFilename(fn: () => void, filename: string) {
const prevFilename = require.main?.filename;
@@ -15,16 +15,16 @@ function withFilename(fn: () => void, filename: string) {
}
}
-describe('getModule', () => {
+describe('getModuleFromFilename', () => {
test('Windows', () => {
withFilename(() => {
- expect(getModule('C:\\Users\\users\\Tim\\Desktop\\node_modules\\module.js', true)).toEqual('module');
+ expect(getModuleFromFilename('C:\\Users\\users\\Tim\\Desktop\\node_modules\\module.js', true)).toEqual('module');
}, 'C:\\Users\\Tim\\app.js');
});
test('POSIX', () => {
withFilename(() => {
- expect(getModule('/Users/users/Tim/Desktop/node_modules/module.js')).toEqual('module');
+ expect(getModuleFromFilename('/Users/users/Tim/Desktop/node_modules/module.js')).toEqual('module');
}, '/Users/Tim/app.js');
});
});
diff --git a/packages/opentelemetry-node/test/propagator.test.ts b/packages/opentelemetry-node/test/propagator.test.ts
index d5222e3103d4..a70ecb051663 100644
--- a/packages/opentelemetry-node/test/propagator.test.ts
+++ b/packages/opentelemetry-node/test/propagator.test.ts
@@ -85,7 +85,7 @@ describe('SentryPropagator', () => {
spanId: '6e0c63257de34c92',
sampled: true,
},
- 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b',
+ 'sentry-environment=production,sentry-release=1.0.0,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b,sentry-transaction=sampled-transaction,sentry-sampled=true',
'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-1',
],
[
@@ -101,7 +101,7 @@ describe('SentryPropagator', () => {
spanId: '6e0c63257de34c92',
sampled: false,
},
- 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=not-sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b',
+ 'sentry-environment=production,sentry-release=1.0.0,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b,sentry-transaction=not-sampled-transaction,sentry-sampled=false',
'd4cda95b652f4a1592b449d5929fda1b-6e0c63257de34c92-0',
],
[
@@ -161,7 +161,7 @@ describe('SentryPropagator', () => {
const baggage = propagation.createBaggage({ foo: { value: 'bar' } });
propagator.inject(propagation.setBaggage(context, baggage), carrier, defaultTextMapSetter);
expect(carrier[SENTRY_BAGGAGE_HEADER]).toBe(
- 'foo=bar,sentry-environment=production,sentry-release=1.0.0,sentry-transaction=sampled-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b',
+ 'foo=bar,sentry-environment=production,sentry-release=1.0.0,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b,sentry-transaction=sampled-transaction,sentry-sampled=true',
);
});
@@ -232,7 +232,7 @@ describe('SentryPropagator', () => {
it('sets defined dynamic sampling context on context', () => {
const baggage =
- 'sentry-environment=production,sentry-release=1.0.0,sentry-transaction=dsc-transaction,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b';
+ 'sentry-environment=production,sentry-release=1.0.0,sentry-public_key=abc,sentry-trace_id=d4cda95b652f4a1592b449d5929fda1b,sentry-transaction=dsc-transaction';
carrier[SENTRY_BAGGAGE_HEADER] = baggage;
const context = propagator.extract(ROOT_CONTEXT, carrier, defaultTextMapGetter);
expect(context.getValue(SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY)).toEqual({
diff --git a/packages/react/src/reactrouterv6.tsx b/packages/react/src/reactrouterv6.tsx
index bc917ff12508..161c7dd5fb3b 100644
--- a/packages/react/src/reactrouterv6.tsx
+++ b/packages/react/src/reactrouterv6.tsx
@@ -119,8 +119,15 @@ function getNormalizedName(
return [location.pathname, 'url'];
}
-function updatePageloadTransaction(location: Location, routes: RouteObject[], matches?: AgnosticDataRouteMatch): void {
- const branches = Array.isArray(matches) ? matches : (_matchRoutes(routes, location) as unknown as RouteMatch[]);
+function updatePageloadTransaction(
+ location: Location,
+ routes: RouteObject[],
+ matches?: AgnosticDataRouteMatch,
+ basename?: string,
+): void {
+ const branches = Array.isArray(matches)
+ ? matches
+ : (_matchRoutes(routes, location, basename) as unknown as RouteMatch[]);
if (activeTransaction && branches) {
activeTransaction.setName(...getNormalizedName(routes, location, branches));
@@ -132,8 +139,9 @@ function handleNavigation(
routes: RouteObject[],
navigationType: Action,
matches?: AgnosticDataRouteMatch,
+ basename?: string,
): void {
- const branches = Array.isArray(matches) ? matches : _matchRoutes(routes, location);
+ const branches = Array.isArray(matches) ? matches : _matchRoutes(routes, location, basename);
if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP') && branches) {
if (activeTransaction) {
@@ -254,15 +262,17 @@ export function wrapCreateBrowserRouter<
TRouter extends Router = Router,
>(createRouterFunction: CreateRouterFunction): CreateRouterFunction {
// `opts` for createBrowserHistory and createMemoryHistory are different, but also not relevant for us at the moment.
+ // `basename` is the only option that is relevant for us, and it is the same for all.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- return function (routes: RouteObject[], opts?: any): TRouter {
+ return function (routes: RouteObject[], opts?: Record & { basename?: string }): TRouter {
const router = createRouterFunction(routes, opts);
+ const basename = opts && opts.basename;
// The initial load ends when `createBrowserRouter` is called.
// This is the earliest convenient time to update the transaction name.
// Callbacks to `router.subscribe` are not called for the initial load.
if (router.state.historyAction === 'POP' && activeTransaction) {
- updatePageloadTransaction(router.state.location, routes);
+ updatePageloadTransaction(router.state.location, routes, undefined, basename);
}
router.subscribe((state: RouterState) => {
@@ -273,7 +283,7 @@ export function wrapCreateBrowserRouter<
(state.historyAction === 'PUSH' || state.historyAction === 'POP') &&
activeTransaction
) {
- handleNavigation(location, routes, state.historyAction);
+ handleNavigation(location, routes, state.historyAction, undefined, basename);
}
});
diff --git a/packages/react/src/types.ts b/packages/react/src/types.ts
index 409a0a33c23d..fb0652acb036 100644
--- a/packages/react/src/types.ts
+++ b/packages/react/src/types.ts
@@ -75,7 +75,11 @@ export type UseNavigationType = () => Action;
export type RouteObjectArrayAlias = any;
export type RouteMatchAlias = any;
export type CreateRoutesFromChildren = (children: JSX.Element[]) => RouteObjectArrayAlias;
-export type MatchRoutes = (routes: RouteObjectArrayAlias, location: Location) => RouteMatchAlias[] | null;
+export type MatchRoutes = (
+ routes: RouteObjectArrayAlias,
+ location: Location,
+ basename?: string,
+) => RouteMatchAlias[] | null;
// Types for react-router >= 6.4.2
export type ShouldRevalidateFunction = (args: any) => boolean;
@@ -203,7 +207,7 @@ export declare enum HistoryAction {
export interface RouterState {
historyAction: Action | HistoryAction | any;
- location: any;
+ location: Location;
}
export interface Router {
state: TState;
diff --git a/packages/react/test/reactrouterv6.4.test.tsx b/packages/react/test/reactrouterv6.4.test.tsx
index a01da694ce2f..e6bfc67b9bcf 100644
--- a/packages/react/test/reactrouterv6.4.test.tsx
+++ b/packages/react/test/reactrouterv6.4.test.tsx
@@ -265,5 +265,44 @@ describe('React Router v6.4', () => {
expect(mockStartTransaction).toHaveBeenCalledTimes(1);
expect(mockSetName).toHaveBeenLastCalledWith('/about/:page', 'route');
});
+
+ it('works with `basename` option', () => {
+ const [mockStartTransaction] = createInstrumentation();
+ const sentryCreateBrowserRouter = wrapCreateBrowserRouter(createMemoryRouter as CreateRouterFunction);
+
+ const router = sentryCreateBrowserRouter(
+ [
+ {
+ path: '/',
+ element: ,
+ },
+ {
+ path: 'about',
+ element: About
,
+ children: [
+ {
+ path: 'us',
+ element: Us
,
+ },
+ ],
+ },
+ ],
+ {
+ initialEntries: ['/app'],
+ basename: '/app',
+ },
+ );
+
+ // @ts-ignore router is fine
+ render();
+
+ expect(mockStartTransaction).toHaveBeenCalledTimes(2);
+ expect(mockStartTransaction).toHaveBeenLastCalledWith({
+ name: '/app/about/us',
+ op: 'navigation',
+ tags: { 'routing.instrumentation': 'react-router-v6' },
+ metadata: { source: 'url' },
+ });
+ });
});
});
diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts
index 21cfc20b17ab..91839a809993 100644
--- a/packages/remix/src/index.server.ts
+++ b/packages/remix/src/index.server.ts
@@ -6,9 +6,56 @@ import { instrumentServer } from './utils/instrumentServer';
import { buildMetadata } from './utils/metadata';
import type { RemixOptions } from './utils/remixOptions';
+// We need to explicitly export @sentry/node as they end up under `default` in ESM builds
+// See: https://github.com/getsentry/sentry-javascript/issues/8474
+export {
+ addGlobalEventProcessor,
+ addBreadcrumb,
+ captureCheckIn,
+ captureException,
+ captureEvent,
+ captureMessage,
+ configureScope,
+ createTransport,
+ extractTraceparentData,
+ getActiveTransaction,
+ getHubFromCarrier,
+ getCurrentHub,
+ Hub,
+ makeMain,
+ Scope,
+ startTransaction,
+ SDK_VERSION,
+ setContext,
+ setExtra,
+ setExtras,
+ setTag,
+ setTags,
+ setUser,
+ spanStatusfromHttpCode,
+ trace,
+ withScope,
+ autoDiscoverNodePerformanceMonitoringIntegrations,
+ makeNodeTransport,
+ defaultIntegrations,
+ defaultStackParser,
+ lastEventId,
+ flush,
+ close,
+ getSentryRelease,
+ addRequestDataToEvent,
+ DEFAULT_USER_INCLUDES,
+ extractRequestData,
+ deepReadDirSync,
+ Integrations,
+ Handlers,
+} from '@sentry/node';
+
+// Keeping the `*` exports for backwards compatibility and types
+export * from '@sentry/node';
+
export { ErrorBoundary, withErrorBoundary } from '@sentry/react';
export { remixRouterInstrumentation, withSentry } from './performance/client';
-export * from '@sentry/node';
export { wrapExpressCreateRequestHandler } from './utils/serverAdapters/express';
function sdkAlreadyInitialized(): boolean {
diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts
index 5e0f300bf82e..64dea4cfb92b 100644
--- a/packages/remix/src/utils/instrumentServer.ts
+++ b/packages/remix/src/utils/instrumentServer.ts
@@ -5,13 +5,12 @@ import { captureException, getCurrentHub } from '@sentry/node';
import type { Transaction, TransactionSource, WrappedFunction } from '@sentry/types';
import {
addExceptionMechanism,
- baggageHeaderToDynamicSamplingContext,
dynamicSamplingContextToSentryBaggageHeader,
- extractTraceparentData,
fill,
isNodeEnv,
loadModule,
logger,
+ tracingContextFromHeaders,
} from '@sentry/utils';
import type {
@@ -237,18 +236,26 @@ function makeWrappedRootLoader(origLoader: DataFunction): DataFunction {
};
}
- // Note: `redirect` and `catch` responses do not have bodies to extract
- if (isResponse(res) && !isRedirectResponse(res) && !isCatchResponse(res)) {
- const data = await extractData(res);
-
- if (typeof data === 'object') {
- return json(
- { ...data, ...traceAndBaggage },
- { headers: res.headers, statusText: res.statusText, status: res.status },
- );
- } else {
- __DEBUG_BUILD__ && logger.warn('Skipping injection of trace and baggage as the response body is not an object');
+ if (isResponse(res)) {
+ // Note: `redirect` and `catch` responses do not have bodies to extract.
+ // We skip injection of trace and baggage in those cases.
+ // For `redirect`, a valid internal redirection target will have the trace and baggage injected.
+ if (isRedirectResponse(res) || isCatchResponse(res)) {
+ __DEBUG_BUILD__ && logger.warn('Skipping injection of trace and baggage as the response does not have a body');
return res;
+ } else {
+ const data = await extractData(res);
+
+ if (typeof data === 'object') {
+ return json(
+ { ...data, ...traceAndBaggage },
+ { headers: res.headers, statusText: res.statusText, status: res.status },
+ );
+ } else {
+ __DEBUG_BUILD__ &&
+ logger.warn('Skipping injection of trace and baggage as the response body is not an object');
+ return res;
+ }
}
}
@@ -290,9 +297,11 @@ export function startRequestHandlerTransaction(
method: string;
},
): Transaction {
- // If there is a trace header set, we extract the data from it (parentSpanId, traceId, and sampling decision)
- const traceparentData = extractTraceparentData(request.headers['sentry-trace']);
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(request.headers.baggage);
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ request.headers['sentry-trace'],
+ request.headers.baggage,
+ );
+ hub.getScope().setPropagationContext(propagationContext);
const transaction = hub.startTransaction({
name,
diff --git a/packages/remix/test/integration/app_v1/entry.server.tsx b/packages/remix/test/integration/app_v1/entry.server.tsx
index ae879492e236..d48f2644fac4 100644
--- a/packages/remix/test/integration/app_v1/entry.server.tsx
+++ b/packages/remix/test/integration/app_v1/entry.server.tsx
@@ -6,6 +6,7 @@ import * as Sentry from '@sentry/remix';
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
tracesSampleRate: 1,
+ tracePropagationTargets: ['example.org'],
// Disabling to test series of envelopes deterministically.
autoSessionTracking: false,
});
diff --git a/packages/remix/test/integration/app_v1/root.tsx b/packages/remix/test/integration/app_v1/root.tsx
index 1e716237343c..ee9b6ceddb78 100644
--- a/packages/remix/test/integration/app_v1/root.tsx
+++ b/packages/remix/test/integration/app_v1/root.tsx
@@ -34,6 +34,10 @@ export const loader: LoaderFunction = async ({ request }) => {
throw redirect('/?type=plain');
case 'returnRedirect':
return redirect('/?type=plain');
+ case 'throwRedirectToExternal':
+ throw redirect('https://example.com');
+ case 'returnRedirectToExternal':
+ return redirect('https://example.com');
default: {
return {};
}
diff --git a/packages/remix/test/integration/app_v2/entry.server.tsx b/packages/remix/test/integration/app_v2/entry.server.tsx
index ae879492e236..d48f2644fac4 100644
--- a/packages/remix/test/integration/app_v2/entry.server.tsx
+++ b/packages/remix/test/integration/app_v2/entry.server.tsx
@@ -6,6 +6,7 @@ import * as Sentry from '@sentry/remix';
Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
tracesSampleRate: 1,
+ tracePropagationTargets: ['example.org'],
// Disabling to test series of envelopes deterministically.
autoSessionTracking: false,
});
diff --git a/packages/remix/test/integration/app_v2/root.tsx b/packages/remix/test/integration/app_v2/root.tsx
index faf075951d69..5af1f8cc7a1a 100644
--- a/packages/remix/test/integration/app_v2/root.tsx
+++ b/packages/remix/test/integration/app_v2/root.tsx
@@ -34,6 +34,10 @@ export const loader: LoaderFunction = async ({ request }) => {
throw redirect('/?type=plain');
case 'returnRedirect':
return redirect('/?type=plain');
+ case 'throwRedirectToExternal':
+ throw redirect('https://example.com');
+ case 'returnRedirectToExternal':
+ return redirect('https://example.com');
default: {
return {};
}
diff --git a/packages/remix/test/integration/test/client/meta-tags.test.ts b/packages/remix/test/integration/test/client/meta-tags.test.ts
index f956787b35c6..6d0a0cd06307 100644
--- a/packages/remix/test/integration/test/client/meta-tags.test.ts
+++ b/packages/remix/test/integration/test/client/meta-tags.test.ts
@@ -2,7 +2,13 @@ import { test, expect } from '@playwright/test';
import { getFirstSentryEnvelopeRequest } from './utils/helpers';
import { Event } from '@sentry/types';
-test('should inject `sentry-trace` and `baggage` meta tags inside the root page.', async ({ page }) => {
+test('should inject `sentry-trace` and `baggage` meta tags inside the root page.', async ({ page, browserName }) => {
+ // This test is flaky on firefox
+ // https://github.com/getsentry/sentry-javascript/issues/8398
+ if (browserName === 'firefox') {
+ test.skip();
+ }
+
await page.goto('/');
const sentryTraceTag = await page.$('meta[name="sentry-trace"]');
@@ -16,7 +22,16 @@ test('should inject `sentry-trace` and `baggage` meta tags inside the root page.
expect(sentryBaggageContent).toEqual(expect.any(String));
});
-test('should inject `sentry-trace` and `baggage` meta tags inside a parameterized route.', async ({ page }) => {
+test('should inject `sentry-trace` and `baggage` meta tags inside a parameterized route.', async ({
+ page,
+ browserName,
+}) => {
+ // This test is flaky on firefox
+ // https://github.com/getsentry/sentry-javascript/issues/8398
+ if (browserName === 'firefox') {
+ test.skip();
+ }
+
await page.goto('/loader-json-response/0');
const sentryTraceTag = await page.$('meta[name="sentry-trace"]');
@@ -30,7 +45,16 @@ test('should inject `sentry-trace` and `baggage` meta tags inside a parameterize
expect(sentryBaggageContent).toEqual(expect.any(String));
});
-test('should send transactions with corresponding `sentry-trace` and `baggage` inside root page', async ({ page }) => {
+test('should send transactions with corresponding `sentry-trace` and `baggage` inside root page', async ({
+ page,
+ browserName,
+}) => {
+ // This test is flaky on firefox
+ // https://github.com/getsentry/sentry-javascript/issues/8398
+ if (browserName === 'firefox') {
+ test.skip();
+ }
+
const envelope = await getFirstSentryEnvelopeRequest(page, '/');
const sentryTraceTag = await page.$('meta[name="sentry-trace"]');
@@ -47,7 +71,14 @@ test('should send transactions with corresponding `sentry-trace` and `baggage` i
test('should send transactions with corresponding `sentry-trace` and `baggage` inside a parameterized route', async ({
page,
+ browserName,
}) => {
+ // This test is flaky on firefox
+ // https://github.com/getsentry/sentry-javascript/issues/8398
+ if (browserName === 'firefox') {
+ test.skip();
+ }
+
const envelope = await getFirstSentryEnvelopeRequest(page, '/loader-json-response/0');
const sentryTraceTag = await page.$('meta[name="sentry-trace"]');
diff --git a/packages/remix/test/integration/test/client/root-loader.test.ts b/packages/remix/test/integration/test/client/root-loader.test.ts
index 4bb5b41a82ce..c78ceb2aa411 100644
--- a/packages/remix/test/integration/test/client/root-loader.test.ts
+++ b/packages/remix/test/integration/test/client/root-loader.test.ts
@@ -125,6 +125,9 @@ test('should inject `sentry-trace` and `baggage` into root loader throwing a red
}) => {
await page.goto('/?type=throwRedirect');
+ // We should be successfully redirected to the path.
+ expect(page.url()).toEqual(expect.stringContaining('/?type=plain'));
+
const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page);
expect(sentryTrace).toEqual(expect.any(String));
@@ -138,11 +141,14 @@ test('should inject `sentry-trace` and `baggage` into root loader throwing a red
});
});
-test('should inject `sentry-trace` and `baggage` into root loader returning a redirection to a plain object', async ({
+test('should inject `sentry-trace` and `baggage` into root loader returning a redirection to valid path.', async ({
page,
}) => {
await page.goto('/?type=returnRedirect');
+ // We should be successfully redirected to the path.
+ expect(page.url()).toEqual(expect.stringContaining('/?type=plain'));
+
const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page);
expect(sentryTrace).toEqual(expect.any(String));
@@ -155,3 +161,27 @@ test('should inject `sentry-trace` and `baggage` into root loader returning a re
sentryBaggage: sentryBaggage,
});
});
+
+test('should return redirect to an external path with no baggage and trace injected.', async ({ page }) => {
+ await page.goto('/?type=returnRedirectToExternal');
+
+ // We should be successfully redirected to the external path.
+ expect(page.url()).toEqual(expect.stringContaining('https://example.com'));
+
+ const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page);
+
+ expect(sentryTrace).toBeUndefined();
+ expect(sentryBaggage).toBeUndefined();
+});
+
+test('should throw redirect to an external path with no baggage and trace injected.', async ({ page }) => {
+ await page.goto('/?type=throwRedirectToExternal');
+
+ // We should be successfully redirected to the external path.
+ expect(page.url()).toEqual(expect.stringContaining('https://example.com'));
+
+ const { sentryTrace, sentryBaggage } = await extractTraceAndBaggageFromMeta(page);
+
+ expect(sentryTrace).toBeUndefined();
+ expect(sentryBaggage).toBeUndefined();
+});
diff --git a/packages/replay/src/constants.ts b/packages/replay/src/constants.ts
index 699cefe8b784..86dc228c50bf 100644
--- a/packages/replay/src/constants.ts
+++ b/packages/replay/src/constants.ts
@@ -42,8 +42,6 @@ export const CONSOLE_ARG_MAX_SIZE = 5_000;
export const SLOW_CLICK_THRESHOLD = 3_000;
/* For scroll actions after a click, we only look for a very short time period to detect programmatic scrolling. */
export const SLOW_CLICK_SCROLL_TIMEOUT = 300;
-/* Clicks in this time period are considered e.g. double/triple clicks. */
-export const MULTI_CLICK_TIMEOUT = 1_000;
/** When encountering a total segment size exceeding this size, stop the replay (as we cannot properly ingest it). */
export const REPLAY_MAX_EVENT_BUFFER_SIZE = 20_000_000; // ~20MB
diff --git a/packages/replay/src/coreHandlers/handleClick.ts b/packages/replay/src/coreHandlers/handleClick.ts
index c5a65ddfdca0..5f7e46dbcbce 100644
--- a/packages/replay/src/coreHandlers/handleClick.ts
+++ b/packages/replay/src/coreHandlers/handleClick.ts
@@ -33,7 +33,6 @@ export class ClickDetector implements ReplayClickDetector {
private _clicks: Click[] = [];
private _teardown: undefined | (() => void);
- private _multiClickTimeout: number;
private _threshold: number;
private _scollTimeout: number;
private _timeout: number;
@@ -51,7 +50,6 @@ export class ClickDetector implements ReplayClickDetector {
) {
// We want everything in s, but options are in ms
this._timeout = slowClickConfig.timeout / 1000;
- this._multiClickTimeout = slowClickConfig.multiClickTimeout / 1000;
this._threshold = slowClickConfig.threshold / 1000;
this._scollTimeout = slowClickConfig.scrollTimeout / 1000;
this._replay = replay;
@@ -126,13 +124,6 @@ export class ClickDetector implements ReplayClickDetector {
return;
}
- const click = this._getClick(node);
-
- if (click) {
- // this means a click on the same element was captured in the last 1s, so we consider this a multi click
- return;
- }
-
const newClick: Click = {
timestamp: breadcrumb.timestamp,
clickBreadcrumb: breadcrumb,
@@ -150,22 +141,14 @@ export class ClickDetector implements ReplayClickDetector {
/** Count multiple clicks on elements. */
private _handleMultiClick(node: HTMLElement): void {
- const click = this._getClick(node);
-
- if (!click) {
- return;
- }
-
- click.clickCount++;
+ this._getClicks(node).forEach(click => {
+ click.clickCount++;
+ });
}
- /** Try to get an existing click on the given element. */
- private _getClick(node: HTMLElement): Click | undefined {
- const now = nowInSeconds();
-
- // Find any click on the same element in the last second
- // If one exists, we consider this click as a double/triple/etc click
- return this._clicks.find(click => click.node === node && now - click.timestamp < this._multiClickTimeout);
+ /** Get all pending clicks for a given node. */
+ private _getClicks(node: HTMLElement): Click[] {
+ return this._clicks.filter(click => click.node === node);
}
/** Check the clicks that happened. */
@@ -182,13 +165,6 @@ export class ClickDetector implements ReplayClickDetector {
click.scrollAfter = click.timestamp <= this._lastScroll ? this._lastScroll - click.timestamp : undefined;
}
- // If an action happens after the multi click threshold, we can skip waiting and handle the click right away
- const actionTime = click.scrollAfter || click.mutationAfter || 0;
- if (actionTime && actionTime >= this._multiClickTimeout) {
- timedOutClicks.push(click);
- return;
- }
-
if (click.timestamp + this._timeout <= now) {
timedOutClicks.push(click);
}
@@ -269,6 +245,10 @@ export class ClickDetector implements ReplayClickDetector {
/** Schedule to check current clicks. */
private _scheduleCheckClicks(): void {
+ if (this._checkClickTimeout) {
+ clearTimeout(this._checkClickTimeout);
+ }
+
this._checkClickTimeout = setTimeout(() => this._checkClicks(), 1000);
}
}
diff --git a/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts b/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts
index 59324031e336..20fa00a633eb 100644
--- a/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts
+++ b/packages/replay/src/coreHandlers/handleNetworkBreadcrumbs.ts
@@ -31,13 +31,19 @@ export function handleNetworkBreadcrumbs(replay: ReplayContainer): void {
try {
const textEncoder = new TextEncoder();
- const { networkDetailAllowUrls, networkCaptureBodies, networkRequestHeaders, networkResponseHeaders } =
- replay.getOptions();
+ const {
+ networkDetailAllowUrls,
+ networkDetailDenyUrls,
+ networkCaptureBodies,
+ networkRequestHeaders,
+ networkResponseHeaders,
+ } = replay.getOptions();
const options: ExtendedNetworkBreadcrumbsOptions = {
replay,
textEncoder,
networkDetailAllowUrls,
+ networkDetailDenyUrls,
networkCaptureBodies,
networkRequestHeaders,
networkResponseHeaders,
diff --git a/packages/replay/src/coreHandlers/util/fetchUtils.ts b/packages/replay/src/coreHandlers/util/fetchUtils.ts
index 9411332d0197..491fe727b1b8 100644
--- a/packages/replay/src/coreHandlers/util/fetchUtils.ts
+++ b/packages/replay/src/coreHandlers/util/fetchUtils.ts
@@ -85,7 +85,8 @@ async function _prepareFetchData(
response_body_size: responseBodySize,
} = breadcrumb.data;
- const captureDetails = urlMatches(url, options.networkDetailAllowUrls);
+ const captureDetails =
+ urlMatches(url, options.networkDetailAllowUrls) && !urlMatches(url, options.networkDetailDenyUrls);
const request = captureDetails
? _getRequestInfo(options, hint.input, requestBodySize)
diff --git a/packages/replay/src/coreHandlers/util/xhrUtils.ts b/packages/replay/src/coreHandlers/util/xhrUtils.ts
index dfb1ccaf3ffc..638af2cbdb5c 100644
--- a/packages/replay/src/coreHandlers/util/xhrUtils.ts
+++ b/packages/replay/src/coreHandlers/util/xhrUtils.ts
@@ -78,7 +78,7 @@ function _prepareXhrData(
return null;
}
- if (!urlMatches(url, options.networkDetailAllowUrls)) {
+ if (!urlMatches(url, options.networkDetailAllowUrls) || urlMatches(url, options.networkDetailDenyUrls)) {
const request = buildSkippedNetworkRequestOrResponse(requestBodySize);
const response = buildSkippedNetworkRequestOrResponse(responseBodySize);
return {
diff --git a/packages/replay/src/integration.ts b/packages/replay/src/integration.ts
index 2baf117b5c38..2e795829894b 100644
--- a/packages/replay/src/integration.ts
+++ b/packages/replay/src/integration.ts
@@ -67,6 +67,7 @@ export class Replay implements Integration {
slowClickIgnoreSelectors = [],
networkDetailAllowUrls = [],
+ networkDetailDenyUrls = [],
networkCaptureBodies = true,
networkRequestHeaders = [],
networkResponseHeaders = [],
@@ -138,6 +139,7 @@ export class Replay implements Integration {
slowClickTimeout,
slowClickIgnoreSelectors,
networkDetailAllowUrls,
+ networkDetailDenyUrls,
networkCaptureBodies,
networkRequestHeaders: _getMergedNetworkHeaders(networkRequestHeaders),
networkResponseHeaders: _getMergedNetworkHeaders(networkResponseHeaders),
diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts
index 8fab410a0c34..c72306239533 100644
--- a/packages/replay/src/replay.ts
+++ b/packages/replay/src/replay.ts
@@ -7,7 +7,6 @@ import { logger } from '@sentry/utils';
import {
BUFFER_CHECKOUT_TIME,
MAX_SESSION_LIFE,
- MULTI_CLICK_TIMEOUT,
SESSION_IDLE_EXPIRE_DURATION,
SESSION_IDLE_PAUSE_DURATION,
SLOW_CLICK_SCROLL_TIMEOUT,
@@ -175,7 +174,6 @@ export class ReplayContainer implements ReplayContainerInterface {
timeout: slowClickTimeout,
scrollTimeout: SLOW_CLICK_SCROLL_TIMEOUT,
ignoreSelector: slowClickIgnoreSelectors ? slowClickIgnoreSelectors.join(',') : '',
- multiClickTimeout: MULTI_CLICK_TIMEOUT,
}
: undefined;
diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts
index e2cfddd0f525..00cda5e3c6e7 100644
--- a/packages/replay/src/types/replay.ts
+++ b/packages/replay/src/types/replay.ts
@@ -70,23 +70,32 @@ export interface ReplayNetworkOptions {
*/
networkDetailAllowUrls: (string | RegExp)[];
+ /**
+ * Deny request/response details for XHR/Fetch requests that match the given URLs.
+ * The URLs can be strings or regular expressions.
+ * When provided a string, we will deny any URL that contains the given string.
+ * You can use a Regex to handle exact matches or more complex matching.
+ * URLs matching these patterns will not have bodies & additional headers captured.
+ */
+ networkDetailDenyUrls: (string | RegExp)[];
+
/**
* If request & response bodies should be captured.
- * Only applies to URLs matched by `networkDetailAllowUrls`.
+ * Only applies to URLs matched by `networkDetailAllowUrls` and not matched by `networkDetailDenyUrls`.
* Defaults to true.
*/
networkCaptureBodies: boolean;
/**
* Capture the following request headers, in addition to the default ones.
- * Only applies to URLs matched by `networkDetailAllowUrls`.
+ * Only applies to URLs matched by `networkDetailAllowUrls` and not matched by `networkDetailDenyUrls`.
* Any headers defined here will be captured in addition to the default headers.
*/
networkRequestHeaders: string[];
/**
* Capture the following response headers, in addition to the default ones.
- * Only applies to URLs matched by `networkDetailAllowUrls`.
+ * Only applies to URLs matched by `networkDetailAllowUrls` and not matched by `networkDetailDenyUrls`.
* Any headers defined here will be captured in addition to the default headers.
*/
networkResponseHeaders: string[];
@@ -476,5 +485,4 @@ export interface SlowClickConfig {
timeout: number;
scrollTimeout: number;
ignoreSelector: string;
- multiClickTimeout: number;
}
diff --git a/packages/replay/src/util/sendReplayRequest.ts b/packages/replay/src/util/sendReplayRequest.ts
index b6f49c0b9c9a..f0a01f0bf79a 100644
--- a/packages/replay/src/util/sendReplayRequest.ts
+++ b/packages/replay/src/util/sendReplayRequest.ts
@@ -93,6 +93,12 @@ export async function sendReplayRequest({
}
*/
+ // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
+ // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
+ // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid
+ // of this `delete`, lest we miss putting it back in the next time the property is in use.)
+ delete replayEvent.sdkProcessingMetadata;
+
const envelope = createReplayEnvelope(replayEvent, preparedRecordingData, dsn, client.getOptions().tunnel);
let response: void | TransportMakeRequestResponse;
diff --git a/packages/replay/test/unit/coreHandlers/handleClick.test.ts b/packages/replay/test/unit/coreHandlers/handleClick.test.ts
index 8b06e4683656..f2980e60df69 100644
--- a/packages/replay/test/unit/coreHandlers/handleClick.test.ts
+++ b/packages/replay/test/unit/coreHandlers/handleClick.test.ts
@@ -26,7 +26,6 @@ describe('Unit | coreHandlers | handleClick', () => {
timeout: 3_000,
scrollTimeout: 200,
ignoreSelector: '',
- multiClickTimeout: 1_000,
},
mockAddBreadcrumbEvent,
);
@@ -72,113 +71,6 @@ describe('Unit | coreHandlers | handleClick', () => {
expect(mockAddBreadcrumbEvent).toHaveBeenCalledTimes(1);
});
- test('it groups multiple clicks together', async () => {
- const replay = {
- getCurrentRoute: () => 'test-route',
- } as ReplayContainer;
-
- const mockAddBreadcrumbEvent = jest.fn();
-
- const detector = new ClickDetector(
- replay,
- {
- threshold: 1_000,
- timeout: 3_000,
- scrollTimeout: 200,
- ignoreSelector: '',
- multiClickTimeout: 1_000,
- },
- mockAddBreadcrumbEvent,
- );
-
- const breadcrumb1: Breadcrumb = {
- timestamp: BASE_TIMESTAMP / 1000,
- data: {
- nodeId: 1,
- },
- };
- const breadcrumb2: Breadcrumb = {
- timestamp: BASE_TIMESTAMP / 1000 + 0.2,
- data: {
- nodeId: 1,
- },
- };
- const breadcrumb3: Breadcrumb = {
- timestamp: BASE_TIMESTAMP / 1000 + 0.6,
- data: {
- nodeId: 1,
- },
- };
- const breadcrumb4: Breadcrumb = {
- timestamp: BASE_TIMESTAMP / 1000 + 2,
- data: {
- nodeId: 1,
- },
- };
- const breadcrumb5: Breadcrumb = {
- timestamp: BASE_TIMESTAMP / 1000 + 2.9,
- data: {
- nodeId: 1,
- },
- };
- const node = document.createElement('button');
- detector.handleClick(breadcrumb1, node);
-
- detector.handleClick(breadcrumb2, node);
-
- detector.handleClick(breadcrumb3, node);
-
- expect(mockAddBreadcrumbEvent).toHaveBeenCalledTimes(0);
-
- jest.advanceTimersByTime(2_000);
-
- expect(mockAddBreadcrumbEvent).toHaveBeenCalledTimes(0);
-
- detector.handleClick(breadcrumb4, node);
- detector.handleClick(breadcrumb5, node);
-
- jest.advanceTimersByTime(1_000);
-
- expect(mockAddBreadcrumbEvent).toHaveBeenCalledTimes(1);
- expect(mockAddBreadcrumbEvent).toHaveBeenCalledWith(replay, {
- category: 'ui.slowClickDetected',
- type: 'default',
- data: {
- // count is not actually correct, because this is identified by a different click handler
- clickCount: 1,
- endReason: 'timeout',
- nodeId: 1,
- route: 'test-route',
- timeAfterClickMs: 3000,
- url: 'http://localhost/',
- },
- message: undefined,
- timestamp: expect.any(Number),
- });
-
- jest.advanceTimersByTime(2_000);
-
- expect(mockAddBreadcrumbEvent).toHaveBeenCalledTimes(2);
- expect(mockAddBreadcrumbEvent).toHaveBeenCalledWith(replay, {
- category: 'ui.slowClickDetected',
- type: 'default',
- data: {
- // count is not actually correct, because this is identified by a different click handler
- clickCount: 1,
- endReason: 'timeout',
- nodeId: 1,
- route: 'test-route',
- timeAfterClickMs: 3000,
- url: 'http://localhost/',
- },
- message: undefined,
- timestamp: expect.any(Number),
- });
-
- jest.advanceTimersByTime(5_000);
- expect(mockAddBreadcrumbEvent).toHaveBeenCalledTimes(2);
- });
-
test('it captures clicks on different elements', async () => {
const replay = {
getCurrentRoute: () => 'test-route',
@@ -193,7 +85,6 @@ describe('Unit | coreHandlers | handleClick', () => {
timeout: 3_000,
scrollTimeout: 200,
ignoreSelector: '',
- multiClickTimeout: 1_000,
},
mockAddBreadcrumbEvent,
);
@@ -247,7 +138,6 @@ describe('Unit | coreHandlers | handleClick', () => {
timeout: 3_000,
scrollTimeout: 200,
ignoreSelector: '',
- multiClickTimeout: 1_000,
},
mockAddBreadcrumbEvent,
);
@@ -304,7 +194,6 @@ describe('Unit | coreHandlers | handleClick', () => {
timeout: 3_000,
scrollTimeout: 200,
ignoreSelector: '',
- multiClickTimeout: 1_000,
},
mockAddBreadcrumbEvent,
);
@@ -437,7 +326,6 @@ describe('Unit | coreHandlers | handleClick', () => {
timeout: 3_000,
scrollTimeout: 200,
ignoreSelector: '',
- multiClickTimeout: 1_000,
},
mockAddBreadcrumbEvent,
);
diff --git a/packages/replay/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts b/packages/replay/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts
index 825c6e4eb452..c0ad9ef59b49 100644
--- a/packages/replay/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts
+++ b/packages/replay/test/unit/coreHandlers/handleNetworkBreadcrumbs.test.ts
@@ -63,6 +63,7 @@ describe('Unit | coreHandlers | handleNetworkBreadcrumbs', () => {
textEncoder: new TextEncoder(),
replay: setupReplayContainer(),
networkDetailAllowUrls: ['https://example.com'],
+ networkDetailDenyUrls: ['http://localhost:8080'],
networkCaptureBodies: false,
networkRequestHeaders: ['content-type', 'accept', 'x-custom-header'],
networkResponseHeaders: ['content-type', 'accept', 'x-custom-header'],
@@ -1382,5 +1383,166 @@ other-header: test`;
]);
});
});
+
+ describe.each([
+ ['exact string match', 'https://example.com/foo'],
+ ['partial string match', 'https://example.com/bar/what'],
+ ['exact regex match', 'http://example.com/exact'],
+ ['partial regex match', 'http://example.com/partial/string'],
+ ])('matching URL %s', (_label, url) => {
+ it('correctly deny URL for fetch request', async () => {
+ options.networkDetailDenyUrls = [
+ 'https://example.com/foo',
+ 'com/bar',
+ /^http:\/\/example.com\/exact$/,
+ /^http:\/\/example.com\/partial/,
+ ];
+
+ const breadcrumb: Breadcrumb = {
+ category: 'fetch',
+ data: {
+ method: 'GET',
+ url,
+ status_code: 200,
+ },
+ };
+
+ const mockResponse = getMockResponse('13', 'test response');
+
+ const hint: FetchBreadcrumbHint = {
+ input: ['GET', { body: 'test input' }],
+ response: mockResponse,
+ startTimestamp: BASE_TIMESTAMP + 1000,
+ endTimestamp: BASE_TIMESTAMP + 2000,
+ };
+ beforeAddNetworkBreadcrumb(options, breadcrumb, hint);
+
+ expect(breadcrumb).toEqual({
+ category: 'fetch',
+ data: {
+ method: 'GET',
+ request_body_size: 10,
+ response_body_size: 13,
+ status_code: 200,
+ url,
+ },
+ });
+
+ await waitForReplayEventBuffer();
+
+ expect((options.replay.eventBuffer as EventBufferArray).events).toEqual([
+ {
+ data: {
+ payload: {
+ data: {
+ method: 'GET',
+ request: {
+ _meta: {
+ warnings: ['URL_SKIPPED'],
+ },
+ headers: {},
+ size: 10,
+ },
+ response: {
+ _meta: {
+ warnings: ['URL_SKIPPED'],
+ },
+ headers: {},
+ size: 13,
+ },
+ statusCode: 200,
+ },
+ description: url,
+ endTimestamp: (BASE_TIMESTAMP + 2000) / 1000,
+ op: 'resource.fetch',
+ startTimestamp: (BASE_TIMESTAMP + 1000) / 1000,
+ },
+ tag: 'performanceSpan',
+ },
+ timestamp: (BASE_TIMESTAMP + 1000) / 1000,
+ type: 5,
+ },
+ ]);
+ });
+
+ it('correctly deny URL for xhr request', async () => {
+ options.networkDetailDenyUrls = [
+ 'https://example.com/foo',
+ 'com/bar',
+ /^http:\/\/example.com\/exact$/,
+ /^http:\/\/example.com\/partial/,
+ ];
+
+ const breadcrumb: Breadcrumb = {
+ category: 'xhr',
+ data: {
+ method: 'GET',
+ url,
+ status_code: 200,
+ },
+ };
+ const xhr = new XMLHttpRequest();
+ Object.defineProperty(xhr, 'response', {
+ value: 'test response',
+ });
+ Object.defineProperty(xhr, 'responseText', {
+ value: 'test response',
+ });
+ const hint: XhrBreadcrumbHint = {
+ xhr,
+ input: 'test input',
+ startTimestamp: BASE_TIMESTAMP + 1000,
+ endTimestamp: BASE_TIMESTAMP + 2000,
+ };
+ beforeAddNetworkBreadcrumb(options, breadcrumb, hint);
+
+ expect(breadcrumb).toEqual({
+ category: 'xhr',
+ data: {
+ method: 'GET',
+ request_body_size: 10,
+ response_body_size: 13,
+ status_code: 200,
+ url,
+ },
+ });
+
+ await waitForReplayEventBuffer();
+
+ expect((options.replay.eventBuffer as EventBufferArray).events).toEqual([
+ {
+ data: {
+ payload: {
+ data: {
+ method: 'GET',
+ request: {
+ _meta: {
+ warnings: ['URL_SKIPPED'],
+ },
+ headers: {},
+ size: 10,
+ },
+ response: {
+ _meta: {
+ warnings: ['URL_SKIPPED'],
+ },
+ headers: {},
+ size: 13,
+ },
+ statusCode: 200,
+ },
+ description: url,
+ endTimestamp: (BASE_TIMESTAMP + 2000) / 1000,
+ op: 'resource.xhr',
+ startTimestamp: (BASE_TIMESTAMP + 1000) / 1000,
+ },
+ tag: 'performanceSpan',
+ },
+ timestamp: (BASE_TIMESTAMP + 1000) / 1000,
+ type: 5,
+ },
+ ]);
+ });
+ });
});
});
diff --git a/packages/replay/test/unit/util/prepareReplayEvent.test.ts b/packages/replay/test/unit/util/prepareReplayEvent.test.ts
index b0f121e1256a..5ada534f65a0 100644
--- a/packages/replay/test/unit/util/prepareReplayEvent.test.ts
+++ b/packages/replay/test/unit/util/prepareReplayEvent.test.ts
@@ -82,7 +82,7 @@ describe('Unit | util | prepareReplayEvent', () => {
name: 'sentry.javascript.testSdk',
version: '1.0.0',
},
- sdkProcessingMetadata: {},
+ sdkProcessingMetadata: expect.any(Object),
breadcrumbs: undefined,
});
});
diff --git a/packages/replay/test/utils/setupReplayContainer.ts b/packages/replay/test/utils/setupReplayContainer.ts
index 0237afddb538..e2a49052a799 100644
--- a/packages/replay/test/utils/setupReplayContainer.ts
+++ b/packages/replay/test/utils/setupReplayContainer.ts
@@ -12,6 +12,7 @@ const DEFAULT_OPTIONS = {
useCompression: false,
blockAllMedia: true,
networkDetailAllowUrls: [],
+ networkDetailDenyUrls: [],
networkCaptureBodies: true,
networkRequestHeaders: [],
networkResponseHeaders: [],
diff --git a/packages/serverless/src/awslambda.ts b/packages/serverless/src/awslambda.ts
index 888b57852327..b5cf41af5e90 100644
--- a/packages/serverless/src/awslambda.ts
+++ b/packages/serverless/src/awslambda.ts
@@ -3,7 +3,7 @@ import type { Scope } from '@sentry/node';
import * as Sentry from '@sentry/node';
import { captureException, captureMessage, flush, getCurrentHub, withScope } from '@sentry/node';
import type { Integration } from '@sentry/types';
-import { baggageHeaderToDynamicSamplingContext, extractTraceparentData, isString, logger } from '@sentry/utils';
+import { isString, logger, tracingContextFromHeaders } from '@sentry/utils';
// NOTE: I have no idea how to fix this right now, and don't want to waste more time, as it builds just fine — Kamil
// eslint-disable-next-line import/no-unresolved
import type { Context, Handler } from 'aws-lambda';
@@ -274,17 +274,20 @@ export function wrapHandler(
}, timeoutWarningDelay) as unknown as NodeJS.Timeout;
}
- // Applying `sentry-trace` to context
- let traceparentData;
- const eventWithHeaders = event as { headers?: { [key: string]: string } };
- if (eventWithHeaders.headers && isString(eventWithHeaders.headers['sentry-trace'])) {
- traceparentData = extractTraceparentData(eventWithHeaders.headers['sentry-trace']);
- }
+ const hub = getCurrentHub();
- const baggageHeader = eventWithHeaders.headers && eventWithHeaders.headers.baggage;
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggageHeader);
+ const eventWithHeaders = event as { headers?: { [key: string]: string } };
- const hub = getCurrentHub();
+ const sentryTrace =
+ eventWithHeaders.headers && isString(eventWithHeaders.headers['sentry-trace'])
+ ? eventWithHeaders.headers['sentry-trace']
+ : undefined;
+ const baggage = eventWithHeaders.headers?.baggage;
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
+ hub.getScope().setPropagationContext(propagationContext);
const transaction = hub.startTransaction({
name: context.functionName,
diff --git a/packages/serverless/src/gcpfunction/http.ts b/packages/serverless/src/gcpfunction/http.ts
index 9bc9052d179d..d3b24f5ba743 100644
--- a/packages/serverless/src/gcpfunction/http.ts
+++ b/packages/serverless/src/gcpfunction/http.ts
@@ -1,13 +1,6 @@
import type { AddRequestDataToEventOptions } from '@sentry/node';
import { captureException, flush, getCurrentHub } from '@sentry/node';
-import {
- baggageHeaderToDynamicSamplingContext,
- extractTraceparentData,
- isString,
- isThenable,
- logger,
- stripUrlQueryAndFragment,
-} from '@sentry/utils';
+import { isString, isThenable, logger, stripUrlQueryAndFragment, tracingContextFromHeaders } from '@sentry/utils';
import { domainify, proxyFunction } from './../utils';
import type { HttpFunction, WrapperOptions } from './general';
@@ -68,21 +61,18 @@ function _wrapHttpFunction(fn: HttpFunction, wrapOptions: Partial {
+ const hub = getCurrentHub();
+
const reqMethod = (req.method || '').toUpperCase();
const reqUrl = stripUrlQueryAndFragment(req.originalUrl || req.url || '');
- // Applying `sentry-trace` to context
- let traceparentData;
- const reqWithHeaders = req as { headers?: { [key: string]: string } };
- if (reqWithHeaders.headers && isString(reqWithHeaders.headers['sentry-trace'])) {
- traceparentData = extractTraceparentData(reqWithHeaders.headers['sentry-trace']);
- }
-
- const baggageHeader = reqWithHeaders.headers?.baggage;
-
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggageHeader);
-
- const hub = getCurrentHub();
+ const sentryTrace = req.headers && isString(req.headers['sentry-trace']) ? req.headers['sentry-trace'] : undefined;
+ const baggage = req.headers?.baggage;
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
+ hub.getScope().setPropagationContext(propagationContext);
const transaction = hub.startTransaction({
name: `${reqMethod} ${reqUrl}`,
diff --git a/packages/serverless/test/__mocks__/@sentry/node.ts b/packages/serverless/test/__mocks__/@sentry/node.ts
index 355065317ea7..6da20c091780 100644
--- a/packages/serverless/test/__mocks__/@sentry/node.ts
+++ b/packages/serverless/test/__mocks__/@sentry/node.ts
@@ -22,6 +22,7 @@ export const fakeScope = {
setSpan: jest.fn(),
getTransaction: jest.fn(() => fakeTransaction),
setSDKProcessingMetadata: jest.fn(),
+ setPropagationContext: jest.fn(),
};
export const fakeSpan = {
finish: jest.fn(),
diff --git a/packages/sveltekit/src/client/load.ts b/packages/sveltekit/src/client/load.ts
index e56d33b2e23c..8907994e8649 100644
--- a/packages/sveltekit/src/client/load.ts
+++ b/packages/sveltekit/src/client/load.ts
@@ -129,6 +129,8 @@ function instrumentSvelteKitFetch(originalFetch: SvelteKitFetch): SvelteKitFetch
return originalFetch;
}
+ const options = client.getOptions();
+
const browserTracingIntegration = client.getIntegrationById('BrowserTracing') as BrowserTracing | undefined;
const breadcrumbsIntegration = client.getIntegrationById('Breadcrumbs') as Breadcrumbs | undefined;
@@ -147,7 +149,10 @@ function instrumentSvelteKitFetch(originalFetch: SvelteKitFetch): SvelteKitFetch
const shouldAttachHeaders: (url: string) => boolean = url => {
return (
!!shouldTraceFetch &&
- stringMatchesSomePattern(url, browserTracingOptions.tracePropagationTargets || ['localhost', /^\//])
+ stringMatchesSomePattern(
+ url,
+ options.tracePropagationTargets || browserTracingOptions.tracePropagationTargets || ['localhost', /^\//],
+ )
);
};
@@ -177,20 +182,15 @@ function instrumentSvelteKitFetch(originalFetch: SvelteKitFetch): SvelteKitFetch
};
const patchedInit: RequestInit = { ...init };
- const activeSpan = getCurrentHub().getScope().getSpan();
- const activeTransaction = activeSpan && activeSpan.transaction;
-
- const createSpan = activeTransaction && shouldCreateSpan(rawUrl);
- const attachHeaders = createSpan && activeTransaction && shouldAttachHeaders(rawUrl);
-
- // only attach headers if we should create a span
- if (attachHeaders) {
- const dsc = activeTransaction.getDynamicSamplingContext();
+ const hub = getCurrentHub();
+ const scope = hub.getScope();
+ const client = hub.getClient();
+ if (client && shouldAttachHeaders(rawUrl)) {
const headers = addTracingHeadersToFetchRequest(
input as string | Request,
- dsc,
- activeSpan,
+ client,
+ scope,
patchedInit as {
headers:
| {
@@ -207,7 +207,7 @@ function instrumentSvelteKitFetch(originalFetch: SvelteKitFetch): SvelteKitFetch
const patchedFetchArgs = [input, patchedInit];
- if (createSpan) {
+ if (shouldCreateSpan(rawUrl)) {
fetchPromise = trace(
{
name: `${method} ${requestData.url}`, // this will become the description of the span
diff --git a/packages/sveltekit/src/server/handle.ts b/packages/sveltekit/src/server/handle.ts
index 6d41317cc044..5c90f42f4c9e 100644
--- a/packages/sveltekit/src/server/handle.ts
+++ b/packages/sveltekit/src/server/handle.ts
@@ -112,7 +112,8 @@ function instrumentHandle({ event, resolve }: Parameters[0], options: Se
return resolve(event);
}
- const { traceparentData, dynamicSamplingContext } = getTracePropagationData(event);
+ const { dynamicSamplingContext, traceparentData, propagationContext } = getTracePropagationData(event);
+ getCurrentHub().getScope().setPropagationContext(propagationContext);
return trace(
{
diff --git a/packages/sveltekit/src/server/load.ts b/packages/sveltekit/src/server/load.ts
index c776dc639d3a..0ad28e1cb4eb 100644
--- a/packages/sveltekit/src/server/load.ts
+++ b/packages/sveltekit/src/server/load.ts
@@ -1,5 +1,5 @@
/* eslint-disable @sentry-internal/sdk/no-optional-chaining */
-import { trace } from '@sentry/core';
+import { getCurrentHub, trace } from '@sentry/core';
import { captureException } from '@sentry/node';
import type { TransactionContext } from '@sentry/types';
import { addExceptionMechanism, addNonEnumerableProperty, objectify } from '@sentry/utils';
@@ -121,7 +121,8 @@ export function wrapServerLoadWithSentry any>(origSe
const routeId = event.route && event.route.id;
- const { dynamicSamplingContext, traceparentData } = getTracePropagationData(event);
+ const { dynamicSamplingContext, traceparentData, propagationContext } = getTracePropagationData(event);
+ getCurrentHub().getScope().setPropagationContext(propagationContext);
const traceLoadContext: TransactionContext = {
op: 'function.sveltekit.server.load',
diff --git a/packages/sveltekit/src/server/utils.ts b/packages/sveltekit/src/server/utils.ts
index 8ef6acced314..1a9e1781643c 100644
--- a/packages/sveltekit/src/server/utils.ts
+++ b/packages/sveltekit/src/server/utils.ts
@@ -1,12 +1,5 @@
-import type { DynamicSamplingContext, StackFrame, TraceparentData } from '@sentry/types';
-import {
- baggageHeaderToDynamicSamplingContext,
- basename,
- escapeStringForRegex,
- extractTraceparentData,
- GLOBAL_OBJ,
- join,
-} from '@sentry/utils';
+import type { StackFrame } from '@sentry/types';
+import { basename, escapeStringForRegex, GLOBAL_OBJ, join, tracingContextFromHeaders } from '@sentry/utils';
import type { RequestEvent } from '@sveltejs/kit';
import { WRAPPED_MODULE_SUFFIX } from '../vite/autoInstrument';
@@ -15,17 +8,13 @@ import type { GlobalWithSentryValues } from '../vite/injectGlobalValues';
/**
* Takes a request event and extracts traceparent and DSC data
* from the `sentry-trace` and `baggage` DSC headers.
+ *
+ * Sets propagation context as a side effect.
*/
-export function getTracePropagationData(event: RequestEvent): {
- traceparentData?: TraceparentData;
- dynamicSamplingContext?: Partial;
-} {
- const sentryTraceHeader = event.request.headers.get('sentry-trace');
+export function getTracePropagationData(event: RequestEvent): ReturnType {
+ const sentryTraceHeader = event.request.headers.get('sentry-trace') || '';
const baggageHeader = event.request.headers.get('baggage');
- const traceparentData = sentryTraceHeader ? extractTraceparentData(sentryTraceHeader) : undefined;
- const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggageHeader);
-
- return { traceparentData, dynamicSamplingContext };
+ return tracingContextFromHeaders(sentryTraceHeader, baggageHeader);
}
/**
diff --git a/packages/sveltekit/test/client/load.test.ts b/packages/sveltekit/test/client/load.test.ts
index 07608bb9845a..6373ea1ff571 100644
--- a/packages/sveltekit/test/client/load.test.ts
+++ b/packages/sveltekit/test/client/load.test.ts
@@ -61,6 +61,7 @@ const mockedGetIntegrationById = vi.fn(id => {
const mockedGetClient = vi.fn(() => {
return {
getIntegrationById: mockedGetIntegrationById,
+ getOptions: () => ({}),
};
});
@@ -77,6 +78,11 @@ vi.mock('@sentry/core', async () => {
getClient: mockedGetClient,
getScope: () => {
return {
+ getPropagationContext: () => ({
+ traceId: '1234567890abcdef1234567890abcdef',
+ spanId: '1234567890abcdef',
+ sampled: false,
+ }),
getSpan: () => {
return {
transaction: {
@@ -371,7 +377,7 @@ describe('wrapLoadWithSentry', () => {
mockedBrowserTracing.options.traceFetch = true;
});
- it("doesn't create a span nor propagate headers, if `shouldCreateSpanForRequest` returns false", async () => {
+ it("doesn't create a span if `shouldCreateSpanForRequest` returns false", async () => {
mockedBrowserTracing.options.shouldCreateSpanForRequest = () => false;
const wrappedLoad = wrapLoadWithSentry(load);
@@ -391,10 +397,6 @@ describe('wrapLoadWithSentry', () => {
expect.any(Function),
);
- expect(mockedSveltekitFetch).toHaveBeenCalledWith(
- ...[originalFetchArgs[0], originalFetchArgs.length === 2 ? originalFetchArgs[1] : {}],
- );
-
mockedBrowserTracing.options.shouldCreateSpanForRequest = () => true;
});
diff --git a/packages/tracing-internal/src/browser/browsertracing.ts b/packages/tracing-internal/src/browser/browsertracing.ts
index 4d1b1bca7c97..4be633821a1a 100644
--- a/packages/tracing-internal/src/browser/browsertracing.ts
+++ b/packages/tracing-internal/src/browser/browsertracing.ts
@@ -1,14 +1,8 @@
/* eslint-disable max-lines */
import type { Hub, IdleTransaction } from '@sentry/core';
-import {
- addTracingExtensions,
- extractTraceparentData,
- getActiveTransaction,
- startIdleTransaction,
- TRACING_DEFAULTS,
-} from '@sentry/core';
+import { addTracingExtensions, getActiveTransaction, startIdleTransaction, TRACING_DEFAULTS } from '@sentry/core';
import type { EventProcessor, Integration, Transaction, TransactionContext, TransactionSource } from '@sentry/types';
-import { baggageHeaderToDynamicSamplingContext, getDomElement, logger } from '@sentry/utils';
+import { getDomElement, logger, tracingContextFromHeaders } from '@sentry/utils';
import { registerBackgroundTabDetection } from './backgroundtab';
import {
@@ -297,24 +291,25 @@ export class BrowserTracing implements Integration {
return undefined;
}
+ const hub = this._getCurrentHub();
+
const { beforeNavigate, idleTimeout, finalTimeout, heartbeatInterval } = this.options;
const isPageloadTransaction = context.op === 'pageload';
- const sentryTraceMetaTagValue = isPageloadTransaction ? getMetaContent('sentry-trace') : null;
- const baggageMetaTagValue = isPageloadTransaction ? getMetaContent('baggage') : null;
-
- const traceParentData = sentryTraceMetaTagValue ? extractTraceparentData(sentryTraceMetaTagValue) : undefined;
- const dynamicSamplingContext = baggageMetaTagValue
- ? baggageHeaderToDynamicSamplingContext(baggageMetaTagValue)
- : undefined;
+ const sentryTrace = isPageloadTransaction ? getMetaContent('sentry-trace') : '';
+ const baggage = isPageloadTransaction ? getMetaContent('baggage') : '';
+ const { traceparentData, dynamicSamplingContext, propagationContext } = tracingContextFromHeaders(
+ sentryTrace,
+ baggage,
+ );
const expandedContext: TransactionContext = {
...context,
- ...traceParentData,
+ ...traceparentData,
metadata: {
...context.metadata,
- dynamicSamplingContext: traceParentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
+ dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
},
trimEnd: true,
};
@@ -341,7 +336,6 @@ export class BrowserTracing implements Integration {
__DEBUG_BUILD__ && logger.log(`[Tracing] Starting ${finalContext.op} transaction on scope`);
- const hub = this._getCurrentHub();
const { location } = WINDOW;
const idleTransaction = startIdleTransaction(
@@ -353,6 +347,24 @@ export class BrowserTracing implements Integration {
{ location }, // for use in the tracesSampler
heartbeatInterval,
);
+
+ const scope = hub.getScope();
+
+ // If it's a pageload and there is a meta tag set
+ // use the traceparentData as the propagation context
+ if (isPageloadTransaction && traceparentData) {
+ scope.setPropagationContext(propagationContext);
+ } else {
+ // Navigation transactions should set a new propagation context based on the
+ // created idle transaction.
+ scope.setPropagationContext({
+ traceId: idleTransaction.traceId,
+ spanId: idleTransaction.spanId,
+ parentSpanId: idleTransaction.parentSpanId,
+ sampled: !!idleTransaction.sampled,
+ });
+ }
+
idleTransaction.registerBeforeFinishCallback(transaction => {
this._collectWebVitals();
addPerformanceEntries(transaction);
@@ -424,11 +436,11 @@ export class BrowserTracing implements Integration {
}
/** Returns the value of a meta tag */
-export function getMetaContent(metaName: string): string | null {
+export function getMetaContent(metaName: string): string | undefined {
// Can't specify generic to `getDomElement` because tracing can be used
// in a variety of environments, have to disable `no-unsafe-member-access`
// as a result.
const metaTag = getDomElement(`meta[name=${metaName}]`);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
- return metaTag ? metaTag.getAttribute('content') : null;
+ return metaTag ? metaTag.getAttribute('content') : undefined;
}
diff --git a/packages/tracing-internal/src/browser/request.ts b/packages/tracing-internal/src/browser/request.ts
index d7e397ae01ac..071b2146bb16 100644
--- a/packages/tracing-internal/src/browser/request.ts
+++ b/packages/tracing-internal/src/browser/request.ts
@@ -1,11 +1,12 @@
/* eslint-disable max-lines */
-import { getCurrentHub, hasTracingEnabled } from '@sentry/core';
-import type { DynamicSamplingContext, Span } from '@sentry/types';
+import { getCurrentHub, getDynamicSamplingContextFromClient, hasTracingEnabled } from '@sentry/core';
+import type { Client, Scope, Span } from '@sentry/types';
import {
addInstrumentationHandler,
BAGGAGE_HEADER_NAME,
browserPerformanceTimeOrigin,
dynamicSamplingContextToSentryBaggageHeader,
+ generateSentryTraceHeader,
isInstanceOf,
SENTRY_XHR_DATA_KEY,
stringMatchesSomePattern,
@@ -214,17 +215,19 @@ export function shouldAttachHeaders(url: string, tracePropagationTargets: (strin
*
* @returns Span if a span was created, otherwise void.
*/
-function fetchCallback(
+export function fetchCallback(
handlerData: FetchData,
shouldCreateSpan: (url: string) => boolean,
shouldAttachHeaders: (url: string) => boolean,
spans: Record,
-): Span | void {
- if (!hasTracingEnabled() || !(handlerData.fetchData && shouldCreateSpan(handlerData.fetchData.url))) {
- return;
+): Span | undefined {
+ if (!hasTracingEnabled() || !handlerData.fetchData) {
+ return undefined;
}
- if (handlerData.endTimestamp) {
+ const shouldCreateSpanResult = shouldCreateSpan(handlerData.fetchData.url);
+
+ if (handlerData.endTimestamp && shouldCreateSpanResult) {
const spanId = handlerData.fetchData.__span;
if (!spanId) return;
@@ -251,27 +254,35 @@ function fetchCallback(
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete spans[spanId];
}
- return;
+ return undefined;
}
- const currentSpan = getCurrentHub().getScope().getSpan();
- const activeTransaction = currentSpan && currentSpan.transaction;
-
- if (currentSpan && activeTransaction) {
- const { method, url } = handlerData.fetchData;
- const span = currentSpan.startChild({
- data: {
- url,
- type: 'fetch',
- 'http.method': method,
- },
- description: `${method} ${url}`,
- op: 'http.client',
- });
-
+ const hub = getCurrentHub();
+ const scope = hub.getScope();
+ const client = hub.getClient();
+ const parentSpan = scope.getSpan();
+
+ const { method, url } = handlerData.fetchData;
+
+ const span =
+ shouldCreateSpanResult && parentSpan
+ ? parentSpan.startChild({
+ data: {
+ url,
+ type: 'fetch',
+ 'http.method': method,
+ },
+ description: `${method} ${url}`,
+ op: 'http.client',
+ })
+ : undefined;
+
+ if (span) {
handlerData.fetchData.__span = span.spanId;
spans[span.spanId] = span;
+ }
+ if (shouldAttachHeaders(handlerData.fetchData.url) && client) {
const request: string | Request = handlerData.args[0];
// In case the user hasn't set the second argument of a fetch call we default it to `{}`.
@@ -280,16 +291,11 @@ function fetchCallback(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const options: { [key: string]: any } = handlerData.args[1];
- if (shouldAttachHeaders(handlerData.fetchData.url)) {
- options.headers = addTracingHeadersToFetchRequest(
- request,
- activeTransaction.getDynamicSamplingContext(),
- span,
- options,
- );
- }
- return span;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
+ options.headers = addTracingHeadersToFetchRequest(request, client, scope, options);
}
+
+ return span;
}
/**
@@ -297,8 +303,8 @@ function fetchCallback(
*/
export function addTracingHeadersToFetchRequest(
request: string | unknown, // unknown is actually type Request but we can't export DOM types from this package,
- dynamicSamplingContext: Partial,
- span: Span,
+ client: Client,
+ scope: Scope,
options: {
headers?:
| {
@@ -306,9 +312,21 @@ export function addTracingHeadersToFetchRequest(
}
| PolymorphicRequestHeaders;
},
-): PolymorphicRequestHeaders {
+): PolymorphicRequestHeaders | undefined {
+ const span = scope.getSpan();
+
+ const transaction = span && span.transaction;
+
+ const { traceId, sampled, dsc } = scope.getPropagationContext();
+
+ const sentryTraceHeader = span ? span.toTraceparent() : generateSentryTraceHeader(traceId, undefined, sampled);
+ const dynamicSamplingContext = transaction
+ ? transaction.getDynamicSamplingContext()
+ : dsc
+ ? dsc
+ : getDynamicSamplingContextFromClient(traceId, client, scope);
+
const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
- const sentryTraceHeader = span.toTraceparent();
const headers =
typeof Request !== 'undefined' && isInstanceOf(request, Request) ? (request as Request).headers : options.headers;
@@ -364,25 +382,24 @@ export function addTracingHeadersToFetchRequest(
*
* @returns Span if a span was created, otherwise void.
*/
-function xhrCallback(
+// eslint-disable-next-line complexity
+export function xhrCallback(
handlerData: XHRData,
shouldCreateSpan: (url: string) => boolean,
shouldAttachHeaders: (url: string) => boolean,
spans: Record,
-): Span | void {
+): Span | undefined {
const xhr = handlerData.xhr;
const sentryXhrData = xhr && xhr[SENTRY_XHR_DATA_KEY];
- if (
- !hasTracingEnabled() ||
- (xhr && xhr.__sentry_own_request__) ||
- !(xhr && sentryXhrData && shouldCreateSpan(sentryXhrData.url))
- ) {
- return;
+ if (!hasTracingEnabled() || (xhr && xhr.__sentry_own_request__) || !xhr || !sentryXhrData) {
+ return undefined;
}
+ const shouldCreateSpanResult = shouldCreateSpan(sentryXhrData.url);
+
// check first if the request has finished and is tracked by an existing span which should now end
- if (handlerData.endTimestamp) {
+ if (handlerData.endTimestamp && shouldCreateSpanResult) {
const spanId = xhr.__sentry_xhr_span_id__;
if (!spanId) return;
@@ -394,45 +411,68 @@ function xhrCallback(
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete spans[spanId];
}
- return;
+ return undefined;
}
- const currentSpan = getCurrentHub().getScope().getSpan();
- const activeTransaction = currentSpan && currentSpan.transaction;
-
- if (currentSpan && activeTransaction) {
- const span = currentSpan.startChild({
- data: {
- ...sentryXhrData.data,
- type: 'xhr',
- 'http.method': sentryXhrData.method,
- url: sentryXhrData.url,
- },
- description: `${sentryXhrData.method} ${sentryXhrData.url}`,
- op: 'http.client',
- });
-
+ const hub = getCurrentHub();
+ const scope = hub.getScope();
+ const parentSpan = scope.getSpan();
+
+ const span =
+ shouldCreateSpanResult && parentSpan
+ ? parentSpan.startChild({
+ data: {
+ ...sentryXhrData.data,
+ type: 'xhr',
+ 'http.method': sentryXhrData.method,
+ url: sentryXhrData.url,
+ },
+ description: `${sentryXhrData.method} ${sentryXhrData.url}`,
+ op: 'http.client',
+ })
+ : undefined;
+
+ if (span) {
xhr.__sentry_xhr_span_id__ = span.spanId;
spans[xhr.__sentry_xhr_span_id__] = span;
+ }
- if (xhr.setRequestHeader && shouldAttachHeaders(sentryXhrData.url)) {
- try {
- xhr.setRequestHeader('sentry-trace', span.toTraceparent());
+ if (xhr.setRequestHeader && shouldAttachHeaders(sentryXhrData.url)) {
+ if (span) {
+ const transaction = span && span.transaction;
+ const dynamicSamplingContext = transaction && transaction.getDynamicSamplingContext();
+ const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
+ setHeaderOnXhr(xhr, span.toTraceparent(), sentryBaggageHeader);
+ } else {
+ const client = hub.getClient();
+ const { traceId, sampled, dsc } = scope.getPropagationContext();
+ const sentryTraceHeader = generateSentryTraceHeader(traceId, undefined, sampled);
+ const dynamicSamplingContext =
+ dsc || (client ? getDynamicSamplingContextFromClient(traceId, client, scope) : undefined);
+ const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
+ setHeaderOnXhr(xhr, sentryTraceHeader, sentryBaggageHeader);
+ }
+ }
- const dynamicSamplingContext = activeTransaction.getDynamicSamplingContext();
- const sentryBaggageHeader = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
+ return span;
+}
- if (sentryBaggageHeader) {
- // From MDN: "If this method is called several times with the same header, the values are merged into one single request header."
- // We can therefore simply set a baggage header without checking what was there before
- // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader
- xhr.setRequestHeader(BAGGAGE_HEADER_NAME, sentryBaggageHeader);
- }
- } catch (_) {
- // Error: InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
- }
+function setHeaderOnXhr(
+ xhr: NonNullable,
+ sentryTraceHeader: string,
+ sentryBaggageHeader: string | undefined,
+): void {
+ try {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ xhr.setRequestHeader!('sentry-trace', sentryTraceHeader);
+ if (sentryBaggageHeader) {
+ // From MDN: "If this method is called several times with the same header, the values are merged into one single request header."
+ // We can therefore simply set a baggage header without checking what was there before
+ // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ xhr.setRequestHeader!(BAGGAGE_HEADER_NAME, sentryBaggageHeader);
}
-
- return span;
+ } catch (_) {
+ // Error: InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
}
}
diff --git a/packages/tracing-internal/test/browser/backgroundtab.test.ts b/packages/tracing-internal/test/browser/backgroundtab.test.ts
index 436d63aab36c..5ce370e6690f 100644
--- a/packages/tracing-internal/test/browser/backgroundtab.test.ts
+++ b/packages/tracing-internal/test/browser/backgroundtab.test.ts
@@ -2,11 +2,11 @@ import { Hub, makeMain } from '@sentry/core';
import { JSDOM } from 'jsdom';
import { addExtensionMethods } from '../../../tracing/src';
-import { getDefaultBrowserClientOptions } from '../../../tracing/test/testutils';
+import { conditionalTest, getDefaultBrowserClientOptions } from '../../../tracing/test/testutils';
import { registerBackgroundTabDetection } from '../../src/browser/backgroundtab';
import { TestClient } from '../utils/TestClient';
-describe('registerBackgroundTabDetection', () => {
+conditionalTest({ min: 10 })('registerBackgroundTabDetection', () => {
let events: Record = {};
let hub: Hub;
beforeEach(() => {
diff --git a/packages/tracing-internal/test/browser/browsertracing.test.ts b/packages/tracing-internal/test/browser/browsertracing.test.ts
index c7cec8a54735..0754afd65fc8 100644
--- a/packages/tracing-internal/test/browser/browsertracing.test.ts
+++ b/packages/tracing-internal/test/browser/browsertracing.test.ts
@@ -7,7 +7,7 @@ import { JSDOM } from 'jsdom';
import type { IdleTransaction } from '../../../tracing/src';
import { getActiveTransaction } from '../../../tracing/src';
-import { getDefaultBrowserClientOptions } from '../../../tracing/test/testutils';
+import { conditionalTest, getDefaultBrowserClientOptions } from '../../../tracing/test/testutils';
import type { BrowserTracingOptions } from '../../src/browser/browsertracing';
import { BrowserTracing, getMetaContent } from '../../src/browser/browsertracing';
import { defaultRequestInstrumentationOptions } from '../../src/browser/request';
@@ -58,7 +58,7 @@ beforeAll(() => {
WINDOW.location = dom.window.location;
});
-describe('BrowserTracing', () => {
+conditionalTest({ min: 10 })('BrowserTracing', () => {
let hub: Hub;
beforeEach(() => {
jest.useFakeTimers();
@@ -94,7 +94,6 @@ describe('BrowserTracing', () => {
const browserTracing = createBrowserTracing();
expect(browserTracing.options).toEqual({
- _experiments: {},
enableLongTask: true,
...TRACING_DEFAULTS,
markBackgroundTransactions: true,
@@ -113,9 +112,6 @@ describe('BrowserTracing', () => {
});
expect(browserTracing.options).toEqual({
- _experiments: {
- enableLongTask: false,
- },
enableLongTask: false,
...TRACING_DEFAULTS,
markBackgroundTransactions: true,
@@ -123,6 +119,9 @@ describe('BrowserTracing', () => {
startTransactionOnLocationChange: true,
startTransactionOnPageLoad: true,
...defaultRequestInstrumentationOptions,
+ _experiments: {
+ enableLongTask: false,
+ },
});
});
@@ -132,7 +131,6 @@ describe('BrowserTracing', () => {
});
expect(browserTracing.options).toEqual({
- _experiments: {},
enableLongTask: false,
...TRACING_DEFAULTS,
markBackgroundTransactions: true,
@@ -248,6 +246,7 @@ describe('BrowserTracing', () => {
traceFetch: true,
traceXHR: true,
tracePropagationTargets: ['something'],
+ _experiments: {},
});
});
@@ -261,6 +260,7 @@ describe('BrowserTracing', () => {
});
expect(instrumentOutgoingRequestsMock).toHaveBeenCalledWith({
+ _experiments: {},
traceFetch: true,
traceXHR: true,
tracePropagationTargets: ['something-else'],
@@ -546,7 +546,7 @@ describe('BrowserTracing', () => {
document.head.innerHTML = '';
const metaTagValue = getMetaContent('dogpark');
- expect(metaTagValue).toBe(null);
+ expect(metaTagValue).toBe(undefined);
});
it('can pick the correct tag out of multiple options', () => {
@@ -636,6 +636,7 @@ describe('BrowserTracing', () => {
release: '1.0.0',
environment: 'production',
public_key: 'pubKey',
+ sampled: 'false',
trace_id: expect.not.stringMatching('12312012123120121231201212312012'),
});
});
diff --git a/packages/tracing-internal/test/browser/metrics/index.test.ts b/packages/tracing-internal/test/browser/metrics/index.test.ts
index d325815bde31..c196fbd2467c 100644
--- a/packages/tracing-internal/test/browser/metrics/index.test.ts
+++ b/packages/tracing-internal/test/browser/metrics/index.test.ts
@@ -14,6 +14,7 @@ describe('_addMeasureSpans', () => {
name: 'measure-1',
duration: 10,
startTime: 12,
+ detail: undefined,
};
const timeOrigin = 100;
diff --git a/packages/tracing-internal/test/browser/request.test.ts b/packages/tracing-internal/test/browser/request.test.ts
index ee714e111a8b..9c8307e97fd7 100644
--- a/packages/tracing-internal/test/browser/request.test.ts
+++ b/packages/tracing-internal/test/browser/request.test.ts
@@ -98,9 +98,7 @@ describe('callbacks', () => {
// each case is [shouldCreateSpanReturnValue, shouldAttachHeadersReturnValue, expectedSpan, expectedHeaderKeys]
[true, true, expect.objectContaining(fetchSpan), ['sentry-trace', 'baggage']],
[true, false, expect.objectContaining(fetchSpan), []],
- // If there's no span then there's no parent span id to stick into a header, so no headers, even if there's a
- // `tracingOrigins` match
- [false, true, undefined, []],
+ [false, true, undefined, ['sentry-trace', 'baggage']],
[false, false, undefined, []],
])(
'span creation/header attachment interaction - shouldCreateSpan: %s, shouldAttachHeaders: %s',
@@ -240,6 +238,7 @@ describe('callbacks', () => {
expect(finishedSpan.data).toEqual({
'http.response_content_length': 123,
'http.method': 'GET',
+ 'http.response.status_code': 404,
type: 'fetch',
url: 'http://dogs.are.great/',
});
@@ -283,9 +282,7 @@ describe('callbacks', () => {
// each case is [shouldCreateSpanReturnValue, shouldAttachHeadersReturnValue, expectedSpan, expectedHeaderKeys]
[true, true, expect.objectContaining(xhrSpan), ['sentry-trace', 'baggage']],
[true, false, expect.objectContaining(xhrSpan), []],
- // If there's no span then there's no parent span id to stick into a header, so no headers, even if there's a
- // `tracingOrigins` match
- [false, true, undefined, []],
+ [false, true, undefined, ['sentry-trace', 'baggage']],
[false, false, undefined, []],
])(
'span creation/header attachment interaction - shouldCreateSpan: %s, shouldAttachHeaders: %s',
diff --git a/packages/tracing-internal/test/browser/router.test.ts b/packages/tracing-internal/test/browser/router.test.ts
index 65ce7e90af48..8ad414a97b80 100644
--- a/packages/tracing-internal/test/browser/router.test.ts
+++ b/packages/tracing-internal/test/browser/router.test.ts
@@ -1,6 +1,7 @@
import type { InstrumentHandlerCallback, InstrumentHandlerType } from '@sentry/utils';
import { JSDOM } from 'jsdom';
+import { conditionalTest } from '../../../tracing/test/testutils';
import { instrumentRoutingWithDefaults } from '../../src/browser/router';
let mockChangeHistory: ({ to, from }: { to: string; from?: string }) => void = () => undefined;
@@ -16,7 +17,7 @@ jest.mock('@sentry/utils', () => {
};
});
-describe('instrumentRoutingWithDefaults', () => {
+conditionalTest({ min: 16 })('instrumentRoutingWithDefaults', () => {
const mockFinish = jest.fn();
const customStartTransaction = jest.fn().mockReturnValue({ finish: mockFinish });
beforeEach(() => {
@@ -46,6 +47,7 @@ describe('instrumentRoutingWithDefaults', () => {
name: 'blank',
op: 'pageload',
metadata: { source: 'url' },
+ startTimestamp: expect.any(Number),
});
});
diff --git a/packages/tracing/test/testutils.ts b/packages/tracing/test/testutils.ts
index 071ecdf5111a..484e3bf3cc35 100644
--- a/packages/tracing/test/testutils.ts
+++ b/packages/tracing/test/testutils.ts
@@ -1,6 +1,6 @@
import { createTransport } from '@sentry/browser';
import type { Client, ClientOptions } from '@sentry/types';
-import { GLOBAL_OBJ, resolvedSyncPromise } from '@sentry/utils';
+import { GLOBAL_OBJ, parseSemver, resolvedSyncPromise } from '@sentry/utils';
import { JSDOM } from 'jsdom';
/**
@@ -58,6 +58,23 @@ export const testOnlyIfNodeVersionAtLeast = (minVersion: number): jest.It => {
return it;
};
+/**
+ * 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.Describe => {
+ const NODE_VERSION = parseSemver(process.versions.node).major;
+ if (!NODE_VERSION) {
+ return describe.skip;
+ }
+
+ return NODE_VERSION < (allowedVersion.min || -Infinity) || NODE_VERSION > (allowedVersion.max || Infinity)
+ ? describe.skip
+ : describe;
+};
+
export function getDefaultBrowserClientOptions(options: Partial = {}): ClientOptions {
return {
integrations: [],
diff --git a/packages/tracing/test/utils.test.ts b/packages/tracing/test/utils.test.ts
index 00d90e873c9e..94374ac58b23 100644
--- a/packages/tracing/test/utils.test.ts
+++ b/packages/tracing/test/utils.test.ts
@@ -77,6 +77,9 @@ describe('extractTraceparentData', () => {
});
test('invalid', () => {
+ // undefined
+ expect(extractTraceparentData(undefined)).toBeUndefined();
+
// empty string
expect(extractTraceparentData('')).toBeUndefined();
diff --git a/packages/types/src/checkin.ts b/packages/types/src/checkin.ts
index a316c0c7a375..b19ff7b78770 100644
--- a/packages/types/src/checkin.ts
+++ b/packages/types/src/checkin.ts
@@ -1,3 +1,5 @@
+import type { TraceContext } from './context';
+
interface CrontabSchedule {
type: 'crontab';
// The crontab schedule string, e.g. 0 * * * *.
@@ -36,6 +38,9 @@ export interface SerializedCheckIn {
// See: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
timezone?: string;
};
+ contexts?: {
+ trace?: TraceContext;
+ };
}
interface InProgressCheckIn {
diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts
index 831b1c10e9f2..ac779fc3058e 100644
--- a/packages/types/src/client.ts
+++ b/packages/types/src/client.ts
@@ -74,9 +74,10 @@ export interface Client {
* @param checkIn An object that describes a check in.
* @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
* to create a monitor automatically when sending a check in.
+ * @param scope An optional scope containing event metadata.
* @returns A string representing the id of the check in.
*/
- captureCheckIn?(checkIn: CheckIn, monitorConfig?: MonitorConfig): string;
+ captureCheckIn?(checkIn: CheckIn, monitorConfig?: MonitorConfig, scope?: Scope): string;
/** Returns the current Dsn. */
getDsn(): DsnComponents | undefined;
diff --git a/packages/types/src/context.ts b/packages/types/src/context.ts
index bab969899cea..052d6f4a6523 100644
--- a/packages/types/src/context.ts
+++ b/packages/types/src/context.ts
@@ -8,6 +8,7 @@ export interface Contexts extends Record {
os?: OsContext;
culture?: CultureContext;
response?: ResponseContext;
+ trace?: TraceContext;
}
export interface AppContext extends Record {
diff --git a/packages/types/src/envelope.ts b/packages/types/src/envelope.ts
index 3f3ebf999ef9..288453fc4fdb 100644
--- a/packages/types/src/envelope.ts
+++ b/packages/types/src/envelope.ts
@@ -20,6 +20,7 @@ export type DynamicSamplingContext = {
transaction?: string;
user_segment?: string;
replay_id?: string;
+ sampled?: string;
};
export type EnvelopeItemType =
@@ -86,7 +87,7 @@ type ReplayRecordingItem = BaseEnvelopeItem Exception,
+ parser: StackParser,
+ key: string,
+ limit: number,
+ event: Event,
+ hint?: EventHint,
+): void {
+ if (!event.exception || !event.exception.values || !hint || !isInstanceOf(hint.originalException, Error)) {
+ return;
+ }
+
+ // Generally speaking the last item in `event.exception.values` is the exception originating from the original Error
+ const originalException: Exception | undefined =
+ event.exception.values.length > 0 ? event.exception.values[event.exception.values.length - 1] : undefined;
+
+ // We only create exception grouping if there is an exception in the event.
+ if (originalException) {
+ event.exception.values = aggregateExceptionsFromError(
+ exceptionFromErrorImplementation,
+ parser,
+ limit,
+ hint.originalException as ExtendedError,
+ key,
+ event.exception.values,
+ originalException,
+ 0,
+ );
+ }
+}
+
+function aggregateExceptionsFromError(
+ exceptionFromErrorImplementation: (stackParser: StackParser, ex: Error) => Exception,
+ parser: StackParser,
+ limit: number,
+ error: ExtendedError,
+ key: string,
+ prevExceptions: Exception[],
+ exception: Exception,
+ exceptionId: number,
+): Exception[] {
+ if (prevExceptions.length >= limit + 1) {
+ return prevExceptions;
+ }
+
+ let newExceptions = [...prevExceptions];
+
+ if (isInstanceOf(error[key], Error)) {
+ applyExceptionGroupFieldsForParentException(exception, exceptionId);
+ const newException = exceptionFromErrorImplementation(parser, error[key]);
+ const newExceptionId = newExceptions.length;
+ applyExceptionGroupFieldsForChildException(newException, key, newExceptionId, exceptionId);
+ newExceptions = aggregateExceptionsFromError(
+ exceptionFromErrorImplementation,
+ parser,
+ limit,
+ error[key],
+ key,
+ [newException, ...newExceptions],
+ newException,
+ newExceptionId,
+ );
+ }
+
+ // This will create exception grouping for AggregateErrors
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError
+ if (Array.isArray(error.errors)) {
+ error.errors.forEach((childError, i) => {
+ if (isInstanceOf(childError, Error)) {
+ applyExceptionGroupFieldsForParentException(exception, exceptionId);
+ const newException = exceptionFromErrorImplementation(parser, childError);
+ const newExceptionId = newExceptions.length;
+ applyExceptionGroupFieldsForChildException(newException, `errors[${i}]`, newExceptionId, exceptionId);
+ newExceptions = aggregateExceptionsFromError(
+ exceptionFromErrorImplementation,
+ parser,
+ limit,
+ childError,
+ key,
+ [newException, ...newExceptions],
+ newException,
+ newExceptionId,
+ );
+ }
+ });
+ }
+
+ return newExceptions;
+}
+
+function applyExceptionGroupFieldsForParentException(exception: Exception, exceptionId: number): void {
+ // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.
+ exception.mechanism = exception.mechanism || { type: 'generic', handled: true };
+
+ exception.mechanism = {
+ ...exception.mechanism,
+ is_exception_group: true,
+ exception_id: exceptionId,
+ };
+}
+
+function applyExceptionGroupFieldsForChildException(
+ exception: Exception,
+ source: string,
+ exceptionId: number,
+ parentId: number | undefined,
+): void {
+ // Don't know if this default makes sense. The protocol requires us to set these values so we pick *some* default.
+ exception.mechanism = exception.mechanism || { type: 'generic', handled: true };
+
+ exception.mechanism = {
+ ...exception.mechanism,
+ type: 'chained',
+ source,
+ exception_id: exceptionId,
+ parent_id: parentId,
+ };
+}
diff --git a/packages/utils/src/baggage.ts b/packages/utils/src/baggage.ts
index 406ee3adc819..674e7f60f7ef 100644
--- a/packages/utils/src/baggage.ts
+++ b/packages/utils/src/baggage.ts
@@ -83,8 +83,12 @@ export function baggageHeaderToDynamicSamplingContext(
*/
export function dynamicSamplingContextToSentryBaggageHeader(
// this also takes undefined for convenience and bundle size in other places
- dynamicSamplingContext: Partial,
+ dynamicSamplingContext?: Partial,
): string | undefined {
+ if (!dynamicSamplingContext) {
+ return undefined;
+ }
+
// Prefix all DSC keys with "sentry-" and put them into a new object
const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce>(
(acc, [dscKey, dscValue]) => {
diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts
index 6b9426c22149..0464dbec25da 100644
--- a/packages/utils/src/index.ts
+++ b/packages/utils/src/index.ts
@@ -1,3 +1,4 @@
+export * from './aggregate-errors';
export * from './browser';
export * from './dsn';
export * from './error';
diff --git a/packages/utils/src/tracing.ts b/packages/utils/src/tracing.ts
index 7eee5312ce6d..f879b856f9f2 100644
--- a/packages/utils/src/tracing.ts
+++ b/packages/utils/src/tracing.ts
@@ -1,4 +1,7 @@
-import type { TraceparentData } from '@sentry/types';
+import type { DynamicSamplingContext, PropagationContext, TraceparentData } from '@sentry/types';
+
+import { baggageHeaderToDynamicSamplingContext } from './baggage';
+import { uuid4 } from './misc';
export const TRACEPARENT_REGEXP = new RegExp(
'^[ \\t]*' + // whitespace
@@ -15,11 +18,13 @@ export const TRACEPARENT_REGEXP = new RegExp(
*
* @returns Object containing data from the header, or undefined if traceparent string is malformed
*/
-export function extractTraceparentData(traceparent: string): TraceparentData | undefined {
- const matches = traceparent.match(TRACEPARENT_REGEXP);
+export function extractTraceparentData(traceparent?: string): TraceparentData | undefined {
+ if (!traceparent) {
+ return undefined;
+ }
- if (!traceparent || !matches) {
- // empty string or no matches is invalid traceparent data
+ const matches = traceparent.match(TRACEPARENT_REGEXP);
+ if (!matches) {
return undefined;
}
@@ -36,3 +41,55 @@ export function extractTraceparentData(traceparent: string): TraceparentData | u
parentSpanId: matches[2],
};
}
+
+/**
+ * Create tracing context from incoming headers.
+ */
+export function tracingContextFromHeaders(
+ sentryTrace: Parameters[0],
+ baggage: Parameters[0],
+): {
+ traceparentData: ReturnType;
+ dynamicSamplingContext: ReturnType;
+ propagationContext: PropagationContext;
+} {
+ const traceparentData = extractTraceparentData(sentryTrace);
+ const dynamicSamplingContext = baggageHeaderToDynamicSamplingContext(baggage);
+
+ const { traceId, parentSpanId, parentSampled } = traceparentData || {};
+
+ const propagationContext: PropagationContext = {
+ traceId: traceId || uuid4(),
+ spanId: uuid4().substring(16),
+ sampled: parentSampled === undefined ? false : parentSampled,
+ };
+
+ if (parentSpanId) {
+ propagationContext.parentSpanId = parentSpanId;
+ }
+
+ if (dynamicSamplingContext) {
+ propagationContext.dsc = dynamicSamplingContext as DynamicSamplingContext;
+ }
+
+ return {
+ traceparentData,
+ dynamicSamplingContext,
+ propagationContext,
+ };
+}
+
+/**
+ * Create sentry-trace header from span context values.
+ */
+export function generateSentryTraceHeader(
+ traceId: string = uuid4(),
+ spanId: string = uuid4().substring(16),
+ sampled?: boolean,
+): string {
+ let sampledString = '';
+ if (sampled !== undefined) {
+ sampledString = sampled ? '-1' : '-0';
+ }
+ return `${traceId}-${spanId}${sampledString}`;
+}
diff --git a/packages/utils/src/worldwide.ts b/packages/utils/src/worldwide.ts
index 37a6deb30851..12e098bf3bc7 100644
--- a/packages/utils/src/worldwide.ts
+++ b/packages/utils/src/worldwide.ts
@@ -55,6 +55,12 @@ export interface InternalGlobal {
[key: string]: Function;
};
};
+ /**
+ * Raw module metadata that is injected by bundler plugins.
+ *
+ * Keys are `error.stack` strings, values are the metadata.
+ */
+ _sentryModuleMetadata?: Record;
}
// The code below for 'isGlobalObj' and 'GLOBAL_OBJ' was copied from core-js before modification
diff --git a/packages/utils/test/aggregate-errors.test.ts b/packages/utils/test/aggregate-errors.test.ts
new file mode 100644
index 000000000000..9a42bba12858
--- /dev/null
+++ b/packages/utils/test/aggregate-errors.test.ts
@@ -0,0 +1,275 @@
+import type { Event, EventHint, Exception, ExtendedError, StackParser } from '@sentry/types';
+
+import { applyAggregateErrorsToEvent, createStackParser } from '../src/index';
+
+const stackParser = createStackParser([0, line => ({ filename: line })]);
+const exceptionFromError = (_stackParser: StackParser, ex: Error): Exception => {
+ return { value: ex.message, mechanism: { type: 'instrument', handled: true } };
+};
+
+describe('applyAggregateErrorsToEvent()', () => {
+ test('should not do anything if event does not contain an exception', () => {
+ const event: Event = { exception: undefined };
+ const eventHint: EventHint = { originalException: new Error() };
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, eventHint);
+
+ // no changes
+ expect(event).toStrictEqual({ exception: undefined });
+ });
+
+ test('should not do anything if event does not contain exception values', () => {
+ const event: Event = { exception: { values: undefined } };
+ const eventHint: EventHint = { originalException: new Error() };
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, eventHint);
+
+ // no changes
+ expect(event).toStrictEqual({ exception: { values: undefined } });
+ });
+
+ test('should not do anything if event does not contain an event hint', () => {
+ const event: Event = { exception: { values: [] } };
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, undefined);
+
+ // no changes
+ expect(event).toStrictEqual({ exception: { values: [] } });
+ });
+
+ test('should not do anything if the event hint does not contain an original exception', () => {
+ const event: Event = { exception: { values: [] } };
+ const eventHint: EventHint = { originalException: undefined };
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, eventHint);
+
+ // no changes
+ expect(event).toStrictEqual({ exception: { values: [] } });
+ });
+
+ test('should recursively walk the original exception based on the `key` option and add them as exceptions to the event', () => {
+ const key = 'cause';
+ const originalException: ExtendedError = new Error('Root Error');
+ originalException[key] = new Error('Nested Error 1');
+ originalException[key][key] = new Error('Nested Error 2');
+
+ const event: Event = { exception: { values: [exceptionFromError(stackParser, originalException)] } };
+ const eventHint: EventHint = { originalException };
+
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, key, 100, event, eventHint);
+ expect(event).toStrictEqual({
+ exception: {
+ values: [
+ {
+ value: 'Nested Error 2',
+ mechanism: {
+ exception_id: 2,
+ handled: true,
+ parent_id: 1,
+ source: 'cause',
+ type: 'chained',
+ },
+ },
+ {
+ value: 'Nested Error 1',
+ mechanism: {
+ exception_id: 1,
+ handled: true,
+ parent_id: 0,
+ is_exception_group: true,
+ source: 'cause',
+ type: 'chained',
+ },
+ },
+ {
+ value: 'Root Error',
+ mechanism: {
+ exception_id: 0,
+ handled: true,
+ is_exception_group: true,
+ type: 'instrument',
+ },
+ },
+ ],
+ },
+ });
+ });
+
+ test('should not modify event if there are no attached errors', () => {
+ const originalException: ExtendedError = new Error('Some Error');
+
+ const event: Event = { exception: { values: [exceptionFromError(stackParser, originalException)] } };
+ const eventHint: EventHint = { originalException };
+
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, eventHint);
+
+ // no changes
+ expect(event).toStrictEqual({ exception: { values: [exceptionFromError(stackParser, originalException)] } });
+ });
+
+ test('should allow to limit number of attached errors', () => {
+ const key = 'cause';
+ const originalException: ExtendedError = new Error('Root Error');
+ const event: Event = { exception: { values: [exceptionFromError(stackParser, originalException)] } };
+
+ let err = originalException;
+ for (let i = 0; i < 10; i++) {
+ const newErr = new Error('Nested Error!');
+ err[key] = newErr;
+ err = newErr;
+ }
+
+ const eventHint: EventHint = { originalException };
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, key, 5, event, eventHint);
+
+ // 6 -> one for original exception + 5 linked
+ expect(event.exception?.values).toHaveLength(5 + 1);
+
+ // Last exception in list should be the root exception
+ expect(event.exception?.values?.[event.exception?.values.length - 1]).toStrictEqual({
+ value: 'Root Error',
+ mechanism: {
+ exception_id: 0,
+ handled: true,
+ is_exception_group: true,
+ type: 'instrument',
+ },
+ });
+ });
+
+ test('should keep the original mechanism type for the root exception', () => {
+ const fakeAggregateError: ExtendedError = new Error('Root Error');
+ fakeAggregateError.errors = [new Error('Nested Error 1'), new Error('Nested Error 2')];
+
+ const event: Event = { exception: { values: [exceptionFromError(stackParser, fakeAggregateError)] } };
+ const eventHint: EventHint = { originalException: fakeAggregateError };
+
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, eventHint);
+ expect(event.exception?.values?.[event.exception.values.length - 1].mechanism?.type).toBe('instrument');
+ });
+
+ test('should recursively walk mixed errors (Aggregate errors and based on `key`)', () => {
+ const chainedError: ExtendedError = new Error('Nested Error 3');
+ chainedError.cause = new Error('Nested Error 4');
+ const fakeAggregateError2: ExtendedError = new Error('AggregateError2');
+ fakeAggregateError2.errors = [new Error('Nested Error 2'), chainedError];
+ const fakeAggregateError1: ExtendedError = new Error('AggregateError1');
+ fakeAggregateError1.errors = [new Error('Nested Error 1'), fakeAggregateError2];
+
+ const event: Event = { exception: { values: [exceptionFromError(stackParser, fakeAggregateError1)] } };
+ const eventHint: EventHint = { originalException: fakeAggregateError1 };
+
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, 'cause', 100, event, eventHint);
+ expect(event).toStrictEqual({
+ exception: {
+ values: [
+ {
+ mechanism: {
+ exception_id: 5,
+ handled: true,
+ parent_id: 4,
+ source: 'cause',
+ type: 'chained',
+ },
+ value: 'Nested Error 4',
+ },
+ {
+ mechanism: {
+ exception_id: 4,
+ handled: true,
+ is_exception_group: true,
+ parent_id: 2,
+ source: 'errors[1]',
+ type: 'chained',
+ },
+ value: 'Nested Error 3',
+ },
+ {
+ mechanism: {
+ exception_id: 3,
+ handled: true,
+ parent_id: 2,
+ source: 'errors[0]',
+ type: 'chained',
+ },
+ value: 'Nested Error 2',
+ },
+ {
+ mechanism: {
+ exception_id: 2,
+ handled: true,
+ is_exception_group: true,
+ parent_id: 0,
+ source: 'errors[1]',
+ type: 'chained',
+ },
+ value: 'AggregateError2',
+ },
+ {
+ mechanism: {
+ exception_id: 1,
+ handled: true,
+ parent_id: 0,
+ source: 'errors[0]',
+ type: 'chained',
+ },
+ value: 'Nested Error 1',
+ },
+ {
+ mechanism: {
+ exception_id: 0,
+ handled: true,
+ is_exception_group: true,
+ type: 'instrument',
+ },
+ value: 'AggregateError1',
+ },
+ ],
+ },
+ });
+ });
+
+ test('should keep the original mechanism type for the root exception', () => {
+ const key = 'cause';
+ const originalException: ExtendedError = new Error('Root Error');
+ originalException[key] = new Error('Nested Error 1');
+ originalException[key][key] = new Error('Nested Error 2');
+
+ const event: Event = { exception: { values: [exceptionFromError(stackParser, originalException)] } };
+ const eventHint: EventHint = { originalException };
+
+ applyAggregateErrorsToEvent(exceptionFromError, stackParser, key, 100, event, eventHint);
+ expect(event).toStrictEqual({
+ exception: {
+ values: [
+ {
+ value: 'Nested Error 2',
+ mechanism: {
+ exception_id: 2,
+ handled: true,
+ parent_id: 1,
+ source: 'cause',
+ type: 'chained',
+ },
+ },
+ {
+ value: 'Nested Error 1',
+ mechanism: {
+ exception_id: 1,
+ handled: true,
+ parent_id: 0,
+ is_exception_group: true,
+ source: 'cause',
+ type: 'chained',
+ },
+ },
+ {
+ value: 'Root Error',
+ mechanism: {
+ exception_id: 0,
+ handled: true,
+ is_exception_group: true,
+ type: 'instrument',
+ },
+ },
+ ],
+ },
+ });
+ });
+});
diff --git a/packages/utils/test/baggage.test.ts b/packages/utils/test/baggage.test.ts
index 8f848badf9de..539a34e44d9c 100644
--- a/packages/utils/test/baggage.test.ts
+++ b/packages/utils/test/baggage.test.ts
@@ -28,6 +28,7 @@ test.each([
});
test.each([
+ [undefined, undefined],
[{}, undefined],
[{ release: 'abcdf' }, 'sentry-release=abcdf'],
[{ release: 'abcdf', environment: '1234' }, 'sentry-release=abcdf,sentry-environment=1234'],
diff --git a/scripts/node-unit-tests.ts b/scripts/node-unit-tests.ts
index e5efc7c2ebd3..c32fa6376d38 100644
--- a/scripts/node-unit-tests.ts
+++ b/scripts/node-unit-tests.ts
@@ -22,6 +22,7 @@ const NODE_8_SKIP_TESTS_PACKAGES = [
'@sentry/nextjs',
'@sentry/remix',
'@sentry/sveltekit',
+ '@sentry-internal/replay-worker',
];
// We have to downgrade some of our dependencies in order to run tests in Node 8 and 10.
@@ -34,7 +35,7 @@ const NODE_8_LEGACY_DEPENDENCIES = [
'lerna@3.13.4',
];
-const NODE_10_SKIP_TESTS_PACKAGES = ['@sentry/remix', '@sentry/sveltekit'];
+const NODE_10_SKIP_TESTS_PACKAGES = ['@sentry/remix', '@sentry/sveltekit', '@sentry-internal/replay-worker'];
const NODE_10_LEGACY_DEPENDENCIES = ['jsdom@16.x', 'lerna@3.13.4'];
const NODE_12_SKIP_TESTS_PACKAGES = ['@sentry/remix', '@sentry/sveltekit'];
diff --git a/yarn.lock b/yarn.lock
index 224622dc7189..8431c6928ee7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2817,10 +2817,17 @@
resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340"
integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==
-"@isaacs/string-locale-compare@^1.1.0":
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b"
- integrity sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==
+"@isaacs/cliui@^8.0.2":
+ version "8.0.2"
+ resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
+ integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
+ dependencies:
+ string-width "^5.1.2"
+ string-width-cjs "npm:string-width@^4.2.0"
+ strip-ansi "^7.0.1"
+ strip-ansi-cjs "npm:strip-ansi@^6.0.1"
+ wrap-ansi "^8.1.0"
+ wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
@@ -2946,6 +2953,13 @@
terminal-link "^2.0.0"
v8-to-istanbul "^8.1.0"
+"@jest/schemas@^29.4.3":
+ version "29.4.3"
+ resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788"
+ integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==
+ dependencies:
+ "@sinclair/typebox" "^0.25.16"
+
"@jest/source-map@^27.5.1":
version "27.5.1"
resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf"
@@ -3093,32 +3107,32 @@
resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919"
integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==
-"@lerna/child-process@6.5.0-alpha.2":
- version "6.5.0-alpha.2"
- resolved "https://registry.npmjs.org/@lerna/child-process/-/child-process-6.5.0-alpha.2.tgz#5ef9cc6c8e521fbb9f18b3031ca3e789345e7b56"
- integrity sha512-lzRKVaI5J5p7CihAVSHaEN7uAMZScNNRwy2hoz6w+lM5vKiMmrc93yl3zjUo0BeyqB1i1b3ntUMMIX6UWGjvuA==
+"@lerna/child-process@7.1.1":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-7.1.1.tgz#60eddd6dc4b6ba0fd51851c78b6dbdc4e1614220"
+ integrity sha512-mR8PaTkckYPLmEBG2VsVsJq2UuzEvjXevOB1rKLKUZ/dPCGcottVhbiEzTxickc+s7Y/1dTTLn/1BKj3B1a5BA==
dependencies:
chalk "^4.1.0"
execa "^5.0.0"
strong-log-transformer "^2.1.0"
-"@lerna/create@6.5.0-alpha.2":
- version "6.5.0-alpha.2"
- resolved "https://registry.npmjs.org/@lerna/create/-/create-6.5.0-alpha.2.tgz#8b4f681e049356a924056358ebd0b485519061d8"
- integrity sha512-LSUv6/2yvU13odiZYpLsy3FQ39oyCinf+puFZ6waYMbVb0LBikbtNZ2YP4rAwyN91PRp5vTwtwqbls47NdHOvg==
+"@lerna/create@7.1.1":
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/@lerna/create/-/create-7.1.1.tgz#2af94afb01971c1b594c06347b6998607aefe5c4"
+ integrity sha512-1PY2OgwGxp7b91JzLKEhONVl69mCt1IyYEc6pzKy3Sv+UOdeK2QFq1SX/85hNOR3iitiyZ75bNWUTcBly1ZlZg==
dependencies:
- "@lerna/child-process" "6.5.0-alpha.2"
- dedent "^0.7.0"
- fs-extra "^9.1.0"
- init-package-json "^3.0.2"
+ "@lerna/child-process" "7.1.1"
+ dedent "0.7.0"
+ fs-extra "^11.1.1"
+ init-package-json "5.0.0"
npm-package-arg "8.1.1"
p-reduce "^2.1.0"
- pacote "^13.6.1"
- pify "^5.0.0"
+ pacote "^15.2.0"
+ pify "5.0.0"
semver "^7.3.4"
slash "^3.0.0"
validate-npm-package-license "^3.0.4"
- validate-npm-package-name "^4.0.0"
+ validate-npm-package-name "5.0.0"
yargs-parser "20.2.4"
"@lint-todo/utils@^13.0.3":
@@ -3201,46 +3215,6 @@
"@nodelib/fs.scandir" "2.1.4"
fastq "^1.6.0"
-"@npmcli/arborist@5.3.0":
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/@npmcli/arborist/-/arborist-5.3.0.tgz#321d9424677bfc08569e98a5ac445ee781f32053"
- integrity sha512-+rZ9zgL1lnbl8Xbb1NQdMjveOMwj4lIYfcDtyJHHi5x4X8jtR6m8SXooJMZy5vmFVZ8w7A2Bnd/oX9eTuU8w5A==
- dependencies:
- "@isaacs/string-locale-compare" "^1.1.0"
- "@npmcli/installed-package-contents" "^1.0.7"
- "@npmcli/map-workspaces" "^2.0.3"
- "@npmcli/metavuln-calculator" "^3.0.1"
- "@npmcli/move-file" "^2.0.0"
- "@npmcli/name-from-folder" "^1.0.1"
- "@npmcli/node-gyp" "^2.0.0"
- "@npmcli/package-json" "^2.0.0"
- "@npmcli/run-script" "^4.1.3"
- bin-links "^3.0.0"
- cacache "^16.0.6"
- common-ancestor-path "^1.0.1"
- json-parse-even-better-errors "^2.3.1"
- json-stringify-nice "^1.1.4"
- mkdirp "^1.0.4"
- mkdirp-infer-owner "^2.0.0"
- nopt "^5.0.0"
- npm-install-checks "^5.0.0"
- npm-package-arg "^9.0.0"
- npm-pick-manifest "^7.0.0"
- npm-registry-fetch "^13.0.0"
- npmlog "^6.0.2"
- pacote "^13.6.1"
- parse-conflict-json "^2.0.1"
- proc-log "^2.0.0"
- promise-all-reject-late "^1.0.0"
- promise-call-limit "^1.0.1"
- read-package-json-fast "^2.0.2"
- readdir-scoped-modules "^1.1.0"
- rimraf "^3.0.2"
- semver "^7.3.7"
- ssri "^9.0.0"
- treeverse "^2.0.0"
- walk-up-path "^1.0.0"
-
"@npmcli/fs@^1.0.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257"
@@ -3257,6 +3231,13 @@
"@gar/promisify" "^1.1.3"
semver "^7.3.5"
+"@npmcli/fs@^3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e"
+ integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==
+ dependencies:
+ semver "^7.3.5"
+
"@npmcli/git@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6"
@@ -3271,22 +3252,21 @@
semver "^7.3.5"
which "^2.0.2"
-"@npmcli/git@^3.0.0":
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-3.0.2.tgz#5c5de6b4d70474cf2d09af149ce42e4e1dacb931"
- integrity sha512-CAcd08y3DWBJqJDpfuVL0uijlq5oaXaOJEKHKc4wqrjd00gkvTZB+nFuLn+doOOKddaQS9JfqtNoFCO2LCvA3w==
+"@npmcli/git@^4.0.0":
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6"
+ integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==
dependencies:
- "@npmcli/promise-spawn" "^3.0.0"
+ "@npmcli/promise-spawn" "^6.0.0"
lru-cache "^7.4.4"
- mkdirp "^1.0.4"
- npm-pick-manifest "^7.0.0"
- proc-log "^2.0.0"
+ npm-pick-manifest "^8.0.0"
+ proc-log "^3.0.0"
promise-inflight "^1.0.1"
promise-retry "^2.0.1"
semver "^7.3.5"
- which "^2.0.2"
+ which "^3.0.0"
-"@npmcli/installed-package-contents@^1.0.6", "@npmcli/installed-package-contents@^1.0.7":
+"@npmcli/installed-package-contents@^1.0.6":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa"
integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==
@@ -3294,25 +3274,13 @@
npm-bundled "^1.1.1"
npm-normalize-package-bin "^1.0.1"
-"@npmcli/map-workspaces@^2.0.3":
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-2.0.4.tgz#9e5e8ab655215a262aefabf139782b894e0504fc"
- integrity sha512-bMo0aAfwhVwqoVM5UzX1DJnlvVvzDCHae821jv48L1EsrYwfOZChlqWYXEtto/+BkBXetPbEWgau++/brh4oVg==
- dependencies:
- "@npmcli/name-from-folder" "^1.0.1"
- glob "^8.0.1"
- minimatch "^5.0.1"
- read-package-json-fast "^2.0.3"
-
-"@npmcli/metavuln-calculator@^3.0.1":
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/@npmcli/metavuln-calculator/-/metavuln-calculator-3.1.1.tgz#9359bd72b400f8353f6a28a25c8457b562602622"
- integrity sha512-n69ygIaqAedecLeVH3KnO39M6ZHiJ2dEv5A7DGvcqCB8q17BGUgW8QaanIkbWUo2aYGZqJaOORTLAlIvKjNDKA==
+"@npmcli/installed-package-contents@^2.0.1":
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33"
+ integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==
dependencies:
- cacache "^16.0.0"
- json-parse-even-better-errors "^2.3.1"
- pacote "^13.0.3"
- semver "^7.3.5"
+ npm-bundled "^3.0.0"
+ npm-normalize-package-bin "^3.0.0"
"@npmcli/move-file@^1.0.1":
version "1.1.2"
@@ -3330,27 +3298,15 @@
mkdirp "^1.0.4"
rimraf "^3.0.2"
-"@npmcli/name-from-folder@^1.0.1":
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/@npmcli/name-from-folder/-/name-from-folder-1.0.1.tgz#77ecd0a4fcb772ba6fe927e2e2e155fbec2e6b1a"
- integrity sha512-qq3oEfcLFwNfEYOQ8HLimRGKlD8WSeGEdtUa7hmzpR8Sa7haL1KVQrvgO6wqMjhWFFVjgtrh1gIxDz+P8sjUaA==
-
"@npmcli/node-gyp@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33"
integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==
-"@npmcli/node-gyp@^2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz#8c20e53e34e9078d18815c1d2dda6f2420d75e35"
- integrity sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A==
-
-"@npmcli/package-json@^2.0.0":
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-2.0.0.tgz#3bbcf4677e21055adbe673d9f08c9f9cde942e4a"
- integrity sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA==
- dependencies:
- json-parse-even-better-errors "^2.3.1"
+"@npmcli/node-gyp@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a"
+ integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==
"@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2":
version "1.3.2"
@@ -3359,23 +3315,23 @@
dependencies:
infer-owner "^1.0.4"
-"@npmcli/promise-spawn@^3.0.0":
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz#53283b5f18f855c6925f23c24e67c911501ef573"
- integrity sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g==
+"@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1":
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz#c8bc4fa2bd0f01cb979d8798ba038f314cfa70f2"
+ integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==
dependencies:
- infer-owner "^1.0.4"
+ which "^3.0.0"
-"@npmcli/run-script@4.1.7":
- version "4.1.7"
- resolved "https://registry.npmjs.org/@npmcli/run-script/-/run-script-4.1.7.tgz#b1a2f57568eb738e45e9ea3123fb054b400a86f7"
- integrity sha512-WXr/MyM4tpKA4BotB81NccGAv8B48lNH0gRoILucbcAhTQXLCoi6HflMV3KdXubIqvP9SuLsFn68Z7r4jl+ppw==
+"@npmcli/run-script@6.0.2", "@npmcli/run-script@^6.0.0":
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885"
+ integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==
dependencies:
- "@npmcli/node-gyp" "^2.0.0"
- "@npmcli/promise-spawn" "^3.0.0"
+ "@npmcli/node-gyp" "^3.0.0"
+ "@npmcli/promise-spawn" "^6.0.0"
node-gyp "^9.0.0"
- read-package-json-fast "^2.0.3"
- which "^2.0.2"
+ read-package-json-fast "^3.0.0"
+ which "^3.0.0"
"@npmcli/run-script@^2.0.0":
version "2.0.0"
@@ -3387,41 +3343,81 @@
node-gyp "^8.2.0"
read-package-json-fast "^2.0.1"
-"@npmcli/run-script@^4.1.0", "@npmcli/run-script@^4.1.3":
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-4.2.1.tgz#c07c5c71bc1c70a5f2a06b0d4da976641609b946"
- integrity sha512-7dqywvVudPSrRCW5nTHpHgeWnbBtz8cFkOuKrecm6ih+oO9ciydhWt6OF7HlqupRRmB8Q/gECVdB9LMfToJbRg==
+"@nrwl/devkit@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-16.4.1.tgz#3605e7f39cccdc47502838593579a1af6f22ae9c"
+ integrity sha512-kio+x1NonteK9Vxrgeai56+cDFkiWUl42YzLamNXORvICgVgGtcR7afdi9l7j9q2YPUuvtBos6T9YddS6YCb2g==
dependencies:
- "@npmcli/node-gyp" "^2.0.0"
- "@npmcli/promise-spawn" "^3.0.0"
- node-gyp "^9.0.0"
- read-package-json-fast "^2.0.3"
- which "^2.0.2"
+ "@nx/devkit" "16.4.1"
-"@nrwl/cli@15.6.3":
- version "15.6.3"
- resolved "https://registry.npmjs.org/@nrwl/cli/-/cli-15.6.3.tgz#999531d6efb30afc39373bdcbd7e78254a3a3fd3"
- integrity sha512-K4E0spofThZXMnhA6R8hkUTdfqmwSnUE2+DlD5Y3jqsvKTAgwF5U41IFkEouFZCf+dWjy0RA20bWoX48EVFtmQ==
+"@nrwl/tao@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.4.1.tgz#4d060a73c2dfdbf00b66c922a2f1f7c30fffa048"
+ integrity sha512-aJqYxgz+PzyeuFrKj7jei8Xwq05JYLmq5o+4/Und+lkMZboqvVWz1ezwiMj9pzGoXz4td8b3sN1B+nwmORm3ZQ==
dependencies:
- nx "15.6.3"
+ nx "16.4.1"
-"@nrwl/devkit@>=15.5.2 < 16":
- version "15.6.3"
- resolved "https://registry.npmjs.org/@nrwl/devkit/-/devkit-15.6.3.tgz#e4e96c53ba3304786a49034286c8511534b2b194"
- integrity sha512-/JDvdzNxUM+C1PCZPCrvmFx+OfywqZdOq1GS9QR8C0VctTLG4D/SGSFD88O1SAdcbH/f1mMiBGfEYZYd23fghQ==
+"@nx/devkit@16.4.1", "@nx/devkit@>=16.1.3 < 17":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-16.4.1.tgz#43b126704d5611b8f19418ade4a60a0fd1e695ff"
+ integrity sha512-N2oDaQQV9r6mnoPsAqKs8H+tsLdNptQms5AxgnhdEMYWH4ppmy6Zutg4h1qZWsbdqSyiLVuOqlPrPlzRM4EA4g==
dependencies:
- "@phenomnomnominal/tsquery" "4.1.1"
+ "@nrwl/devkit" "16.4.1"
ejs "^3.1.7"
ignore "^5.0.4"
- semver "7.3.4"
+ semver "7.5.3"
+ tmp "~0.2.1"
tslib "^2.3.0"
-"@nrwl/tao@15.6.3":
- version "15.6.3"
- resolved "https://registry.npmjs.org/@nrwl/tao/-/tao-15.6.3.tgz#b24e11345375dea96bc386c60b9b1102a7584932"
- integrity sha512-bDZbPIbU5Mf2BvX0q8GjPxrm1WkYyfW+gp7mLuuJth2sEpZiCr47mSwuGko/y4CKXvIX46VQcAS0pKQMKugXsg==
- dependencies:
- nx "15.6.3"
+"@nx/nx-darwin-arm64@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.4.1.tgz#c7069c28972d19c0fa982819b9aa3e3af3637798"
+ integrity sha512-DkY51qgBlqgHwAVrK4k58tNZ1Uuqi4czA+aLs+J2OvC8W/4uRSajGPL4LWgdPWYe1zKxJvhFIFswchn8uQuaBw==
+
+"@nx/nx-darwin-x64@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-16.4.1.tgz#9d641ce027b2fa46c210229e7b133d5611318670"
+ integrity sha512-jMJz6wsCOl7n3x4lmiS7BbQZdGmKKsN1IUaLcJfxZjFN3YS8euO2bwO74trFkfNOdYG8KjFuw/+A62USYj4e+g==
+
+"@nx/nx-freebsd-x64@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.4.1.tgz#ee3806e1313327f58b4df624e703ba8fefb17711"
+ integrity sha512-8Ql2/g+WZOKnPC7x4IeW/vzIRi9K9BE6LvFGGMsTvqKJHurboGlPjBAAqo/wmgM+JPNivtzX+IsQQkcGQrFfLw==
+
+"@nx/nx-linux-arm-gnueabihf@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.4.1.tgz#8082e04b60350f9ca186911ca0ff431b32d141d2"
+ integrity sha512-EyK/q86FXO78oGcubBXlqdzCsrMBx+CgEyndS2IlvpGFXN3v2s3jE8v/RXWbPskJ6zJZytRvyMjTjxAnzjxb+A==
+
+"@nx/nx-linux-arm64-gnu@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.4.1.tgz#4931d04b842c066e8082cb39753d8dc01bb119d8"
+ integrity sha512-2YpmfnHahuFXD7DN4j/O+8hvV1P1oa+QxO+hxBfPdqU45YmOPSwbVEcTsjYmc++iG9xURpGaSu3hGmk5JR4OoQ==
+
+"@nx/nx-linux-arm64-musl@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.4.1.tgz#06cf22f9cb18e9ec1799b249a2b3af5734b8b767"
+ integrity sha512-+xDP3/veLSPaLFrp1lItZTK2rqpMEftOC+2TsRPQ1BwivGxBegerQYWgZxe6nfuBGrRD2xj8+aY4on5UfmYBJw==
+
+"@nx/nx-linux-x64-gnu@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.4.1.tgz#be5678fdfbfdb23a86a53f8fd18710a9aeb5b6e3"
+ integrity sha512-psbB+hTXffeeATO692To4zxz08XNUHNiHefZYVwT6hUWw+EsUAadnd3VimP9xoSzHyzvUk6raYPT783MySTzGg==
+
+"@nx/nx-linux-x64-musl@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.4.1.tgz#8ba537f29edfe9b548e40301fdc286c9aff145f2"
+ integrity sha512-pztJGR64NRygp675p/tkQIF2clIc9mxRVpVAaeIc1DoQTEpyeagqi6bTPwTTUdhDhTleqV6r3wOTL/3ImUrpng==
+
+"@nx/nx-win32-arm64-msvc@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.4.1.tgz#a601d766db76175e69d002d6dfcc859a9f5d777d"
+ integrity sha512-tmfVFZ5lKahYg16mUs7gwEJtlBkL9cEoc1Pf7cuFXHT+T7z5WhXoZ0q7VTyArf3gisK4fTmTAEEuUEK2MbQ2xA==
+
+"@nx/nx-win32-x64-msvc@16.4.1":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.4.1.tgz#d48b2b6f9762dcda5ae51b4f4ecd354479f42605"
+ integrity sha512-MAy719VC8hCPkYJ6j5Gl+s4pevWL0dxbzcXtQDstC0Y7XWPFmHS+CDgK8zHWfaN8mK6Sebv+nTQ+e/ptEu1+TA==
"@octokit/auth-token@^3.0.0":
version "3.0.2"
@@ -3430,7 +3426,7 @@
dependencies:
"@octokit/types" "^8.0.0"
-"@octokit/core@^4.0.0", "@octokit/core@^4.1.0":
+"@octokit/core@^4.1.0":
version "4.2.0"
resolved "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz#8c253ba9605aca605bc46187c34fcccae6a96648"
integrity sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==
@@ -3443,6 +3439,19 @@
before-after-hook "^2.2.0"
universal-user-agent "^6.0.0"
+"@octokit/core@^4.2.1":
+ version "4.2.4"
+ resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907"
+ integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==
+ dependencies:
+ "@octokit/auth-token" "^3.0.0"
+ "@octokit/graphql" "^5.0.0"
+ "@octokit/request" "^6.0.0"
+ "@octokit/request-error" "^3.0.0"
+ "@octokit/types" "^9.0.0"
+ before-after-hook "^2.2.0"
+ universal-user-agent "^6.0.0"
+
"@octokit/endpoint@^7.0.0":
version "7.0.3"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.3.tgz#0b96035673a9e3bedf8bab8f7335de424a2147ed"
@@ -3461,11 +3470,6 @@
"@octokit/types" "^8.0.0"
universal-user-agent "^6.0.0"
-"@octokit/openapi-types@^12.11.0":
- version "12.11.0"
- resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz#da5638d64f2b919bca89ce6602d059f1b52d3ef0"
- integrity sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==
-
"@octokit/openapi-types@^14.0.0":
version "14.0.0"
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a"
@@ -3476,18 +3480,16 @@
resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz#d92838a6cd9fb4639ca875ddb3437f1045cc625e"
integrity sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==
+"@octokit/openapi-types@^18.0.0":
+ version "18.0.0"
+ resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.0.0.tgz#f43d765b3c7533fd6fb88f3f25df079c24fccf69"
+ integrity sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==
+
"@octokit/plugin-enterprise-rest@6.0.1":
version "6.0.1"
resolved "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437"
integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==
-"@octokit/plugin-paginate-rest@^3.0.0":
- version "3.1.0"
- resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-3.1.0.tgz#86f8be759ce2d6d7c879a31490fd2f7410b731f0"
- integrity sha512-+cfc40pMzWcLkoDcLb1KXqjX0jTGYXjKuQdFQDc6UAknISJHnZTiBqld6HDwRJvD4DsouDKrWXNbNV0lE/3AXA==
- dependencies:
- "@octokit/types" "^6.41.0"
-
"@octokit/plugin-paginate-rest@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz#f34b5a7d9416019126042cd7d7b811e006c0d561"
@@ -3495,19 +3497,19 @@
dependencies:
"@octokit/types" "^9.0.0"
+"@octokit/plugin-paginate-rest@^6.1.2":
+ version "6.1.2"
+ resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8"
+ integrity sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==
+ dependencies:
+ "@octokit/tsconfig" "^1.0.2"
+ "@octokit/types" "^9.2.3"
+
"@octokit/plugin-request-log@^1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85"
integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==
-"@octokit/plugin-rest-endpoint-methods@^6.0.0":
- version "6.8.1"
- resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.8.1.tgz#97391fda88949eb15f68dc291957ccbe1d3e8ad1"
- integrity sha512-QrlaTm8Lyc/TbU7BL/8bO49vp+RZ6W3McxxmmQTgYxf2sWkO8ZKuj4dLhPNJD6VCUW1hetCmeIM0m6FTVpDiEg==
- dependencies:
- "@octokit/types" "^8.1.1"
- deprecation "^2.3.1"
-
"@octokit/plugin-rest-endpoint-methods@^7.0.0":
version "7.0.1"
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.0.1.tgz#f7ebe18144fd89460f98f35a587b056646e84502"
@@ -3516,6 +3518,13 @@
"@octokit/types" "^9.0.0"
deprecation "^2.3.1"
+"@octokit/plugin-rest-endpoint-methods@^7.1.2":
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797"
+ integrity sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==
+ dependencies:
+ "@octokit/types" "^10.0.0"
+
"@octokit/request-error@^3.0.0":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.2.tgz#f74c0f163d19463b87528efe877216c41d6deb0a"
@@ -3537,15 +3546,15 @@
node-fetch "^2.6.7"
universal-user-agent "^6.0.0"
-"@octokit/rest@19.0.3":
- version "19.0.3"
- resolved "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.3.tgz#b9a4e8dc8d53e030d611c053153ee6045f080f02"
- integrity sha512-5arkTsnnRT7/sbI4fqgSJ35KiFaN7zQm0uQiQtivNQLI8RQx8EHwJCajcTUwmaCMNDg7tdCvqAnc7uvHHPxrtQ==
+"@octokit/rest@19.0.11":
+ version "19.0.11"
+ resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c"
+ integrity sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==
dependencies:
- "@octokit/core" "^4.0.0"
- "@octokit/plugin-paginate-rest" "^3.0.0"
+ "@octokit/core" "^4.2.1"
+ "@octokit/plugin-paginate-rest" "^6.1.2"
"@octokit/plugin-request-log" "^1.0.4"
- "@octokit/plugin-rest-endpoint-methods" "^6.0.0"
+ "@octokit/plugin-rest-endpoint-methods" "^7.1.2"
"@octokit/rest@^19.0.5":
version "19.0.7"
@@ -3557,12 +3566,17 @@
"@octokit/plugin-request-log" "^1.0.4"
"@octokit/plugin-rest-endpoint-methods" "^7.0.0"
-"@octokit/types@^6.41.0":
- version "6.41.0"
- resolved "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz#e58ef78d78596d2fb7df9c6259802464b5f84a04"
- integrity sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==
+"@octokit/tsconfig@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@octokit/tsconfig/-/tsconfig-1.0.2.tgz#59b024d6f3c0ed82f00d08ead5b3750469125af7"
+ integrity sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==
+
+"@octokit/types@^10.0.0":
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/@octokit/types/-/types-10.0.0.tgz#7ee19c464ea4ada306c43f1a45d444000f419a4a"
+ integrity sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==
dependencies:
- "@octokit/openapi-types" "^12.11.0"
+ "@octokit/openapi-types" "^18.0.0"
"@octokit/types@^8.0.0":
version "8.0.0"
@@ -3571,13 +3585,6 @@
dependencies:
"@octokit/openapi-types" "^14.0.0"
-"@octokit/types@^8.1.1":
- version "8.2.1"
- resolved "https://registry.npmjs.org/@octokit/types/-/types-8.2.1.tgz#a6de091ae68b5541f8d4fcf9a12e32836d4648aa"
- integrity sha512-8oWMUji8be66q2B9PmEIUyQm00VPDPun07umUWSaCwxmeaquFBro4Hcc3ruVoDo3zkQyZBlRvhIMEYS3pBhanw==
- dependencies:
- "@octokit/openapi-types" "^14.0.0"
-
"@octokit/types@^9.0.0":
version "9.0.0"
resolved "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz#6050db04ddf4188ec92d60e4da1a2ce0633ff635"
@@ -3585,6 +3592,13 @@
dependencies:
"@octokit/openapi-types" "^16.0.0"
+"@octokit/types@^9.2.3":
+ version "9.3.2"
+ resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5"
+ integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==
+ dependencies:
+ "@octokit/openapi-types" "^18.0.0"
+
"@opentelemetry/api@0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.14.0.tgz#4e17d8d2f1da72b19374efa7b6526aa001267cae"
@@ -3715,12 +3729,10 @@
node-addon-api "^3.2.1"
node-gyp-build "^4.3.0"
-"@phenomnomnominal/tsquery@4.1.1":
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/@phenomnomnominal/tsquery/-/tsquery-4.1.1.tgz#42971b83590e9d853d024ddb04a18085a36518df"
- integrity sha512-jjMmK1tnZbm1Jq5a7fBliM4gQwjxMU7TFoRNwIyzwlO+eHPRCFv/Nv+H/Gi1jc3WR7QURG8D5d0Tn12YGrUqBQ==
- dependencies:
- esquery "^1.0.1"
+"@pkgjs/parseargs@^0.11.0":
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
+ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@playwright/test@^1.31.1":
version "1.31.1"
@@ -4154,11 +4166,30 @@
"@sentry/cli" "^1.74.6"
webpack-sources "^2.0.0 || ^3.0.0"
+"@sigstore/protobuf-specs@^0.1.0":
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz#957cb64ea2f5ce527cc9cf02a096baeb0d2b99b4"
+ integrity sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ==
+
+"@sigstore/tuf@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.0.tgz#13b69323e7bf8de458cd6c952c57acd1169772a5"
+ integrity sha512-bLzi9GeZgMCvjJeLUIfs8LJYCxrPRA8IXQkzUtaFKKVPTz0mucRyqFcV2U20yg9K+kYAD0YSitzGfRZCFLjdHQ==
+ dependencies:
+ "@sigstore/protobuf-specs" "^0.1.0"
+ make-fetch-happen "^11.0.1"
+ tuf-js "^1.1.3"
+
"@simple-dom/interface@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f"
integrity sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA==
+"@sinclair/typebox@^0.25.16":
+ version "0.25.24"
+ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718"
+ integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==
+
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
@@ -4384,6 +4415,19 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
+"@tufjs/canonical-json@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31"
+ integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==
+
+"@tufjs/models@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef"
+ integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==
+ dependencies:
+ "@tufjs/canonical-json" "1.0.0"
+ minimatch "^9.0.0"
+
"@types/accepts@^1.3.5":
version "1.3.5"
resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575"
@@ -5793,10 +5837,10 @@
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
-"@yarnpkg/parsers@^3.0.0-rc.18":
- version "3.0.0-rc.31"
- resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.31.tgz#fbcce77c3783b2be8a381edf70bea3182e0b8b16"
- integrity sha512-7M67TPmTM5OmtoypK0KHV3vIY9z0v4qZ6zF7flH8THLgjGuoA7naop8pEfL9x5vCtid1PDC4A4COrcym4WAZpQ==
+"@yarnpkg/parsers@3.0.0-rc.46":
+ version "3.0.0-rc.46"
+ resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01"
+ integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==
dependencies:
js-yaml "^3.10.0"
tslib "^2.4.0"
@@ -5813,7 +5857,7 @@
resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b"
integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==
-JSONStream@^1.0.4, JSONStream@^1.3.4:
+JSONStream@^1.3.4, JSONStream@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==
@@ -6148,7 +6192,7 @@ ansi-styles@^5.0.0:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
-ansi-styles@^6.0.0:
+ansi-styles@^6.0.0, ansi-styles@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
@@ -6308,7 +6352,7 @@ aproba@^1.0.3, aproba@^1.1.1:
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
-"aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0:
+"aproba@^1.0.3 || ^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc"
integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==
@@ -7650,18 +7694,6 @@ bignumber.js@^9.0.0:
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5"
integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==
-bin-links@^3.0.0:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-3.0.3.tgz#3842711ef3db2cd9f16a5f404a996a12db355a6e"
- integrity sha512-zKdnMPWEdh4F5INR07/eBrodC7QrF5JKvqskjz/ZZRXg5YSAZIbn8zGhbhUrElzHBZ2fvEQdOU59RHcTG3GiwA==
- dependencies:
- cmd-shim "^5.0.0"
- mkdirp-infer-owner "^2.0.0"
- npm-normalize-package-bin "^2.0.0"
- read-cmd-shim "^3.0.0"
- rimraf "^3.0.0"
- write-file-atomic "^4.0.0"
-
binary-extensions@^1.0.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
@@ -8554,10 +8586,10 @@ busboy@^1.6.0:
dependencies:
streamsearch "^1.1.0"
-byte-size@7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/byte-size/-/byte-size-7.0.0.tgz#36528cd1ca87d39bd9abd51f5715dc93b6ceb032"
- integrity sha512-NNiBxKgxybMBtWdmvx7ZITJi4ZG+CYUgwOSZTfqB1qogkRHrhbQE/R2r5Fh94X+InN5MCYz6SvB/ejHMj/HbsQ==
+byte-size@8.1.1:
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae"
+ integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==
bytes@1:
version "1.0.0"
@@ -8693,7 +8725,7 @@ cacache@^15.0.4, cacache@^15.0.5, cacache@^15.0.6, cacache@^15.2.0:
tar "^6.0.2"
unique-filename "^1.1.1"
-cacache@^16.0.0, cacache@^16.0.6, cacache@^16.1.0:
+cacache@^16.1.0:
version "16.1.3"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e"
integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==
@@ -8717,6 +8749,24 @@ cacache@^16.0.0, cacache@^16.0.6, cacache@^16.1.0:
tar "^6.1.11"
unique-filename "^2.0.0"
+cacache@^17.0.0:
+ version "17.1.3"
+ resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.3.tgz#c6ac23bec56516a7c0c52020fd48b4909d7c7044"
+ integrity sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==
+ dependencies:
+ "@npmcli/fs" "^3.1.0"
+ fs-minipass "^3.0.0"
+ glob "^10.2.2"
+ lru-cache "^7.7.1"
+ minipass "^5.0.0"
+ minipass-collect "^1.0.2"
+ minipass-flush "^1.0.5"
+ minipass-pipeline "^1.2.4"
+ p-map "^4.0.0"
+ ssri "^10.0.0"
+ tar "^6.1.11"
+ unique-filename "^3.0.0"
+
cache-base@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
@@ -9064,6 +9114,11 @@ ci-info@^3.2.0, ci-info@^3.3.2, ci-info@^3.4.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f"
integrity sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==
+ci-info@^3.6.1:
+ version "3.8.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91"
+ integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==
+
ci-job-number@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/ci-job-number/-/ci-job-number-1.2.2.tgz#f4e5918fcaeeda95b604f214be7d7d4a961fe0c0"
@@ -9266,12 +9321,10 @@ clone@^2.1.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
-cmd-shim@5.0.0, cmd-shim@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-5.0.0.tgz#8d0aaa1a6b0708630694c4dbde070ed94c707724"
- integrity sha512-qkCtZ59BidfEwHltnJwkyVZn+XQojdAySM1D1gSeh11Z4pW1Kpolkyo53L5noc0nrxmIvyFwTmJRo4xs7FFLPw==
- dependencies:
- mkdirp-infer-owner "^2.0.0"
+cmd-shim@6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d"
+ integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==
co@^4.6.0:
version "4.6.0"
@@ -9477,11 +9530,6 @@ commenting@1.1.0:
resolved "https://registry.yarnpkg.com/commenting/-/commenting-1.1.0.tgz#fae14345c6437b8554f30bc6aa6c1e1633033590"
integrity sha512-YeNK4tavZwtH7jEgK1ZINXzLKm6DZdEMfsaaieOsCAN0S8vsY7UeuO3Q7d/M018EFgE+IeUAuBOKkFccBZsUZA==
-common-ancestor-path@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7"
- integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==
-
common-tags@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
@@ -9557,14 +9605,6 @@ concat-stream@^2.0.0:
readable-stream "^3.0.2"
typedarray "^0.0.6"
-config-chain@1.1.12:
- version "1.1.12"
- resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
- integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
- dependencies:
- ini "^1.3.4"
- proto-list "~1.2.1"
-
configstore@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96"
@@ -9647,87 +9687,78 @@ continuable-cache@^0.3.1:
resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f"
integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=
-conventional-changelog-angular@5.0.12:
- version "5.0.12"
- resolved "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz#c979b8b921cbfe26402eb3da5bbfda02d865a2b9"
- integrity sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==
+conventional-changelog-angular@6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz#a9a9494c28b7165889144fd5b91573c4aa9ca541"
+ integrity sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==
dependencies:
compare-func "^2.0.0"
- q "^1.5.1"
-conventional-changelog-core@4.2.4:
- version "4.2.4"
- resolved "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz#e50d047e8ebacf63fac3dc67bf918177001e1e9f"
- integrity sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==
+conventional-changelog-core@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz#3c331b155d5b9850f47b4760aeddfc983a92ad49"
+ integrity sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==
dependencies:
add-stream "^1.0.0"
- conventional-changelog-writer "^5.0.0"
- conventional-commits-parser "^3.2.0"
- dateformat "^3.0.0"
- get-pkg-repo "^4.0.0"
- git-raw-commits "^2.0.8"
+ conventional-changelog-writer "^6.0.0"
+ conventional-commits-parser "^4.0.0"
+ dateformat "^3.0.3"
+ get-pkg-repo "^4.2.1"
+ git-raw-commits "^3.0.0"
git-remote-origin-url "^2.0.0"
- git-semver-tags "^4.1.1"
- lodash "^4.17.15"
- normalize-package-data "^3.0.0"
- q "^1.5.1"
+ git-semver-tags "^5.0.0"
+ normalize-package-data "^3.0.3"
read-pkg "^3.0.0"
read-pkg-up "^3.0.0"
- through2 "^4.0.0"
-conventional-changelog-preset-loader@^2.3.4:
- version "2.3.4"
- resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c"
- integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==
+conventional-changelog-preset-loader@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz#14975ef759d22515d6eabae6396c2ae721d4c105"
+ integrity sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==
-conventional-changelog-writer@^5.0.0:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz#e0757072f045fe03d91da6343c843029e702f359"
- integrity sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==
+conventional-changelog-writer@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-6.0.0.tgz#8c8dea0441c6e648c9b25bb784e750d02f8002d5"
+ integrity sha512-8PyWTnn7zBIt9l4hj4UusFs1TyG+9Ulu1zlOAc72L7Sdv9Hsc8E86ot7htY3HXCVhXHB/NO0pVGvZpwsyJvFfw==
dependencies:
- conventional-commits-filter "^2.0.7"
- dateformat "^3.0.0"
+ conventional-commits-filter "^3.0.0"
+ dateformat "^3.0.3"
handlebars "^4.7.7"
json-stringify-safe "^5.0.1"
- lodash "^4.17.15"
- meow "^8.0.0"
- semver "^6.0.0"
- split "^1.0.0"
- through2 "^4.0.0"
+ meow "^8.1.2"
+ semver "^6.3.0"
+ split "^1.0.1"
-conventional-commits-filter@^2.0.7:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz#f8d9b4f182fce00c9af7139da49365b136c8a0b3"
- integrity sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==
+conventional-commits-filter@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz#bf1113266151dd64c49cd269e3eb7d71d7015ee2"
+ integrity sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==
dependencies:
lodash.ismatch "^4.4.0"
- modify-values "^1.0.0"
+ modify-values "^1.0.1"
-conventional-commits-parser@^3.2.0:
- version "3.2.4"
- resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz#a7d3b77758a202a9b2293d2112a8d8052c740972"
- integrity sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==
+conventional-commits-parser@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz#02ae1178a381304839bce7cea9da5f1b549ae505"
+ integrity sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==
dependencies:
- JSONStream "^1.0.4"
+ JSONStream "^1.3.5"
is-text-path "^1.0.1"
- lodash "^4.17.15"
- meow "^8.0.0"
- split2 "^3.0.0"
- through2 "^4.0.0"
+ meow "^8.1.2"
+ split2 "^3.2.2"
-conventional-recommended-bump@6.1.0:
- version "6.1.0"
- resolved "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz#cfa623285d1de554012f2ffde70d9c8a22231f55"
- integrity sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==
+conventional-recommended-bump@7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz#ec01f6c7f5d0e2491c2d89488b0d757393392424"
+ integrity sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==
dependencies:
concat-stream "^2.0.0"
- conventional-changelog-preset-loader "^2.3.4"
- conventional-commits-filter "^2.0.7"
- conventional-commits-parser "^3.2.0"
- git-raw-commits "^2.0.8"
- git-semver-tags "^4.1.1"
- meow "^8.0.0"
- q "^1.5.1"
+ conventional-changelog-preset-loader "^3.0.0"
+ conventional-commits-filter "^3.0.0"
+ conventional-commits-parser "^4.0.0"
+ git-raw-commits "^3.0.0"
+ git-semver-tags "^5.0.0"
+ meow "^8.1.2"
convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.7.0"
@@ -9879,17 +9910,6 @@ cors@^2.8.5, cors@~2.8.5:
object-assign "^4"
vary "^1"
-cosmiconfig@7.0.0:
- version "7.0.0"
- resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3"
- integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==
- dependencies:
- "@types/parse-json" "^4.0.0"
- import-fresh "^3.2.1"
- parse-json "^5.0.0"
- path-type "^4.0.0"
- yaml "^1.10.0"
-
cosmiconfig@^5.0.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
@@ -9911,6 +9931,16 @@ cosmiconfig@^7.0.0:
path-type "^4.0.0"
yaml "^1.10.0"
+cosmiconfig@^8.2.0:
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.2.0.tgz#f7d17c56a590856cd1e7cee98734dca272b0d8fd"
+ integrity sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==
+ dependencies:
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.0"
+ parse-json "^5.0.0"
+ path-type "^4.0.0"
+
create-ecdh@^4.0.0:
version "4.0.4"
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
@@ -10493,7 +10523,7 @@ dateformat@^1.0.6:
get-stdin "^4.0.1"
meow "^3.3.0"
-dateformat@^3.0.0:
+dateformat@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
@@ -10919,6 +10949,11 @@ diff-sequences@^27.5.1:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327"
integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==
+diff-sequences@^29.4.3:
+ version "29.4.3"
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2"
+ integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==
+
diff@3.5.0, diff@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
@@ -11104,13 +11139,6 @@ dot-case@^3.0.4:
no-case "^3.0.4"
tslib "^2.0.3"
-dot-prop@6.0.1:
- version "6.0.1"
- resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083"
- integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==
- dependencies:
- is-obj "^2.0.0"
-
dot-prop@^5.1.0, dot-prop@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
@@ -12051,7 +12079,7 @@ env-paths@^2.2.0:
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
-envinfo@^7.7.4:
+envinfo@7.8.1:
version "7.8.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==
@@ -12652,7 +12680,7 @@ esprima@~3.0.0:
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9"
integrity sha1-U88kes2ncxPlUcOqLnM0LT+099k=
-esquery@^1.0.1, esquery@^1.4.0:
+esquery@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
@@ -13499,6 +13527,14 @@ foreground-child@^2.0.0:
cross-spawn "^7.0.0"
signal-exit "^3.0.2"
+foreground-child@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d"
+ integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==
+ dependencies:
+ cross-spawn "^7.0.0"
+ signal-exit "^4.0.1"
+
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
@@ -13591,16 +13627,6 @@ fs-extra@4.0.2:
jsonfile "^4.0.0"
universalify "^0.1.0"
-fs-extra@9.1.0, fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0:
- version "9.1.0"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
- integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
- dependencies:
- at-least-node "^1.0.0"
- graceful-fs "^4.2.0"
- jsonfile "^6.0.1"
- universalify "^2.0.0"
-
fs-extra@^0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.24.0.tgz#d4e4342a96675cb7846633a6099249332b539952"
@@ -13620,6 +13646,15 @@ fs-extra@^10.0.0, fs-extra@^10.1.0:
jsonfile "^6.0.1"
universalify "^2.0.0"
+fs-extra@^11.1.1:
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d"
+ integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==
+ dependencies:
+ graceful-fs "^4.2.0"
+ jsonfile "^6.0.1"
+ universalify "^2.0.0"
+
fs-extra@^4.0.2, fs-extra@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
@@ -13656,6 +13691,16 @@ fs-extra@^8.0.0, fs-extra@^8.0.1, fs-extra@^8.1.0:
jsonfile "^4.0.0"
universalify "^0.1.0"
+fs-extra@^9.0.0, fs-extra@^9.0.1, fs-extra@^9.1.0:
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
+ integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
+ dependencies:
+ at-least-node "^1.0.0"
+ graceful-fs "^4.2.0"
+ jsonfile "^6.0.1"
+ universalify "^2.0.0"
+
fs-merger@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/fs-merger/-/fs-merger-3.2.1.tgz#a225b11ae530426138294b8fbb19e82e3d4e0b3b"
@@ -13681,6 +13726,13 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0:
dependencies:
minipass "^3.0.0"
+fs-minipass@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.2.tgz#5b383858efa8c1eb8c33b39e994f7e8555b8b3a3"
+ integrity sha512-2GAfyfoaCDRrM6jaOS3UsBts8yJ55VioXdWcOL7dK9zdAuKT71+WBA4ifnNYqVjYv+4SsPxjK0JT4yIIn4cA/g==
+ dependencies:
+ minipass "^5.0.0"
+
fs-monkey@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3"
@@ -13882,7 +13934,7 @@ get-package-type@^0.1.0:
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
-get-pkg-repo@^4.0.0:
+get-pkg-repo@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385"
integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==
@@ -13961,16 +14013,14 @@ git-hooks-list@1.0.3:
resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-1.0.3.tgz#be5baaf78203ce342f2f844a9d2b03dba1b45156"
integrity sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==
-git-raw-commits@^2.0.8:
- version "2.0.11"
- resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723"
- integrity sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==
+git-raw-commits@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-3.0.0.tgz#5432f053a9744f67e8db03dbc48add81252cfdeb"
+ integrity sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==
dependencies:
dargs "^7.0.0"
- lodash "^4.17.15"
- meow "^8.0.0"
- split2 "^3.0.0"
- through2 "^4.0.0"
+ meow "^8.1.2"
+ split2 "^3.2.2"
git-remote-origin-url@^2.0.0:
version "2.0.0"
@@ -13985,13 +14035,13 @@ git-repo-info@^2.1.1:
resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-2.1.1.tgz#220ffed8cbae74ef8a80e3052f2ccb5179aed058"
integrity sha512-8aCohiDo4jwjOwma4FmYFd3i97urZulL8XL24nIPxuE+GZnfsAyy/g2Shqx6OjUiFKUXZM+Yy+KHnOmmA3FVcg==
-git-semver-tags@^4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-4.1.1.tgz#63191bcd809b0ec3e151ba4751c16c444e5b5780"
- integrity sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==
+git-semver-tags@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-5.0.0.tgz#775ff55effae0b50b755448408de6cd56ce293e2"
+ integrity sha512-fZ+tmZ1O5aXW/T5nLzZLbxWAHdQTLLXalOECMNAmhoEQSfqZjtaeMjpsXH4C5qVhrICTkVQeQFujB1lKzIHljA==
dependencies:
- meow "^8.0.0"
- semver "^6.0.0"
+ meow "^8.1.2"
+ semver "^6.3.0"
git-up@^7.0.0:
version "7.0.0"
@@ -14123,6 +14173,17 @@ glob@9.3.2:
minipass "^4.2.4"
path-scurry "^1.6.1"
+glob@^10.2.2:
+ version "10.3.1"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.1.tgz#9789cb1b994515bedb811a6deca735b5c37d2bf4"
+ integrity sha512-9BKYcEeIs7QwlCYs+Y3GBvqAMISufUS0i2ELd11zpZjxI5V9iyRj0HgzB5/cLf2NY4vcYBTYzJ7GIui7j/4DOw==
+ dependencies:
+ foreground-child "^3.1.0"
+ jackspeak "^2.0.3"
+ minimatch "^9.0.1"
+ minipass "^5.0.0 || ^6.0.2"
+ path-scurry "^1.10.0"
+
glob@^5.0.10, glob@^5.0.15:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
@@ -14146,6 +14207,16 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.4, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, gl
once "^1.3.0"
path-is-absolute "^1.0.0"
+glob@^9.2.0:
+ version "9.3.5"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21"
+ integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==
+ dependencies:
+ fs.realpath "^1.0.0"
+ minimatch "^8.0.2"
+ minipass "^4.2.4"
+ path-scurry "^1.6.1"
+
global-dirs@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686"
@@ -14349,7 +14420,12 @@ got@^9.6.0:
to-readable-stream "^1.0.0"
url-parse-lax "^3.0.0"
-graceful-fs@4.2.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+graceful-fs@4.2.11:
+ version "4.2.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
+ integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
+
+graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
@@ -14765,6 +14841,13 @@ hosted-git-info@^5.0.0:
dependencies:
lru-cache "^7.5.1"
+hosted-git-info@^6.0.0:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.1.tgz#629442c7889a69c05de604d52996b74fe6f26d58"
+ integrity sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==
+ dependencies:
+ lru-cache "^7.5.1"
+
hpack.js@^2.1.6:
version "2.1.6"
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
@@ -14858,6 +14941,11 @@ http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0:
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
+http-cache-semantics@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
+ integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==
+
http-deceiver@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@@ -15072,6 +15160,13 @@ ignore-walk@^5.0.1:
dependencies:
minimatch "^5.0.1"
+ignore-walk@^6.0.0:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.3.tgz#0fcdb6decaccda35e308a7b0948645dd9523b7bb"
+ integrity sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==
+ dependencies:
+ minimatch "^9.0.0"
+
ignore@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
@@ -15132,6 +15227,14 @@ import-lazy@^2.1.0:
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==
+import-local@3.1.0, import-local@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4"
+ integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==
+ dependencies:
+ pkg-dir "^4.2.0"
+ resolve-cwd "^3.0.0"
+
import-local@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
@@ -15140,14 +15243,6 @@ import-local@^2.0.0:
pkg-dir "^3.0.0"
resolve-cwd "^2.0.0"
-import-local@^3.0.2:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4"
- integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==
- dependencies:
- pkg-dir "^4.2.0"
- resolve-cwd "^3.0.0"
-
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@@ -15213,23 +15308,23 @@ ini@2.0.0, ini@^2.0.0:
resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5"
integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==
-ini@^1.3.2, ini@^1.3.4, ini@~1.3.0:
+ini@^1.3.2, ini@^1.3.4, ini@^1.3.8, ini@~1.3.0:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-init-package-json@3.0.2, init-package-json@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-3.0.2.tgz#f5bc9bac93f2bdc005778bc2271be642fecfcd69"
- integrity sha512-YhlQPEjNFqlGdzrBfDNRLhvoSgX7iQRgSxgsNknRQ9ITXFT7UMfVMWhBTOh2Y+25lRnGrv5Xz8yZwQ3ACR6T3A==
+init-package-json@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-5.0.0.tgz#030cf0ea9c84cfc1b0dc2e898b45d171393e4b40"
+ integrity sha512-kBhlSheBfYmq3e0L1ii+VKe3zBTLL5lDCDWR+f9dLmEGSB3MqLlMlsolubSsyI88Bg6EA+BIMlomAnQ1SwgQBw==
dependencies:
- npm-package-arg "^9.0.1"
- promzard "^0.3.0"
- read "^1.0.7"
- read-package-json "^5.0.0"
+ npm-package-arg "^10.0.0"
+ promzard "^1.0.0"
+ read "^2.0.0"
+ read-package-json "^6.0.0"
semver "^7.3.5"
validate-npm-package-license "^3.0.4"
- validate-npm-package-name "^4.0.0"
+ validate-npm-package-name "^5.0.0"
injection-js@^2.2.1, injection-js@^2.4.0:
version "2.4.0"
@@ -15481,7 +15576,14 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
-is-ci@2.0.0, is-ci@^2.0.0:
+is-ci@3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867"
+ integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==
+ dependencies:
+ ci-info "^3.2.0"
+
+is-ci@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
@@ -15507,6 +15609,13 @@ is-core-module@^2.2.0, is-core-module@^2.8.1, is-core-module@^2.9.0:
dependencies:
has "^1.0.3"
+is-core-module@^2.5.0:
+ version "2.12.1"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd"
+ integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==
+ dependencies:
+ has "^1.0.3"
+
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@@ -15731,7 +15840,7 @@ is-path-inside@^3.0.2:
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
-is-plain-obj@2.1.0, is-plain-obj@^2.0.0:
+is-plain-obj@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
@@ -16088,6 +16197,15 @@ isurl@^1.0.0-alpha5:
has-to-string-tag-x "^1.2.0"
is-object "^1.0.1"
+jackspeak@^2.0.3:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.2.1.tgz#655e8cf025d872c9c03d3eb63e8f0c024fef16a6"
+ integrity sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==
+ dependencies:
+ "@isaacs/cliui" "^8.0.2"
+ optionalDependencies:
+ "@pkgjs/parseargs" "^0.11.0"
+
jake@^10.8.5:
version "10.8.5"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46"
@@ -16180,6 +16298,16 @@ jest-config@^27.5.1:
slash "^3.0.0"
strip-json-comments "^3.1.1"
+"jest-diff@>=29.4.3 < 30":
+ version "29.5.0"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63"
+ integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==
+ dependencies:
+ chalk "^4.0.0"
+ diff-sequences "^29.4.3"
+ jest-get-type "^29.4.3"
+ pretty-format "^29.5.0"
+
jest-diff@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def"
@@ -16238,6 +16366,11 @@ jest-get-type@^27.5.1:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1"
integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==
+jest-get-type@^29.4.3:
+ version "29.4.3"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5"
+ integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==
+
jest-haste-map@^27.5.1:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f"
@@ -16721,6 +16854,11 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1:
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+json-parse-even-better-errors@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7"
+ integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==
+
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
@@ -16748,11 +16886,6 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
dependencies:
jsonify "~0.0.0"
-json-stringify-nice@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67"
- integrity sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==
-
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
@@ -16851,16 +16984,6 @@ jsprim@^1.2.2:
array-includes "^3.1.2"
object.assign "^4.1.2"
-just-diff-apply@^5.2.0:
- version "5.4.1"
- resolved "https://registry.yarnpkg.com/just-diff-apply/-/just-diff-apply-5.4.1.tgz#1debed059ad009863b4db0e8d8f333d743cdd83b"
- integrity sha512-AAV5Jw7tsniWwih8Ly3fXxEZ06y+6p5TwQMsw0dzZ/wPKilzyDgdAnL0Ug4NNIquPUOh1vfFWEHbmXUqM5+o8g==
-
-just-diff@^5.0.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-5.1.1.tgz#8da6414342a5ed6d02ccd64f5586cbbed3146202"
- integrity sha512-u8HXJ3HlNrTzY7zrYYKjNEfBlyjqhdBkoyTVdjtn7p02RJD5NvR8rIClzeGA7t+UYP1/7eAkWNLU0+P3QrEqKQ==
-
just-extend@^4.0.2:
version "4.1.1"
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.1.tgz#158f1fdb01f128c411dc8b286a7b4837b3545282"
@@ -17167,47 +17290,47 @@ leek@0.0.24:
lodash.assign "^3.2.0"
rsvp "^3.0.21"
-lerna@6.5.0-alpha.2:
- version "6.5.0-alpha.2"
- resolved "https://registry.npmjs.org/lerna/-/lerna-6.5.0-alpha.2.tgz#d7f2f338d7f681feea606ec851795a06d008b282"
- integrity sha512-RTLl8XreCn05ja47EYvs2OOz89IZrKw0/DpSkavw/wC0jDoXosjqUNNcdYaEIAYafD3w5k9We2/GtpIIyBftOQ==
+lerna@7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.1.1.tgz#6703062e6c4ddefdaf41e8890e9200690924fd71"
+ integrity sha512-rjivAl3bYu2+lWOi90vy0tYFgwBYPMiNkR/DuEWZC08wle5dsbOZ/SlXeLk9+kzbF89Bt5P6p+qF78A2tJsWPA==
dependencies:
- "@lerna/child-process" "6.5.0-alpha.2"
- "@lerna/create" "6.5.0-alpha.2"
- "@npmcli/arborist" "5.3.0"
- "@npmcli/run-script" "4.1.7"
- "@nrwl/devkit" ">=15.5.2 < 16"
+ "@lerna/child-process" "7.1.1"
+ "@lerna/create" "7.1.1"
+ "@npmcli/run-script" "6.0.2"
+ "@nx/devkit" ">=16.1.3 < 17"
"@octokit/plugin-enterprise-rest" "6.0.1"
- "@octokit/rest" "19.0.3"
- byte-size "7.0.0"
+ "@octokit/rest" "19.0.11"
+ byte-size "8.1.1"
chalk "4.1.0"
clone-deep "4.0.1"
- cmd-shim "5.0.0"
+ cmd-shim "6.0.1"
columnify "1.6.0"
- config-chain "1.1.12"
- conventional-changelog-angular "5.0.12"
- conventional-changelog-core "4.2.4"
- conventional-recommended-bump "6.1.0"
- cosmiconfig "7.0.0"
+ conventional-changelog-angular "6.0.0"
+ conventional-changelog-core "5.0.1"
+ conventional-recommended-bump "7.0.1"
+ cosmiconfig "^8.2.0"
dedent "0.7.0"
- dot-prop "6.0.1"
- envinfo "^7.7.4"
+ envinfo "7.8.1"
execa "5.0.0"
- fs-extra "9.1.0"
+ fs-extra "^11.1.1"
get-port "5.1.1"
get-stream "6.0.0"
git-url-parse "13.1.0"
glob-parent "5.1.2"
globby "11.1.0"
- graceful-fs "4.2.10"
+ graceful-fs "4.2.11"
has-unicode "2.0.1"
- import-local "^3.0.2"
- init-package-json "3.0.2"
+ import-local "3.1.0"
+ ini "^1.3.8"
+ init-package-json "5.0.0"
inquirer "^8.2.4"
- is-ci "2.0.0"
+ is-ci "3.0.1"
is-stream "2.0.0"
- libnpmaccess "6.0.3"
- libnpmpublish "6.0.4"
+ jest-diff ">=29.4.3 < 30"
+ js-yaml "4.1.0"
+ libnpmaccess "7.0.2"
+ libnpmpublish "7.3.0"
load-json-file "6.2.0"
make-dir "3.1.0"
minimatch "3.0.5"
@@ -17215,36 +17338,34 @@ lerna@6.5.0-alpha.2:
node-fetch "2.6.7"
npm-package-arg "8.1.1"
npm-packlist "5.1.1"
- npm-registry-fetch "13.3.0"
+ npm-registry-fetch "^14.0.5"
npmlog "^6.0.2"
- nx ">=15.5.2 < 16"
+ nx ">=16.1.3 < 17"
p-map "4.0.0"
p-map-series "2.1.0"
p-pipe "3.1.0"
p-queue "6.6.2"
p-reduce "2.1.0"
p-waterfall "2.1.1"
- pacote "13.6.1"
- path-exists "4.0.0"
+ pacote "^15.2.0"
pify "5.0.0"
- read-cmd-shim "3.0.0"
- read-package-json "5.0.1"
+ read-cmd-shim "4.0.0"
+ read-package-json "6.0.4"
resolve-from "5.0.0"
- rimraf "^3.0.2"
- semver "7.3.4"
+ rimraf "^4.4.1"
+ semver "^7.3.8"
signal-exit "3.0.7"
slash "3.0.0"
- ssri "9.0.1"
+ ssri "^9.0.1"
strong-log-transformer "2.1.0"
tar "6.1.11"
temp-dir "1.0.0"
- typescript "^3 || ^4"
- upath "^2.0.1"
- uuid "8.3.2"
+ typescript ">=3 < 6"
+ upath "2.0.1"
+ uuid "^9.0.0"
validate-npm-package-license "3.0.4"
- validate-npm-package-name "4.0.0"
- write-file-atomic "4.0.1"
- write-json-file "4.3.0"
+ validate-npm-package-name "5.0.0"
+ write-file-atomic "5.0.1"
write-pkg "4.0.0"
yargs "16.2.0"
yargs-parser "20.2.4"
@@ -17344,26 +17465,27 @@ levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-libnpmaccess@6.0.3:
- version "6.0.3"
- resolved "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-6.0.3.tgz#473cc3e4aadb2bc713419d92e45d23b070d8cded"
- integrity sha512-4tkfUZprwvih2VUZYMozL7EMKgQ5q9VW2NtRyxWtQWlkLTAWHRklcAvBN49CVqEkhUw7vTX2fNgB5LzgUucgYg==
- dependencies:
- aproba "^2.0.0"
- minipass "^3.1.1"
- npm-package-arg "^9.0.1"
- npm-registry-fetch "^13.0.0"
-
-libnpmpublish@6.0.4:
- version "6.0.4"
- resolved "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-6.0.4.tgz#adb41ec6b0c307d6f603746a4d929dcefb8f1a0b"
- integrity sha512-lvAEYW8mB8QblL6Q/PI/wMzKNvIrF7Kpujf/4fGS/32a2i3jzUXi04TNyIBcK6dQJ34IgywfaKGh+Jq4HYPFmg==
- dependencies:
- normalize-package-data "^4.0.0"
- npm-package-arg "^9.0.1"
- npm-registry-fetch "^13.0.0"
+libnpmaccess@7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-7.0.2.tgz#7f056c8c933dd9c8ba771fa6493556b53c5aac52"
+ integrity sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw==
+ dependencies:
+ npm-package-arg "^10.1.0"
+ npm-registry-fetch "^14.0.3"
+
+libnpmpublish@7.3.0:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.3.0.tgz#2ceb2b36866d75a6cd7b4aa748808169f4d17e37"
+ integrity sha512-fHUxw5VJhZCNSls0KLNEG0mCD2PN1i14gH5elGOgiVnU3VgTcRahagYP2LKI1m0tFCJ+XrAm0zVYyF5RCbXzcg==
+ dependencies:
+ ci-info "^3.6.1"
+ normalize-package-data "^5.0.0"
+ npm-package-arg "^10.1.0"
+ npm-registry-fetch "^14.0.3"
+ proc-log "^3.0.0"
semver "^7.3.7"
- ssri "^9.0.0"
+ sigstore "^1.4.0"
+ ssri "^10.0.1"
license-webpack-plugin@2.3.0:
version "2.3.0"
@@ -17929,6 +18051,11 @@ lru-cache@^9.0.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.0.1.tgz#ac061ed291f8b9adaca2b085534bb1d3b61bef83"
integrity sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==
+"lru-cache@^9.1.1 || ^10.0.0":
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61"
+ integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==
+
lru_map@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd"
@@ -18036,7 +18163,7 @@ make-error@1.x, make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
-make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.6:
+make-fetch-happen@^10.0.3:
version "10.2.1"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164"
integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==
@@ -18058,6 +18185,27 @@ make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.6:
socks-proxy-agent "^7.0.0"
ssri "^9.0.0"
+make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1:
+ version "11.1.1"
+ resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f"
+ integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==
+ dependencies:
+ agentkeepalive "^4.2.1"
+ cacache "^17.0.0"
+ http-cache-semantics "^4.1.1"
+ http-proxy-agent "^5.0.0"
+ https-proxy-agent "^5.0.0"
+ is-lambda "^1.0.1"
+ lru-cache "^7.7.1"
+ minipass "^5.0.0"
+ minipass-fetch "^3.0.0"
+ minipass-flush "^1.0.5"
+ minipass-pipeline "^1.2.4"
+ negotiator "^0.6.3"
+ promise-retry "^2.0.1"
+ socks-proxy-agent "^7.0.0"
+ ssri "^10.0.0"
+
make-fetch-happen@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd"
@@ -18294,7 +18442,7 @@ meow@^3.3.0:
redent "^1.0.0"
trim-newlines "^1.0.0"
-meow@^8.0.0:
+meow@^8.1.2:
version "8.1.2"
resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897"
integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==
@@ -18507,6 +18655,20 @@ minimatch@^7.4.1:
dependencies:
brace-expansion "^2.0.1"
+minimatch@^8.0.2:
+ version "8.0.4"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229"
+ integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==
+ dependencies:
+ brace-expansion "^2.0.1"
+
+minimatch@^9.0.0, minimatch@^9.0.1:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.2.tgz#397e387fff22f6795844d00badc903a3d5de7057"
+ integrity sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==
+ dependencies:
+ brace-expansion "^2.0.1"
+
minimatch@~3.0.4:
version "3.0.8"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1"
@@ -18567,6 +18729,17 @@ minipass-fetch@^2.0.3:
optionalDependencies:
encoding "^0.1.13"
+minipass-fetch@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.3.tgz#d9df70085609864331b533c960fd4ffaa78d15ce"
+ integrity sha512-n5ITsTkDqYkYJZjcRWzZt9qnZKCT7nKCosJhHoj7S7zD+BP4jVbWs+odsniw5TA3E0sLomhTKOKjF86wf11PuQ==
+ dependencies:
+ minipass "^5.0.0"
+ minipass-sized "^1.0.3"
+ minizlib "^2.1.2"
+ optionalDependencies:
+ encoding "^0.1.13"
+
minipass-flush@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373"
@@ -18626,6 +18799,11 @@ minipass@^5.0.0:
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
+"minipass@^5.0.0 || ^6.0.2":
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/minipass/-/minipass-6.0.2.tgz#542844b6c4ce95b202c0995b0a471f1229de4c81"
+ integrity sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==
+
minizlib@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
@@ -18670,15 +18848,6 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
-mkdirp-infer-owner@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316"
- integrity sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==
- dependencies:
- chownr "^2.0.0"
- infer-owner "^1.0.4"
- mkdirp "^1.0.3"
-
mkdirp@0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.4.tgz#fd01504a6797ec5c9be81ff43d204961ed64a512"
@@ -18742,7 +18911,7 @@ mocha@^6.1.4, mocha@^6.2.0:
yargs-parser "13.1.2"
yargs-unparser "1.6.0"
-modify-values@^1.0.0:
+modify-values@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
@@ -18908,11 +19077,16 @@ mute-stream@0.0.7:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
-mute-stream@0.0.8, mute-stream@~0.0.4:
+mute-stream@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
+mute-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e"
+ integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==
+
mysql@^2.18.1:
version "2.18.1"
resolved "https://registry.yarnpkg.com/mysql/-/mysql-2.18.1.tgz#2254143855c5a8c73825e4522baf2ea021766717"
@@ -19451,12 +19625,22 @@ normalize-package-data@^3.0.0:
semver "^7.3.4"
validate-npm-package-license "^3.0.1"
-normalize-package-data@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-4.0.1.tgz#b46b24e0616d06cadf9d5718b29b6d445a82a62c"
- integrity sha512-EBk5QKKuocMJhB3BILuKhmaPjI8vNRSpIfO9woLC6NyHVkKKdVEdAO1mrT0ZfxNR1lKwCcTkuZfmGIFdizZ8Pg==
+normalize-package-data@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e"
+ integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==
dependencies:
- hosted-git-info "^5.0.0"
+ hosted-git-info "^4.0.1"
+ is-core-module "^2.5.0"
+ semver "^7.3.4"
+ validate-npm-package-license "^3.0.1"
+
+normalize-package-data@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz#abcb8d7e724c40d88462b84982f7cbf6859b4588"
+ integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==
+ dependencies:
+ hosted-git-info "^6.0.0"
is-core-module "^2.8.1"
semver "^7.3.5"
validate-npm-package-license "^3.0.4"
@@ -19526,12 +19710,12 @@ npm-bundled@^1.1.2:
dependencies:
npm-normalize-package-bin "^1.0.1"
-npm-bundled@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-2.0.1.tgz#94113f7eb342cd7a67de1e789f896b04d2c600f4"
- integrity sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw==
+npm-bundled@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7"
+ integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==
dependencies:
- npm-normalize-package-bin "^2.0.0"
+ npm-normalize-package-bin "^3.0.0"
npm-install-checks@^4.0.0:
version "4.0.0"
@@ -19540,10 +19724,10 @@ npm-install-checks@^4.0.0:
dependencies:
semver "^7.1.1"
-npm-install-checks@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-5.0.0.tgz#5ff27d209a4e3542b8ac6b0c1db6063506248234"
- integrity sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA==
+npm-install-checks@^6.0.0:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.1.1.tgz#b459b621634d06546664207fde16810815808db1"
+ integrity sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw==
dependencies:
semver "^7.1.1"
@@ -19552,10 +19736,10 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1:
resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
-npm-normalize-package-bin@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz#9447a1adaaf89d8ad0abe24c6c84ad614a675fff"
- integrity sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==
+npm-normalize-package-bin@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832"
+ integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==
npm-package-arg@8.0.1:
version "8.0.1"
@@ -19584,6 +19768,16 @@ npm-package-arg@8.1.5, npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-packa
semver "^7.3.4"
validate-npm-package-name "^3.0.0"
+npm-package-arg@^10.0.0, npm-package-arg@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-10.1.0.tgz#827d1260a683806685d17193073cc152d3c7e9b1"
+ integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==
+ dependencies:
+ hosted-git-info "^6.0.0"
+ proc-log "^3.0.0"
+ semver "^7.3.5"
+ validate-npm-package-name "^5.0.0"
+
npm-package-arg@^6.0.0, npm-package-arg@^6.1.0:
version "6.1.1"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7"
@@ -19594,7 +19788,7 @@ npm-package-arg@^6.0.0, npm-package-arg@^6.1.0:
semver "^5.6.0"
validate-npm-package-name "^3.0.0"
-npm-package-arg@^9.0.0, npm-package-arg@^9.0.1, npm-package-arg@^9.1.0:
+npm-package-arg@^9.1.0:
version "9.1.2"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz#fc8acecb00235f42270dda446f36926ddd9ac2bc"
integrity sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==
@@ -19653,15 +19847,12 @@ npm-packlist@^3.0.0:
npm-bundled "^1.1.1"
npm-normalize-package-bin "^1.0.1"
-npm-packlist@^5.1.0:
- version "5.1.3"
- resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.3.tgz#69d253e6fd664b9058b85005905012e00e69274b"
- integrity sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg==
+npm-packlist@^7.0.0:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32"
+ integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==
dependencies:
- glob "^8.0.1"
- ignore-walk "^5.0.1"
- npm-bundled "^2.0.0"
- npm-normalize-package-bin "^2.0.0"
+ ignore-walk "^6.0.0"
npm-pick-manifest@6.1.0:
version "6.1.0"
@@ -19691,29 +19882,16 @@ npm-pick-manifest@^3.0.0:
npm-package-arg "^6.0.0"
semver "^5.4.1"
-npm-pick-manifest@^7.0.0:
- version "7.0.2"
- resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-7.0.2.tgz#1d372b4e7ea7c6712316c0e99388a73ed3496e84"
- integrity sha512-gk37SyRmlIjvTfcYl6RzDbSmS9Y4TOBXfsPnoYqTHARNgWbyDiCSMLUpmALDj4jjcTZpURiEfsSHJj9k7EV4Rw==
+npm-pick-manifest@^8.0.0:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz#c6acd97d1ad4c5dbb80eac7b386b03ffeb289e5f"
+ integrity sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==
dependencies:
- npm-install-checks "^5.0.0"
- npm-normalize-package-bin "^2.0.0"
- npm-package-arg "^9.0.0"
+ npm-install-checks "^6.0.0"
+ npm-normalize-package-bin "^3.0.0"
+ npm-package-arg "^10.0.0"
semver "^7.3.5"
-npm-registry-fetch@13.3.0:
- version "13.3.0"
- resolved "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-13.3.0.tgz#0ce10fa4a699a1e70685ecf41bbfb4150d74231b"
- integrity sha512-10LJQ/1+VhKrZjIuY9I/+gQTvumqqlgnsCufoXETHAPFTS3+M+Z5CFhZRDHGavmJ6rOye3UvNga88vl8n1r6gg==
- dependencies:
- make-fetch-happen "^10.0.6"
- minipass "^3.1.6"
- minipass-fetch "^2.0.3"
- minipass-json-stream "^1.0.1"
- minizlib "^2.1.2"
- npm-package-arg "^9.0.1"
- proc-log "^2.0.0"
-
npm-registry-fetch@^11.0.0:
version "11.0.0"
resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz#68c1bb810c46542760d62a6a965f85a702d43a76"
@@ -19726,18 +19904,18 @@ npm-registry-fetch@^11.0.0:
minizlib "^2.0.0"
npm-package-arg "^8.0.0"
-npm-registry-fetch@^13.0.0, npm-registry-fetch@^13.0.1:
- version "13.3.1"
- resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz#bb078b5fa6c52774116ae501ba1af2a33166af7e"
- integrity sha512-eukJPi++DKRTjSBRcDZSDDsGqRK3ehbxfFUcgaRd0Yp6kRwOwh2WVn0r+8rMB4nnuzvAk6rQVzl6K5CkYOmnvw==
+npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5:
+ version "14.0.5"
+ resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d"
+ integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==
dependencies:
- make-fetch-happen "^10.0.6"
- minipass "^3.1.6"
- minipass-fetch "^2.0.3"
+ make-fetch-happen "^11.0.0"
+ minipass "^5.0.0"
+ minipass-fetch "^3.0.0"
minipass-json-stream "^1.0.1"
minizlib "^2.1.2"
- npm-package-arg "^9.0.1"
- proc-log "^2.0.0"
+ npm-package-arg "^10.0.0"
+ proc-log "^3.0.0"
npm-registry-fetch@^4.0.0:
version "4.0.7"
@@ -19842,16 +20020,15 @@ nwsapi@^2.2.0:
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
-nx@15.6.3, "nx@>=15.5.2 < 16":
- version "15.6.3"
- resolved "https://registry.npmjs.org/nx/-/nx-15.6.3.tgz#900087bce38c6e5975660c23ebd41ead1bf54f98"
- integrity sha512-3t0A0GPLNen1yPAyE+VGZ3nkAzZYb5nfXtAcx8SHBlKq4u42yBY3khBmP1y4Og3jhIwFIj7J7Npeh8ZKrthmYQ==
+nx@16.4.1, "nx@>=16.1.3 < 17":
+ version "16.4.1"
+ resolved "https://registry.yarnpkg.com/nx/-/nx-16.4.1.tgz#3a8a58f78d6fbf2264639d401278ee16140d0b11"
+ integrity sha512-om1v2xu+e4/ibQ4PgnFfemwnfS4e9Biss3R0lx1d8GmaVRIJ/o4Ng0c6F5Uw9l/WMc0DyAnGBthKyrVAlHPs1A==
dependencies:
- "@nrwl/cli" "15.6.3"
- "@nrwl/tao" "15.6.3"
+ "@nrwl/tao" "16.4.1"
"@parcel/watcher" "2.0.4"
"@yarnpkg/lockfile" "^1.1.0"
- "@yarnpkg/parsers" "^3.0.0-rc.18"
+ "@yarnpkg/parsers" "3.0.0-rc.46"
"@zkochan/js-yaml" "0.0.6"
axios "^1.0.0"
chalk "^4.1.0"
@@ -19872,7 +20049,7 @@ nx@15.6.3, "nx@>=15.5.2 < 16":
minimatch "3.0.5"
npm-run-path "^4.0.1"
open "^8.4.0"
- semver "7.3.4"
+ semver "7.5.3"
string-width "^4.2.3"
strong-log-transformer "^2.1.0"
tar-stream "~2.2.0"
@@ -19882,6 +20059,17 @@ nx@15.6.3, "nx@>=15.5.2 < 16":
v8-compile-cache "2.3.0"
yargs "^17.6.2"
yargs-parser "21.1.1"
+ optionalDependencies:
+ "@nx/nx-darwin-arm64" "16.4.1"
+ "@nx/nx-darwin-x64" "16.4.1"
+ "@nx/nx-freebsd-x64" "16.4.1"
+ "@nx/nx-linux-arm-gnueabihf" "16.4.1"
+ "@nx/nx-linux-arm64-gnu" "16.4.1"
+ "@nx/nx-linux-arm64-musl" "16.4.1"
+ "@nx/nx-linux-x64-gnu" "16.4.1"
+ "@nx/nx-linux-x64-musl" "16.4.1"
+ "@nx/nx-win32-arm64-msvc" "16.4.1"
+ "@nx/nx-win32-x64-msvc" "16.4.1"
oauth-sign@~0.9.0:
version "0.9.0"
@@ -20431,33 +20619,6 @@ pacote@12.0.2:
ssri "^8.0.1"
tar "^6.1.0"
-pacote@13.6.1:
- version "13.6.1"
- resolved "https://registry.npmjs.org/pacote/-/pacote-13.6.1.tgz#ac6cbd9032b4c16e5c1e0c60138dfe44e4cc589d"
- integrity sha512-L+2BI1ougAPsFjXRyBhcKmfT016NscRFLv6Pz5EiNf1CCFJFU0pSKKQwsZTyAQB+sTuUL4TyFyp6J1Ork3dOqw==
- dependencies:
- "@npmcli/git" "^3.0.0"
- "@npmcli/installed-package-contents" "^1.0.7"
- "@npmcli/promise-spawn" "^3.0.0"
- "@npmcli/run-script" "^4.1.0"
- cacache "^16.0.0"
- chownr "^2.0.0"
- fs-minipass "^2.1.0"
- infer-owner "^1.0.4"
- minipass "^3.1.6"
- mkdirp "^1.0.4"
- npm-package-arg "^9.0.0"
- npm-packlist "^5.1.0"
- npm-pick-manifest "^7.0.0"
- npm-registry-fetch "^13.0.1"
- proc-log "^2.0.0"
- promise-retry "^2.0.1"
- read-package-json "^5.0.0"
- read-package-json-fast "^2.0.3"
- rimraf "^3.0.2"
- ssri "^9.0.0"
- tar "^6.1.11"
-
pacote@9.5.12:
version "9.5.12"
resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66"
@@ -20494,31 +20655,28 @@ pacote@9.5.12:
unique-filename "^1.1.1"
which "^1.3.1"
-pacote@^13.0.3, pacote@^13.6.1:
- version "13.6.2"
- resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.6.2.tgz#0d444ba3618ab3e5cd330b451c22967bbd0ca48a"
- integrity sha512-Gu8fU3GsvOPkak2CkbojR7vjs3k3P9cA6uazKTHdsdV0gpCEQq2opelnEv30KRQWgVzP5Vd/5umjcedma3MKtg==
- dependencies:
- "@npmcli/git" "^3.0.0"
- "@npmcli/installed-package-contents" "^1.0.7"
- "@npmcli/promise-spawn" "^3.0.0"
- "@npmcli/run-script" "^4.1.0"
- cacache "^16.0.0"
- chownr "^2.0.0"
- fs-minipass "^2.1.0"
- infer-owner "^1.0.4"
- minipass "^3.1.6"
- mkdirp "^1.0.4"
- npm-package-arg "^9.0.0"
- npm-packlist "^5.1.0"
- npm-pick-manifest "^7.0.0"
- npm-registry-fetch "^13.0.1"
- proc-log "^2.0.0"
+pacote@^15.2.0:
+ version "15.2.0"
+ resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3"
+ integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==
+ dependencies:
+ "@npmcli/git" "^4.0.0"
+ "@npmcli/installed-package-contents" "^2.0.1"
+ "@npmcli/promise-spawn" "^6.0.1"
+ "@npmcli/run-script" "^6.0.0"
+ cacache "^17.0.0"
+ fs-minipass "^3.0.0"
+ minipass "^5.0.0"
+ npm-package-arg "^10.0.0"
+ npm-packlist "^7.0.0"
+ npm-pick-manifest "^8.0.0"
+ npm-registry-fetch "^14.0.0"
+ proc-log "^3.0.0"
promise-retry "^2.0.1"
- read-package-json "^5.0.0"
- read-package-json-fast "^2.0.3"
- rimraf "^3.0.2"
- ssri "^9.0.0"
+ read-package-json "^6.0.0"
+ read-package-json-fast "^3.0.0"
+ sigstore "^1.3.0"
+ ssri "^10.0.0"
tar "^6.1.11"
pad@^3.2.0:
@@ -20573,15 +20731,6 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5:
pbkdf2 "^3.0.3"
safe-buffer "^5.1.1"
-parse-conflict-json@^2.0.1:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/parse-conflict-json/-/parse-conflict-json-2.0.2.tgz#3d05bc8ffe07d39600dc6436c6aefe382033d323"
- integrity sha512-jDbRGb00TAPFsKWCpZZOT93SxVP9nONOSgES3AevqRq/CHvavEBvKAjxX9p5Y5F0RZLxH9Ufd9+RwtCsa+lFDA==
- dependencies:
- json-parse-even-better-errors "^2.3.1"
- just-diff "^5.0.1"
- just-diff-apply "^5.2.0"
-
parse-json@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
@@ -20701,11 +20850,6 @@ path-dirname@^1.0.0:
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=
-path-exists@4.0.0, path-exists@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
- integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
-
path-exists@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
@@ -20718,6 +20862,11 @@ path-exists@^3.0.0:
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
path-exists@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7"
@@ -20765,6 +20914,14 @@ path-root@^0.1.1:
dependencies:
path-root-regex "^0.1.0"
+path-scurry@^1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.0.tgz#0ffbd4c1f7de9600f98a1405507d9f9acb438ab3"
+ integrity sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g==
+ dependencies:
+ lru-cache "^9.1.1 || ^10.0.0"
+ minipass "^5.0.0 || ^6.0.2"
+
path-scurry@^1.6.1:
version "1.6.4"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.6.4.tgz#020a9449e5382a4acb684f9c7e1283bc5695de66"
@@ -20927,7 +21084,7 @@ pidtree@^0.3.0:
resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a"
integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==
-pify@5.0.0, pify@^5.0.0:
+pify@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f"
integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==
@@ -22158,6 +22315,15 @@ pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1:
ansi-styles "^5.0.0"
react-is "^17.0.1"
+pretty-format@^29.5.0:
+ version "29.5.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a"
+ integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==
+ dependencies:
+ "@jest/schemas" "^29.4.3"
+ ansi-styles "^5.0.0"
+ react-is "^18.0.0"
+
pretty-ms@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-7.0.1.tgz#7d903eaab281f7d8e03c66f867e239dc32fb73e8"
@@ -22175,11 +22341,16 @@ private@^0.1.6, private@^0.1.8:
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
-proc-log@^2.0.0, proc-log@^2.0.1:
+proc-log@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-2.0.1.tgz#8f3f69a1f608de27878f91f5c688b225391cb685"
integrity sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==
+proc-log@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8"
+ integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -22202,16 +22373,6 @@ progress@^2.0.0, progress@^2.0.3:
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-promise-all-reject-late@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2"
- integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==
-
-promise-call-limit@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.1.tgz#4bdee03aeb85674385ca934da7114e9bcd3c6e24"
- integrity sha512-3+hgaa19jzCGLuSCbieeRsu5C2joKfYn8pY6JAuXFRVfF4IO+L7UPpFWNTeWT9pM7uhskvbPPd/oEOktCn317Q==
-
promise-inflight@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
@@ -22265,12 +22426,12 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"
-promzard@^0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee"
- integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=
+promzard@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.0.tgz#3246f8e6c9895a77c0549cefb65828ac0f6c006b"
+ integrity sha512-KQVDEubSUHGSt5xLakaToDFrSoZhStB8dXLzk2xvwR67gJktrHFvpR63oZgHyK19WKbHFLXJqCPXdVR3aBP8Ig==
dependencies:
- read "1"
+ read "^2.0.0"
prop-types@15.7.2:
version "15.7.2"
@@ -22304,11 +22465,6 @@ proper-lockfile@^4.1.2:
retry "^0.12.0"
signal-exit "^3.0.2"
-proto-list@~1.2.1:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
- integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
-
protobufjs@^6.10.2, protobufjs@^6.8.6:
version "6.11.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74"
@@ -22434,7 +22590,7 @@ pupa@^2.1.1:
dependencies:
escape-goat "^2.0.0"
-q@^1.1.2, q@^1.5.1, q@~1.5.0:
+q@^1.1.2, q@~1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
@@ -22622,6 +22778,11 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+react-is@^18.0.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
+ integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
+
react-refresh@0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
@@ -22706,17 +22867,12 @@ read-cache@^1.0.0:
dependencies:
pify "^2.3.0"
-read-cmd-shim@3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-3.0.0.tgz#62b8c638225c61e6cc607f8f4b779f3b8238f155"
- integrity sha512-KQDVjGqhZk92PPNRj9ZEXEuqg8bUobSKRw+q0YQ3TKI5xkce7bUJobL4Z/OtiEbAAv70yEpYIXp4iQ9L8oPVog==
-
-read-cmd-shim@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-3.0.1.tgz#868c235ec59d1de2db69e11aec885bc095aea087"
- integrity sha512-kEmDUoYf/CDy8yZbLTmhB1X9kkjf9Q80PCNsDMb7ufrGd6zZSQA1+UyjrO+pZm5K/S4OXCWJeiIt1JA8kAsa6g==
+read-cmd-shim@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz#640a08b473a49043e394ae0c7a34dd822c73b9bb"
+ integrity sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==
-read-package-json-fast@^2.0.1, read-package-json-fast@^2.0.2, read-package-json-fast@^2.0.3:
+read-package-json-fast@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83"
integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==
@@ -22724,15 +22880,23 @@ read-package-json-fast@^2.0.1, read-package-json-fast@^2.0.2, read-package-json-
json-parse-even-better-errors "^2.3.0"
npm-normalize-package-bin "^1.0.1"
-read-package-json@5.0.1:
- version "5.0.1"
- resolved "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.1.tgz#1ed685d95ce258954596b13e2e0e76c7d0ab4c26"
- integrity sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg==
+read-package-json-fast@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049"
+ integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==
dependencies:
- glob "^8.0.1"
- json-parse-even-better-errors "^2.3.1"
- normalize-package-data "^4.0.0"
- npm-normalize-package-bin "^1.0.1"
+ json-parse-even-better-errors "^3.0.0"
+ npm-normalize-package-bin "^3.0.0"
+
+read-package-json@6.0.4, read-package-json@^6.0.0:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836"
+ integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==
+ dependencies:
+ glob "^10.2.2"
+ json-parse-even-better-errors "^3.0.0"
+ normalize-package-data "^5.0.0"
+ npm-normalize-package-bin "^3.0.0"
read-package-json@^2.0.0:
version "2.1.2"
@@ -22744,16 +22908,6 @@ read-package-json@^2.0.0:
normalize-package-data "^2.0.0"
npm-normalize-package-bin "^1.0.0"
-read-package-json@^5.0.0:
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-5.0.2.tgz#b8779ccfd169f523b67208a89cc912e3f663f3fa"
- integrity sha512-BSzugrt4kQ/Z0krro8zhTwV1Kd79ue25IhNN/VtHFy1mG/6Tluyi+msc0UpwaoQzxSHa28mntAjIZY6kEgfR9Q==
- dependencies:
- glob "^8.0.1"
- json-parse-even-better-errors "^2.3.1"
- normalize-package-data "^4.0.0"
- npm-normalize-package-bin "^2.0.0"
-
read-package-tree@5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.3.1.tgz#a32cb64c7f31eb8a6f31ef06f9cedf74068fe636"
@@ -22841,12 +22995,12 @@ read-pkg@^5.0.0, read-pkg@^5.2.0:
parse-json "^5.0.0"
type-fest "^0.6.0"
-read@1, read@^1.0.7:
- version "1.0.7"
- resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
- integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=
+read@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/read/-/read-2.1.0.tgz#69409372c54fe3381092bc363a00650b6ac37218"
+ integrity sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ==
dependencies:
- mute-stream "~0.0.4"
+ mute-stream "~1.0.0"
"readable-stream@1 || 2", readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
@@ -22861,7 +23015,7 @@ read@1, read@^1.0.7:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
+"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -22880,7 +23034,7 @@ readable-stream@~1.0.2:
isarray "0.0.1"
string_decoder "~0.10.x"
-readdir-scoped-modules@^1.0.0, readdir-scoped-modules@^1.1.0:
+readdir-scoped-modules@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309"
integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==
@@ -23566,6 +23720,13 @@ rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.5.2, rimraf@^2.5.3, rimra
dependencies:
glob "^7.1.3"
+rimraf@^4.4.1:
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755"
+ integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==
+ dependencies:
+ glob "^9.2.0"
+
rimraf@~2.5.2:
version "2.5.4"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04"
@@ -23974,9 +24135,9 @@ semver-intersect@1.4.0:
semver "^5.0.0"
"semver@2 || 3 || 4 || 5", semver@^5.0.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
- version "5.7.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
- integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
+ version "5.7.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
+ integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
semver@7.3.2:
version "7.3.2"
@@ -23997,17 +24158,24 @@ semver@7.3.5:
dependencies:
lru-cache "^6.0.0"
-semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7:
- version "7.3.8"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
- integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
+semver@7.5.3:
+ version "7.5.3"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
+ integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==
+ dependencies:
+ lru-cache "^6.0.0"
+
+semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8:
+ version "7.5.4"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
+ integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
send@0.18.0:
version "0.18.0"
@@ -24182,6 +24350,21 @@ signal-exit@3.0.7, signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, s
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+signal-exit@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.0.2.tgz#ff55bb1d9ff2114c13b400688fa544ac63c36967"
+ integrity sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==
+
+sigstore@^1.3.0, sigstore@^1.4.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.6.0.tgz#887a4007c6ee83f3ef3fd844be1a0840e849c301"
+ integrity sha512-QODKff/qW/TXOZI6V/Clqu74xnInAS6it05mufj4/fSewexLtfEntgLZZcBtUK44CDQyUE5TUXYy1ARYzlfG9g==
+ dependencies:
+ "@sigstore/protobuf-specs" "^0.1.0"
+ "@sigstore/tuf" "^1.0.0"
+ make-fetch-happen "^11.0.1"
+ tuf-js "^1.1.3"
+
silent-error@^1.0.0, silent-error@^1.0.1, silent-error@^1.1.0, silent-error@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/silent-error/-/silent-error-1.1.1.tgz#f72af5b0d73682a2ba1778b7e32cd8aa7c2d8662"
@@ -24489,13 +24672,6 @@ sort-keys@^2.0.0:
dependencies:
is-plain-obj "^1.0.0"
-sort-keys@^4.0.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.2.0.tgz#6b7638cee42c506fff8c1cecde7376d21315be18"
- integrity sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==
- dependencies:
- is-plain-obj "^2.0.0"
-
sort-object-keys@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45"
@@ -24763,7 +24939,7 @@ split-string@^3.0.1, split-string@^3.0.2:
dependencies:
extend-shallow "^3.0.0"
-split2@^3.0.0:
+split2@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f"
integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==
@@ -24782,7 +24958,7 @@ split@0.3:
dependencies:
through "2"
-split@^1.0.0:
+split@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
@@ -24824,12 +25000,12 @@ sshpk@^1.7.0:
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
-ssri@9.0.1, ssri@^9.0.0:
- version "9.0.1"
- resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057"
- integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==
+ssri@^10.0.0, ssri@^10.0.1:
+ version "10.0.4"
+ resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.4.tgz#5a20af378be586df139ddb2dfb3bf992cf0daba6"
+ integrity sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==
dependencies:
- minipass "^3.1.1"
+ minipass "^5.0.0"
ssri@^6.0.0, ssri@^6.0.1:
version "6.0.2"
@@ -24845,6 +25021,13 @@ ssri@^8.0.0, ssri@^8.0.1:
dependencies:
minipass "^3.1.1"
+ssri@^9.0.0, ssri@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057"
+ integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==
+ dependencies:
+ minipass "^3.1.1"
+
stable@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
@@ -25028,6 +25211,15 @@ 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@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.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@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -25045,15 +25237,6 @@ string-width@^1.0.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
-"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.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@^3.0.0, string-width@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
@@ -25063,7 +25246,7 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
-string-width@^5.0.0:
+string-width@^5.0.0, 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"
integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
@@ -25141,6 +25324,13 @@ 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.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==
+ dependencies:
+ ansi-regex "^5.0.1"
+
strip-ansi@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
@@ -25169,13 +25359,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
-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==
- dependencies:
- ansi-regex "^5.0.1"
-
strip-ansi@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
@@ -25888,13 +26071,6 @@ through2@^3.0.1:
inherits "^2.0.4"
readable-stream "2 || 3"
-through2@^4.0.0:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764"
- integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==
- dependencies:
- readable-stream "3"
-
through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6, through@~2.3, through@~2.3.1:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
@@ -26156,11 +26332,6 @@ tree-sync@^2.0.0, tree-sync@^2.1.0:
quick-temp "^0.1.5"
walk-sync "^0.3.3"
-treeverse@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/treeverse/-/treeverse-2.0.0.tgz#036dcef04bc3fd79a9b79a68d4da03e882d8a9ca"
- integrity sha512-N5gJCkLu1aXccpOTtqV6ddSEi6ZmGkh3hjmbu1IjcavJK4qyOVQmi0myQKM7z5jVGmD68SJoliaVrMmVObhj6A==
-
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
@@ -26285,6 +26456,15 @@ tty-browserify@0.0.1, tty-browserify@^0.0.1:
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"
integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==
+tuf-js@^1.1.3:
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43"
+ integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==
+ dependencies:
+ "@tufjs/models" "1.0.4"
+ debug "^4.3.4"
+ make-fetch-happen "^11.1.1"
+
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@@ -26424,11 +26604,16 @@ typescript@4.3.5:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
-typescript@4.9.5, "typescript@^3 || ^4":
+typescript@4.9.5:
version "4.9.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
+"typescript@>=3 < 6":
+ version "5.1.6"
+ 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"
@@ -26577,6 +26762,13 @@ unique-filename@^2.0.0:
dependencies:
unique-slug "^3.0.0"
+unique-filename@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea"
+ integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==
+ dependencies:
+ unique-slug "^4.0.0"
+
unique-slug@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c"
@@ -26591,6 +26783,13 @@ unique-slug@^3.0.0:
dependencies:
imurmurhash "^0.1.4"
+unique-slug@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3"
+ integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==
+ dependencies:
+ imurmurhash "^0.1.4"
+
unique-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
@@ -26657,16 +26856,16 @@ untildify@^2.1.0:
dependencies:
os-homedir "^1.0.0"
+upath@2.0.1, upath@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b"
+ integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==
+
upath@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
-upath@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b"
- integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==
-
update-browserslist-db@^1.0.10, update-browserslist-db@^1.0.9:
version "1.0.10"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
@@ -26912,10 +27111,10 @@ validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validat
spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0"
-validate-npm-package-name@4.0.0, validate-npm-package-name@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz#fe8f1c50ac20afdb86f177da85b3600f0ac0d747"
- integrity sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==
+validate-npm-package-name@5.0.0, validate-npm-package-name@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713"
+ integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==
dependencies:
builtins "^5.0.0"
@@ -26926,6 +27125,13 @@ validate-npm-package-name@^3.0.0:
dependencies:
builtins "^1.0.3"
+validate-npm-package-name@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz#fe8f1c50ac20afdb86f177da85b3600f0ac0d747"
+ integrity sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==
+ dependencies:
+ builtins "^5.0.0"
+
validate-peer-dependencies@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/validate-peer-dependencies/-/validate-peer-dependencies-1.2.0.tgz#22aab93c514f4fda457d36c80685e8b1160d2036"
@@ -27144,11 +27350,6 @@ walk-sync@^3.0.0:
matcher-collection "^2.0.1"
minimatch "^3.0.4"
-walk-up-path@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-1.0.0.tgz#d4745e893dd5fd0dbb58dd0a4c6a33d9c9fec53e"
- integrity sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==
-
walkdir@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.4.1.tgz#dc119f83f4421df52e3061e514228a2db20afa39"
@@ -27705,6 +27906,13 @@ which@^2.0.1, which@^2.0.2:
dependencies:
isexe "^2.0.0"
+which@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1"
+ integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==
+ dependencies:
+ isexe "^2.0.0"
+
why-is-node-running@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.2.2.tgz#4185b2b4699117819e7154594271e7e344c9973e"
@@ -27813,6 +28021,15 @@ workerpool@^6.1.5, workerpool@^6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
+"wrap-ansi-cjs@npm:wrap-ansi@^7.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@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
@@ -27831,27 +28048,27 @@ 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==
+wrap-ansi@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
+ integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
dependencies:
- ansi-styles "^4.0.0"
- string-width "^4.1.0"
- strip-ansi "^6.0.0"
+ ansi-styles "^6.1.0"
+ string-width "^5.0.1"
+ strip-ansi "^7.0.1"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-write-file-atomic@4.0.1:
- version "4.0.1"
- resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f"
- integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==
+write-file-atomic@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7"
+ integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==
dependencies:
imurmurhash "^0.1.4"
- signal-exit "^3.0.7"
+ signal-exit "^4.0.1"
write-file-atomic@^2.4.2:
version "2.4.3"
@@ -27872,26 +28089,6 @@ write-file-atomic@^3.0.0:
signal-exit "^3.0.2"
typedarray-to-buffer "^3.1.5"
-write-file-atomic@^4.0.0:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd"
- integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==
- dependencies:
- imurmurhash "^0.1.4"
- signal-exit "^3.0.7"
-
-write-json-file@4.3.0:
- version "4.3.0"
- resolved "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz#908493d6fd23225344af324016e4ca8f702dd12d"
- integrity sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==
- dependencies:
- detect-indent "^6.0.0"
- graceful-fs "^4.1.15"
- is-plain-obj "^2.0.0"
- make-dir "^3.0.0"
- sort-keys "^4.0.0"
- write-file-atomic "^3.0.0"
-
write-json-file@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a"