diff --git a/.craft.yml b/.craft.yml
index c06d90bc7689..0b7faad1f26b 100644
--- a/.craft.yml
+++ b/.craft.yml
@@ -6,101 +6,104 @@ targets:
## 1. Base Packages, node or browser SDKs depend on
## 1.1 Types
- name: npm
- id: "@sentry/types"
+ id: '@sentry/types'
includeNames: /^sentry-types-\d.*\.tgz$/
## 1.2 Utils
- name: npm
- id: "@sentry/utils"
+ id: '@sentry/utils'
includeNames: /^sentry-utils-\d.*\.tgz$/
## 1.3 Core SDK
- name: npm
- id: "@sentry/core"
+ id: '@sentry/core'
includeNames: /^sentry-core-\d.*\.tgz$/
## 1.4 Tracing package
- name: npm
- id: "@sentry-internal/tracing"
+ id: '@sentry-internal/tracing'
includeNames: /^sentry-internal-tracing-\d.*\.tgz$/
## 1.5 Replay package (browser only)
- name: npm
- id: "@sentry/replay"
+ id: '@sentry/replay'
includeNames: /^sentry-replay-\d.*\.tgz$/
## 2. Browser & Node SDKs
- name: npm
- id: "@sentry/browser"
+ id: '@sentry/browser'
includeNames: /^sentry-browser-\d.*\.tgz$/
- name: npm
- id: "@sentry/node"
+ id: '@sentry/node'
includeNames: /^sentry-node-\d.*\.tgz$/
## 3 Browser-based Packages
- name: npm
- id: "@sentry/angular-ivy"
+ id: '@sentry/angular-ivy'
includeNames: /^sentry-angular-ivy-\d.*\.tgz$/
- name: npm
- id: "@sentry/angular"
+ id: '@sentry/angular'
includeNames: /^sentry-angular-\d.*\.tgz$/
- name: npm
- id: "@sentry/ember"
+ id: '@sentry/ember'
includeNames: /^sentry-ember-\d.*\.tgz$/
- name: npm
- id: "@sentry/react"
+ id: '@sentry/react'
includeNames: /^sentry-react-\d.*\.tgz$/
- name: npm
- id: "@sentry/svelte"
+ id: '@sentry/svelte'
includeNames: /^sentry-svelte-\d.*\.tgz$/
- name: npm
- id: "@sentry/vue"
+ id: '@sentry/vue'
includeNames: /^sentry-vue-\d.*\.tgz$/
- name: npm
- id: "@sentry/wasm"
+ id: '@sentry/wasm'
includeNames: /^sentry-wasm-\d.*\.tgz$/
- name: npm
- id: "@sentry/integrations"
+ id: '@sentry/integrations'
includeNames: /^sentry-integrations-\d.*\.tgz$/
## 4. Node-based Packages
- name: npm
- id: "@sentry/serverless"
+ id: '@sentry/serverless'
includeNames: /^sentry-serverless-\d.*\.tgz$/
- name: npm
- id: "@sentry/opentelemetry-node"
+ id: '@sentry/opentelemetry-node'
includeNames: /^sentry-opentelemetry-node-\d.*\.tgz$/
## 5. Fullstack/Meta Frameworks (depending on Node and Browser or Framework SDKs)
- name: npm
- id: "@sentry/nextjs"
+ id: '@sentry/nextjs'
includeNames: /^sentry-nextjs-\d.*\.tgz$/
- name: npm
- id: "@sentry/remix"
+ id: '@sentry/remix'
includeNames: /^sentry-remix-\d.*\.tgz$/
- name: npm
- id: "@sentry/sveltekit"
+ id: '@sentry/sveltekit'
includeNames: /^sentry-sveltekit-\d.*\.tgz$/
- name: npm
- id: "@sentry/gatsby"
+ id: '@sentry/gatsby'
includeNames: /^sentry-gatsby-\d.*\.tgz$/
## 6. Other Packages
## 6.1
- name: npm
- id: "@sentry-internal/typescript"
+ id: '@sentry-internal/typescript'
includeNames: /^sentry-internal-typescript-\d.*\.tgz$/
- name: npm
- id: "@sentry-internal/eslint-plugin-sdk"
+ id: '@sentry-internal/eslint-plugin-sdk'
includeNames: /^sentry-internal-eslint-plugin-sdk-\d.*\.tgz$/
## 6.2
- name: npm
- id: "@sentry-internal/eslint-config-sdk"
+ id: '@sentry-internal/eslint-config-sdk'
includeNames: /^sentry-internal-eslint-config-sdk-\d.*\.tgz$/
## 7. Deprecated packages we still release (but no packages depend on them anymore)
- name: npm
- id: "@sentry/hub"
+ id: '@sentry/hub'
includeNames: /^sentry-hub-\d.*\.tgz$/
- name: npm
- id: "@sentry/tracing"
+ id: '@sentry/tracing'
includeNames: /^sentry-tracing-\d.*\.tgz$/
+ - name: npm
+ id: '@sentry/node-experimental'
+ includeNames: /^sentry-node-experimental-\d.*\.tgz$/
# AWS Lambda Layer target
- name: aws-lambda-layer
@@ -118,7 +121,7 @@ targets:
# CDN Bundle Target
- name: gcs
- id: "browser-cdn-bundles"
+ id: 'browser-cdn-bundles'
includeNames: /.*\.js.*$/
bucket: sentry-js-sdk
paths:
diff --git a/docs/new-sdk-release-checklist.md b/docs/new-sdk-release-checklist.md
index aca0f0f399c4..1b40763cdd6c 100644
--- a/docs/new-sdk-release-checklist.md
+++ b/docs/new-sdk-release-checklist.md
@@ -61,7 +61,7 @@ When you’re ready to make the first release, there are a couple of steps that
- [ ] 3) Add an `npm` target in `craft.yml` for the new package. Make sure to insert it in the right place, after all the Sentry dependencies of your package but before packages that depend on your new package (if applicable).
```yml
- name: npm
- id: npm:@sentry/[yourPackage]
+ id: '@sentry/[yourPackage]'
includeNames: /^sentry-[yourPackage]-\d.*\.tgz$/
```
- [ ] 4) Cut a new release (as usual, see [Publishing Release](https://github.com/getsentry/sentry-javascript/blob/develop/docs/publishing-a-release.md))
diff --git a/package.json b/package.json
index 0d800adc7824..05a48e6d3c4c 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
"packages/nextjs",
"packages/node",
"packages/node-integration-tests",
+ "packages/node-experimental",
"packages/opentelemetry-node",
"packages/react",
"packages/remix",
diff --git a/packages/node-experimental/.eslintrc.js b/packages/node-experimental/.eslintrc.js
new file mode 100644
index 000000000000..9899ea1b73d8
--- /dev/null
+++ b/packages/node-experimental/.eslintrc.js
@@ -0,0 +1,9 @@
+module.exports = {
+ env: {
+ node: true,
+ },
+ extends: ['../../.eslintrc.js'],
+ rules: {
+ '@sentry-internal/sdk/no-optional-chaining': 'off',
+ },
+};
diff --git a/packages/node-experimental/LICENSE b/packages/node-experimental/LICENSE
new file mode 100644
index 000000000000..4ac873d49f33
--- /dev/null
+++ b/packages/node-experimental/LICENSE
@@ -0,0 +1,14 @@
+Copyright (c) 2022 Sentry (https://sentry.io) and individual contributors. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packages/node-experimental/README.md b/packages/node-experimental/README.md
new file mode 100644
index 000000000000..5f0947201488
--- /dev/null
+++ b/packages/node-experimental/README.md
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+# Official Sentry SDK for Node (Preview)
+
+[![npm version](https://img.shields.io/npm/v/@sentry/node-experimental.svg)](https://www.npmjs.com/package/@sentry/node-experimental)
+[![npm dm](https://img.shields.io/npm/dm/@sentry/node-experimental.svg)](https://www.npmjs.com/package/@sentry/node-experimental)
+[![npm dt](https://img.shields.io/npm/dt/@sentry/node-experimental.svg)](https://www.npmjs.com/package/@sentry/node-experimental)
+
+This is a WIP, proof of concept implementation of a Node SDK that uses OpenTelemetry for performance instrumentation under the hood.
+
+THIS MAY/WILL BREAK IN MANY UNEXPECTED WAYS. We may remove, add, change any of the integrations, add/remove any exports, etc.
+This package is **NOT READY TO USE IN ANY FORM OF PRODUCTION ENVIRONMENT**!
+
+This SDK is **considered experimental and in an alpha state**. It may experience breaking changes, and may be discontinued at any time. Please reach out on
+[GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose) if you have any feedback/concerns.
+
+## Installation
+
+```bash
+npm install @sentry/node-experimental
+
+# Or yarn
+yarn add @sentry/node-experimental
+```
+
+## Usage
+
+```js
+// ES5 Syntax
+const Sentry = require('@sentry/node-experimental');
+// ES6 Syntax
+import * as Sentry from '@sentry/node-experimental';
+
+Sentry.init({
+ dsn: '__DSN__',
+ // ...
+});
+```
+
+Note that it is necessary to initialize Sentry **before you import any package that may be instrumented by us**.
+
+## Available (Performance) Integrations
+
+* Http
+* Express
+* Fastify
+* Nest
+* Mysql
+* Mysql2
+* GraphQL
+* Mongo
+* Mongoose
+* Postgres
+* Prisma
+
+All of these are auto-discovered, you don't need to configure anything for performance.
+You still need to register middlewares etc. for error capturing.
+Other, non-performance integrations from `@sentry/node` are also available (except for Undici).
+
+## Links
+
+- [Official SDK Docs](https://docs.sentry.io/quickstart/)
diff --git a/packages/node-experimental/jest.config.js b/packages/node-experimental/jest.config.js
new file mode 100644
index 000000000000..24f49ab59a4c
--- /dev/null
+++ b/packages/node-experimental/jest.config.js
@@ -0,0 +1 @@
+module.exports = require('../../jest/jest.config.js');
diff --git a/packages/node-experimental/package.json b/packages/node-experimental/package.json
new file mode 100644
index 000000000000..d24cd20c3831
--- /dev/null
+++ b/packages/node-experimental/package.json
@@ -0,0 +1,76 @@
+{
+ "name": "@sentry/node-experimental",
+ "version": "7.60.0",
+ "description": "Experimental version of a Node SDK using OpenTelemetry for performance instrumentation",
+ "repository": "git://github.com/getsentry/sentry-javascript.git",
+ "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node-experimental",
+ "author": "Sentry",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "main": "build/cjs/index.js",
+ "module": "build/esm/index.js",
+ "types": "build/types/index.d.ts",
+ "typesVersions": {
+ "<4.9": {
+ "build/types/index.d.ts": [
+ "build/types-ts3.8/index.d.ts"
+ ]
+ }
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "dependencies": {
+ "@opentelemetry/api": "~1.4.1",
+ "@opentelemetry/instrumentation": "~0.41.0",
+ "@opentelemetry/instrumentation-fastify": "~0.32.0",
+ "@opentelemetry/instrumentation-http": "~0.41.0",
+ "@opentelemetry/instrumentation-express": "~0.33.0",
+ "@opentelemetry/instrumentation-graphql": "~0.35.0",
+ "@opentelemetry/instrumentation-mongodb": "~0.36.0",
+ "@opentelemetry/instrumentation-mongoose": "~0.33.0",
+ "@opentelemetry/instrumentation-mysql": "~0.34.0",
+ "@opentelemetry/instrumentation-mysql2": "~0.34.0",
+ "@opentelemetry/instrumentation-pg": "~0.36.0",
+ "@opentelemetry/instrumentation-nestjs-core": "~0.33.0",
+ "@opentelemetry/semantic-conventions": "~1.15.0",
+ "@opentelemetry/sdk-trace-node": "~1.15.0",
+ "@prisma/instrumentation": "~5.0.0",
+ "@sentry/core": "7.60.0",
+ "@sentry/node": "7.60.0",
+ "@sentry/opentelemetry-node": "7.60.0",
+ "@sentry/types": "7.60.0",
+ "@sentry/utils": "7.60.0"
+ },
+ "scripts": {
+ "build": "run-p build:transpile build:types",
+ "build:dev": "yarn build",
+ "build:transpile": "rollup -c rollup.npm.config.js",
+ "build:types": "run-s build:types:core build:types:downlevel",
+ "build:types:core": "tsc -p tsconfig.types.json",
+ "build:types:downlevel": "yarn downlevel-dts build/types build/types-ts3.8 --to ts3.8",
+ "build:watch": "run-p build:transpile:watch build:types:watch",
+ "build:dev:watch": "yarn build:watch",
+ "build:transpile:watch": "rollup -c rollup.npm.config.js --watch",
+ "build:types:watch": "tsc -p tsconfig.types.json --watch",
+ "build:tarball": "ts-node ../../scripts/prepack.ts && npm pack ./build",
+ "circularDepCheck": "madge --circular src/index.ts",
+ "clean": "rimraf build coverage sentry-node-experimental-*.tgz",
+ "fix": "run-s fix:eslint fix:prettier",
+ "fix:eslint": "eslint . --format stylish --fix",
+ "fix:prettier": "prettier --write \"{src,test,scripts}/**/**.ts\"",
+ "lint": "run-s lint:prettier lint:eslint",
+ "lint:eslint": "eslint . --format stylish",
+ "lint:prettier": "prettier --check \"{src,test,scripts}/**/**.ts\"",
+ "test": "yarn test:jest",
+ "test:jest": "jest",
+ "test:watch": "jest --watch",
+ "yalc:publish": "ts-node ../../scripts/prepack.ts && yalc publish build --push"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ },
+ "sideEffects": false
+}
diff --git a/packages/node-experimental/rollup.npm.config.js b/packages/node-experimental/rollup.npm.config.js
new file mode 100644
index 000000000000..5a62b528ef44
--- /dev/null
+++ b/packages/node-experimental/rollup.npm.config.js
@@ -0,0 +1,3 @@
+import { makeBaseNPMConfig, makeNPMConfigVariants } from '../../rollup/index.js';
+
+export default makeNPMConfigVariants(makeBaseNPMConfig());
diff --git a/packages/node-experimental/src/index.ts b/packages/node-experimental/src/index.ts
new file mode 100644
index 000000000000..1b3e961409e5
--- /dev/null
+++ b/packages/node-experimental/src/index.ts
@@ -0,0 +1,13 @@
+import { Integrations as CoreIntegrations } from '@sentry/core';
+
+import * as NodePreviewIntegrations from './integrations';
+
+const INTEGRATIONS = {
+ ...CoreIntegrations,
+ ...NodePreviewIntegrations,
+};
+
+export { init } from './sdk/init';
+export { INTEGRATIONS as Integrations };
+export { getAutoPerformanceIntegrations } from './integrations/getAutoPerformanceIntegrations';
+export * as Handlers from './sdk/handlers';
diff --git a/packages/node-experimental/src/integrations/express.ts b/packages/node-experimental/src/integrations/express.ts
new file mode 100644
index 000000000000..f51860364378
--- /dev/null
+++ b/packages/node-experimental/src/integrations/express.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * Express integration
+ *
+ * Capture tracing data for express.
+ */
+export class Express extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Express';
+
+ /**
+ * @inheritDoc
+ */
+ public name: string = Express.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new ExpressInstrumentation()];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/fastify.ts b/packages/node-experimental/src/integrations/fastify.ts
new file mode 100644
index 000000000000..70969c40be46
--- /dev/null
+++ b/packages/node-experimental/src/integrations/fastify.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { FastifyInstrumentation } from '@opentelemetry/instrumentation-fastify';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * Express integration
+ *
+ * Capture tracing data for fastify.
+ */
+export class Fastify extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Fastify';
+
+ /**
+ * @inheritDoc
+ */
+ public name: string = Fastify.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new FastifyInstrumentation()];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/getAutoPerformanceIntegrations.ts b/packages/node-experimental/src/integrations/getAutoPerformanceIntegrations.ts
new file mode 100644
index 000000000000..d770d50a9a30
--- /dev/null
+++ b/packages/node-experimental/src/integrations/getAutoPerformanceIntegrations.ts
@@ -0,0 +1,89 @@
+import type { Integration, IntegrationClass } from '@sentry/types';
+import { dynamicRequire } from '@sentry/utils';
+
+import type { Express } from './express';
+import type { Fastify } from './fastify';
+import type { GraphQL } from './graphql';
+import type { Mongo } from './mongo';
+import type { Mongoose } from './mongoose';
+import type { Mysql } from './mysql';
+import type { Mysql2 } from './mysql2';
+import type { Nest } from './nest';
+import type { Postgres } from './postgres';
+import type { Prisma } from './prisma';
+
+const INTEGRATIONS = [
+ () => {
+ const integration = dynamicRequire(module, './express') as {
+ Express: IntegrationClass;
+ };
+ return new integration.Express();
+ },
+ () => {
+ const integration = dynamicRequire(module, './fastify') as {
+ Fastify: IntegrationClass;
+ };
+ return new integration.Fastify();
+ },
+ () => {
+ const integration = dynamicRequire(module, './graphql') as {
+ GraphQL: IntegrationClass;
+ };
+ return new integration.GraphQL();
+ },
+ () => {
+ const integration = dynamicRequire(module, './mongo') as {
+ Mongo: IntegrationClass;
+ };
+ return new integration.Mongo();
+ },
+ () => {
+ const integration = dynamicRequire(module, './mongoose') as {
+ Mongoose: IntegrationClass;
+ };
+ return new integration.Mongoose();
+ },
+ () => {
+ const integration = dynamicRequire(module, './mysql') as {
+ Mysql: IntegrationClass;
+ };
+ return new integration.Mysql();
+ },
+ () => {
+ const integration = dynamicRequire(module, './mysql2') as {
+ Mysql2: IntegrationClass;
+ };
+ return new integration.Mysql2();
+ },
+ () => {
+ const integration = dynamicRequire(module, './postgres') as {
+ Postgres: IntegrationClass;
+ };
+ return new integration.Postgres();
+ },
+ () => {
+ const integration = dynamicRequire(module, './prisma') as {
+ Prisma: IntegrationClass;
+ };
+ return new integration.Prisma();
+ },
+ () => {
+ const integration = dynamicRequire(module, './nest') as {
+ Nest: IntegrationClass;
+ };
+ return new integration.Nest();
+ },
+];
+
+/** TODO */
+export function getAutoPerformanceIntegrations(): Integration[] {
+ const loadedIntegrations = INTEGRATIONS.map(tryLoad => {
+ try {
+ return tryLoad();
+ } catch (_) {
+ return undefined;
+ }
+ }).filter(integration => !!integration) as Integration[];
+
+ return loadedIntegrations;
+}
diff --git a/packages/node-experimental/src/integrations/graphql.ts b/packages/node-experimental/src/integrations/graphql.ts
new file mode 100644
index 000000000000..c606f1b6f126
--- /dev/null
+++ b/packages/node-experimental/src/integrations/graphql.ts
@@ -0,0 +1,31 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * GraphQL integration
+ *
+ * Capture tracing data for GraphQL.
+ */
+export class GraphQL extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'GraphQL';
+
+ /**
+ * @inheritDoc
+ */
+ public name: string = GraphQL.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [
+ new GraphQLInstrumentation({
+ ignoreTrivialResolveSpans: true,
+ }),
+ ];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/http.ts b/packages/node-experimental/src/integrations/http.ts
new file mode 100644
index 000000000000..dd00f2e3f87a
--- /dev/null
+++ b/packages/node-experimental/src/integrations/http.ts
@@ -0,0 +1,194 @@
+import type { Attributes } from '@opentelemetry/api';
+import { SpanKind } from '@opentelemetry/api';
+import { registerInstrumentations } from '@opentelemetry/instrumentation';
+import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
+import type { Span as OtelSpan } from '@opentelemetry/sdk-trace-node';
+import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
+import { hasTracingEnabled } from '@sentry/core';
+import { getCurrentHub } from '@sentry/node';
+import type { AdditionalOtelSpanData } from '@sentry/opentelemetry-node';
+import { addOtelSpanData } from '@sentry/opentelemetry-node';
+import type { EventProcessor, Hub, Integration } from '@sentry/types';
+import type { ClientRequest, IncomingMessage, ServerResponse } from 'http';
+
+import type { NodePreviewClient } from '../sdk/client';
+import { getRequestSpanData } from '../utils/getRequestSpanData';
+
+interface TracingOptions {
+ /**
+ * Function determining whether or not to create spans to track outgoing requests to the given URL.
+ * By default, spans will be created for all outgoing requests.
+ */
+ shouldCreateSpanForRequest?: (url: string) => boolean;
+}
+
+interface HttpOptions {
+ /**
+ * Whether breadcrumbs should be recorded for requests
+ * Defaults to true
+ */
+ breadcrumbs?: boolean;
+
+ /**
+ * Whether tracing spans should be created for requests
+ * Defaults to false
+ */
+ tracing?: TracingOptions | boolean;
+}
+
+/**
+ * Http instrumentation based on @opentelemetry/instrumentation-http.
+ * This instrumentation does two things:
+ * * Create breadcrumbs for outgoing requests
+ * * Create spans for outgoing requests
+ *
+ * Note that this integration is also needed for the Express integration to work!
+ */
+export class Http implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Http';
+
+ /**
+ * @inheritDoc
+ */
+ public name: string = Http.id;
+
+ private _unload?: () => void;
+ private readonly _breadcrumbs: boolean;
+ // undefined: default behavior based on tracing settings
+ private readonly _tracing: boolean | undefined;
+ private _shouldCreateSpans: boolean = false;
+ private _shouldCreateSpanForRequest?: (url: string) => boolean;
+
+ /**
+ * @inheritDoc
+ */
+ public constructor(options: HttpOptions = {}) {
+ this._breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;
+ this._tracing = typeof options.tracing === 'undefined' ? undefined : !!options.tracing;
+
+ if (options.tracing && typeof options.tracing === 'object') {
+ this._shouldCreateSpanForRequest = options.tracing.shouldCreateSpanForRequest;
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setupOnce(_addGlobalEventProcessor: (callback: EventProcessor) => void, _getCurrentHub: () => Hub): void {
+ // No need to instrument if we don't want to track anything
+ if (!this._breadcrumbs && this._tracing === false) {
+ return;
+ }
+
+ const client = getCurrentHub().getClient();
+ const clientOptions = client?.getOptions();
+
+ this._shouldCreateSpans = typeof this._tracing === 'undefined' ? hasTracingEnabled(clientOptions) : this._tracing;
+
+ // Register instrumentations we care about
+ this._unload = registerInstrumentations({
+ instrumentations: [
+ new HttpInstrumentation({
+ requireParentforOutgoingSpans: true,
+ requireParentforIncomingSpans: false,
+ applyCustomAttributesOnSpan: (span, req, res) => {
+ this._onSpan(span as unknown as OtelSpan, req, res);
+ },
+ }),
+ ],
+ });
+
+ this._shouldCreateSpanForRequest =
+ // eslint-disable-next-line deprecation/deprecation
+ this._shouldCreateSpanForRequest || clientOptions?.shouldCreateSpanForRequest;
+
+ client?.otelHooks.on('spanEnd', this._onSpanEnd);
+ }
+
+ /**
+ * Unregister this integration.
+ */
+ public unregister(): void {
+ this._unload?.();
+
+ const client = getCurrentHub().getClient();
+ client?.otelHooks.off('spanEnd', this._onSpanEnd);
+ }
+
+ private _onSpanEnd: (otelSpan: OtelSpan) => void | false = (otelSpan: OtelSpan) => {
+ if (!this._shouldCreateSpans) {
+ return false;
+ }
+
+ if (this._shouldCreateSpanForRequest) {
+ const url = getHttpUrl(otelSpan.attributes);
+ if (url && !this._shouldCreateSpanForRequest(url)) {
+ return false;
+ }
+ }
+
+ return undefined;
+ };
+
+ /** Handle an emitted span from the HTTP instrumentation. */
+ private _onSpan(
+ span: OtelSpan,
+ request: ClientRequest | IncomingMessage,
+ response: IncomingMessage | ServerResponse,
+ ): void {
+ const data = getRequestSpanData(span, request, response);
+ const { attributes } = span;
+
+ const additionalData: AdditionalOtelSpanData = {
+ tags: {},
+ data: {
+ url: data.url,
+ },
+ contexts: {},
+ metadata: {},
+ };
+
+ if (span.kind === SpanKind.SERVER) {
+ additionalData.metadata = { request };
+ }
+
+ if (attributes[SemanticAttributes.HTTP_STATUS_CODE]) {
+ const statusCode = attributes[SemanticAttributes.HTTP_STATUS_CODE] as string;
+ additionalData.tags['http.status_code'] = statusCode;
+ additionalData.data['http.response.status_code'] = statusCode;
+ }
+
+ if (data['http.query']) {
+ additionalData.data['http.query'] = data['http.query'].slice(1);
+ }
+ if (data['http.fragment']) {
+ additionalData.data['http.fragment'] = data['http.fragment'].slice(1);
+ }
+
+ addOtelSpanData(span.spanContext().spanId, additionalData);
+
+ getCurrentHub().addBreadcrumb(
+ {
+ category: 'http',
+ data: {
+ status_code: response.statusCode,
+ ...data,
+ },
+ type: 'http',
+ },
+ {
+ event: 'response',
+ request,
+ response,
+ },
+ );
+ }
+}
+
+function getHttpUrl(attributes: Attributes): string | undefined {
+ const url = attributes[SemanticAttributes.HTTP_URL];
+ return typeof url === 'string' ? url : undefined;
+}
diff --git a/packages/node-experimental/src/integrations/index.ts b/packages/node-experimental/src/integrations/index.ts
new file mode 100644
index 000000000000..efe485d6c1b6
--- /dev/null
+++ b/packages/node-experimental/src/integrations/index.ts
@@ -0,0 +1,37 @@
+import { Integrations as NodeIntegrations } from '@sentry/node';
+
+const {
+ Console,
+ OnUncaughtException,
+ OnUnhandledRejection,
+ LinkedErrors,
+ Modules,
+ ContextLines,
+ Context,
+ RequestData,
+ LocalVariables,
+} = NodeIntegrations;
+
+export {
+ Console,
+ OnUncaughtException,
+ OnUnhandledRejection,
+ LinkedErrors,
+ Modules,
+ ContextLines,
+ Context,
+ RequestData,
+ LocalVariables,
+};
+
+export { Express } from './express';
+export { Http } from './http';
+export { Fastify } from './fastify';
+export { GraphQL } from './graphql';
+export { Mongo } from './mongo';
+export { Mongoose } from './mongoose';
+export { Mysql } from './mysql';
+export { Mysql2 } from './mysql2';
+export { Nest } from './nest';
+export { Postgres } from './postgres';
+export { Prisma } from './prisma';
diff --git a/packages/node-experimental/src/integrations/lazy.ts b/packages/node-experimental/src/integrations/lazy.ts
new file mode 100644
index 000000000000..85545992eb41
--- /dev/null
+++ b/packages/node-experimental/src/integrations/lazy.ts
@@ -0,0 +1,38 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { registerInstrumentations } from '@opentelemetry/instrumentation';
+
+/** TODO */
+export abstract class NodePerformanceIntegration {
+ protected _options: IntegrationOptions;
+ protected _unload?: () => void;
+
+ public constructor(options: IntegrationOptions) {
+ this._options = options;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public setupOnce(): void {
+ const instrumentations = this.setupInstrumentation(this._options);
+
+ if (!instrumentations) {
+ return;
+ }
+
+ // Register instrumentations we care about
+ this._unload = registerInstrumentations({
+ instrumentations,
+ });
+ }
+
+ /**
+ * Unregister this integration.
+ */
+ public unregister(): void {
+ this._unload?.();
+ }
+
+ // Return the instrumentation(s) needed for this integration.
+ public abstract setupInstrumentation(options: IntegrationOptions): Instrumentation[] | void;
+}
diff --git a/packages/node-experimental/src/integrations/mongo.ts b/packages/node-experimental/src/integrations/mongo.ts
new file mode 100644
index 000000000000..109251986af6
--- /dev/null
+++ b/packages/node-experimental/src/integrations/mongo.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * MongoDB integration
+ *
+ * Capture tracing data for MongoDB.
+ */
+export class Mongo extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Mongo';
+
+ /**
+ * @inheritDoc
+ */
+ public name: string = Mongo.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new MongoDBInstrumentation({})];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/mongoose.ts b/packages/node-experimental/src/integrations/mongoose.ts
new file mode 100644
index 000000000000..5f85ae2bb771
--- /dev/null
+++ b/packages/node-experimental/src/integrations/mongoose.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { MongooseInstrumentation } from '@opentelemetry/instrumentation-mongoose';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * Mongoose integration
+ *
+ * Capture tracing data for Mongoose.
+ */
+export class Mongoose extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Mongoose';
+
+ /**
+ * @inheritDoc
+ */
+ public name: string = Mongoose.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new MongooseInstrumentation({})];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/mysql.ts b/packages/node-experimental/src/integrations/mysql.ts
new file mode 100644
index 000000000000..bae4e81f21a2
--- /dev/null
+++ b/packages/node-experimental/src/integrations/mysql.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { MySQLInstrumentation } from '@opentelemetry/instrumentation-mysql';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * MySQL integration
+ *
+ * Capture tracing data for mysql.
+ */
+export class Mysql extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Mysql';
+
+ /**
+ * @inheritDoc`
+ */
+ public name: string = Mysql.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new MySQLInstrumentation({})];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/mysql2.ts b/packages/node-experimental/src/integrations/mysql2.ts
new file mode 100644
index 000000000000..0620e7ad0b63
--- /dev/null
+++ b/packages/node-experimental/src/integrations/mysql2.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { MySQL2Instrumentation } from '@opentelemetry/instrumentation-mysql2';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * MySQL2 integration
+ *
+ * Capture tracing data for mysql2
+ */
+export class Mysql2 extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Mysql2';
+
+ /**
+ * @inheritDoc`
+ */
+ public name: string = Mysql2.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new MySQL2Instrumentation({})];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/nest.ts b/packages/node-experimental/src/integrations/nest.ts
new file mode 100644
index 000000000000..1845e4c3b9c6
--- /dev/null
+++ b/packages/node-experimental/src/integrations/nest.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * Nest framework integration
+ *
+ * Capture tracing data for nest.
+ */
+export class Nest extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Nest';
+
+ /**
+ * @inheritDoc`
+ */
+ public name: string = Nest.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new NestInstrumentation({})];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/postgres.ts b/packages/node-experimental/src/integrations/postgres.ts
new file mode 100644
index 000000000000..b061b209c8c8
--- /dev/null
+++ b/packages/node-experimental/src/integrations/postgres.ts
@@ -0,0 +1,27 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { PgInstrumentation } from '@opentelemetry/instrumentation-pg';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * Postgres integration
+ *
+ * Capture tracing data for pg.
+ */
+export class Postgres extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Postgres';
+
+ /**
+ * @inheritDoc`
+ */
+ public name: string = Postgres.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new PgInstrumentation({})];
+ }
+}
diff --git a/packages/node-experimental/src/integrations/prisma.ts b/packages/node-experimental/src/integrations/prisma.ts
new file mode 100644
index 000000000000..8fe0b0deb131
--- /dev/null
+++ b/packages/node-experimental/src/integrations/prisma.ts
@@ -0,0 +1,31 @@
+import type { Instrumentation } from '@opentelemetry/instrumentation';
+import { PrismaInstrumentation } from '@prisma/instrumentation';
+import type { Integration } from '@sentry/types';
+
+import { NodePerformanceIntegration } from './lazy';
+
+/**
+ * Prisma integration
+ *
+ * Capture tracing data for prisma.
+ * Note: This requieres to set:
+ * previewFeatures = ["tracing"]
+ * For the prisma client.
+ * See https://www.prisma.io/docs/concepts/components/prisma-client/opentelemetry-tracing for more details.
+ */
+export class Prisma extends NodePerformanceIntegration implements Integration {
+ /**
+ * @inheritDoc
+ */
+ public static id: string = 'Prisma';
+
+ /**
+ * @inheritDoc`
+ */
+ public name: string = Prisma.id;
+
+ /** @inheritDoc */
+ public setupInstrumentation(): void | Instrumentation[] {
+ return [new PrismaInstrumentation({})];
+ }
+}
diff --git a/packages/node-experimental/src/sdk/client.ts b/packages/node-experimental/src/sdk/client.ts
new file mode 100644
index 000000000000..2f04d1e7d27e
--- /dev/null
+++ b/packages/node-experimental/src/sdk/client.ts
@@ -0,0 +1,43 @@
+import type { Tracer } from '@opentelemetry/api';
+import { trace } from '@opentelemetry/api';
+import { NodeClient, SDK_VERSION } from '@sentry/node';
+import { OtelHooks } from '@sentry/opentelemetry-node';
+
+import type { NodePreviewClientOptions } from '../types';
+
+/**
+ * A client built on top of the NodeClient, which provides some otel-specific things on top.
+ */
+export class NodePreviewClient extends NodeClient {
+ public otelHooks: OtelHooks;
+
+ private _tracer: Tracer | undefined;
+
+ public constructor(options: ConstructorParameters[0]) {
+ super(options);
+
+ this.otelHooks = new OtelHooks();
+ }
+
+ /** Get the OTEL tracer. */
+ public get tracer(): Tracer {
+ if (this._tracer) {
+ return this._tracer;
+ }
+
+ const name = '@sentry/node-experimental';
+ const version = SDK_VERSION;
+ const tracer = trace.getTracer(name, version);
+ this._tracer = tracer;
+
+ return tracer;
+ }
+
+ /**
+ * Get the options for the node preview client.
+ */
+ public getOptions(): NodePreviewClientOptions {
+ // Just a type-cast, basically
+ return super.getOptions();
+ }
+}
diff --git a/packages/node-experimental/src/sdk/handlers.ts b/packages/node-experimental/src/sdk/handlers.ts
new file mode 100644
index 000000000000..2c9b9b1ad832
--- /dev/null
+++ b/packages/node-experimental/src/sdk/handlers.ts
@@ -0,0 +1,5 @@
+import { Handlers } from '@sentry/node';
+
+const { requestHandler, errorHandler } = Handlers;
+
+export { requestHandler, errorHandler };
diff --git a/packages/node-experimental/src/sdk/init.ts b/packages/node-experimental/src/sdk/init.ts
new file mode 100644
index 000000000000..de7556dc71f6
--- /dev/null
+++ b/packages/node-experimental/src/sdk/init.ts
@@ -0,0 +1,38 @@
+import { hasTracingEnabled } from '@sentry/core';
+import { defaultIntegrations as defaultNodeIntegrations, init as initNode } from '@sentry/node';
+
+import { getAutoPerformanceIntegrations } from '../integrations/getAutoPerformanceIntegrations';
+import { Http } from '../integrations/http';
+import type { NodePreviewOptions } from '../types';
+import { NodePreviewClient } from './client';
+import { initOtel } from './initOtel';
+
+const ignoredDefaultIntegrations = ['Http', 'Undici'];
+
+export const defaultIntegrations = [
+ ...defaultNodeIntegrations.filter(i => !ignoredDefaultIntegrations.includes(i.name)),
+ new Http(),
+];
+
+/**
+ * Initialize Sentry for Node.
+ */
+export function init(options: NodePreviewOptions | undefined = {}): void {
+ const isTracingEnabled = hasTracingEnabled(options);
+
+ options.defaultIntegrations =
+ options.defaultIntegrations === false
+ ? []
+ : [
+ ...(Array.isArray(options.defaultIntegrations) ? options.defaultIntegrations : defaultIntegrations),
+ ...(isTracingEnabled ? getAutoPerformanceIntegrations() : []),
+ ];
+
+ options.instrumenter = 'otel';
+ options.clientClass = NodePreviewClient;
+
+ initNode(options);
+
+ // Always init Otel, even if tracing is disabled, because we need it for trace propagation & the HTTP integration
+ initOtel();
+}
diff --git a/packages/node-experimental/src/sdk/initOtel.ts b/packages/node-experimental/src/sdk/initOtel.ts
new file mode 100644
index 000000000000..d0e69b4e1883
--- /dev/null
+++ b/packages/node-experimental/src/sdk/initOtel.ts
@@ -0,0 +1,38 @@
+import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
+import { AlwaysOnSampler, NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
+import { getCurrentHub } from '@sentry/core';
+import { SentryPropagator, SentrySpanProcessor } from '@sentry/opentelemetry-node';
+
+import type { NodePreviewClient } from './client';
+
+/**
+ * Initialize OpenTelemetry for Node.
+ * We use the @sentry/opentelemetry-node package to communicate with OpenTelemetry.
+ */
+export function initOtel(): () => void {
+ const client = getCurrentHub().getClient();
+
+ if (client?.getOptions().debug) {
+ diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
+ }
+
+ // We use the custom otelHooks from the client to communicate with @sentry/opentelemetry-node
+ const hooks = client?.otelHooks;
+
+ // Create and configure NodeTracerProvider
+ const provider = new NodeTracerProvider({
+ sampler: new AlwaysOnSampler(),
+ });
+ provider.addSpanProcessor(new SentrySpanProcessor({ hooks }));
+
+ // Initialize the provider
+ provider.register({
+ propagator: new SentryPropagator(),
+ });
+
+ // Cleanup function
+ return () => {
+ void provider.forceFlush();
+ void provider.shutdown();
+ };
+}
diff --git a/packages/node-experimental/src/types.ts b/packages/node-experimental/src/types.ts
new file mode 100644
index 000000000000..c64d38be8b8d
--- /dev/null
+++ b/packages/node-experimental/src/types.ts
@@ -0,0 +1,4 @@
+import type { NodeClient, NodeOptions } from '@sentry/node';
+
+export type NodePreviewOptions = NodeOptions;
+export type NodePreviewClientOptions = ConstructorParameters[0];
diff --git a/packages/node-experimental/src/utils/getRequestSpanData.ts b/packages/node-experimental/src/utils/getRequestSpanData.ts
new file mode 100644
index 000000000000..8d5d45f5f907
--- /dev/null
+++ b/packages/node-experimental/src/utils/getRequestSpanData.ts
@@ -0,0 +1,39 @@
+import type { Span as OtelSpan } from '@opentelemetry/sdk-trace-base';
+import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
+import type { SanitizedRequestData } from '@sentry/types';
+import { getSanitizedUrlString, parseUrl } from '@sentry/utils';
+import type { ClientRequest, IncomingMessage, ServerResponse } from 'http';
+
+/**
+ * Get sanitizied request data from an OTEL span.
+ */
+export function getRequestSpanData(
+ span: OtelSpan,
+ _request: ClientRequest | IncomingMessage,
+ _response: IncomingMessage | ServerResponse,
+): SanitizedRequestData {
+ const data: SanitizedRequestData = {
+ url: span.attributes[SemanticAttributes.HTTP_URL] as string,
+ 'http.method': (span.attributes[SemanticAttributes.HTTP_METHOD] as string) || 'GET',
+ };
+
+ try {
+ const urlStr = span.attributes[SemanticAttributes.HTTP_URL];
+ if (typeof urlStr === 'string') {
+ const url = parseUrl(urlStr);
+
+ data.url = getSanitizedUrlString(url);
+
+ if (url.search) {
+ data['http.query'] = url.search;
+ }
+ if (url.hash) {
+ data['http.fragment'] = url.hash;
+ }
+ }
+ } catch {
+ // ignore
+ }
+
+ return data;
+}
diff --git a/packages/node-experimental/test/helpers/getDefaultNodePreviewClientOptions.ts b/packages/node-experimental/test/helpers/getDefaultNodePreviewClientOptions.ts
new file mode 100644
index 000000000000..c9f3f9e40d2a
--- /dev/null
+++ b/packages/node-experimental/test/helpers/getDefaultNodePreviewClientOptions.ts
@@ -0,0 +1,15 @@
+import { createTransport } from '@sentry/core';
+import { resolvedSyncPromise } from '@sentry/utils';
+
+import type { NodePreviewClientOptions } from '../../src/types';
+
+export function getDefaultNodePreviewClientOptions(
+ options: Partial = {},
+): NodePreviewClientOptions {
+ return {
+ integrations: [],
+ transport: () => createTransport({ recordDroppedEvent: () => undefined }, _ => resolvedSyncPromise({})),
+ stackParser: () => [],
+ ...options,
+ };
+}
diff --git a/packages/node-experimental/test/sdk.test.ts b/packages/node-experimental/test/sdk.test.ts
new file mode 100644
index 000000000000..ea230368b1d8
--- /dev/null
+++ b/packages/node-experimental/test/sdk.test.ts
@@ -0,0 +1,128 @@
+import type { Integration } from '@sentry/types';
+
+import * as auto from '../src/integrations/getAutoPerformanceIntegrations';
+import { init } from '../src/sdk/init';
+import * as sdk from '../src/sdk/init';
+
+// eslint-disable-next-line no-var
+declare var global: any;
+
+const PUBLIC_DSN = 'https://username@domain/123';
+
+class MockIntegration implements Integration {
+ public name: string;
+ public setupOnce: jest.Mock = jest.fn();
+ public constructor(name: string) {
+ this.name = name;
+ }
+}
+
+const defaultIntegrationsBackup = sdk.defaultIntegrations;
+
+describe('init()', () => {
+ let mockAutoPerformanceIntegrations: jest.SpyInstance = jest.fn(() => []);
+
+ beforeEach(() => {
+ global.__SENTRY__ = {};
+
+ mockAutoPerformanceIntegrations = jest.spyOn(auto, 'getAutoPerformanceIntegrations').mockImplementation(() => []);
+ });
+
+ afterEach(() => {
+ // @ts-ignore - Reset the default integrations of node sdk to original
+ sdk.defaultIntegrations = defaultIntegrationsBackup;
+ });
+
+ it("doesn't install default integrations if told not to", () => {
+ const mockDefaultIntegrations = [
+ new MockIntegration('Mock integration 1.1'),
+ new MockIntegration('Mock integration 1.2'),
+ ];
+
+ // @ts-ignore - Replace default integrations with mock integrations, needs ts-ignore because imports are readonly
+ sdk.defaultIntegrations = mockDefaultIntegrations;
+
+ init({ dsn: PUBLIC_DSN, defaultIntegrations: false });
+
+ expect(mockDefaultIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(0);
+ expect(mockDefaultIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(0);
+ expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0);
+ });
+
+ it('installs merged default integrations, with overrides provided through options', () => {
+ const mockDefaultIntegrations = [
+ new MockIntegration('Some mock integration 2.1'),
+ new MockIntegration('Some mock integration 2.2'),
+ ];
+
+ // @ts-ignore - Replace default integrations with mock integrations, needs ts-ignore because imports are readonly
+ sdk.defaultIntegrations = mockDefaultIntegrations;
+
+ const mockIntegrations = [
+ new MockIntegration('Some mock integration 2.1'),
+ new MockIntegration('Some mock integration 2.3'),
+ ];
+
+ init({ dsn: PUBLIC_DSN, integrations: mockIntegrations });
+
+ expect(mockDefaultIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(0);
+ expect(mockDefaultIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0);
+ });
+
+ it('installs integrations returned from a callback function', () => {
+ const mockDefaultIntegrations = [
+ new MockIntegration('Some mock integration 3.1'),
+ new MockIntegration('Some mock integration 3.2'),
+ ];
+
+ // @ts-ignore - Replace default integrations with mock integrations, needs ts-ignore because imports are readonly
+ sdk.defaultIntegrations = mockDefaultIntegrations;
+
+ const newIntegration = new MockIntegration('Some mock integration 3.3');
+
+ init({
+ dsn: PUBLIC_DSN,
+ integrations: integrations => {
+ const newIntegrations = [...integrations];
+ newIntegrations[1] = newIntegration;
+ return newIntegrations;
+ },
+ });
+
+ expect(mockDefaultIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockDefaultIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(0);
+ expect(newIntegration.setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0);
+ });
+
+ it('installs performance default instrumentations if tracing is enabled', () => {
+ const mockDefaultIntegrations = [
+ new MockIntegration('Some mock integration 4.1'),
+ new MockIntegration('Some mock integration 4.2'),
+ ];
+
+ // @ts-ignore - Replace default integrations with mock integrations, needs ts-ignore because imports are readonly
+ sdk.defaultIntegrations = mockDefaultIntegrations;
+
+ const autoPerformanceIntegration = new MockIntegration('Some mock integration 4.4');
+
+ mockAutoPerformanceIntegrations.mockReset().mockImplementation(() => [autoPerformanceIntegration]);
+
+ const mockIntegrations = [
+ new MockIntegration('Some mock integration 4.1'),
+ new MockIntegration('Some mock integration 4.3'),
+ ];
+
+ init({ dsn: PUBLIC_DSN, integrations: mockIntegrations, enableTracing: true });
+
+ expect(mockDefaultIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(0);
+ expect(mockDefaultIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockIntegrations[0].setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockIntegrations[1].setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(autoPerformanceIntegration.setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
+ expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/packages/node-experimental/tsconfig.json b/packages/node-experimental/tsconfig.json
new file mode 100644
index 000000000000..bf45a09f2d71
--- /dev/null
+++ b/packages/node-experimental/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+
+ "include": ["src/**/*"],
+
+ "compilerOptions": {
+ // package-specific options
+ }
+}
diff --git a/packages/node-experimental/tsconfig.test.json b/packages/node-experimental/tsconfig.test.json
new file mode 100644
index 000000000000..87f6afa06b86
--- /dev/null
+++ b/packages/node-experimental/tsconfig.test.json
@@ -0,0 +1,12 @@
+{
+ "extends": "./tsconfig.json",
+
+ "include": ["test/**/*"],
+
+ "compilerOptions": {
+ // should include all types from `./tsconfig.json` plus types for all test frameworks used
+ "types": ["node", "jest"]
+
+ // other package-specific, test-specific options
+ }
+}
diff --git a/packages/node-experimental/tsconfig.types.json b/packages/node-experimental/tsconfig.types.json
new file mode 100644
index 000000000000..65455f66bd75
--- /dev/null
+++ b/packages/node-experimental/tsconfig.types.json
@@ -0,0 +1,10 @@
+{
+ "extends": "./tsconfig.json",
+
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "build/types"
+ }
+}
diff --git a/packages/node/src/sdk.ts b/packages/node/src/sdk.ts
index 06be10d848b6..7287d1938346 100644
--- a/packages/node/src/sdk.ts
+++ b/packages/node/src/sdk.ts
@@ -168,7 +168,7 @@ export function init(options: NodeOptions = {}): void {
transport: options.transport || makeNodeTransport,
};
- initAndBind(NodeClient, clientOptions);
+ initAndBind(options.clientClass || NodeClient, clientOptions);
if (options.autoSessionTracking) {
startSessionTracking();
diff --git a/packages/node/src/types.ts b/packages/node/src/types.ts
index b0ecb354dd82..fb128653870f 100644
--- a/packages/node/src/types.ts
+++ b/packages/node/src/types.ts
@@ -1,5 +1,6 @@
import type { ClientOptions, Options, SamplingContext } from '@sentry/types';
+import type { NodeClient } from './client';
import type { NodeTransportOptions } from './transports';
export interface BaseNodeOptions {
@@ -32,6 +33,14 @@ export interface BaseNodeOptions {
*/
includeLocalVariables?: boolean;
+ /**
+ * Specify a custom NodeClient to be used. Must extend NodeClient!
+ * This is not a public, supported API, but used internally only.
+ *
+ * @hidden
+ * */
+ clientClass?: typeof NodeClient;
+
// TODO (v8): Remove this in v8
/**
* @deprecated Moved to constructor options of the `Http` and `Undici` integration.
diff --git a/packages/opentelemetry-node/package.json b/packages/opentelemetry-node/package.json
index 8d8c3ae4a2b8..4943e2fb5c58 100644
--- a/packages/opentelemetry-node/package.json
+++ b/packages/opentelemetry-node/package.json
@@ -34,10 +34,10 @@
"@opentelemetry/semantic-conventions": "1.x"
},
"devDependencies": {
- "@opentelemetry/api": "^1.2.0",
+ "@opentelemetry/api": "^1.4.1",
"@opentelemetry/core": "^1.7.0",
- "@opentelemetry/sdk-trace-base": "^1.7.0",
- "@opentelemetry/sdk-trace-node": "^1.7.0",
+ "@opentelemetry/sdk-trace-base": "^1.15.0",
+ "@opentelemetry/sdk-trace-node": "^1.15.0",
"@opentelemetry/semantic-conventions": "^1.7.0",
"@sentry/node": "7.60.0"
},
diff --git a/packages/opentelemetry-node/src/hooks.ts b/packages/opentelemetry-node/src/hooks.ts
new file mode 100644
index 000000000000..db7511a2a43f
--- /dev/null
+++ b/packages/opentelemetry-node/src/hooks.ts
@@ -0,0 +1,69 @@
+import type { Span as OtelSpan } from '@opentelemetry/sdk-trace-base';
+import type { Span } from '@sentry/types';
+
+/**
+ * Keep some otel hooks separate from the default client hooks.
+ */
+export class OtelHooks {
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ private _hooks: Record = {};
+
+ /**
+ * Fires when an Otel Span is ended.
+ * Receives the Otel Span as argument.
+ * Return `false` from the callback to skip this span in Sentry.
+ */
+ public on(hook: 'spanEnd', callback: (otelSpan: OtelSpan, sentrySpan: Span) => void | false): void;
+
+ /**
+ * @inheritdoc
+ */
+ public on(hook: string, callback: unknown): void {
+ if (!this._hooks[hook]) {
+ this._hooks[hook] = [];
+ }
+
+ // @ts-ignore We assue the types are correct
+ this._hooks[hook].push(callback);
+ }
+
+ /**
+ * Unregister the hook.
+ */
+ public off(hook: 'spanEnd', callback: (otelSpan: OtelSpan, sentrySpan: Span) => void | false): void;
+
+ /**
+ * @inheritdoc
+ */
+ public off(hook: string, callback: unknown): void {
+ if (!this._hooks[hook]) {
+ return;
+ }
+
+ // @ts-ignore We assue the types are correct
+ const index = this._hooks[hook].indexOf(callback);
+ if (index > -1) {
+ this._hooks[hook].splice(index, 1);
+ }
+ }
+
+ /**
+ * Emit the otel span end hook.
+ * Returns `false` if the span should not be sent to Sentry.
+ */
+ public emit(hook: 'spanEnd', otelSpan: OtelSpan, sentrySpan: Span): void | false;
+
+ /**
+ * @inheritdoc
+ */
+ public emit(hook: string, ...rest: unknown[]): void | false {
+ if (this._hooks[hook]) {
+ for (const callback of this._hooks[hook]) {
+ const cancel = callback(...rest);
+ if (cancel === false) {
+ return false;
+ }
+ }
+ }
+ }
+}
diff --git a/packages/opentelemetry-node/src/index.ts b/packages/opentelemetry-node/src/index.ts
index 752c2cfaa0aa..1ef86c354008 100644
--- a/packages/opentelemetry-node/src/index.ts
+++ b/packages/opentelemetry-node/src/index.ts
@@ -1,2 +1,4 @@
export { SentrySpanProcessor } from './spanprocessor';
export { SentryPropagator } from './propagator';
+export { OtelHooks } from './hooks';
+export * from './utils/spanData';
diff --git a/packages/opentelemetry-node/src/spanprocessor.ts b/packages/opentelemetry-node/src/spanprocessor.ts
index 980084a9adec..dbcda429953b 100644
--- a/packages/opentelemetry-node/src/spanprocessor.ts
+++ b/packages/opentelemetry-node/src/spanprocessor.ts
@@ -7,21 +7,33 @@ import type { DynamicSamplingContext, Span as SentrySpan, TraceparentData, Trans
import { isString, logger } from '@sentry/utils';
import { SENTRY_DYNAMIC_SAMPLING_CONTEXT_KEY, SENTRY_TRACE_PARENT_CONTEXT_KEY } from './constants';
+import type { OtelHooks } from './hooks';
import { isSentryRequestSpan } from './utils/isSentryRequest';
import { mapOtelStatus } from './utils/mapOtelStatus';
import { parseSpanDescription } from './utils/parseOtelSpanDescription';
+import { clearOtelSpanData, getOtelSpanData } from './utils/spanData';
export const SENTRY_SPAN_PROCESSOR_MAP: Map = new Map<
SentrySpan['spanId'],
SentrySpan
>();
+// make sure to remove references in maps, to ensure this can be GCed
+function clearSpan(otelSpanId: string): void {
+ clearOtelSpanData(otelSpanId);
+ SENTRY_SPAN_PROCESSOR_MAP.delete(otelSpanId);
+}
+
/**
* Converts OpenTelemetry Spans to Sentry Spans and sends them to Sentry via
* the Sentry SDK.
*/
export class SentrySpanProcessor implements OtelSpanProcessor {
- public constructor() {
+ private _hooks?: OtelHooks;
+
+ public constructor({ hooks }: { hooks?: OtelHooks } = {}) {
+ this._hooks = hooks;
+
addTracingExtensions();
addGlobalEventProcessor(event => {
@@ -98,11 +110,17 @@ export class SentrySpanProcessor implements OtelSpanProcessor {
// leading to an infinite loop.
// In this case, we do not want to finish the span, in order to avoid sending it to Sentry
if (isSentryRequestSpan(otelSpan)) {
- // Make sure to remove any references, so this can be GCed
- SENTRY_SPAN_PROCESSOR_MAP.delete(otelSpanId);
+ clearSpan(otelSpanId);
return;
}
+ if (this._hooks) {
+ if (this._hooks.emit('spanEnd', otelSpan, sentrySpan) === false) {
+ clearSpan(otelSpanId);
+ return;
+ }
+ }
+
otelSpan.events.forEach(event => {
if (event.name !== 'exception') {
return;
@@ -152,7 +170,7 @@ export class SentrySpanProcessor implements OtelSpanProcessor {
sentrySpan.finish(convertOtelTimeToSeconds(otelSpan.endTime));
- SENTRY_SPAN_PROCESSOR_MAP.delete(otelSpanId);
+ clearSpan(otelSpanId);
}
/**
@@ -209,37 +227,57 @@ function updateSpanWithOtelData(sentrySpan: SentrySpan, otelSpan: OtelSpan): voi
const { op, description, data } = parseSpanDescription(otelSpan);
+ const { data: additionalData, tags } = getOtelSpanData(otelSpan.spanContext().spanId);
+
sentrySpan.setStatus(mapOtelStatus(otelSpan));
sentrySpan.setData('otel.kind', SpanKind[kind]);
- Object.keys(attributes).forEach(prop => {
- const value = attributes[prop];
- sentrySpan.setData(prop, value);
- });
-
- if (data) {
- Object.keys(data).forEach(prop => {
- const value = data[prop];
- sentrySpan.setData(prop, value);
+ if (tags) {
+ Object.keys(tags).forEach(prop => {
+ sentrySpan.setTag(prop, tags[prop]);
});
}
+ const allData = { ...attributes, ...data, ...additionalData };
+
+ Object.keys(allData).forEach(prop => {
+ const value = allData[prop];
+ sentrySpan.setData(prop, value);
+ });
+
sentrySpan.op = op;
sentrySpan.description = description;
}
function updateTransactionWithOtelData(transaction: Transaction, otelSpan: OtelSpan): void {
const { op, description, source, data } = parseSpanDescription(otelSpan);
+ const { data: additionalData, tags, contexts, metadata } = getOtelSpanData(otelSpan.spanContext().spanId);
transaction.setContext('otel', {
attributes: otelSpan.attributes,
resource: otelSpan.resource.attributes,
});
- if (data) {
- Object.keys(data).forEach(prop => {
- const value = data[prop];
- transaction.setData(prop, value);
+ if (tags) {
+ Object.keys(tags).forEach(prop => {
+ transaction.setTag(prop, tags[prop]);
+ });
+ }
+
+ if (metadata) {
+ transaction.setMetadata(metadata);
+ }
+
+ const allData = { ...data, ...additionalData };
+
+ Object.keys(allData).forEach(prop => {
+ const value = allData[prop];
+ transaction.setData(prop, value);
+ });
+
+ if (contexts) {
+ Object.keys(contexts).forEach(prop => {
+ transaction.setContext(prop, contexts[prop]);
});
}
diff --git a/packages/opentelemetry-node/src/utils/spanData.ts b/packages/opentelemetry-node/src/utils/spanData.ts
new file mode 100644
index 000000000000..ed83892301d9
--- /dev/null
+++ b/packages/opentelemetry-node/src/utils/spanData.ts
@@ -0,0 +1,33 @@
+import type { Context } from '@sentry/types';
+
+type SentryTags = Record;
+type SentryData = Record;
+type Contexts = Record;
+
+export interface AdditionalOtelSpanData {
+ data: SentryData;
+ tags: SentryTags;
+ contexts: Contexts;
+ metadata: unknown;
+}
+
+const OTEL_SPAN_DATA_MAP: Map = new Map();
+
+/** Add data that should be added to the sentry span resulting from the given otel span ID. */
+export function addOtelSpanData(otelSpanId: string, data: AdditionalOtelSpanData): void {
+ OTEL_SPAN_DATA_MAP.set(otelSpanId, data);
+}
+
+/** Get additional data for a Sentry span. */
+export function getOtelSpanData(otelSpanId: string): AdditionalOtelSpanData {
+ if (OTEL_SPAN_DATA_MAP.has(otelSpanId)) {
+ return OTEL_SPAN_DATA_MAP.get(otelSpanId) as AdditionalOtelSpanData;
+ }
+
+ return { data: {}, tags: {}, contexts: {}, metadata: {} };
+}
+
+/** Add data that should be added to the sentry span resulting from the given otel span ID. */
+export function clearOtelSpanData(otelSpanId: string): void {
+ OTEL_SPAN_DATA_MAP.delete(otelSpanId);
+}
diff --git a/yarn.lock b/yarn.lock
index 197a789d7ceb..62a2265380ab 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3613,6 +3613,11 @@
dependencies:
"@opentelemetry/context-base" "^0.14.0"
+"@opentelemetry/api@1.4.1", "@opentelemetry/api@^1.4.1", "@opentelemetry/api@~1.4.1":
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f"
+ integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==
+
"@opentelemetry/api@^0.12.0":
version "0.12.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.12.0.tgz#0359c3926e8f16fdcd8c78f196bd1e9fc4e66777"
@@ -3620,15 +3625,12 @@
dependencies:
"@opentelemetry/context-base" "^0.12.0"
-"@opentelemetry/api@^1.2.0":
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686"
- integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g==
-
-"@opentelemetry/context-async-hooks@1.7.0":
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-1.7.0.tgz#b78d1f4f30b484d92d7926dc9d29ec1ccd489cf5"
- integrity sha512-g4bMzyVW5dVBeMkyadaf3NRFpmNrdD4Pp9OJsrP29HwIam/zVMNfIWQpT5IBzjtTSMhl/ED5YQYR+UOSjVq3sQ==
+"@opentelemetry/context-async-hooks@1.15.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/context-async-hooks/-/context-async-hooks-1.15.0.tgz#134ecbe9096227f72e3178a15287a420a13746a0"
+ integrity sha512-sfxQOyAyV3WsKswGX0Yx3P+e7t3EtxpF/PC+6e4+rqs88oUfTaP3214iz4GQuuzV9yCG8DRWTZ96J6E/iD0qeA==
+ dependencies:
+ tslib "^2.3.1"
"@opentelemetry/context-base@^0.12.0":
version "0.12.0"
@@ -3640,12 +3642,20 @@
resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.14.0.tgz#c67fc20a4d891447ca1a855d7d70fa79a3533001"
integrity sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw==
-"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.7.0":
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c"
- integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ==
+"@opentelemetry/core@1.14.0":
+ version "1.14.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.14.0.tgz#64e876b29cb736c984d54164cd47433f513eafd3"
+ integrity sha512-MnMZ+sxsnlzloeuXL2nm5QcNczt/iO82UOeQQDHhV83F2fP3sgntW2evvtoxJki0MBLxEsh5ADD7PR/Hn5uzjw==
dependencies:
- "@opentelemetry/semantic-conventions" "1.7.0"
+ "@opentelemetry/semantic-conventions" "1.14.0"
+
+"@opentelemetry/core@1.15.0", "@opentelemetry/core@^1.1.0", "@opentelemetry/core@^1.8.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.0.tgz#2ba928df0443732825a72a766c2edae9a7f9863f"
+ integrity sha512-GGTS6BytfaN8OgbCUOnxg/a9WVsVUj0484zXHZuBzvIXx7V4Tmkb0IHnnhS7Q0cBLNLgjNuvrCpQaP8fIvO4bg==
+ dependencies:
+ "@opentelemetry/semantic-conventions" "1.15.0"
+ tslib "^2.3.1"
"@opentelemetry/core@^0.12.0":
version "0.12.0"
@@ -3656,27 +3666,169 @@
"@opentelemetry/context-base" "^0.12.0"
semver "^7.1.3"
-"@opentelemetry/propagator-b3@1.7.0":
+"@opentelemetry/core@^1.7.0":
version "1.7.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-b3/-/propagator-b3-1.7.0.tgz#8c089c2bab733ea7122cb4a5f7ffaaa355127555"
- integrity sha512-8kKGS1KwArvkThdhubMZlomuREE9FaBcn9L4JrYHh2jly1FZpqOtFNO2byHymVRjH59d43Pa+eJuFpD0Fp7kSw==
+ resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c"
+ integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ==
+ dependencies:
+ "@opentelemetry/semantic-conventions" "1.7.0"
+
+"@opentelemetry/instrumentation-express@~0.33.0":
+ version "0.33.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-express/-/instrumentation-express-0.33.0.tgz#d972ef43420759761f7dbfe78a6ae159cd925a69"
+ integrity sha512-Cem3AssubzUoBK5ab89rBt2kY90i/FFyQwMC9wPjBQldkOaT4cR+5ufvWritXRfoPltqEeX2imLavujNH6EzCw==
dependencies:
- "@opentelemetry/core" "1.7.0"
+ "@opentelemetry/core" "^1.8.0"
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ "@types/express" "4.17.13"
+ tslib "^2.3.1"
-"@opentelemetry/propagator-jaeger@1.7.0":
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.7.0.tgz#1c1439866e05ba81da303ad28286aa25d129bf03"
- integrity sha512-V7i/L1bx+R/ve4z6dTdn2jtvFxGThRsXS2wNb/tWZVfV8gqnePQp+HfoLrqB/Yz2iRPUcMWrcjx6vV78umvJFA==
+"@opentelemetry/instrumentation-fastify@~0.32.0":
+ version "0.32.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.32.0.tgz#9f0846282f5f428b3ec9a749c1111cf2f153986d"
+ integrity sha512-M0zRI5+FfA2UnNk9YSeofhZkM5X46w2lDW/1pVahpIlfyPoEbOdRO2YrfR6Y9t9emR62IKk4tN/IcSgXIK2RRg==
dependencies:
- "@opentelemetry/core" "1.7.0"
+ "@opentelemetry/core" "^1.8.0"
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ tslib "^2.3.1"
-"@opentelemetry/resources@1.7.0":
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5"
- integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg==
+"@opentelemetry/instrumentation-graphql@~0.35.0":
+ version "0.35.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.35.0.tgz#45d2df2be320c7289aff49cabfbbfa8791670b19"
+ integrity sha512-hKuOXTzB8UBaxVteKU2nMRGnUPt6bD9SSBBLYaDOGGPF1Gs4XsiuMMRuyXomMIudelM7flPpbuqiP9YoSJuXQQ==
dependencies:
- "@opentelemetry/core" "1.7.0"
- "@opentelemetry/semantic-conventions" "1.7.0"
+ "@opentelemetry/instrumentation" "^0.41.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation-http@~0.41.0":
+ version "0.41.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-http/-/instrumentation-http-0.41.0.tgz#c92ffcb9581544d76d17540f7df442fad8601035"
+ integrity sha512-O/YTVH4xE96rxRYoo14vayM9s0MUTtMASMAtYS3yvXMJETgc5aFnTrWezKQ6VJ2Lew5qfm1ZISzFURLSUM0qTw==
+ dependencies:
+ "@opentelemetry/core" "1.15.0"
+ "@opentelemetry/instrumentation" "0.41.0"
+ "@opentelemetry/semantic-conventions" "1.15.0"
+ semver "^7.5.1"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation-mongodb@~0.36.0":
+ version "0.36.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.36.0.tgz#2ee2acffb1869d9dc3a89e9b879be987e18c1b11"
+ integrity sha512-bisDLBO0JqydPh4rkgrbYhnFOd4T2ZAnFAnBFll9TB1jJEHTeeobdBThuwxvur5q5ZfbjevreUcMydG6UBNMaA==
+ dependencies:
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/sdk-metrics" "^1.9.1"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation-mongoose@~0.33.0":
+ version "0.33.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.33.0.tgz#8063740274120105f559bcf663125d3f7cc00cb4"
+ integrity sha512-IB4zCJ7vsiILx5hjPH7PtlvKIVN84m3rER8zu7xeaMpfpzD5/khj6et0x1aE+KzPS49nIOZx3qmH67MocSNevg==
+ dependencies:
+ "@opentelemetry/core" "^1.8.0"
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation-mysql2@~0.34.0":
+ version "0.34.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.34.0.tgz#48f560b7169128195d19114451c3a5c907b7833a"
+ integrity sha512-wEJ9BcZTT/60a69V5GS/XlQx+JyoOKKYYR/kdZ2p/XY/UI+kELPSWiLZAR00YLYi33g0zVZlKG3gfHU1KFn5sQ==
+ dependencies:
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation-mysql@~0.34.0":
+ version "0.34.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.34.0.tgz#437294f3c8b02ad76b3d56e77f28d9af6cf19c91"
+ integrity sha512-muBzhaSk3to1XK2aSMFTP9lW6YALebQ8ick9raDBESiLf8JREZDJWVlhfaigeJGBk53tUBZ3Ty1g1Cfe15+OhQ==
+ dependencies:
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ "@types/mysql" "2.15.19"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation-nestjs-core@~0.33.0":
+ version "0.33.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.33.0.tgz#f2d64f033f9a84c2ba4ce85c0ec1381ec542b452"
+ integrity sha512-/c1nipi2XLt2TQlFpKNof44o99H7BmdOWiZBAdIATJpvOKPbn+Ggt4OQQdtmxFyzMX13dTxgtpQ5RX2Orvxz2Q==
+ dependencies:
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation-pg@~0.36.0":
+ version "0.36.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.36.0.tgz#43270d2849a0e074ec6eb705dc12216e5c7cc84c"
+ integrity sha512-S9RmzTILWTl7AVfdp/e8lWQTlpwrpoPbpxAfEJ1ENzTlPMmdw0jWPAQTgrTLQa6cpzhiypDHts3g2b6hc1zFYQ==
+ dependencies:
+ "@opentelemetry/core" "^1.8.0"
+ "@opentelemetry/instrumentation" "^0.41.0"
+ "@opentelemetry/semantic-conventions" "^1.0.0"
+ "@opentelemetry/sql-common" "^0.40.0"
+ "@types/pg" "8.6.1"
+ "@types/pg-pool" "2.0.3"
+ tslib "^2.3.1"
+
+"@opentelemetry/instrumentation@0.40.0":
+ version "0.40.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.40.0.tgz#13d5f2d60c3fafef124ab6961a32204f7ef8bb25"
+ integrity sha512-23TzBKPflUS1uEq5SXymnQKQDSda35KvHjnvxdcDQGE+wg6hwDHgScUCWiBmZW4sxAaPcANfs+Wc9B7yDuyT6Q==
+ dependencies:
+ "@types/shimmer" "^1.0.2"
+ import-in-the-middle "1.3.5"
+ require-in-the-middle "^7.1.0"
+ semver "^7.3.2"
+ shimmer "^1.2.1"
+
+"@opentelemetry/instrumentation@0.41.0", "@opentelemetry/instrumentation@^0.41.0", "@opentelemetry/instrumentation@~0.41.0":
+ version "0.41.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.0.tgz#a67a7f6d215d8802c2e956907a913b793037e04d"
+ integrity sha512-Ut9SnZfi7MexOk+GHCMjEtYHogIb6v1dfbnq+oTbQj0lOQUSNLtlO6bXwUdtmPhbvrx6bC0AGr1L6g3rNimv9w==
+ dependencies:
+ "@types/shimmer" "^1.0.2"
+ import-in-the-middle "1.4.1"
+ require-in-the-middle "^7.1.1"
+ semver "^7.5.1"
+ shimmer "^1.2.1"
+ tslib "^2.3.1"
+
+"@opentelemetry/propagator-b3@1.15.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-b3/-/propagator-b3-1.15.0.tgz#502c3b7030646e7654ce243ae24b67aeac405a53"
+ integrity sha512-YafSIITpCmo76VdlJ/GvS5x+uuRWCU5BqCOV9CITi11Tk4aqTxMR3pXlMoPYQWstUUgacQf4dGcdvdS+1rkDWQ==
+ dependencies:
+ "@opentelemetry/core" "1.15.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/propagator-jaeger@1.15.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.15.0.tgz#098cfebe885f8c0f4ed3073aa9a7c0aa253086c8"
+ integrity sha512-OU6WNxuqjxNZoRcIBCsmvTBktAPuBUj1bh+DI+oYAvzwP2NXLavSDJWjVMGTJQDgZuR7lFijmx9EfwyAO9x37Q==
+ dependencies:
+ "@opentelemetry/core" "1.15.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/resources@1.14.0":
+ version "1.14.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.14.0.tgz#d6b0a4e71c2706d33c8c6ec7a7b8fea6ad27ddea"
+ integrity sha512-qRfWIgBxxl3z47E036Aey0Lj2ZjlFb27Q7Xnj1y1z/P293RXJZGLtcfn/w8JF7v1Q2hs3SDGxz7Wb9Dko1YUQA==
+ dependencies:
+ "@opentelemetry/core" "1.14.0"
+ "@opentelemetry/semantic-conventions" "1.14.0"
+
+"@opentelemetry/resources@1.15.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.0.tgz#748a6ae9017636b8b30f5dee1fff3e166e51f63d"
+ integrity sha512-Sb8A6ZXHXDlgHv32UNRE3y8McWE3vkb5dsSttYArYa5ZpwjiF5ge0vnnKUUnG7bY0AgF9VBIOORZE8gsrnD2WA==
+ dependencies:
+ "@opentelemetry/core" "1.15.0"
+ "@opentelemetry/semantic-conventions" "1.15.0"
+ tslib "^2.3.1"
"@opentelemetry/resources@^0.12.0":
version "0.12.0"
@@ -3686,26 +3838,59 @@
"@opentelemetry/api" "^0.12.0"
"@opentelemetry/core" "^0.12.0"
-"@opentelemetry/sdk-trace-base@1.7.0", "@opentelemetry/sdk-trace-base@^1.7.0":
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5"
- integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg==
+"@opentelemetry/sdk-metrics@^1.9.1":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.15.0.tgz#e47ad688882fc2daedcbbe3db16a5c110feb23e8"
+ integrity sha512-fFUnAcPvlXO39nlIduGuaeCuiZyFtSLCn9gW/0djFRO5DFst4m4gcT6+llXvNWuUvtGB49s56NP10B9IZRN0Rw==
dependencies:
- "@opentelemetry/core" "1.7.0"
- "@opentelemetry/resources" "1.7.0"
- "@opentelemetry/semantic-conventions" "1.7.0"
+ "@opentelemetry/core" "1.15.0"
+ "@opentelemetry/resources" "1.15.0"
+ lodash.merge "^4.6.2"
+ tslib "^2.3.1"
-"@opentelemetry/sdk-trace-node@^1.7.0":
- version "1.7.0"
- resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.7.0.tgz#83bf458c33db930144cebed72b524034135fce7b"
- integrity sha512-DCAAbi0Zbb1pIofQcKzoAVy9/6bz24asFYeLb4fW/8QYAaawDnxumA++5Huw/RcYdJs8q8AIRBykwjYWWCm/5A==
- dependencies:
- "@opentelemetry/context-async-hooks" "1.7.0"
- "@opentelemetry/core" "1.7.0"
- "@opentelemetry/propagator-b3" "1.7.0"
- "@opentelemetry/propagator-jaeger" "1.7.0"
- "@opentelemetry/sdk-trace-base" "1.7.0"
- semver "^7.3.5"
+"@opentelemetry/sdk-trace-base@1.14.0":
+ version "1.14.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.14.0.tgz#831af08f002228a11e577ff860eb6059c8b80fb7"
+ integrity sha512-NzRGt3PS+HPKfQYMb6Iy8YYc5OKA73qDwci/6ujOIvyW9vcqBJSWbjZ8FeLEAmuatUB5WrRhEKu9b0sIiIYTrQ==
+ dependencies:
+ "@opentelemetry/core" "1.14.0"
+ "@opentelemetry/resources" "1.14.0"
+ "@opentelemetry/semantic-conventions" "1.14.0"
+
+"@opentelemetry/sdk-trace-base@1.15.0", "@opentelemetry/sdk-trace-base@^1.15.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.0.tgz#92340ded8f9fec1aaa63afb40c6e7e01769c2852"
+ integrity sha512-udt1c9VHipbZwvCPIQR1VLg25Z4AMR/g0X8KmcInbFruGWQ/lptVPkz3yvWAsGSta5yHNQ3uoPwcyCygGnQ6Lg==
+ dependencies:
+ "@opentelemetry/core" "1.15.0"
+ "@opentelemetry/resources" "1.15.0"
+ "@opentelemetry/semantic-conventions" "1.15.0"
+ tslib "^2.3.1"
+
+"@opentelemetry/sdk-trace-node@^1.15.0", "@opentelemetry/sdk-trace-node@~1.15.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.15.0.tgz#2d49eafb070a6a53e8df7e91dab30ec2370ba310"
+ integrity sha512-TKBx9oThZUVKkoGpXhFT/XUgpjq28TWwc6j3JlsL+cJX77DKBnVC+2H+kdVVJHRzyfqDx4LEJJVCwQO3K+cbXA==
+ dependencies:
+ "@opentelemetry/context-async-hooks" "1.15.0"
+ "@opentelemetry/core" "1.15.0"
+ "@opentelemetry/propagator-b3" "1.15.0"
+ "@opentelemetry/propagator-jaeger" "1.15.0"
+ "@opentelemetry/sdk-trace-base" "1.15.0"
+ semver "^7.5.1"
+ tslib "^2.3.1"
+
+"@opentelemetry/semantic-conventions@1.14.0":
+ version "1.14.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.14.0.tgz#6a729b7f372ce30f77a3f217c09bc216f863fccb"
+ integrity sha512-rJfCY8rCWz3cb4KI6pEofnytvMPuj3YLQwoscCCYZ5DkdiPjo15IQ0US7+mjcWy9H3fcZIzf2pbJZ7ck/h4tug==
+
+"@opentelemetry/semantic-conventions@1.15.0", "@opentelemetry/semantic-conventions@^1.0.0", "@opentelemetry/semantic-conventions@~1.15.0":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.0.tgz#e6173daa5fd61f353b02c858001388bf26e9d059"
+ integrity sha512-f3wwFrFyCpGrFBrFs7lCUJSCSCGyeKG52c+EKeobs3Dd29M75yO6GYkt6PkYPfDawxSlV5p+4yJPPk8tPObzTQ==
+ dependencies:
+ tslib "^2.3.1"
"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.7.0":
version "1.7.0"
@@ -3717,6 +3902,13 @@
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-0.12.0.tgz#7e392aecdbdbd5d737d3995998b120dc17589ab0"
integrity sha512-BuCcDW0uLNYYTns0/LwXkJ8lp8aDm7kpS+WunEmPAPRSCe6ciOYRvzn5reqJfX93rf+6A3U2SgrBnCTH+0qoQQ==
+"@opentelemetry/sql-common@^0.40.0":
+ version "0.40.0"
+ resolved "https://registry.yarnpkg.com/@opentelemetry/sql-common/-/sql-common-0.40.0.tgz#8cbed0722354d62997c3b9e1adf0e16257be6b15"
+ integrity sha512-vSqRJYUPJVjMFQpYkQS3ruexCPSZJ8esne3LazLwtCPaPRvzZ7WG3tX44RouAn7w4wMp8orKguBqtt+ng2UTnw==
+ dependencies:
+ "@opentelemetry/core" "^1.1.0"
+
"@opentelemetry/tracing@^0.12.0":
version "0.12.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/tracing/-/tracing-0.12.0.tgz#769927721d417bfac85eef50c2af068bedce8873"
@@ -3773,6 +3965,15 @@
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e.tgz#bf5e2373ca68ce7556b967cb4965a7095e93fe53"
integrity sha512-e3k2Vd606efd1ZYy2NQKkT4C/pn31nehyLhVug6To/q8JT8FpiMrDy7zmm3KLF0L98NOQQcutaVtAPhzKhzn9w==
+"@prisma/instrumentation@~5.0.0":
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/@prisma/instrumentation/-/instrumentation-5.0.0.tgz#6112461d0ffa401b9278c26d3fef027b0b42820d"
+ integrity sha512-GUt9ztQXriBmxPIDBd20eBHOX+LaF3zj4ot6mpMB/2YkceU4MvicdEoaX2VkF3r/xM7TatCF9IR2d35wOIv2GA==
+ dependencies:
+ "@opentelemetry/api" "1.4.1"
+ "@opentelemetry/instrumentation" "0.40.0"
+ "@opentelemetry/sdk-trace-base" "1.14.0"
+
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
@@ -4808,6 +5009,16 @@
"@types/qs" "*"
"@types/range-parser" "*"
+"@types/express@4.17.13":
+ version "4.17.13"
+ resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034"
+ integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==
+ dependencies:
+ "@types/body-parser" "*"
+ "@types/express-serve-static-core" "^4.17.18"
+ "@types/qs" "*"
+ "@types/serve-static" "*"
+
"@types/express@4.17.14", "@types/express@^4.17.14", "@types/express@^4.17.2":
version "4.17.14"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c"
@@ -4982,6 +5193,13 @@
"@types/bson" "*"
"@types/node" "*"
+"@types/mysql@2.15.19":
+ version "2.15.19"
+ resolved "https://registry.yarnpkg.com/@types/mysql/-/mysql-2.15.19.tgz#d158927bb7c1a78f77e56de861a3b15cae0e7aed"
+ integrity sha512-wSRg2QZv14CWcZXkgdvHbbV2ACufNy5EgI8mBBxnJIptchv7DBy/h53VMa2jDhyo0C9MO4iowE6z9vF8Ja1DkQ==
+ dependencies:
+ "@types/node" "*"
+
"@types/mysql@^2.15.21":
version "2.15.21"
resolved "https://registry.yarnpkg.com/@types/mysql/-/mysql-2.15.21.tgz#7516cba7f9d077f980100c85fd500c8210bd5e45"
@@ -5037,6 +5255,31 @@
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.0.tgz#38590dc2c3cf5717154064e3ee9b6947ee21b299"
integrity sha512-oPwPSj4a1wu9rsXTEGIJz91ISU725t0BmSnUhb57sI+M8XEmvUop84lzuiYdq0Y5M6xLY8DBPg0C2xEQKLyvBA==
+"@types/pg-pool@2.0.3":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@types/pg-pool/-/pg-pool-2.0.3.tgz#3eb8df2933f617f219a53091ad4080c94ba1c959"
+ integrity sha512-fwK5WtG42Yb5RxAwxm3Cc2dJ39FlgcaNiXKvtTLAwtCn642X7dgel+w1+cLWwpSOFImR3YjsZtbkfjxbHtFAeg==
+ dependencies:
+ "@types/pg" "*"
+
+"@types/pg@*":
+ version "8.10.2"
+ resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.10.2.tgz#7814d1ca02c8071f4d0864c1b17c589b061dba43"
+ integrity sha512-MKFs9P6nJ+LAeHLU3V0cODEOgyThJ3OAnmOlsZsxux6sfQs3HRXR5bBn7xG5DjckEFhTAxsXi7k7cd0pCMxpJw==
+ dependencies:
+ "@types/node" "*"
+ pg-protocol "*"
+ pg-types "^4.0.1"
+
+"@types/pg@8.6.1":
+ version "8.6.1"
+ resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.6.1.tgz#099450b8dc977e8197a44f5229cedef95c8747f9"
+ integrity sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==
+ dependencies:
+ "@types/node" "*"
+ pg-protocol "*"
+ pg-types "^2.2.0"
+
"@types/pg@^8.6.5":
version "8.6.5"
resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.6.5.tgz#2dce9cb468a6a5e0f1296a59aea3ac75dd27b702"
@@ -5166,6 +5409,11 @@
"@types/mime" "^1"
"@types/node" "*"
+"@types/shimmer@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f"
+ integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==
+
"@types/sinon@^7.0.11":
version "7.5.2"
resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.5.2.tgz#5e2f1d120f07b9cda07e5dedd4f3bf8888fccdb9"
@@ -5963,6 +6211,11 @@ acorn-import-assertions@^1.7.6:
resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9"
integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==
+acorn-import-assertions@^1.9.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac"
+ integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==
+
acorn-jsx@^5.3.1:
version "5.3.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
@@ -9202,6 +9455,11 @@ cjs-module-lexer@^1.0.0:
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
+cjs-module-lexer@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107"
+ integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==
+
class-utils@^0.3.5:
version "0.3.6"
resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
@@ -15284,6 +15542,23 @@ import-from@^2.1.0:
dependencies:
resolve-from "^3.0.0"
+import-in-the-middle@1.3.5:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.3.5.tgz#78384fbcfc7c08faf2b1f61cb94e7dd25651df9c"
+ integrity sha512-yzHlBqi1EBFrkieAnSt8eTgO5oLSl+YJ7qaOpUH/PMqQOMZoQ/RmDlwnTLQrwYto+gHYjRG+i/IbsB1eDx32NQ==
+ dependencies:
+ module-details-from-path "^1.0.3"
+
+import-in-the-middle@1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.1.tgz#31b25123bc35d556986a172bb398a3e6c32af9be"
+ integrity sha512-hGG0PcCsykVo8MBVH8l0uEWLWW6DXMgJA9jvC0yps6M3uIJ8L/tagTCbyF8Ud5TtqJ8/jmZL1YkyySyeVkVQrA==
+ dependencies:
+ acorn "^8.8.2"
+ acorn-import-assertions "^1.9.0"
+ cjs-module-lexer "^1.2.2"
+ module-details-from-path "^1.0.3"
+
import-lazy@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
@@ -18986,6 +19261,11 @@ module-definition@^3.3.1:
ast-module-types "^2.7.1"
node-source-walk "^4.0.0"
+module-details-from-path@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b"
+ integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==
+
module-lookup-amd@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/module-lookup-amd/-/module-lookup-amd-7.0.1.tgz#d67c1a93f2ff8e38b8774b99a638e9a4395774b2"
@@ -20253,7 +20533,7 @@ object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.6:
define-properties "^1.1.4"
es-abstract "^1.20.4"
-obuf@^1.0.0, obuf@^1.1.2:
+obuf@^1.0.0, obuf@^1.1.2, obuf@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
@@ -21085,6 +21365,11 @@ pg-int8@1.0.1:
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
+pg-numeric@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a"
+ integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==
+
pg-pool@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.5.1.tgz#f499ce76f9bf5097488b3b83b19861f28e4ed905"
@@ -21106,6 +21391,19 @@ pg-types@^2.1.0, pg-types@^2.2.0:
postgres-date "~1.0.4"
postgres-interval "^1.1.0"
+pg-types@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-4.0.1.tgz#31857e89d00a6c66b06a14e907c3deec03889542"
+ integrity sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==
+ dependencies:
+ pg-int8 "1.0.1"
+ pg-numeric "1.0.2"
+ postgres-array "~3.0.1"
+ postgres-bytea "~3.0.0"
+ postgres-date "~2.0.1"
+ postgres-interval "^3.0.0"
+ postgres-range "^1.1.1"
+
pg@^8.7.3:
version "8.7.3"
resolved "https://registry.yarnpkg.com/pg/-/pg-8.7.3.tgz#8a5bdd664ca4fda4db7997ec634c6e5455b27c44"
@@ -22289,16 +22587,33 @@ postgres-array@~2.0.0:
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
+postgres-array@~3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-3.0.2.tgz#68d6182cb0f7f152a7e60dc6a6889ed74b0a5f98"
+ integrity sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==
+
postgres-bytea@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=
+postgres-bytea@~3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-3.0.0.tgz#9048dc461ac7ba70a6a42d109221619ecd1cb089"
+ integrity sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==
+ dependencies:
+ obuf "~1.1.2"
+
postgres-date@~1.0.4:
version "1.0.7"
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8"
integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==
+postgres-date@~2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-2.0.1.tgz#638b62e5c33764c292d37b08f5257ecb09231457"
+ integrity sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==
+
postgres-interval@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695"
@@ -22306,6 +22621,16 @@ postgres-interval@^1.1.0:
dependencies:
xtend "^4.0.0"
+postgres-interval@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-3.0.0.tgz#baf7a8b3ebab19b7f38f07566c7aab0962f0c86a"
+ integrity sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==
+
+postgres-range@^1.1.1:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/postgres-range/-/postgres-range-1.1.3.tgz#9ccd7b01ca2789eb3c2e0888b3184225fa859f76"
+ integrity sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==
+
precinct@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/precinct/-/precinct-7.1.0.tgz#a0311e0b59029647eaf57c2d30b8efa9c85d129a"
@@ -23484,6 +23809,15 @@ require-from-string@^2.0.2:
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
+require-in-the-middle@^7.1.0, require-in-the-middle@^7.1.1:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf"
+ integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==
+ dependencies:
+ debug "^4.1.1"
+ module-details-from-path "^1.0.3"
+ resolve "^1.22.1"
+
require-main-filename@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
@@ -24227,7 +24561,7 @@ semver@7.5.3:
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:
+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, semver@^7.5.1:
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==
@@ -24393,6 +24727,11 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
+shimmer@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
+ integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
+
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"