@sentry/tanstackstart-react 10.53.1 → 10.55.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.
- package/README.md +3 -2
- package/build/cjs/client/index.js +5 -26
- package/build/cjs/client/index.js.map +1 -1
- package/build/cjs/client/sdk.js +12 -9
- package/build/cjs/client/sdk.js.map +1 -1
- package/build/cjs/client/tunnelRoute.js +2 -13
- package/build/cjs/client/tunnelRoute.js.map +1 -1
- package/build/cjs/index.server.js +1 -0
- package/build/cjs/index.server.js.map +1 -1
- package/build/cjs/server/globalMiddleware.js +38 -22
- package/build/cjs/server/globalMiddleware.js.map +1 -1
- package/build/cjs/server/index.js +16 -29
- package/build/cjs/server/index.js.map +1 -1
- package/build/cjs/server/middleware.js +10 -66
- package/build/cjs/server/middleware.js.map +1 -1
- package/build/cjs/server/routeParametrization.js +47 -0
- package/build/cjs/server/routeParametrization.js.map +1 -0
- package/build/cjs/server/sdk.js +9 -7
- package/build/cjs/server/sdk.js.map +1 -1
- package/build/cjs/server/tunnelRoute.js +11 -31
- package/build/cjs/server/tunnelRoute.js.map +1 -1
- package/build/cjs/server/utils.js +4 -21
- package/build/cjs/server/utils.js.map +1 -1
- package/build/cjs/server/wrapFetchWithSentry.js +88 -44
- package/build/cjs/server/wrapFetchWithSentry.js.map +1 -1
- package/build/cjs/vite/autoInstrumentMiddleware.js +15 -97
- package/build/cjs/vite/autoInstrumentMiddleware.js.map +1 -1
- package/build/cjs/vite/routePatterns.js +60 -0
- package/build/cjs/vite/routePatterns.js.map +1 -0
- package/build/cjs/vite/sentryTanstackStart.js +8 -44
- package/build/cjs/vite/sentryTanstackStart.js.map +1 -1
- package/build/cjs/vite/sourceMaps.js +34 -75
- package/build/cjs/vite/sourceMaps.js.map +1 -1
- package/build/cjs/vite/tunnelRoute.js +30 -63
- package/build/cjs/vite/tunnelRoute.js.map +1 -1
- package/build/esm/client/index.js +5 -26
- package/build/esm/client/index.js.map +1 -1
- package/build/esm/client/sdk.js +12 -9
- package/build/esm/client/sdk.js.map +1 -1
- package/build/esm/client/tunnelRoute.js +2 -13
- package/build/esm/client/tunnelRoute.js.map +1 -1
- package/build/esm/index.server.js +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/server/globalMiddleware.js +39 -23
- package/build/esm/server/globalMiddleware.js.map +1 -1
- package/build/esm/server/index.js +16 -30
- package/build/esm/server/index.js.map +1 -1
- package/build/esm/server/middleware.js +10 -66
- package/build/esm/server/middleware.js.map +1 -1
- package/build/esm/server/routeParametrization.js +44 -0
- package/build/esm/server/routeParametrization.js.map +1 -0
- package/build/esm/server/sdk.js +9 -7
- package/build/esm/server/sdk.js.map +1 -1
- package/build/esm/server/tunnelRoute.js +11 -31
- package/build/esm/server/tunnelRoute.js.map +1 -1
- package/build/esm/server/utils.js +5 -21
- package/build/esm/server/utils.js.map +1 -1
- package/build/esm/server/wrapFetchWithSentry.js +90 -46
- package/build/esm/server/wrapFetchWithSentry.js.map +1 -1
- package/build/esm/vite/autoInstrumentMiddleware.js +15 -97
- package/build/esm/vite/autoInstrumentMiddleware.js.map +1 -1
- package/build/esm/vite/routePatterns.js +57 -0
- package/build/esm/vite/routePatterns.js.map +1 -0
- package/build/esm/vite/sentryTanstackStart.js +8 -44
- package/build/esm/vite/sentryTanstackStart.js.map +1 -1
- package/build/esm/vite/sourceMaps.js +34 -75
- package/build/esm/vite/sourceMaps.js.map +1 -1
- package/build/esm/vite/tunnelRoute.js +30 -63
- package/build/esm/vite/tunnelRoute.js.map +1 -1
- package/build/types/client/sdk.d.ts.map +1 -1
- package/build/types/index.types.d.ts +1 -0
- package/build/types/index.types.d.ts.map +1 -1
- package/build/types/server/globalMiddleware.d.ts.map +1 -1
- package/build/types/server/index.d.ts +5 -0
- package/build/types/server/index.d.ts.map +1 -1
- package/build/types/server/routeParametrization.d.ts +12 -0
- package/build/types/server/routeParametrization.d.ts.map +1 -0
- package/build/types/server/sdk.d.ts.map +1 -1
- package/build/types/server/utils.d.ts +0 -9
- package/build/types/server/utils.d.ts.map +1 -1
- package/build/types/server/wrapFetchWithSentry.d.ts.map +1 -1
- package/build/types/vite/routePatterns.d.ts +18 -0
- package/build/types/vite/routePatterns.d.ts.map +1 -0
- package/build/types/vite/sentryTanstackStart.d.ts +17 -0
- package/build/types/vite/sentryTanstackStart.d.ts.map +1 -1
- package/build/types/vite/sourceMaps.d.ts +4 -4
- package/build/types/vite/sourceMaps.d.ts.map +1 -1
- package/build/types-ts3.8/index.types.d.ts +1 -0
- package/build/types-ts3.8/server/index.d.ts +5 -0
- package/build/types-ts3.8/server/routeParametrization.d.ts +12 -0
- package/build/types-ts3.8/server/utils.d.ts +0 -9
- package/build/types-ts3.8/vite/routePatterns.d.ts +18 -0
- package/build/types-ts3.8/vite/sentryTanstackStart.d.ts +17 -0
- package/build/types-ts3.8/vite/sourceMaps.d.ts +4 -4
- package/package.json +5 -5
|
@@ -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';\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,37 +1,16 @@
|
|
|
1
1
|
export * from '@sentry/react';
|
|
2
2
|
export { init } from './sdk.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* No-op stub for client-side builds.
|
|
6
|
-
* The actual implementation is server-only, but this stub is needed to prevent build errors.
|
|
7
|
-
*/
|
|
8
4
|
function wrapMiddlewaresWithSentry(middlewares) {
|
|
9
5
|
return Object.values(middlewares);
|
|
10
6
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* The actual implementation is server-only, but this stub is needed to prevent rendering errors.
|
|
15
|
-
*/
|
|
16
|
-
const sentryGlobalRequestMiddleware = { '~types': undefined, options: {} };
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* No-op stub for client-side builds.
|
|
20
|
-
* The actual implementation is server-only, but this stub is needed to prevent rendering errors.
|
|
21
|
-
*/
|
|
22
|
-
const sentryGlobalFunctionMiddleware = { '~types': undefined, options: {} };
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* No-op stub for client-side builds.
|
|
26
|
-
* The actual implementation is server-only, but this stub is needed to prevent rendering errors.
|
|
27
|
-
*/
|
|
28
|
-
function createSentryTunnelRoute(_options)
|
|
29
|
-
|
|
30
|
-
{
|
|
7
|
+
const sentryGlobalRequestMiddleware = { "~types": void 0, options: {} };
|
|
8
|
+
const sentryGlobalFunctionMiddleware = { "~types": void 0, options: {} };
|
|
9
|
+
function createSentryTunnelRoute(_options) {
|
|
31
10
|
return {
|
|
32
11
|
handlers: {
|
|
33
|
-
POST: async () => new Response(null, { status: 500 })
|
|
34
|
-
}
|
|
12
|
+
POST: async () => new Response(null, { status: 500 })
|
|
13
|
+
}
|
|
35
14
|
};
|
|
36
15
|
}
|
|
37
16
|
|
|
@@ -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 { TanStackMiddlewareBase } 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: TanStackMiddlewareBase = { '~types': undefined, options: {} };\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: TanStackMiddlewareBase = { '~types': undefined, options: {} };\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":";;;
|
|
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 { TanStackMiddlewareBase } 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: TanStackMiddlewareBase = { '~types': undefined, options: {} };\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: TanStackMiddlewareBase = { '~types': undefined, options: {} };\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":";;;AAcO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,OAAO,WAAW,CAAA;AAClC;AAMO,MAAM,gCAAwD,EAAE,QAAA,EAAU,MAAA,EAAW,OAAA,EAAS,EAAC;AAM/F,MAAM,iCAAyD,EAAE,QAAA,EAAU,MAAA,EAAW,OAAA,EAAS,EAAC;AAMhG,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;;;;"}
|
package/build/esm/client/sdk.js
CHANGED
|
@@ -2,20 +2,23 @@ import { applySdkMetadata } from '@sentry/core';
|
|
|
2
2
|
import { getDefaultIntegrations, init as init$1 } from '@sentry/react';
|
|
3
3
|
import { applyTunnelRouteOption } from './tunnelRoute.js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Initializes the TanStack Start React SDK
|
|
7
|
-
*
|
|
8
|
-
* @param options Configuration options for the SDK.
|
|
9
|
-
*/
|
|
10
5
|
function init(options) {
|
|
11
6
|
const sentryOptions = {
|
|
12
7
|
defaultIntegrations: [...getDefaultIntegrations(options)],
|
|
13
|
-
...options
|
|
8
|
+
...options
|
|
14
9
|
};
|
|
15
|
-
|
|
16
10
|
applyTunnelRouteOption(sentryOptions);
|
|
17
|
-
applySdkMetadata(sentryOptions,
|
|
18
|
-
|
|
11
|
+
applySdkMetadata(sentryOptions, "tanstackstart-react", ["tanstackstart-react", "react"]);
|
|
12
|
+
sentryOptions.ignoreSpans = [
|
|
13
|
+
...sentryOptions.ignoreSpans || [],
|
|
14
|
+
/\/node_modules\//,
|
|
15
|
+
/\/favicon\.ico/,
|
|
16
|
+
/\/@id\//,
|
|
17
|
+
/\/@react-refresh/,
|
|
18
|
+
/\/@tanstack-start\//,
|
|
19
|
+
/\/@fs\//,
|
|
20
|
+
/\/@vite\//
|
|
21
|
+
];
|
|
19
22
|
return init$1(sentryOptions);
|
|
20
23
|
}
|
|
21
24
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../../src/client/sdk.ts"],"sourcesContent":["import type { Client } from '@sentry/core';\nimport { applySdkMetadata } from '@sentry/core';\nimport type { BrowserOptions as ReactBrowserOptions } from '@sentry/react';\nimport { getDefaultIntegrations as getReactDefaultIntegrations, init as initReactSDK } from '@sentry/react';\nimport { applyTunnelRouteOption } from './tunnelRoute';\n\n/**\n * Initializes the TanStack Start React SDK\n *\n * @param options Configuration options for the SDK.\n */\nexport function init(options: ReactBrowserOptions): Client | undefined {\n const sentryOptions: ReactBrowserOptions = {\n defaultIntegrations: [...getReactDefaultIntegrations(options)],\n ...options,\n };\n\n applyTunnelRouteOption(sentryOptions);\n applySdkMetadata(sentryOptions, 'tanstackstart-react', ['tanstackstart-react', 'react']);\n\n return initReactSDK(sentryOptions);\n}\n"],"names":["getReactDefaultIntegrations","initReactSDK"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../../src/client/sdk.ts"],"sourcesContent":["import type { Client } from '@sentry/core';\nimport { applySdkMetadata } from '@sentry/core';\nimport type { BrowserOptions as ReactBrowserOptions } from '@sentry/react';\nimport { getDefaultIntegrations as getReactDefaultIntegrations, init as initReactSDK } from '@sentry/react';\nimport { applyTunnelRouteOption } from './tunnelRoute';\n\n/**\n * Initializes the TanStack Start React SDK\n *\n * @param options Configuration options for the SDK.\n */\nexport function init(options: ReactBrowserOptions): Client | undefined {\n const sentryOptions: ReactBrowserOptions = {\n defaultIntegrations: [...getReactDefaultIntegrations(options)],\n ...options,\n };\n\n applyTunnelRouteOption(sentryOptions);\n applySdkMetadata(sentryOptions, 'tanstackstart-react', ['tanstackstart-react', 'react']);\n\n sentryOptions.ignoreSpans = [\n ...(sentryOptions.ignoreSpans || []),\n /\\/node_modules\\//,\n /\\/favicon\\.ico/,\n /\\/@id\\//,\n /\\/@react-refresh/,\n /\\/@tanstack-start\\//,\n /\\/@fs\\//,\n /\\/@vite\\//,\n ];\n\n return initReactSDK(sentryOptions);\n}\n"],"names":["getReactDefaultIntegrations","initReactSDK"],"mappings":";;;;AAWO,SAAS,KAAK,OAAA,EAAkD;AACrE,EAAA,MAAM,aAAA,GAAqC;AAAA,IACzC,mBAAA,EAAqB,CAAC,GAAGA,sBAAA,CAA4B,OAAO,CAAC,CAAA;AAAA,IAC7D,GAAG;AAAA,GACL;AAEA,EAAA,sBAAA,CAAuB,aAAa,CAAA;AACpC,EAAA,gBAAA,CAAiB,aAAA,EAAe,qBAAA,EAAuB,CAAC,qBAAA,EAAuB,OAAO,CAAC,CAAA;AAEvF,EAAA,aAAA,CAAc,WAAA,GAAc;AAAA,IAC1B,GAAI,aAAA,CAAc,WAAA,IAAe,EAAC;AAAA,IAClC,kBAAA;AAAA,IACA,gBAAA;AAAA,IACA,SAAA;AAAA,IACA,kBAAA;AAAA,IACA,qBAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAOC,OAAa,aAAa,CAAA;AACnC;;;;"}
|
|
@@ -1,33 +1,22 @@
|
|
|
1
1
|
import { consoleSandbox } from '@sentry/core';
|
|
2
2
|
|
|
3
3
|
let hasWarnedAboutManagedTunnelRouteOverride = false;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Applies the managed tunnel route from `sentryTanstackStart({ tunnelRoute: ... })` unless the user already
|
|
7
|
-
* configured an explicit runtime `tunnel` option in `Sentry.init()`.
|
|
8
|
-
*/
|
|
9
4
|
function applyTunnelRouteOption(options) {
|
|
10
|
-
const managedTunnelRoute =
|
|
11
|
-
typeof __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ !== 'undefined' ? __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ : undefined;
|
|
12
|
-
|
|
5
|
+
const managedTunnelRoute = typeof __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ !== "undefined" ? __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ : void 0;
|
|
13
6
|
if (!managedTunnelRoute) {
|
|
14
7
|
return;
|
|
15
8
|
}
|
|
16
|
-
|
|
17
9
|
if (options.tunnel) {
|
|
18
10
|
if (!hasWarnedAboutManagedTunnelRouteOverride) {
|
|
19
11
|
hasWarnedAboutManagedTunnelRouteOverride = true;
|
|
20
12
|
consoleSandbox(() => {
|
|
21
|
-
// eslint-disable-next-line no-console
|
|
22
13
|
console.warn(
|
|
23
|
-
|
|
14
|
+
"[@sentry/tanstackstart-react] `Sentry.init({ tunnel: ... })` overrides the managed `sentryTanstackStart({ tunnelRoute: ... })` route. Remove the runtime `tunnel` option if you want the managed tunnel route to be used."
|
|
24
15
|
);
|
|
25
16
|
});
|
|
26
17
|
}
|
|
27
|
-
|
|
28
18
|
return;
|
|
29
19
|
}
|
|
30
|
-
|
|
31
20
|
options.tunnel = managedTunnelRoute;
|
|
32
21
|
}
|
|
33
22
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnelRoute.js","sources":["../../../src/client/tunnelRoute.ts"],"sourcesContent":["import { consoleSandbox } from '@sentry/core';\nimport type { BrowserOptions as ReactBrowserOptions } from '@sentry/react';\n\ndeclare const __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__: string | undefined;\n\nlet hasWarnedAboutManagedTunnelRouteOverride = false;\n\n/**\n * Applies the managed tunnel route from `sentryTanstackStart({ tunnelRoute: ... })` unless the user already\n * configured an explicit runtime `tunnel` option in `Sentry.init()`.\n */\nexport function applyTunnelRouteOption(options: ReactBrowserOptions): void {\n const managedTunnelRoute =\n typeof __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ !== 'undefined' ? __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ : undefined;\n\n if (!managedTunnelRoute) {\n return;\n }\n\n if (options.tunnel) {\n if (!hasWarnedAboutManagedTunnelRouteOverride) {\n hasWarnedAboutManagedTunnelRouteOverride = true;\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[@sentry/tanstackstart-react] `Sentry.init({ tunnel: ... })` overrides the managed `sentryTanstackStart({ tunnelRoute: ... })` route. Remove the runtime `tunnel` option if you want the managed tunnel route to be used.',\n );\n });\n }\n\n return;\n }\n\n options.tunnel = managedTunnelRoute;\n}\n"],"names":[],"mappings":";;AAKA,IAAI,wCAAA,GAA2C,
|
|
1
|
+
{"version":3,"file":"tunnelRoute.js","sources":["../../../src/client/tunnelRoute.ts"],"sourcesContent":["import { consoleSandbox } from '@sentry/core';\nimport type { BrowserOptions as ReactBrowserOptions } from '@sentry/react';\n\ndeclare const __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__: string | undefined;\n\nlet hasWarnedAboutManagedTunnelRouteOverride = false;\n\n/**\n * Applies the managed tunnel route from `sentryTanstackStart({ tunnelRoute: ... })` unless the user already\n * configured an explicit runtime `tunnel` option in `Sentry.init()`.\n */\nexport function applyTunnelRouteOption(options: ReactBrowserOptions): void {\n const managedTunnelRoute =\n typeof __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ !== 'undefined' ? __SENTRY_TANSTACKSTART_TUNNEL_ROUTE__ : undefined;\n\n if (!managedTunnelRoute) {\n return;\n }\n\n if (options.tunnel) {\n if (!hasWarnedAboutManagedTunnelRouteOverride) {\n hasWarnedAboutManagedTunnelRouteOverride = true;\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n '[@sentry/tanstackstart-react] `Sentry.init({ tunnel: ... })` overrides the managed `sentryTanstackStart({ tunnelRoute: ... })` route. Remove the runtime `tunnel` option if you want the managed tunnel route to be used.',\n );\n });\n }\n\n return;\n }\n\n options.tunnel = managedTunnelRoute;\n}\n"],"names":[],"mappings":";;AAKA,IAAI,wCAAA,GAA2C,KAAA;AAMxC,SAAS,uBAAuB,OAAA,EAAoC;AACzE,EAAA,MAAM,kBAAA,GACJ,OAAO,qCAAA,KAA0C,WAAA,GAAc,qCAAA,GAAwC,MAAA;AAEzG,EAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,QAAQ,MAAA,EAAQ;AAClB,IAAA,IAAI,CAAC,wCAAA,EAA0C;AAC7C,MAAA,wCAAA,GAA2C,IAAA;AAC3C,MAAA,cAAA,CAAe,MAAM;AAEnB,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN;AAAA,SACF;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAEA,IAAA;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,MAAA,GAAS,kBAAA;AACnB;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ErrorBoundary, tanstackRouterBrowserTracingIntegration, withErrorBoundary } from './server/index.js';
|
|
1
|
+
export { ErrorBoundary, replayIntegration, tanstackRouterBrowserTracingIntegration, withErrorBoundary } from './server/index.js';
|
|
2
2
|
export * from '@sentry/node';
|
|
3
3
|
export { createSentryTunnelRoute } from './server/tunnelRoute.js';
|
|
4
4
|
export { init } from './server/sdk.js';
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"10.
|
|
1
|
+
{"type":"module","version":"10.55.0","sideEffects":false}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addNonEnumerableProperty, captureException } from '@sentry/core';
|
|
1
|
+
import { addNonEnumerableProperty, captureException, getActiveSpan, spanToJSON, updateSpanName, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
|
|
2
2
|
import { SENTRY_INTERNAL } from './middleware.js';
|
|
3
3
|
|
|
4
4
|
function createSentryMiddlewareHandler(mechanismType) {
|
|
@@ -7,40 +7,56 @@ function createSentryMiddlewareHandler(mechanismType) {
|
|
|
7
7
|
return await next();
|
|
8
8
|
} catch (e) {
|
|
9
9
|
captureException(e, {
|
|
10
|
-
mechanism: { type: mechanismType, handled: false }
|
|
10
|
+
mechanism: { type: mechanismType, handled: false }
|
|
11
|
+
});
|
|
12
|
+
throw e;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function createSentryFunctionMiddlewareHandler(mechanismType) {
|
|
17
|
+
return async function sentryFunctionMiddlewareHandler({
|
|
18
|
+
next,
|
|
19
|
+
serverFnMeta
|
|
20
|
+
}) {
|
|
21
|
+
const activeSpan = getActiveSpan();
|
|
22
|
+
const spanData = activeSpan ? spanToJSON(activeSpan) : void 0;
|
|
23
|
+
if (activeSpan && spanData?.op === "function.tanstackstart") {
|
|
24
|
+
if (serverFnMeta?.name) {
|
|
25
|
+
const method = spanData.description?.split(" ")[0] || "GET";
|
|
26
|
+
updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);
|
|
27
|
+
activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, "route");
|
|
28
|
+
}
|
|
29
|
+
if (serverFnMeta?.id) {
|
|
30
|
+
activeSpan.setAttribute("tanstackstart.function.id", serverFnMeta.id);
|
|
31
|
+
}
|
|
32
|
+
if (serverFnMeta?.filename) {
|
|
33
|
+
activeSpan.setAttribute("tanstackstart.function.filename", serverFnMeta.filename);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
return await next();
|
|
38
|
+
} catch (e) {
|
|
39
|
+
captureException(e, {
|
|
40
|
+
mechanism: { type: mechanismType, handled: false }
|
|
11
41
|
});
|
|
12
42
|
throw e;
|
|
13
43
|
}
|
|
14
44
|
};
|
|
15
45
|
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Global request middleware that captures errors from API route requests.
|
|
19
|
-
* Should be added as the first entry in the `requestMiddleware` array of `createStart()`.
|
|
20
|
-
*/
|
|
21
46
|
const sentryGlobalRequestMiddleware = {
|
|
22
|
-
|
|
23
|
-
|
|
47
|
+
"~types": void 0,
|
|
24
48
|
options: {
|
|
25
49
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
-
server: createSentryMiddlewareHandler(
|
|
27
|
-
}
|
|
50
|
+
server: createSentryMiddlewareHandler("auto.middleware.tanstackstart.request")
|
|
51
|
+
}
|
|
28
52
|
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Global function middleware that captures errors from server function invocations.
|
|
32
|
-
* Should be added as the first entry in the `functionMiddleware` array of `createStart()`.
|
|
33
|
-
*/
|
|
34
53
|
const sentryGlobalFunctionMiddleware = {
|
|
35
|
-
|
|
36
|
-
|
|
54
|
+
"~types": void 0,
|
|
37
55
|
options: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
56
|
+
server: createSentryFunctionMiddlewareHandler("auto.middleware.tanstackstart.server_function")
|
|
57
|
+
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
58
|
+
}
|
|
41
59
|
};
|
|
42
|
-
|
|
43
|
-
// Mark as internal so the Vite auto-instrumentation plugin skips these middleware
|
|
44
60
|
addNonEnumerableProperty(sentryGlobalRequestMiddleware, SENTRY_INTERNAL, true);
|
|
45
61
|
addNonEnumerableProperty(sentryGlobalFunctionMiddleware, SENTRY_INTERNAL, true);
|
|
46
62
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"globalMiddleware.js","sources":["../../../src/server/globalMiddleware.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"globalMiddleware.js","sources":["../../../src/server/globalMiddleware.ts"],"sourcesContent":["import {\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n addNonEnumerableProperty,\n captureException,\n getActiveSpan,\n spanToJSON,\n updateSpanName,\n} from '@sentry/core';\nimport type { TanStackMiddlewareBase } from '../common/types';\nimport { SENTRY_INTERNAL } from './middleware';\n\ntype ServerFnMeta = {\n id?: string;\n name?: string;\n filename?: string;\n};\n\nfunction createSentryMiddlewareHandler(mechanismType: string) {\n return async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown> }): Promise<unknown> {\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\nfunction createSentryFunctionMiddlewareHandler(mechanismType: string) {\n return async function sentryFunctionMiddlewareHandler({\n next,\n serverFnMeta,\n }: {\n next: () => Promise<unknown>;\n serverFnMeta?: ServerFnMeta;\n }): Promise<unknown> {\n const activeSpan = getActiveSpan();\n const spanData = activeSpan ? spanToJSON(activeSpan) : undefined;\n if (activeSpan && spanData?.op === 'function.tanstackstart') {\n if (serverFnMeta?.name) {\n const method = spanData.description?.split(' ')[0] || 'GET';\n updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);\n activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n if (serverFnMeta?.id) {\n activeSpan.setAttribute('tanstackstart.function.id', serverFnMeta.id);\n }\n if (serverFnMeta?.filename) {\n activeSpan.setAttribute('tanstackstart.function.filename', serverFnMeta.filename);\n }\n }\n\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\n/**\n * Global request middleware that captures errors from API route requests.\n * Should be added as the first entry in the `requestMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalRequestMiddleware: TanStackMiddlewareBase = {\n '~types': undefined,\n\n options: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n server: createSentryMiddlewareHandler('auto.middleware.tanstackstart.request') as (...args: any[]) => any,\n },\n};\n\n/**\n * Global function middleware that captures errors from server function invocations.\n * Should be added as the first entry in the `functionMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalFunctionMiddleware: TanStackMiddlewareBase = {\n '~types': undefined,\n\n options: {\n server: createSentryFunctionMiddlewareHandler('auto.middleware.tanstackstart.server_function') as (\n ...args: any[] // eslint-disable-line @typescript-eslint/no-explicit-any\n ) => any, // eslint-disable-line @typescript-eslint/no-explicit-any\n },\n};\n\n// Mark as internal so the Vite auto-instrumentation plugin skips these middleware\naddNonEnumerableProperty(sentryGlobalRequestMiddleware, SENTRY_INTERNAL, true);\naddNonEnumerableProperty(sentryGlobalFunctionMiddleware, SENTRY_INTERNAL, true);\n"],"names":[],"mappings":";;;AAiBA,SAAS,8BAA8B,aAAA,EAAuB;AAC5D,EAAA,OAAO,eAAe,uBAAA,CAAwB,EAAE,IAAA,EAAK,EAAuD;AAC1G,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAEA,SAAS,sCAAsC,aAAA,EAAuB;AACpE,EAAA,OAAO,eAAe,+BAAA,CAAgC;AAAA,IACpD,IAAA;AAAA,IACA;AAAA,GACF,EAGqB;AACnB,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAa,UAAA,CAAW,UAAU,CAAA,GAAI,MAAA;AACvD,IAAA,IAAI,UAAA,IAAc,QAAA,EAAU,EAAA,KAAO,wBAAA,EAA0B;AAC3D,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,MAAM,SAAS,QAAA,CAAS,WAAA,EAAa,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,KAAA;AACtD,QAAA,cAAA,CAAe,YAAY,CAAA,EAAG,MAAM,CAAA,YAAA,EAAe,YAAA,CAAa,IAAI,CAAA,CAAE,CAAA;AACtE,QAAA,UAAA,CAAW,YAAA,CAAa,kCAAkC,OAAO,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,UAAA,CAAW,YAAA,CAAa,2BAAA,EAA6B,YAAA,CAAa,EAAE,CAAA;AAAA,MACtE;AACA,MAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,QAAA,UAAA,CAAW,YAAA,CAAa,iCAAA,EAAmC,YAAA,CAAa,QAAQ,CAAA;AAAA,MAClF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMO,MAAM,6BAAA,GAAwD;AAAA,EACnE,QAAA,EAAU,MAAA;AAAA,EAEV,OAAA,EAAS;AAAA;AAAA,IAEP,MAAA,EAAQ,8BAA8B,uCAAuC;AAAA;AAEjF;AAMO,MAAM,8BAAA,GAAyD;AAAA,EACpE,QAAA,EAAU,MAAA;AAAA,EAEV,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,sCAAsC,+CAA+C;AAAA;AAAA;AAIjG;AAGA,wBAAA,CAAyB,6BAAA,EAA+B,iBAAiB,IAAI,CAAA;AAC7E,wBAAA,CAAyB,8BAAA,EAAgC,iBAAiB,IAAI,CAAA;;;;"}
|
|
@@ -5,46 +5,32 @@ export { wrapMiddlewaresWithSentry } from './middleware.js';
|
|
|
5
5
|
export { sentryGlobalFunctionMiddleware, sentryGlobalRequestMiddleware } from './globalMiddleware.js';
|
|
6
6
|
export { createSentryTunnelRoute } from './tunnelRoute.js';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
* A no-op stub of the browser tracing integration for the server. Router setup code is shared between client and server,
|
|
10
|
-
* so this stub is needed to prevent build errors during SSR bundling.
|
|
11
|
-
*/
|
|
12
|
-
function tanstackRouterBrowserTracingIntegration(
|
|
13
|
-
_router,
|
|
14
|
-
_options,
|
|
15
|
-
) {
|
|
8
|
+
function replayIntegration(_options) {
|
|
16
9
|
return {
|
|
17
|
-
name:
|
|
18
|
-
setup() {
|
|
10
|
+
name: "Replay",
|
|
11
|
+
setup() {
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function tanstackRouterBrowserTracingIntegration(_router, _options) {
|
|
16
|
+
return {
|
|
17
|
+
name: "BrowserTracing",
|
|
18
|
+
setup() {
|
|
19
|
+
}
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors
|
|
24
|
-
* so they should simply be a passthrough.
|
|
25
|
-
*/
|
|
26
22
|
const ErrorBoundary = (props) => {
|
|
27
23
|
if (!props.children) {
|
|
28
24
|
return null;
|
|
29
25
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return (props.children )();
|
|
26
|
+
if (typeof props.children === "function") {
|
|
27
|
+
return props.children();
|
|
33
28
|
}
|
|
34
|
-
|
|
35
29
|
return props.children;
|
|
36
30
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch
|
|
40
|
-
* SSR errors so they should simply be a passthrough.
|
|
41
|
-
*/
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
-
function withErrorBoundary(
|
|
44
|
-
WrappedComponent,
|
|
45
|
-
) {
|
|
46
|
-
return WrappedComponent ;
|
|
31
|
+
function withErrorBoundary(WrappedComponent) {
|
|
32
|
+
return WrappedComponent;
|
|
47
33
|
}
|
|
48
34
|
|
|
49
|
-
export { ErrorBoundary, tanstackRouterBrowserTracingIntegration, withErrorBoundary };
|
|
35
|
+
export { ErrorBoundary, replayIntegration, tanstackRouterBrowserTracingIntegration, withErrorBoundary };
|
|
50
36
|
//# sourceMappingURL=index.js.map
|
|
@@ -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 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":";;;;;;;
|
|
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;;;;"}
|
|
@@ -2,109 +2,53 @@ import { addNonEnumerableProperty } from '@sentry/core';
|
|
|
2
2
|
import { getActiveSpan, startSpanManual, withActiveSpan } from '@sentry/node';
|
|
3
3
|
import { getMiddlewareSpanOptions } from './utils.js';
|
|
4
4
|
|
|
5
|
-
const SENTRY_WRAPPED =
|
|
6
|
-
const SENTRY_INTERNAL =
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Creates a proxy for the next function that ends the current span and restores the parent span.
|
|
10
|
-
* This ensures that subsequent middleware spans are children of the root span, not nested children.
|
|
11
|
-
*/
|
|
12
|
-
function getNextProxy(
|
|
13
|
-
next,
|
|
14
|
-
span,
|
|
15
|
-
prevSpan,
|
|
16
|
-
nextState,
|
|
17
|
-
) {
|
|
5
|
+
const SENTRY_WRAPPED = "__SENTRY_WRAPPED__";
|
|
6
|
+
const SENTRY_INTERNAL = "__SENTRY_INTERNAL__";
|
|
7
|
+
function getNextProxy(next, span, prevSpan, nextState) {
|
|
18
8
|
return new Proxy(next, {
|
|
19
9
|
apply: (originalNext, thisArgNext, argsNext) => {
|
|
20
10
|
nextState.called = true;
|
|
21
11
|
span.end();
|
|
22
|
-
|
|
23
12
|
if (prevSpan) {
|
|
24
13
|
return withActiveSpan(prevSpan, () => {
|
|
25
14
|
return Reflect.apply(originalNext, thisArgNext, argsNext);
|
|
26
15
|
});
|
|
27
16
|
}
|
|
28
|
-
|
|
29
17
|
return Reflect.apply(originalNext, thisArgNext, argsNext);
|
|
30
|
-
}
|
|
18
|
+
}
|
|
31
19
|
});
|
|
32
20
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* Wraps a TanStack Start middleware with Sentry instrumentation to create spans.
|
|
36
|
-
*/
|
|
37
|
-
function wrapMiddlewareWithSentry(
|
|
38
|
-
middleware,
|
|
39
|
-
options,
|
|
40
|
-
) {
|
|
41
|
-
if (
|
|
42
|
-
(middleware )[SENTRY_WRAPPED] ||
|
|
43
|
-
(middleware )[SENTRY_INTERNAL]
|
|
44
|
-
) {
|
|
45
|
-
// already instrumented or internal Sentry middleware
|
|
21
|
+
function wrapMiddlewareWithSentry(middleware, options) {
|
|
22
|
+
if (middleware[SENTRY_WRAPPED] || middleware[SENTRY_INTERNAL]) {
|
|
46
23
|
return middleware;
|
|
47
24
|
}
|
|
48
|
-
|
|
49
|
-
// instrument server middleware
|
|
50
25
|
if (middleware.options?.server) {
|
|
51
26
|
middleware.options.server = new Proxy(middleware.options.server, {
|
|
52
27
|
apply: (originalServer, thisArgServer, argsServer) => {
|
|
53
28
|
const prevSpan = getActiveSpan();
|
|
54
|
-
|
|
55
29
|
return startSpanManual(getMiddlewareSpanOptions(options.name), async (span) => {
|
|
56
30
|
const nextState = { called: false };
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Users call next() inside their middleware to move down the middleware chain. We proxy next() to end the span when it is called.
|
|
60
|
-
const middlewareArgs = argsServer[0] ;
|
|
61
|
-
if (middlewareArgs && typeof middlewareArgs === 'object' && typeof middlewareArgs.next === 'function') {
|
|
31
|
+
const middlewareArgs = argsServer[0];
|
|
32
|
+
if (middlewareArgs && typeof middlewareArgs === "object" && typeof middlewareArgs.next === "function") {
|
|
62
33
|
middlewareArgs.next = getNextProxy(middlewareArgs.next, span, prevSpan, nextState);
|
|
63
34
|
}
|
|
64
|
-
|
|
65
35
|
try {
|
|
66
36
|
const result = await originalServer.apply(thisArgServer, argsServer);
|
|
67
|
-
|
|
68
|
-
// End span here if next() wasn't called, else we already ended it in next()
|
|
69
37
|
if (!nextState.called) {
|
|
70
38
|
span.end();
|
|
71
39
|
}
|
|
72
|
-
|
|
73
40
|
return result;
|
|
74
41
|
} catch (e) {
|
|
75
42
|
span.end();
|
|
76
43
|
throw e;
|
|
77
44
|
}
|
|
78
45
|
});
|
|
79
|
-
}
|
|
46
|
+
}
|
|
80
47
|
});
|
|
81
|
-
|
|
82
|
-
// mark as instrumented
|
|
83
|
-
addNonEnumerableProperty(middleware , SENTRY_WRAPPED, true);
|
|
48
|
+
addNonEnumerableProperty(middleware, SENTRY_WRAPPED, true);
|
|
84
49
|
}
|
|
85
|
-
|
|
86
50
|
return middleware;
|
|
87
51
|
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Wraps multiple TanStack Start middlewares with Sentry instrumentation.
|
|
91
|
-
* Object keys are used as span names to avoid users having to specify this manually.
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```ts
|
|
95
|
-
* import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';
|
|
96
|
-
*
|
|
97
|
-
* const wrappedMiddlewares = wrapMiddlewaresWithSentry({
|
|
98
|
-
* authMiddleware,
|
|
99
|
-
* loggingMiddleware,
|
|
100
|
-
* });
|
|
101
|
-
*
|
|
102
|
-
* createServerFn().middleware(wrappedMiddlewares)
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
|
-
* @param middlewares - An object containing middlewares
|
|
106
|
-
* @returns An array of wrapped middlewares
|
|
107
|
-
*/
|
|
108
52
|
function wrapMiddlewaresWithSentry(middlewares) {
|
|
109
53
|
return Object.entries(middlewares).map(([name, middleware]) => {
|
|
110
54
|
return wrapMiddlewareWithSentry(middleware, { name });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sources":["../../../src/server/middleware.ts"],"sourcesContent":["import { addNonEnumerableProperty } from '@sentry/core';\nimport type { Span } from '@sentry/node';\nimport { getActiveSpan, startSpanManual, withActiveSpan } from '@sentry/node';\nimport type { MiddlewareWrapperOptions, TanStackMiddlewareBase } from '../common/types';\nimport { getMiddlewareSpanOptions } from './utils';\n\nconst SENTRY_WRAPPED = '__SENTRY_WRAPPED__';\nexport const SENTRY_INTERNAL = '__SENTRY_INTERNAL__';\n\n/**\n * Creates a proxy for the next function that ends the current span and restores the parent span.\n * This ensures that subsequent middleware spans are children of the root span, not nested children.\n */\nfunction getNextProxy<T extends (...args: unknown[]) => unknown>(\n next: T,\n span: Span,\n prevSpan: Span | undefined,\n nextState: { called: boolean },\n): T {\n return new Proxy(next, {\n apply: (originalNext, thisArgNext, argsNext) => {\n nextState.called = true;\n span.end();\n\n if (prevSpan) {\n return withActiveSpan(prevSpan, () => {\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n });\n }\n\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n },\n });\n}\n\n/**\n * Wraps a TanStack Start middleware with Sentry instrumentation to create spans.\n */\nfunction wrapMiddlewareWithSentry<T extends TanStackMiddlewareBase>(\n middleware: T,\n options: MiddlewareWrapperOptions,\n): T {\n if (\n (middleware as TanStackMiddlewareBase & { [SENTRY_WRAPPED]?: boolean })[SENTRY_WRAPPED] ||\n (middleware as TanStackMiddlewareBase & { [SENTRY_INTERNAL]?: boolean })[SENTRY_INTERNAL]\n ) {\n // already instrumented or internal Sentry middleware\n return middleware;\n }\n\n // instrument server middleware\n if (middleware.options?.server) {\n middleware.options.server = new Proxy(middleware.options.server, {\n apply: (originalServer, thisArgServer, argsServer) => {\n const prevSpan = getActiveSpan();\n\n return startSpanManual(getMiddlewareSpanOptions(options.name), async (span: Span) => {\n const nextState = { called: false };\n\n // The server function receives { next, context, request } as first argument\n // Users call next() inside their middleware to move down the middleware chain. We proxy next() to end the span when it is called.\n const middlewareArgs = argsServer[0] as { next?: (...args: unknown[]) => unknown } | undefined;\n if (middlewareArgs && typeof middlewareArgs === 'object' && typeof middlewareArgs.next === 'function') {\n middlewareArgs.next = getNextProxy(middlewareArgs.next, span, prevSpan, nextState);\n }\n\n try {\n const result = await originalServer.apply(thisArgServer, argsServer);\n\n // End span here if next() wasn't called, else we already ended it in next()\n if (!nextState.called) {\n span.end();\n }\n\n return result;\n } catch (e) {\n span.end();\n throw e;\n }\n });\n },\n });\n\n // mark as instrumented\n addNonEnumerableProperty(middleware as unknown as Record<string, unknown>, SENTRY_WRAPPED, true);\n }\n\n return middleware;\n}\n\n/**\n * Wraps multiple TanStack Start middlewares with Sentry instrumentation.\n * Object keys are used as span names to avoid users having to specify this manually.\n *\n * @example\n * ```ts\n * import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n *\n * const wrappedMiddlewares = wrapMiddlewaresWithSentry({\n * authMiddleware,\n * loggingMiddleware,\n * });\n *\n * createServerFn().middleware(wrappedMiddlewares)\n * ```\n *\n * @param middlewares - An object containing middlewares\n * @returns An array of wrapped middlewares\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.entries(middlewares).map(([name, middleware]) => {\n return wrapMiddlewareWithSentry(middleware, { name });\n });\n}\n"],"names":[],"mappings":";;;;AAMA,MAAM,cAAA,GAAiB,
|
|
1
|
+
{"version":3,"file":"middleware.js","sources":["../../../src/server/middleware.ts"],"sourcesContent":["import { addNonEnumerableProperty } from '@sentry/core';\nimport type { Span } from '@sentry/node';\nimport { getActiveSpan, startSpanManual, withActiveSpan } from '@sentry/node';\nimport type { MiddlewareWrapperOptions, TanStackMiddlewareBase } from '../common/types';\nimport { getMiddlewareSpanOptions } from './utils';\n\nconst SENTRY_WRAPPED = '__SENTRY_WRAPPED__';\nexport const SENTRY_INTERNAL = '__SENTRY_INTERNAL__';\n\n/**\n * Creates a proxy for the next function that ends the current span and restores the parent span.\n * This ensures that subsequent middleware spans are children of the root span, not nested children.\n */\nfunction getNextProxy<T extends (...args: unknown[]) => unknown>(\n next: T,\n span: Span,\n prevSpan: Span | undefined,\n nextState: { called: boolean },\n): T {\n return new Proxy(next, {\n apply: (originalNext, thisArgNext, argsNext) => {\n nextState.called = true;\n span.end();\n\n if (prevSpan) {\n return withActiveSpan(prevSpan, () => {\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n });\n }\n\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n },\n });\n}\n\n/**\n * Wraps a TanStack Start middleware with Sentry instrumentation to create spans.\n */\nfunction wrapMiddlewareWithSentry<T extends TanStackMiddlewareBase>(\n middleware: T,\n options: MiddlewareWrapperOptions,\n): T {\n if (\n (middleware as TanStackMiddlewareBase & { [SENTRY_WRAPPED]?: boolean })[SENTRY_WRAPPED] ||\n (middleware as TanStackMiddlewareBase & { [SENTRY_INTERNAL]?: boolean })[SENTRY_INTERNAL]\n ) {\n // already instrumented or internal Sentry middleware\n return middleware;\n }\n\n // instrument server middleware\n if (middleware.options?.server) {\n middleware.options.server = new Proxy(middleware.options.server, {\n apply: (originalServer, thisArgServer, argsServer) => {\n const prevSpan = getActiveSpan();\n\n return startSpanManual(getMiddlewareSpanOptions(options.name), async (span: Span) => {\n const nextState = { called: false };\n\n // The server function receives { next, context, request } as first argument\n // Users call next() inside their middleware to move down the middleware chain. We proxy next() to end the span when it is called.\n const middlewareArgs = argsServer[0] as { next?: (...args: unknown[]) => unknown } | undefined;\n if (middlewareArgs && typeof middlewareArgs === 'object' && typeof middlewareArgs.next === 'function') {\n middlewareArgs.next = getNextProxy(middlewareArgs.next, span, prevSpan, nextState);\n }\n\n try {\n const result = await originalServer.apply(thisArgServer, argsServer);\n\n // End span here if next() wasn't called, else we already ended it in next()\n if (!nextState.called) {\n span.end();\n }\n\n return result;\n } catch (e) {\n span.end();\n throw e;\n }\n });\n },\n });\n\n // mark as instrumented\n addNonEnumerableProperty(middleware as unknown as Record<string, unknown>, SENTRY_WRAPPED, true);\n }\n\n return middleware;\n}\n\n/**\n * Wraps multiple TanStack Start middlewares with Sentry instrumentation.\n * Object keys are used as span names to avoid users having to specify this manually.\n *\n * @example\n * ```ts\n * import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n *\n * const wrappedMiddlewares = wrapMiddlewaresWithSentry({\n * authMiddleware,\n * loggingMiddleware,\n * });\n *\n * createServerFn().middleware(wrappedMiddlewares)\n * ```\n *\n * @param middlewares - An object containing middlewares\n * @returns An array of wrapped middlewares\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.entries(middlewares).map(([name, middleware]) => {\n return wrapMiddlewareWithSentry(middleware, { name });\n });\n}\n"],"names":[],"mappings":";;;;AAMA,MAAM,cAAA,GAAiB,oBAAA;AAChB,MAAM,eAAA,GAAkB;AAM/B,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,QAAA,EACA,SAAA,EACG;AACH,EAAA,OAAO,IAAI,MAAM,IAAA,EAAM;AAAA,IACrB,KAAA,EAAO,CAAC,YAAA,EAAc,WAAA,EAAa,QAAA,KAAa;AAC9C,MAAA,SAAA,CAAU,MAAA,GAAS,IAAA;AACnB,MAAA,IAAA,CAAK,GAAA,EAAI;AAET,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,cAAA,CAAe,UAAU,MAAM;AACpC,UAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,QAC1D,CAAC,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACD,CAAA;AACH;AAKA,SAAS,wBAAA,CACP,YACA,OAAA,EACG;AACH,EAAA,IACG,UAAA,CAAuE,cAAc,CAAA,IACrF,UAAA,CAAwE,eAAe,CAAA,EACxF;AAEA,IAAA,OAAO,UAAA;AAAA,EACT;AAGA,EAAA,IAAI,UAAA,CAAW,SAAS,MAAA,EAAQ;AAC9B,IAAA,UAAA,CAAW,QAAQ,MAAA,GAAS,IAAI,KAAA,CAAM,UAAA,CAAW,QAAQ,MAAA,EAAQ;AAAA,MAC/D,KAAA,EAAO,CAAC,cAAA,EAAgB,aAAA,EAAe,UAAA,KAAe;AACpD,QAAA,MAAM,WAAW,aAAA,EAAc;AAE/B,QAAA,OAAO,gBAAgB,wBAAA,CAAyB,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,IAAA,KAAe;AACnF,UAAA,MAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,EAAM;AAIlC,UAAA,MAAM,cAAA,GAAiB,WAAW,CAAC,CAAA;AACnC,UAAA,IAAI,kBAAkB,OAAO,cAAA,KAAmB,YAAY,OAAO,cAAA,CAAe,SAAS,UAAA,EAAY;AACrG,YAAA,cAAA,CAAe,OAAO,YAAA,CAAa,cAAA,CAAe,IAAA,EAAM,IAAA,EAAM,UAAU,SAAS,CAAA;AAAA,UACnF;AAEA,UAAA,IAAI;AACF,YAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,KAAA,CAAM,eAAe,UAAU,CAAA;AAGnE,YAAA,IAAI,CAAC,UAAU,MAAA,EAAQ;AACrB,cAAA,IAAA,CAAK,GAAA,EAAI;AAAA,YACX;AAEA,YAAA,OAAO,MAAA;AAAA,UACT,SAAS,CAAA,EAAG;AACV,YAAA,IAAA,CAAK,GAAA,EAAI;AACT,YAAA,MAAM,CAAA;AAAA,UACR;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAGD,IAAA,wBAAA,CAAyB,UAAA,EAAkD,gBAAgB,IAAI,CAAA;AAAA,EACjG;AAEA,EAAA,OAAO,UAAA;AACT;AAqBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,QAAQ,WAAW,CAAA,CAAE,IAAI,CAAC,CAAC,IAAA,EAAM,UAAU,CAAA,KAAM;AAC7D,IAAA,OAAO,wBAAA,CAAyB,UAAA,EAAY,EAAE,IAAA,EAAM,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
|
|
2
|
+
import { getActiveSpan, getRootSpan, spanToJSON, updateSpanName, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, getCurrentScope, escapeStringForRegex } from '@sentry/core';
|
|
3
|
+
|
|
4
|
+
function patternToRegex(pattern) {
|
|
5
|
+
const segments = pattern.split("/").map((segment) => {
|
|
6
|
+
if (segment.startsWith("$")) {
|
|
7
|
+
return "[^/]+";
|
|
8
|
+
}
|
|
9
|
+
return escapeStringForRegex(segment);
|
|
10
|
+
}).join("/");
|
|
11
|
+
return new RegExp(`^${segments}$`);
|
|
12
|
+
}
|
|
13
|
+
function matchUrlToRoutePattern(pathname, patterns) {
|
|
14
|
+
const normalizedPathname = pathname.length > 1 ? pathname.replace(/\/$/, "") : pathname;
|
|
15
|
+
for (const pattern of patterns) {
|
|
16
|
+
if (patternToRegex(pattern).test(normalizedPathname)) {
|
|
17
|
+
return pattern;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
function updateSpanWithRouteParametrization(method, pathname, patterns) {
|
|
23
|
+
const matchedPattern = matchUrlToRoutePattern(pathname, patterns);
|
|
24
|
+
if (!matchedPattern) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const activeSpan = getActiveSpan();
|
|
28
|
+
if (!activeSpan) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const rootSpan = getRootSpan(activeSpan);
|
|
32
|
+
const rootSpanData = spanToJSON(rootSpan).data;
|
|
33
|
+
if (rootSpanData?.[ATTR_HTTP_ROUTE]) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const transactionName = `${method} ${matchedPattern}`;
|
|
37
|
+
updateSpanName(rootSpan, transactionName);
|
|
38
|
+
rootSpan.setAttribute(ATTR_HTTP_ROUTE, matchedPattern);
|
|
39
|
+
rootSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, "route");
|
|
40
|
+
getCurrentScope().setTransactionName(transactionName);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { matchUrlToRoutePattern, updateSpanWithRouteParametrization };
|
|
44
|
+
//# sourceMappingURL=routeParametrization.js.map
|