Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ef7b5e9
Add a TanStack Start tunnel route helper
nikolovlazar Apr 13, 2026
1691509
Merge branch 'develop' into lazarnikolov/js-2140-tanstack-start-tunne…
nikolovlazar Apr 13, 2026
316be89
Add TanStack Start tunnel route e2e coverage
nikolovlazar Apr 13, 2026
e6b6290
Merge branch 'lazarnikolov/js-2140-tanstack-start-tunnel-adapter' of …
nikolovlazar Apr 13, 2026
08b4154
Refactor TanStack Start e2e app to cover managed tunnel route variants
nikolovlazar Apr 15, 2026
3991017
Merge branch 'develop' into lazarnikolov/js-2140-tanstack-start-tunne…
nikolovlazar Apr 15, 2026
98202a9
Generate stable 8-character tunnel route paths
nikolovlazar Apr 15, 2026
320a55f
refactor(tanstackstart-react): mark tunnel route cache key internal
nikolovlazar Apr 16, 2026
73fbbeb
test(tanstackstart-react): narrow tunnel response matcher
nikolovlazar Apr 16, 2026
5a2c6e9
Merge branch 'develop' into lazarnikolov/js-2140-tanstack-start-tunne…
nikolovlazar Apr 16, 2026
ee3da8d
fix(tanstackstart-react): stub createSentryTunnelRoute on client
nikolovlazar Apr 16, 2026
1d827f5
Refactor TanStack Start tunnel route handling
nikolovlazar Apr 20, 2026
7c9124c
Merge branch 'develop' into lazarnikolov/js-2140-tanstack-start-tunne…
nikolovlazar Apr 20, 2026
4390705
Fix tunnel route lint issues
nikolovlazar Apr 20, 2026
e68a210
Refactor TanStack tunnel route config
nikolovlazar Apr 20, 2026
c993616
fix(tanstackstart-react): treat empty tunnel path as omitted
nikolovlazar Apr 21, 2026
52c33cb
fix(tanstackstart-react): use path in tunnelRoute tests and type options
nikolovlazar Apr 21, 2026
d77dec4
Merge branch 'develop' into lazarnikolov/js-2140-tanstack-start-tunne…
nikolovlazar Apr 21, 2026
29a5d89
style(tanstackstart-react): format sentryTanstackStart test imports
nikolovlazar Apr 21, 2026
c356b37
fix(tanstackstart-react): detect tunnel route conflicts under both ts…
nikolovlazar Apr 21, 2026
9e04b81
refactor(tanstackstart-react): simplify allowedDsns options check
nikolovlazar Apr 23, 2026
da03651
test(tanstackstart-react): add e2e variant for object-form tunnelRoute
nikolovlazar Apr 23, 2026
00c9a99
Merge branch 'develop' into lazarnikolov/js-2140-tanstack-start-tunne…
nikolovlazar Apr 23, 2026
af60d11
test(tanstackstart-react): drop tunnel chain from default test:assert
nikolovlazar Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/tanstackstart-react/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { init } from './sdk';
export { wrapFetchWithSentry } from './wrapFetchWithSentry';
export { wrapMiddlewaresWithSentry } from './middleware';
export { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from './globalMiddleware';
export { createSentryTunnelRoute } from './tunnelRoute';
Comment thread
cursor[bot] marked this conversation as resolved.

/**
* A no-op stub of the browser tracing integration for the server. Router setup code is shared between client and server,
Expand Down
43 changes: 43 additions & 0 deletions packages/tanstackstart-react/src/server/tunnelRoute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { handleTunnelRequest } from '@sentry/core';

export interface CreateSentryTunnelRouteOptions {
allowedDsns: string[];
}

type SentryTunnelRouteHandlerContext = {
request: Request;
};

type SentryTunnelRoute = {
handlers: {
POST: (context: SentryTunnelRouteHandlerContext) => Promise<Response>;
};
};

/**
* Creates a TanStack Start server route configuration for tunneling Sentry envelopes.
*
* @example
* ```ts
* import { createFileRoute } from '@tanstack/react-router';
* import * as Sentry from '@sentry/tanstackstart-react';
*
* export const Route = createFileRoute('/monitoring')({
* server: Sentry.createSentryTunnelRoute({
* allowedDsns: ['https://public@o0.ingest.sentry.io/0'],
* }),
* });
* ```
*/
export function createSentryTunnelRoute(options: CreateSentryTunnelRouteOptions): SentryTunnelRoute {
return {
handlers: {
POST: async ({ request }) => {
return handleTunnelRequest({
request,
allowedDsns: options.allowedDsns,
});
},
},
};
}
48 changes: 48 additions & 0 deletions packages/tanstackstart-react/test/server/tunnelRoute.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { afterEach, describe, expect, it, vi } from 'vitest';

const handleTunnelRequestSpy = vi.fn();

vi.mock('@sentry/core', async importOriginal => {
const original = await importOriginal();
return {
...original,
handleTunnelRequest: (...args: unknown[]) => handleTunnelRequestSpy(...args),
};
});

const { createSentryTunnelRoute } = await import('../../src/server/tunnelRoute');

describe('createSentryTunnelRoute', () => {
afterEach(() => {
vi.clearAllMocks();
});

it('returns a server route config with only a POST handler', () => {
const route = createSentryTunnelRoute({
allowedDsns: ['https://public@o0.ingest.sentry.io/0'],
});

expect(Object.keys(route.handlers)).toEqual(['POST']);
expect(route.handlers.POST).toBeTypeOf('function');
});

it('forwards the request and allowed DSNs to handleTunnelRequest', async () => {
const request = new Request('http://localhost:3000/monitoring', { method: 'POST', body: 'envelope' });
const allowedDsns = ['https://public@o0.ingest.sentry.io/0'];
const response = new Response('ok', { status: 200 });

handleTunnelRequestSpy.mockResolvedValueOnce(response);

const route = createSentryTunnelRoute({ allowedDsns });
const result = await route.handlers.POST({ request });

expect(handleTunnelRequestSpy).toHaveBeenCalledTimes(1);
const [options] = handleTunnelRequestSpy.mock.calls[0]!;
expect(options).toEqual({
request,
allowedDsns,
});
expect(options.allowedDsns).toBe(allowedDsns);
expect(result).toBe(response);
});
});
Comment thread
cursor[bot] marked this conversation as resolved.
Loading
Loading