diff --git a/.craft.yml b/.craft.yml
index 7e2ee3217533..355b545e02be 100644
--- a/.craft.yml
+++ b/.craft.yml
@@ -139,6 +139,9 @@ targets:
- name: npm
id: '@sentry/react-router'
includeNames: /^sentry-react-router-\d.*\.tgz$/
+ - name: npm
+ id: '@sentry/nitro'
+ includeNames: /^sentry-nitro-\d.*\.tgz$/
## 7. Other Packages
## 7.1
@@ -256,3 +259,9 @@ targets:
packageUrl: 'https://www.npmjs.com/package/@sentry/elysia'
mainDocsUrl: 'https://docs.sentry.io/platforms/javascript/guides/elysia/'
onlyIfPresent: /^sentry-elysia-\d.*\.tgz$/
+ 'npm:@sentry/nitro':
+ name: 'Sentry Nitro SDK'
+ sdkName: 'sentry.javascript.nitro'
+ packageUrl: 'https://www.npmjs.com/package/@sentry/nitro'
+ mainDocsUrl: 'https://github.com/getsentry/sentry-javascript/tree/master/packages/nitro'
+ onlyIfPresent: /^sentry-nitro-\d.*\.tgz$/
diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index 47edbfeed264..499244434f82 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -52,6 +52,7 @@ body:
- '@sentry/google-cloud-serverless'
- '@sentry/nestjs'
- '@sentry/nextjs'
+ - '@sentry/nitro'
- '@sentry/nuxt'
- '@sentry/react'
- '@sentry/react-router'
diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml
index ac4e1df08841..bbfdba31161f 100644
--- a/.github/workflows/canary.yml
+++ b/.github/workflows/canary.yml
@@ -120,6 +120,9 @@ jobs:
- test-application: 'nestjs-microservices'
build-command: 'test:build-latest'
label: 'nestjs-microservices (latest)'
+ - test-application: 'nitro-3'
+ build-command: 'test:build-canary'
+ label: 'nitro-3 (canary)'
steps:
- name: Check out current commit
diff --git a/.github/workflows/issue-package-label.yml b/.github/workflows/issue-package-label.yml
index 323b17219b1a..fb77747f336f 100644
--- a/.github/workflows/issue-package-label.yml
+++ b/.github/workflows/issue-package-label.yml
@@ -65,6 +65,9 @@ jobs:
"@sentry.nestjs": {
"label": "Nest.js"
},
+ "@sentry.nitro": {
+ "label": "Nitro"
+ },
"@sentry.nextjs": {
"label": "Next.js"
},
diff --git a/README.md b/README.md
index 841a6380b5e2..71ae65bbe406 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ package. Please refer to the README and instructions of those SDKs for more deta
- [`@sentry/gatsby`](https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby): SDK for Gatsby
- [`@sentry/nestjs`](https://github.com/getsentry/sentry-javascript/tree/master/packages/nestjs): SDK for NestJS
- [`@sentry/nextjs`](https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs): SDK for Next.js
+- [`@sentry/nitro`](https://github.com/getsentry/sentry-javascript/tree/master/packages/nitro): SDK for Nitro
- [`@sentry/remix`](https://github.com/getsentry/sentry-javascript/tree/master/packages/remix): SDK for Remix
- [`@sentry/tanstackstart-react`](https://github.com/getsentry/sentry-javascript/tree/master/packages/tanstackstart-react): SDK for TanStack Start React
- [`@sentry/aws-serverless`](https://github.com/getsentry/sentry-javascript/tree/master/packages/aws-serverless): SDK
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/.npmrc b/dev-packages/e2e-tests/test-applications/nitro-3/.npmrc
new file mode 100644
index 000000000000..070f80f05092
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/.npmrc
@@ -0,0 +1,2 @@
+@sentry:registry=http://127.0.0.1:4873
+@sentry-internal:registry=http://127.0.0.1:4873
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/index.html b/dev-packages/e2e-tests/test-applications/nitro-3/index.html
new file mode 100644
index 000000000000..4e9315ac391e
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+ Nitro E2E Test
+
+
+ Nitro E2E Test App
+
+
+
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/instrument.mjs b/dev-packages/e2e-tests/test-applications/nitro-3/instrument.mjs
new file mode 100644
index 000000000000..53b80d309a5b
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/instrument.mjs
@@ -0,0 +1,8 @@
+import * as Sentry from '@sentry/nitro';
+
+Sentry.init({
+ environment: 'qa', // dynamic sampling bias to keep transactions
+ dsn: process.env.E2E_TEST_DSN,
+ tunnel: `http://localhost:3031/`, // proxy server
+ tracesSampleRate: 1,
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/package.json b/dev-packages/e2e-tests/test-applications/nitro-3/package.json
new file mode 100644
index 000000000000..ab92769115d1
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "nitro-3",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "build": "vite build",
+ "start": "PORT=3030 NODE_OPTIONS='--import ./instrument.mjs' node .output/server/index.mjs",
+ "clean": "npx rimraf node_modules pnpm-lock.yaml .output",
+ "test": "playwright test",
+ "test:build": "pnpm install && pnpm build",
+ "test:assert": "pnpm test"
+ },
+ "dependencies": {
+ "@sentry/browser": "latest || *",
+ "@sentry/nitro": "latest || *"
+ },
+ "devDependencies": {
+ "@playwright/test": "~1.56.0",
+ "@sentry-internal/test-utils": "link:../../../test-utils",
+ "@sentry/core": "latest || *",
+ "nitro": "^3.0.260415-beta",
+ "rolldown": "latest",
+ "vite": "latest"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ }
+}
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/playwright.config.mjs b/dev-packages/e2e-tests/test-applications/nitro-3/playwright.config.mjs
new file mode 100644
index 000000000000..31f2b913b58b
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/playwright.config.mjs
@@ -0,0 +1,7 @@
+import { getPlaywrightConfig } from '@sentry-internal/test-utils';
+
+const config = getPlaywrightConfig({
+ startCommand: `pnpm start`,
+});
+
+export default config;
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/server/api/index.ts b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/index.ts
new file mode 100644
index 000000000000..a9fca21eecfb
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/index.ts
@@ -0,0 +1,5 @@
+import { defineHandler } from 'nitro/h3';
+
+export default defineHandler(() => {
+ return { status: 'ok' };
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-error.ts b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-error.ts
new file mode 100644
index 000000000000..170efb1977ab
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-error.ts
@@ -0,0 +1,5 @@
+import { defineHandler } from 'nitro/h3';
+
+export default defineHandler(() => {
+ throw new Error('This is a test error');
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-isolation/[id].ts b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-isolation/[id].ts
new file mode 100644
index 000000000000..a8c2cd7a99f5
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-isolation/[id].ts
@@ -0,0 +1,10 @@
+import { getDefaultIsolationScope, setTag } from '@sentry/core';
+import { defineHandler } from 'nitro/h3';
+
+export default defineHandler(() => {
+ setTag('my-isolated-tag', true);
+ // Check if the tag leaked into the default (global) isolation scope
+ setTag('my-global-scope-isolated-tag', getDefaultIsolationScope().getScopeData().tags['my-isolated-tag']);
+
+ throw new Error('Isolation test error');
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-nesting.ts b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-nesting.ts
new file mode 100644
index 000000000000..687c6f3f1e9a
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-nesting.ts
@@ -0,0 +1,16 @@
+import { startSpan } from '@sentry/nitro';
+import { defineHandler } from 'nitro/h3';
+
+export default defineHandler(() => {
+ startSpan({ name: 'db.select', op: 'db' }, () => {
+ // simulate a select query
+ });
+
+ startSpan({ name: 'db.insert', op: 'db' }, () => {
+ startSpan({ name: 'db.serialize', op: 'serialize' }, () => {
+ // simulate serializing data before insert
+ });
+ });
+
+ return { status: 'ok', nesting: true };
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-param/[id].ts b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-param/[id].ts
new file mode 100644
index 000000000000..ef67525b36ba
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-param/[id].ts
@@ -0,0 +1,6 @@
+import { defineHandler } from 'nitro/h3';
+
+export default defineHandler(event => {
+ const id = event.req.url;
+ return { id };
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-transaction.ts b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-transaction.ts
new file mode 100644
index 000000000000..b488b371310d
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/server/api/test-transaction.ts
@@ -0,0 +1,5 @@
+import { defineHandler } from 'nitro/h3';
+
+export default defineHandler(() => {
+ return { status: 'ok', transaction: true };
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/server/middleware/test.ts b/dev-packages/e2e-tests/test-applications/nitro-3/server/middleware/test.ts
new file mode 100644
index 000000000000..92d8f80c3756
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/server/middleware/test.ts
@@ -0,0 +1,10 @@
+import { defineHandler, getQuery, setResponseHeader } from 'nitro/h3';
+
+export default defineHandler(event => {
+ setResponseHeader(event, 'x-sentry-test-middleware', 'executed');
+
+ const query = getQuery(event);
+ if (query['middleware-error'] === '1') {
+ throw new Error('Middleware error');
+ }
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/src/main.ts b/dev-packages/e2e-tests/test-applications/nitro-3/src/main.ts
new file mode 100644
index 000000000000..d27d0ba1763a
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/src/main.ts
@@ -0,0 +1,10 @@
+import * as Sentry from '@sentry/browser';
+
+// Let's us test trace propagation
+Sentry.init({
+ environment: 'qa',
+ dsn: 'https://public@dsn.ingest.sentry.io/1337',
+ tunnel: 'http://localhost:3031/', // proxy server
+ integrations: [Sentry.browserTracingIntegration()],
+ tracesSampleRate: 1.0,
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/start-event-proxy.mjs b/dev-packages/e2e-tests/test-applications/nitro-3/start-event-proxy.mjs
new file mode 100644
index 000000000000..928e68908661
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/start-event-proxy.mjs
@@ -0,0 +1,6 @@
+import { startEventProxyServer } from '@sentry-internal/test-utils';
+
+startEventProxyServer({
+ port: 3031,
+ proxyServerName: 'nitro-3',
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/nitro-3/tests/errors.test.ts
new file mode 100644
index 000000000000..8e419ac9ba62
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/tests/errors.test.ts
@@ -0,0 +1,45 @@
+import { expect, test } from '@playwright/test';
+import { waitForError } from '@sentry-internal/test-utils';
+
+test('Sends an error event to Sentry', async ({ request }) => {
+ const errorEventPromise = waitForError('nitro-3', event => {
+ return !event.type && !!event.exception?.values?.some(v => v.value === 'This is a test error');
+ });
+
+ await request.get('/api/test-error');
+
+ const errorEvent = await errorEventPromise;
+
+ // Nitro wraps thrown errors in an HTTPError with .cause, producing a chained exception
+ expect(errorEvent.exception?.values).toHaveLength(2);
+
+ // The innermost exception (values[0]) is the original thrown error
+ expect(errorEvent.exception?.values?.[0]?.type).toBe('Error');
+ expect(errorEvent.exception?.values?.[0]?.value).toBe('This is a test error');
+ expect(errorEvent.exception?.values?.[0]?.mechanism).toEqual(
+ expect.objectContaining({
+ handled: false,
+ type: 'auto.function.nitro.captureErrorHook',
+ }),
+ );
+
+ // The outermost exception (values[1]) is the HTTPError wrapper
+ expect(errorEvent.exception?.values?.[1]?.type).toBe('HTTPError');
+ expect(errorEvent.exception?.values?.[1]?.value).toBe('This is a test error');
+});
+
+test('Does not send 404 errors to Sentry', async ({ request }) => {
+ let errorReceived = false;
+
+ void waitForError('nitro-3', event => {
+ if (!event.type) {
+ errorReceived = true;
+ return true;
+ }
+ return false;
+ });
+
+ await request.get('/api/non-existent-route');
+
+ expect(errorReceived).toBe(false);
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/tests/isolation.test.ts b/dev-packages/e2e-tests/test-applications/nitro-3/tests/isolation.test.ts
new file mode 100644
index 000000000000..7234fa0948ca
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/tests/isolation.test.ts
@@ -0,0 +1,25 @@
+import { expect, test } from '@playwright/test';
+import { waitForError, waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Isolation scope prevents tag leaking between requests', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', event => {
+ return event?.transaction === 'GET /api/test-isolation/:id';
+ });
+
+ const errorPromise = waitForError('nitro-3', event => {
+ return !event.type && !!event.exception?.values?.some(v => v.value === 'Isolation test error');
+ });
+
+ await request.get('/api/test-isolation/1').catch(() => {
+ // noop - route throws
+ });
+
+ const transactionEvent = await transactionEventPromise;
+ const error = await errorPromise;
+
+ // Assert that isolation scope works properly
+ expect(error.tags?.['my-isolated-tag']).toBe(true);
+ expect(error.tags?.['my-global-scope-isolated-tag']).not.toBeDefined();
+ expect(transactionEvent.tags?.['my-isolated-tag']).toBe(true);
+ expect(transactionEvent.tags?.['my-global-scope-isolated-tag']).not.toBeDefined();
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/tests/middleware.test.ts b/dev-packages/e2e-tests/test-applications/nitro-3/tests/middleware.test.ts
new file mode 100644
index 000000000000..eec281d28f98
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/tests/middleware.test.ts
@@ -0,0 +1,40 @@
+import { expect, test } from '@playwright/test';
+import { waitForError, waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Creates middleware spans for requests', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', event => {
+ return event?.transaction === 'GET /api/test-transaction';
+ });
+
+ const response = await request.get('/api/test-transaction');
+
+ expect(response.headers()['x-sentry-test-middleware']).toBe('executed');
+
+ const transactionEvent = await transactionEventPromise;
+
+ // h3 middleware spans have origin auto.http.nitro.h3 and op middleware.nitro
+ const h3MiddlewareSpans = transactionEvent.spans?.filter(
+ span => span.origin === 'auto.http.nitro.h3' && span.op === 'middleware.nitro',
+ );
+ expect(h3MiddlewareSpans?.length).toBeGreaterThanOrEqual(1);
+});
+
+test('Captures errors thrown in middleware with error status on span', async ({ request }) => {
+ const errorEventPromise = waitForError('nitro-3', event => {
+ return !event.type && !!event.exception?.values?.some(v => v.value === 'Middleware error');
+ });
+
+ const transactionEventPromise = waitForTransaction('nitro-3', event => {
+ return event?.transaction === 'GET /api/test-transaction' && event?.contexts?.trace?.status === 'internal_error';
+ });
+
+ await request.get('/api/test-transaction?middleware-error=1');
+
+ const errorEvent = await errorEventPromise;
+ expect(errorEvent.exception?.values?.some(v => v.value === 'Middleware error')).toBe(true);
+
+ const transactionEvent = await transactionEventPromise;
+
+ // The transaction span should have error status
+ expect(transactionEvent.contexts?.trace?.status).toBe('internal_error');
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/tests/span-nesting.test.ts b/dev-packages/e2e-tests/test-applications/nitro-3/tests/span-nesting.test.ts
new file mode 100644
index 000000000000..090f8af36fb2
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/tests/span-nesting.test.ts
@@ -0,0 +1,146 @@
+import { expect, test } from '@playwright/test';
+import { waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Span nesting: all spans share the same trace_id', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', event => {
+ return event?.transaction === 'GET /api/test-nesting';
+ });
+
+ await request.get('/api/test-nesting');
+
+ const event = await transactionEventPromise;
+ const traceId = event.contexts?.trace?.trace_id;
+
+ expect(traceId).toMatch(/[a-f0-9]{32}/);
+
+ // Every child span must belong to the same trace
+ for (const span of event.spans ?? []) {
+ expect(span.trace_id).toBe(traceId);
+ }
+});
+
+test('Span nesting: h3 middleware spans are children of the srvx request span', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', event => {
+ return event?.transaction === 'GET /api/test-nesting';
+ });
+
+ await request.get('/api/test-nesting');
+
+ const event = await transactionEventPromise;
+
+ // Find the srvx request span
+ const srvxSpan = event.spans?.find(span => span.origin === 'auto.http.nitro.srvx' && span.op === 'http.server');
+ expect(srvxSpan).toBeDefined();
+
+ // All h3 middleware spans should be children of the srvx span
+ const h3Spans = event.spans?.filter(span => span.origin === 'auto.http.nitro.h3');
+ expect(h3Spans?.length).toBeGreaterThanOrEqual(1);
+
+ for (const span of h3Spans ?? []) {
+ expect(span.parent_span_id).toBe(srvxSpan!.span_id);
+ }
+});
+
+test('Span nesting: manual startSpan calls inside route handler are children of the srvx request span', async ({
+ request,
+}) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', event => {
+ return event?.transaction === 'GET /api/test-nesting';
+ });
+
+ await request.get('/api/test-nesting');
+
+ const event = await transactionEventPromise;
+
+ // Find the srvx request span — this is the parent of all h3 and manual spans
+ const srvxSpan = event.spans?.find(span => span.origin === 'auto.http.nitro.srvx' && span.op === 'http.server');
+ expect(srvxSpan).toBeDefined();
+ const srvxSpanId = srvxSpan!.span_id;
+
+ // Find the manually created db spans
+ const dbSelectSpan = event.spans?.find(span => span.op === 'db' && span.description === 'db.select');
+ const dbInsertSpan = event.spans?.find(span => span.op === 'db' && span.description === 'db.insert');
+ expect(dbSelectSpan).toBeDefined();
+ expect(dbInsertSpan).toBeDefined();
+
+ // FIXME: Once nitro's h3 tracing plugin emits a separate span for route handlers (type: "route"),
+ // the db spans should be children of the h3 route handler span, not the srvx span directly.
+ // Currently nitro bypasses h3's ~routes for file-based routing, so h3 only emits middleware spans.
+ // Both db spans should be children of the srvx request span
+ expect(dbSelectSpan!.parent_span_id).toBe(srvxSpanId);
+ expect(dbInsertSpan!.parent_span_id).toBe(srvxSpanId);
+
+ // Both db spans should be siblings (same parent)
+ expect(dbSelectSpan!.parent_span_id).toBe(dbInsertSpan!.parent_span_id);
+
+ // The serialize span should be nested inside the db.insert span
+ const serializeSpan = event.spans?.find(span => span.op === 'serialize' && span.description === 'db.serialize');
+ expect(serializeSpan).toBeDefined();
+ expect(serializeSpan!.parent_span_id).toBe(dbInsertSpan!.span_id);
+});
+
+// FIXME: Nitro's file-based routing bypasses h3's ~routes, so h3's tracing plugin never wraps
+// route handlers with type: "route". Once this is fixed upstream or we add our own wrapping,
+// uncomment these tests to verify the h3 route handler span exists and is the parent of manual spans.
+//
+// test('Span nesting: h3 route handler span is a child of the srvx request span', async ({ request }) => {
+// const transactionEventPromise = waitForTransaction('nitro-3', event => {
+// return event?.transaction === 'GET /api/test-nesting';
+// });
+//
+// await request.get('/api/test-nesting');
+//
+// const event = await transactionEventPromise;
+//
+// const srvxSpan = event.spans?.find(span => span.origin === 'auto.http.nitro.srvx' && span.op === 'http.server');
+// expect(srvxSpan).toBeDefined();
+//
+// const h3HandlerSpan = event.spans?.find(
+// span => span.origin === 'auto.http.nitro.h3' && span.op === 'http.server',
+// );
+// expect(h3HandlerSpan).toBeDefined();
+// expect(h3HandlerSpan!.parent_span_id).toBe(srvxSpan!.span_id);
+// });
+//
+// test('Span nesting: manual startSpan calls are children of the h3 route handler span', async ({ request }) => {
+// const transactionEventPromise = waitForTransaction('nitro-3', event => {
+// return event?.transaction === 'GET /api/test-nesting';
+// });
+//
+// await request.get('/api/test-nesting');
+//
+// const event = await transactionEventPromise;
+//
+// const h3HandlerSpan = event.spans?.find(
+// span => span.origin === 'auto.http.nitro.h3' && span.op === 'http.server',
+// );
+// expect(h3HandlerSpan).toBeDefined();
+//
+// const dbSelectSpan = event.spans?.find(span => span.op === 'db' && span.description === 'db.select');
+// const dbInsertSpan = event.spans?.find(span => span.op === 'db' && span.description === 'db.insert');
+// expect(dbSelectSpan!.parent_span_id).toBe(h3HandlerSpan!.span_id);
+// expect(dbInsertSpan!.parent_span_id).toBe(h3HandlerSpan!.span_id);
+// });
+
+test('Span nesting: middleware spans start before manual spans in the span tree', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', event => {
+ return event?.transaction === 'GET /api/test-nesting';
+ });
+
+ await request.get('/api/test-nesting');
+
+ const event = await transactionEventPromise;
+
+ // Middleware spans should start before the manual db spans
+ const middlewareSpans = event.spans?.filter(span => span.op === 'middleware.nitro') ?? [];
+ const dbSpans = event.spans?.filter(span => span.op === 'db') ?? [];
+
+ expect(middlewareSpans.length).toBeGreaterThanOrEqual(1);
+ expect(dbSpans.length).toBeGreaterThanOrEqual(1);
+
+ const earliestMiddlewareStart = Math.min(...middlewareSpans.map(s => s.start_timestamp));
+ const earliestDbStart = Math.min(...dbSpans.map(s => s.start_timestamp));
+
+ // Middleware should start before the db spans
+ expect(earliestMiddlewareStart).toBeLessThanOrEqual(earliestDbStart);
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/tests/trace-propagation.test.ts b/dev-packages/e2e-tests/test-applications/nitro-3/tests/trace-propagation.test.ts
new file mode 100644
index 000000000000..705521ad759d
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/tests/trace-propagation.test.ts
@@ -0,0 +1,16 @@
+import { expect, test } from '@playwright/test';
+import { waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Propagates server trace to client pageload via Server-Timing headers', async ({ page }) => {
+ const clientTxnPromise = waitForTransaction('nitro-3', event => {
+ return event?.contexts?.trace?.op === 'pageload';
+ });
+
+ await page.goto('/');
+
+ const clientTxn = await clientTxnPromise;
+
+ expect(clientTxn.contexts?.trace?.trace_id).toBeDefined();
+ expect(clientTxn.contexts?.trace?.trace_id).toMatch(/[a-f0-9]{32}/);
+ expect(clientTxn.contexts?.trace?.op).toBe('pageload');
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nitro-3/tests/transactions.test.ts
new file mode 100644
index 000000000000..48de9c4349df
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/tests/transactions.test.ts
@@ -0,0 +1,78 @@
+import { expect, test } from '@playwright/test';
+import { waitForTransaction } from '@sentry-internal/test-utils';
+
+test('Sends a transaction event for a successful route', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', transactionEvent => {
+ return transactionEvent?.transaction === 'GET /api/test-transaction';
+ });
+
+ await request.get('/api/test-transaction');
+
+ const transactionEvent = await transactionEventPromise;
+
+ expect(transactionEvent).toEqual(
+ expect.objectContaining({
+ transaction: 'GET /api/test-transaction',
+ type: 'transaction',
+ }),
+ );
+
+ // srvx.request creates a span for the request
+ const srvxSpans = transactionEvent.spans?.filter(span => span.origin === 'auto.http.nitro.srvx');
+ expect(srvxSpans?.length).toBeGreaterThanOrEqual(1);
+
+ // h3 creates a child span for the route handler
+ const h3Spans = transactionEvent.spans?.filter(span => span.origin === 'auto.http.nitro.h3');
+ expect(h3Spans?.length).toBeGreaterThanOrEqual(1);
+});
+
+test('Sets correct HTTP status code on transaction', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', transactionEvent => {
+ return transactionEvent?.transaction === 'GET /api/test-transaction';
+ });
+
+ await request.get('/api/test-transaction');
+
+ const transactionEvent = await transactionEventPromise;
+
+ expect(transactionEvent.contexts?.trace?.data).toEqual(
+ expect.objectContaining({
+ 'http.response.status_code': 200,
+ }),
+ );
+
+ expect(transactionEvent.contexts?.trace?.status).toBe('ok');
+});
+
+test('Uses parameterized route for transaction name', async ({ request }) => {
+ const transactionEventPromise = waitForTransaction('nitro-3', transactionEvent => {
+ return transactionEvent?.transaction === 'GET /api/test-param/:id';
+ });
+
+ await request.get('/api/test-param/123');
+
+ const transactionEvent = await transactionEventPromise;
+
+ expect(transactionEvent).toEqual(
+ expect.objectContaining({
+ transaction: 'GET /api/test-param/:id',
+ transaction_info: expect.objectContaining({ source: 'route' }),
+ type: 'transaction',
+ }),
+ );
+
+ expect(transactionEvent.contexts?.trace?.data).toEqual(
+ expect.objectContaining({
+ 'http.route': '/api/test-param/:id',
+ }),
+ );
+});
+
+test('Sets Server-Timing response headers for trace propagation', async ({ request }) => {
+ const response = await request.get('/api/test-transaction');
+ const headers = response.headers();
+
+ expect(headers['server-timing']).toBeDefined();
+ expect(headers['server-timing']).toContain('sentry-trace;desc="');
+ expect(headers['server-timing']).toContain('baggage;desc="');
+});
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/tsconfig.json b/dev-packages/e2e-tests/test-applications/nitro-3/tsconfig.json
new file mode 100644
index 000000000000..b9a951fbebb1
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "paths": {
+ "~/*": ["./*"]
+ }
+ },
+ "include": ["src/**/*.ts", "routes/**/*.ts", "vite.config.ts"]
+}
diff --git a/dev-packages/e2e-tests/test-applications/nitro-3/vite.config.ts b/dev-packages/e2e-tests/test-applications/nitro-3/vite.config.ts
new file mode 100644
index 000000000000..d488f8298777
--- /dev/null
+++ b/dev-packages/e2e-tests/test-applications/nitro-3/vite.config.ts
@@ -0,0 +1,15 @@
+import { withSentryConfig } from '@sentry/nitro';
+import { nitro } from 'nitro/vite';
+import { defineConfig } from 'vite';
+
+export default defineConfig({
+ plugins: [
+ nitro(
+ // FIXME: Nitro plugin has a type issue
+ // @ts-expect-error
+ withSentryConfig({
+ serverDir: './server',
+ }),
+ ),
+ ],
+});
diff --git a/dev-packages/e2e-tests/verdaccio-config/config.yaml b/dev-packages/e2e-tests/verdaccio-config/config.yaml
index d80ed2aa429f..8878490df729 100644
--- a/dev-packages/e2e-tests/verdaccio-config/config.yaml
+++ b/dev-packages/e2e-tests/verdaccio-config/config.yaml
@@ -242,6 +242,12 @@ packages:
unpublish: $all
# proxy: npmjs # Don't proxy for E2E tests!
+ '@sentry/nitro':
+ access: $all
+ publish: $all
+ unpublish: $all
+ # proxy: npmjs # Don't proxy for E2E tests!
+
'@sentry-internal/*':
access: $all
publish: $all
diff --git a/package.json b/package.json
index 511970b04c2f..662e0fa94c95 100644
--- a/package.json
+++ b/package.json
@@ -71,6 +71,7 @@
"packages/integration-shims",
"packages/nestjs",
"packages/nextjs",
+ "packages/nitro",
"packages/node",
"packages/node-core",
"packages/node-native",
diff --git a/packages/nitro/LICENSE b/packages/nitro/LICENSE
new file mode 100644
index 000000000000..0ecae617386e
--- /dev/null
+++ b/packages/nitro/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Functional Software, Inc. dba Sentry
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+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/nitro/README.md b/packages/nitro/README.md
new file mode 100644
index 000000000000..367e70b456e4
--- /dev/null
+++ b/packages/nitro/README.md
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+> NOTICE: This package is in beta state and may be subject to breaking changes.
+
+# Official Sentry SDK for Nitro
+
+[](https://www.npmjs.com/package/@sentry/nitro)
+[](https://www.npmjs.com/package/@sentry/nitro)
+[](https://www.npmjs.com/package/@sentry/nitro)
+
+## Links
+
+- [Official Nitro SDK Docs](https://docs.sentry.io/platforms/javascript/guides/nitro/)
+
+## Compatibility
+
+The minimum supported version of Nitro is `3.0.0-alpha.1`.
+
+## General
+
+This package is a wrapper around `@sentry/node` with added instrumentation for Nitro's features like:
+
+- HTTP handlers and error capturing.
+- [Middleware instrumentation](https://nitro.build/guide/routing#middleware).
+
+
+
+## Manual Setup
+
+### 1. Prerequisites & Installation
+
+1. Install the Sentry Nitro SDK:
+
+ ```bash
+ # Using npm
+ npm install @sentry/nitro
+
+ # Using yarn
+ yarn add @sentry/nitro
+
+ # Using pnpm
+ pnpm add @sentry/nitro
+ ```
+
+### 2. Build-Time Nitro Config Setup
+
+1. Import `withSentryConfig` from `@sentry/nitro` and call it with your Nitro config.
+
+#### In `nitro.config.ts`
+
+If you are using a dedicated `nitro.config.ts` file, you can import `withSentryConfig` from `@sentry/nitro` and call it with your Nitro config.
+
+```javascript
+import { defineNitroConfig } from 'nitro/config';
+import { withSentryConfig } from '@sentry/nitro';
+
+const config = defineNitroConfig({
+ // ...
+});
+
+export default withSentryConfig(config, {
+ // Sentry Build Options
+});
+```
+
+#### In `vite.config.ts`
+
+If you are using Nitro as a Vite plugin, you can import `withSentryConfig` from `@sentry/nitro` and call it with your Nitro config.
+
+```ts
+import { defineConfig } from 'vite';
+import { nitro } from 'nitro/vite';
+import { withSentryConfig } from '@sentry/nitro';
+
+export default defineConfig({
+ plugins: [nitro()],
+ nitro: withSentryConfig(
+ {
+ // Nitro options
+ },
+ {
+ // Sentry Build Options
+ },
+ ),
+});
+```
+
+### 3. Sentry Config Setup
+
+Create an `instrument.mjs` file in your project root to initialize the Sentry SDK:
+
+```javascript
+import * as Sentry from '@sentry/nitro';
+
+Sentry.init({
+ dsn: '__YOUR_DSN__',
+ tracesSampleRate: 1.0,
+});
+```
+
+Then use `--import` in `NODE_OPTIONS` to load the instrumentation before your app code:
+
+```bash
+NODE_OPTIONS='--import ./instrument.mjs' npx nitro dev
+```
+
+This works with any Nitro command (`nitro dev`, `nitro preview`, or a production start script).
+
+## Uploading Source Maps
+
+The `withSentryConfig` function automatically configures source map uploading when the `authToken`, `org`, and `project`
+options are provided:
+
+```javascript
+export default withSentryConfig(config, {
+ org: 'your-sentry-org',
+ project: 'your-sentry-project',
+ authToken: process.env.SENTRY_AUTH_TOKEN,
+});
+```
+
+## Troubleshoot
+
+If you encounter any issues with error tracking or integrations, refer to the official [Sentry Nitro SDK documentation](https://docs.sentry.io/platforms/javascript/guides/nitro/). If the documentation does not provide the necessary information, consider opening an issue on GitHub.
diff --git a/packages/nitro/package.json b/packages/nitro/package.json
new file mode 100644
index 000000000000..2f5ee0d52fa8
--- /dev/null
+++ b/packages/nitro/package.json
@@ -0,0 +1,72 @@
+{
+ "name": "@sentry/nitro",
+ "version": "10.49.0",
+ "description": "Official Sentry SDK for Nitro",
+ "repository": "git://github.com/getsentry/sentry-javascript.git",
+ "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nitro",
+ "author": "Sentry",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.19.1"
+ },
+ "files": [
+ "/build"
+ ],
+ "main": "build/esm/index.js",
+ "module": "build/esm/index.js",
+ "types": "build/types/index.d.ts",
+ "typesVersions": {
+ "*": {
+ "plugins": [
+ "build/types/plugins.d.ts"
+ ]
+ }
+ },
+ "exports": {
+ "./package.json": "./package.json",
+ ".": {
+ "types": "./build/types/index.d.ts",
+ "node": {
+ "import": "./build/esm/index.js"
+ }
+ }
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "peerDependencies": {
+ "nitro": ">=3.0.0-0 <4.0.0 || 3.0.260311-beta || 3.0.260415-beta"
+ },
+ "dependencies": {
+ "@sentry/core": "10.49.0",
+ "@sentry/node": "10.49.0",
+ "@sentry/opentelemetry": "10.49.0"
+ },
+ "devDependencies": {
+ "h3": "^2.0.1-rc.13",
+ "nitro": "^3.0.260415-beta"
+ },
+ "scripts": {
+ "build": "run-p build:transpile build:types",
+ "build:dev": "yarn build",
+ "build:transpile": "rollup -c rollup.npm.config.mjs",
+ "build:types": "run-s build:types:core",
+ "build:types:core": "tsc -p tsconfig.types.json",
+ "build:watch": "run-p build:transpile:watch build:types:watch",
+ "build:dev:watch": "yarn build:watch",
+ "build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch",
+ "build:types:watch": "tsc -p tsconfig.types.json --watch",
+ "build:tarball": "npm pack",
+ "clean": "rimraf build coverage sentry-nitro-*.tgz",
+ "fix": "eslint . --format stylish --fix",
+ "lint": "eslint . --format stylish",
+ "lint:es-compatibility": "es-check es2022 ./build/esm/*.js --module",
+ "test": "vitest run",
+ "test:watch": "vitest --watch",
+ "yalc:publish": "yalc publish --push --sig"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ },
+ "sideEffects": false
+}
diff --git a/packages/nitro/rollup.npm.config.mjs b/packages/nitro/rollup.npm.config.mjs
new file mode 100644
index 000000000000..1e41829a3a3a
--- /dev/null
+++ b/packages/nitro/rollup.npm.config.mjs
@@ -0,0 +1,12 @@
+import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils';
+
+export default [
+ ...makeNPMConfigVariants(
+ makeBaseNPMConfig({
+ entrypoints: ['src/index.ts', 'src/runtime/plugins/server.ts'],
+ packageSpecificConfig: {
+ external: [/^nitro/, /^h3/, /^srvx/, /^@sentry\/opentelemetry/],
+ },
+ }),
+ ),
+];
diff --git a/packages/nitro/src/common/debug-build.ts b/packages/nitro/src/common/debug-build.ts
new file mode 100644
index 000000000000..60aa50940582
--- /dev/null
+++ b/packages/nitro/src/common/debug-build.ts
@@ -0,0 +1,8 @@
+declare const __DEBUG_BUILD__: boolean;
+
+/**
+ * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
+ *
+ * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
+ */
+export const DEBUG_BUILD = __DEBUG_BUILD__;
diff --git a/packages/nitro/src/config.ts b/packages/nitro/src/config.ts
new file mode 100644
index 000000000000..219eb453fb18
--- /dev/null
+++ b/packages/nitro/src/config.ts
@@ -0,0 +1,34 @@
+import type { NitroConfig } from 'nitro/types';
+import { createNitroModule } from './module';
+
+type SentryNitroOptions = {
+ // TODO: Add options
+};
+
+/**
+ * Modifies the passed in Nitro configuration with automatic build-time instrumentation.
+ *
+ * @param config A Nitro configuration object, as usually exported in `nitro.config.ts` or `nitro.config.mjs`.
+ * @returns The modified config to be exported
+ */
+export function withSentryConfig(config: NitroConfig, moduleOptions?: SentryNitroOptions): NitroConfig {
+ return setupSentryNitroModule(config, moduleOptions);
+}
+
+/**
+ * Sets up the Sentry Nitro module, useful for meta framework integrations.
+ */
+export function setupSentryNitroModule(
+ config: NitroConfig,
+ _moduleOptions?: SentryNitroOptions,
+ _serverConfigFile?: string,
+): NitroConfig {
+ if (!config.tracingChannel) {
+ config.tracingChannel = true;
+ }
+
+ config.modules = config.modules || [];
+ config.modules.push(createNitroModule());
+
+ return config;
+}
diff --git a/packages/nitro/src/index.ts b/packages/nitro/src/index.ts
new file mode 100644
index 000000000000..51f10f7ba5b5
--- /dev/null
+++ b/packages/nitro/src/index.ts
@@ -0,0 +1,4 @@
+/* eslint-disable import/export */
+export * from './config';
+export * from '@sentry/node';
+export { init } from './sdk';
diff --git a/packages/nitro/src/instruments/instrumentServer.ts b/packages/nitro/src/instruments/instrumentServer.ts
new file mode 100644
index 000000000000..ec891055558b
--- /dev/null
+++ b/packages/nitro/src/instruments/instrumentServer.ts
@@ -0,0 +1,12 @@
+import type { Nitro } from 'nitro/types';
+import { addPlugin } from '../utils/plugin';
+import { createResolver } from '../utils/resolver';
+
+/**
+ * Sets up the Nitro server instrumentation plugin
+ * @param nitro - The Nitro instance.
+ */
+export function instrumentServer(nitro: Nitro): void {
+ const moduleResolver = createResolver(import.meta.url);
+ addPlugin(nitro, moduleResolver.resolve('../runtime/plugins/server'));
+}
diff --git a/packages/nitro/src/module.ts b/packages/nitro/src/module.ts
new file mode 100644
index 000000000000..1f0955301813
--- /dev/null
+++ b/packages/nitro/src/module.ts
@@ -0,0 +1,14 @@
+import type { NitroModule } from 'nitro/types';
+import { instrumentServer } from './instruments/instrumentServer';
+
+/**
+ * Creates a Nitro module to setup the Sentry SDK.
+ */
+export function createNitroModule(): NitroModule {
+ return {
+ name: 'sentry',
+ setup: nitro => {
+ instrumentServer(nitro);
+ },
+ };
+}
diff --git a/packages/nitro/src/runtime/README.md b/packages/nitro/src/runtime/README.md
new file mode 100644
index 000000000000..43c190e6d015
--- /dev/null
+++ b/packages/nitro/src/runtime/README.md
@@ -0,0 +1,5 @@
+# Nitro Runtime
+
+This directory contains the runtime code for Nitro, this includes plugins or any runtime code they may use.
+
+Do not mix runtime code with other code, this directory will be packaged with the SDK and shipped as-is.
diff --git a/packages/nitro/src/runtime/hooks/captureErrorHook.ts b/packages/nitro/src/runtime/hooks/captureErrorHook.ts
new file mode 100644
index 000000000000..38ab4fd699fa
--- /dev/null
+++ b/packages/nitro/src/runtime/hooks/captureErrorHook.ts
@@ -0,0 +1,84 @@
+import {
+ captureException,
+ flushIfServerless,
+ getActiveSpan,
+ getClient,
+ getCurrentScope,
+ getRootSpan,
+ parseUrl,
+ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
+} from '@sentry/core';
+import { HTTPError } from 'h3';
+import type { CapturedErrorContext } from 'nitro/types';
+
+/**
+ * Extracts the relevant context information from the error context (HTTPEvent in Nitro Error)
+ * and creates a structured context object.
+ */
+function extractErrorContext(errorContext: CapturedErrorContext | undefined): Record {
+ const ctx: Record = {};
+
+ if (!errorContext) {
+ return ctx;
+ }
+
+ if (errorContext.event) {
+ ctx.method = errorContext.event.req.method;
+ ctx.path = parseUrl(errorContext.event.req.url).path;
+ }
+
+ if (Array.isArray(errorContext.tags)) {
+ ctx.tags = errorContext.tags;
+ }
+
+ return ctx;
+}
+
+/**
+ * Hook that can be added in a Nitro plugin. It captures an error and sends it to Sentry.
+ */
+export async function captureErrorHook(error: Error, errorContext: CapturedErrorContext): Promise {
+ const sentryClient = getClient();
+ const sentryClientOptions = sentryClient?.getOptions();
+
+ if (
+ sentryClientOptions &&
+ 'enableNitroErrorHandler' in sentryClientOptions &&
+ sentryClientOptions.enableNitroErrorHandler === false
+ ) {
+ return;
+ }
+
+ // Do not report HTTPErrors with 3xx or 4xx status codes
+ if (HTTPError.isError(error) && error.status >= 300 && error.status < 500) {
+ return;
+ }
+
+ const method = errorContext.event?.req.method ?? '';
+ let path: string | null = null;
+
+ try {
+ if (errorContext.event?.req.url) {
+ path = new URL(errorContext.event.req.url).pathname;
+ }
+ } catch {
+ // If URL parsing fails, leave path as null
+ }
+
+ if (path) {
+ getCurrentScope().setTransactionName(`${method} ${path}`);
+ const activeSpan = getActiveSpan();
+ const activeRootSpan = activeSpan ? getRootSpan(activeSpan) : undefined;
+ activeRootSpan?.updateName(`${method} ${path}`);
+ activeRootSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
+ }
+
+ const structuredContext = extractErrorContext(errorContext);
+
+ captureException(error, {
+ captureContext: { contexts: { nitro: structuredContext } },
+ mechanism: { handled: false, type: 'auto.function.nitro.captureErrorHook' },
+ });
+
+ await flushIfServerless();
+}
diff --git a/packages/nitro/src/runtime/hooks/captureTracingEvents.ts b/packages/nitro/src/runtime/hooks/captureTracingEvents.ts
new file mode 100644
index 000000000000..bf70536b7800
--- /dev/null
+++ b/packages/nitro/src/runtime/hooks/captureTracingEvents.ts
@@ -0,0 +1,280 @@
+import {
+ captureException,
+ getActiveSpan,
+ getClient,
+ getHttpSpanDetailsFromUrlObject,
+ getRootSpan,
+ GLOBAL_OBJ,
+ httpHeadersToSpanAttributes,
+ parseStringToURLObject,
+ SEMANTIC_ATTRIBUTE_SENTRY_OP,
+ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
+ SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
+ setHttpStatus,
+ type Span,
+ SPAN_STATUS_ERROR,
+ startSpanManual,
+ updateSpanName,
+} from '@sentry/core';
+import { tracingChannel, type TracingChannelContextWithSpan } from '@sentry/opentelemetry/tracing-channel';
+import type { TracingRequestEvent as H3TracingRequestEvent } from 'h3/tracing';
+import type { RequestEvent as SrvxRequestEvent } from 'srvx/tracing';
+import { setServerTimingHeaders } from './setServerTimingHeaders';
+
+/**
+ * Global object with the trace channels
+ */
+const globalWithTraceChannels = GLOBAL_OBJ as typeof GLOBAL_OBJ & {
+ __SENTRY_NITRO_HTTP_CHANNELS_INSTRUMENTED__: boolean;
+};
+
+/**
+ * Captures tracing events emitted by Nitro tracing channels.
+ */
+export function captureTracingEvents(): void {
+ if (globalWithTraceChannels.__SENTRY_NITRO_HTTP_CHANNELS_INSTRUMENTED__) {
+ return;
+ }
+
+ setupH3TracingChannels();
+ setupSrvxTracingChannels();
+ globalWithTraceChannels.__SENTRY_NITRO_HTTP_CHANNELS_INSTRUMENTED__ = true;
+}
+
+/**
+ * No-op function to satisfy the tracing channel subscribe callbacks
+ */
+const NOOP = (): void => {};
+
+/**
+ * Extracts the HTTP status code from a tracing channel result.
+ * The result is the return value of the traced handler, which is a Response for srvx
+ * and may or may not be a Response for h3.
+ */
+function getResponseStatusCode(result: unknown): number | undefined {
+ if (result && typeof result === 'object' && 'status' in result && typeof result.status === 'number') {
+ return result.status;
+ }
+ return undefined;
+}
+
+function onTraceEnd(data: TracingChannelContextWithSpan<{ result?: unknown }>): void {
+ const statusCode = getResponseStatusCode(data.result);
+ if (data._sentrySpan && statusCode !== undefined) {
+ setHttpStatus(data._sentrySpan, statusCode);
+ }
+
+ data._sentrySpan?.end();
+}
+
+function onTraceError(data: TracingChannelContextWithSpan<{ error: unknown }>): void {
+ captureException(data.error, { mechanism: { type: 'auto.http.nitro.onTraceError', handled: false } });
+ data._sentrySpan?.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' });
+ data._sentrySpan?.end();
+}
+
+/**
+ * Extracts the parameterized route pattern from the h3 event context.
+ */
+function getParameterizedRoute(event: H3TracingRequestEvent['event']): string | undefined {
+ const matchedRoute = event.context?.matchedRoute;
+ if (!matchedRoute) {
+ return undefined;
+ }
+
+ const routePath = matchedRoute.route;
+
+ // Skip catch-all routes as they're not useful for transaction grouping
+ if (!routePath || routePath === '/**') {
+ return undefined;
+ }
+
+ return routePath;
+}
+
+function setupH3TracingChannels(): void {
+ const h3Channel = tracingChannel('h3.request', data => {
+ const parsedUrl = parseStringToURLObject(data.event.url.href);
+ const routePattern = getParameterizedRoute(data.event);
+
+ const [spanName, urlAttributes] = getHttpSpanDetailsFromUrlObject(
+ parsedUrl,
+ 'server',
+ 'auto.http.nitro.h3',
+ { method: data.event.req.method },
+ routePattern,
+ );
+
+ return startSpanManual(
+ {
+ name: spanName,
+ attributes: {
+ ...urlAttributes,
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.nitro.h3',
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: data?.type === 'middleware' ? 'middleware.nitro' : 'http.server',
+ },
+ },
+ span => {
+ setParameterizedRouteAttributes(span, data.event);
+
+ return span;
+ },
+ );
+ });
+
+ h3Channel.subscribe({
+ start: (data: H3TracingRequestEvent) => {
+ setServerTimingHeaders(data.event);
+ },
+ asyncStart: NOOP,
+ end: NOOP,
+ asyncEnd: (data: TracingChannelContextWithSpan) => {
+ onTraceEnd(data);
+
+ if (!data._sentrySpan) {
+ return;
+ }
+
+ // Update the root span (srvx transaction) with the parameterized route name.
+ // The srvx span is created before h3 resolves the route, so it initially has the raw URL.
+ // Note: data.type is always 'middleware' in asyncEnd regardless of handler type,
+ // so we rely on getParameterizedRoute() to filter out catch-all routes instead.
+ const rootSpan = getRootSpan(data._sentrySpan);
+ if (rootSpan && rootSpan !== data._sentrySpan) {
+ const routePattern = getParameterizedRoute(data.event);
+ if (routePattern) {
+ const method = data.event.req.method || 'GET';
+ updateSpanName(rootSpan, `${method} ${routePattern}`);
+ rootSpan.setAttributes({
+ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
+ 'http.route': routePattern,
+ });
+ }
+ }
+ },
+ error: onTraceError,
+ });
+}
+
+function setupSrvxTracingChannels(): void {
+ // Store the parent span per-request so middleware and fetch share the same parent.
+ // WeakMap ensures per-request isolation in concurrent environments and automatic cleanup.
+ const requestParentSpans = new WeakMap();
+
+ const fetchChannel = tracingChannel('srvx.request', data => {
+ const parsedUrl = data.request._url ? parseStringToURLObject(data.request._url.href) : undefined;
+ const [spanName, urlAttributes] = getHttpSpanDetailsFromUrlObject(parsedUrl, 'server', 'auto.http.nitro.srvx', {
+ method: data.request.method,
+ });
+
+ const sendDefaultPii = getClient()?.getOptions().sendDefaultPii ?? false;
+ const headerAttributes = httpHeadersToSpanAttributes(
+ Object.fromEntries(data.request.headers.entries()),
+ sendDefaultPii,
+ );
+
+ return startSpanManual(
+ {
+ name: spanName,
+ attributes: {
+ ...urlAttributes,
+ ...headerAttributes,
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.nitro.srvx',
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: data.middleware ? 'middleware.nitro' : 'http.server',
+ 'server.port': data.server.options.port,
+ },
+ // Use the same parent span as middleware to make them siblings
+ parentSpan: requestParentSpans.get(data.request) || undefined,
+ },
+ span => span,
+ );
+ });
+
+ // Subscribe to events (span already created in bindStore)
+ fetchChannel.subscribe({
+ start: () => {},
+ asyncStart: () => {},
+ end: () => {},
+ asyncEnd: data => {
+ onTraceEnd(data);
+
+ // Clean up parent span reference after the fetch handler completes.
+ requestParentSpans.delete(data.request);
+ },
+ error: data => {
+ onTraceError(data);
+ // Clean up parent span reference on error too
+ requestParentSpans.delete(data.request);
+ },
+ });
+
+ const middlewareChannel = tracingChannel('srvx.middleware', data => {
+ // For the first middleware, capture the current parent span per-request
+ if (data.middleware?.index === 0) {
+ const activeSpan = getActiveSpan();
+ if (activeSpan) {
+ requestParentSpans.set(data.request, activeSpan);
+ }
+ }
+
+ const parsedUrl = data.request._url ? parseStringToURLObject(data.request._url.href) : undefined;
+ const [, urlAttributes] = getHttpSpanDetailsFromUrlObject(parsedUrl, 'server', 'auto.http.nitro.srvx', {
+ method: data.request.method,
+ });
+
+ // Create span as a child of the original parent, not the previous middleware
+ return startSpanManual(
+ {
+ name: `${data.middleware?.handler.name ?? 'unknown'} - ${data.request.method} ${data.request._url?.pathname}`,
+ attributes: {
+ ...urlAttributes,
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.nitro.srvx',
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'middleware.nitro',
+ },
+ parentSpan: requestParentSpans.get(data.request) || undefined,
+ },
+ span => span,
+ );
+ });
+
+ // Subscribe to events (span already created in bindStore)
+ middlewareChannel.subscribe({
+ start: () => {},
+ asyncStart: () => {},
+ end: () => {},
+ asyncEnd: onTraceEnd,
+ error: onTraceError,
+ });
+}
+
+/**
+ * Sets the parameterized route attributes on the span.
+ */
+function setParameterizedRouteAttributes(span: Span, event: H3TracingRequestEvent['event']): void {
+ const rootSpan = getRootSpan(span);
+ if (!rootSpan) {
+ return;
+ }
+
+ const matchedRoutePath = getParameterizedRoute(event);
+ if (!matchedRoutePath) {
+ return;
+ }
+
+ rootSpan.setAttributes({
+ [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
+ 'http.route': matchedRoutePath,
+ });
+
+ const params = event.context?.params;
+
+ if (params && typeof params === 'object') {
+ Object.entries(params).forEach(([key, value]) => {
+ // Based on this convention: https://getsentry.github.io/sentry-conventions/generated/attributes/url.html#urlpathparameterkey
+ rootSpan.setAttributes({
+ [`url.path.parameter.${key}`]: String(value),
+ [`params.${key}`]: String(value),
+ });
+ });
+ }
+}
diff --git a/packages/nitro/src/runtime/hooks/setServerTimingHeaders.ts b/packages/nitro/src/runtime/hooks/setServerTimingHeaders.ts
new file mode 100644
index 000000000000..4573f8171c19
--- /dev/null
+++ b/packages/nitro/src/runtime/hooks/setServerTimingHeaders.ts
@@ -0,0 +1,27 @@
+import { getTraceData } from '@sentry/core';
+import type { TracingRequestEvent as H3TracingRequestEvent } from 'h3/tracing';
+
+/**
+ * Sets Server-Timing response headers for trace propagation to the client.
+ * The browser SDK reads these via the Performance API to connect pageload traces.
+ */
+export function setServerTimingHeaders(event: H3TracingRequestEvent['event']): void {
+ if (event.context._sentryServerTimingSet) {
+ return;
+ }
+
+ const headers = event.res?.headers;
+ if (!headers) {
+ return;
+ }
+
+ const traceData = getTraceData();
+ if (traceData['sentry-trace']) {
+ headers.append('Server-Timing', `sentry-trace;desc="${traceData['sentry-trace']}"`);
+ }
+ if (traceData.baggage) {
+ headers.append('Server-Timing', `baggage;desc="${traceData.baggage}"`);
+ }
+
+ event.context._sentryServerTimingSet = true;
+}
diff --git a/packages/nitro/src/runtime/plugins/server.ts b/packages/nitro/src/runtime/plugins/server.ts
new file mode 100644
index 000000000000..2feee84bcc55
--- /dev/null
+++ b/packages/nitro/src/runtime/plugins/server.ts
@@ -0,0 +1,9 @@
+import { definePlugin } from 'nitro';
+import { captureErrorHook } from '../hooks/captureErrorHook';
+import { captureTracingEvents } from '../hooks/captureTracingEvents';
+
+export default definePlugin(nitroApp => {
+ nitroApp.hooks.hook('error', captureErrorHook);
+
+ captureTracingEvents();
+});
diff --git a/packages/nitro/src/sdk.ts b/packages/nitro/src/sdk.ts
new file mode 100644
index 000000000000..e3b884512d52
--- /dev/null
+++ b/packages/nitro/src/sdk.ts
@@ -0,0 +1,29 @@
+import type { Integration } from '@sentry/core';
+import { applySdkMetadata } from '@sentry/core';
+import type { NodeClient, NodeOptions } from '@sentry/node';
+import { getDefaultIntegrations as getDefaultNodeIntegrations, init as nodeInit } from '@sentry/node';
+
+/**
+ * Initializes the Nitro SDK
+ */
+export function init(options: NodeOptions | undefined = {}): NodeClient | undefined {
+ const opts: NodeOptions = {
+ defaultIntegrations: getDefaultIntegrations(options),
+ ...options,
+ };
+
+ applySdkMetadata(opts, 'nitro', ['nitro', 'node']);
+
+ const client = nodeInit(opts);
+
+ return client;
+}
+
+/**
+ * Get the default integrations for the Nitro SDK.
+ *
+ * @returns The default integrations for the Nitro SDK.
+ */
+export function getDefaultIntegrations(options: NodeOptions): Integration[] | undefined {
+ return [...getDefaultNodeIntegrations(options)];
+}
diff --git a/packages/nitro/src/utils/plugin.ts b/packages/nitro/src/utils/plugin.ts
new file mode 100644
index 000000000000..443e3f430ba1
--- /dev/null
+++ b/packages/nitro/src/utils/plugin.ts
@@ -0,0 +1,9 @@
+import type { Nitro } from 'nitro/types';
+
+/**
+ * Adds a Nitro plugin
+ */
+export function addPlugin(nitro: Nitro, plugin: string): void {
+ nitro.options.plugins = nitro.options.plugins || [];
+ nitro.options.plugins.push(plugin);
+}
diff --git a/packages/nitro/src/utils/resolver.ts b/packages/nitro/src/utils/resolver.ts
new file mode 100644
index 000000000000..f0bde304d929
--- /dev/null
+++ b/packages/nitro/src/utils/resolver.ts
@@ -0,0 +1,25 @@
+import { dirname, resolve } from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+export interface Resolver {
+ resolve(...path: string[]): string;
+}
+
+/**
+ * Creates a resolver for the given base path.
+ * @example
+ * ```ts
+ * const resolver = createResolver(import.meta.url);
+ * resolver.resolve('foo/bar.js');
+ * ```
+ */
+export function createResolver(base: string): Resolver {
+ let resolvedBase = base;
+ if (base.startsWith('file://')) {
+ resolvedBase = dirname(fileURLToPath(base));
+ }
+
+ return {
+ resolve: (...path) => resolve(resolvedBase, ...path),
+ };
+}
diff --git a/packages/nitro/test/index.test.ts b/packages/nitro/test/index.test.ts
new file mode 100644
index 000000000000..bc9db1cddfbb
--- /dev/null
+++ b/packages/nitro/test/index.test.ts
@@ -0,0 +1,11 @@
+// Dummy test to satisfy the test runner
+import { describe, expect, test } from 'vitest';
+import * as NitroServer from '../src';
+
+describe('Nitro SDK', () => {
+ // This is a place holder test at best to satisfy the test runner
+ test('exports client and server SDKs', () => {
+ expect(NitroServer).toBeDefined();
+ expect(NitroServer.init).toBeDefined();
+ });
+});
diff --git a/packages/nitro/test/runtime/hooks/captureErrorHook.test.ts b/packages/nitro/test/runtime/hooks/captureErrorHook.test.ts
new file mode 100644
index 000000000000..804ef569a619
--- /dev/null
+++ b/packages/nitro/test/runtime/hooks/captureErrorHook.test.ts
@@ -0,0 +1,168 @@
+import * as SentryCore from '@sentry/core';
+import { HTTPError } from 'h3';
+import { beforeEach, describe, expect, it, vi } from 'vitest';
+import { captureErrorHook } from '../../../src/runtime/hooks/captureErrorHook';
+
+vi.mock('@sentry/core', async importOriginal => {
+ const mod = await importOriginal();
+ return {
+ ...(mod as any),
+ captureException: vi.fn(),
+ flushIfServerless: vi.fn(),
+ getClient: vi.fn(),
+ getCurrentScope: vi.fn(() => ({
+ setTransactionName: vi.fn(),
+ })),
+ };
+});
+
+describe('captureErrorHook', () => {
+ const mockErrorContext = {
+ event: {
+ req: { method: 'GET', url: 'http://localhost/test-path' },
+ },
+ };
+
+ beforeEach(() => {
+ vi.clearAllMocks();
+ (SentryCore.getClient as any).mockReturnValue({
+ getOptions: () => ({}),
+ });
+ (SentryCore.flushIfServerless as any).mockResolvedValue(undefined);
+ });
+
+ it('should capture regular errors', async () => {
+ const error = new Error('Test error');
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(SentryCore.captureException).toHaveBeenCalledWith(
+ error,
+ expect.objectContaining({
+ mechanism: { handled: false, type: 'auto.function.nitro.captureErrorHook' },
+ }),
+ );
+ });
+
+ it('should include structured context with method and path', async () => {
+ const error = new Error('Test error');
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(SentryCore.captureException).toHaveBeenCalledWith(
+ error,
+ expect.objectContaining({
+ captureContext: {
+ contexts: {
+ nitro: { method: 'GET', path: '/test-path' },
+ },
+ },
+ }),
+ );
+ });
+
+ it('should set transaction name from method and path', async () => {
+ const mockSetTransactionName = vi.fn();
+ (SentryCore.getCurrentScope as any).mockReturnValue({
+ setTransactionName: mockSetTransactionName,
+ });
+
+ const error = new Error('Test error');
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(mockSetTransactionName).toHaveBeenCalledWith('GET /test-path');
+ });
+
+ it('should skip HTTPError with 4xx status codes', async () => {
+ const error = new HTTPError({ status: 404, message: 'Not found' });
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(SentryCore.captureException).not.toHaveBeenCalled();
+ });
+
+ it('should skip HTTPError with 3xx status codes', async () => {
+ const error = new HTTPError({ status: 302, message: 'Redirect' });
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(SentryCore.captureException).not.toHaveBeenCalled();
+ });
+
+ it('should capture HTTPError with 5xx status codes', async () => {
+ const error = new HTTPError({ status: 500, message: 'Server error' });
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(SentryCore.captureException).toHaveBeenCalledWith(
+ error,
+ expect.objectContaining({
+ mechanism: { handled: false, type: 'auto.function.nitro.captureErrorHook' },
+ }),
+ );
+ });
+
+ it('should skip when enableNitroErrorHandler is false', async () => {
+ (SentryCore.getClient as any).mockReturnValue({
+ getOptions: () => ({ enableNitroErrorHandler: false }),
+ });
+
+ const error = new Error('Test error');
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(SentryCore.captureException).not.toHaveBeenCalled();
+ });
+
+ it('should call flushIfServerless after capturing', async () => {
+ const error = new Error('Test error');
+
+ await captureErrorHook(error, mockErrorContext);
+
+ expect(SentryCore.flushIfServerless).toHaveBeenCalled();
+ });
+
+ it('should handle missing event in error context', async () => {
+ const error = new Error('Test error');
+ const contextWithoutEvent = {
+ event: undefined,
+ };
+
+ await captureErrorHook(error, contextWithoutEvent);
+
+ expect(SentryCore.captureException).toHaveBeenCalledWith(
+ error,
+ expect.objectContaining({
+ captureContext: {
+ contexts: {
+ nitro: {},
+ },
+ },
+ }),
+ );
+ });
+
+ it('should include tags in structured context when available', async () => {
+ const error = new Error('Test error');
+ const contextWithTags = {
+ event: {
+ req: { method: 'POST', url: 'http://localhost/api/test' },
+ } as any,
+ tags: ['tag1', 'tag2'],
+ };
+
+ await captureErrorHook(error, contextWithTags);
+
+ expect(SentryCore.captureException).toHaveBeenCalledWith(
+ error,
+ expect.objectContaining({
+ captureContext: {
+ contexts: {
+ nitro: { method: 'POST', path: '/api/test', tags: ['tag1', 'tag2'] },
+ },
+ },
+ }),
+ );
+ });
+});
diff --git a/packages/nitro/test/tsconfig.json b/packages/nitro/test/tsconfig.json
new file mode 100644
index 000000000000..38ca0b13bcdd
--- /dev/null
+++ b/packages/nitro/test/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../tsconfig.test.json"
+}
diff --git a/packages/nitro/tsconfig.json b/packages/nitro/tsconfig.json
new file mode 100644
index 000000000000..202590772b10
--- /dev/null
+++ b/packages/nitro/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../../tsconfig.json",
+
+ "include": ["src/**/*"],
+
+ "compilerOptions": {
+ // package-specific options
+ "module": "esnext",
+ "moduleResolution": "bundler"
+ }
+}
diff --git a/packages/nitro/tsconfig.test.json b/packages/nitro/tsconfig.test.json
new file mode 100644
index 000000000000..c41efeacd92f
--- /dev/null
+++ b/packages/nitro/tsconfig.test.json
@@ -0,0 +1,10 @@
+{
+ "extends": "./tsconfig.json",
+
+ "include": ["test/**/*", "vite.config.ts"],
+
+ "compilerOptions": {
+ // should include all types from `./tsconfig.json` plus types for all test frameworks used
+ "types": ["node"]
+ }
+}
diff --git a/packages/nitro/tsconfig.types.json b/packages/nitro/tsconfig.types.json
new file mode 100644
index 000000000000..6240cd92efaa
--- /dev/null
+++ b/packages/nitro/tsconfig.types.json
@@ -0,0 +1,13 @@
+{
+ "extends": "./tsconfig.json",
+
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "build/types"
+ },
+
+ "//": "This is built separately in tsconfig.setup-types.json",
+ "exclude": ["src/setup.ts"]
+}
diff --git a/packages/nitro/vite.config.ts b/packages/nitro/vite.config.ts
new file mode 100644
index 000000000000..4c0db8cdc068
--- /dev/null
+++ b/packages/nitro/vite.config.ts
@@ -0,0 +1,11 @@
+import baseConfig from '../../vite/vite.config';
+
+export default {
+ ...baseConfig,
+ test: {
+ typecheck: {
+ enabled: true,
+ tsconfig: './tsconfig.test.json',
+ },
+ },
+};
diff --git a/packages/opentelemetry/src/tracingChannel.ts b/packages/opentelemetry/src/tracingChannel.ts
index 984986b7cdcb..5548201c5f4c 100644
--- a/packages/opentelemetry/src/tracingChannel.ts
+++ b/packages/opentelemetry/src/tracingChannel.ts
@@ -18,7 +18,7 @@ import { DEBUG_BUILD } from './debug-build';
*/
export type OtelTracingChannelTransform = (data: TData) => Span;
-type WithSpan = TData & { _sentrySpan?: Span };
+export type TracingChannelContextWithSpan = TContext & { _sentrySpan?: Span };
/**
* A TracingChannel whose `subscribe` / `unsubscribe` accept partial subscriber
@@ -26,7 +26,7 @@ type WithSpan = TData & { _sentrySpan?: Span };
*/
export interface OtelTracingChannel<
TData extends object = object,
- TDataWithSpan extends object = WithSpan,
+ TDataWithSpan extends object = TracingChannelContextWithSpan,
> extends Omit, 'subscribe' | 'unsubscribe'> {
subscribe(subscribers: Partial>): void;
unsubscribe(subscribers: Partial>): void;
@@ -52,10 +52,10 @@ interface ContextApi {
export function tracingChannel(
channelNameOrInstance: string,
transformStart: OtelTracingChannelTransform,
-): OtelTracingChannel> {
- const channel = nativeTracingChannel, WithSpan>(
+): OtelTracingChannel> {
+ const channel = nativeTracingChannel, TracingChannelContextWithSpan>(
channelNameOrInstance,
- ) as unknown as OtelTracingChannel>;
+ ) as unknown as OtelTracingChannel>;
let lookup: AsyncLocalStorageLookup | undefined;
try {
@@ -78,7 +78,7 @@ export function tracingChannel(
// Bind the start channel so that each trace invocation runs the transform
// and stores the resulting context (with span) in AsyncLocalStorage.
// @ts-expect-error bindStore types don't account for AsyncLocalStorage of a different generic type
- channel.start.bindStore(otelStorage, (data: WithSpan) => {
+ channel.start.bindStore(otelStorage, (data: TracingChannelContextWithSpan) => {
const span = transformStart(data);
// Store the span on data so downstream event handlers (asyncEnd, error, etc.) can access it.
diff --git a/yarn.lock b/yarn.lock
index cc45a89c5703..28bb2317af71 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3182,12 +3182,12 @@
tunnel-agent "^0.6.0"
uuid "^8.3.2"
-"@dabh/diagnostics@^2.0.2":
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
- integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==
+"@dabh/diagnostics@^2.0.2", "@dabh/diagnostics@^2.0.8":
+ version "2.0.8"
+ resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.8.tgz#ead97e72ca312cf0e6dd7af0d300b58993a31a5e"
+ integrity sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==
dependencies:
- colorspace "1.1.x"
+ "@so-ric/colorspace" "^1.1.6"
enabled "2.0.x"
kuler "^2.0.0"
@@ -3329,25 +3329,25 @@
lodash "^4.17.21"
resolve "^1.20.0"
-"@emnapi/core@^1.1.0", "@emnapi/core@^1.4.3", "@emnapi/core@^1.7.1":
- version "1.9.1"
- resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.9.1.tgz#2143069c744ca2442074f8078462e51edd63c7bd"
- integrity sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==
+"@emnapi/core@1.9.2", "@emnapi/core@^1.1.0", "@emnapi/core@^1.4.3":
+ version "1.9.2"
+ resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.9.2.tgz#3870265ecffc7352d01ead62d8d83d8358a2d034"
+ integrity sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==
dependencies:
- "@emnapi/wasi-threads" "1.2.0"
+ "@emnapi/wasi-threads" "1.2.1"
tslib "^2.4.0"
-"@emnapi/runtime@^1.1.0", "@emnapi/runtime@^1.4.3", "@emnapi/runtime@^1.7.0", "@emnapi/runtime@^1.7.1":
- version "1.9.1"
- resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.9.1.tgz#115ff2a0d589865be6bd8e9d701e499c473f2a8d"
- integrity sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==
+"@emnapi/runtime@1.9.2", "@emnapi/runtime@^1.1.0", "@emnapi/runtime@^1.4.3", "@emnapi/runtime@^1.7.0":
+ version "1.9.2"
+ resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.9.2.tgz#8b469a3db160817cadb1de9050211a9d1ea84fa2"
+ integrity sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==
dependencies:
tslib "^2.4.0"
-"@emnapi/wasi-threads@1.2.0":
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz#a19d9772cc3d195370bf6e2a805eec40aa75e18e"
- integrity sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==
+"@emnapi/wasi-threads@1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz#28fed21a1ba1ce797c44a070abc94d42f3ae8548"
+ integrity sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==
dependencies:
tslib "^2.4.0"
@@ -5332,13 +5332,11 @@
"@emnapi/runtime" "^1.4.3"
"@tybys/wasm-util" "^0.10.0"
-"@napi-rs/wasm-runtime@^1.1.1":
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz#c3705ab549d176b8dc5172723d6156c3dc426af2"
- integrity sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==
+"@napi-rs/wasm-runtime@^1.1.3":
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz#1eeb8699770481306e5fcd84471f20fcb6177336"
+ integrity sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==
dependencies:
- "@emnapi/core" "^1.7.1"
- "@emnapi/runtime" "^1.7.1"
"@tybys/wasm-util" "^0.10.1"
"@nestjs/common@^10.0.0":
@@ -6471,10 +6469,10 @@
resolved "https://registry.yarnpkg.com/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.76.0.tgz#3dbef82283f871c9cb59325c9daf4f740d11a6e9"
integrity sha512-0jLzzmnu8/mqNhKBnNS2lFUbPEzRdj5ReiZwHGHpjma0+ullmmwP2AqSEqx3ssHDK9CpcEMdKOK2LsbCfhHKIA==
-"@oxc-project/types@=0.120.0":
- version "0.120.0"
- resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.120.0.tgz#af521b0e689dd0eaa04fe4feef9b68d98b74783d"
- integrity sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==
+"@oxc-project/types@=0.124.0":
+ version "0.124.0"
+ resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.124.0.tgz#1dfd7b3fbb98febc2f91b505f48c940db73c8701"
+ integrity sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==
"@oxc-project/types@^0.76.0":
version "0.76.0"
@@ -6831,9 +6829,9 @@
integrity sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==
"@poppinss/colors@^4.1.5":
- version "4.1.5"
- resolved "https://registry.yarnpkg.com/@poppinss/colors/-/colors-4.1.5.tgz#09273b845a4816f5fd9c53c78a3bc656650fe18f"
- integrity sha512-FvdDqtcRCtz6hThExcFOgW0cWX+xwSMWcRuQe5ZEb2m7cVQOAVZOIMt+/v9RxGiD9/OY16qJBXK4CVKWAPalBw==
+ version "4.1.6"
+ resolved "https://registry.yarnpkg.com/@poppinss/colors/-/colors-4.1.6.tgz#bf8546e30cfc5ee8dfe68988ce58eb0ad9d7c21b"
+ integrity sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==
dependencies:
kleur "^4.1.5"
@@ -7191,87 +7189,94 @@
dependencies:
web-streams-polyfill "^3.1.1"
-"@rolldown/binding-android-arm64@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.10.tgz#0bbd3380f49a6d0dc96c9b32fb7dad26ae0dfaa7"
- integrity sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==
-
-"@rolldown/binding-darwin-arm64@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.10.tgz#a30b051784fbb13635e652ba4041c6ce7a4ce7ab"
- integrity sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==
-
-"@rolldown/binding-darwin-x64@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.10.tgz#2d9dea982d5be90b95b6d8836ff26a4b0959d94b"
- integrity sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==
-
-"@rolldown/binding-freebsd-x64@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.10.tgz#4efc3aca43ae4dfb90729eeca6e84ef6e6b38c4a"
- integrity sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==
-
-"@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.10.tgz#4a19a5d24537e925b25e9583b6cd575b2ad9fa27"
- integrity sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==
-
-"@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.10.tgz#01a41e5e905838353ae9a3da10dc8242dcd61453"
- integrity sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==
-
-"@rolldown/binding-linux-arm64-musl@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.10.tgz#bd059e5f83471de29ce35b0ba254995d8091ca40"
- integrity sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==
-
-"@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.10.tgz#fe726a540631015f269a989c0cfb299283190390"
- integrity sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==
-
-"@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.10.tgz#825ced028bad3f1fa9ce83b1f3dac76e0424367f"
- integrity sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==
-
-"@rolldown/binding-linux-x64-gnu@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.10.tgz#b700dae69274aa3d54a16ca5e00e30f47a089119"
- integrity sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==
-
-"@rolldown/binding-linux-x64-musl@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.10.tgz#eb875660ad68a2348acab36a7005699e87f6e9dd"
- integrity sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==
-
-"@rolldown/binding-openharmony-arm64@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.10.tgz#72aa24b412f83025087bcf83ce09634b2bd93c5c"
- integrity sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==
-
-"@rolldown/binding-wasm32-wasi@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.10.tgz#7f3303a96c5dc01d1f4c539b1dcbc16392c6f17d"
- integrity sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==
- dependencies:
- "@napi-rs/wasm-runtime" "^1.1.1"
-
-"@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.10.tgz#3419144a04ad12c69c48536b01fc21ac9d87ecf4"
- integrity sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==
-
-"@rolldown/binding-win32-x64-msvc@1.0.0-rc.10":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.10.tgz#09bee46e6a32c6086beeabc3da12e67be714f882"
- integrity sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==
-
-"@rolldown/pluginutils@1.0.0-rc.10", "@rolldown/pluginutils@^1.0.0-beta.9":
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.10.tgz#eed997f37f928a3300bbe2161f42687d8a3ae759"
- integrity sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==
+"@rolldown/binding-android-arm64@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz#ca20574c469ade7b941f90c9af5e83e7c67f06b7"
+ integrity sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==
+
+"@rolldown/binding-darwin-arm64@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz#ce2c5c7fc4958dfc94783dc09b3d09f3c2e1d072"
+ integrity sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==
+
+"@rolldown/binding-darwin-x64@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz#251ecdf1fdb751031cb6486907c105daaf9dab21"
+ integrity sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==
+
+"@rolldown/binding-freebsd-x64@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz#dbcfe95f409bf671a77bd83bff0fdc877d217728"
+ integrity sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==
+
+"@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz#ea002b45445be6f9ed1883a834b335bc2ccd510f"
+ integrity sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==
+
+"@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz#12b96e7e7821a9dc2cd5c670ad56882987ed5c62"
+ integrity sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==
+
+"@rolldown/binding-linux-arm64-musl@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz#738b0f62f0b65bf676dfe48595017f1883859d1f"
+ integrity sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==
+
+"@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz#3088b9fbc2783033985b558316f87f39281bc533"
+ integrity sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==
+
+"@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz#ac0aa6f1b72e3151d56c43145a71c745cf862a9a"
+ integrity sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==
+
+"@rolldown/binding-linux-x64-gnu@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz#b8cf27aa5be6da641c22dad5665d0240551d2dec"
+ integrity sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==
+
+"@rolldown/binding-linux-x64-musl@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz#4531f9eca77963935026634ba9b61c2535340534"
+ integrity sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==
+
+"@rolldown/binding-openharmony-arm64@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz#66ff691a65f9325171bced98e353b4cc4b0095c3"
+ integrity sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==
+
+"@rolldown/binding-wasm32-wasi@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz#7db6c90aa510eef65d7d0f14e8ca23775e8e5eee"
+ integrity sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==
+ dependencies:
+ "@emnapi/core" "1.9.2"
+ "@emnapi/runtime" "1.9.2"
+ "@napi-rs/wasm-runtime" "^1.1.3"
+
+"@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz#81f9097abbd4493cc13373b26f5a3da8461dbb47"
+ integrity sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==
+
+"@rolldown/binding-win32-x64-msvc@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz#cef11bc89149f3a77771727be75490fbb13ae193"
+ integrity sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==
+
+"@rolldown/pluginutils@1.0.0-rc.15":
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz#e75d7731593e195d23710f9ff49bf5c745c96682"
+ integrity sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==
+
+"@rolldown/pluginutils@^1.0.0-beta.9":
+ version "1.0.0-rc.16"
+ resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz#bc27c8f906309b57c6c10eddb21043fd8e86b87e"
+ integrity sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==
"@rollup/plugin-alias@^5.0.0":
version "5.1.1"
@@ -8390,6 +8395,14 @@
dependencies:
tslib "^2.6.2"
+"@so-ric/colorspace@^1.1.6":
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/@so-ric/colorspace/-/colorspace-1.1.6.tgz#62515d8b9f27746b76950a83bde1af812d91923b"
+ integrity sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==
+ dependencies:
+ color "^5.0.2"
+ text-hex "1.0.x"
+
"@socket.io/component-emitter@~3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553"
@@ -13753,7 +13766,7 @@ collection-visit@^1.0.0:
map-visit "^1.0.0"
object-visit "^1.0.0"
-color-convert@^1.9.0, color-convert@^1.9.3:
+color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
@@ -13767,6 +13780,13 @@ color-convert@^2.0.1:
dependencies:
color-name "~1.1.4"
+color-convert@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-3.1.3.tgz#db6627b97181cb8facdfce755ae26f97ab0711f1"
+ integrity sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==
+ dependencies:
+ color-name "^2.0.0"
+
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
@@ -13777,7 +13797,12 @@ color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-color-string@^1.6.0, color-string@^1.9.0:
+color-name@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-2.1.0.tgz#0b677385c1c4b4edfdeaf77e38fa338e3a40b693"
+ integrity sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==
+
+color-string@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
@@ -13785,19 +13810,18 @@ color-string@^1.6.0, color-string@^1.9.0:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
+color-string@^2.1.3:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/color-string/-/color-string-2.1.4.tgz#9dcf566ff976e23368c8bd673f5c35103ab41058"
+ integrity sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==
+ dependencies:
+ color-name "^2.0.0"
+
color-support@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
-color@^3.1.3:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164"
- integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
- dependencies:
- color-convert "^1.9.3"
- color-string "^1.6.0"
-
color@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
@@ -13806,6 +13830,14 @@ color@^4.2.3:
color-convert "^2.0.1"
color-string "^1.9.0"
+color@^5.0.2:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/color/-/color-5.0.3.tgz#f79390b1b778e222ffbb54304d3dbeaef633f97f"
+ integrity sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==
+ dependencies:
+ color-convert "^3.1.3"
+ color-string "^2.1.3"
+
colord@^2.9.3:
version "2.9.3"
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
@@ -13831,14 +13863,6 @@ colors@^1.4.0:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
-colorspace@1.1.x:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243"
- integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==
- dependencies:
- color "^3.1.3"
- text-hex "1.0.x"
-
combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -14313,10 +14337,10 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6:
dependencies:
uncrypto "^0.1.3"
-crossws@^0.4.4:
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/crossws/-/crossws-0.4.4.tgz#d62574bcc6de75f0e45fe08b5133d9ba8436a30c"
- integrity sha512-w6c4OdpRNnudVmcgr7brb/+/HmYjMQvYToO/oTrprTwxRUiom3LYWU1PMWuD006okbUWpII1Ea9/+kwpUfmyRg==
+crossws@^0.4.4, crossws@^0.4.5:
+ version "0.4.5"
+ resolved "https://registry.yarnpkg.com/crossws/-/crossws-0.4.5.tgz#e300fec909cd93fe377a1cee84f6813c9c786edf"
+ integrity sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA==
crypto-random-string@^2.0.0:
version "2.0.0"
@@ -16017,14 +16041,15 @@ env-paths@^2.2.0:
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
-env-runner@^0.1.6:
- version "0.1.6"
- resolved "https://registry.yarnpkg.com/env-runner/-/env-runner-0.1.6.tgz#b2acc95c00bc9a00457d7ad5220f10bd75595b2d"
- integrity sha512-fSb7X1zdda8k6611a6/SdSQpDe7a/bqMz2UWdbHjk9YWzpUR4/fn9YtE/hqgGQ2nhvVN0zUtcL1SRMKwIsDbAA==
+env-runner@^0.1.6, env-runner@^0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/env-runner/-/env-runner-0.1.7.tgz#ab26aa711cf195c9d8e158b6e864291fbd8d202e"
+ integrity sha512-i7h96jxETJYhXy5grgHNJ9xNzCzWIn9Ck/VkkYgOlE4gOqknsLX3CmlVb5LmwNex8sOoLFVZLz+TIw/+b5rktA==
dependencies:
crossws "^0.4.4"
- httpxy "^0.3.1"
- srvx "^0.11.9"
+ exsolve "^1.0.8"
+ httpxy "^0.5.0"
+ srvx "^0.11.13"
envinfo@7.21.0:
version "7.21.0"
@@ -18791,13 +18816,13 @@ h3@^1.10.0, h3@^1.12.0, h3@^1.15.3, h3@^1.15.5:
ufo "^1.6.3"
uncrypto "^0.1.3"
-h3@^2.0.1-rc.16:
- version "2.0.1-rc.17"
- resolved "https://registry.yarnpkg.com/h3/-/h3-2.0.1-rc.17.tgz#86fb5a5261a38f59e0fb3384581e345285be3b61"
- integrity sha512-9rPJs68qMj7HJH78z7uSIAw6rl3EElLdVSirTeAf6B5ogwiFVIr9AKMMS4u00Gp8DYIPnnjtw3ZWN7EkYcPBrQ==
+h3@^2.0.1-rc.13, h3@^2.0.1-rc.16, h3@^2.0.1-rc.20:
+ version "2.0.1-rc.20"
+ resolved "https://registry.yarnpkg.com/h3/-/h3-2.0.1-rc.20.tgz#51050db30afb0b6e69718d88cccc23666fbe8039"
+ integrity sha512-28ljodXuUp0fZovdiSRq4G9OgrxCztrJe5VdYzXAB7ueRvI7pIUqLU14Xi3XqdYJ/khXjfpUOOD2EQa6CmBgsg==
dependencies:
rou3 "^0.8.1"
- srvx "^0.11.12"
+ srvx "^0.11.13"
handle-thing@^2.0.0:
version "2.0.1"
@@ -19156,10 +19181,10 @@ hookable@^5.5.3:
resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d"
integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==
-hookable@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/hookable/-/hookable-6.0.1.tgz#be950f1b8ef38af24d4354657e9e3590d2a5b5e6"
- integrity sha512-uKGyY8BuzN/a5gvzvA+3FVWo0+wUjgtfSdnmjtrOVwQCZPHpHDH2WRO3VZSOeluYrHoDCiXFffZXs8Dj1ULWtw==
+hookable@^6.0.1, hookable@^6.1.1:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/hookable/-/hookable-6.1.1.tgz#825f966b4b426db2e622d94d7a31a70f196f9d2f"
+ integrity sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==
hosted-git-info@^5.0.0:
version "5.1.0"
@@ -19417,10 +19442,10 @@ httpxy@^0.1.7:
resolved "https://registry.yarnpkg.com/httpxy/-/httpxy-0.1.7.tgz#02d02e57eda10e8b5c0e3f9f10860e3d7a5991a4"
integrity sha512-pXNx8gnANKAndgga5ahefxc++tJvNL87CXoRwxn1cJE2ZkWEojF3tNfQIEhZX/vfpt+wzeAzpUI4qkediX1MLQ==
-httpxy@^0.3.1:
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/httpxy/-/httpxy-0.3.1.tgz#da1bb1a4a26cb44d7835a9297c845a0e06372083"
- integrity sha512-XjG/CEoofEisMrnFr0D6U6xOZ4mRfnwcYQ9qvvnT4lvnX8BoeA3x3WofB75D+vZwpaobFVkBIHrZzoK40w8XSw==
+httpxy@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/httpxy/-/httpxy-0.5.0.tgz#a9c53543760dee498611827a464e56e14639c0d0"
+ integrity sha512-qwX7QX/rK2visT10/b7bSeZWQOMlSm3svTD0pZpU+vJjNUP0YHtNv4c3z+MO+MSnGuRFWJFdCZiV+7F7dXIOzg==
human-signals@^1.1.1:
version "1.1.1"
@@ -23116,10 +23141,10 @@ next@14.2.35:
"@next/swc-win32-ia32-msvc" "14.2.33"
"@next/swc-win32-x64-msvc" "14.2.33"
-nf3@^0.3.11:
- version "0.3.13"
- resolved "https://registry.yarnpkg.com/nf3/-/nf3-0.3.13.tgz#9dfbc08158c9f12583ebf82bd89c97dc362b7df1"
- integrity sha512-drDt0yl4d/yUhlpD0GzzqahSpA5eUNeIfFq0/aoZb0UlPY0ZwP4u1EfREVvZrYdEnJ3OU9Le9TrzbvWgEkkeKw==
+nf3@^0.3.11, nf3@^0.3.16:
+ version "0.3.16"
+ resolved "https://registry.yarnpkg.com/nf3/-/nf3-0.3.16.tgz#36e3d1bb36d98ee78b47627b7967864c2ea01720"
+ integrity sha512-Gs0xRPpUm2nDkqbi40NJ9g7qDIcjcJzgExiydnq6LAyqhI2jfno8wG3NKTL+IiJsx799UHOb1CnSd4Wg4SG4Pw==
ng-packagr@^14.2.2:
version "14.3.0"
@@ -23186,6 +23211,26 @@ nitro@^3.0.260311-beta:
unenv "^2.0.0-rc.24"
unstorage "^2.0.0-alpha.6"
+nitro@^3.0.260415-beta:
+ version "3.0.260415-beta"
+ resolved "https://registry.yarnpkg.com/nitro/-/nitro-3.0.260415-beta.tgz#2a40c38c9a2d6ae14b259ebe78e5ce1142d0c5e5"
+ integrity sha512-J0ntJERWtIdvweZdmkCiF8eOFvP9fIAJR2gpeIDrHbAlYavK41WQfADo/YoZ/LF7RMTZBiPaH/pt2s/nPru9Iw==
+ dependencies:
+ consola "^3.4.2"
+ crossws "^0.4.5"
+ db0 "^0.3.4"
+ env-runner "^0.1.7"
+ h3 "^2.0.1-rc.20"
+ hookable "^6.1.1"
+ nf3 "^0.3.16"
+ ocache "^0.1.4"
+ ofetch "^2.0.0-alpha.3"
+ ohash "^2.0.11"
+ rolldown "^1.0.0-rc.15"
+ srvx "^0.11.15"
+ unenv "^2.0.0-rc.24"
+ unstorage "^2.0.0-alpha.7"
+
nitropack@^2.11.10, nitropack@^2.11.13, nitropack@^2.13.1:
version "2.13.1"
resolved "https://registry.yarnpkg.com/nitropack/-/nitropack-2.13.1.tgz#70be1b14eb0d2fed9c670fe7cfff3741c384ecf2"
@@ -23936,7 +23981,7 @@ obuf@^1.0.0, obuf@^1.1.2:
resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
-ocache@^0.1.2:
+ocache@^0.1.2, ocache@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/ocache/-/ocache-0.1.4.tgz#d4a71be84ceaeb5685cc0128c197d44713dda9a7"
integrity sha512-e7geNdWjxSnvsSgvLuPvgKgu7ubM10ZmTPOgpr7mz2BXYtvjMKTiLhjFi/gWU8chkuP6hNkZBsa9LzOusyaqkQ==
@@ -27149,29 +27194,29 @@ roarr@^7.0.4:
safe-stable-stringify "^2.4.1"
semver-compare "^1.0.0"
-rolldown@^1.0.0-rc.8:
- version "1.0.0-rc.10"
- resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.0.0-rc.10.tgz#41c55e52d833c52c90131973047250548e35f2bf"
- integrity sha512-q7j6vvarRFmKpgJUT8HCAUljkgzEp4LAhPlJUvQhA5LA1SUL36s5QCysMutErzL3EbNOZOkoziSx9iZC4FddKA==
+rolldown@^1.0.0-rc.15, rolldown@^1.0.0-rc.8:
+ version "1.0.0-rc.15"
+ resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.0.0-rc.15.tgz#ea3526443b2dbe834e9f8f6c1fde6232ec687170"
+ integrity sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==
dependencies:
- "@oxc-project/types" "=0.120.0"
- "@rolldown/pluginutils" "1.0.0-rc.10"
+ "@oxc-project/types" "=0.124.0"
+ "@rolldown/pluginutils" "1.0.0-rc.15"
optionalDependencies:
- "@rolldown/binding-android-arm64" "1.0.0-rc.10"
- "@rolldown/binding-darwin-arm64" "1.0.0-rc.10"
- "@rolldown/binding-darwin-x64" "1.0.0-rc.10"
- "@rolldown/binding-freebsd-x64" "1.0.0-rc.10"
- "@rolldown/binding-linux-arm-gnueabihf" "1.0.0-rc.10"
- "@rolldown/binding-linux-arm64-gnu" "1.0.0-rc.10"
- "@rolldown/binding-linux-arm64-musl" "1.0.0-rc.10"
- "@rolldown/binding-linux-ppc64-gnu" "1.0.0-rc.10"
- "@rolldown/binding-linux-s390x-gnu" "1.0.0-rc.10"
- "@rolldown/binding-linux-x64-gnu" "1.0.0-rc.10"
- "@rolldown/binding-linux-x64-musl" "1.0.0-rc.10"
- "@rolldown/binding-openharmony-arm64" "1.0.0-rc.10"
- "@rolldown/binding-wasm32-wasi" "1.0.0-rc.10"
- "@rolldown/binding-win32-arm64-msvc" "1.0.0-rc.10"
- "@rolldown/binding-win32-x64-msvc" "1.0.0-rc.10"
+ "@rolldown/binding-android-arm64" "1.0.0-rc.15"
+ "@rolldown/binding-darwin-arm64" "1.0.0-rc.15"
+ "@rolldown/binding-darwin-x64" "1.0.0-rc.15"
+ "@rolldown/binding-freebsd-x64" "1.0.0-rc.15"
+ "@rolldown/binding-linux-arm-gnueabihf" "1.0.0-rc.15"
+ "@rolldown/binding-linux-arm64-gnu" "1.0.0-rc.15"
+ "@rolldown/binding-linux-arm64-musl" "1.0.0-rc.15"
+ "@rolldown/binding-linux-ppc64-gnu" "1.0.0-rc.15"
+ "@rolldown/binding-linux-s390x-gnu" "1.0.0-rc.15"
+ "@rolldown/binding-linux-x64-gnu" "1.0.0-rc.15"
+ "@rolldown/binding-linux-x64-musl" "1.0.0-rc.15"
+ "@rolldown/binding-openharmony-arm64" "1.0.0-rc.15"
+ "@rolldown/binding-wasm32-wasi" "1.0.0-rc.15"
+ "@rolldown/binding-win32-arm64-msvc" "1.0.0-rc.15"
+ "@rolldown/binding-win32-x64-msvc" "1.0.0-rc.15"
rollup-plugin-cleanup@^3.2.1:
version "3.2.1"
@@ -28502,10 +28547,10 @@ sqlstring@2.3.1:
resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40"
integrity sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=
-srvx@^0.11.12, srvx@^0.11.2, srvx@^0.11.9:
- version "0.11.13"
- resolved "https://registry.yarnpkg.com/srvx/-/srvx-0.11.13.tgz#cc77a98cb9a459c34f75ee4345bd0eef9f613a54"
- integrity sha512-oknN6qduuMPafxKtHucUeG32Q963pjriA5g3/Bl05cwEsUe5VVbIU4qR9LrALHbipSCyBe+VmfDGGydqazDRkw==
+srvx@^0.11.13, srvx@^0.11.15, srvx@^0.11.2, srvx@^0.11.9:
+ version "0.11.15"
+ resolved "https://registry.yarnpkg.com/srvx/-/srvx-0.11.15.tgz#51c08f993bb116f5821ec929a466a29e8d5c7b61"
+ integrity sha512-iXsux0UcOjdvs0LCMa2Ws3WwcDUozA3JN3BquNXkaFPP7TpRqgunKdEgoZ/uwb1J6xaYHfxtz9Twlh6yzwM6Tg==
sshpk@^1.18.0:
version "1.18.0"
@@ -30496,7 +30541,7 @@ unstorage@^1.16.0, unstorage@^1.17.4:
ofetch "^1.5.1"
ufo "^1.6.3"
-unstorage@^2.0.0-alpha.6:
+unstorage@^2.0.0-alpha.6, unstorage@^2.0.0-alpha.7:
version "2.0.0-alpha.7"
resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-2.0.0-alpha.7.tgz#803ea90176683bf2175bb01065cb07df6d65280a"
integrity sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog==
@@ -31625,12 +31670,12 @@ winston@3.13.0:
winston-transport "^4.7.0"
winston@^3.17.0:
- version "3.17.0"
- resolved "https://registry.yarnpkg.com/winston/-/winston-3.17.0.tgz#74b8665ce9b4ea7b29d0922cfccf852a08a11423"
- integrity sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==
+ version "3.19.0"
+ resolved "https://registry.yarnpkg.com/winston/-/winston-3.19.0.tgz#cc1d1262f5f45946904085cfffe73efb4b7a581d"
+ integrity sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==
dependencies:
"@colors/colors" "^1.6.0"
- "@dabh/diagnostics" "^2.0.2"
+ "@dabh/diagnostics" "^2.0.8"
async "^3.2.3"
is-stream "^2.0.0"
logform "^2.7.0"