@sentry/tanstackstart-react 10.62.0 → 10.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/build/cjs/client/index.js +3 -0
  2. package/build/cjs/client/index.js.map +1 -1
  3. package/build/cjs/index.client.js +1 -0
  4. package/build/cjs/index.client.js.map +1 -1
  5. package/build/cjs/index.server.js +1 -0
  6. package/build/cjs/index.server.js.map +1 -1
  7. package/build/cjs/server/index.js +1 -0
  8. package/build/cjs/server/index.js.map +1 -1
  9. package/build/cjs/server/tunnelRoute.js +18 -0
  10. package/build/cjs/server/tunnelRoute.js.map +1 -1
  11. package/build/cjs/vite/tunnelRoute.js +8 -0
  12. package/build/cjs/vite/tunnelRoute.js.map +1 -1
  13. package/build/esm/client/index.js +3 -1
  14. package/build/esm/client/index.js.map +1 -1
  15. package/build/esm/index.client.js +1 -1
  16. package/build/esm/index.server.js +1 -1
  17. package/build/esm/package.json +1 -1
  18. package/build/esm/server/index.js +1 -1
  19. package/build/esm/server/index.js.map +1 -1
  20. package/build/esm/server/tunnelRoute.js +19 -2
  21. package/build/esm/server/tunnelRoute.js.map +1 -1
  22. package/build/esm/vite/tunnelRoute.js +8 -0
  23. package/build/esm/vite/tunnelRoute.js.map +1 -1
  24. package/build/types/client/index.d.ts +6 -0
  25. package/build/types/client/index.d.ts.map +1 -1
  26. package/build/types/index.types.d.ts +1 -0
  27. package/build/types/index.types.d.ts.map +1 -1
  28. package/build/types/server/index.d.ts +1 -1
  29. package/build/types/server/index.d.ts.map +1 -1
  30. package/build/types/server/tunnelRoute.d.ts +6 -0
  31. package/build/types/server/tunnelRoute.d.ts.map +1 -1
  32. package/build/types/vite/tunnelRoute.d.ts.map +1 -1
  33. package/build/types-ts3.8/client/index.d.ts +6 -0
  34. package/build/types-ts3.8/index.types.d.ts +1 -0
  35. package/build/types-ts3.8/server/index.d.ts +1 -1
  36. package/build/types-ts3.8/server/tunnelRoute.d.ts +6 -0
  37. package/package.json +5 -5
@@ -23,9 +23,12 @@ function createSentryTunnelRoute(_options) {
23
23
  }
24
24
  };
25
25
  }
26
+ function registerSentryServerTunnelRoute(_path) {
27
+ }
26
28
 
27
29
  exports.init = sdk.init;
28
30
  exports.createSentryTunnelRoute = createSentryTunnelRoute;
31
+ exports.registerSentryServerTunnelRoute = registerSentryServerTunnelRoute;
29
32
  exports.sentryGlobalFunctionMiddleware = sentryGlobalFunctionMiddleware;
30
33
  exports.sentryGlobalRequestMiddleware = sentryGlobalRequestMiddleware;
31
34
  exports.wrapMiddlewaresWithSentry = wrapMiddlewaresWithSentry;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/client/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type {\n SentryGlobalFunctionMiddleware,\n SentryGlobalRequestMiddleware,\n TanStackMiddlewareBase,\n} from '../common/types';\nimport type { CreateSentryTunnelRouteOptions } from '../server/tunnelRoute';\n\nexport * from '@sentry/react';\n\nexport { init } from './sdk';\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent build errors.\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.values(middlewares);\n}\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport function createSentryTunnelRoute(_options: CreateSentryTunnelRouteOptions): {\n handlers: {\n POST: () => Promise<Response>;\n };\n} {\n return {\n handlers: {\n POST: async () => new Response(null, { status: 500 }),\n },\n };\n}\n"],"names":[],"mappings":";;;;;AAkBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,OAAO,WAAW,CAAA;AAClC;AAMO,MAAM,6BAAA,GAA+D;AAAA,EAC1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,MAAM,8BAAA,GAAiE;AAAA,EAC5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,SAAS,wBAAwB,QAAA,EAItC;AACA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,YAAY,IAAI,QAAA,CAAS,MAAM,EAAE,MAAA,EAAQ,KAAK;AAAA;AACtD,GACF;AACF;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/client/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type {\n SentryGlobalFunctionMiddleware,\n SentryGlobalRequestMiddleware,\n TanStackMiddlewareBase,\n} from '../common/types';\nimport type { CreateSentryTunnelRouteOptions } from '../server/tunnelRoute';\n\nexport * from '@sentry/react';\n\nexport { init } from './sdk';\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent build errors.\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.values(middlewares);\n}\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport function createSentryTunnelRoute(_options: CreateSentryTunnelRouteOptions): {\n handlers: {\n POST: () => Promise<Response>;\n };\n} {\n return {\n handlers: {\n POST: async () => new Response(null, { status: 500 }),\n },\n };\n}\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed so the managed tunnel route module\n * can statically import it (the call is server-guarded and tree-shaken from the client bundle).\n */\nexport function registerSentryServerTunnelRoute(_path: string): void {}\n"],"names":[],"mappings":";;;;;AAkBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,OAAO,WAAW,CAAA;AAClC;AAMO,MAAM,6BAAA,GAA+D;AAAA,EAC1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,MAAM,8BAAA,GAAiE;AAAA,EAC5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,SAAS,wBAAwB,QAAA,EAItC;AACA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,YAAY,IAAI,QAAA,CAAS,MAAM,EAAE,MAAA,EAAQ,KAAK;AAAA;AACtD,GACF;AACF;AAOO,SAAS,gCAAgC,KAAA,EAAqB;AAAC;;;;;;;;;;;;;;;;;;;"}
@@ -7,6 +7,7 @@ const sdk = require('./client/sdk.js');
7
7
 
8
8
 
9
9
  exports.createSentryTunnelRoute = index.createSentryTunnelRoute;
10
+ exports.registerSentryServerTunnelRoute = index.registerSentryServerTunnelRoute;
10
11
  exports.sentryGlobalFunctionMiddleware = index.sentryGlobalFunctionMiddleware;
11
12
  exports.sentryGlobalRequestMiddleware = index.sentryGlobalRequestMiddleware;
12
13
  exports.wrapMiddlewaresWithSentry = index.wrapMiddlewaresWithSentry;
@@ -1 +1 @@
1
- {"version":3,"file":"index.client.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.client.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
@@ -15,6 +15,7 @@ exports.replayIntegration = index.replayIntegration;
15
15
  exports.tanstackRouterBrowserTracingIntegration = index.tanstackRouterBrowserTracingIntegration;
16
16
  exports.withErrorBoundary = index.withErrorBoundary;
17
17
  exports.createSentryTunnelRoute = tunnelRoute.createSentryTunnelRoute;
18
+ exports.registerSentryServerTunnelRoute = tunnelRoute.registerSentryServerTunnelRoute;
18
19
  exports.init = sdk.init;
19
20
  exports.sentryGlobalFunctionMiddleware = globalMiddleware.sentryGlobalFunctionMiddleware;
20
21
  exports.sentryGlobalRequestMiddleware = globalMiddleware.sentryGlobalRequestMiddleware;
@@ -1 +1 @@
1
- {"version":3,"file":"index.server.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.server.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -40,6 +40,7 @@ exports.wrapMiddlewaresWithSentry = middleware.wrapMiddlewaresWithSentry;
40
40
  exports.sentryGlobalFunctionMiddleware = globalMiddleware.sentryGlobalFunctionMiddleware;
41
41
  exports.sentryGlobalRequestMiddleware = globalMiddleware.sentryGlobalRequestMiddleware;
42
42
  exports.createSentryTunnelRoute = tunnelRoute.createSentryTunnelRoute;
43
+ exports.registerSentryServerTunnelRoute = tunnelRoute.registerSentryServerTunnelRoute;
43
44
  exports.ErrorBoundary = ErrorBoundary;
44
45
  exports.replayIntegration = replayIntegration;
45
46
  exports.tanstackRouterBrowserTracingIntegration = tanstackRouterBrowserTracingIntegration;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type { Integration } from '@sentry/core';\n\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\nexport { wrapFetchWithSentry } from './wrapFetchWithSentry';\nexport { wrapMiddlewaresWithSentry } from './middleware';\nexport { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from './globalMiddleware';\nexport { createSentryTunnelRoute } from './tunnelRoute';\n\n/**\n * A no-op stub of the replay integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function replayIntegration(_options?: Record<string, unknown>): Integration {\n return {\n name: 'Replay',\n setup() {},\n };\n}\n\n/**\n * A no-op stub of the browser tracing integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function tanstackRouterBrowserTracingIntegration(\n _router: unknown,\n _options?: Record<string, unknown>,\n): Integration {\n return {\n name: 'BrowserTracing',\n setup() {},\n };\n}\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":";;;;;;;;;AAiBO,SAAS,kBAAkB,QAAA,EAAiD;AACjF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,SAAS,uCAAA,CACd,SACA,QAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,MAAM,aAAA,GAAgB,CAAC,KAAA,KAA6D;AACzF,EAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,KAAA,CAAM,QAAA,KAAa,UAAA,EAAY;AACxC,IAAA,OAAQ,MAAM,QAAA,EAAmC;AAAA,EACnD;AAEA,EAAA,OAAO,KAAA,CAAM,QAAA;AACf;AAOO,SAAS,kBACd,gBAAA,EACa;AACb,EAAA,OAAO,gBAAA;AACT;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type { Integration } from '@sentry/core';\n\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\nexport { wrapFetchWithSentry } from './wrapFetchWithSentry';\nexport { wrapMiddlewaresWithSentry } from './middleware';\nexport { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from './globalMiddleware';\nexport { createSentryTunnelRoute, registerSentryServerTunnelRoute } from './tunnelRoute';\n\n/**\n * A no-op stub of the replay integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function replayIntegration(_options?: Record<string, unknown>): Integration {\n return {\n name: 'Replay',\n setup() {},\n };\n}\n\n/**\n * A no-op stub of the browser tracing integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function tanstackRouterBrowserTracingIntegration(\n _router: unknown,\n _options?: Record<string, unknown>,\n): Integration {\n return {\n name: 'BrowserTracing',\n setup() {},\n };\n}\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":";;;;;;;;;AAiBO,SAAS,kBAAkB,QAAA,EAAiD;AACjF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,SAAS,uCAAA,CACd,SACA,QAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,MAAM,aAAA,GAAgB,CAAC,KAAA,KAA6D;AACzF,EAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,KAAA,CAAM,QAAA,KAAa,UAAA,EAAY;AACxC,IAAA,OAAQ,MAAM,QAAA,EAAmC;AAAA,EACnD;AAEA,EAAA,OAAO,KAAA,CAAM,QAAA;AACf;AAOO,SAAS,kBACd,gBAAA,EACa;AACb,EAAA,OAAO,gBAAA;AACT;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -2,10 +2,27 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const core = require('@sentry/core');
4
4
 
5
+ const registeredTunnelRoutePaths = /* @__PURE__ */ new Set();
6
+ function registerSentryServerTunnelRoute(path) {
7
+ if (registeredTunnelRoutePaths.has(path)) {
8
+ return;
9
+ }
10
+ const client = core.getClient();
11
+ if (!client) {
12
+ return;
13
+ }
14
+ registeredTunnelRoutePaths.add(path);
15
+ const options = client.getOptions();
16
+ options.ignoreSpans = [
17
+ ...options.ignoreSpans ?? [],
18
+ { attributes: { "http.target": new RegExp(`^${core.escapeStringForRegex(path)}(?:[/?#]|$)`) } }
19
+ ];
20
+ }
5
21
  function createSentryTunnelRoute(options) {
6
22
  return {
7
23
  handlers: {
8
24
  POST: async ({ request }) => {
25
+ registerSentryServerTunnelRoute(new URL(request.url).pathname);
9
26
  const allowedDsnsFromOptions = options.allowedDsns?.length ? options.allowedDsns : void 0;
10
27
  const allowedDsns = allowedDsnsFromOptions ?? (() => {
11
28
  const client = core.getClient();
@@ -28,4 +45,5 @@ function createSentryTunnelRoute(options) {
28
45
  }
29
46
 
30
47
  exports.createSentryTunnelRoute = createSentryTunnelRoute;
48
+ exports.registerSentryServerTunnelRoute = registerSentryServerTunnelRoute;
31
49
  //# sourceMappingURL=tunnelRoute.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelRoute.js","sources":["../../../src/server/tunnelRoute.ts"],"sourcesContent":["import { dsnToString, getClient, handleTunnelRequest } from '@sentry/core';\n\nexport interface CreateSentryTunnelRouteOptions {\n allowedDsns?: string[];\n}\n\ntype SentryTunnelRouteHandlerContext = {\n request: Request;\n};\n\ntype SentryTunnelRoute = {\n handlers: {\n POST: (context: SentryTunnelRouteHandlerContext) => Promise<Response>;\n };\n};\n\n/**\n * Creates a TanStack Start server route configuration for tunneling Sentry envelopes.\n *\n * @example\n * ```ts\n * import { createFileRoute } from '@tanstack/react-router';\n * import * as Sentry from '@sentry/tanstackstart-react';\n *\n * export const Route = createFileRoute('/monitoring')({\n * server: Sentry.createSentryTunnelRoute({\n * allowedDsns: ['https://public@o0.ingest.sentry.io/0'],\n * }),\n * });\n * ```\n */\nexport function createSentryTunnelRoute(options: CreateSentryTunnelRouteOptions): SentryTunnelRoute {\n return {\n handlers: {\n POST: async ({ request }) => {\n const allowedDsnsFromOptions = options.allowedDsns?.length ? options.allowedDsns : undefined;\n\n const allowedDsns =\n allowedDsnsFromOptions ??\n (() => {\n const client = getClient();\n const dsn = client?.getDsn();\n return dsn ? [dsnToString(dsn)] : undefined;\n })();\n\n if (!allowedDsns) {\n return new Response(\n 'Tunnel route requires Sentry server SDK initialized with a DSN, or pass allowedDsns explicitly.',\n { status: 500 },\n );\n }\n\n return handleTunnelRequest({\n request,\n allowedDsns,\n });\n },\n },\n };\n}\n"],"names":["getClient","dsnToString","handleTunnelRequest"],"mappings":";;;;AA+BO,SAAS,wBAAwB,OAAA,EAA4D;AAClG,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,OAAO,EAAE,OAAA,EAAQ,KAAM;AAC3B,QAAA,MAAM,sBAAA,GAAyB,OAAA,CAAQ,WAAA,EAAa,MAAA,GAAS,QAAQ,WAAA,GAAc,MAAA;AAEnF,QAAA,MAAM,WAAA,GACJ,2BACC,MAAM;AACL,UAAA,MAAM,SAASA,cAAA,EAAU;AACzB,UAAA,MAAM,GAAA,GAAM,QAAQ,MAAA,EAAO;AAC3B,UAAA,OAAO,GAAA,GAAM,CAACC,gBAAA,CAAY,GAAG,CAAC,CAAA,GAAI,MAAA;AAAA,QACpC,CAAA,GAAG;AAEL,QAAA,IAAI,CAAC,WAAA,EAAa;AAChB,UAAA,OAAO,IAAI,QAAA;AAAA,YACT,iGAAA;AAAA,YACA,EAAE,QAAQ,GAAA;AAAI,WAChB;AAAA,QACF;AAEA,QAAA,OAAOC,wBAAA,CAAoB;AAAA,UACzB,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,MACH;AAAA;AACF,GACF;AACF;;;;"}
1
+ {"version":3,"file":"tunnelRoute.js","sources":["../../../src/server/tunnelRoute.ts"],"sourcesContent":["import { dsnToString, escapeStringForRegex, getClient, handleTunnelRequest } from '@sentry/core';\n\nconst registeredTunnelRoutePaths = new Set<string>();\n\n/**\n * Drops the incoming `http.server` transaction for a tunnel route by matching its request path (the\n * `http.target` attribute, set at span creation, so it works for static and streamed lifecycles).\n * Called at server startup for the managed route and from the handler (self-registration) otherwise.\n */\nexport function registerSentryServerTunnelRoute(path: string): void {\n // Dedupe: the route module can be re-evaluated (HMR, multiple import paths).\n if (registeredTunnelRoutePaths.has(path)) {\n return;\n }\n\n const client = getClient();\n if (!client) {\n return;\n }\n\n registeredTunnelRoutePaths.add(path);\n\n const options = client.getOptions();\n options.ignoreSpans = [\n ...(options.ignoreSpans ?? []),\n { attributes: { 'http.target': new RegExp(`^${escapeStringForRegex(path)}(?:[/?#]|$)`) } },\n ];\n}\n\nexport interface CreateSentryTunnelRouteOptions {\n allowedDsns?: string[];\n}\n\ntype SentryTunnelRouteHandlerContext = {\n request: Request;\n};\n\ntype SentryTunnelRoute = {\n handlers: {\n POST: (context: SentryTunnelRouteHandlerContext) => Promise<Response>;\n };\n};\n\n/**\n * Creates a TanStack Start server route configuration for tunneling Sentry envelopes.\n *\n * @example\n * ```ts\n * import { createFileRoute } from '@tanstack/react-router';\n * import * as Sentry from '@sentry/tanstackstart-react';\n *\n * export const Route = createFileRoute('/monitoring')({\n * server: Sentry.createSentryTunnelRoute({\n * allowedDsns: ['https://public@o0.ingest.sentry.io/0'],\n * }),\n * });\n * ```\n */\nexport function createSentryTunnelRoute(options: CreateSentryTunnelRouteOptions): SentryTunnelRoute {\n return {\n handlers: {\n POST: async ({ request }) => {\n // Self-register the path so the tunnel route's own transaction is dropped: at span-end for the\n // static path, and at span-start for subsequent streamed requests. The first streamed request\n // still leaks here (this runs after its span was sampled); managed routes avoid even that via\n // the startup registration.\n registerSentryServerTunnelRoute(new URL(request.url).pathname);\n\n const allowedDsnsFromOptions = options.allowedDsns?.length ? options.allowedDsns : undefined;\n\n const allowedDsns =\n allowedDsnsFromOptions ??\n (() => {\n const client = getClient();\n const dsn = client?.getDsn();\n return dsn ? [dsnToString(dsn)] : undefined;\n })();\n\n if (!allowedDsns) {\n return new Response(\n 'Tunnel route requires Sentry server SDK initialized with a DSN, or pass allowedDsns explicitly.',\n { status: 500 },\n );\n }\n\n return handleTunnelRequest({\n request,\n allowedDsns,\n });\n },\n },\n };\n}\n"],"names":["getClient","escapeStringForRegex","dsnToString","handleTunnelRequest"],"mappings":";;;;AAEA,MAAM,0BAAA,uBAAiC,GAAA,EAAY;AAO5C,SAAS,gCAAgC,IAAA,EAAoB;AAElE,EAAA,IAAI,0BAAA,CAA2B,GAAA,CAAI,IAAI,CAAA,EAAG;AACxC,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,SAASA,cAAA,EAAU;AACzB,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA;AAAA,EACF;AAEA,EAAA,0BAAA,CAA2B,IAAI,IAAI,CAAA;AAEnC,EAAA,MAAM,OAAA,GAAU,OAAO,UAAA,EAAW;AAClC,EAAA,OAAA,CAAQ,WAAA,GAAc;AAAA,IACpB,GAAI,OAAA,CAAQ,WAAA,IAAe,EAAC;AAAA,IAC5B,EAAE,UAAA,EAAY,EAAE,aAAA,EAAe,IAAI,MAAA,CAAO,CAAA,CAAA,EAAIC,yBAAA,CAAqB,IAAI,CAAC,CAAA,WAAA,CAAa,CAAA,EAAE;AAAE,GAC3F;AACF;AA+BO,SAAS,wBAAwB,OAAA,EAA4D;AAClG,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,OAAO,EAAE,OAAA,EAAQ,KAAM;AAK3B,QAAA,+BAAA,CAAgC,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,EAAE,QAAQ,CAAA;AAE7D,QAAA,MAAM,sBAAA,GAAyB,OAAA,CAAQ,WAAA,EAAa,MAAA,GAAS,QAAQ,WAAA,GAAc,MAAA;AAEnF,QAAA,MAAM,WAAA,GACJ,2BACC,MAAM;AACL,UAAA,MAAM,SAASD,cAAA,EAAU;AACzB,UAAA,MAAM,GAAA,GAAM,QAAQ,MAAA,EAAO;AAC3B,UAAA,OAAO,GAAA,GAAM,CAACE,gBAAA,CAAY,GAAG,CAAC,CAAA,GAAI,MAAA;AAAA,QACpC,CAAA,GAAG;AAEL,QAAA,IAAI,CAAC,WAAA,EAAa;AAChB,UAAA,OAAO,IAAI,QAAA;AAAA,YACT,iGAAA;AAAA,YACA,EAAE,QAAQ,GAAA;AAAI,WAChB;AAAA,QACF;AAEA,QAAA,OAAOC,wBAAA,CAAoB;AAAA,UACzB,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,MACH;AAAA;AACF,GACF;AACF;;;;;"}
@@ -122,6 +122,14 @@ function makeTunnelRoutePlugin(options, debug) {
122
122
  return null;
123
123
  }
124
124
  return `import { createFileRoute } from '@tanstack/react-router';
125
+ import { registerSentryServerTunnelRoute } from '@sentry/tanstackstart-react';
126
+
127
+ // Server-only: drop the tunnel route's own transaction. Registered synchronously at module evaluation
128
+ // (before any request) so streamed spans are filtered from the first request. The SSR guard tree-shakes
129
+ // it (and the import) out of the client bundle.
130
+ if (import.meta.env.SSR) {
131
+ registerSentryServerTunnelRoute(${serializedTunnelRoute});
132
+ }
125
133
 
126
134
  export const Route = createFileRoute(${serializedTunnelRoute})({
127
135
  server: {
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelRoute.js","sources":["../../../src/vite/tunnelRoute.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\nexport type TunnelRouteOptions =\n | true\n | string\n | {\n /**\n * A list of DSNs that are allowed to use the managed tunnel route.\n *\n * If omitted or empty, the tunnel route will derive the allowed DSN from the active server Sentry SDK at runtime.\n */\n allowedDsns?: string[];\n\n /**\n * Controls the public route path used by the managed tunnel route.\n *\n * If omitted, an opaque path is generated once per dev session or production build.\n */\n path?: string;\n };\n\nconst MANAGED_TUNNEL_ROUTE_IMPORT = 'SentryManagedTunnelRouteImport';\nconst MANAGED_TUNNEL_ROUTE_NAME = 'SentryManagedTunnelRoute';\nconst MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY = '__SENTRY_INTERNAL_TANSTACKSTART_TUNNEL_ROUTE__';\n\nconst VIRTUAL_TUNNEL_ROUTE_ID = 'virtual:sentry-tanstackstart-react/tunnel-route';\nconst RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID = `\\0${VIRTUAL_TUNNEL_ROUTE_ID}`;\n\nfunction generateRandomTunnelRoute(): string {\n const randomPath = Array.from({ length: 8 }, () => Math.floor(Math.random() * 36).toString(36)).join('');\n\n return `/${randomPath}`;\n}\n\nexport function resolveTunnelRoute(tunnel: true | string): string {\n if (typeof tunnel === 'string') {\n return tunnel;\n }\n\n if (process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY]) {\n return process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY];\n }\n\n const resolvedTunnelRoute = generateRandomTunnelRoute();\n process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY] = resolvedTunnelRoute;\n return resolvedTunnelRoute;\n}\n\ntype NormalizedTunnelRouteOptions = {\n resolvedPath: string;\n allowedDsns: string[] | undefined;\n};\n\nfunction validateStaticPath(path: string): void {\n if (!path.startsWith('/') || path.includes('?') || path.includes('#')) {\n throw new Error(\n '[@sentry/tanstackstart-react] `tunnelRoute` static paths must start with `/` and must not contain query or hash segments.',\n );\n }\n}\n\nfunction normalizeTunnelRouteOptions(options: TunnelRouteOptions): NormalizedTunnelRouteOptions {\n if (options === true) {\n return { resolvedPath: resolveTunnelRoute(true), allowedDsns: undefined };\n }\n\n if (typeof options === 'string') {\n validateStaticPath(options);\n return {\n resolvedPath: resolveTunnelRoute(options),\n allowedDsns: undefined,\n };\n }\n\n const allowedDsns = options.allowedDsns && options.allowedDsns.length > 0 ? options.allowedDsns : undefined;\n const path = options.path;\n\n if (path) {\n validateStaticPath(path);\n }\n\n return { resolvedPath: resolveTunnelRoute(path || true), allowedDsns };\n}\n\n// `routeTree.gen.ts` quote style follows `tsr.config.json#quoteStyle` (`single` | `double`),\n// so we check both forms for each route-identifying key.\nconst ROUTE_CONFLICT_KEYS = ['fullPath', 'path', 'id'] as const;\n\nfunction hasRouteConflict(source: string, resolvedTunnelRoute: string): boolean {\n const literals = [`'${resolvedTunnelRoute}'`, `\"${resolvedTunnelRoute}\"`];\n return ROUTE_CONFLICT_KEYS.some(key => literals.some(literal => source.includes(`${key}: ${literal}`)));\n}\n\nfunction injectAfterLastImport(source: string, statement: string): string {\n const importMatches = [...source.matchAll(/^import .+$/gm)];\n const lastImport = importMatches.at(-1);\n\n if (lastImport?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because `routeTree.gen.ts` imports could not be located.',\n );\n }\n\n const insertIndex = lastImport.index + lastImport[0].length;\n return `${source.slice(0, insertIndex)}\\n${statement}${source.slice(insertIndex)}`;\n}\n\nexport function injectManagedTunnelRoute(source: string, resolvedTunnelRoute: string): string {\n if (source.includes(VIRTUAL_TUNNEL_ROUTE_ID)) {\n return source;\n }\n\n if (hasRouteConflict(source, resolvedTunnelRoute)) {\n throw new Error(\n `[@sentry/tanstackstart-react] Cannot register managed tunnel route \"${resolvedTunnelRoute}\" because an existing TanStack Start route already uses that path.`,\n );\n }\n\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n\n let transformedSource = injectAfterLastImport(\n source,\n `import { Route as ${MANAGED_TUNNEL_ROUTE_IMPORT} } from '${VIRTUAL_TUNNEL_ROUTE_ID}'`,\n );\n\n const rootRouteChildrenMatch = transformedSource.match(\n /const rootRouteChildren(?:\\s*:\\s*RootRouteChildren)?\\s*=\\s*\\{/,\n );\n\n if (rootRouteChildrenMatch?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because the generated TanStack route tree did not contain `rootRouteChildren`.',\n );\n }\n\n const injectedRootRouteChildrenDeclaration = `const ${MANAGED_TUNNEL_ROUTE_NAME} = ${MANAGED_TUNNEL_ROUTE_IMPORT}.update({\n id: ${serializedTunnelRoute},\n path: ${serializedTunnelRoute},\n getParentRoute: () => rootRouteImport,\n} as any)\n\n${rootRouteChildrenMatch[0]}\n ${MANAGED_TUNNEL_ROUTE_NAME}: ${MANAGED_TUNNEL_ROUTE_NAME},\n`;\n\n transformedSource = `${transformedSource.slice(0, rootRouteChildrenMatch.index)}${injectedRootRouteChildrenDeclaration}${transformedSource.slice(rootRouteChildrenMatch.index + rootRouteChildrenMatch[0].length)}`;\n\n return transformedSource;\n}\n\nexport function makeTunnelRoutePlugin(options: TunnelRouteOptions, debug?: boolean): Plugin {\n const normalized = normalizeTunnelRouteOptions(options);\n const resolvedTunnelRoute = normalized.resolvedPath;\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n const serializedAllowedDsns = normalized.allowedDsns ? JSON.stringify(normalized.allowedDsns) : undefined;\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[@sentry/tanstackstart-react] Registered tunnel route: ${resolvedTunnelRoute}`);\n }\n\n return {\n name: 'sentry-tanstackstart-tunnel-route',\n enforce: 'pre',\n config() {\n return {\n define: {\n __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__: serializedTunnelRoute,\n },\n };\n },\n resolveId(source) {\n return source === VIRTUAL_TUNNEL_ROUTE_ID ? RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID : null;\n },\n load(id) {\n if (id !== RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID) {\n return null;\n }\n\n return `import { createFileRoute } from '@tanstack/react-router';\n\nexport const Route = createFileRoute(${serializedTunnelRoute})({\n server: {\n handlers: {\n async POST({ request }) {\n const Sentry = await import('@sentry/tanstackstart-react');\n return Sentry.createSentryTunnelRoute(${serializedAllowedDsns ? `{ allowedDsns: ${serializedAllowedDsns} }` : `{}`}).handlers.POST({ request });\n },\n },\n },\n});\n`;\n },\n transform(source, id) {\n if (!id.endsWith('/routeTree.gen.ts') && !id.endsWith('\\\\routeTree.gen.ts')) {\n return null;\n }\n\n return injectManagedTunnelRoute(source, resolvedTunnelRoute);\n },\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tunnelRoute.js","sources":["../../../src/vite/tunnelRoute.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\nexport type TunnelRouteOptions =\n | true\n | string\n | {\n /**\n * A list of DSNs that are allowed to use the managed tunnel route.\n *\n * If omitted or empty, the tunnel route will derive the allowed DSN from the active server Sentry SDK at runtime.\n */\n allowedDsns?: string[];\n\n /**\n * Controls the public route path used by the managed tunnel route.\n *\n * If omitted, an opaque path is generated once per dev session or production build.\n */\n path?: string;\n };\n\nconst MANAGED_TUNNEL_ROUTE_IMPORT = 'SentryManagedTunnelRouteImport';\nconst MANAGED_TUNNEL_ROUTE_NAME = 'SentryManagedTunnelRoute';\nconst MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY = '__SENTRY_INTERNAL_TANSTACKSTART_TUNNEL_ROUTE__';\n\nconst VIRTUAL_TUNNEL_ROUTE_ID = 'virtual:sentry-tanstackstart-react/tunnel-route';\nconst RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID = `\\0${VIRTUAL_TUNNEL_ROUTE_ID}`;\n\nfunction generateRandomTunnelRoute(): string {\n const randomPath = Array.from({ length: 8 }, () => Math.floor(Math.random() * 36).toString(36)).join('');\n\n return `/${randomPath}`;\n}\n\nexport function resolveTunnelRoute(tunnel: true | string): string {\n if (typeof tunnel === 'string') {\n return tunnel;\n }\n\n if (process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY]) {\n return process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY];\n }\n\n const resolvedTunnelRoute = generateRandomTunnelRoute();\n process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY] = resolvedTunnelRoute;\n return resolvedTunnelRoute;\n}\n\ntype NormalizedTunnelRouteOptions = {\n resolvedPath: string;\n allowedDsns: string[] | undefined;\n};\n\nfunction validateStaticPath(path: string): void {\n if (!path.startsWith('/') || path.includes('?') || path.includes('#')) {\n throw new Error(\n '[@sentry/tanstackstart-react] `tunnelRoute` static paths must start with `/` and must not contain query or hash segments.',\n );\n }\n}\n\nfunction normalizeTunnelRouteOptions(options: TunnelRouteOptions): NormalizedTunnelRouteOptions {\n if (options === true) {\n return { resolvedPath: resolveTunnelRoute(true), allowedDsns: undefined };\n }\n\n if (typeof options === 'string') {\n validateStaticPath(options);\n return {\n resolvedPath: resolveTunnelRoute(options),\n allowedDsns: undefined,\n };\n }\n\n const allowedDsns = options.allowedDsns && options.allowedDsns.length > 0 ? options.allowedDsns : undefined;\n const path = options.path;\n\n if (path) {\n validateStaticPath(path);\n }\n\n return { resolvedPath: resolveTunnelRoute(path || true), allowedDsns };\n}\n\n// `routeTree.gen.ts` quote style follows `tsr.config.json#quoteStyle` (`single` | `double`),\n// so we check both forms for each route-identifying key.\nconst ROUTE_CONFLICT_KEYS = ['fullPath', 'path', 'id'] as const;\n\nfunction hasRouteConflict(source: string, resolvedTunnelRoute: string): boolean {\n const literals = [`'${resolvedTunnelRoute}'`, `\"${resolvedTunnelRoute}\"`];\n return ROUTE_CONFLICT_KEYS.some(key => literals.some(literal => source.includes(`${key}: ${literal}`)));\n}\n\nfunction injectAfterLastImport(source: string, statement: string): string {\n const importMatches = [...source.matchAll(/^import .+$/gm)];\n const lastImport = importMatches.at(-1);\n\n if (lastImport?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because `routeTree.gen.ts` imports could not be located.',\n );\n }\n\n const insertIndex = lastImport.index + lastImport[0].length;\n return `${source.slice(0, insertIndex)}\\n${statement}${source.slice(insertIndex)}`;\n}\n\nexport function injectManagedTunnelRoute(source: string, resolvedTunnelRoute: string): string {\n if (source.includes(VIRTUAL_TUNNEL_ROUTE_ID)) {\n return source;\n }\n\n if (hasRouteConflict(source, resolvedTunnelRoute)) {\n throw new Error(\n `[@sentry/tanstackstart-react] Cannot register managed tunnel route \"${resolvedTunnelRoute}\" because an existing TanStack Start route already uses that path.`,\n );\n }\n\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n\n let transformedSource = injectAfterLastImport(\n source,\n `import { Route as ${MANAGED_TUNNEL_ROUTE_IMPORT} } from '${VIRTUAL_TUNNEL_ROUTE_ID}'`,\n );\n\n const rootRouteChildrenMatch = transformedSource.match(\n /const rootRouteChildren(?:\\s*:\\s*RootRouteChildren)?\\s*=\\s*\\{/,\n );\n\n if (rootRouteChildrenMatch?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because the generated TanStack route tree did not contain `rootRouteChildren`.',\n );\n }\n\n const injectedRootRouteChildrenDeclaration = `const ${MANAGED_TUNNEL_ROUTE_NAME} = ${MANAGED_TUNNEL_ROUTE_IMPORT}.update({\n id: ${serializedTunnelRoute},\n path: ${serializedTunnelRoute},\n getParentRoute: () => rootRouteImport,\n} as any)\n\n${rootRouteChildrenMatch[0]}\n ${MANAGED_TUNNEL_ROUTE_NAME}: ${MANAGED_TUNNEL_ROUTE_NAME},\n`;\n\n transformedSource = `${transformedSource.slice(0, rootRouteChildrenMatch.index)}${injectedRootRouteChildrenDeclaration}${transformedSource.slice(rootRouteChildrenMatch.index + rootRouteChildrenMatch[0].length)}`;\n\n return transformedSource;\n}\n\nexport function makeTunnelRoutePlugin(options: TunnelRouteOptions, debug?: boolean): Plugin {\n const normalized = normalizeTunnelRouteOptions(options);\n const resolvedTunnelRoute = normalized.resolvedPath;\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n const serializedAllowedDsns = normalized.allowedDsns ? JSON.stringify(normalized.allowedDsns) : undefined;\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[@sentry/tanstackstart-react] Registered tunnel route: ${resolvedTunnelRoute}`);\n }\n\n return {\n name: 'sentry-tanstackstart-tunnel-route',\n enforce: 'pre',\n config() {\n return {\n define: {\n __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__: serializedTunnelRoute,\n },\n };\n },\n resolveId(source) {\n return source === VIRTUAL_TUNNEL_ROUTE_ID ? RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID : null;\n },\n load(id) {\n if (id !== RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID) {\n return null;\n }\n\n return `import { createFileRoute } from '@tanstack/react-router';\nimport { registerSentryServerTunnelRoute } from '@sentry/tanstackstart-react';\n\n// Server-only: drop the tunnel route's own transaction. Registered synchronously at module evaluation\n// (before any request) so streamed spans are filtered from the first request. The SSR guard tree-shakes\n// it (and the import) out of the client bundle.\nif (import.meta.env.SSR) {\n registerSentryServerTunnelRoute(${serializedTunnelRoute});\n}\n\nexport const Route = createFileRoute(${serializedTunnelRoute})({\n server: {\n handlers: {\n async POST({ request }) {\n const Sentry = await import('@sentry/tanstackstart-react');\n return Sentry.createSentryTunnelRoute(${serializedAllowedDsns ? `{ allowedDsns: ${serializedAllowedDsns} }` : `{}`}).handlers.POST({ request });\n },\n },\n },\n});\n`;\n },\n transform(source, id) {\n if (!id.endsWith('/routeTree.gen.ts') && !id.endsWith('\\\\routeTree.gen.ts')) {\n return null;\n }\n\n return injectManagedTunnelRoute(source, resolvedTunnelRoute);\n },\n };\n}\n"],"names":[],"mappings":"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"}
@@ -21,6 +21,8 @@ function createSentryTunnelRoute(_options) {
21
21
  }
22
22
  };
23
23
  }
24
+ function registerSentryServerTunnelRoute(_path) {
25
+ }
24
26
 
25
- export { createSentryTunnelRoute, sentryGlobalFunctionMiddleware, sentryGlobalRequestMiddleware, wrapMiddlewaresWithSentry };
27
+ export { createSentryTunnelRoute, registerSentryServerTunnelRoute, sentryGlobalFunctionMiddleware, sentryGlobalRequestMiddleware, wrapMiddlewaresWithSentry };
26
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/client/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type {\n SentryGlobalFunctionMiddleware,\n SentryGlobalRequestMiddleware,\n TanStackMiddlewareBase,\n} from '../common/types';\nimport type { CreateSentryTunnelRouteOptions } from '../server/tunnelRoute';\n\nexport * from '@sentry/react';\n\nexport { init } from './sdk';\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent build errors.\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.values(middlewares);\n}\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport function createSentryTunnelRoute(_options: CreateSentryTunnelRouteOptions): {\n handlers: {\n POST: () => Promise<Response>;\n };\n} {\n return {\n handlers: {\n POST: async () => new Response(null, { status: 500 }),\n },\n };\n}\n"],"names":[],"mappings":";;;AAkBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,OAAO,WAAW,CAAA;AAClC;AAMO,MAAM,6BAAA,GAA+D;AAAA,EAC1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,MAAM,8BAAA,GAAiE;AAAA,EAC5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,SAAS,wBAAwB,QAAA,EAItC;AACA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,YAAY,IAAI,QAAA,CAAS,MAAM,EAAE,MAAA,EAAQ,KAAK;AAAA;AACtD,GACF;AACF;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/client/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type {\n SentryGlobalFunctionMiddleware,\n SentryGlobalRequestMiddleware,\n TanStackMiddlewareBase,\n} from '../common/types';\nimport type { CreateSentryTunnelRouteOptions } from '../server/tunnelRoute';\n\nexport * from '@sentry/react';\n\nexport { init } from './sdk';\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent build errors.\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.values(middlewares);\n}\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n options: {},\n};\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed to prevent rendering errors.\n */\nexport function createSentryTunnelRoute(_options: CreateSentryTunnelRouteOptions): {\n handlers: {\n POST: () => Promise<Response>;\n };\n} {\n return {\n handlers: {\n POST: async () => new Response(null, { status: 500 }),\n },\n };\n}\n\n/**\n * No-op stub for client-side builds.\n * The actual implementation is server-only, but this stub is needed so the managed tunnel route module\n * can statically import it (the call is server-guarded and tree-shaken from the client bundle).\n */\nexport function registerSentryServerTunnelRoute(_path: string): void {}\n"],"names":[],"mappings":";;;AAkBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,OAAO,WAAW,CAAA;AAClC;AAMO,MAAM,6BAAA,GAA+D;AAAA,EAC1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,MAAM,8BAAA,GAAiE;AAAA,EAC5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,SAAS;AACX;AAMO,SAAS,wBAAwB,QAAA,EAItC;AACA,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,YAAY,IAAI,QAAA,CAAS,MAAM,EAAE,MAAA,EAAQ,KAAK;AAAA;AACtD,GACF;AACF;AAOO,SAAS,gCAAgC,KAAA,EAAqB;AAAC;;;;"}
@@ -1,4 +1,4 @@
1
- export { createSentryTunnelRoute, sentryGlobalFunctionMiddleware, sentryGlobalRequestMiddleware, wrapMiddlewaresWithSentry } from './client/index.js';
1
+ export { createSentryTunnelRoute, registerSentryServerTunnelRoute, sentryGlobalFunctionMiddleware, sentryGlobalRequestMiddleware, wrapMiddlewaresWithSentry } from './client/index.js';
2
2
  export * from '@sentry/react';
3
3
  export { init } from './client/sdk.js';
4
4
  //# sourceMappingURL=index.client.js.map
@@ -1,6 +1,6 @@
1
1
  export { ErrorBoundary, replayIntegration, tanstackRouterBrowserTracingIntegration, withErrorBoundary } from './server/index.js';
2
2
  export * from '@sentry/node';
3
- export { createSentryTunnelRoute } from './server/tunnelRoute.js';
3
+ export { createSentryTunnelRoute, registerSentryServerTunnelRoute } from './server/tunnelRoute.js';
4
4
  export { init } from './server/sdk.js';
5
5
  export { sentryGlobalFunctionMiddleware, sentryGlobalRequestMiddleware } from './server/globalMiddleware.js';
6
6
  export { wrapFetchWithSentry } from './server/wrapFetchWithSentry.js';
@@ -1 +1 @@
1
- {"type":"module","version":"10.62.0","sideEffects":false}
1
+ {"type":"module","version":"10.63.0","sideEffects":false}
@@ -3,7 +3,7 @@ export { init } from './sdk.js';
3
3
  export { wrapFetchWithSentry } from './wrapFetchWithSentry.js';
4
4
  export { wrapMiddlewaresWithSentry } from './middleware.js';
5
5
  export { sentryGlobalFunctionMiddleware, sentryGlobalRequestMiddleware } from './globalMiddleware.js';
6
- export { createSentryTunnelRoute } from './tunnelRoute.js';
6
+ export { createSentryTunnelRoute, registerSentryServerTunnelRoute } from './tunnelRoute.js';
7
7
 
8
8
  function replayIntegration(_options) {
9
9
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type { Integration } from '@sentry/core';\n\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\nexport { wrapFetchWithSentry } from './wrapFetchWithSentry';\nexport { wrapMiddlewaresWithSentry } from './middleware';\nexport { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from './globalMiddleware';\nexport { createSentryTunnelRoute } from './tunnelRoute';\n\n/**\n * A no-op stub of the replay integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function replayIntegration(_options?: Record<string, unknown>): Integration {\n return {\n name: 'Replay',\n setup() {},\n };\n}\n\n/**\n * A no-op stub of the browser tracing integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function tanstackRouterBrowserTracingIntegration(\n _router: unknown,\n _options?: Record<string, unknown>,\n): Integration {\n return {\n name: 'BrowserTracing',\n setup() {},\n };\n}\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":";;;;;;;AAiBO,SAAS,kBAAkB,QAAA,EAAiD;AACjF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,SAAS,uCAAA,CACd,SACA,QAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,MAAM,aAAA,GAAgB,CAAC,KAAA,KAA6D;AACzF,EAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,KAAA,CAAM,QAAA,KAAa,UAAA,EAAY;AACxC,IAAA,OAAQ,MAAM,QAAA,EAAmC;AAAA,EACnD;AAEA,EAAA,OAAO,KAAA,CAAM,QAAA;AACf;AAOO,SAAS,kBACd,gBAAA,EACa;AACb,EAAA,OAAO,gBAAA;AACT;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nimport type { Integration } from '@sentry/core';\n\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\nexport { wrapFetchWithSentry } from './wrapFetchWithSentry';\nexport { wrapMiddlewaresWithSentry } from './middleware';\nexport { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from './globalMiddleware';\nexport { createSentryTunnelRoute, registerSentryServerTunnelRoute } from './tunnelRoute';\n\n/**\n * A no-op stub of the replay integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function replayIntegration(_options?: Record<string, unknown>): Integration {\n return {\n name: 'Replay',\n setup() {},\n };\n}\n\n/**\n * A no-op stub of the browser tracing integration for the server. Router setup code is shared between client and server,\n * so this stub is needed to prevent build errors during SSR bundling.\n */\nexport function tanstackRouterBrowserTracingIntegration(\n _router: unknown,\n _options?: Record<string, unknown>,\n): Integration {\n return {\n name: 'BrowserTracing',\n setup() {},\n };\n}\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":";;;;;;;AAiBO,SAAS,kBAAkB,QAAA,EAAiD;AACjF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,SAAS,uCAAA,CACd,SACA,QAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,GAAQ;AAAA,IAAC;AAAA,GACX;AACF;AAMO,MAAM,aAAA,GAAgB,CAAC,KAAA,KAA6D;AACzF,EAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,KAAA,CAAM,QAAA,KAAa,UAAA,EAAY;AACxC,IAAA,OAAQ,MAAM,QAAA,EAAmC;AAAA,EACnD;AAEA,EAAA,OAAO,KAAA,CAAM,QAAA;AACf;AAOO,SAAS,kBACd,gBAAA,EACa;AACb,EAAA,OAAO,gBAAA;AACT;;;;"}
@@ -1,9 +1,26 @@
1
- import { getClient, dsnToString, handleTunnelRequest } from '@sentry/core';
1
+ import { getClient, dsnToString, handleTunnelRequest, escapeStringForRegex } from '@sentry/core';
2
2
 
3
+ const registeredTunnelRoutePaths = /* @__PURE__ */ new Set();
4
+ function registerSentryServerTunnelRoute(path) {
5
+ if (registeredTunnelRoutePaths.has(path)) {
6
+ return;
7
+ }
8
+ const client = getClient();
9
+ if (!client) {
10
+ return;
11
+ }
12
+ registeredTunnelRoutePaths.add(path);
13
+ const options = client.getOptions();
14
+ options.ignoreSpans = [
15
+ ...options.ignoreSpans ?? [],
16
+ { attributes: { "http.target": new RegExp(`^${escapeStringForRegex(path)}(?:[/?#]|$)`) } }
17
+ ];
18
+ }
3
19
  function createSentryTunnelRoute(options) {
4
20
  return {
5
21
  handlers: {
6
22
  POST: async ({ request }) => {
23
+ registerSentryServerTunnelRoute(new URL(request.url).pathname);
7
24
  const allowedDsnsFromOptions = options.allowedDsns?.length ? options.allowedDsns : void 0;
8
25
  const allowedDsns = allowedDsnsFromOptions ?? (() => {
9
26
  const client = getClient();
@@ -25,5 +42,5 @@ function createSentryTunnelRoute(options) {
25
42
  };
26
43
  }
27
44
 
28
- export { createSentryTunnelRoute };
45
+ export { createSentryTunnelRoute, registerSentryServerTunnelRoute };
29
46
  //# sourceMappingURL=tunnelRoute.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelRoute.js","sources":["../../../src/server/tunnelRoute.ts"],"sourcesContent":["import { dsnToString, getClient, handleTunnelRequest } from '@sentry/core';\n\nexport interface CreateSentryTunnelRouteOptions {\n allowedDsns?: string[];\n}\n\ntype SentryTunnelRouteHandlerContext = {\n request: Request;\n};\n\ntype SentryTunnelRoute = {\n handlers: {\n POST: (context: SentryTunnelRouteHandlerContext) => Promise<Response>;\n };\n};\n\n/**\n * Creates a TanStack Start server route configuration for tunneling Sentry envelopes.\n *\n * @example\n * ```ts\n * import { createFileRoute } from '@tanstack/react-router';\n * import * as Sentry from '@sentry/tanstackstart-react';\n *\n * export const Route = createFileRoute('/monitoring')({\n * server: Sentry.createSentryTunnelRoute({\n * allowedDsns: ['https://public@o0.ingest.sentry.io/0'],\n * }),\n * });\n * ```\n */\nexport function createSentryTunnelRoute(options: CreateSentryTunnelRouteOptions): SentryTunnelRoute {\n return {\n handlers: {\n POST: async ({ request }) => {\n const allowedDsnsFromOptions = options.allowedDsns?.length ? options.allowedDsns : undefined;\n\n const allowedDsns =\n allowedDsnsFromOptions ??\n (() => {\n const client = getClient();\n const dsn = client?.getDsn();\n return dsn ? [dsnToString(dsn)] : undefined;\n })();\n\n if (!allowedDsns) {\n return new Response(\n 'Tunnel route requires Sentry server SDK initialized with a DSN, or pass allowedDsns explicitly.',\n { status: 500 },\n );\n }\n\n return handleTunnelRequest({\n request,\n allowedDsns,\n });\n },\n },\n };\n}\n"],"names":[],"mappings":";;AA+BO,SAAS,wBAAwB,OAAA,EAA4D;AAClG,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,OAAO,EAAE,OAAA,EAAQ,KAAM;AAC3B,QAAA,MAAM,sBAAA,GAAyB,OAAA,CAAQ,WAAA,EAAa,MAAA,GAAS,QAAQ,WAAA,GAAc,MAAA;AAEnF,QAAA,MAAM,WAAA,GACJ,2BACC,MAAM;AACL,UAAA,MAAM,SAAS,SAAA,EAAU;AACzB,UAAA,MAAM,GAAA,GAAM,QAAQ,MAAA,EAAO;AAC3B,UAAA,OAAO,GAAA,GAAM,CAAC,WAAA,CAAY,GAAG,CAAC,CAAA,GAAI,MAAA;AAAA,QACpC,CAAA,GAAG;AAEL,QAAA,IAAI,CAAC,WAAA,EAAa;AAChB,UAAA,OAAO,IAAI,QAAA;AAAA,YACT,iGAAA;AAAA,YACA,EAAE,QAAQ,GAAA;AAAI,WAChB;AAAA,QACF;AAEA,QAAA,OAAO,mBAAA,CAAoB;AAAA,UACzB,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,MACH;AAAA;AACF,GACF;AACF;;;;"}
1
+ {"version":3,"file":"tunnelRoute.js","sources":["../../../src/server/tunnelRoute.ts"],"sourcesContent":["import { dsnToString, escapeStringForRegex, getClient, handleTunnelRequest } from '@sentry/core';\n\nconst registeredTunnelRoutePaths = new Set<string>();\n\n/**\n * Drops the incoming `http.server` transaction for a tunnel route by matching its request path (the\n * `http.target` attribute, set at span creation, so it works for static and streamed lifecycles).\n * Called at server startup for the managed route and from the handler (self-registration) otherwise.\n */\nexport function registerSentryServerTunnelRoute(path: string): void {\n // Dedupe: the route module can be re-evaluated (HMR, multiple import paths).\n if (registeredTunnelRoutePaths.has(path)) {\n return;\n }\n\n const client = getClient();\n if (!client) {\n return;\n }\n\n registeredTunnelRoutePaths.add(path);\n\n const options = client.getOptions();\n options.ignoreSpans = [\n ...(options.ignoreSpans ?? []),\n { attributes: { 'http.target': new RegExp(`^${escapeStringForRegex(path)}(?:[/?#]|$)`) } },\n ];\n}\n\nexport interface CreateSentryTunnelRouteOptions {\n allowedDsns?: string[];\n}\n\ntype SentryTunnelRouteHandlerContext = {\n request: Request;\n};\n\ntype SentryTunnelRoute = {\n handlers: {\n POST: (context: SentryTunnelRouteHandlerContext) => Promise<Response>;\n };\n};\n\n/**\n * Creates a TanStack Start server route configuration for tunneling Sentry envelopes.\n *\n * @example\n * ```ts\n * import { createFileRoute } from '@tanstack/react-router';\n * import * as Sentry from '@sentry/tanstackstart-react';\n *\n * export const Route = createFileRoute('/monitoring')({\n * server: Sentry.createSentryTunnelRoute({\n * allowedDsns: ['https://public@o0.ingest.sentry.io/0'],\n * }),\n * });\n * ```\n */\nexport function createSentryTunnelRoute(options: CreateSentryTunnelRouteOptions): SentryTunnelRoute {\n return {\n handlers: {\n POST: async ({ request }) => {\n // Self-register the path so the tunnel route's own transaction is dropped: at span-end for the\n // static path, and at span-start for subsequent streamed requests. The first streamed request\n // still leaks here (this runs after its span was sampled); managed routes avoid even that via\n // the startup registration.\n registerSentryServerTunnelRoute(new URL(request.url).pathname);\n\n const allowedDsnsFromOptions = options.allowedDsns?.length ? options.allowedDsns : undefined;\n\n const allowedDsns =\n allowedDsnsFromOptions ??\n (() => {\n const client = getClient();\n const dsn = client?.getDsn();\n return dsn ? [dsnToString(dsn)] : undefined;\n })();\n\n if (!allowedDsns) {\n return new Response(\n 'Tunnel route requires Sentry server SDK initialized with a DSN, or pass allowedDsns explicitly.',\n { status: 500 },\n );\n }\n\n return handleTunnelRequest({\n request,\n allowedDsns,\n });\n },\n },\n };\n}\n"],"names":[],"mappings":";;AAEA,MAAM,0BAAA,uBAAiC,GAAA,EAAY;AAO5C,SAAS,gCAAgC,IAAA,EAAoB;AAElE,EAAA,IAAI,0BAAA,CAA2B,GAAA,CAAI,IAAI,CAAA,EAAG;AACxC,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA;AAAA,EACF;AAEA,EAAA,0BAAA,CAA2B,IAAI,IAAI,CAAA;AAEnC,EAAA,MAAM,OAAA,GAAU,OAAO,UAAA,EAAW;AAClC,EAAA,OAAA,CAAQ,WAAA,GAAc;AAAA,IACpB,GAAI,OAAA,CAAQ,WAAA,IAAe,EAAC;AAAA,IAC5B,EAAE,UAAA,EAAY,EAAE,aAAA,EAAe,IAAI,MAAA,CAAO,CAAA,CAAA,EAAI,oBAAA,CAAqB,IAAI,CAAC,CAAA,WAAA,CAAa,CAAA,EAAE;AAAE,GAC3F;AACF;AA+BO,SAAS,wBAAwB,OAAA,EAA4D;AAClG,EAAA,OAAO;AAAA,IACL,QAAA,EAAU;AAAA,MACR,IAAA,EAAM,OAAO,EAAE,OAAA,EAAQ,KAAM;AAK3B,QAAA,+BAAA,CAAgC,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,EAAE,QAAQ,CAAA;AAE7D,QAAA,MAAM,sBAAA,GAAyB,OAAA,CAAQ,WAAA,EAAa,MAAA,GAAS,QAAQ,WAAA,GAAc,MAAA;AAEnF,QAAA,MAAM,WAAA,GACJ,2BACC,MAAM;AACL,UAAA,MAAM,SAAS,SAAA,EAAU;AACzB,UAAA,MAAM,GAAA,GAAM,QAAQ,MAAA,EAAO;AAC3B,UAAA,OAAO,GAAA,GAAM,CAAC,WAAA,CAAY,GAAG,CAAC,CAAA,GAAI,MAAA;AAAA,QACpC,CAAA,GAAG;AAEL,QAAA,IAAI,CAAC,WAAA,EAAa;AAChB,UAAA,OAAO,IAAI,QAAA;AAAA,YACT,iGAAA;AAAA,YACA,EAAE,QAAQ,GAAA;AAAI,WAChB;AAAA,QACF;AAEA,QAAA,OAAO,mBAAA,CAAoB;AAAA,UACzB,OAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,MACH;AAAA;AACF,GACF;AACF;;;;"}
@@ -120,6 +120,14 @@ function makeTunnelRoutePlugin(options, debug) {
120
120
  return null;
121
121
  }
122
122
  return `import { createFileRoute } from '@tanstack/react-router';
123
+ import { registerSentryServerTunnelRoute } from '@sentry/tanstackstart-react';
124
+
125
+ // Server-only: drop the tunnel route's own transaction. Registered synchronously at module evaluation
126
+ // (before any request) so streamed spans are filtered from the first request. The SSR guard tree-shakes
127
+ // it (and the import) out of the client bundle.
128
+ if (import.meta.env.SSR) {
129
+ registerSentryServerTunnelRoute(${serializedTunnelRoute});
130
+ }
123
131
 
124
132
  export const Route = createFileRoute(${serializedTunnelRoute})({
125
133
  server: {
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelRoute.js","sources":["../../../src/vite/tunnelRoute.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\nexport type TunnelRouteOptions =\n | true\n | string\n | {\n /**\n * A list of DSNs that are allowed to use the managed tunnel route.\n *\n * If omitted or empty, the tunnel route will derive the allowed DSN from the active server Sentry SDK at runtime.\n */\n allowedDsns?: string[];\n\n /**\n * Controls the public route path used by the managed tunnel route.\n *\n * If omitted, an opaque path is generated once per dev session or production build.\n */\n path?: string;\n };\n\nconst MANAGED_TUNNEL_ROUTE_IMPORT = 'SentryManagedTunnelRouteImport';\nconst MANAGED_TUNNEL_ROUTE_NAME = 'SentryManagedTunnelRoute';\nconst MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY = '__SENTRY_INTERNAL_TANSTACKSTART_TUNNEL_ROUTE__';\n\nconst VIRTUAL_TUNNEL_ROUTE_ID = 'virtual:sentry-tanstackstart-react/tunnel-route';\nconst RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID = `\\0${VIRTUAL_TUNNEL_ROUTE_ID}`;\n\nfunction generateRandomTunnelRoute(): string {\n const randomPath = Array.from({ length: 8 }, () => Math.floor(Math.random() * 36).toString(36)).join('');\n\n return `/${randomPath}`;\n}\n\nexport function resolveTunnelRoute(tunnel: true | string): string {\n if (typeof tunnel === 'string') {\n return tunnel;\n }\n\n if (process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY]) {\n return process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY];\n }\n\n const resolvedTunnelRoute = generateRandomTunnelRoute();\n process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY] = resolvedTunnelRoute;\n return resolvedTunnelRoute;\n}\n\ntype NormalizedTunnelRouteOptions = {\n resolvedPath: string;\n allowedDsns: string[] | undefined;\n};\n\nfunction validateStaticPath(path: string): void {\n if (!path.startsWith('/') || path.includes('?') || path.includes('#')) {\n throw new Error(\n '[@sentry/tanstackstart-react] `tunnelRoute` static paths must start with `/` and must not contain query or hash segments.',\n );\n }\n}\n\nfunction normalizeTunnelRouteOptions(options: TunnelRouteOptions): NormalizedTunnelRouteOptions {\n if (options === true) {\n return { resolvedPath: resolveTunnelRoute(true), allowedDsns: undefined };\n }\n\n if (typeof options === 'string') {\n validateStaticPath(options);\n return {\n resolvedPath: resolveTunnelRoute(options),\n allowedDsns: undefined,\n };\n }\n\n const allowedDsns = options.allowedDsns && options.allowedDsns.length > 0 ? options.allowedDsns : undefined;\n const path = options.path;\n\n if (path) {\n validateStaticPath(path);\n }\n\n return { resolvedPath: resolveTunnelRoute(path || true), allowedDsns };\n}\n\n// `routeTree.gen.ts` quote style follows `tsr.config.json#quoteStyle` (`single` | `double`),\n// so we check both forms for each route-identifying key.\nconst ROUTE_CONFLICT_KEYS = ['fullPath', 'path', 'id'] as const;\n\nfunction hasRouteConflict(source: string, resolvedTunnelRoute: string): boolean {\n const literals = [`'${resolvedTunnelRoute}'`, `\"${resolvedTunnelRoute}\"`];\n return ROUTE_CONFLICT_KEYS.some(key => literals.some(literal => source.includes(`${key}: ${literal}`)));\n}\n\nfunction injectAfterLastImport(source: string, statement: string): string {\n const importMatches = [...source.matchAll(/^import .+$/gm)];\n const lastImport = importMatches.at(-1);\n\n if (lastImport?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because `routeTree.gen.ts` imports could not be located.',\n );\n }\n\n const insertIndex = lastImport.index + lastImport[0].length;\n return `${source.slice(0, insertIndex)}\\n${statement}${source.slice(insertIndex)}`;\n}\n\nexport function injectManagedTunnelRoute(source: string, resolvedTunnelRoute: string): string {\n if (source.includes(VIRTUAL_TUNNEL_ROUTE_ID)) {\n return source;\n }\n\n if (hasRouteConflict(source, resolvedTunnelRoute)) {\n throw new Error(\n `[@sentry/tanstackstart-react] Cannot register managed tunnel route \"${resolvedTunnelRoute}\" because an existing TanStack Start route already uses that path.`,\n );\n }\n\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n\n let transformedSource = injectAfterLastImport(\n source,\n `import { Route as ${MANAGED_TUNNEL_ROUTE_IMPORT} } from '${VIRTUAL_TUNNEL_ROUTE_ID}'`,\n );\n\n const rootRouteChildrenMatch = transformedSource.match(\n /const rootRouteChildren(?:\\s*:\\s*RootRouteChildren)?\\s*=\\s*\\{/,\n );\n\n if (rootRouteChildrenMatch?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because the generated TanStack route tree did not contain `rootRouteChildren`.',\n );\n }\n\n const injectedRootRouteChildrenDeclaration = `const ${MANAGED_TUNNEL_ROUTE_NAME} = ${MANAGED_TUNNEL_ROUTE_IMPORT}.update({\n id: ${serializedTunnelRoute},\n path: ${serializedTunnelRoute},\n getParentRoute: () => rootRouteImport,\n} as any)\n\n${rootRouteChildrenMatch[0]}\n ${MANAGED_TUNNEL_ROUTE_NAME}: ${MANAGED_TUNNEL_ROUTE_NAME},\n`;\n\n transformedSource = `${transformedSource.slice(0, rootRouteChildrenMatch.index)}${injectedRootRouteChildrenDeclaration}${transformedSource.slice(rootRouteChildrenMatch.index + rootRouteChildrenMatch[0].length)}`;\n\n return transformedSource;\n}\n\nexport function makeTunnelRoutePlugin(options: TunnelRouteOptions, debug?: boolean): Plugin {\n const normalized = normalizeTunnelRouteOptions(options);\n const resolvedTunnelRoute = normalized.resolvedPath;\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n const serializedAllowedDsns = normalized.allowedDsns ? JSON.stringify(normalized.allowedDsns) : undefined;\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[@sentry/tanstackstart-react] Registered tunnel route: ${resolvedTunnelRoute}`);\n }\n\n return {\n name: 'sentry-tanstackstart-tunnel-route',\n enforce: 'pre',\n config() {\n return {\n define: {\n __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__: serializedTunnelRoute,\n },\n };\n },\n resolveId(source) {\n return source === VIRTUAL_TUNNEL_ROUTE_ID ? RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID : null;\n },\n load(id) {\n if (id !== RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID) {\n return null;\n }\n\n return `import { createFileRoute } from '@tanstack/react-router';\n\nexport const Route = createFileRoute(${serializedTunnelRoute})({\n server: {\n handlers: {\n async POST({ request }) {\n const Sentry = await import('@sentry/tanstackstart-react');\n return Sentry.createSentryTunnelRoute(${serializedAllowedDsns ? `{ allowedDsns: ${serializedAllowedDsns} }` : `{}`}).handlers.POST({ request });\n },\n },\n },\n});\n`;\n },\n transform(source, id) {\n if (!id.endsWith('/routeTree.gen.ts') && !id.endsWith('\\\\routeTree.gen.ts')) {\n return null;\n }\n\n return injectManagedTunnelRoute(source, resolvedTunnelRoute);\n },\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tunnelRoute.js","sources":["../../../src/vite/tunnelRoute.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\nexport type TunnelRouteOptions =\n | true\n | string\n | {\n /**\n * A list of DSNs that are allowed to use the managed tunnel route.\n *\n * If omitted or empty, the tunnel route will derive the allowed DSN from the active server Sentry SDK at runtime.\n */\n allowedDsns?: string[];\n\n /**\n * Controls the public route path used by the managed tunnel route.\n *\n * If omitted, an opaque path is generated once per dev session or production build.\n */\n path?: string;\n };\n\nconst MANAGED_TUNNEL_ROUTE_IMPORT = 'SentryManagedTunnelRouteImport';\nconst MANAGED_TUNNEL_ROUTE_NAME = 'SentryManagedTunnelRoute';\nconst MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY = '__SENTRY_INTERNAL_TANSTACKSTART_TUNNEL_ROUTE__';\n\nconst VIRTUAL_TUNNEL_ROUTE_ID = 'virtual:sentry-tanstackstart-react/tunnel-route';\nconst RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID = `\\0${VIRTUAL_TUNNEL_ROUTE_ID}`;\n\nfunction generateRandomTunnelRoute(): string {\n const randomPath = Array.from({ length: 8 }, () => Math.floor(Math.random() * 36).toString(36)).join('');\n\n return `/${randomPath}`;\n}\n\nexport function resolveTunnelRoute(tunnel: true | string): string {\n if (typeof tunnel === 'string') {\n return tunnel;\n }\n\n if (process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY]) {\n return process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY];\n }\n\n const resolvedTunnelRoute = generateRandomTunnelRoute();\n process.env[MANAGED_TUNNEL_ROUTE_PATH_ENV_KEY] = resolvedTunnelRoute;\n return resolvedTunnelRoute;\n}\n\ntype NormalizedTunnelRouteOptions = {\n resolvedPath: string;\n allowedDsns: string[] | undefined;\n};\n\nfunction validateStaticPath(path: string): void {\n if (!path.startsWith('/') || path.includes('?') || path.includes('#')) {\n throw new Error(\n '[@sentry/tanstackstart-react] `tunnelRoute` static paths must start with `/` and must not contain query or hash segments.',\n );\n }\n}\n\nfunction normalizeTunnelRouteOptions(options: TunnelRouteOptions): NormalizedTunnelRouteOptions {\n if (options === true) {\n return { resolvedPath: resolveTunnelRoute(true), allowedDsns: undefined };\n }\n\n if (typeof options === 'string') {\n validateStaticPath(options);\n return {\n resolvedPath: resolveTunnelRoute(options),\n allowedDsns: undefined,\n };\n }\n\n const allowedDsns = options.allowedDsns && options.allowedDsns.length > 0 ? options.allowedDsns : undefined;\n const path = options.path;\n\n if (path) {\n validateStaticPath(path);\n }\n\n return { resolvedPath: resolveTunnelRoute(path || true), allowedDsns };\n}\n\n// `routeTree.gen.ts` quote style follows `tsr.config.json#quoteStyle` (`single` | `double`),\n// so we check both forms for each route-identifying key.\nconst ROUTE_CONFLICT_KEYS = ['fullPath', 'path', 'id'] as const;\n\nfunction hasRouteConflict(source: string, resolvedTunnelRoute: string): boolean {\n const literals = [`'${resolvedTunnelRoute}'`, `\"${resolvedTunnelRoute}\"`];\n return ROUTE_CONFLICT_KEYS.some(key => literals.some(literal => source.includes(`${key}: ${literal}`)));\n}\n\nfunction injectAfterLastImport(source: string, statement: string): string {\n const importMatches = [...source.matchAll(/^import .+$/gm)];\n const lastImport = importMatches.at(-1);\n\n if (lastImport?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because `routeTree.gen.ts` imports could not be located.',\n );\n }\n\n const insertIndex = lastImport.index + lastImport[0].length;\n return `${source.slice(0, insertIndex)}\\n${statement}${source.slice(insertIndex)}`;\n}\n\nexport function injectManagedTunnelRoute(source: string, resolvedTunnelRoute: string): string {\n if (source.includes(VIRTUAL_TUNNEL_ROUTE_ID)) {\n return source;\n }\n\n if (hasRouteConflict(source, resolvedTunnelRoute)) {\n throw new Error(\n `[@sentry/tanstackstart-react] Cannot register managed tunnel route \"${resolvedTunnelRoute}\" because an existing TanStack Start route already uses that path.`,\n );\n }\n\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n\n let transformedSource = injectAfterLastImport(\n source,\n `import { Route as ${MANAGED_TUNNEL_ROUTE_IMPORT} } from '${VIRTUAL_TUNNEL_ROUTE_ID}'`,\n );\n\n const rootRouteChildrenMatch = transformedSource.match(\n /const rootRouteChildren(?:\\s*:\\s*RootRouteChildren)?\\s*=\\s*\\{/,\n );\n\n if (rootRouteChildrenMatch?.index === undefined) {\n throw new Error(\n '[@sentry/tanstackstart-react] Failed to inject the managed tunnel route because the generated TanStack route tree did not contain `rootRouteChildren`.',\n );\n }\n\n const injectedRootRouteChildrenDeclaration = `const ${MANAGED_TUNNEL_ROUTE_NAME} = ${MANAGED_TUNNEL_ROUTE_IMPORT}.update({\n id: ${serializedTunnelRoute},\n path: ${serializedTunnelRoute},\n getParentRoute: () => rootRouteImport,\n} as any)\n\n${rootRouteChildrenMatch[0]}\n ${MANAGED_TUNNEL_ROUTE_NAME}: ${MANAGED_TUNNEL_ROUTE_NAME},\n`;\n\n transformedSource = `${transformedSource.slice(0, rootRouteChildrenMatch.index)}${injectedRootRouteChildrenDeclaration}${transformedSource.slice(rootRouteChildrenMatch.index + rootRouteChildrenMatch[0].length)}`;\n\n return transformedSource;\n}\n\nexport function makeTunnelRoutePlugin(options: TunnelRouteOptions, debug?: boolean): Plugin {\n const normalized = normalizeTunnelRouteOptions(options);\n const resolvedTunnelRoute = normalized.resolvedPath;\n const serializedTunnelRoute = JSON.stringify(resolvedTunnelRoute);\n const serializedAllowedDsns = normalized.allowedDsns ? JSON.stringify(normalized.allowedDsns) : undefined;\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[@sentry/tanstackstart-react] Registered tunnel route: ${resolvedTunnelRoute}`);\n }\n\n return {\n name: 'sentry-tanstackstart-tunnel-route',\n enforce: 'pre',\n config() {\n return {\n define: {\n __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__: serializedTunnelRoute,\n },\n };\n },\n resolveId(source) {\n return source === VIRTUAL_TUNNEL_ROUTE_ID ? RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID : null;\n },\n load(id) {\n if (id !== RESOLVED_VIRTUAL_TUNNEL_ROUTE_ID) {\n return null;\n }\n\n return `import { createFileRoute } from '@tanstack/react-router';\nimport { registerSentryServerTunnelRoute } from '@sentry/tanstackstart-react';\n\n// Server-only: drop the tunnel route's own transaction. Registered synchronously at module evaluation\n// (before any request) so streamed spans are filtered from the first request. The SSR guard tree-shakes\n// it (and the import) out of the client bundle.\nif (import.meta.env.SSR) {\n registerSentryServerTunnelRoute(${serializedTunnelRoute});\n}\n\nexport const Route = createFileRoute(${serializedTunnelRoute})({\n server: {\n handlers: {\n async POST({ request }) {\n const Sentry = await import('@sentry/tanstackstart-react');\n return Sentry.createSentryTunnelRoute(${serializedAllowedDsns ? `{ allowedDsns: ${serializedAllowedDsns} }` : `{}`}).handlers.POST({ request });\n },\n },\n },\n});\n`;\n },\n transform(source, id) {\n if (!id.endsWith('/routeTree.gen.ts') && !id.endsWith('\\\\routeTree.gen.ts')) {\n return null;\n }\n\n return injectManagedTunnelRoute(source, resolvedTunnelRoute);\n },\n };\n}\n"],"names":[],"mappings":"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"}
@@ -26,4 +26,10 @@ export declare function createSentryTunnelRoute(_options: CreateSentryTunnelRout
26
26
  POST: () => Promise<Response>;
27
27
  };
28
28
  };
29
+ /**
30
+ * No-op stub for client-side builds.
31
+ * The actual implementation is server-only, but this stub is needed so the managed tunnel route module
32
+ * can statically import it (the call is server-guarded and tree-shaken from the client bundle).
33
+ */
34
+ export declare function registerSentryServerTunnelRoute(_path: string): void;
29
35
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,8BAA8B,EAC9B,6BAA6B,EAC7B,sBAAsB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAE5E,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,sBAAsB,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAE/G;AAED;;;GAGG;AACH,eAAO,MAAM,6BAA6B,EAAE,6BAI3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,8BAA8B,EAAE,8BAI5C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,8BAA8B,GAAG;IACjF,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;KAC/B,CAAC;CACH,CAMA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,8BAA8B,EAC9B,6BAA6B,EAC7B,sBAAsB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAE5E,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAE7B;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,sBAAsB,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAE/G;AAED;;;GAGG;AACH,eAAO,MAAM,6BAA6B,EAAE,6BAI3C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,8BAA8B,EAAE,8BAI5C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,8BAA8B,GAAG;IACjF,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;KAC/B,CAAC;CACH,CAMA;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAG"}
@@ -29,4 +29,5 @@ export declare const tanstackRouterBrowserTracingIntegration: typeof clientSdk.t
29
29
  export declare const sentryGlobalRequestMiddleware: typeof serverSdk.sentryGlobalRequestMiddleware;
30
30
  export declare const sentryGlobalFunctionMiddleware: typeof serverSdk.sentryGlobalFunctionMiddleware;
31
31
  export declare const createSentryTunnelRoute: typeof serverSdk.createSentryTunnelRoute;
32
+ export declare const registerSentryServerTunnelRoute: typeof serverSdk.registerSentryServerTunnelRoute;
32
33
  //# sourceMappingURL=index.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.types.d.ts","sourceRoot":"","sources":["../../src/index.types.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAE3C,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAEzB,4CAA4C;AAC5C,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,cAAc,GAAG,SAAS,CAAC,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtH,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,wBAAwB,EAAE,OAAO,SAAS,CAAC,wBAAwB,CAAC;AACzF,MAAM,CAAC,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,SAAS,CAAC,gBAAgB,CAAC;AAEzE,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;AACjF,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,WAAW,CAAC;AAErD,MAAM,CAAC,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,SAAS,CAAC,aAAa,CAAC;AACnE,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAE3E,MAAM,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAE/E,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB,EAAE,OAAO,SAAS,CAAC,qBAAqB,CAAC;AACnF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,gCAAgC,EAAE,OAAO,SAAS,CAAC,gCAAgC,CAAC;AACzG,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,OAAO,SAAS,CAAC,sBAAsB,CAAC;AACrF,MAAM,CAAC,OAAO,CAAC,MAAM,0BAA0B,EAAE,OAAO,SAAS,CAAC,0BAA0B,CAAC;AAC7F,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAC7E,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAE7E,MAAM,CAAC,OAAO,CAAC,MAAM,yBAAyB,EAAE,OAAO,SAAS,CAAC,yBAAyB,CAAC;AAE3F,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAC3E,MAAM,CAAC,OAAO,CAAC,MAAM,uCAAuC,EAAE,OAAO,SAAS,CAAC,uCAAuC,CAAC;AACvH,MAAM,CAAC,OAAO,CAAC,MAAM,6BAA6B,EAAE,OAAO,SAAS,CAAC,6BAA6B,CAAC;AACnG,MAAM,CAAC,OAAO,CAAC,MAAM,8BAA8B,EAAE,OAAO,SAAS,CAAC,8BAA8B,CAAC;AACrG,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.types.d.ts","sourceRoot":"","sources":["../../src/index.types.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,KAAK,SAAS,MAAM,UAAU,CAAC;AAE3C,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAEzB,4CAA4C;AAC5C,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC,cAAc,GAAG,SAAS,CAAC,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAEtH,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,wBAAwB,EAAE,OAAO,SAAS,CAAC,wBAAwB,CAAC;AACzF,MAAM,CAAC,OAAO,CAAC,MAAM,gBAAgB,EAAE,OAAO,SAAS,CAAC,gBAAgB,CAAC;AAEzE,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;AACjF,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,WAAW,CAAC;AAErD,MAAM,CAAC,OAAO,CAAC,MAAM,aAAa,EAAE,OAAO,SAAS,CAAC,aAAa,CAAC;AACnE,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAE3E,MAAM,CAAC,OAAO,CAAC,MAAM,MAAM,EAAE,OAAO,SAAS,CAAC,MAAM,GAAG,OAAO,SAAS,CAAC,MAAM,CAAC;AAE/E,MAAM,CAAC,OAAO,CAAC,MAAM,qBAAqB,EAAE,OAAO,SAAS,CAAC,qBAAqB,CAAC;AACnF,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,gCAAgC,EAAE,OAAO,SAAS,CAAC,gCAAgC,CAAC;AACzG,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,EAAE,OAAO,SAAS,CAAC,sBAAsB,CAAC;AACrF,MAAM,CAAC,OAAO,CAAC,MAAM,0BAA0B,EAAE,OAAO,SAAS,CAAC,0BAA0B,CAAC;AAC7F,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAC7E,MAAM,CAAC,OAAO,CAAC,MAAM,kBAAkB,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAC;AAE7E,MAAM,CAAC,OAAO,CAAC,MAAM,yBAAyB,EAAE,OAAO,SAAS,CAAC,yBAAyB,CAAC;AAE3F,MAAM,CAAC,OAAO,CAAC,MAAM,iBAAiB,EAAE,OAAO,SAAS,CAAC,iBAAiB,CAAC;AAC3E,MAAM,CAAC,OAAO,CAAC,MAAM,uCAAuC,EAAE,OAAO,SAAS,CAAC,uCAAuC,CAAC;AACvH,MAAM,CAAC,OAAO,CAAC,MAAM,6BAA6B,EAAE,OAAO,SAAS,CAAC,6BAA6B,CAAC;AACnG,MAAM,CAAC,OAAO,CAAC,MAAM,8BAA8B,EAAE,OAAO,SAAS,CAAC,8BAA8B,CAAC;AACrG,MAAM,CAAC,OAAO,CAAC,MAAM,uBAAuB,EAAE,OAAO,SAAS,CAAC,uBAAuB,CAAC;AACvF,MAAM,CAAC,OAAO,CAAC,MAAM,+BAA+B,EAAE,OAAO,SAAS,CAAC,+BAA+B,CAAC"}
@@ -4,7 +4,7 @@ export { init } from './sdk';
4
4
  export { wrapFetchWithSentry } from './wrapFetchWithSentry';
5
5
  export { wrapMiddlewaresWithSentry } from './middleware';
6
6
  export { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from './globalMiddleware';
7
- export { createSentryTunnelRoute } from './tunnelRoute';
7
+ export { createSentryTunnelRoute, registerSentryServerTunnelRoute } from './tunnelRoute';
8
8
  /**
9
9
  * A no-op stub of the replay integration for the server. Router setup code is shared between client and server,
10
10
  * so this stub is needed to prevent build errors during SSR bundling.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,cAAc,cAAc,CAAC;AAE7B,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,6BAA6B,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAKjF;AAED;;;GAGG;AACH,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,WAAW,CAKb;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAG,KAAK,CAAC,SAU7E,CAAC;AAEF;;;GAGG;AAEH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7D,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GACvC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAEb"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,cAAc,cAAc,CAAC;AAE7B,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,6BAA6B,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAC;AAEzF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAKjF;AAED;;;GAGG;AACH,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,WAAW,CAKb;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAG,KAAK,CAAC,SAU7E,CAAC;AAEF;;;GAGG;AAEH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7D,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GACvC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAEb"}
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Drops the incoming `http.server` transaction for a tunnel route by matching its request path (the
3
+ * `http.target` attribute, set at span creation, so it works for static and streamed lifecycles).
4
+ * Called at server startup for the managed route and from the handler (self-registration) otherwise.
5
+ */
6
+ export declare function registerSentryServerTunnelRoute(path: string): void;
1
7
  export interface CreateSentryTunnelRouteOptions {
2
8
  allowedDsns?: string[];
3
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelRoute.d.ts","sourceRoot":"","sources":["../../../src/server/tunnelRoute.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,8BAA8B;IAC7C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,KAAK,+BAA+B,GAAG;IACrC,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE;QACR,IAAI,EAAE,CAAC,OAAO,EAAE,+BAA+B,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;KACvE,CAAC;CACH,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,iBAAiB,CA4BlG"}
1
+ {"version":3,"file":"tunnelRoute.d.ts","sourceRoot":"","sources":["../../../src/server/tunnelRoute.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkBlE;AAED,MAAM,WAAW,8BAA8B;IAC7C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,KAAK,+BAA+B,GAAG;IACrC,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE;QACR,IAAI,EAAE,CAAC,OAAO,EAAE,+BAA+B,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;KACvE,CAAC;CACH,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,iBAAiB,CAkClG"}
@@ -1 +1 @@
1
- {"version":3,"file":"tunnelRoute.d.ts","sourceRoot":"","sources":["../../../src/vite/tunnelRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,MAAM,kBAAkB,GAC1B,IAAI,GACJ,MAAM,GACN;IACE;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAeN,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAYhE;AA6DD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAyC5F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAmD1F"}
1
+ {"version":3,"file":"tunnelRoute.d.ts","sourceRoot":"","sources":["../../../src/vite/tunnelRoute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,MAAM,MAAM,kBAAkB,GAC1B,IAAI,GACJ,MAAM,GACN;IACE;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAeN,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAYhE;AA6DD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAyC5F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CA2D1F"}
@@ -26,4 +26,10 @@ export declare function createSentryTunnelRoute(_options: CreateSentryTunnelRout
26
26
  POST: () => Promise<Response>;
27
27
  };
28
28
  };
29
+ /**
30
+ * No-op stub for client-side builds.
31
+ * The actual implementation is server-only, but this stub is needed so the managed tunnel route module
32
+ * can statically import it (the call is server-guarded and tree-shaken from the client bundle).
33
+ */
34
+ export declare function registerSentryServerTunnelRoute(_path: string): void;
29
35
  //# sourceMappingURL=index.d.ts.map
@@ -29,4 +29,5 @@ export declare const tanstackRouterBrowserTracingIntegration: typeof clientSdk.t
29
29
  export declare const sentryGlobalRequestMiddleware: typeof serverSdk.sentryGlobalRequestMiddleware;
30
30
  export declare const sentryGlobalFunctionMiddleware: typeof serverSdk.sentryGlobalFunctionMiddleware;
31
31
  export declare const createSentryTunnelRoute: typeof serverSdk.createSentryTunnelRoute;
32
+ export declare const registerSentryServerTunnelRoute: typeof serverSdk.registerSentryServerTunnelRoute;
32
33
  //# sourceMappingURL=index.types.d.ts.map
@@ -4,7 +4,7 @@ export { init } from './sdk';
4
4
  export { wrapFetchWithSentry } from './wrapFetchWithSentry';
5
5
  export { wrapMiddlewaresWithSentry } from './middleware';
6
6
  export { sentryGlobalRequestMiddleware, sentryGlobalFunctionMiddleware } from './globalMiddleware';
7
- export { createSentryTunnelRoute } from './tunnelRoute';
7
+ export { createSentryTunnelRoute, registerSentryServerTunnelRoute } from './tunnelRoute';
8
8
  /**
9
9
  * A no-op stub of the replay integration for the server. Router setup code is shared between client and server,
10
10
  * so this stub is needed to prevent build errors during SSR bundling.
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Drops the incoming `http.server` transaction for a tunnel route by matching its request path (the
3
+ * `http.target` attribute, set at span creation, so it works for static and streamed lifecycles).
4
+ * Called at server startup for the managed route and from the handler (self-registration) otherwise.
5
+ */
6
+ export declare function registerSentryServerTunnelRoute(path: string): void;
1
7
  export interface CreateSentryTunnelRouteOptions {
2
8
  allowedDsns?: string[];
3
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/tanstackstart-react",
3
- "version": "10.62.0",
3
+ "version": "10.63.0",
4
4
  "description": "Official Sentry SDK for TanStack Start React",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tanstackstart-react",
@@ -64,11 +64,11 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "@opentelemetry/api": "^1.9.1",
67
- "@sentry/browser-utils": "10.62.0",
67
+ "@sentry/browser-utils": "10.63.0",
68
68
  "@sentry/conventions": "^0.12.0",
69
- "@sentry/core": "10.62.0",
70
- "@sentry/node": "10.62.0",
71
- "@sentry/react": "10.62.0",
69
+ "@sentry/core": "10.63.0",
70
+ "@sentry/node": "10.63.0",
71
+ "@sentry/react": "10.63.0",
72
72
  "@sentry/vite-plugin": "^5.3.0"
73
73
  },
74
74
  "devDependencies": {