@sentry/react-router 9.36.0 → 9.38.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 (35) hide show
  1. package/README.md +3 -5
  2. package/build/cjs/client/hydratedRouter.js.map +1 -1
  3. package/build/cjs/client/sdk.js.map +1 -1
  4. package/build/cjs/common/debug-build.js.map +1 -1
  5. package/build/cjs/server/createSentryHandleRequest.js.map +1 -1
  6. package/build/cjs/server/instrumentation/reactRouter.js.map +1 -1
  7. package/build/cjs/server/instrumentation/util.js.map +1 -1
  8. package/build/cjs/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
  9. package/build/cjs/server/integration/reactRouterServer.js.map +1 -1
  10. package/build/cjs/server/sdk.js.map +1 -1
  11. package/build/cjs/server/wrapSentryHandleRequest.js.map +1 -1
  12. package/build/cjs/server/wrapServerAction.js.map +1 -1
  13. package/build/cjs/server/wrapServerLoader.js.map +1 -1
  14. package/build/cjs/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  15. package/build/cjs/vite/makeCustomSentryVitePlugins.js.map +1 -1
  16. package/build/cjs/vite/makeEnableSourceMapsPlugin.js.map +1 -1
  17. package/build/cjs/vite/plugin.js.map +1 -1
  18. package/build/esm/client/hydratedRouter.js.map +1 -1
  19. package/build/esm/client/sdk.js.map +1 -1
  20. package/build/esm/common/debug-build.js.map +1 -1
  21. package/build/esm/package.json +1 -1
  22. package/build/esm/server/createSentryHandleRequest.js.map +1 -1
  23. package/build/esm/server/instrumentation/reactRouter.js.map +1 -1
  24. package/build/esm/server/instrumentation/util.js.map +1 -1
  25. package/build/esm/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
  26. package/build/esm/server/integration/reactRouterServer.js.map +1 -1
  27. package/build/esm/server/sdk.js.map +1 -1
  28. package/build/esm/server/wrapSentryHandleRequest.js.map +1 -1
  29. package/build/esm/server/wrapServerAction.js.map +1 -1
  30. package/build/esm/server/wrapServerLoader.js.map +1 -1
  31. package/build/esm/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  32. package/build/esm/vite/makeCustomSentryVitePlugins.js.map +1 -1
  33. package/build/esm/vite/makeEnableSourceMapsPlugin.js.map +1 -1
  34. package/build/esm/vite/plugin.js.map +1 -1
  35. package/package.json +6 -5
package/README.md CHANGED
@@ -4,16 +4,14 @@
4
4
  </a>
5
5
  </p>
6
6
 
7
- # Official Sentry SDK for React Router Framework (EXPERIMENTAL)
7
+ # Official Sentry SDK for React Router Framework (BETA)
8
8
 
9
9
  [![npm version](https://img.shields.io/npm/v/@sentry/react-router.svg)](https://www.npmjs.com/package/@sentry/react-router)
10
10
  [![npm dm](https://img.shields.io/npm/dm/@sentry/react-router.svg)](https://www.npmjs.com/package/@sentry/react-router)
11
11
  [![npm dt](https://img.shields.io/npm/dt/@sentry/react-router.svg)](https://www.npmjs.com/package/@sentry/react-router)
12
12
 
13
- > [!WARNING]
14
- > This SDK is considered ⚠️ **experimental and in an alpha state**. It may experience breaking changes. Please reach out
15
- > on [GitHub](https://github.com/getsentry/sentry-javascript/issues/) if you have any feedback or concerns. This
16
- > SDK is for [React Router (framework)](https://reactrouter.com/start/framework/installation). If you're using [React Router (library)](https://reactrouter.com/start/library/installation) see our
13
+ > This SDK is currently in beta. Beta features are still in progress and may have bugs. Please reach out on [GitHub](https://github.com/getsentry/sentry-javascript/issues/) if you have any feedback or concerns.
14
+ > This SDK is for [React Router (framework)](https://reactrouter.com/start/framework/installation). If you're using [React Router (library)](https://reactrouter.com/start/library/installation) see our
17
15
  > [React SDK here](https://docs.sentry.io/platforms/javascript/guides/react/features/react-router/v7/).
18
16
 
19
17
  ## Links
@@ -1 +1 @@
1
- {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n const pageloadName = pageloadSpan ? spanToJSON(pageloadSpan).description : undefined;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName) && // this event is for the currently active pageload\n normalizePathname(parameterizePageloadRoute) !== normalizePathname(pageloadName) // route is not parameterized yet\n ) {\n pageloadSpan?.updateName(parameterizePageloadRoute);\n pageloadSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n const navigationSpanName = navigationSpan ? spanToJSON(navigationSpan).description : undefined;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName && // we have an active pageload tx\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) && // this event is for the currently active navigation\n normalizePathname(parameterizedNavRoute) !== normalizePathname(navigationSpanName) // route is not parameterized yet\n ) {\n navigationSpan?.updateName(parameterizedNavRoute);\n navigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":["GLOBAL_OBJ","spanToJSON","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","DEBUG_BUILD","consoleSandbox","getClient","startBrowserTracingNavigationSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","getActiveSpan","getRootSpan"],"mappings":"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"}
1
+ {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n const pageloadName = pageloadSpan ? spanToJSON(pageloadSpan).description : undefined;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName) && // this event is for the currently active pageload\n normalizePathname(parameterizePageloadRoute) !== normalizePathname(pageloadName) // route is not parameterized yet\n ) {\n pageloadSpan?.updateName(parameterizePageloadRoute);\n pageloadSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n const navigationSpanName = navigationSpan ? spanToJSON(navigationSpan).description : undefined;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName && // we have an active pageload tx\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) && // this event is for the currently active navigation\n normalizePathname(parameterizedNavRoute) !== normalizePathname(navigationSpanName) // route is not parameterized yet\n ) {\n navigationSpan?.updateName(parameterizedNavRoute);\n navigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":["GLOBAL_OBJ","spanToJSON","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","DEBUG_BUILD","consoleSandbox","getClient","startBrowserTracingNavigationSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","getActiveSpan","getRootSpan"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sources":["../../../src/client/sdk.ts"],"sourcesContent":["import type { BrowserOptions } from '@sentry/browser';\nimport { init as browserInit } from '@sentry/browser';\nimport type { Client } from '@sentry/core';\nimport { applySdkMetadata, consoleSandbox, setTag } from '@sentry/core';\n\nconst BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\n/**\n * Initializes the client side of the React Router SDK.\n */\nexport function init(options: BrowserOptions): Client | undefined {\n // If BrowserTracing integration was passed to options, emit a warning\n if (options.integrations && Array.isArray(options.integrations)) {\n const hasBrowserTracing = options.integrations.some(\n integration => integration.name === BROWSER_TRACING_INTEGRATION_ID,\n );\n\n if (hasBrowserTracing) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n 'browserTracingIntegration is not fully compatible with @sentry/react-router. Please use reactRouterTracingIntegration instead.',\n );\n });\n }\n }\n\n applySdkMetadata(options, 'react-router', ['react-router', 'browser']);\n\n const client = browserInit(options);\n\n setTag('runtime', 'browser');\n\n return client;\n}\n"],"names":["consoleSandbox","applySdkMetadata","browserInit","setTag"],"mappings":";;;;;AAKA,MAAM,8BAAA,GAAiC,gBAAgB;;AAEvD;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAsC;AAClE;AACA,EAAE,IAAI,OAAO,CAAC,gBAAgB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;AACnE,IAAI,MAAM,iBAAkB,GAAE,OAAO,CAAC,YAAY,CAAC,IAAI;AACvD,MAAM,eAAe,WAAW,CAAC,IAAA,KAAS,8BAA8B;AACxE,KAAK;;AAEL,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAMA,mBAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,IAAI;AACpB,UAAU,gIAAgI;AAC1I,SAAS;AACT,OAAO,CAAC;AACR;AACA;;AAEA,EAAEC,qBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;;AAExE,EAAE,MAAM,MAAO,GAAEC,YAAW,CAAC,OAAO,CAAC;;AAErC,EAAEC,WAAM,CAAC,SAAS,EAAE,SAAS,CAAC;;AAE9B,EAAE,OAAO,MAAM;AACf;;;;"}
1
+ {"version":3,"file":"sdk.js","sources":["../../../src/client/sdk.ts"],"sourcesContent":["import type { BrowserOptions } from '@sentry/browser';\nimport { init as browserInit } from '@sentry/browser';\nimport type { Client } from '@sentry/core';\nimport { applySdkMetadata, consoleSandbox, setTag } from '@sentry/core';\n\nconst BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\n/**\n * Initializes the client side of the React Router SDK.\n */\nexport function init(options: BrowserOptions): Client | undefined {\n // If BrowserTracing integration was passed to options, emit a warning\n if (options.integrations && Array.isArray(options.integrations)) {\n const hasBrowserTracing = options.integrations.some(\n integration => integration.name === BROWSER_TRACING_INTEGRATION_ID,\n );\n\n if (hasBrowserTracing) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n 'browserTracingIntegration is not fully compatible with @sentry/react-router. Please use reactRouterTracingIntegration instead.',\n );\n });\n }\n }\n\n applySdkMetadata(options, 'react-router', ['react-router', 'browser']);\n\n const client = browserInit(options);\n\n setTag('runtime', 'browser');\n\n return client;\n}\n"],"names":["consoleSandbox","applySdkMetadata","browserInit","setTag"],"mappings":";;;;;AAKA,MAAM,8BAAA,GAAiC,gBAAgB;;AAEvD;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAsC;AAClE;AACA,EAAE,IAAI,OAAO,CAAC,gBAAgB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;AACnE,IAAI,MAAM,iBAAA,GAAoB,OAAO,CAAC,YAAY,CAAC,IAAI;AACvD,MAAM,eAAe,WAAW,CAAC,IAAA,KAAS,8BAA8B;AACxE,KAAK;;AAEL,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAMA,mBAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,IAAI;AACpB,UAAU,gIAAgI;AAC1I,SAAS;AACT,OAAO,CAAC;AACR;AACA;;AAEA,EAAEC,qBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;;AAExE,EAAE,MAAM,MAAA,GAASC,YAAW,CAAC,OAAO,CAAC;;AAErC,EAAEC,WAAM,CAAC,SAAS,EAAE,SAAS,CAAC;;AAE9B,EAAE,OAAO,MAAM;AACf;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"debug-build.js","sources":["../../../src/common/debug-build.ts"],"sourcesContent":["declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n"],"names":[],"mappings":";;AAEA;AACA;AACA;AACA;AACA;AACO,MAAM,WAAY,IAAiB,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;;;;"}
1
+ {"version":3,"file":"debug-build.js","sources":["../../../src/common/debug-build.ts"],"sourcesContent":["declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n"],"names":[],"mappings":";;AAEA;AACA;AACA;AACA;AACA;AACO,MAAM,WAAA,IAAc,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"createSentryHandleRequest.js","sources":["../../../src/server/createSentryHandleRequest.tsx"],"sourcesContent":["import type { createReadableStreamFromReadable } from '@react-router/node';\nimport type { ReactNode } from 'react';\nimport React from 'react';\nimport type { AppLoadContext, EntryContext, ServerRouter } from 'react-router';\nimport { PassThrough } from 'stream';\nimport { getMetaTagTransformer, wrapSentryHandleRequest } from './wrapSentryHandleRequest';\n\ntype RenderToPipeableStreamOptions = {\n [key: string]: unknown;\n onShellReady?: () => void;\n onAllReady?: () => void;\n onShellError?: (error: unknown) => void;\n onError?: (error: unknown) => void;\n};\n\ntype RenderToPipeableStreamResult = {\n pipe: (destination: NodeJS.WritableStream) => void;\n abort: () => void;\n};\n\ntype RenderToPipeableStreamFunction = (\n node: ReactNode,\n options: RenderToPipeableStreamOptions,\n) => RenderToPipeableStreamResult;\n\nexport interface SentryHandleRequestOptions {\n /**\n * Timeout in milliseconds after which the rendering stream will be aborted\n * @default 10000\n */\n streamTimeout?: number;\n\n /**\n * React's renderToPipeableStream function from 'react-dom/server'\n */\n renderToPipeableStream: RenderToPipeableStreamFunction;\n\n /**\n * The <ServerRouter /> component from '@react-router/server'\n */\n ServerRouter: typeof ServerRouter;\n\n /**\n * createReadableStreamFromReadable from '@react-router/node'\n */\n createReadableStreamFromReadable: typeof createReadableStreamFromReadable;\n\n /**\n * Regular expression to identify bot user agents\n * @default /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i\n */\n botRegex?: RegExp;\n}\n\n/**\n * A complete Sentry-instrumented handleRequest implementation that handles both\n * route parametrization and trace meta tag injection.\n *\n * @param options Configuration options\n * @returns A Sentry-instrumented handleRequest function\n */\nexport function createSentryHandleRequest(\n options: SentryHandleRequestOptions,\n): (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown> {\n const {\n streamTimeout = 10000,\n renderToPipeableStream,\n ServerRouter,\n createReadableStreamFromReadable,\n botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i,\n } = options;\n\n const handleRequest = function handleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n _loadContext: AppLoadContext,\n ): Promise<Response> {\n return new Promise((resolve, reject) => {\n let shellRendered = false;\n const userAgent = request.headers.get('user-agent');\n\n // Determine if we should use onAllReady or onShellReady\n const isBot = typeof userAgent === 'string' && botRegex.test(userAgent);\n const isSpaMode = !!(routerContext as { isSpaMode?: boolean }).isSpaMode;\n\n const readyOption = isBot || isSpaMode ? 'onAllReady' : 'onShellReady';\n\n const { pipe, abort } = renderToPipeableStream(<ServerRouter context={routerContext} url={request.url} />, {\n [readyOption]() {\n shellRendered = true;\n const body = new PassThrough();\n\n const stream = createReadableStreamFromReadable(body);\n\n responseHeaders.set('Content-Type', 'text/html');\n\n resolve(\n new Response(stream, {\n headers: responseHeaders,\n status: responseStatusCode,\n }),\n );\n\n // this injects trace data to the HTML head\n pipe(getMetaTagTransformer(body));\n },\n onShellError(error: unknown) {\n reject(error);\n },\n onError(error: unknown) {\n // eslint-disable-next-line no-param-reassign\n responseStatusCode = 500;\n // Log streaming rendering errors from inside the shell. Don't log\n // errors encountered during initial shell rendering since they'll\n // reject and get logged in handleDocumentRequest.\n if (shellRendered) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n },\n });\n\n // Abort the rendering stream after the `streamTimeout`\n setTimeout(abort, streamTimeout);\n });\n };\n\n // Wrap the handle request function for request parametrization\n return wrapSentryHandleRequest(handleRequest);\n}\n"],"names":["React","PassThrough","stream","getMetaTagTransformer","wrapSentryHandleRequest"],"mappings":";;;;;;AAsDA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,yBAAyB;AACzC,EAAE,OAAO;AACT;;AAMA,CAAsB;AACtB,EAAE,MAAM;AACR,IAAI,aAAA,GAAgB,KAAK;AACzB,IAAI,sBAAsB;AAC1B,IAAI,YAAY;AAChB,IAAI,gCAAgC;AACpC,IAAI,QAAA,GAAW,oFAAoF;AACnG,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,aAAA,GAAgB,SAAS,aAAa;AAC9C,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,YAAY;AAChB,IAAuB;AACvB,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC5C,MAAM,IAAI,aAAc,GAAE,KAAK;AAC/B,MAAM,MAAM,SAAU,GAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;;AAEzD;AACA,MAAM,MAAM,KAAA,GAAQ,OAAO,SAAU,KAAI,QAAS,IAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;AAC7E,MAAM,MAAM,YAAY,CAAC,CAAC,CAAC,aAAA,GAA0C,SAAS;;AAE9E,MAAM,MAAM,cAAc,KAAA,IAAS,SAAU,GAAE,YAAa,GAAE,cAAc;;AAE5E,MAAM,MAAM,EAAE,IAAI,EAAE,OAAQ,GAAE,sBAAsB,CAACA,aAAC,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,OAAO,EAAC,aAAc,EAAE,GAAG,EAAC,OAAQ,CAAC,GAAG,EAAE,EAAE,EAAE;AACjH,QAAQ,CAAC,WAAW,CAAC,GAAG;AACxB,UAAU,aAAA,GAAgB,IAAI;AAC9B,UAAU,MAAM,IAAK,GAAE,IAAIC,kBAAW,EAAE;;AAExC,UAAU,MAAMC,QAAO,GAAE,gCAAgC,CAAC,IAAI,CAAC;;AAE/D,UAAU,eAAe,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC;;AAE1D,UAAU,OAAO;AACjB,YAAY,IAAI,QAAQ,CAACA,QAAM,EAAE;AACjC,cAAc,OAAO,EAAE,eAAe;AACtC,cAAc,MAAM,EAAE,kBAAkB;AACxC,aAAa,CAAC;AACd,WAAW;;AAEX;AACA,UAAU,IAAI,CAACC,6CAAqB,CAAC,IAAI,CAAC,CAAC;AAC3C,SAAS;AACT,QAAQ,YAAY,CAAC,KAAK,EAAW;AACrC,UAAU,MAAM,CAAC,KAAK,CAAC;AACvB,SAAS;AACT,QAAQ,OAAO,CAAC,KAAK,EAAW;AAChC;AACA,UAAU,kBAAA,GAAqB,GAAG;AAClC;AACA;AACA;AACA,UAAU,IAAI,aAAa,EAAE;AAC7B;AACA,YAAY,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAChC;AACA,SAAS;AACT,OAAO,CAAC;;AAER;AACA,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC;AACtC,KAAK,CAAC;AACN,GAAG;;AAEH;AACA,EAAE,OAAOC,+CAAuB,CAAC,aAAa,CAAC;AAC/C;;;;"}
1
+ {"version":3,"file":"createSentryHandleRequest.js","sources":["../../../src/server/createSentryHandleRequest.tsx"],"sourcesContent":["import type { createReadableStreamFromReadable } from '@react-router/node';\nimport type { ReactNode } from 'react';\nimport React from 'react';\nimport type { AppLoadContext, EntryContext, ServerRouter } from 'react-router';\nimport { PassThrough } from 'stream';\nimport { getMetaTagTransformer, wrapSentryHandleRequest } from './wrapSentryHandleRequest';\n\ntype RenderToPipeableStreamOptions = {\n [key: string]: unknown;\n onShellReady?: () => void;\n onAllReady?: () => void;\n onShellError?: (error: unknown) => void;\n onError?: (error: unknown) => void;\n};\n\ntype RenderToPipeableStreamResult = {\n pipe: (destination: NodeJS.WritableStream) => void;\n abort: () => void;\n};\n\ntype RenderToPipeableStreamFunction = (\n node: ReactNode,\n options: RenderToPipeableStreamOptions,\n) => RenderToPipeableStreamResult;\n\nexport interface SentryHandleRequestOptions {\n /**\n * Timeout in milliseconds after which the rendering stream will be aborted\n * @default 10000\n */\n streamTimeout?: number;\n\n /**\n * React's renderToPipeableStream function from 'react-dom/server'\n */\n renderToPipeableStream: RenderToPipeableStreamFunction;\n\n /**\n * The <ServerRouter /> component from '@react-router/server'\n */\n ServerRouter: typeof ServerRouter;\n\n /**\n * createReadableStreamFromReadable from '@react-router/node'\n */\n createReadableStreamFromReadable: typeof createReadableStreamFromReadable;\n\n /**\n * Regular expression to identify bot user agents\n * @default /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i\n */\n botRegex?: RegExp;\n}\n\n/**\n * A complete Sentry-instrumented handleRequest implementation that handles both\n * route parametrization and trace meta tag injection.\n *\n * @param options Configuration options\n * @returns A Sentry-instrumented handleRequest function\n */\nexport function createSentryHandleRequest(\n options: SentryHandleRequestOptions,\n): (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown> {\n const {\n streamTimeout = 10000,\n renderToPipeableStream,\n ServerRouter,\n createReadableStreamFromReadable,\n botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i,\n } = options;\n\n const handleRequest = function handleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n _loadContext: AppLoadContext,\n ): Promise<Response> {\n return new Promise((resolve, reject) => {\n let shellRendered = false;\n const userAgent = request.headers.get('user-agent');\n\n // Determine if we should use onAllReady or onShellReady\n const isBot = typeof userAgent === 'string' && botRegex.test(userAgent);\n const isSpaMode = !!(routerContext as { isSpaMode?: boolean }).isSpaMode;\n\n const readyOption = isBot || isSpaMode ? 'onAllReady' : 'onShellReady';\n\n const { pipe, abort } = renderToPipeableStream(<ServerRouter context={routerContext} url={request.url} />, {\n [readyOption]() {\n shellRendered = true;\n const body = new PassThrough();\n\n const stream = createReadableStreamFromReadable(body);\n\n responseHeaders.set('Content-Type', 'text/html');\n\n resolve(\n new Response(stream, {\n headers: responseHeaders,\n status: responseStatusCode,\n }),\n );\n\n // this injects trace data to the HTML head\n pipe(getMetaTagTransformer(body));\n },\n onShellError(error: unknown) {\n reject(error);\n },\n onError(error: unknown) {\n // eslint-disable-next-line no-param-reassign\n responseStatusCode = 500;\n // Log streaming rendering errors from inside the shell. Don't log\n // errors encountered during initial shell rendering since they'll\n // reject and get logged in handleDocumentRequest.\n if (shellRendered) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n },\n });\n\n // Abort the rendering stream after the `streamTimeout`\n setTimeout(abort, streamTimeout);\n });\n };\n\n // Wrap the handle request function for request parametrization\n return wrapSentryHandleRequest(handleRequest);\n}\n"],"names":["React","PassThrough","stream","getMetaTagTransformer","wrapSentryHandleRequest"],"mappings":";;;;;;AAsDA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,yBAAyB;AACzC,EAAE,OAAO;AACT;;AAMA,CAAsB;AACtB,EAAE,MAAM;AACR,IAAI,aAAA,GAAgB,KAAK;AACzB,IAAI,sBAAsB;AAC1B,IAAI,YAAY;AAChB,IAAI,gCAAgC;AACpC,IAAI,QAAA,GAAW,oFAAoF;AACnG,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,aAAA,GAAgB,SAAS,aAAa;AAC9C,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,YAAY;AAChB,IAAuB;AACvB,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC5C,MAAM,IAAI,aAAA,GAAgB,KAAK;AAC/B,MAAM,MAAM,SAAA,GAAY,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;;AAEzD;AACA,MAAM,MAAM,KAAA,GAAQ,OAAO,SAAA,KAAc,QAAA,IAAY,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;AAC7E,MAAM,MAAM,YAAY,CAAC,CAAC,CAAC,aAAA,GAA0C,SAAS;;AAE9E,MAAM,MAAM,cAAc,KAAA,IAAS,SAAA,GAAY,YAAA,GAAe,cAAc;;AAE5E,MAAM,MAAM,EAAE,IAAI,EAAE,OAAM,GAAI,sBAAsB,CAACA,aAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,OAAO,EAAC,aAAc,EAAE,GAAG,EAAC,OAAQ,CAAC,GAAG,EAAA,EAAI,EAAE;AACjH,QAAQ,CAAC,WAAW,CAAC,GAAG;AACxB,UAAU,aAAA,GAAgB,IAAI;AAC9B,UAAU,MAAM,IAAA,GAAO,IAAIC,kBAAW,EAAE;;AAExC,UAAU,MAAMC,QAAA,GAAS,gCAAgC,CAAC,IAAI,CAAC;;AAE/D,UAAU,eAAe,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC;;AAE1D,UAAU,OAAO;AACjB,YAAY,IAAI,QAAQ,CAACA,QAAM,EAAE;AACjC,cAAc,OAAO,EAAE,eAAe;AACtC,cAAc,MAAM,EAAE,kBAAkB;AACxC,aAAa,CAAC;AACd,WAAW;;AAEX;AACA,UAAU,IAAI,CAACC,6CAAqB,CAAC,IAAI,CAAC,CAAC;AAC3C,SAAS;AACT,QAAQ,YAAY,CAAC,KAAK,EAAW;AACrC,UAAU,MAAM,CAAC,KAAK,CAAC;AACvB,SAAS;AACT,QAAQ,OAAO,CAAC,KAAK,EAAW;AAChC;AACA,UAAU,kBAAA,GAAqB,GAAG;AAClC;AACA;AACA;AACA,UAAU,IAAI,aAAa,EAAE;AAC7B;AACA,YAAY,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAChC;AACA,SAAS;AACT,OAAO,CAAC;;AAER;AACA,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC;AACtC,KAAK,CAAC;AACN,GAAG;;AAEH;AACA,EAAE,OAAOC,+CAAuB,CAAC,aAAa,CAAC;AAC/C;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport {\n getActiveSpan,\n getRootSpan,\n logger,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest, SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch (error) {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && logger.debug('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // Set the source and overwrite attributes on the root span to ensure the transaction name\n // is derived from the raw URL pathname rather than any parameterized route that may be set later\n // TODO: try to set derived parameterized route from build here (args[0])\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${request.method} ${url.pathname}`,\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","isDataRequest","getActiveSpan","getRootSpan","DEBUG_BUILD","logger","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","startSpan","getSpanName","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","getOpName"],"mappings":"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"}
1
+ {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport {\n getActiveSpan,\n getRootSpan,\n logger,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest, SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch (error) {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && logger.debug('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // Set the source and overwrite attributes on the root span to ensure the transaction name\n // is derived from the raw URL pathname rather than any parameterized route that may be set later\n // TODO: try to set derived parameterized route from build here (args[0])\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${request.method} ${url.pathname}`,\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","isDataRequest","getActiveSpan","getRootSpan","DEBUG_BUILD","logger","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","startSpan","getSpanName","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","getOpName"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sources":["../../../../src/server/instrumentation/util.ts"],"sourcesContent":["/**\n * Gets the op name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getOpName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'function.react-router.loader'\n : isActionRequest(pathName, requestMethod)\n ? 'function.react-router.action'\n : 'function.react-router';\n}\n\n/**\n * Gets the span name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getSpanName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'Executing Server Loader'\n : isActionRequest(pathName, requestMethod)\n ? 'Executing Server Action'\n : 'Unknown Data Request';\n}\n\n/**\n * Checks if the request is a server loader request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isLoaderRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'GET';\n}\n\n/**\n * Checks if the request is a server action request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isActionRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'POST';\n}\n\n/**\n * Checks if the request is a react-router data request\n * @param pathname The URL pathname to check\n */\nexport function isDataRequest(pathname: string): boolean {\n return pathname.endsWith('.data');\n}\n\nexport const SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE = 'sentry.overwrite-route';\n"],"names":[],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC3E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,uBAAuB;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC7E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,sBAAsB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,KAAK;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,MAAM;AAC5D;;AAEA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,QAAQ,EAAmB;AACzD,EAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AACnC;;AAEO,MAAM,mCAAoC,GAAE;;;;;;;;;"}
1
+ {"version":3,"file":"util.js","sources":["../../../../src/server/instrumentation/util.ts"],"sourcesContent":["/**\n * Gets the op name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getOpName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'function.react-router.loader'\n : isActionRequest(pathName, requestMethod)\n ? 'function.react-router.action'\n : 'function.react-router';\n}\n\n/**\n * Gets the span name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getSpanName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'Executing Server Loader'\n : isActionRequest(pathName, requestMethod)\n ? 'Executing Server Action'\n : 'Unknown Data Request';\n}\n\n/**\n * Checks if the request is a server loader request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isLoaderRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'GET';\n}\n\n/**\n * Checks if the request is a server action request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isActionRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'POST';\n}\n\n/**\n * Checks if the request is a react-router data request\n * @param pathname The URL pathname to check\n */\nexport function isDataRequest(pathname: string): boolean {\n return pathname.endsWith('.data');\n}\n\nexport const SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE = 'sentry.overwrite-route';\n"],"names":[],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC3E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,uBAAuB;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC7E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,sBAAsB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,KAAK;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,MAAM;AAC5D;;AAEA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,QAAQ,EAAmB;AACzD,EAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AACnC;;AAEO,MAAM,mCAAA,GAAsC;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint, defineIntegration, logger } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node';\n\n/**\n * Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/\n *\n */\n\nfunction _lowQualityTransactionsFilterIntegration(options: NodeOptions): {\n name: string;\n processEvent: (event: Event, hint: EventHint, client: Client) => Event | null;\n} {\n const matchedRegexes = [/GET \\/node_modules\\//, /GET \\/favicon\\.ico/, /GET \\/@id\\//, /GET \\/__manifest\\?/];\n\n return {\n name: 'LowQualityTransactionsFilter',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event | null {\n if (event.type !== 'transaction' || !event.transaction) {\n return event;\n }\n\n const transaction = event.transaction;\n\n if (matchedRegexes.some(regex => transaction.match(regex))) {\n options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);\n return null;\n }\n\n return event;\n },\n };\n}\n\nexport const lowQualityTransactionsFilterIntegration = defineIntegration((options: NodeOptions) =>\n _lowQualityTransactionsFilterIntegration(options),\n);\n"],"names":["logger","defineIntegration"],"mappings":";;;;AAGA;AACA;AACA;AACA;;AAEA,SAAS,wCAAwC,CAAC,OAAO;;AAGzD,CAAE;AACF,EAAE,MAAM,cAAe,GAAE,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,aAAa,EAAE,oBAAoB,CAAC;;AAE5G,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,8BAA8B;;AAExC,IAAI,YAAY,CAAC,KAAK,EAAS,KAAK,EAAa,OAAO,EAAwB;AAChF,MAAM,IAAI,KAAK,CAAC,IAAK,KAAI,aAAc,IAAG,CAAC,KAAK,CAAC,WAAW,EAAE;AAC9D,QAAQ,OAAO,KAAK;AACpB;;AAEA,MAAM,MAAM,WAAA,GAAc,KAAK,CAAC,WAAW;;AAE3C,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,KAAA,IAAS,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;AAClE,QAAQ,OAAO,CAAC,KAAM,IAAGA,WAAM,CAAC,GAAG,CAAC,kDAAkD,EAAE,KAAK,CAAC,WAAW,CAAC;AAC1G,QAAQ,OAAO,IAAI;AACnB;;AAEA,MAAM,OAAO,KAAK;AAClB,KAAK;AACL,GAAG;AACH;;MAEa,uCAAwC,GAAEC,sBAAiB,CAAC,CAAC,OAAO;AACjF,EAAE,wCAAwC,CAAC,OAAO,CAAC;AACnD;;;;"}
1
+ {"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint, defineIntegration, logger } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node';\n\n/**\n * Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/\n *\n */\n\nfunction _lowQualityTransactionsFilterIntegration(options: NodeOptions): {\n name: string;\n processEvent: (event: Event, hint: EventHint, client: Client) => Event | null;\n} {\n const matchedRegexes = [/GET \\/node_modules\\//, /GET \\/favicon\\.ico/, /GET \\/@id\\//, /GET \\/__manifest\\?/];\n\n return {\n name: 'LowQualityTransactionsFilter',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event | null {\n if (event.type !== 'transaction' || !event.transaction) {\n return event;\n }\n\n const transaction = event.transaction;\n\n if (matchedRegexes.some(regex => transaction.match(regex))) {\n options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);\n return null;\n }\n\n return event;\n },\n };\n}\n\nexport const lowQualityTransactionsFilterIntegration = defineIntegration((options: NodeOptions) =>\n _lowQualityTransactionsFilterIntegration(options),\n);\n"],"names":["logger","defineIntegration"],"mappings":";;;;AAGA;AACA;AACA;AACA;;AAEA,SAAS,wCAAwC,CAAC,OAAO;;AAGzD,CAAE;AACF,EAAE,MAAM,cAAA,GAAiB,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,aAAa,EAAE,oBAAoB,CAAC;;AAE5G,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,8BAA8B;;AAExC,IAAI,YAAY,CAAC,KAAK,EAAS,KAAK,EAAa,OAAO,EAAwB;AAChF,MAAM,IAAI,KAAK,CAAC,IAAA,KAAS,aAAA,IAAiB,CAAC,KAAK,CAAC,WAAW,EAAE;AAC9D,QAAQ,OAAO,KAAK;AACpB;;AAEA,MAAM,MAAM,WAAA,GAAc,KAAK,CAAC,WAAW;;AAE3C,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,KAAA,IAAS,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;AAClE,QAAQ,OAAO,CAAC,KAAA,IAASA,WAAM,CAAC,GAAG,CAAC,kDAAkD,EAAE,KAAK,CAAC,WAAW,CAAC;AAC1G,QAAQ,OAAO,IAAI;AACnB;;AAEA,MAAM,OAAO,KAAK;AAClB,KAAK;AACL,GAAG;AACH;;MAEa,uCAAA,GAA0CC,sBAAiB,CAAC,CAAC,OAAO;AACjF,EAAE,wCAAwC,CAAC,OAAO,CAAC;AACnD;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactRouterServer.js","sources":["../../../../src/server/integration/reactRouterServer.ts"],"sourcesContent":["import { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node';\nimport { ReactRouterInstrumentation } from '../instrumentation/reactRouter';\n\nconst INTEGRATION_NAME = 'ReactRouterServer';\n\nconst instrumentReactRouter = generateInstrumentOnce('React-Router-Server', () => {\n return new ReactRouterInstrumentation();\n});\n\nexport const instrumentReactRouterServer = Object.assign(\n (): void => {\n instrumentReactRouter();\n },\n { id: INTEGRATION_NAME },\n);\n\n/**\n * Integration capturing tracing data for React Router server functions.\n */\nexport const reactRouterServerIntegration = defineIntegration(() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentReactRouterServer();\n },\n };\n});\n"],"names":["generateInstrumentOnce","ReactRouterInstrumentation","defineIntegration"],"mappings":";;;;;;AAIA,MAAM,gBAAA,GAAmB,mBAAmB;;AAE5C,MAAM,qBAAA,GAAwBA,2BAAsB,CAAC,qBAAqB,EAAE,MAAM;AAClF,EAAE,OAAO,IAAIC,sCAA0B,EAAE;AACzC,CAAC,CAAC;;AAEW,MAAA,2BAAA,GAA8B,MAAM,CAAC,MAAM;AACxD,EAAE,MAAY;AACd,IAAI,qBAAqB,EAAE;AAC3B,GAAG;AACH,EAAE,EAAE,EAAE,EAAE,gBAAA,EAAkB;AAC1B;;AAEA;AACA;AACA;MACa,4BAA6B,GAAEC,sBAAiB,CAAC,MAAM;AACpE,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,2BAA2B,EAAE;AACnC,KAAK;AACL,GAAG;AACH,CAAC;;;;;"}
1
+ {"version":3,"file":"reactRouterServer.js","sources":["../../../../src/server/integration/reactRouterServer.ts"],"sourcesContent":["import { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node';\nimport { ReactRouterInstrumentation } from '../instrumentation/reactRouter';\n\nconst INTEGRATION_NAME = 'ReactRouterServer';\n\nconst instrumentReactRouter = generateInstrumentOnce('React-Router-Server', () => {\n return new ReactRouterInstrumentation();\n});\n\nexport const instrumentReactRouterServer = Object.assign(\n (): void => {\n instrumentReactRouter();\n },\n { id: INTEGRATION_NAME },\n);\n\n/**\n * Integration capturing tracing data for React Router server functions.\n */\nexport const reactRouterServerIntegration = defineIntegration(() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentReactRouterServer();\n },\n };\n});\n"],"names":["generateInstrumentOnce","ReactRouterInstrumentation","defineIntegration"],"mappings":";;;;;;AAIA,MAAM,gBAAA,GAAmB,mBAAmB;;AAE5C,MAAM,qBAAA,GAAwBA,2BAAsB,CAAC,qBAAqB,EAAE,MAAM;AAClF,EAAE,OAAO,IAAIC,sCAA0B,EAAE;AACzC,CAAC,CAAC;;AAEK,MAAM,2BAAA,GAA8B,MAAM,CAAC,MAAM;AACxD,EAAE,MAAY;AACd,IAAI,qBAAqB,EAAE;AAC3B,GAAG;AACH,EAAE,EAAE,EAAE,EAAE,gBAAA,EAAkB;AAC1B;;AAEA;AACA;AACA;MACa,4BAAA,GAA+BC,sBAAiB,CAAC,MAAM;AACpE,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,2BAA2B,EAAE;AACnC,KAAK;AACL,GAAG;AACH,CAAC;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type { EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, getGlobalScope, logger, setTag } from '@sentry/core';\nimport type { NodeClient, NodeOptions } from '@sentry/node';\nimport { getDefaultIntegrations as getNodeDefaultIntegrations, init as initNodeSdk, NODE_VERSION } from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\nimport { lowQualityTransactionsFilterIntegration } from './integration/lowQualityTransactionsFilterIntegration';\nimport { reactRouterServerIntegration } from './integration/reactRouterServer';\n\n/**\n * Returns the default integrations for the React Router SDK.\n * @param options The options for the SDK.\n */\nexport function getDefaultReactRouterServerIntegrations(options: NodeOptions): Integration[] {\n const integrations = [...getNodeDefaultIntegrations(options), lowQualityTransactionsFilterIntegration(options)];\n\n if (\n (NODE_VERSION.major === 20 && NODE_VERSION.minor < 19) || // https://nodejs.org/en/blog/release/v20.19.0\n (NODE_VERSION.major === 22 && NODE_VERSION.minor < 12) // https://nodejs.org/en/blog/release/v22.12.0\n ) {\n integrations.push(reactRouterServerIntegration());\n }\n\n return integrations;\n}\n\n/**\n * Initializes the server side of the React Router SDK\n */\nexport function init(options: NodeOptions): NodeClient | undefined {\n const opts: NodeOptions = {\n ...options,\n defaultIntegrations: getDefaultReactRouterServerIntegrations(options),\n };\n\n DEBUG_BUILD && logger.log('Initializing SDK...');\n\n applySdkMetadata(opts, 'react-router', ['react-router', 'node']);\n\n const client = initNodeSdk(opts);\n\n setTag('runtime', 'node');\n\n // Overwrite the transaction name for instrumented data loaders because the trace data gets overwritten at a later point.\n // We only update the tx in case SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE got set in our instrumentation before.\n getGlobalScope().addEventProcessor(\n Object.assign(\n (event => {\n const overwrite = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n if (\n event.type === 'transaction' &&\n (event.transaction === 'GET *' || event.transaction === 'POST *') &&\n event.contexts?.trace?.data?.[ATTR_HTTP_ROUTE] === '*' &&\n overwrite\n ) {\n event.transaction = overwrite;\n event.contexts.trace.data[ATTR_HTTP_ROUTE] = 'url';\n }\n\n // always yeet this attribute into the void, as this should not reach the server\n delete event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n\n return event;\n }) satisfies EventProcessor,\n { id: 'ReactRouterTransactionEnhancer' },\n ),\n );\n\n DEBUG_BUILD && logger.log('SDK successfully initialized');\n\n return client;\n}\n"],"names":["getNodeDefaultIntegrations","lowQualityTransactionsFilterIntegration","NODE_VERSION","reactRouterServerIntegration","DEBUG_BUILD","logger","applySdkMetadata","initNodeSdk","setTag","getGlobalScope","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","ATTR_HTTP_ROUTE"],"mappings":";;;;;;;;;;AAUA;AACA;AACA;AACA;AACO,SAAS,uCAAuC,CAAC,OAAO,EAA8B;AAC7F,EAAE,MAAM,YAAA,GAAe,CAAC,GAAGA,2BAA0B,CAAC,OAAO,CAAC,EAAEC,+EAAuC,CAAC,OAAO,CAAC,CAAC;;AAEjH,EAAE;AACF,IAAI,CAACC,iBAAY,CAAC,KAAA,KAAU,EAAA,IAAMA,iBAAY,CAAC,KAAA,GAAQ,EAAE;AACzD,KAAKA,iBAAY,CAAC,KAAM,KAAI,EAAG,IAAGA,iBAAY,CAAC,KAAM,GAAE,EAAE,CAAA;AACzD,IAAI;AACJ,IAAI,YAAY,CAAC,IAAI,CAACC,8CAA4B,EAAE,CAAC;AACrD;;AAEA,EAAE,OAAO,YAAY;AACrB;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAuC;AACnE,EAAE,MAAM,IAAI,GAAgB;AAC5B,IAAI,GAAG,OAAO;AACd,IAAI,mBAAmB,EAAE,uCAAuC,CAAC,OAAO,CAAC;AACzE,GAAG;;AAEH,EAAEC,0BAAeC,WAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC;;AAElD,EAAEC,qBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;;AAElE,EAAE,MAAM,MAAO,GAAEC,SAAW,CAAC,IAAI,CAAC;;AAElC,EAAEC,WAAM,CAAC,SAAS,EAAE,MAAM,CAAC;;AAE3B;AACA;AACA,EAAEC,mBAAc,EAAE,CAAC,iBAAiB;AACpC,IAAI,MAAM,CAAC,MAAM;AACjB,OAAO,SAAS;AAChB,QAAQ,MAAM,SAAA,GAAY,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAGC,wCAAmC,CAAC;AAC5F,QAAQ;AACR,UAAU,KAAK,CAAC,IAAK,KAAI,aAAc;AACvC,WAAW,KAAK,CAAC,WAAA,KAAgB,OAAA,IAAW,KAAK,CAAC,WAAA,KAAgB,QAAQ,CAAE;AAC5E,UAAU,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAGC,mCAAe,CAAE,KAAI,GAAI;AACjE,UAAU;AACV,UAAU;AACV,UAAU,KAAK,CAAC,WAAY,GAAE,SAAS;AACvC,UAAU,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAACA,mCAAe,CAAE,GAAE,KAAK;AAC5D;;AAEA;AACA,QAAQ,OAAO,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAGD,wCAAmC,CAAC;;AAEjF,QAAQ,OAAO,KAAK;AACpB,OAAO;AACP,MAAM,EAAE,EAAE,EAAE,gCAAA,EAAkC;AAC9C,KAAK;AACL,GAAG;;AAEH,EAAEN,0BAAeC,WAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC;;AAE3D,EAAE,OAAO,MAAM;AACf;;;;;"}
1
+ {"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type { EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, getGlobalScope, logger, setTag } from '@sentry/core';\nimport type { NodeClient, NodeOptions } from '@sentry/node';\nimport { getDefaultIntegrations as getNodeDefaultIntegrations, init as initNodeSdk, NODE_VERSION } from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\nimport { lowQualityTransactionsFilterIntegration } from './integration/lowQualityTransactionsFilterIntegration';\nimport { reactRouterServerIntegration } from './integration/reactRouterServer';\n\n/**\n * Returns the default integrations for the React Router SDK.\n * @param options The options for the SDK.\n */\nexport function getDefaultReactRouterServerIntegrations(options: NodeOptions): Integration[] {\n const integrations = [...getNodeDefaultIntegrations(options), lowQualityTransactionsFilterIntegration(options)];\n\n if (\n (NODE_VERSION.major === 20 && NODE_VERSION.minor < 19) || // https://nodejs.org/en/blog/release/v20.19.0\n (NODE_VERSION.major === 22 && NODE_VERSION.minor < 12) // https://nodejs.org/en/blog/release/v22.12.0\n ) {\n integrations.push(reactRouterServerIntegration());\n }\n\n return integrations;\n}\n\n/**\n * Initializes the server side of the React Router SDK\n */\nexport function init(options: NodeOptions): NodeClient | undefined {\n const opts: NodeOptions = {\n ...options,\n defaultIntegrations: getDefaultReactRouterServerIntegrations(options),\n };\n\n DEBUG_BUILD && logger.log('Initializing SDK...');\n\n applySdkMetadata(opts, 'react-router', ['react-router', 'node']);\n\n const client = initNodeSdk(opts);\n\n setTag('runtime', 'node');\n\n // Overwrite the transaction name for instrumented data loaders because the trace data gets overwritten at a later point.\n // We only update the tx in case SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE got set in our instrumentation before.\n getGlobalScope().addEventProcessor(\n Object.assign(\n (event => {\n const overwrite = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n if (\n event.type === 'transaction' &&\n (event.transaction === 'GET *' || event.transaction === 'POST *') &&\n event.contexts?.trace?.data?.[ATTR_HTTP_ROUTE] === '*' &&\n overwrite\n ) {\n event.transaction = overwrite;\n event.contexts.trace.data[ATTR_HTTP_ROUTE] = 'url';\n }\n\n // always yeet this attribute into the void, as this should not reach the server\n delete event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n\n return event;\n }) satisfies EventProcessor,\n { id: 'ReactRouterTransactionEnhancer' },\n ),\n );\n\n DEBUG_BUILD && logger.log('SDK successfully initialized');\n\n return client;\n}\n"],"names":["getNodeDefaultIntegrations","lowQualityTransactionsFilterIntegration","NODE_VERSION","reactRouterServerIntegration","DEBUG_BUILD","logger","applySdkMetadata","initNodeSdk","setTag","getGlobalScope","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","ATTR_HTTP_ROUTE"],"mappings":";;;;;;;;;;AAUA;AACA;AACA;AACA;AACO,SAAS,uCAAuC,CAAC,OAAO,EAA8B;AAC7F,EAAE,MAAM,YAAA,GAAe,CAAC,GAAGA,2BAA0B,CAAC,OAAO,CAAC,EAAEC,+EAAuC,CAAC,OAAO,CAAC,CAAC;;AAEjH,EAAE;AACF,IAAI,CAACC,iBAAY,CAAC,KAAA,KAAU,EAAA,IAAMA,iBAAY,CAAC,KAAA,GAAQ,EAAE;AACzD,KAAKA,iBAAY,CAAC,KAAA,KAAU,EAAA,IAAMA,iBAAY,CAAC,KAAA,GAAQ,EAAE,CAAA;AACzD,IAAI;AACJ,IAAI,YAAY,CAAC,IAAI,CAACC,8CAA4B,EAAE,CAAC;AACrD;;AAEA,EAAE,OAAO,YAAY;AACrB;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAuC;AACnE,EAAE,MAAM,IAAI,GAAgB;AAC5B,IAAI,GAAG,OAAO;AACd,IAAI,mBAAmB,EAAE,uCAAuC,CAAC,OAAO,CAAC;AACzE,GAAG;;AAEH,EAAEC,0BAAeC,WAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC;;AAElD,EAAEC,qBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;;AAElE,EAAE,MAAM,MAAA,GAASC,SAAW,CAAC,IAAI,CAAC;;AAElC,EAAEC,WAAM,CAAC,SAAS,EAAE,MAAM,CAAC;;AAE3B;AACA;AACA,EAAEC,mBAAc,EAAE,CAAC,iBAAiB;AACpC,IAAI,MAAM,CAAC,MAAM;AACjB,OAAO,SAAS;AAChB,QAAQ,MAAM,SAAA,GAAY,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAGC,wCAAmC,CAAC;AAC5F,QAAQ;AACR,UAAU,KAAK,CAAC,IAAA,KAAS,aAAA;AACzB,WAAW,KAAK,CAAC,WAAA,KAAgB,OAAA,IAAW,KAAK,CAAC,WAAA,KAAgB,QAAQ,CAAA;AAC1E,UAAU,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAGC,mCAAe,CAAA,KAAM,GAAA;AAC7D,UAAU;AACV,UAAU;AACV,UAAU,KAAK,CAAC,WAAA,GAAc,SAAS;AACvC,UAAU,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAACA,mCAAe,CAAA,GAAI,KAAK;AAC5D;;AAEA;AACA,QAAQ,OAAO,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAGD,wCAAmC,CAAC;;AAEjF,QAAQ,OAAO,KAAK;AACpB,OAAO;AACP,MAAM,EAAE,EAAE,EAAE,gCAAA,EAAkC;AAC9C,KAAK;AACL,GAAG;;AAEH,EAAEN,0BAAeC,WAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC;;AAE3D,EAAE,OAAO,MAAM;AACf;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n getActiveSpan,\n getRootSpan,\n getTraceMetaTags,\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext } from 'react-router';\nimport type { PassThrough } from 'stream';\nimport { Transform } from 'stream';\n\ntype OriginalHandleRequest = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(originalHandle: OriginalHandleRequest): OriginalHandleRequest {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n if (parameterizedPath) {\n const activeSpan = getActiveSpan();\n if (activeSpan) {\n const rootSpan = getRootSpan(activeSpan);\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: `${request.method} ${routeName}`,\n });\n }\n }\n\n return originalHandle(request, responseStatusCode, responseHeaders, routerContext, loadContext);\n };\n}\n\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n\n/**\n * Injects Sentry trace meta tags into the HTML response by piping through a transform stream.\n * This enables distributed tracing by adding trace context to the HTML document head.\n *\n * @param body - PassThrough stream containing the HTML response body to modify\n */\nexport function getMetaTagTransformer(body: PassThrough): Transform {\n const headClosingTag = '</head>';\n const htmlMetaTagTransformer = new Transform({\n transform(chunk, _encoding, callback) {\n const html = Buffer.isBuffer(chunk) ? chunk.toString() : String(chunk);\n if (html.includes(headClosingTag)) {\n const modifiedHtml = html.replace(headClosingTag, `${getTraceMetaTags()}${headClosingTag}`);\n callback(null, modifiedHtml);\n return;\n }\n callback(null, chunk);\n },\n });\n htmlMetaTagTransformer.pipe(body);\n return htmlMetaTagTransformer;\n}\n"],"names":["getActiveSpan","getRootSpan","getRPCMetadata","context","RPCType","ATTR_HTTP_ROUTE","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME","Transform","getTraceMetaTags"],"mappings":";;;;;;;;AAsBA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,cAAc,EAAgD;AACtG,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAkB;AAC5B,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAM,MAAM,UAAA,GAAaA,kBAAa,EAAE;AACxC,MAAM,IAAI,UAAU,EAAE;AACtB,QAAQ,MAAM,QAAS,GAAEC,gBAAW,CAAC,UAAU,CAAC;AAChD,QAAQ,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,QAAA,MAAA,WAAA,GAAAC,qBAAA,CAAAC,WAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,QAAA,IAAA,WAAA,EAAA,IAAA,KAAAC,cAAA,CAAA,IAAA,EAAA;AACA,UAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA;;AAEA;AACA,QAAA,QAAA,CAAA,aAAA,CAAA;AACA,UAAA,CAAAC,mCAAA,GAAA,SAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,OAAA;AACA,UAAA,CAAAC,+CAAA,GAAA,CAAA,EAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,SAAA,CAAA;AACA;AACA;;AAEA,IAAA,OAAA,cAAA,CAAA,OAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,aAAA,EAAA,WAAA,CAAA;AACA,GAAA;AACA;;AAEA;AACA,MAAA,mBAAA,GAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,qBAAA,CAAA,IAAA,EAAA;AACA,EAAA,MAAA,cAAA,GAAA,SAAA;AACA,EAAA,MAAA,sBAAA,GAAA,IAAAC,gBAAA,CAAA;AACA,IAAA,SAAA,CAAA,KAAA,EAAA,SAAA,EAAA,QAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,MAAA,CAAA,QAAA,CAAA,KAAA,CAAA,GAAA,KAAA,CAAA,QAAA,EAAA,GAAA,MAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,CAAA,QAAA,CAAA,cAAA,CAAA,EAAA;AACA,QAAA,MAAA,YAAA,GAAA,IAAA,CAAA,OAAA,CAAA,cAAA,EAAA,CAAA,EAAAC,qBAAA,EAAA,CAAA,EAAA,cAAA,CAAA,CAAA,CAAA;AACA,QAAA,QAAA,CAAA,IAAA,EAAA,YAAA,CAAA;AACA,QAAA;AACA;AACA,MAAA,QAAA,CAAA,IAAA,EAAA,KAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA,EAAA,sBAAA,CAAA,IAAA,CAAA,IAAA,CAAA;AACA,EAAA,OAAA,sBAAA;AACA;;;;;;"}
1
+ {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n getActiveSpan,\n getRootSpan,\n getTraceMetaTags,\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext } from 'react-router';\nimport type { PassThrough } from 'stream';\nimport { Transform } from 'stream';\n\ntype OriginalHandleRequest = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(originalHandle: OriginalHandleRequest): OriginalHandleRequest {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n if (parameterizedPath) {\n const activeSpan = getActiveSpan();\n if (activeSpan) {\n const rootSpan = getRootSpan(activeSpan);\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: `${request.method} ${routeName}`,\n });\n }\n }\n\n return originalHandle(request, responseStatusCode, responseHeaders, routerContext, loadContext);\n };\n}\n\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n\n/**\n * Injects Sentry trace meta tags into the HTML response by piping through a transform stream.\n * This enables distributed tracing by adding trace context to the HTML document head.\n *\n * @param body - PassThrough stream containing the HTML response body to modify\n */\nexport function getMetaTagTransformer(body: PassThrough): Transform {\n const headClosingTag = '</head>';\n const htmlMetaTagTransformer = new Transform({\n transform(chunk, _encoding, callback) {\n const html = Buffer.isBuffer(chunk) ? chunk.toString() : String(chunk);\n if (html.includes(headClosingTag)) {\n const modifiedHtml = html.replace(headClosingTag, `${getTraceMetaTags()}${headClosingTag}`);\n callback(null, modifiedHtml);\n return;\n }\n callback(null, chunk);\n },\n });\n htmlMetaTagTransformer.pipe(body);\n return htmlMetaTagTransformer;\n}\n"],"names":["getActiveSpan","getRootSpan","getRPCMetadata","context","RPCType","ATTR_HTTP_ROUTE","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME","Transform","getTraceMetaTags"],"mappings":";;;;;;;;AAsBA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,cAAc,EAAgD;AACtG,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAA;AACV,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAM,MAAM,UAAA,GAAaA,kBAAa,EAAE;AACxC,MAAM,IAAI,UAAU,EAAE;AACtB,QAAQ,MAAM,QAAA,GAAWC,gBAAW,CAAC,UAAU,CAAC;AAChD,QAAQ,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,QAAA,MAAA,WAAA,GAAAC,qBAAA,CAAAC,WAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,QAAA,IAAA,WAAA,EAAA,IAAA,KAAAC,cAAA,CAAA,IAAA,EAAA;AACA,UAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA;;AAEA;AACA,QAAA,QAAA,CAAA,aAAA,CAAA;AACA,UAAA,CAAAC,mCAAA,GAAA,SAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,OAAA;AACA,UAAA,CAAAC,+CAAA,GAAA,CAAA,EAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,SAAA,CAAA;AACA;AACA;;AAEA,IAAA,OAAA,cAAA,CAAA,OAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,aAAA,EAAA,WAAA,CAAA;AACA,GAAA;AACA;;AAEA;AACA,MAAA,mBAAA,GAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,qBAAA,CAAA,IAAA,EAAA;AACA,EAAA,MAAA,cAAA,GAAA,SAAA;AACA,EAAA,MAAA,sBAAA,GAAA,IAAAC,gBAAA,CAAA;AACA,IAAA,SAAA,CAAA,KAAA,EAAA,SAAA,EAAA,QAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,MAAA,CAAA,QAAA,CAAA,KAAA,CAAA,GAAA,KAAA,CAAA,QAAA,EAAA,GAAA,MAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,CAAA,QAAA,CAAA,cAAA,CAAA,EAAA;AACA,QAAA,MAAA,YAAA,GAAA,IAAA,CAAA,OAAA,CAAA,cAAA,EAAA,CAAA,EAAAC,qBAAA,EAAA,CAAA,EAAA,cAAA,CAAA,CAAA,CAAA;AACA,QAAA,QAAA,CAAA,IAAA,EAAA,YAAA,CAAA;AACA,QAAA;AACA;AACA,MAAA,QAAA,CAAA,IAAA,EAAA,KAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA,EAAA,sBAAA,CAAA,IAAA,CAAA,IAAA,CAAA;AACA,EAAA,OAAA,sBAAA;AACA;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'POST') {\n const url = parseStringToURLObject(args.request.url);\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","parseStringToURLObject","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":";;;;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAK,GAAE,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAK,GAAEC,gBAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAIC,eAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,MAAM,EAAE;AACnD,QAAQ,MAAM,GAAI,GAAEC,2BAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AAC5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAACC,qCAAgC,GAAG,KAAK;AACrD,YAAY,CAACC,wCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;;AAEA,IAAA,OAAAC,cAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,wBAAA;AACA,UAAA,CAAAC,iCAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'POST') {\n const url = parseStringToURLObject(args.request.url);\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","parseStringToURLObject","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":";;;;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAOC,gBAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAIC,eAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,MAAM,EAAE;AACnD,QAAQ,MAAM,GAAA,GAAMC,2BAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AAC5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAACC,qCAAgC,GAAG,KAAK;AACrD,YAAY,CAACC,wCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;;AAEA,IAAA,OAAAC,cAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,wBAAA;AACA,UAAA,CAAAC,iCAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'GET') {\n const url = parseStringToURLObject(args.request.url);\n\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","parseStringToURLObject","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":";;;;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAK,GAAE,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAK,GAAEC,gBAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAIC,eAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,KAAK,EAAE;AAClD,QAAQ,MAAM,GAAI,GAAEC,2BAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;;AAE5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAACC,qCAAgC,GAAG,KAAK;AACrD,YAAY,CAACC,wCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;AACA,IAAA,OAAAC,cAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,wBAAA;AACA,UAAA,CAAAC,iCAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'GET') {\n const url = parseStringToURLObject(args.request.url);\n\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n };\n}\n"],"names":["getActiveSpan","getRootSpan","spanToJSON","parseStringToURLObject","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":";;;;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAASA,kBAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAOC,gBAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAIC,eAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,KAAK,EAAE;AAClD,QAAQ,MAAM,GAAA,GAAMC,2BAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;;AAE5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAACC,qCAAgC,GAAG,KAAK;AACrD,YAAY,CAACC,wCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;AACA,IAAA,OAAAC,cAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAAC,qCAAA,GAAA,wBAAA;AACA,UAAA,CAAAC,iCAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"handleOnBuildEnd.js","sources":["../../../../src/vite/buildEnd/handleOnBuildEnd.ts"],"sourcesContent":["import { rm } from 'node:fs/promises';\nimport type { Config } from '@react-router/dev/config';\nimport SentryCli from '@sentry/cli';\nimport { glob } from 'glob';\nimport type { SentryReactRouterBuildOptions } from '../types';\n\ntype BuildEndHook = NonNullable<Config['buildEnd']>;\n\nfunction getSentryConfig(viteConfig: unknown): SentryReactRouterBuildOptions {\n if (!viteConfig || typeof viteConfig !== 'object' || !('sentryConfig' in viteConfig)) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] sentryConfig not found - it needs to be passed to vite.config.ts');\n }\n\n return (viteConfig as { sentryConfig: SentryReactRouterBuildOptions }).sentryConfig;\n}\n\n/**\n * A build end hook that handles Sentry release creation and source map uploads.\n * It creates a new Sentry release if configured, uploads source maps to Sentry,\n * and optionally deletes the source map files after upload.\n */\nexport const sentryOnBuildEnd: BuildEndHook = async ({ reactRouterConfig, viteConfig }) => {\n const sentryConfig = getSentryConfig(viteConfig);\n\n const {\n authToken,\n org,\n project,\n release,\n sourceMapsUploadOptions = { enabled: true },\n debug = false,\n unstable_sentryVitePluginOptions,\n }: SentryReactRouterBuildOptions = {\n ...sentryConfig.unstable_sentryVitePluginOptions,\n ...sentryConfig,\n release: {\n ...sentryConfig.unstable_sentryVitePluginOptions?.release,\n ...sentryConfig.release,\n },\n };\n\n const cliInstance = new SentryCli(null, {\n authToken,\n org,\n project,\n ...unstable_sentryVitePluginOptions,\n });\n // check if release should be created\n if (release?.name) {\n try {\n await cliInstance.releases.new(release.name);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not create release', error);\n }\n }\n\n if (sourceMapsUploadOptions?.enabled ?? (true && viteConfig.build.sourcemap !== false)) {\n // inject debugIds\n try {\n await cliInstance.execute(['sourcemaps', 'inject', reactRouterConfig.buildDirectory], debug);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not inject debug ids', error);\n }\n\n // upload sourcemaps\n try {\n await cliInstance.releases.uploadSourceMaps(release?.name || 'undefined', {\n include: [\n {\n paths: [reactRouterConfig.buildDirectory],\n },\n ],\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not upload sourcemaps', error);\n }\n }\n // delete sourcemaps after upload\n let updatedFilesToDeleteAfterUpload = sourceMapsUploadOptions?.filesToDeleteAfterUpload;\n // set a default value no option was set\n if (typeof sourceMapsUploadOptions?.filesToDeleteAfterUpload === 'undefined') {\n updatedFilesToDeleteAfterUpload = [`${reactRouterConfig.buildDirectory}/**/*.map`];\n if (debug) {\n // eslint-disable-next-line no-console\n console.info(\n `[Sentry] Automatically setting \\`sourceMapsUploadOptions.filesToDeleteAfterUpload: ${JSON.stringify(\n updatedFilesToDeleteAfterUpload,\n )}\\` to delete generated source maps after they were uploaded to Sentry.`,\n );\n }\n }\n if (updatedFilesToDeleteAfterUpload) {\n try {\n const filePathsToDelete = await glob(updatedFilesToDeleteAfterUpload, {\n absolute: true,\n nodir: true,\n });\n if (debug) {\n filePathsToDelete.forEach(filePathToDelete => {\n // eslint-disable-next-line no-console\n console.info(`Deleting asset after upload: ${filePathToDelete}`);\n });\n }\n await Promise.all(\n filePathsToDelete.map(filePathToDelete =>\n rm(filePathToDelete, { force: true }).catch((e: unknown) => {\n if (debug) {\n // This is allowed to fail - we just don't do anything\n // eslint-disable-next-line no-console\n console.debug(`An error occurred while attempting to delete asset: ${filePathToDelete}`, e);\n }\n }),\n ),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Error deleting files after sourcemap upload:', error);\n }\n }\n};\n"],"names":["SentryCli","glob","rm"],"mappings":"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"}
1
+ {"version":3,"file":"handleOnBuildEnd.js","sources":["../../../../src/vite/buildEnd/handleOnBuildEnd.ts"],"sourcesContent":["import { rm } from 'node:fs/promises';\nimport type { Config } from '@react-router/dev/config';\nimport SentryCli from '@sentry/cli';\nimport { glob } from 'glob';\nimport type { SentryReactRouterBuildOptions } from '../types';\n\ntype BuildEndHook = NonNullable<Config['buildEnd']>;\n\nfunction getSentryConfig(viteConfig: unknown): SentryReactRouterBuildOptions {\n if (!viteConfig || typeof viteConfig !== 'object' || !('sentryConfig' in viteConfig)) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] sentryConfig not found - it needs to be passed to vite.config.ts');\n }\n\n return (viteConfig as { sentryConfig: SentryReactRouterBuildOptions }).sentryConfig;\n}\n\n/**\n * A build end hook that handles Sentry release creation and source map uploads.\n * It creates a new Sentry release if configured, uploads source maps to Sentry,\n * and optionally deletes the source map files after upload.\n */\nexport const sentryOnBuildEnd: BuildEndHook = async ({ reactRouterConfig, viteConfig }) => {\n const sentryConfig = getSentryConfig(viteConfig);\n\n const {\n authToken,\n org,\n project,\n release,\n sourceMapsUploadOptions = { enabled: true },\n debug = false,\n unstable_sentryVitePluginOptions,\n }: SentryReactRouterBuildOptions = {\n ...sentryConfig.unstable_sentryVitePluginOptions,\n ...sentryConfig,\n release: {\n ...sentryConfig.unstable_sentryVitePluginOptions?.release,\n ...sentryConfig.release,\n },\n };\n\n const cliInstance = new SentryCli(null, {\n authToken,\n org,\n project,\n ...unstable_sentryVitePluginOptions,\n });\n // check if release should be created\n if (release?.name) {\n try {\n await cliInstance.releases.new(release.name);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not create release', error);\n }\n }\n\n if (sourceMapsUploadOptions?.enabled ?? (true && viteConfig.build.sourcemap !== false)) {\n // inject debugIds\n try {\n await cliInstance.execute(['sourcemaps', 'inject', reactRouterConfig.buildDirectory], debug);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not inject debug ids', error);\n }\n\n // upload sourcemaps\n try {\n await cliInstance.releases.uploadSourceMaps(release?.name || 'undefined', {\n include: [\n {\n paths: [reactRouterConfig.buildDirectory],\n },\n ],\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not upload sourcemaps', error);\n }\n }\n // delete sourcemaps after upload\n let updatedFilesToDeleteAfterUpload = sourceMapsUploadOptions?.filesToDeleteAfterUpload;\n // set a default value no option was set\n if (typeof sourceMapsUploadOptions?.filesToDeleteAfterUpload === 'undefined') {\n updatedFilesToDeleteAfterUpload = [`${reactRouterConfig.buildDirectory}/**/*.map`];\n if (debug) {\n // eslint-disable-next-line no-console\n console.info(\n `[Sentry] Automatically setting \\`sourceMapsUploadOptions.filesToDeleteAfterUpload: ${JSON.stringify(\n updatedFilesToDeleteAfterUpload,\n )}\\` to delete generated source maps after they were uploaded to Sentry.`,\n );\n }\n }\n if (updatedFilesToDeleteAfterUpload) {\n try {\n const filePathsToDelete = await glob(updatedFilesToDeleteAfterUpload, {\n absolute: true,\n nodir: true,\n });\n if (debug) {\n filePathsToDelete.forEach(filePathToDelete => {\n // eslint-disable-next-line no-console\n console.info(`Deleting asset after upload: ${filePathToDelete}`);\n });\n }\n await Promise.all(\n filePathsToDelete.map(filePathToDelete =>\n rm(filePathToDelete, { force: true }).catch((e: unknown) => {\n if (debug) {\n // This is allowed to fail - we just don't do anything\n // eslint-disable-next-line no-console\n console.debug(`An error occurred while attempting to delete asset: ${filePathToDelete}`, e);\n }\n }),\n ),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Error deleting files after sourcemap upload:', error);\n }\n }\n};\n"],"names":["SentryCli","glob","rm"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"makeCustomSentryVitePlugins.js","sources":["../../../src/vite/makeCustomSentryVitePlugins.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/vite-plugin';\nimport { type Plugin } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * Create a custom subset of sentry's vite plugins\n */\nexport async function makeCustomSentryVitePlugins(options: SentryReactRouterBuildOptions): Promise<Plugin[]> {\n const {\n debug,\n unstable_sentryVitePluginOptions,\n bundleSizeOptimizations,\n authToken,\n org,\n project,\n telemetry,\n reactComponentAnnotation,\n release,\n } = options;\n\n const sentryVitePlugins = sentryVitePlugin({\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations,\n debug: debug ?? false,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n telemetry: telemetry ?? true,\n _metaOptions: {\n telemetry: {\n metaFramework: 'react-router',\n },\n ...unstable_sentryVitePluginOptions?._metaOptions,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n ...unstable_sentryVitePluginOptions?.reactComponentAnnotation,\n },\n release: {\n ...unstable_sentryVitePluginOptions?.release,\n ...release,\n },\n // will be handled in buildEnd hook\n sourcemaps: {\n disable: true,\n ...unstable_sentryVitePluginOptions?.sourcemaps,\n },\n ...unstable_sentryVitePluginOptions,\n }) as Plugin[];\n\n // only use a subset of the plugins as all upload and file deletion tasks will be handled in the buildEnd hook\n return [\n ...sentryVitePlugins.filter(plugin => {\n return [\n 'sentry-telemetry-plugin',\n 'sentry-vite-release-injection-plugin',\n ...(reactComponentAnnotation?.enabled || unstable_sentryVitePluginOptions?.reactComponentAnnotation?.enabled\n ? ['sentry-vite-component-name-annotate-plugin']\n : []),\n ].includes(plugin.name);\n }),\n ];\n}\n"],"names":["sentryVitePlugin"],"mappings":";;;;AAIA;AACA;AACA;AACO,eAAe,2BAA2B,CAAC,OAAO,EAAoD;AAC7G,EAAE,MAAM;AACR,IAAI,KAAK;AACT,IAAI,gCAAgC;AACpC,IAAI,uBAAuB;AAC3B,IAAI,SAAS;AACb,IAAI,GAAG;AACP,IAAI,OAAO;AACX,IAAI,SAAS;AACb,IAAI,wBAAwB;AAC5B,IAAI,OAAO;AACX,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,iBAAA,GAAoBA,2BAAgB,CAAC;AAC7C,IAAI,SAAS,EAAE,SAAU,IAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB;AACzD,IAAI,uBAAuB;AAC3B,IAAI,KAAK,EAAE,KAAM,IAAG,KAAK;AACzB,IAAI,GAAG,EAAE,GAAI,IAAG,OAAO,CAAC,GAAG,CAAC,UAAU;AACtC,IAAI,OAAO,EAAE,OAAQ,IAAG,OAAO,CAAC,GAAG,CAAC,cAAc;AAClD,IAAI,SAAS,EAAE,SAAU,IAAG,IAAI;AAChC,IAAI,YAAY,EAAE;AAClB,MAAM,SAAS,EAAE;AACjB,QAAQ,aAAa,EAAE,cAAc;AACrC,OAAO;AACP,MAAM,GAAG,gCAAgC,EAAE,YAAY;AACvD,KAAK;AACL,IAAI,wBAAwB,EAAE;AAC9B,MAAM,OAAO,EAAE,wBAAwB,EAAE,OAAA,IAAW,SAAS;AAC7D,MAAM,iBAAiB,EAAE,wBAAwB,EAAE,iBAAA,IAAqB,SAAS;AACjF,MAAM,GAAG,gCAAgC,EAAE,wBAAwB;AACnE,KAAK;AACL,IAAI,OAAO,EAAE;AACb,MAAM,GAAG,gCAAgC,EAAE,OAAO;AAClD,MAAM,GAAG,OAAO;AAChB,KAAK;AACL;AACA,IAAI,UAAU,EAAE;AAChB,MAAM,OAAO,EAAE,IAAI;AACnB,MAAM,GAAG,gCAAgC,EAAE,UAAU;AACrD,KAAK;AACL,IAAI,GAAG,gCAAgC;AACvC,GAAG,CAAE;;AAEL;AACA,EAAE,OAAO;AACT,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,UAAU;AAC1C,MAAM,OAAO;AACb,QAAQ,yBAAyB;AACjC,QAAQ,sCAAsC;AAC9C,QAAQ,IAAI,wBAAwB,EAAE,WAAW,gCAAgC,EAAE,wBAAwB,EAAE;AAC7G,YAAY,CAAC,4CAA4C;AACzD,YAAY,EAAE,CAAC;AACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AAC7B,KAAK,CAAC;AACN,GAAG;AACH;;;;"}
1
+ {"version":3,"file":"makeCustomSentryVitePlugins.js","sources":["../../../src/vite/makeCustomSentryVitePlugins.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/vite-plugin';\nimport { type Plugin } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * Create a custom subset of sentry's vite plugins\n */\nexport async function makeCustomSentryVitePlugins(options: SentryReactRouterBuildOptions): Promise<Plugin[]> {\n const {\n debug,\n unstable_sentryVitePluginOptions,\n bundleSizeOptimizations,\n authToken,\n org,\n project,\n telemetry,\n reactComponentAnnotation,\n release,\n } = options;\n\n const sentryVitePlugins = sentryVitePlugin({\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations,\n debug: debug ?? false,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n telemetry: telemetry ?? true,\n _metaOptions: {\n telemetry: {\n metaFramework: 'react-router',\n },\n ...unstable_sentryVitePluginOptions?._metaOptions,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n ...unstable_sentryVitePluginOptions?.reactComponentAnnotation,\n },\n release: {\n ...unstable_sentryVitePluginOptions?.release,\n ...release,\n },\n // will be handled in buildEnd hook\n sourcemaps: {\n disable: true,\n ...unstable_sentryVitePluginOptions?.sourcemaps,\n },\n ...unstable_sentryVitePluginOptions,\n }) as Plugin[];\n\n // only use a subset of the plugins as all upload and file deletion tasks will be handled in the buildEnd hook\n return [\n ...sentryVitePlugins.filter(plugin => {\n return [\n 'sentry-telemetry-plugin',\n 'sentry-vite-release-injection-plugin',\n ...(reactComponentAnnotation?.enabled || unstable_sentryVitePluginOptions?.reactComponentAnnotation?.enabled\n ? ['sentry-vite-component-name-annotate-plugin']\n : []),\n ].includes(plugin.name);\n }),\n ];\n}\n"],"names":["sentryVitePlugin"],"mappings":";;;;AAIA;AACA;AACA;AACO,eAAe,2BAA2B,CAAC,OAAO,EAAoD;AAC7G,EAAE,MAAM;AACR,IAAI,KAAK;AACT,IAAI,gCAAgC;AACpC,IAAI,uBAAuB;AAC3B,IAAI,SAAS;AACb,IAAI,GAAG;AACP,IAAI,OAAO;AACX,IAAI,SAAS;AACb,IAAI,wBAAwB;AAC5B,IAAI,OAAO;AACX,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,iBAAA,GAAoBA,2BAAgB,CAAC;AAC7C,IAAI,SAAS,EAAE,SAAA,IAAa,OAAO,CAAC,GAAG,CAAC,iBAAiB;AACzD,IAAI,uBAAuB;AAC3B,IAAI,KAAK,EAAE,KAAA,IAAS,KAAK;AACzB,IAAI,GAAG,EAAE,GAAA,IAAO,OAAO,CAAC,GAAG,CAAC,UAAU;AACtC,IAAI,OAAO,EAAE,OAAA,IAAW,OAAO,CAAC,GAAG,CAAC,cAAc;AAClD,IAAI,SAAS,EAAE,SAAA,IAAa,IAAI;AAChC,IAAI,YAAY,EAAE;AAClB,MAAM,SAAS,EAAE;AACjB,QAAQ,aAAa,EAAE,cAAc;AACrC,OAAO;AACP,MAAM,GAAG,gCAAgC,EAAE,YAAY;AACvD,KAAK;AACL,IAAI,wBAAwB,EAAE;AAC9B,MAAM,OAAO,EAAE,wBAAwB,EAAE,OAAA,IAAW,SAAS;AAC7D,MAAM,iBAAiB,EAAE,wBAAwB,EAAE,iBAAA,IAAqB,SAAS;AACjF,MAAM,GAAG,gCAAgC,EAAE,wBAAwB;AACnE,KAAK;AACL,IAAI,OAAO,EAAE;AACb,MAAM,GAAG,gCAAgC,EAAE,OAAO;AAClD,MAAM,GAAG,OAAO;AAChB,KAAK;AACL;AACA,IAAI,UAAU,EAAE;AAChB,MAAM,OAAO,EAAE,IAAI;AACnB,MAAM,GAAG,gCAAgC,EAAE,UAAU;AACrD,KAAK;AACL,IAAI,GAAG,gCAAgC;AACvC,GAAG,CAAA;;AAEH;AACA,EAAE,OAAO;AACT,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,UAAU;AAC1C,MAAM,OAAO;AACb,QAAQ,yBAAyB;AACjC,QAAQ,sCAAsC;AAC9C,QAAQ,IAAI,wBAAwB,EAAE,WAAW,gCAAgC,EAAE,wBAAwB,EAAE;AAC7G,YAAY,CAAC,4CAA4C;AACzD,YAAY,EAAE,CAAC;AACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AAC7B,KAAK,CAAC;AACN,GAAG;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"makeEnableSourceMapsPlugin.js","sources":["../../../src/vite/makeEnableSourceMapsPlugin.ts"],"sourcesContent":["import { consoleSandbox } from '@sentry/core';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Sentry plugin for React Router to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsPlugin(options: SentryReactRouterBuildOptions): Plugin {\n return {\n name: 'sentry-react-router-update-source-map-setting',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n };\n}\n\n/** There are 3 ways to set up source map generation\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - we won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryReactRouterBuildOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteSourceMap = viteConfig?.build?.sourcemap;\n let updatedSourceMapSetting = viteSourceMap;\n\n const settingKey = 'vite.build.sourcemap';\n\n if (viteSourceMap === false) {\n updatedSourceMapSetting = viteSourceMap;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Source map generation is currently disabled in your Vite configuration (\\`${settingKey}: false \\`). This setting is either a default setting or was explicitly set in your configuration. Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified. To show unminified code, enable source maps in \\`${settingKey}\\` (e.g. by setting them to \\`hidden\\`).`,\n );\n });\n } else if (viteSourceMap && ['hidden', 'inline', true].includes(viteSourceMap)) {\n updatedSourceMapSetting = viteSourceMap;\n\n if (sentryPluginOptions?.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteSourceMap.toString()}\\`. Sentry will keep this source map setting. This will un-minify the code snippet on the Sentry Issue page.`,\n );\n });\n }\n } else {\n updatedSourceMapSetting = 'hidden';\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n });\n }\n\n return updatedSourceMapSetting;\n}\n"],"names":["consoleSandbox"],"mappings":";;;;AAIA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,OAAO,EAAyC;AAC3F,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,+CAA+C;AACzD,IAAI,KAAK,EAAE,OAAO;AAClB,IAAI,OAAO,EAAE,MAAM;AACnB,IAAI,MAAM,CAAC,UAAU,EAAE;AACvB,MAAM,OAAO;AACb,QAAQ,GAAG,UAAU;AACrB,QAAQ,KAAK,EAAE;AACf,UAAU,GAAG,UAAU,CAAC,KAAK;AAC7B,UAAU,SAAS,EAAE,2BAA2B,CAAC,UAAU,EAAE,OAAO,CAAC;AACrE,SAAS;AACT,OAAO;AACP,KAAK;AACL,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,2BAA2B;AAC3C,EAAE,UAAU;AACZ,EAAE,mBAAmB;AACrB,EAAiC;AACjC,EAAE,UAAU,CAAC,KAAM,GAAE,UAAU,CAAC,KAAA,IAAS,EAAE;;AAE3C,EAAE,MAAM,aAAc,GAAE,UAAU,EAAE,KAAK,EAAE,SAAS;AACpD,EAAE,IAAI,uBAAwB,GAAE,aAAa;;AAE7C,EAAE,MAAM,UAAW,GAAE,sBAAsB;;AAE3C,EAAE,IAAI,aAAc,KAAI,KAAK,EAAE;AAC/B,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAIA,mBAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,IAAI;AAClB,QAAQ,CAAC,mFAAmF,EAAE,UAAU,CAAC,2QAA2Q,EAAE,UAAU,CAAC,wCAAwC,CAAC;AAC1a,OAAO;AACP,KAAK,CAAC;AACN,SAAS,IAAI,aAAc,IAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;AAClF,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAI,IAAI,mBAAmB,EAAE,KAAK,EAAE;AACpC,MAAMA,mBAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,GAAG;AACnB,UAAU,CAAC,yBAAyB,EAAE,UAAU,CAAC,eAAe,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,4GAA4G,CAAC;AACxM,SAAS;AACT,OAAO,CAAC;AACR;AACA,SAAS;AACT,IAAI,uBAAA,GAA0B,QAAQ;;AAEtC,IAAIA,mBAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,CAAC,mEAAmE,EAAE,UAAU,CAAC,kFAAkF,CAAC;AAC5K,OAAO;AACP,KAAK,CAAC;AACN;;AAEA,EAAE,OAAO,uBAAuB;AAChC;;;;;"}
1
+ {"version":3,"file":"makeEnableSourceMapsPlugin.js","sources":["../../../src/vite/makeEnableSourceMapsPlugin.ts"],"sourcesContent":["import { consoleSandbox } from '@sentry/core';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Sentry plugin for React Router to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsPlugin(options: SentryReactRouterBuildOptions): Plugin {\n return {\n name: 'sentry-react-router-update-source-map-setting',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n };\n}\n\n/** There are 3 ways to set up source map generation\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - we won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryReactRouterBuildOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteSourceMap = viteConfig?.build?.sourcemap;\n let updatedSourceMapSetting = viteSourceMap;\n\n const settingKey = 'vite.build.sourcemap';\n\n if (viteSourceMap === false) {\n updatedSourceMapSetting = viteSourceMap;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Source map generation is currently disabled in your Vite configuration (\\`${settingKey}: false \\`). This setting is either a default setting or was explicitly set in your configuration. Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified. To show unminified code, enable source maps in \\`${settingKey}\\` (e.g. by setting them to \\`hidden\\`).`,\n );\n });\n } else if (viteSourceMap && ['hidden', 'inline', true].includes(viteSourceMap)) {\n updatedSourceMapSetting = viteSourceMap;\n\n if (sentryPluginOptions?.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteSourceMap.toString()}\\`. Sentry will keep this source map setting. This will un-minify the code snippet on the Sentry Issue page.`,\n );\n });\n }\n } else {\n updatedSourceMapSetting = 'hidden';\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n });\n }\n\n return updatedSourceMapSetting;\n}\n"],"names":["consoleSandbox"],"mappings":";;;;AAIA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,OAAO,EAAyC;AAC3F,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,+CAA+C;AACzD,IAAI,KAAK,EAAE,OAAO;AAClB,IAAI,OAAO,EAAE,MAAM;AACnB,IAAI,MAAM,CAAC,UAAU,EAAE;AACvB,MAAM,OAAO;AACb,QAAQ,GAAG,UAAU;AACrB,QAAQ,KAAK,EAAE;AACf,UAAU,GAAG,UAAU,CAAC,KAAK;AAC7B,UAAU,SAAS,EAAE,2BAA2B,CAAC,UAAU,EAAE,OAAO,CAAC;AACrE,SAAS;AACT,OAAO;AACP,KAAK;AACL,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,2BAA2B;AAC3C,EAAE,UAAU;AACZ,EAAE,mBAAmB;AACrB,EAAiC;AACjC,EAAE,UAAU,CAAC,KAAA,GAAQ,UAAU,CAAC,KAAA,IAAS,EAAE;;AAE3C,EAAE,MAAM,aAAA,GAAgB,UAAU,EAAE,KAAK,EAAE,SAAS;AACpD,EAAE,IAAI,uBAAA,GAA0B,aAAa;;AAE7C,EAAE,MAAM,UAAA,GAAa,sBAAsB;;AAE3C,EAAE,IAAI,aAAA,KAAkB,KAAK,EAAE;AAC/B,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAIA,mBAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,IAAI;AAClB,QAAQ,CAAC,mFAAmF,EAAE,UAAU,CAAC,2QAA2Q,EAAE,UAAU,CAAC,wCAAwC,CAAC;AAC1a,OAAO;AACP,KAAK,CAAC;AACN,SAAS,IAAI,aAAA,IAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;AAClF,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAI,IAAI,mBAAmB,EAAE,KAAK,EAAE;AACpC,MAAMA,mBAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,GAAG;AACnB,UAAU,CAAC,yBAAyB,EAAE,UAAU,CAAC,eAAe,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,4GAA4G,CAAC;AACxM,SAAS;AACT,OAAO,CAAC;AACR;AACA,SAAS;AACT,IAAI,uBAAA,GAA0B,QAAQ;;AAEtC,IAAIA,mBAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,CAAC,mEAAmE,EAAE,UAAU,CAAC,kFAAkF,CAAC;AAC5K,OAAO;AACP,KAAK,CAAC;AACN;;AAEA,EAAE,OAAO,uBAAuB;AAChC;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import type { ConfigEnv } from 'vite';\nimport { type Plugin } from 'vite';\nimport { makeConfigInjectorPlugin } from './makeConfigInjectorPlugin';\nimport { makeCustomSentryVitePlugins } from './makeCustomSentryVitePlugins';\nimport { makeEnableSourceMapsPlugin } from './makeEnableSourceMapsPlugin';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Vite plugin for Sentry that handles source map uploads and bundle size optimizations.\n *\n * @param options - Configuration options for the Sentry Vite plugin\n * @param viteConfig - The Vite user config object\n * @returns An array of Vite plugins\n */\nexport async function sentryReactRouter(\n options: SentryReactRouterBuildOptions = {},\n config: ConfigEnv,\n): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n\n plugins.push(makeConfigInjectorPlugin(options));\n\n if (process.env.NODE_ENV !== 'development' && config.command === 'build' && config.mode !== 'development') {\n plugins.push(makeEnableSourceMapsPlugin(options));\n plugins.push(...(await makeCustomSentryVitePlugins(options)));\n }\n\n return plugins;\n}\n"],"names":["makeConfigInjectorPlugin","makeEnableSourceMapsPlugin","makeCustomSentryVitePlugins"],"mappings":";;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,iBAAiB;AACvC,EAAE,OAAO,GAAkC,EAAE;AAC7C,EAAE,MAAM;AACR,EAAqB;AACrB,EAAE,MAAM,OAAO,GAAa,EAAE;;AAE9B,EAAE,OAAO,CAAC,IAAI,CAACA,iDAAwB,CAAC,OAAO,CAAC,CAAC;;AAEjD,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAA,KAAa,aAAc,IAAG,MAAM,CAAC,OAAA,KAAY,OAAQ,IAAG,MAAM,CAAC,IAAA,KAAS,aAAa,EAAE;AAC7G,IAAI,OAAO,CAAC,IAAI,CAACC,qDAA0B,CAAC,OAAO,CAAC,CAAC;AACrD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,MAAMC,uDAA2B,CAAC,OAAO,CAAC,CAAC,CAAC;AACjE;;AAEA,EAAE,OAAO,OAAO;AAChB;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import type { ConfigEnv } from 'vite';\nimport { type Plugin } from 'vite';\nimport { makeConfigInjectorPlugin } from './makeConfigInjectorPlugin';\nimport { makeCustomSentryVitePlugins } from './makeCustomSentryVitePlugins';\nimport { makeEnableSourceMapsPlugin } from './makeEnableSourceMapsPlugin';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Vite plugin for Sentry that handles source map uploads and bundle size optimizations.\n *\n * @param options - Configuration options for the Sentry Vite plugin\n * @param viteConfig - The Vite user config object\n * @returns An array of Vite plugins\n */\nexport async function sentryReactRouter(\n options: SentryReactRouterBuildOptions = {},\n config: ConfigEnv,\n): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n\n plugins.push(makeConfigInjectorPlugin(options));\n\n if (process.env.NODE_ENV !== 'development' && config.command === 'build' && config.mode !== 'development') {\n plugins.push(makeEnableSourceMapsPlugin(options));\n plugins.push(...(await makeCustomSentryVitePlugins(options)));\n }\n\n return plugins;\n}\n"],"names":["makeConfigInjectorPlugin","makeEnableSourceMapsPlugin","makeCustomSentryVitePlugins"],"mappings":";;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,iBAAiB;AACvC,EAAE,OAAO,GAAkC,EAAE;AAC7C,EAAE,MAAM;AACR,EAAqB;AACrB,EAAE,MAAM,OAAO,GAAa,EAAE;;AAE9B,EAAE,OAAO,CAAC,IAAI,CAACA,iDAAwB,CAAC,OAAO,CAAC,CAAC;;AAEjD,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAA,KAAa,aAAA,IAAiB,MAAM,CAAC,OAAA,KAAY,OAAA,IAAW,MAAM,CAAC,IAAA,KAAS,aAAa,EAAE;AAC7G,IAAI,OAAO,CAAC,IAAI,CAACC,qDAA0B,CAAC,OAAO,CAAC,CAAC;AACrD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,MAAMC,uDAA2B,CAAC,OAAO,CAAC,CAAC,CAAC;AACjE;;AAEA,EAAE,OAAO,OAAO;AAChB;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n const pageloadName = pageloadSpan ? spanToJSON(pageloadSpan).description : undefined;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName) && // this event is for the currently active pageload\n normalizePathname(parameterizePageloadRoute) !== normalizePathname(pageloadName) // route is not parameterized yet\n ) {\n pageloadSpan?.updateName(parameterizePageloadRoute);\n pageloadSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n const navigationSpanName = navigationSpan ? spanToJSON(navigationSpan).description : undefined;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName && // we have an active pageload tx\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) && // this event is for the currently active navigation\n normalizePathname(parameterizedNavRoute) !== normalizePathname(navigationSpanName) // route is not parameterized yet\n ) {\n navigationSpan?.updateName(parameterizedNavRoute);\n navigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hydratedRouter.js","sources":["../../../src/client/hydratedRouter.ts"],"sourcesContent":["import { startBrowserTracingNavigationSpan } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport {\n consoleSandbox,\n getActiveSpan,\n getClient,\n getRootSpan,\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n} from '@sentry/core';\nimport type { DataRouter, RouterState } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\n\nconst GLOBAL_OBJ_WITH_DATA_ROUTER = GLOBAL_OBJ as typeof GLOBAL_OBJ & {\n __reactRouterDataRouter?: DataRouter;\n};\n\nconst MAX_RETRIES = 40; // 2 seconds at 50ms interval\n\n/**\n * Instruments the React Router Data Router for pageloads and navigation.\n *\n * This function waits for the router to be available after hydration, then:\n * 1. Updates the pageload transaction with parameterized route info\n * 2. Patches router.navigate() to create navigation transactions\n * 3. Subscribes to router state changes to update navigation transactions with parameterized routes\n */\nexport function instrumentHydratedRouter(): void {\n function trySubscribe(): boolean {\n const router = GLOBAL_OBJ_WITH_DATA_ROUTER.__reactRouterDataRouter;\n\n if (router) {\n // The first time we hit the router, we try to update the pageload transaction\n // todo: update pageload tx here\n const pageloadSpan = getActiveRootSpan();\n const pageloadName = pageloadSpan ? spanToJSON(pageloadSpan).description : undefined;\n const parameterizePageloadRoute = getParameterizedRoute(router.state);\n if (\n pageloadName &&\n normalizePathname(router.state.location.pathname) === normalizePathname(pageloadName) && // this event is for the currently active pageload\n normalizePathname(parameterizePageloadRoute) !== normalizePathname(pageloadName) // route is not parameterized yet\n ) {\n pageloadSpan?.updateName(parameterizePageloadRoute);\n pageloadSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n\n // Patching navigate for creating accurate navigation transactions\n if (typeof router.navigate === 'function') {\n const originalNav = router.navigate.bind(router);\n router.navigate = function sentryPatchedNavigate(...args) {\n maybeCreateNavigationTransaction(\n String(args[0]) || '<unknown route>', // will be updated anyway\n 'url', // this also will be updated once we have the parameterized route\n );\n return originalNav(...args);\n };\n }\n\n // Subscribe to router state changes to update navigation transactions with parameterized routes\n router.subscribe(newState => {\n const navigationSpan = getActiveRootSpan();\n const navigationSpanName = navigationSpan ? spanToJSON(navigationSpan).description : undefined;\n const parameterizedNavRoute = getParameterizedRoute(newState);\n\n if (\n navigationSpanName && // we have an active pageload tx\n newState.navigation.state === 'idle' && // navigation has completed\n normalizePathname(newState.location.pathname) === normalizePathname(navigationSpanName) && // this event is for the currently active navigation\n normalizePathname(parameterizedNavRoute) !== normalizePathname(navigationSpanName) // route is not parameterized yet\n ) {\n navigationSpan?.updateName(parameterizedNavRoute);\n navigationSpan?.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n });\n return true;\n }\n return false;\n }\n\n // Wait until the router is available (since the SDK loads before hydration)\n if (!trySubscribe()) {\n let retryCount = 0;\n // Retry until the router is available or max retries reached\n const interval = setInterval(() => {\n if (trySubscribe() || retryCount >= MAX_RETRIES) {\n if (retryCount >= MAX_RETRIES) {\n DEBUG_BUILD &&\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn('Unable to instrument React Router: router not found after hydration.');\n });\n }\n clearInterval(interval);\n }\n retryCount++;\n }, 50);\n }\n}\n\nfunction maybeCreateNavigationTransaction(name: string, source: 'url' | 'route'): Span | undefined {\n const client = getClient();\n\n if (!client) {\n return undefined;\n }\n\n return startBrowserTracingNavigationSpan(client, {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source,\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'navigation',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.react-router',\n },\n });\n}\n\nfunction getActiveRootSpan(): Span | undefined {\n const activeSpan = getActiveSpan();\n if (!activeSpan) {\n return undefined;\n }\n\n const rootSpan = getRootSpan(activeSpan);\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n\nfunction getParameterizedRoute(routerState: RouterState): string {\n const lastMatch = routerState.matches[routerState.matches.length - 1];\n return normalizePathname(lastMatch?.route.path ?? routerState.location.pathname);\n}\n\nfunction normalizePathname(pathname: string): string {\n // Ensure it starts with a single slash\n let normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n // Remove trailing slash unless it's the root\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sources":["../../../src/client/sdk.ts"],"sourcesContent":["import type { BrowserOptions } from '@sentry/browser';\nimport { init as browserInit } from '@sentry/browser';\nimport type { Client } from '@sentry/core';\nimport { applySdkMetadata, consoleSandbox, setTag } from '@sentry/core';\n\nconst BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\n/**\n * Initializes the client side of the React Router SDK.\n */\nexport function init(options: BrowserOptions): Client | undefined {\n // If BrowserTracing integration was passed to options, emit a warning\n if (options.integrations && Array.isArray(options.integrations)) {\n const hasBrowserTracing = options.integrations.some(\n integration => integration.name === BROWSER_TRACING_INTEGRATION_ID,\n );\n\n if (hasBrowserTracing) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n 'browserTracingIntegration is not fully compatible with @sentry/react-router. Please use reactRouterTracingIntegration instead.',\n );\n });\n }\n }\n\n applySdkMetadata(options, 'react-router', ['react-router', 'browser']);\n\n const client = browserInit(options);\n\n setTag('runtime', 'browser');\n\n return client;\n}\n"],"names":["browserInit"],"mappings":";;;AAKA,MAAM,8BAAA,GAAiC,gBAAgB;;AAEvD;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAsC;AAClE;AACA,EAAE,IAAI,OAAO,CAAC,gBAAgB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;AACnE,IAAI,MAAM,iBAAkB,GAAE,OAAO,CAAC,YAAY,CAAC,IAAI;AACvD,MAAM,eAAe,WAAW,CAAC,IAAA,KAAS,8BAA8B;AACxE,KAAK;;AAEL,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAM,cAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,IAAI;AACpB,UAAU,gIAAgI;AAC1I,SAAS;AACT,OAAO,CAAC;AACR;AACA;;AAEA,EAAE,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;;AAExE,EAAE,MAAM,MAAO,GAAEA,MAAW,CAAC,OAAO,CAAC;;AAErC,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;;AAE9B,EAAE,OAAO,MAAM;AACf;;;;"}
1
+ {"version":3,"file":"sdk.js","sources":["../../../src/client/sdk.ts"],"sourcesContent":["import type { BrowserOptions } from '@sentry/browser';\nimport { init as browserInit } from '@sentry/browser';\nimport type { Client } from '@sentry/core';\nimport { applySdkMetadata, consoleSandbox, setTag } from '@sentry/core';\n\nconst BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\n/**\n * Initializes the client side of the React Router SDK.\n */\nexport function init(options: BrowserOptions): Client | undefined {\n // If BrowserTracing integration was passed to options, emit a warning\n if (options.integrations && Array.isArray(options.integrations)) {\n const hasBrowserTracing = options.integrations.some(\n integration => integration.name === BROWSER_TRACING_INTEGRATION_ID,\n );\n\n if (hasBrowserTracing) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n 'browserTracingIntegration is not fully compatible with @sentry/react-router. Please use reactRouterTracingIntegration instead.',\n );\n });\n }\n }\n\n applySdkMetadata(options, 'react-router', ['react-router', 'browser']);\n\n const client = browserInit(options);\n\n setTag('runtime', 'browser');\n\n return client;\n}\n"],"names":["browserInit"],"mappings":";;;AAKA,MAAM,8BAAA,GAAiC,gBAAgB;;AAEvD;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAsC;AAClE;AACA,EAAE,IAAI,OAAO,CAAC,gBAAgB,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;AACnE,IAAI,MAAM,iBAAA,GAAoB,OAAO,CAAC,YAAY,CAAC,IAAI;AACvD,MAAM,eAAe,WAAW,CAAC,IAAA,KAAS,8BAA8B;AACxE,KAAK;;AAEL,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAM,cAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,IAAI;AACpB,UAAU,gIAAgI;AAC1I,SAAS;AACT,OAAO,CAAC;AACR;AACA;;AAEA,EAAE,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;;AAExE,EAAE,MAAM,MAAA,GAASA,MAAW,CAAC,OAAO,CAAC;;AAErC,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;;AAE9B,EAAE,OAAO,MAAM;AACf;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"debug-build.js","sources":["../../../src/common/debug-build.ts"],"sourcesContent":["declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n"],"names":[],"mappings":"AAEA;AACA;AACA;AACA;AACA;AACO,MAAM,WAAY,IAAiB,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;;;;"}
1
+ {"version":3,"file":"debug-build.js","sources":["../../../src/common/debug-build.ts"],"sourcesContent":["declare const __DEBUG_BUILD__: boolean;\n\n/**\n * This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.\n *\n * ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.\n */\nexport const DEBUG_BUILD = __DEBUG_BUILD__;\n"],"names":[],"mappings":"AAEA;AACA;AACA;AACA;AACA;AACO,MAAM,WAAA,IAAc,OAAA,gBAAA,KAAA,WAAA,IAAA,gBAAA;;;;"}
@@ -1 +1 @@
1
- {"type":"module","version":"9.36.0"}
1
+ {"type":"module","version":"9.38.0"}
@@ -1 +1 @@
1
- {"version":3,"file":"createSentryHandleRequest.js","sources":["../../../src/server/createSentryHandleRequest.tsx"],"sourcesContent":["import type { createReadableStreamFromReadable } from '@react-router/node';\nimport type { ReactNode } from 'react';\nimport React from 'react';\nimport type { AppLoadContext, EntryContext, ServerRouter } from 'react-router';\nimport { PassThrough } from 'stream';\nimport { getMetaTagTransformer, wrapSentryHandleRequest } from './wrapSentryHandleRequest';\n\ntype RenderToPipeableStreamOptions = {\n [key: string]: unknown;\n onShellReady?: () => void;\n onAllReady?: () => void;\n onShellError?: (error: unknown) => void;\n onError?: (error: unknown) => void;\n};\n\ntype RenderToPipeableStreamResult = {\n pipe: (destination: NodeJS.WritableStream) => void;\n abort: () => void;\n};\n\ntype RenderToPipeableStreamFunction = (\n node: ReactNode,\n options: RenderToPipeableStreamOptions,\n) => RenderToPipeableStreamResult;\n\nexport interface SentryHandleRequestOptions {\n /**\n * Timeout in milliseconds after which the rendering stream will be aborted\n * @default 10000\n */\n streamTimeout?: number;\n\n /**\n * React's renderToPipeableStream function from 'react-dom/server'\n */\n renderToPipeableStream: RenderToPipeableStreamFunction;\n\n /**\n * The <ServerRouter /> component from '@react-router/server'\n */\n ServerRouter: typeof ServerRouter;\n\n /**\n * createReadableStreamFromReadable from '@react-router/node'\n */\n createReadableStreamFromReadable: typeof createReadableStreamFromReadable;\n\n /**\n * Regular expression to identify bot user agents\n * @default /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i\n */\n botRegex?: RegExp;\n}\n\n/**\n * A complete Sentry-instrumented handleRequest implementation that handles both\n * route parametrization and trace meta tag injection.\n *\n * @param options Configuration options\n * @returns A Sentry-instrumented handleRequest function\n */\nexport function createSentryHandleRequest(\n options: SentryHandleRequestOptions,\n): (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown> {\n const {\n streamTimeout = 10000,\n renderToPipeableStream,\n ServerRouter,\n createReadableStreamFromReadable,\n botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i,\n } = options;\n\n const handleRequest = function handleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n _loadContext: AppLoadContext,\n ): Promise<Response> {\n return new Promise((resolve, reject) => {\n let shellRendered = false;\n const userAgent = request.headers.get('user-agent');\n\n // Determine if we should use onAllReady or onShellReady\n const isBot = typeof userAgent === 'string' && botRegex.test(userAgent);\n const isSpaMode = !!(routerContext as { isSpaMode?: boolean }).isSpaMode;\n\n const readyOption = isBot || isSpaMode ? 'onAllReady' : 'onShellReady';\n\n const { pipe, abort } = renderToPipeableStream(<ServerRouter context={routerContext} url={request.url} />, {\n [readyOption]() {\n shellRendered = true;\n const body = new PassThrough();\n\n const stream = createReadableStreamFromReadable(body);\n\n responseHeaders.set('Content-Type', 'text/html');\n\n resolve(\n new Response(stream, {\n headers: responseHeaders,\n status: responseStatusCode,\n }),\n );\n\n // this injects trace data to the HTML head\n pipe(getMetaTagTransformer(body));\n },\n onShellError(error: unknown) {\n reject(error);\n },\n onError(error: unknown) {\n // eslint-disable-next-line no-param-reassign\n responseStatusCode = 500;\n // Log streaming rendering errors from inside the shell. Don't log\n // errors encountered during initial shell rendering since they'll\n // reject and get logged in handleDocumentRequest.\n if (shellRendered) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n },\n });\n\n // Abort the rendering stream after the `streamTimeout`\n setTimeout(abort, streamTimeout);\n });\n };\n\n // Wrap the handle request function for request parametrization\n return wrapSentryHandleRequest(handleRequest);\n}\n"],"names":[],"mappings":";;;;AAsDA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,yBAAyB;AACzC,EAAE,OAAO;AACT;;AAMA,CAAsB;AACtB,EAAE,MAAM;AACR,IAAI,aAAA,GAAgB,KAAK;AACzB,IAAI,sBAAsB;AAC1B,IAAI,YAAY;AAChB,IAAI,gCAAgC;AACpC,IAAI,QAAA,GAAW,oFAAoF;AACnG,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,aAAA,GAAgB,SAAS,aAAa;AAC9C,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,YAAY;AAChB,IAAuB;AACvB,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC5C,MAAM,IAAI,aAAc,GAAE,KAAK;AAC/B,MAAM,MAAM,SAAU,GAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;;AAEzD;AACA,MAAM,MAAM,KAAA,GAAQ,OAAO,SAAU,KAAI,QAAS,IAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;AAC7E,MAAM,MAAM,YAAY,CAAC,CAAC,CAAC,aAAA,GAA0C,SAAS;;AAE9E,MAAM,MAAM,cAAc,KAAA,IAAS,SAAU,GAAE,YAAa,GAAE,cAAc;;AAE5E,MAAM,MAAM,EAAE,IAAI,EAAE,OAAQ,GAAE,sBAAsB,CAAC,KAAC,CAAA,aAAA,CAAA,YAAA,EAAA,EAAa,OAAO,EAAC,aAAc,EAAE,GAAG,EAAC,OAAQ,CAAC,GAAG,EAAE,EAAE,EAAE;AACjH,QAAQ,CAAC,WAAW,CAAC,GAAG;AACxB,UAAU,aAAA,GAAgB,IAAI;AAC9B,UAAU,MAAM,IAAK,GAAE,IAAI,WAAW,EAAE;;AAExC,UAAU,MAAM,MAAO,GAAE,gCAAgC,CAAC,IAAI,CAAC;;AAE/D,UAAU,eAAe,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC;;AAE1D,UAAU,OAAO;AACjB,YAAY,IAAI,QAAQ,CAAC,MAAM,EAAE;AACjC,cAAc,OAAO,EAAE,eAAe;AACtC,cAAc,MAAM,EAAE,kBAAkB;AACxC,aAAa,CAAC;AACd,WAAW;;AAEX;AACA,UAAU,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;AAC3C,SAAS;AACT,QAAQ,YAAY,CAAC,KAAK,EAAW;AACrC,UAAU,MAAM,CAAC,KAAK,CAAC;AACvB,SAAS;AACT,QAAQ,OAAO,CAAC,KAAK,EAAW;AAChC;AACA,UAAU,kBAAA,GAAqB,GAAG;AAClC;AACA;AACA;AACA,UAAU,IAAI,aAAa,EAAE;AAC7B;AACA,YAAY,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAChC;AACA,SAAS;AACT,OAAO,CAAC;;AAER;AACA,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC;AACtC,KAAK,CAAC;AACN,GAAG;;AAEH;AACA,EAAE,OAAO,uBAAuB,CAAC,aAAa,CAAC;AAC/C;;;;"}
1
+ {"version":3,"file":"createSentryHandleRequest.js","sources":["../../../src/server/createSentryHandleRequest.tsx"],"sourcesContent":["import type { createReadableStreamFromReadable } from '@react-router/node';\nimport type { ReactNode } from 'react';\nimport React from 'react';\nimport type { AppLoadContext, EntryContext, ServerRouter } from 'react-router';\nimport { PassThrough } from 'stream';\nimport { getMetaTagTransformer, wrapSentryHandleRequest } from './wrapSentryHandleRequest';\n\ntype RenderToPipeableStreamOptions = {\n [key: string]: unknown;\n onShellReady?: () => void;\n onAllReady?: () => void;\n onShellError?: (error: unknown) => void;\n onError?: (error: unknown) => void;\n};\n\ntype RenderToPipeableStreamResult = {\n pipe: (destination: NodeJS.WritableStream) => void;\n abort: () => void;\n};\n\ntype RenderToPipeableStreamFunction = (\n node: ReactNode,\n options: RenderToPipeableStreamOptions,\n) => RenderToPipeableStreamResult;\n\nexport interface SentryHandleRequestOptions {\n /**\n * Timeout in milliseconds after which the rendering stream will be aborted\n * @default 10000\n */\n streamTimeout?: number;\n\n /**\n * React's renderToPipeableStream function from 'react-dom/server'\n */\n renderToPipeableStream: RenderToPipeableStreamFunction;\n\n /**\n * The <ServerRouter /> component from '@react-router/server'\n */\n ServerRouter: typeof ServerRouter;\n\n /**\n * createReadableStreamFromReadable from '@react-router/node'\n */\n createReadableStreamFromReadable: typeof createReadableStreamFromReadable;\n\n /**\n * Regular expression to identify bot user agents\n * @default /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i\n */\n botRegex?: RegExp;\n}\n\n/**\n * A complete Sentry-instrumented handleRequest implementation that handles both\n * route parametrization and trace meta tag injection.\n *\n * @param options Configuration options\n * @returns A Sentry-instrumented handleRequest function\n */\nexport function createSentryHandleRequest(\n options: SentryHandleRequestOptions,\n): (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown> {\n const {\n streamTimeout = 10000,\n renderToPipeableStream,\n ServerRouter,\n createReadableStreamFromReadable,\n botRegex = /bot|crawler|spider|googlebot|chrome-lighthouse|baidu|bing|google|yahoo|lighthouse/i,\n } = options;\n\n const handleRequest = function handleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n _loadContext: AppLoadContext,\n ): Promise<Response> {\n return new Promise((resolve, reject) => {\n let shellRendered = false;\n const userAgent = request.headers.get('user-agent');\n\n // Determine if we should use onAllReady or onShellReady\n const isBot = typeof userAgent === 'string' && botRegex.test(userAgent);\n const isSpaMode = !!(routerContext as { isSpaMode?: boolean }).isSpaMode;\n\n const readyOption = isBot || isSpaMode ? 'onAllReady' : 'onShellReady';\n\n const { pipe, abort } = renderToPipeableStream(<ServerRouter context={routerContext} url={request.url} />, {\n [readyOption]() {\n shellRendered = true;\n const body = new PassThrough();\n\n const stream = createReadableStreamFromReadable(body);\n\n responseHeaders.set('Content-Type', 'text/html');\n\n resolve(\n new Response(stream, {\n headers: responseHeaders,\n status: responseStatusCode,\n }),\n );\n\n // this injects trace data to the HTML head\n pipe(getMetaTagTransformer(body));\n },\n onShellError(error: unknown) {\n reject(error);\n },\n onError(error: unknown) {\n // eslint-disable-next-line no-param-reassign\n responseStatusCode = 500;\n // Log streaming rendering errors from inside the shell. Don't log\n // errors encountered during initial shell rendering since they'll\n // reject and get logged in handleDocumentRequest.\n if (shellRendered) {\n // eslint-disable-next-line no-console\n console.error(error);\n }\n },\n });\n\n // Abort the rendering stream after the `streamTimeout`\n setTimeout(abort, streamTimeout);\n });\n };\n\n // Wrap the handle request function for request parametrization\n return wrapSentryHandleRequest(handleRequest);\n}\n"],"names":[],"mappings":";;;;AAsDA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,yBAAyB;AACzC,EAAE,OAAO;AACT;;AAMA,CAAsB;AACtB,EAAE,MAAM;AACR,IAAI,aAAA,GAAgB,KAAK;AACzB,IAAI,sBAAsB;AAC1B,IAAI,YAAY;AAChB,IAAI,gCAAgC;AACpC,IAAI,QAAA,GAAW,oFAAoF;AACnG,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,aAAA,GAAgB,SAAS,aAAa;AAC9C,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,YAAY;AAChB,IAAuB;AACvB,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;AAC5C,MAAM,IAAI,aAAA,GAAgB,KAAK;AAC/B,MAAM,MAAM,SAAA,GAAY,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;;AAEzD;AACA,MAAM,MAAM,KAAA,GAAQ,OAAO,SAAA,KAAc,QAAA,IAAY,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;AAC7E,MAAM,MAAM,YAAY,CAAC,CAAC,CAAC,aAAA,GAA0C,SAAS;;AAE9E,MAAM,MAAM,cAAc,KAAA,IAAS,SAAA,GAAY,YAAA,GAAe,cAAc;;AAE5E,MAAM,MAAM,EAAE,IAAI,EAAE,OAAM,GAAI,sBAAsB,CAAC,KAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,OAAO,EAAC,aAAc,EAAE,GAAG,EAAC,OAAQ,CAAC,GAAG,EAAA,EAAI,EAAE;AACjH,QAAQ,CAAC,WAAW,CAAC,GAAG;AACxB,UAAU,aAAA,GAAgB,IAAI;AAC9B,UAAU,MAAM,IAAA,GAAO,IAAI,WAAW,EAAE;;AAExC,UAAU,MAAM,MAAA,GAAS,gCAAgC,CAAC,IAAI,CAAC;;AAE/D,UAAU,eAAe,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC;;AAE1D,UAAU,OAAO;AACjB,YAAY,IAAI,QAAQ,CAAC,MAAM,EAAE;AACjC,cAAc,OAAO,EAAE,eAAe;AACtC,cAAc,MAAM,EAAE,kBAAkB;AACxC,aAAa,CAAC;AACd,WAAW;;AAEX;AACA,UAAU,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;AAC3C,SAAS;AACT,QAAQ,YAAY,CAAC,KAAK,EAAW;AACrC,UAAU,MAAM,CAAC,KAAK,CAAC;AACvB,SAAS;AACT,QAAQ,OAAO,CAAC,KAAK,EAAW;AAChC;AACA,UAAU,kBAAA,GAAqB,GAAG;AAClC;AACA;AACA;AACA,UAAU,IAAI,aAAa,EAAE;AAC7B;AACA,YAAY,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;AAChC;AACA,SAAS;AACT,OAAO,CAAC;;AAER;AACA,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC;AACtC,KAAK,CAAC;AACN,GAAG;;AAEH;AACA,EAAE,OAAO,uBAAuB,CAAC,aAAa,CAAC;AAC/C;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport {\n getActiveSpan,\n getRootSpan,\n logger,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest, SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch (error) {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && logger.debug('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // Set the source and overwrite attributes on the root span to ensure the transaction name\n // is derived from the raw URL pathname rather than any parameterized route that may be set later\n // TODO: try to set derived parameterized route from build here (args[0])\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${request.method} ${url.pathname}`,\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":[],"mappings":";;;;;AAkBA,MAAM,iBAAkB,GAAE,CAAC,SAAS,CAAC;AACrC,MAAM,SAAA,GAAY,cAAc;;AAEhC;AACA;AACA;AACA;AACO,MAAM,0BAAA,SAAmC,mBAAmB,CAAwB;AAC3F,GAAS,WAAW,CAAC,MAAM,GAA0B,EAAE,EAAE;AACzD,IAAI,KAAK,CAAC,4BAA4B,EAAE,WAAW,EAAE,MAAM,CAAC;AAC5D;;AAEA;AACA;AACA;AACA;AACA,GAAY,IAAI,GAAwC;AACxD,IAAI,MAAM,uBAAA,GAA0B,IAAI,mCAAmC;AAC3E,MAAM,SAAS;AACf,MAAM,iBAAiB;AACvB,MAAM,CAAC,aAAa,KAA+B;AACnD,QAAQ,OAAO,IAAI,CAAC,yBAAyB,CAAC,aAAa,CAAC;AAC5D,OAAO;AACP,MAAM,CAAC,cAAc,KAAc;AACnC;AACA,QAAQ,OAAO,cAAc;AAC7B,OAAO;AACP,KAAK;;AAEL,IAAI,OAAO,uBAAuB;AAClC;;AAEA;AACA;AACA;AACA;AACA,GAAU,yBAAyB,CAAC,aAAa,EAAsD;AACvG,IAAI,OAAO,IAAI,KAAK,CAAC,aAAa,EAAE;AACpC,MAAM,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;AAClC,QAAQ,IAAI,IAAK,KAAI,sBAAsB,EAAE;AAC7C,UAAU,MAAM,QAAS,GAAE,MAAM,CAAC,IAAI,CAAC;AACvC,UAAU,OAAO,SAAS,iCAAiC,EAAgB,GAAG,IAAI,EAAa;AAC/F,YAAY,MAAM,sBAAuB,GAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;;AAErE,YAAY,OAAO,eAAe,2BAA2B,CAAC,OAAO,EAAW,cAAc,EAAY;AAC1G,cAAc,IAAI,GAAG;AACrB,cAAc,IAAI;AAClB,gBAAgB,GAAA,GAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;AAC1C,eAAgB,CAAA,OAAO,KAAK,EAAE;AAC9B,gBAAgB,OAAO,sBAAsB,CAAC,OAAO,EAAE,cAAc,CAAC;AACtE;;AAEA;AACA,cAAc,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAChD,gBAAgB,OAAO,sBAAsB,CAAC,OAAO,EAAE,cAAc,CAAC;AACtE;;AAEA,cAAc,MAAM,UAAA,GAAa,aAAa,EAAE;AAChD,cAAc,MAAM,WAAW,UAAA,IAAc,WAAW,CAAC,UAAU,CAAC;;AAEpE,cAAc,IAAI,CAAC,QAAQ,EAAE;AAC7B,gBAAgB,eAAe,MAAM,CAAC,KAAK,CAAC,8DAA8D,CAAC;AAC3G,gBAAgB,OAAO,sBAAsB,CAAC,OAAO,EAAE,cAAc,CAAC;AACtE;;AAEA;AACA;AACA;AACA,cAAc,QAAQ,CAAC,aAAa,CAAC;AACrC,gBAAgB,CAAC,gCAAgC,GAAG,KAAK;AACzD,gBAAgB,CAAC,mCAAmC,GAAG,CAAC,EAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,eAAA,CAAA;;AAEA,cAAA,OAAA,SAAA;AACA,gBAAA;AACA,kBAAA,IAAA,EAAA,WAAA,CAAA,GAAA,CAAA,QAAA,EAAA,OAAA,CAAA,MAAA,CAAA;AACA,kBAAA,UAAA,EAAA;AACA,oBAAA,CAAA,gCAAA,GAAA,wBAAA;AACA,oBAAA,CAAA,4BAAA,GAAA,SAAA,CAAA,GAAA,CAAA,QAAA,EAAA,OAAA,CAAA,MAAA,CAAA;AACA,mBAAA;AACA,iBAAA;AACA,gBAAA,MAAA;AACA,kBAAA,OAAA,sBAAA,CAAA,OAAA,EAAA,cAAA,CAAA;AACA,iBAAA;AACA,eAAA;AACA,aAAA;AACA,WAAA;AACA;AACA,QAAA,OAAA,OAAA,CAAA,GAAA,CAAA,MAAA,EAAA,IAAA,EAAA,QAAA,CAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA;AACA;;;;"}
1
+ {"version":3,"file":"reactRouter.js","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"sourcesContent":["import type { InstrumentationConfig } from '@opentelemetry/instrumentation';\nimport { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';\nimport {\n getActiveSpan,\n getRootSpan,\n logger,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n startSpan,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { getOpName, getSpanName, isDataRequest, SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './util';\n\ntype ReactRouterModuleExports = typeof reactRouter;\n\nconst supportedVersions = ['>=7.0.0'];\nconst COMPONENT = 'react-router';\n\n/**\n * Instrumentation for React Router's server request handler.\n * This patches the requestHandler function to add Sentry performance monitoring for data loaders.\n */\nexport class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {\n public constructor(config: InstrumentationConfig = {}) {\n super('ReactRouterInstrumentation', SDK_VERSION, config);\n }\n\n /**\n * Initializes the instrumentation by defining the React Router server modules to be patched.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n protected init(): InstrumentationNodeModuleDefinition {\n const reactRouterServerModule = new InstrumentationNodeModuleDefinition(\n COMPONENT,\n supportedVersions,\n (moduleExports: ReactRouterModuleExports) => {\n return this._createPatchedModuleProxy(moduleExports);\n },\n (_moduleExports: unknown) => {\n // nothing to unwrap here\n return _moduleExports;\n },\n );\n\n return reactRouterServerModule;\n }\n\n /**\n * Creates a proxy around the React Router module exports that patches the createRequestHandler function.\n * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.\n */\n private _createPatchedModuleProxy(moduleExports: ReactRouterModuleExports): ReactRouterModuleExports {\n return new Proxy(moduleExports, {\n get(target, prop, receiver) {\n if (prop === 'createRequestHandler') {\n const original = target[prop];\n return function sentryWrappedCreateRequestHandler(this: unknown, ...args: unknown[]) {\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n let url: URL;\n try {\n url = new URL(request.url);\n } catch (error) {\n return originalRequestHandler(request, initialContext);\n }\n\n // We currently just want to trace loaders and actions\n if (!isDataRequest(url.pathname)) {\n return originalRequestHandler(request, initialContext);\n }\n\n const activeSpan = getActiveSpan();\n const rootSpan = activeSpan && getRootSpan(activeSpan);\n\n if (!rootSpan) {\n DEBUG_BUILD && logger.debug('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // Set the source and overwrite attributes on the root span to ensure the transaction name\n // is derived from the raw URL pathname rather than any parameterized route that may be set later\n // TODO: try to set derived parameterized route from build here (args[0])\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${request.method} ${url.pathname}`,\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method),\n },\n },\n () => {\n return originalRequestHandler(request, initialContext);\n },\n );\n };\n };\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sources":["../../../../src/server/instrumentation/util.ts"],"sourcesContent":["/**\n * Gets the op name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getOpName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'function.react-router.loader'\n : isActionRequest(pathName, requestMethod)\n ? 'function.react-router.action'\n : 'function.react-router';\n}\n\n/**\n * Gets the span name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getSpanName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'Executing Server Loader'\n : isActionRequest(pathName, requestMethod)\n ? 'Executing Server Action'\n : 'Unknown Data Request';\n}\n\n/**\n * Checks if the request is a server loader request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isLoaderRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'GET';\n}\n\n/**\n * Checks if the request is a server action request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isActionRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'POST';\n}\n\n/**\n * Checks if the request is a react-router data request\n * @param pathname The URL pathname to check\n */\nexport function isDataRequest(pathname: string): boolean {\n return pathname.endsWith('.data');\n}\n\nexport const SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE = 'sentry.overwrite-route';\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC3E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,uBAAuB;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC7E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,sBAAsB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,KAAK;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,MAAM;AAC5D;;AAEA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,QAAQ,EAAmB;AACzD,EAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AACnC;;AAEO,MAAM,mCAAoC,GAAE;;;;"}
1
+ {"version":3,"file":"util.js","sources":["../../../../src/server/instrumentation/util.ts"],"sourcesContent":["/**\n * Gets the op name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getOpName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'function.react-router.loader'\n : isActionRequest(pathName, requestMethod)\n ? 'function.react-router.action'\n : 'function.react-router';\n}\n\n/**\n * Gets the span name for a request based on whether it's a loader or action request.\n * @param pathName The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function getSpanName(pathName: string, requestMethod: string): string {\n return isLoaderRequest(pathName, requestMethod)\n ? 'Executing Server Loader'\n : isActionRequest(pathName, requestMethod)\n ? 'Executing Server Action'\n : 'Unknown Data Request';\n}\n\n/**\n * Checks if the request is a server loader request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isLoaderRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'GET';\n}\n\n/**\n * Checks if the request is a server action request\n * @param pathname The URL pathname to check\n * @param requestMethod The HTTP request method\n */\nexport function isActionRequest(pathname: string, requestMethod: string): boolean {\n return isDataRequest(pathname) && requestMethod === 'POST';\n}\n\n/**\n * Checks if the request is a react-router data request\n * @param pathname The URL pathname to check\n */\nexport function isDataRequest(pathname: string): boolean {\n return pathname.endsWith('.data');\n}\n\nexport const SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE = 'sentry.overwrite-route';\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACO,SAAS,SAAS,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC3E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,uBAAuB;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,QAAQ,EAAU,aAAa,EAAkB;AAC7E,EAAE,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa;AAChD,MAAM;AACN,MAAM,eAAe,CAAC,QAAQ,EAAE,aAAa;AAC7C,QAAQ;AACR,QAAQ,sBAAsB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,KAAK;AAC3D;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,QAAQ,EAAU,aAAa,EAAmB;AAClF,EAAE,OAAO,aAAa,CAAC,QAAQ,KAAK,aAAA,KAAkB,MAAM;AAC5D;;AAEA;AACA;AACA;AACA;AACO,SAAS,aAAa,CAAC,QAAQ,EAAmB;AACzD,EAAE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;AACnC;;AAEO,MAAM,mCAAA,GAAsC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint, defineIntegration, logger } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node';\n\n/**\n * Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/\n *\n */\n\nfunction _lowQualityTransactionsFilterIntegration(options: NodeOptions): {\n name: string;\n processEvent: (event: Event, hint: EventHint, client: Client) => Event | null;\n} {\n const matchedRegexes = [/GET \\/node_modules\\//, /GET \\/favicon\\.ico/, /GET \\/@id\\//, /GET \\/__manifest\\?/];\n\n return {\n name: 'LowQualityTransactionsFilter',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event | null {\n if (event.type !== 'transaction' || !event.transaction) {\n return event;\n }\n\n const transaction = event.transaction;\n\n if (matchedRegexes.some(regex => transaction.match(regex))) {\n options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);\n return null;\n }\n\n return event;\n },\n };\n}\n\nexport const lowQualityTransactionsFilterIntegration = defineIntegration((options: NodeOptions) =>\n _lowQualityTransactionsFilterIntegration(options),\n);\n"],"names":[],"mappings":";;AAGA;AACA;AACA;AACA;;AAEA,SAAS,wCAAwC,CAAC,OAAO;;AAGzD,CAAE;AACF,EAAE,MAAM,cAAe,GAAE,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,aAAa,EAAE,oBAAoB,CAAC;;AAE5G,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,8BAA8B;;AAExC,IAAI,YAAY,CAAC,KAAK,EAAS,KAAK,EAAa,OAAO,EAAwB;AAChF,MAAM,IAAI,KAAK,CAAC,IAAK,KAAI,aAAc,IAAG,CAAC,KAAK,CAAC,WAAW,EAAE;AAC9D,QAAQ,OAAO,KAAK;AACpB;;AAEA,MAAM,MAAM,WAAA,GAAc,KAAK,CAAC,WAAW;;AAE3C,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,KAAA,IAAS,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;AAClE,QAAQ,OAAO,CAAC,KAAM,IAAG,MAAM,CAAC,GAAG,CAAC,kDAAkD,EAAE,KAAK,CAAC,WAAW,CAAC;AAC1G,QAAQ,OAAO,IAAI;AACnB;;AAEA,MAAM,OAAO,KAAK;AAClB,KAAK;AACL,GAAG;AACH;;MAEa,uCAAwC,GAAE,iBAAiB,CAAC,CAAC,OAAO;AACjF,EAAE,wCAAwC,CAAC,OAAO,CAAC;AACnD;;;;"}
1
+ {"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint, defineIntegration, logger } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node';\n\n/**\n * Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/\n *\n */\n\nfunction _lowQualityTransactionsFilterIntegration(options: NodeOptions): {\n name: string;\n processEvent: (event: Event, hint: EventHint, client: Client) => Event | null;\n} {\n const matchedRegexes = [/GET \\/node_modules\\//, /GET \\/favicon\\.ico/, /GET \\/@id\\//, /GET \\/__manifest\\?/];\n\n return {\n name: 'LowQualityTransactionsFilter',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event | null {\n if (event.type !== 'transaction' || !event.transaction) {\n return event;\n }\n\n const transaction = event.transaction;\n\n if (matchedRegexes.some(regex => transaction.match(regex))) {\n options.debug && logger.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);\n return null;\n }\n\n return event;\n },\n };\n}\n\nexport const lowQualityTransactionsFilterIntegration = defineIntegration((options: NodeOptions) =>\n _lowQualityTransactionsFilterIntegration(options),\n);\n"],"names":[],"mappings":";;AAGA;AACA;AACA;AACA;;AAEA,SAAS,wCAAwC,CAAC,OAAO;;AAGzD,CAAE;AACF,EAAE,MAAM,cAAA,GAAiB,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,aAAa,EAAE,oBAAoB,CAAC;;AAE5G,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,8BAA8B;;AAExC,IAAI,YAAY,CAAC,KAAK,EAAS,KAAK,EAAa,OAAO,EAAwB;AAChF,MAAM,IAAI,KAAK,CAAC,IAAA,KAAS,aAAA,IAAiB,CAAC,KAAK,CAAC,WAAW,EAAE;AAC9D,QAAQ,OAAO,KAAK;AACpB;;AAEA,MAAM,MAAM,WAAA,GAAc,KAAK,CAAC,WAAW;;AAE3C,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,KAAA,IAAS,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;AAClE,QAAQ,OAAO,CAAC,KAAA,IAAS,MAAM,CAAC,GAAG,CAAC,kDAAkD,EAAE,KAAK,CAAC,WAAW,CAAC;AAC1G,QAAQ,OAAO,IAAI;AACnB;;AAEA,MAAM,OAAO,KAAK;AAClB,KAAK;AACL,GAAG;AACH;;MAEa,uCAAA,GAA0C,iBAAiB,CAAC,CAAC,OAAO;AACjF,EAAE,wCAAwC,CAAC,OAAO,CAAC;AACnD;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactRouterServer.js","sources":["../../../../src/server/integration/reactRouterServer.ts"],"sourcesContent":["import { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node';\nimport { ReactRouterInstrumentation } from '../instrumentation/reactRouter';\n\nconst INTEGRATION_NAME = 'ReactRouterServer';\n\nconst instrumentReactRouter = generateInstrumentOnce('React-Router-Server', () => {\n return new ReactRouterInstrumentation();\n});\n\nexport const instrumentReactRouterServer = Object.assign(\n (): void => {\n instrumentReactRouter();\n },\n { id: INTEGRATION_NAME },\n);\n\n/**\n * Integration capturing tracing data for React Router server functions.\n */\nexport const reactRouterServerIntegration = defineIntegration(() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentReactRouterServer();\n },\n };\n});\n"],"names":[],"mappings":";;;;AAIA,MAAM,gBAAA,GAAmB,mBAAmB;;AAE5C,MAAM,qBAAA,GAAwB,sBAAsB,CAAC,qBAAqB,EAAE,MAAM;AAClF,EAAE,OAAO,IAAI,0BAA0B,EAAE;AACzC,CAAC,CAAC;;AAEW,MAAA,2BAAA,GAA8B,MAAM,CAAC,MAAM;AACxD,EAAE,MAAY;AACd,IAAI,qBAAqB,EAAE;AAC3B,GAAG;AACH,EAAE,EAAE,EAAE,EAAE,gBAAA,EAAkB;AAC1B;;AAEA;AACA;AACA;MACa,4BAA6B,GAAE,iBAAiB,CAAC,MAAM;AACpE,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,2BAA2B,EAAE;AACnC,KAAK;AACL,GAAG;AACH,CAAC;;;;"}
1
+ {"version":3,"file":"reactRouterServer.js","sources":["../../../../src/server/integration/reactRouterServer.ts"],"sourcesContent":["import { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce } from '@sentry/node';\nimport { ReactRouterInstrumentation } from '../instrumentation/reactRouter';\n\nconst INTEGRATION_NAME = 'ReactRouterServer';\n\nconst instrumentReactRouter = generateInstrumentOnce('React-Router-Server', () => {\n return new ReactRouterInstrumentation();\n});\n\nexport const instrumentReactRouterServer = Object.assign(\n (): void => {\n instrumentReactRouter();\n },\n { id: INTEGRATION_NAME },\n);\n\n/**\n * Integration capturing tracing data for React Router server functions.\n */\nexport const reactRouterServerIntegration = defineIntegration(() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentReactRouterServer();\n },\n };\n});\n"],"names":[],"mappings":";;;;AAIA,MAAM,gBAAA,GAAmB,mBAAmB;;AAE5C,MAAM,qBAAA,GAAwB,sBAAsB,CAAC,qBAAqB,EAAE,MAAM;AAClF,EAAE,OAAO,IAAI,0BAA0B,EAAE;AACzC,CAAC,CAAC;;AAEK,MAAM,2BAAA,GAA8B,MAAM,CAAC,MAAM;AACxD,EAAE,MAAY;AACd,IAAI,qBAAqB,EAAE;AAC3B,GAAG;AACH,EAAE,EAAE,EAAE,EAAE,gBAAA,EAAkB;AAC1B;;AAEA;AACA;AACA;MACa,4BAAA,GAA+B,iBAAiB,CAAC,MAAM;AACpE,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,2BAA2B,EAAE;AACnC,KAAK;AACL,GAAG;AACH,CAAC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type { EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, getGlobalScope, logger, setTag } from '@sentry/core';\nimport type { NodeClient, NodeOptions } from '@sentry/node';\nimport { getDefaultIntegrations as getNodeDefaultIntegrations, init as initNodeSdk, NODE_VERSION } from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\nimport { lowQualityTransactionsFilterIntegration } from './integration/lowQualityTransactionsFilterIntegration';\nimport { reactRouterServerIntegration } from './integration/reactRouterServer';\n\n/**\n * Returns the default integrations for the React Router SDK.\n * @param options The options for the SDK.\n */\nexport function getDefaultReactRouterServerIntegrations(options: NodeOptions): Integration[] {\n const integrations = [...getNodeDefaultIntegrations(options), lowQualityTransactionsFilterIntegration(options)];\n\n if (\n (NODE_VERSION.major === 20 && NODE_VERSION.minor < 19) || // https://nodejs.org/en/blog/release/v20.19.0\n (NODE_VERSION.major === 22 && NODE_VERSION.minor < 12) // https://nodejs.org/en/blog/release/v22.12.0\n ) {\n integrations.push(reactRouterServerIntegration());\n }\n\n return integrations;\n}\n\n/**\n * Initializes the server side of the React Router SDK\n */\nexport function init(options: NodeOptions): NodeClient | undefined {\n const opts: NodeOptions = {\n ...options,\n defaultIntegrations: getDefaultReactRouterServerIntegrations(options),\n };\n\n DEBUG_BUILD && logger.log('Initializing SDK...');\n\n applySdkMetadata(opts, 'react-router', ['react-router', 'node']);\n\n const client = initNodeSdk(opts);\n\n setTag('runtime', 'node');\n\n // Overwrite the transaction name for instrumented data loaders because the trace data gets overwritten at a later point.\n // We only update the tx in case SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE got set in our instrumentation before.\n getGlobalScope().addEventProcessor(\n Object.assign(\n (event => {\n const overwrite = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n if (\n event.type === 'transaction' &&\n (event.transaction === 'GET *' || event.transaction === 'POST *') &&\n event.contexts?.trace?.data?.[ATTR_HTTP_ROUTE] === '*' &&\n overwrite\n ) {\n event.transaction = overwrite;\n event.contexts.trace.data[ATTR_HTTP_ROUTE] = 'url';\n }\n\n // always yeet this attribute into the void, as this should not reach the server\n delete event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n\n return event;\n }) satisfies EventProcessor,\n { id: 'ReactRouterTransactionEnhancer' },\n ),\n );\n\n DEBUG_BUILD && logger.log('SDK successfully initialized');\n\n return client;\n}\n"],"names":["getNodeDefaultIntegrations","initNodeSdk"],"mappings":";;;;;;;;AAUA;AACA;AACA;AACA;AACO,SAAS,uCAAuC,CAAC,OAAO,EAA8B;AAC7F,EAAE,MAAM,YAAA,GAAe,CAAC,GAAGA,sBAA0B,CAAC,OAAO,CAAC,EAAE,uCAAuC,CAAC,OAAO,CAAC,CAAC;;AAEjH,EAAE;AACF,IAAI,CAAC,YAAY,CAAC,KAAA,KAAU,EAAA,IAAM,YAAY,CAAC,KAAA,GAAQ,EAAE;AACzD,KAAK,YAAY,CAAC,KAAM,KAAI,EAAG,IAAG,YAAY,CAAC,KAAM,GAAE,EAAE,CAAA;AACzD,IAAI;AACJ,IAAI,YAAY,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC;AACrD;;AAEA,EAAE,OAAO,YAAY;AACrB;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAuC;AACnE,EAAE,MAAM,IAAI,GAAgB;AAC5B,IAAI,GAAG,OAAO;AACd,IAAI,mBAAmB,EAAE,uCAAuC,CAAC,OAAO,CAAC;AACzE,GAAG;;AAEH,EAAE,eAAe,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC;;AAElD,EAAE,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;;AAElE,EAAE,MAAM,MAAO,GAAEC,MAAW,CAAC,IAAI,CAAC;;AAElC,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC;;AAE3B;AACA;AACA,EAAE,cAAc,EAAE,CAAC,iBAAiB;AACpC,IAAI,MAAM,CAAC,MAAM;AACjB,OAAO,SAAS;AAChB,QAAQ,MAAM,SAAA,GAAY,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAG,mCAAmC,CAAC;AAC5F,QAAQ;AACR,UAAU,KAAK,CAAC,IAAK,KAAI,aAAc;AACvC,WAAW,KAAK,CAAC,WAAA,KAAgB,OAAA,IAAW,KAAK,CAAC,WAAA,KAAgB,QAAQ,CAAE;AAC5E,UAAU,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAG,eAAe,CAAE,KAAI,GAAI;AACjE,UAAU;AACV,UAAU;AACV,UAAU,KAAK,CAAC,WAAY,GAAE,SAAS;AACvC,UAAU,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAE,GAAE,KAAK;AAC5D;;AAEA;AACA,QAAQ,OAAO,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAG,mCAAmC,CAAC;;AAEjF,QAAQ,OAAO,KAAK;AACpB,OAAO;AACP,MAAM,EAAE,EAAE,EAAE,gCAAA,EAAkC;AAC9C,KAAK;AACL,GAAG;;AAEH,EAAE,eAAe,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC;;AAE3D,EAAE,OAAO,MAAM;AACf;;;;"}
1
+ {"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type { EventProcessor, Integration } from '@sentry/core';\nimport { applySdkMetadata, getGlobalScope, logger, setTag } from '@sentry/core';\nimport type { NodeClient, NodeOptions } from '@sentry/node';\nimport { getDefaultIntegrations as getNodeDefaultIntegrations, init as initNodeSdk, NODE_VERSION } from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\nimport { lowQualityTransactionsFilterIntegration } from './integration/lowQualityTransactionsFilterIntegration';\nimport { reactRouterServerIntegration } from './integration/reactRouterServer';\n\n/**\n * Returns the default integrations for the React Router SDK.\n * @param options The options for the SDK.\n */\nexport function getDefaultReactRouterServerIntegrations(options: NodeOptions): Integration[] {\n const integrations = [...getNodeDefaultIntegrations(options), lowQualityTransactionsFilterIntegration(options)];\n\n if (\n (NODE_VERSION.major === 20 && NODE_VERSION.minor < 19) || // https://nodejs.org/en/blog/release/v20.19.0\n (NODE_VERSION.major === 22 && NODE_VERSION.minor < 12) // https://nodejs.org/en/blog/release/v22.12.0\n ) {\n integrations.push(reactRouterServerIntegration());\n }\n\n return integrations;\n}\n\n/**\n * Initializes the server side of the React Router SDK\n */\nexport function init(options: NodeOptions): NodeClient | undefined {\n const opts: NodeOptions = {\n ...options,\n defaultIntegrations: getDefaultReactRouterServerIntegrations(options),\n };\n\n DEBUG_BUILD && logger.log('Initializing SDK...');\n\n applySdkMetadata(opts, 'react-router', ['react-router', 'node']);\n\n const client = initNodeSdk(opts);\n\n setTag('runtime', 'node');\n\n // Overwrite the transaction name for instrumented data loaders because the trace data gets overwritten at a later point.\n // We only update the tx in case SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE got set in our instrumentation before.\n getGlobalScope().addEventProcessor(\n Object.assign(\n (event => {\n const overwrite = event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n if (\n event.type === 'transaction' &&\n (event.transaction === 'GET *' || event.transaction === 'POST *') &&\n event.contexts?.trace?.data?.[ATTR_HTTP_ROUTE] === '*' &&\n overwrite\n ) {\n event.transaction = overwrite;\n event.contexts.trace.data[ATTR_HTTP_ROUTE] = 'url';\n }\n\n // always yeet this attribute into the void, as this should not reach the server\n delete event.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE];\n\n return event;\n }) satisfies EventProcessor,\n { id: 'ReactRouterTransactionEnhancer' },\n ),\n );\n\n DEBUG_BUILD && logger.log('SDK successfully initialized');\n\n return client;\n}\n"],"names":["getNodeDefaultIntegrations","initNodeSdk"],"mappings":";;;;;;;;AAUA;AACA;AACA;AACA;AACO,SAAS,uCAAuC,CAAC,OAAO,EAA8B;AAC7F,EAAE,MAAM,YAAA,GAAe,CAAC,GAAGA,sBAA0B,CAAC,OAAO,CAAC,EAAE,uCAAuC,CAAC,OAAO,CAAC,CAAC;;AAEjH,EAAE;AACF,IAAI,CAAC,YAAY,CAAC,KAAA,KAAU,EAAA,IAAM,YAAY,CAAC,KAAA,GAAQ,EAAE;AACzD,KAAK,YAAY,CAAC,KAAA,KAAU,EAAA,IAAM,YAAY,CAAC,KAAA,GAAQ,EAAE,CAAA;AACzD,IAAI;AACJ,IAAI,YAAY,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC;AACrD;;AAEA,EAAE,OAAO,YAAY;AACrB;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAuC;AACnE,EAAE,MAAM,IAAI,GAAgB;AAC5B,IAAI,GAAG,OAAO;AACd,IAAI,mBAAmB,EAAE,uCAAuC,CAAC,OAAO,CAAC;AACzE,GAAG;;AAEH,EAAE,eAAe,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC;;AAElD,EAAE,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;;AAElE,EAAE,MAAM,MAAA,GAASC,MAAW,CAAC,IAAI,CAAC;;AAElC,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC;;AAE3B;AACA;AACA,EAAE,cAAc,EAAE,CAAC,iBAAiB;AACpC,IAAI,MAAM,CAAC,MAAM;AACjB,OAAO,SAAS;AAChB,QAAQ,MAAM,SAAA,GAAY,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAG,mCAAmC,CAAC;AAC5F,QAAQ;AACR,UAAU,KAAK,CAAC,IAAA,KAAS,aAAA;AACzB,WAAW,KAAK,CAAC,WAAA,KAAgB,OAAA,IAAW,KAAK,CAAC,WAAA,KAAgB,QAAQ,CAAA;AAC1E,UAAU,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAG,eAAe,CAAA,KAAM,GAAA;AAC7D,UAAU;AACV,UAAU;AACV,UAAU,KAAK,CAAC,WAAA,GAAc,SAAS;AACvC,UAAU,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAA,GAAI,KAAK;AAC5D;;AAEA;AACA,QAAQ,OAAO,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,GAAG,mCAAmC,CAAC;;AAEjF,QAAQ,OAAO,KAAK;AACpB,OAAO;AACP,MAAM,EAAE,EAAE,EAAE,gCAAA,EAAkC;AAC9C,KAAK;AACL,GAAG;;AAEH,EAAE,eAAe,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC;;AAE3D,EAAE,OAAO,MAAM;AACf;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n getActiveSpan,\n getRootSpan,\n getTraceMetaTags,\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext } from 'react-router';\nimport type { PassThrough } from 'stream';\nimport { Transform } from 'stream';\n\ntype OriginalHandleRequest = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(originalHandle: OriginalHandleRequest): OriginalHandleRequest {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n if (parameterizedPath) {\n const activeSpan = getActiveSpan();\n if (activeSpan) {\n const rootSpan = getRootSpan(activeSpan);\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: `${request.method} ${routeName}`,\n });\n }\n }\n\n return originalHandle(request, responseStatusCode, responseHeaders, routerContext, loadContext);\n };\n}\n\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n\n/**\n * Injects Sentry trace meta tags into the HTML response by piping through a transform stream.\n * This enables distributed tracing by adding trace context to the HTML document head.\n *\n * @param body - PassThrough stream containing the HTML response body to modify\n */\nexport function getMetaTagTransformer(body: PassThrough): Transform {\n const headClosingTag = '</head>';\n const htmlMetaTagTransformer = new Transform({\n transform(chunk, _encoding, callback) {\n const html = Buffer.isBuffer(chunk) ? chunk.toString() : String(chunk);\n if (html.includes(headClosingTag)) {\n const modifiedHtml = html.replace(headClosingTag, `${getTraceMetaTags()}${headClosingTag}`);\n callback(null, modifiedHtml);\n return;\n }\n callback(null, chunk);\n },\n });\n htmlMetaTagTransformer.pipe(body);\n return htmlMetaTagTransformer;\n}\n"],"names":[],"mappings":";;;;;;AAsBA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,cAAc,EAAgD;AACtG,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAkB;AAC5B,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAM,MAAM,UAAA,GAAa,aAAa,EAAE;AACxC,MAAM,IAAI,UAAU,EAAE;AACtB,QAAQ,MAAM,QAAS,GAAE,WAAW,CAAC,UAAU,CAAC;AAChD,QAAQ,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,QAAA,MAAA,WAAA,GAAA,cAAA,CAAA,OAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,QAAA,IAAA,WAAA,EAAA,IAAA,KAAA,OAAA,CAAA,IAAA,EAAA;AACA,UAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA;;AAEA;AACA,QAAA,QAAA,CAAA,aAAA,CAAA;AACA,UAAA,CAAA,eAAA,GAAA,SAAA;AACA,UAAA,CAAA,gCAAA,GAAA,OAAA;AACA,UAAA,CAAA,0CAAA,GAAA,CAAA,EAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,SAAA,CAAA;AACA;AACA;;AAEA,IAAA,OAAA,cAAA,CAAA,OAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,aAAA,EAAA,WAAA,CAAA;AACA,GAAA;AACA;;AAEA;AACA,MAAA,mBAAA,GAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,qBAAA,CAAA,IAAA,EAAA;AACA,EAAA,MAAA,cAAA,GAAA,SAAA;AACA,EAAA,MAAA,sBAAA,GAAA,IAAA,SAAA,CAAA;AACA,IAAA,SAAA,CAAA,KAAA,EAAA,SAAA,EAAA,QAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,MAAA,CAAA,QAAA,CAAA,KAAA,CAAA,GAAA,KAAA,CAAA,QAAA,EAAA,GAAA,MAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,CAAA,QAAA,CAAA,cAAA,CAAA,EAAA;AACA,QAAA,MAAA,YAAA,GAAA,IAAA,CAAA,OAAA,CAAA,cAAA,EAAA,CAAA,EAAA,gBAAA,EAAA,CAAA,EAAA,cAAA,CAAA,CAAA,CAAA;AACA,QAAA,QAAA,CAAA,IAAA,EAAA,YAAA,CAAA;AACA,QAAA;AACA;AACA,MAAA,QAAA,CAAA,IAAA,EAAA,KAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA,EAAA,sBAAA,CAAA,IAAA,CAAA,IAAA,CAAA;AACA,EAAA,OAAA,sBAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapSentryHandleRequest.js","sources":["../../../src/server/wrapSentryHandleRequest.ts"],"sourcesContent":["import { context } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport {\n getActiveSpan,\n getRootSpan,\n getTraceMetaTags,\n SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n} from '@sentry/core';\nimport type { AppLoadContext, EntryContext } from 'react-router';\nimport type { PassThrough } from 'stream';\nimport { Transform } from 'stream';\n\ntype OriginalHandleRequest = (\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n) => Promise<unknown>;\n\n/**\n * Wraps the original handleRequest function to add Sentry instrumentation.\n *\n * @param originalHandle - The original handleRequest function to wrap\n * @returns A wrapped version of the handle request function with Sentry instrumentation\n */\nexport function wrapSentryHandleRequest(originalHandle: OriginalHandleRequest): OriginalHandleRequest {\n return async function sentryInstrumentedHandleRequest(\n request: Request,\n responseStatusCode: number,\n responseHeaders: Headers,\n routerContext: EntryContext,\n loadContext: AppLoadContext,\n ) {\n const parameterizedPath =\n routerContext?.staticHandlerContext?.matches?.[routerContext.staticHandlerContext.matches.length - 1]?.route.path;\n\n if (parameterizedPath) {\n const activeSpan = getActiveSpan();\n if (activeSpan) {\n const rootSpan = getRootSpan(activeSpan);\n const routeName = `/${parameterizedPath}`;\n\n // The express instrumentation writes on the rpcMetadata and that ends up stomping on the `http.route` attribute.\n const rpcMetadata = getRPCMetadata(context.active());\n\n if (rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n\n // The span exporter picks up the `http.route` (ATTR_HTTP_ROUTE) attribute to set the transaction name\n rootSpan.setAttributes({\n [ATTR_HTTP_ROUTE]: routeName,\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',\n [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: `${request.method} ${routeName}`,\n });\n }\n }\n\n return originalHandle(request, responseStatusCode, responseHeaders, routerContext, loadContext);\n };\n}\n\n/** @deprecated Use `wrapSentryHandleRequest` instead. */\nexport const sentryHandleRequest = wrapSentryHandleRequest;\n\n/**\n * Injects Sentry trace meta tags into the HTML response by piping through a transform stream.\n * This enables distributed tracing by adding trace context to the HTML document head.\n *\n * @param body - PassThrough stream containing the HTML response body to modify\n */\nexport function getMetaTagTransformer(body: PassThrough): Transform {\n const headClosingTag = '</head>';\n const htmlMetaTagTransformer = new Transform({\n transform(chunk, _encoding, callback) {\n const html = Buffer.isBuffer(chunk) ? chunk.toString() : String(chunk);\n if (html.includes(headClosingTag)) {\n const modifiedHtml = html.replace(headClosingTag, `${getTraceMetaTags()}${headClosingTag}`);\n callback(null, modifiedHtml);\n return;\n }\n callback(null, chunk);\n },\n });\n htmlMetaTagTransformer.pipe(body);\n return htmlMetaTagTransformer;\n}\n"],"names":[],"mappings":";;;;;;AAsBA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,uBAAuB,CAAC,cAAc,EAAgD;AACtG,EAAE,OAAO,eAAe,+BAA+B;AACvD,IAAI,OAAO;AACX,IAAI,kBAAkB;AACtB,IAAI,eAAe;AACnB,IAAI,aAAa;AACjB,IAAI,WAAW;AACf,IAAI;AACJ,IAAI,MAAM,iBAAA;AACV,MAAM,aAAa,EAAE,oBAAoB,EAAE,OAAO,GAAG,aAAa,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI;;AAEvH,IAAI,IAAI,iBAAiB,EAAE;AAC3B,MAAM,MAAM,UAAA,GAAa,aAAa,EAAE;AACxC,MAAM,IAAI,UAAU,EAAE;AACtB,QAAQ,MAAM,QAAA,GAAW,WAAW,CAAC,UAAU,CAAC;AAChD,QAAQ,MAAM,YAAY,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;;AAEA;AACA,QAAA,MAAA,WAAA,GAAA,cAAA,CAAA,OAAA,CAAA,MAAA,EAAA,CAAA;;AAEA,QAAA,IAAA,WAAA,EAAA,IAAA,KAAA,OAAA,CAAA,IAAA,EAAA;AACA,UAAA,WAAA,CAAA,KAAA,GAAA,SAAA;AACA;;AAEA;AACA,QAAA,QAAA,CAAA,aAAA,CAAA;AACA,UAAA,CAAA,eAAA,GAAA,SAAA;AACA,UAAA,CAAA,gCAAA,GAAA,OAAA;AACA,UAAA,CAAA,0CAAA,GAAA,CAAA,EAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,SAAA,CAAA,CAAA;AACA,SAAA,CAAA;AACA;AACA;;AAEA,IAAA,OAAA,cAAA,CAAA,OAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,aAAA,EAAA,WAAA,CAAA;AACA,GAAA;AACA;;AAEA;AACA,MAAA,mBAAA,GAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA,qBAAA,CAAA,IAAA,EAAA;AACA,EAAA,MAAA,cAAA,GAAA,SAAA;AACA,EAAA,MAAA,sBAAA,GAAA,IAAA,SAAA,CAAA;AACA,IAAA,SAAA,CAAA,KAAA,EAAA,SAAA,EAAA,QAAA,EAAA;AACA,MAAA,MAAA,IAAA,GAAA,MAAA,CAAA,QAAA,CAAA,KAAA,CAAA,GAAA,KAAA,CAAA,QAAA,EAAA,GAAA,MAAA,CAAA,KAAA,CAAA;AACA,MAAA,IAAA,IAAA,CAAA,QAAA,CAAA,cAAA,CAAA,EAAA;AACA,QAAA,MAAA,YAAA,GAAA,IAAA,CAAA,OAAA,CAAA,cAAA,EAAA,CAAA,EAAA,gBAAA,EAAA,CAAA,EAAA,cAAA,CAAA,CAAA,CAAA;AACA,QAAA,QAAA,CAAA,IAAA,EAAA,YAAA,CAAA;AACA,QAAA;AACA;AACA,MAAA,QAAA,CAAA,IAAA,EAAA,KAAA,CAAA;AACA,KAAA;AACA,GAAA,CAAA;AACA,EAAA,sBAAA,CAAA,IAAA,CAAA,IAAA,CAAA;AACA,EAAA,OAAA,sBAAA;AACA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'POST') {\n const url = parseStringToURLObject(args.request.url);\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n };\n}\n"],"names":[],"mappings":";;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAK,GAAE,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAK,GAAE,WAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,MAAM,EAAE;AACnD,QAAQ,MAAM,GAAI,GAAE,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AAC5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAAC,gCAAgC,GAAG,KAAK;AACrD,YAAY,CAAC,mCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;;AAEA,IAAA,OAAA,SAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAA,gCAAA,GAAA,wBAAA;AACA,UAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param actionFn - The server action function to wrap\n *\n * @example\n * ```ts\n * // Wrap an action function with custom span options\n * export const action = wrapServerAction(\n * {\n * name: 'Submit Form Data',\n * description: 'Processes form submission data',\n * },\n * async ({ request }) => {\n * // ... your action logic\n * }\n * );\n * ```\n */\nexport function wrapServerAction<T>(options: SpanOptions = {}, actionFn: (args: ActionFunctionArgs) => Promise<T>) {\n return async function (args: ActionFunctionArgs) {\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'POST') {\n const url = parseStringToURLObject(args.request.url);\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n };\n}\n"],"names":[],"mappings":";;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAO,WAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,MAAM,EAAE;AACnD,QAAQ,MAAM,GAAA,GAAM,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;AAC5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAAC,gCAAgC,GAAG,KAAK;AACrD,YAAY,CAAC,mCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;;AAEA,IAAA,OAAA,SAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAA,gCAAA,GAAA,wBAAA;AACA,UAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'GET') {\n const url = parseStringToURLObject(args.request.url);\n\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n };\n}\n"],"names":[],"mappings":";;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAK,GAAE,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAK,GAAE,WAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,KAAK,EAAE;AAClD,QAAQ,MAAM,GAAI,GAAE,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;;AAE5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAAC,gCAAgC,GAAG,KAAK;AACrD,YAAY,CAAC,mCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;AACA,IAAA,OAAA,SAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAA,gCAAA,GAAA,wBAAA;AACA,UAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import type { SpanAttributes } from '@sentry/core';\nimport {\n getActiveSpan,\n getRootSpan,\n parseStringToURLObject,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE } from './instrumentation/util';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n * @param options - Optional span configuration options including name, operation, description and attributes\n * @param loaderFn - The server loader function to wrap\n *\n * @example\n * ```ts\n * // Wrap a loader function with custom span options\n * export const loader = wrapServerLoader(\n * {\n * name: 'Load Some Data',\n * description: 'Loads some data from the db',\n * },\n * async ({ params }) => {\n * // ... your loader logic\n * }\n * );\n * ```\n */\nexport function wrapServerLoader<T>(options: SpanOptions = {}, loaderFn: (args: LoaderFunctionArgs) => Promise<T>) {\n return async function (args: LoaderFunctionArgs) {\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n // coming from auto.http.otel.http\n if (spanToJSON(root).description === 'GET') {\n const url = parseStringToURLObject(args.request.url);\n\n if (url?.pathname) {\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE]: `${args.request.method} ${url.pathname}`,\n });\n }\n }\n }\n return startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react-router',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react-router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n };\n}\n"],"names":[],"mappings":";;;AAmBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,gBAAgB,CAAI,OAAO,GAAgB,EAAE,EAAE,QAAQ,EAA4C;AACnH,EAAE,OAAO,gBAAgB,IAAI,EAAsB;AACnD,IAAI,MAAM,IAAA,GAAO,OAAO,CAAC,IAAA,IAAQ,yBAAyB;AAC1D,IAAI,MAAM,MAAA,GAAS,aAAa,EAAE;AAClC,IAAI,IAAI,MAAM,EAAE;AAChB,MAAM,MAAM,IAAA,GAAO,WAAW,CAAC,MAAM,CAAC;AACtC;AACA,MAAM,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,WAAA,KAAgB,KAAK,EAAE;AAClD,QAAQ,MAAM,GAAA,GAAM,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;;AAE5D,QAAQ,IAAI,GAAG,EAAE,QAAQ,EAAE;AAC3B,UAAU,IAAI,CAAC,aAAa,CAAC;AAC7B,YAAY,CAAC,gCAAgC,GAAG,KAAK;AACrD,YAAY,CAAC,mCAAmC,GAAG,CAAC,EAAA,IAAA,CAAA,OAAA,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,WAAA,CAAA;AACA;AACA;AACA;AACA,IAAA,OAAA,SAAA;AACA,MAAA;AACA,QAAA,IAAA;AACA,QAAA,GAAA,OAAA;AACA,QAAA,UAAA,EAAA;AACA,UAAA,CAAA,gCAAA,GAAA,wBAAA;AACA,UAAA,CAAA,4BAAA,GAAA,8BAAA;AACA,UAAA,GAAA,OAAA,CAAA,UAAA;AACA,SAAA;AACA,OAAA;AACA,MAAA,MAAA,QAAA,CAAA,IAAA,CAAA;AACA,KAAA;AACA,GAAA;AACA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"handleOnBuildEnd.js","sources":["../../../../src/vite/buildEnd/handleOnBuildEnd.ts"],"sourcesContent":["import { rm } from 'node:fs/promises';\nimport type { Config } from '@react-router/dev/config';\nimport SentryCli from '@sentry/cli';\nimport { glob } from 'glob';\nimport type { SentryReactRouterBuildOptions } from '../types';\n\ntype BuildEndHook = NonNullable<Config['buildEnd']>;\n\nfunction getSentryConfig(viteConfig: unknown): SentryReactRouterBuildOptions {\n if (!viteConfig || typeof viteConfig !== 'object' || !('sentryConfig' in viteConfig)) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] sentryConfig not found - it needs to be passed to vite.config.ts');\n }\n\n return (viteConfig as { sentryConfig: SentryReactRouterBuildOptions }).sentryConfig;\n}\n\n/**\n * A build end hook that handles Sentry release creation and source map uploads.\n * It creates a new Sentry release if configured, uploads source maps to Sentry,\n * and optionally deletes the source map files after upload.\n */\nexport const sentryOnBuildEnd: BuildEndHook = async ({ reactRouterConfig, viteConfig }) => {\n const sentryConfig = getSentryConfig(viteConfig);\n\n const {\n authToken,\n org,\n project,\n release,\n sourceMapsUploadOptions = { enabled: true },\n debug = false,\n unstable_sentryVitePluginOptions,\n }: SentryReactRouterBuildOptions = {\n ...sentryConfig.unstable_sentryVitePluginOptions,\n ...sentryConfig,\n release: {\n ...sentryConfig.unstable_sentryVitePluginOptions?.release,\n ...sentryConfig.release,\n },\n };\n\n const cliInstance = new SentryCli(null, {\n authToken,\n org,\n project,\n ...unstable_sentryVitePluginOptions,\n });\n // check if release should be created\n if (release?.name) {\n try {\n await cliInstance.releases.new(release.name);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not create release', error);\n }\n }\n\n if (sourceMapsUploadOptions?.enabled ?? (true && viteConfig.build.sourcemap !== false)) {\n // inject debugIds\n try {\n await cliInstance.execute(['sourcemaps', 'inject', reactRouterConfig.buildDirectory], debug);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not inject debug ids', error);\n }\n\n // upload sourcemaps\n try {\n await cliInstance.releases.uploadSourceMaps(release?.name || 'undefined', {\n include: [\n {\n paths: [reactRouterConfig.buildDirectory],\n },\n ],\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not upload sourcemaps', error);\n }\n }\n // delete sourcemaps after upload\n let updatedFilesToDeleteAfterUpload = sourceMapsUploadOptions?.filesToDeleteAfterUpload;\n // set a default value no option was set\n if (typeof sourceMapsUploadOptions?.filesToDeleteAfterUpload === 'undefined') {\n updatedFilesToDeleteAfterUpload = [`${reactRouterConfig.buildDirectory}/**/*.map`];\n if (debug) {\n // eslint-disable-next-line no-console\n console.info(\n `[Sentry] Automatically setting \\`sourceMapsUploadOptions.filesToDeleteAfterUpload: ${JSON.stringify(\n updatedFilesToDeleteAfterUpload,\n )}\\` to delete generated source maps after they were uploaded to Sentry.`,\n );\n }\n }\n if (updatedFilesToDeleteAfterUpload) {\n try {\n const filePathsToDelete = await glob(updatedFilesToDeleteAfterUpload, {\n absolute: true,\n nodir: true,\n });\n if (debug) {\n filePathsToDelete.forEach(filePathToDelete => {\n // eslint-disable-next-line no-console\n console.info(`Deleting asset after upload: ${filePathToDelete}`);\n });\n }\n await Promise.all(\n filePathsToDelete.map(filePathToDelete =>\n rm(filePathToDelete, { force: true }).catch((e: unknown) => {\n if (debug) {\n // This is allowed to fail - we just don't do anything\n // eslint-disable-next-line no-console\n console.debug(`An error occurred while attempting to delete asset: ${filePathToDelete}`, e);\n }\n }),\n ),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Error deleting files after sourcemap upload:', error);\n }\n }\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handleOnBuildEnd.js","sources":["../../../../src/vite/buildEnd/handleOnBuildEnd.ts"],"sourcesContent":["import { rm } from 'node:fs/promises';\nimport type { Config } from '@react-router/dev/config';\nimport SentryCli from '@sentry/cli';\nimport { glob } from 'glob';\nimport type { SentryReactRouterBuildOptions } from '../types';\n\ntype BuildEndHook = NonNullable<Config['buildEnd']>;\n\nfunction getSentryConfig(viteConfig: unknown): SentryReactRouterBuildOptions {\n if (!viteConfig || typeof viteConfig !== 'object' || !('sentryConfig' in viteConfig)) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] sentryConfig not found - it needs to be passed to vite.config.ts');\n }\n\n return (viteConfig as { sentryConfig: SentryReactRouterBuildOptions }).sentryConfig;\n}\n\n/**\n * A build end hook that handles Sentry release creation and source map uploads.\n * It creates a new Sentry release if configured, uploads source maps to Sentry,\n * and optionally deletes the source map files after upload.\n */\nexport const sentryOnBuildEnd: BuildEndHook = async ({ reactRouterConfig, viteConfig }) => {\n const sentryConfig = getSentryConfig(viteConfig);\n\n const {\n authToken,\n org,\n project,\n release,\n sourceMapsUploadOptions = { enabled: true },\n debug = false,\n unstable_sentryVitePluginOptions,\n }: SentryReactRouterBuildOptions = {\n ...sentryConfig.unstable_sentryVitePluginOptions,\n ...sentryConfig,\n release: {\n ...sentryConfig.unstable_sentryVitePluginOptions?.release,\n ...sentryConfig.release,\n },\n };\n\n const cliInstance = new SentryCli(null, {\n authToken,\n org,\n project,\n ...unstable_sentryVitePluginOptions,\n });\n // check if release should be created\n if (release?.name) {\n try {\n await cliInstance.releases.new(release.name);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not create release', error);\n }\n }\n\n if (sourceMapsUploadOptions?.enabled ?? (true && viteConfig.build.sourcemap !== false)) {\n // inject debugIds\n try {\n await cliInstance.execute(['sourcemaps', 'inject', reactRouterConfig.buildDirectory], debug);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not inject debug ids', error);\n }\n\n // upload sourcemaps\n try {\n await cliInstance.releases.uploadSourceMaps(release?.name || 'undefined', {\n include: [\n {\n paths: [reactRouterConfig.buildDirectory],\n },\n ],\n });\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('[Sentry] Could not upload sourcemaps', error);\n }\n }\n // delete sourcemaps after upload\n let updatedFilesToDeleteAfterUpload = sourceMapsUploadOptions?.filesToDeleteAfterUpload;\n // set a default value no option was set\n if (typeof sourceMapsUploadOptions?.filesToDeleteAfterUpload === 'undefined') {\n updatedFilesToDeleteAfterUpload = [`${reactRouterConfig.buildDirectory}/**/*.map`];\n if (debug) {\n // eslint-disable-next-line no-console\n console.info(\n `[Sentry] Automatically setting \\`sourceMapsUploadOptions.filesToDeleteAfterUpload: ${JSON.stringify(\n updatedFilesToDeleteAfterUpload,\n )}\\` to delete generated source maps after they were uploaded to Sentry.`,\n );\n }\n }\n if (updatedFilesToDeleteAfterUpload) {\n try {\n const filePathsToDelete = await glob(updatedFilesToDeleteAfterUpload, {\n absolute: true,\n nodir: true,\n });\n if (debug) {\n filePathsToDelete.forEach(filePathToDelete => {\n // eslint-disable-next-line no-console\n console.info(`Deleting asset after upload: ${filePathToDelete}`);\n });\n }\n await Promise.all(\n filePathsToDelete.map(filePathToDelete =>\n rm(filePathToDelete, { force: true }).catch((e: unknown) => {\n if (debug) {\n // This is allowed to fail - we just don't do anything\n // eslint-disable-next-line no-console\n console.debug(`An error occurred while attempting to delete asset: ${filePathToDelete}`, e);\n }\n }),\n ),\n );\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Error deleting files after sourcemap upload:', error);\n }\n }\n};\n"],"names":[],"mappings":";;;;AAQA,SAAS,eAAe,CAAC,UAAU,EAA0C;AAC7E,EAAE,IAAI,CAAC,UAAA,IAAc,OAAO,UAAA,KAAe,QAAA,IAAY,EAAE,cAAA,IAAkB,UAAU,CAAC,EAAE;AACxF;AACA,IAAI,OAAO,CAAC,KAAK,CAAC,2EAA2E,CAAC;AAC9F;;AAEA,EAAE,OAAO,CAAC,UAAA,GAA+D,YAAY;AACrF;;AAEA;AACA;AACA;AACA;AACA;AACO,MAAM,gBAAgB,GAAiB,OAAO,EAAE,iBAAiB,EAAE,UAAA,EAAY,KAAK;AAC3F,EAAE,MAAM,YAAA,GAAe,eAAe,CAAC,UAAU,CAAC;;AAElD,EAAE,MAAM;AACR,IAAI,SAAS;AACb,IAAI,GAAG;AACP,IAAI,OAAO;AACX,IAAI,OAAO;AACX,IAAI,0BAA0B,EAAE,OAAO,EAAE,MAAM;AAC/C,IAAI,KAAA,GAAQ,KAAK;AACjB,IAAI,gCAAgC;AACpC,GAAG,GAAkC;AACrC,IAAI,GAAG,YAAY,CAAC,gCAAgC;AACpD,IAAI,GAAG,YAAY;AACnB,IAAI,OAAO,EAAE;AACb,MAAM,GAAG,YAAY,CAAC,gCAAgC,EAAE,OAAO;AAC/D,MAAM,GAAG,YAAY,CAAC,OAAO;AAC7B,KAAK;AACL,GAAG;;AAEH,EAAE,MAAM,WAAA,GAAc,IAAI,SAAS,CAAC,IAAI,EAAE;AAC1C,IAAI,SAAS;AACb,IAAI,GAAG;AACP,IAAI,OAAO;AACX,IAAI,GAAG,gCAAgC;AACvC,GAAG,CAAC;AACJ;AACA,EAAE,IAAI,OAAO,EAAE,IAAI,EAAE;AACrB,IAAI,IAAI;AACR,MAAM,MAAM,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;AAClD,KAAI,CAAE,OAAO,KAAK,EAAE;AACpB;AACA,MAAM,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,KAAK,CAAC;AAC/D;AACA;;AAEA,EAAE,IAAI,uBAAuB,EAAE,OAAA,KAAoB,UAAU,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,EAAE;AAC1F;AACA,IAAI,IAAI;AACR,MAAM,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,EAAE,iBAAiB,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC;AAClG,KAAI,CAAE,OAAO,KAAK,EAAE;AACpB;AACA,MAAM,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC;AACjE;;AAEA;AACA,IAAI,IAAI;AACR,MAAM,MAAM,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAA,IAAQ,WAAW,EAAE;AAChF,QAAQ,OAAO,EAAE;AACjB,UAAU;AACV,YAAY,KAAK,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;AACrD,WAAW;AACX,SAAS;AACT,OAAO,CAAC;AACR,KAAI,CAAE,OAAO,KAAK,EAAE;AACpB;AACA,MAAM,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC;AAClE;AACA;AACA;AACA,EAAE,IAAI,+BAAA,GAAkC,uBAAuB,EAAE,wBAAwB;AACzF;AACA,EAAE,IAAI,OAAO,uBAAuB,EAAE,wBAAA,KAA6B,WAAW,EAAE;AAChF,IAAI,+BAAA,GAAkC,CAAC,CAAC,EAAA,iBAAA,CAAA,cAAA,CAAA,SAAA,CAAA,CAAA;AACA,IAAA,IAAA,KAAA,EAAA;AACA;AACA,MAAA,OAAA,CAAA,IAAA;AACA,QAAA,CAAA,mFAAA,EAAA,IAAA,CAAA,SAAA;AACA,UAAA,+BAAA;AACA,SAAA,CAAA,sEAAA,CAAA;AACA,OAAA;AACA;AACA;AACA,EAAA,IAAA,+BAAA,EAAA;AACA,IAAA,IAAA;AACA,MAAA,MAAA,iBAAA,GAAA,MAAA,IAAA,CAAA,+BAAA,EAAA;AACA,QAAA,QAAA,EAAA,IAAA;AACA,QAAA,KAAA,EAAA,IAAA;AACA,OAAA,CAAA;AACA,MAAA,IAAA,KAAA,EAAA;AACA,QAAA,iBAAA,CAAA,OAAA,CAAA,gBAAA,IAAA;AACA;AACA,UAAA,OAAA,CAAA,IAAA,CAAA,CAAA,6BAAA,EAAA,gBAAA,CAAA,CAAA,CAAA;AACA,SAAA,CAAA;AACA;AACA,MAAA,MAAA,OAAA,CAAA,GAAA;AACA,QAAA,iBAAA,CAAA,GAAA,CAAA,gBAAA;AACA,UAAA,EAAA,CAAA,gBAAA,EAAA,EAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,KAAA;AACA,YAAA,IAAA,KAAA,EAAA;AACA;AACA;AACA,cAAA,OAAA,CAAA,KAAA,CAAA,CAAA,oDAAA,EAAA,gBAAA,CAAA,CAAA,EAAA,CAAA,CAAA;AACA;AACA,WAAA,CAAA;AACA,SAAA;AACA,OAAA;AACA,KAAA,CAAA,OAAA,KAAA,EAAA;AACA;AACA,MAAA,OAAA,CAAA,KAAA,CAAA,8CAAA,EAAA,KAAA,CAAA;AACA;AACA;AACA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"makeCustomSentryVitePlugins.js","sources":["../../../src/vite/makeCustomSentryVitePlugins.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/vite-plugin';\nimport { type Plugin } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * Create a custom subset of sentry's vite plugins\n */\nexport async function makeCustomSentryVitePlugins(options: SentryReactRouterBuildOptions): Promise<Plugin[]> {\n const {\n debug,\n unstable_sentryVitePluginOptions,\n bundleSizeOptimizations,\n authToken,\n org,\n project,\n telemetry,\n reactComponentAnnotation,\n release,\n } = options;\n\n const sentryVitePlugins = sentryVitePlugin({\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations,\n debug: debug ?? false,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n telemetry: telemetry ?? true,\n _metaOptions: {\n telemetry: {\n metaFramework: 'react-router',\n },\n ...unstable_sentryVitePluginOptions?._metaOptions,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n ...unstable_sentryVitePluginOptions?.reactComponentAnnotation,\n },\n release: {\n ...unstable_sentryVitePluginOptions?.release,\n ...release,\n },\n // will be handled in buildEnd hook\n sourcemaps: {\n disable: true,\n ...unstable_sentryVitePluginOptions?.sourcemaps,\n },\n ...unstable_sentryVitePluginOptions,\n }) as Plugin[];\n\n // only use a subset of the plugins as all upload and file deletion tasks will be handled in the buildEnd hook\n return [\n ...sentryVitePlugins.filter(plugin => {\n return [\n 'sentry-telemetry-plugin',\n 'sentry-vite-release-injection-plugin',\n ...(reactComponentAnnotation?.enabled || unstable_sentryVitePluginOptions?.reactComponentAnnotation?.enabled\n ? ['sentry-vite-component-name-annotate-plugin']\n : []),\n ].includes(plugin.name);\n }),\n ];\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACO,eAAe,2BAA2B,CAAC,OAAO,EAAoD;AAC7G,EAAE,MAAM;AACR,IAAI,KAAK;AACT,IAAI,gCAAgC;AACpC,IAAI,uBAAuB;AAC3B,IAAI,SAAS;AACb,IAAI,GAAG;AACP,IAAI,OAAO;AACX,IAAI,SAAS;AACb,IAAI,wBAAwB;AAC5B,IAAI,OAAO;AACX,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,iBAAA,GAAoB,gBAAgB,CAAC;AAC7C,IAAI,SAAS,EAAE,SAAU,IAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB;AACzD,IAAI,uBAAuB;AAC3B,IAAI,KAAK,EAAE,KAAM,IAAG,KAAK;AACzB,IAAI,GAAG,EAAE,GAAI,IAAG,OAAO,CAAC,GAAG,CAAC,UAAU;AACtC,IAAI,OAAO,EAAE,OAAQ,IAAG,OAAO,CAAC,GAAG,CAAC,cAAc;AAClD,IAAI,SAAS,EAAE,SAAU,IAAG,IAAI;AAChC,IAAI,YAAY,EAAE;AAClB,MAAM,SAAS,EAAE;AACjB,QAAQ,aAAa,EAAE,cAAc;AACrC,OAAO;AACP,MAAM,GAAG,gCAAgC,EAAE,YAAY;AACvD,KAAK;AACL,IAAI,wBAAwB,EAAE;AAC9B,MAAM,OAAO,EAAE,wBAAwB,EAAE,OAAA,IAAW,SAAS;AAC7D,MAAM,iBAAiB,EAAE,wBAAwB,EAAE,iBAAA,IAAqB,SAAS;AACjF,MAAM,GAAG,gCAAgC,EAAE,wBAAwB;AACnE,KAAK;AACL,IAAI,OAAO,EAAE;AACb,MAAM,GAAG,gCAAgC,EAAE,OAAO;AAClD,MAAM,GAAG,OAAO;AAChB,KAAK;AACL;AACA,IAAI,UAAU,EAAE;AAChB,MAAM,OAAO,EAAE,IAAI;AACnB,MAAM,GAAG,gCAAgC,EAAE,UAAU;AACrD,KAAK;AACL,IAAI,GAAG,gCAAgC;AACvC,GAAG,CAAE;;AAEL;AACA,EAAE,OAAO;AACT,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,UAAU;AAC1C,MAAM,OAAO;AACb,QAAQ,yBAAyB;AACjC,QAAQ,sCAAsC;AAC9C,QAAQ,IAAI,wBAAwB,EAAE,WAAW,gCAAgC,EAAE,wBAAwB,EAAE;AAC7G,YAAY,CAAC,4CAA4C;AACzD,YAAY,EAAE,CAAC;AACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AAC7B,KAAK,CAAC;AACN,GAAG;AACH;;;;"}
1
+ {"version":3,"file":"makeCustomSentryVitePlugins.js","sources":["../../../src/vite/makeCustomSentryVitePlugins.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/vite-plugin';\nimport { type Plugin } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * Create a custom subset of sentry's vite plugins\n */\nexport async function makeCustomSentryVitePlugins(options: SentryReactRouterBuildOptions): Promise<Plugin[]> {\n const {\n debug,\n unstable_sentryVitePluginOptions,\n bundleSizeOptimizations,\n authToken,\n org,\n project,\n telemetry,\n reactComponentAnnotation,\n release,\n } = options;\n\n const sentryVitePlugins = sentryVitePlugin({\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations,\n debug: debug ?? false,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n telemetry: telemetry ?? true,\n _metaOptions: {\n telemetry: {\n metaFramework: 'react-router',\n },\n ...unstable_sentryVitePluginOptions?._metaOptions,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n ...unstable_sentryVitePluginOptions?.reactComponentAnnotation,\n },\n release: {\n ...unstable_sentryVitePluginOptions?.release,\n ...release,\n },\n // will be handled in buildEnd hook\n sourcemaps: {\n disable: true,\n ...unstable_sentryVitePluginOptions?.sourcemaps,\n },\n ...unstable_sentryVitePluginOptions,\n }) as Plugin[];\n\n // only use a subset of the plugins as all upload and file deletion tasks will be handled in the buildEnd hook\n return [\n ...sentryVitePlugins.filter(plugin => {\n return [\n 'sentry-telemetry-plugin',\n 'sentry-vite-release-injection-plugin',\n ...(reactComponentAnnotation?.enabled || unstable_sentryVitePluginOptions?.reactComponentAnnotation?.enabled\n ? ['sentry-vite-component-name-annotate-plugin']\n : []),\n ].includes(plugin.name);\n }),\n ];\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACO,eAAe,2BAA2B,CAAC,OAAO,EAAoD;AAC7G,EAAE,MAAM;AACR,IAAI,KAAK;AACT,IAAI,gCAAgC;AACpC,IAAI,uBAAuB;AAC3B,IAAI,SAAS;AACb,IAAI,GAAG;AACP,IAAI,OAAO;AACX,IAAI,SAAS;AACb,IAAI,wBAAwB;AAC5B,IAAI,OAAO;AACX,GAAE,GAAI,OAAO;;AAEb,EAAE,MAAM,iBAAA,GAAoB,gBAAgB,CAAC;AAC7C,IAAI,SAAS,EAAE,SAAA,IAAa,OAAO,CAAC,GAAG,CAAC,iBAAiB;AACzD,IAAI,uBAAuB;AAC3B,IAAI,KAAK,EAAE,KAAA,IAAS,KAAK;AACzB,IAAI,GAAG,EAAE,GAAA,IAAO,OAAO,CAAC,GAAG,CAAC,UAAU;AACtC,IAAI,OAAO,EAAE,OAAA,IAAW,OAAO,CAAC,GAAG,CAAC,cAAc;AAClD,IAAI,SAAS,EAAE,SAAA,IAAa,IAAI;AAChC,IAAI,YAAY,EAAE;AAClB,MAAM,SAAS,EAAE;AACjB,QAAQ,aAAa,EAAE,cAAc;AACrC,OAAO;AACP,MAAM,GAAG,gCAAgC,EAAE,YAAY;AACvD,KAAK;AACL,IAAI,wBAAwB,EAAE;AAC9B,MAAM,OAAO,EAAE,wBAAwB,EAAE,OAAA,IAAW,SAAS;AAC7D,MAAM,iBAAiB,EAAE,wBAAwB,EAAE,iBAAA,IAAqB,SAAS;AACjF,MAAM,GAAG,gCAAgC,EAAE,wBAAwB;AACnE,KAAK;AACL,IAAI,OAAO,EAAE;AACb,MAAM,GAAG,gCAAgC,EAAE,OAAO;AAClD,MAAM,GAAG,OAAO;AAChB,KAAK;AACL;AACA,IAAI,UAAU,EAAE;AAChB,MAAM,OAAO,EAAE,IAAI;AACnB,MAAM,GAAG,gCAAgC,EAAE,UAAU;AACrD,KAAK;AACL,IAAI,GAAG,gCAAgC;AACvC,GAAG,CAAA;;AAEH;AACA,EAAE,OAAO;AACT,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC,UAAU;AAC1C,MAAM,OAAO;AACb,QAAQ,yBAAyB;AACjC,QAAQ,sCAAsC;AAC9C,QAAQ,IAAI,wBAAwB,EAAE,WAAW,gCAAgC,EAAE,wBAAwB,EAAE;AAC7G,YAAY,CAAC,4CAA4C;AACzD,YAAY,EAAE,CAAC;AACf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;AAC7B,KAAK,CAAC;AACN,GAAG;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"makeEnableSourceMapsPlugin.js","sources":["../../../src/vite/makeEnableSourceMapsPlugin.ts"],"sourcesContent":["import { consoleSandbox } from '@sentry/core';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Sentry plugin for React Router to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsPlugin(options: SentryReactRouterBuildOptions): Plugin {\n return {\n name: 'sentry-react-router-update-source-map-setting',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n };\n}\n\n/** There are 3 ways to set up source map generation\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - we won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryReactRouterBuildOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteSourceMap = viteConfig?.build?.sourcemap;\n let updatedSourceMapSetting = viteSourceMap;\n\n const settingKey = 'vite.build.sourcemap';\n\n if (viteSourceMap === false) {\n updatedSourceMapSetting = viteSourceMap;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Source map generation is currently disabled in your Vite configuration (\\`${settingKey}: false \\`). This setting is either a default setting or was explicitly set in your configuration. Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified. To show unminified code, enable source maps in \\`${settingKey}\\` (e.g. by setting them to \\`hidden\\`).`,\n );\n });\n } else if (viteSourceMap && ['hidden', 'inline', true].includes(viteSourceMap)) {\n updatedSourceMapSetting = viteSourceMap;\n\n if (sentryPluginOptions?.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteSourceMap.toString()}\\`. Sentry will keep this source map setting. This will un-minify the code snippet on the Sentry Issue page.`,\n );\n });\n }\n } else {\n updatedSourceMapSetting = 'hidden';\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n });\n }\n\n return updatedSourceMapSetting;\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,OAAO,EAAyC;AAC3F,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,+CAA+C;AACzD,IAAI,KAAK,EAAE,OAAO;AAClB,IAAI,OAAO,EAAE,MAAM;AACnB,IAAI,MAAM,CAAC,UAAU,EAAE;AACvB,MAAM,OAAO;AACb,QAAQ,GAAG,UAAU;AACrB,QAAQ,KAAK,EAAE;AACf,UAAU,GAAG,UAAU,CAAC,KAAK;AAC7B,UAAU,SAAS,EAAE,2BAA2B,CAAC,UAAU,EAAE,OAAO,CAAC;AACrE,SAAS;AACT,OAAO;AACP,KAAK;AACL,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,2BAA2B;AAC3C,EAAE,UAAU;AACZ,EAAE,mBAAmB;AACrB,EAAiC;AACjC,EAAE,UAAU,CAAC,KAAM,GAAE,UAAU,CAAC,KAAA,IAAS,EAAE;;AAE3C,EAAE,MAAM,aAAc,GAAE,UAAU,EAAE,KAAK,EAAE,SAAS;AACpD,EAAE,IAAI,uBAAwB,GAAE,aAAa;;AAE7C,EAAE,MAAM,UAAW,GAAE,sBAAsB;;AAE3C,EAAE,IAAI,aAAc,KAAI,KAAK,EAAE;AAC/B,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAI,cAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,IAAI;AAClB,QAAQ,CAAC,mFAAmF,EAAE,UAAU,CAAC,2QAA2Q,EAAE,UAAU,CAAC,wCAAwC,CAAC;AAC1a,OAAO;AACP,KAAK,CAAC;AACN,SAAS,IAAI,aAAc,IAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;AAClF,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAI,IAAI,mBAAmB,EAAE,KAAK,EAAE;AACpC,MAAM,cAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,GAAG;AACnB,UAAU,CAAC,yBAAyB,EAAE,UAAU,CAAC,eAAe,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,4GAA4G,CAAC;AACxM,SAAS;AACT,OAAO,CAAC;AACR;AACA,SAAS;AACT,IAAI,uBAAA,GAA0B,QAAQ;;AAEtC,IAAI,cAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,CAAC,mEAAmE,EAAE,UAAU,CAAC,kFAAkF,CAAC;AAC5K,OAAO;AACP,KAAK,CAAC;AACN;;AAEA,EAAE,OAAO,uBAAuB;AAChC;;;;"}
1
+ {"version":3,"file":"makeEnableSourceMapsPlugin.js","sources":["../../../src/vite/makeEnableSourceMapsPlugin.ts"],"sourcesContent":["import { consoleSandbox } from '@sentry/core';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Sentry plugin for React Router to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsPlugin(options: SentryReactRouterBuildOptions): Plugin {\n return {\n name: 'sentry-react-router-update-source-map-setting',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n };\n}\n\n/** There are 3 ways to set up source map generation\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - we won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryReactRouterBuildOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteSourceMap = viteConfig?.build?.sourcemap;\n let updatedSourceMapSetting = viteSourceMap;\n\n const settingKey = 'vite.build.sourcemap';\n\n if (viteSourceMap === false) {\n updatedSourceMapSetting = viteSourceMap;\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Source map generation is currently disabled in your Vite configuration (\\`${settingKey}: false \\`). This setting is either a default setting or was explicitly set in your configuration. Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified. To show unminified code, enable source maps in \\`${settingKey}\\` (e.g. by setting them to \\`hidden\\`).`,\n );\n });\n } else if (viteSourceMap && ['hidden', 'inline', true].includes(viteSourceMap)) {\n updatedSourceMapSetting = viteSourceMap;\n\n if (sentryPluginOptions?.debug) {\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteSourceMap.toString()}\\`. Sentry will keep this source map setting. This will un-minify the code snippet on the Sentry Issue page.`,\n );\n });\n }\n } else {\n updatedSourceMapSetting = 'hidden';\n\n consoleSandbox(() => {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n });\n }\n\n return updatedSourceMapSetting;\n}\n"],"names":[],"mappings":";;AAIA;AACA;AACA;AACO,SAAS,0BAA0B,CAAC,OAAO,EAAyC;AAC3F,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,+CAA+C;AACzD,IAAI,KAAK,EAAE,OAAO;AAClB,IAAI,OAAO,EAAE,MAAM;AACnB,IAAI,MAAM,CAAC,UAAU,EAAE;AACvB,MAAM,OAAO;AACb,QAAQ,GAAG,UAAU;AACrB,QAAQ,KAAK,EAAE;AACf,UAAU,GAAG,UAAU,CAAC,KAAK;AAC7B,UAAU,SAAS,EAAE,2BAA2B,CAAC,UAAU,EAAE,OAAO,CAAC;AACrE,SAAS;AACT,OAAO;AACP,KAAK;AACL,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,2BAA2B;AAC3C,EAAE,UAAU;AACZ,EAAE,mBAAmB;AACrB,EAAiC;AACjC,EAAE,UAAU,CAAC,KAAA,GAAQ,UAAU,CAAC,KAAA,IAAS,EAAE;;AAE3C,EAAE,MAAM,aAAA,GAAgB,UAAU,EAAE,KAAK,EAAE,SAAS;AACpD,EAAE,IAAI,uBAAA,GAA0B,aAAa;;AAE7C,EAAE,MAAM,UAAA,GAAa,sBAAsB;;AAE3C,EAAE,IAAI,aAAA,KAAkB,KAAK,EAAE;AAC/B,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAI,cAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,IAAI;AAClB,QAAQ,CAAC,mFAAmF,EAAE,UAAU,CAAC,2QAA2Q,EAAE,UAAU,CAAC,wCAAwC,CAAC;AAC1a,OAAO;AACP,KAAK,CAAC;AACN,SAAS,IAAI,aAAA,IAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;AAClF,IAAI,uBAAA,GAA0B,aAAa;;AAE3C,IAAI,IAAI,mBAAmB,EAAE,KAAK,EAAE;AACpC,MAAM,cAAc,CAAC,MAAM;AAC3B;AACA,QAAQ,OAAO,CAAC,GAAG;AACnB,UAAU,CAAC,yBAAyB,EAAE,UAAU,CAAC,eAAe,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,4GAA4G,CAAC;AACxM,SAAS;AACT,OAAO,CAAC;AACR;AACA,SAAS;AACT,IAAI,uBAAA,GAA0B,QAAQ;;AAEtC,IAAI,cAAc,CAAC,MAAM;AACzB;AACA,MAAM,OAAO,CAAC,GAAG;AACjB,QAAQ,CAAC,mEAAmE,EAAE,UAAU,CAAC,kFAAkF,CAAC;AAC5K,OAAO;AACP,KAAK,CAAC;AACN;;AAEA,EAAE,OAAO,uBAAuB;AAChC;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import type { ConfigEnv } from 'vite';\nimport { type Plugin } from 'vite';\nimport { makeConfigInjectorPlugin } from './makeConfigInjectorPlugin';\nimport { makeCustomSentryVitePlugins } from './makeCustomSentryVitePlugins';\nimport { makeEnableSourceMapsPlugin } from './makeEnableSourceMapsPlugin';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Vite plugin for Sentry that handles source map uploads and bundle size optimizations.\n *\n * @param options - Configuration options for the Sentry Vite plugin\n * @param viteConfig - The Vite user config object\n * @returns An array of Vite plugins\n */\nexport async function sentryReactRouter(\n options: SentryReactRouterBuildOptions = {},\n config: ConfigEnv,\n): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n\n plugins.push(makeConfigInjectorPlugin(options));\n\n if (process.env.NODE_ENV !== 'development' && config.command === 'build' && config.mode !== 'development') {\n plugins.push(makeEnableSourceMapsPlugin(options));\n plugins.push(...(await makeCustomSentryVitePlugins(options)));\n }\n\n return plugins;\n}\n"],"names":[],"mappings":";;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,iBAAiB;AACvC,EAAE,OAAO,GAAkC,EAAE;AAC7C,EAAE,MAAM;AACR,EAAqB;AACrB,EAAE,MAAM,OAAO,GAAa,EAAE;;AAE9B,EAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;;AAEjD,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAA,KAAa,aAAc,IAAG,MAAM,CAAC,OAAA,KAAY,OAAQ,IAAG,MAAM,CAAC,IAAA,KAAS,aAAa,EAAE;AAC7G,IAAI,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACrD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,2BAA2B,CAAC,OAAO,CAAC,CAAC,CAAC;AACjE;;AAEA,EAAE,OAAO,OAAO;AAChB;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import type { ConfigEnv } from 'vite';\nimport { type Plugin } from 'vite';\nimport { makeConfigInjectorPlugin } from './makeConfigInjectorPlugin';\nimport { makeCustomSentryVitePlugins } from './makeCustomSentryVitePlugins';\nimport { makeEnableSourceMapsPlugin } from './makeEnableSourceMapsPlugin';\nimport type { SentryReactRouterBuildOptions } from './types';\n\n/**\n * A Vite plugin for Sentry that handles source map uploads and bundle size optimizations.\n *\n * @param options - Configuration options for the Sentry Vite plugin\n * @param viteConfig - The Vite user config object\n * @returns An array of Vite plugins\n */\nexport async function sentryReactRouter(\n options: SentryReactRouterBuildOptions = {},\n config: ConfigEnv,\n): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n\n plugins.push(makeConfigInjectorPlugin(options));\n\n if (process.env.NODE_ENV !== 'development' && config.command === 'build' && config.mode !== 'development') {\n plugins.push(makeEnableSourceMapsPlugin(options));\n plugins.push(...(await makeCustomSentryVitePlugins(options)));\n }\n\n return plugins;\n}\n"],"names":[],"mappings":";;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,iBAAiB;AACvC,EAAE,OAAO,GAAkC,EAAE;AAC7C,EAAE,MAAM;AACR,EAAqB;AACrB,EAAE,MAAM,OAAO,GAAa,EAAE;;AAE9B,EAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;;AAEjD,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAA,KAAa,aAAA,IAAiB,MAAM,CAAC,OAAA,KAAY,OAAA,IAAW,MAAM,CAAC,IAAA,KAAS,aAAa,EAAE;AAC7G,IAAI,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACrD,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,2BAA2B,CAAC,OAAO,CAAC,CAAC,CAAC;AACjE;;AAEA,EAAE,OAAO,OAAO;AAChB;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/react-router",
3
- "version": "9.36.0",
3
+ "version": "9.38.0",
4
4
  "description": "Official Sentry SDK for React Router (Framework)",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react-router",
@@ -38,17 +38,18 @@
38
38
  "@opentelemetry/core": "^1.30.1",
39
39
  "@opentelemetry/instrumentation": "0.57.2",
40
40
  "@opentelemetry/semantic-conventions": "^1.34.0",
41
- "@sentry/browser": "9.36.0",
41
+ "@sentry/browser": "9.38.0",
42
42
  "@sentry/cli": "^2.46.0",
43
- "@sentry/core": "9.36.0",
44
- "@sentry/node": "9.36.0",
45
- "@sentry/react": "9.36.0",
43
+ "@sentry/core": "9.38.0",
44
+ "@sentry/node": "9.38.0",
45
+ "@sentry/react": "9.38.0",
46
46
  "@sentry/vite-plugin": "^3.5.0",
47
47
  "glob": "11.0.1"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@react-router/dev": "^7.5.2",
51
51
  "@react-router/node": "^7.5.2",
52
+ "react": "^18.3.1",
52
53
  "react-router": "^7.5.2",
53
54
  "vite": "^6.1.0"
54
55
  },