@sentry/react-router 10.68.0 → 11.0.0-alpha.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 (100) hide show
  1. package/build/cjs/client/createClientInstrumentation.js +18 -12
  2. package/build/cjs/client/createClientInstrumentation.js.map +1 -1
  3. package/build/cjs/client/hydratedRouter.js +4 -1
  4. package/build/cjs/client/hydratedRouter.js.map +1 -1
  5. package/build/cjs/client/tracingIntegration.js +1 -0
  6. package/build/cjs/client/tracingIntegration.js.map +1 -1
  7. package/build/cjs/client/utils.js +6 -2
  8. package/build/cjs/client/utils.js.map +1 -1
  9. package/build/cjs/index.server.js +0 -4
  10. package/build/cjs/index.server.js.map +1 -1
  11. package/build/cjs/server/createSentryHandleRequest.js.map +1 -1
  12. package/build/cjs/server/createServerInstrumentation.js +71 -65
  13. package/build/cjs/server/createServerInstrumentation.js.map +1 -1
  14. package/build/cjs/server/integration/reactRouterServer.js +1 -40
  15. package/build/cjs/server/integration/reactRouterServer.js.map +1 -1
  16. package/build/cjs/server/serverBuild.js +0 -4
  17. package/build/cjs/server/serverBuild.js.map +1 -1
  18. package/build/cjs/server/serverGlobals.js +0 -9
  19. package/build/cjs/server/serverGlobals.js.map +1 -1
  20. package/build/cjs/vite/buildEnd/handleOnBuildEnd.js +26 -14
  21. package/build/cjs/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  22. package/build/cjs/vite/makeCustomSentryVitePlugins.js +29 -10
  23. package/build/cjs/vite/makeCustomSentryVitePlugins.js.map +1 -1
  24. package/build/cjs/vite/makeServerBuildCapturePlugin.js +2 -6
  25. package/build/cjs/vite/makeServerBuildCapturePlugin.js.map +1 -1
  26. package/build/cjs/vite/plugin.js +2 -0
  27. package/build/cjs/vite/plugin.js.map +1 -1
  28. package/build/esm/client/createClientInstrumentation.js +20 -14
  29. package/build/esm/client/createClientInstrumentation.js.map +1 -1
  30. package/build/esm/client/hydratedRouter.js +4 -1
  31. package/build/esm/client/hydratedRouter.js.map +1 -1
  32. package/build/esm/client/tracingIntegration.js +1 -0
  33. package/build/esm/client/tracingIntegration.js.map +1 -1
  34. package/build/esm/client/utils.js +7 -3
  35. package/build/esm/client/utils.js.map +1 -1
  36. package/build/esm/index.server.js +0 -2
  37. package/build/esm/index.server.js.map +1 -1
  38. package/build/esm/package.json +1 -1
  39. package/build/esm/server/createSentryHandleRequest.js.map +1 -1
  40. package/build/esm/server/createServerInstrumentation.js +73 -67
  41. package/build/esm/server/createServerInstrumentation.js.map +1 -1
  42. package/build/esm/server/integration/reactRouterServer.js +3 -41
  43. package/build/esm/server/integration/reactRouterServer.js.map +1 -1
  44. package/build/esm/server/serverBuild.js +1 -4
  45. package/build/esm/server/serverBuild.js.map +1 -1
  46. package/build/esm/server/serverGlobals.js +1 -8
  47. package/build/esm/server/serverGlobals.js.map +1 -1
  48. package/build/esm/vite/buildEnd/handleOnBuildEnd.js +26 -14
  49. package/build/esm/vite/buildEnd/handleOnBuildEnd.js.map +1 -1
  50. package/build/esm/vite/makeCustomSentryVitePlugins.js +28 -9
  51. package/build/esm/vite/makeCustomSentryVitePlugins.js.map +1 -1
  52. package/build/esm/vite/makeServerBuildCapturePlugin.js +2 -6
  53. package/build/esm/vite/makeServerBuildCapturePlugin.js.map +1 -1
  54. package/build/esm/vite/plugin.js +2 -0
  55. package/build/esm/vite/plugin.js.map +1 -1
  56. package/build/types/client/createClientInstrumentation.d.ts.map +1 -1
  57. package/build/types/client/hydratedRouter.d.ts.map +1 -1
  58. package/build/types/client/tracingIntegration.d.ts.map +1 -1
  59. package/build/types/client/utils.d.ts.map +1 -1
  60. package/build/types/index.types.d.ts +1 -0
  61. package/build/types/index.types.d.ts.map +1 -1
  62. package/build/types/server/createSentryHandleRequest.d.ts.map +1 -1
  63. package/build/types/server/createServerInstrumentation.d.ts.map +1 -1
  64. package/build/types/server/index.d.ts +0 -2
  65. package/build/types/server/index.d.ts.map +1 -1
  66. package/build/types/server/integration/reactRouterServer.d.ts +0 -3
  67. package/build/types/server/integration/reactRouterServer.d.ts.map +1 -1
  68. package/build/types/server/serverGlobals.d.ts +0 -10
  69. package/build/types/server/serverGlobals.d.ts.map +1 -1
  70. package/build/types/vite/buildEnd/handleOnBuildEnd.d.ts.map +1 -1
  71. package/build/types/vite/makeCustomSentryVitePlugins.d.ts.map +1 -1
  72. package/build/types/vite/makeServerBuildCapturePlugin.d.ts.map +1 -1
  73. package/build/types/vite/plugin.d.ts.map +1 -1
  74. package/build/types/vite/types.d.ts +1 -1
  75. package/build/types/vite/types.d.ts.map +1 -1
  76. package/package.json +14 -14
  77. package/build/cjs/server/instrumentation/reactRouter.js +0 -106
  78. package/build/cjs/server/instrumentation/reactRouter.js.map +0 -1
  79. package/build/cjs/server/instrumentation/util.js +0 -24
  80. package/build/cjs/server/instrumentation/util.js.map +0 -1
  81. package/build/cjs/server/wrapServerAction.js +0 -56
  82. package/build/cjs/server/wrapServerAction.js.map +0 -1
  83. package/build/cjs/server/wrapServerLoader.js +0 -56
  84. package/build/cjs/server/wrapServerLoader.js.map +0 -1
  85. package/build/esm/server/instrumentation/reactRouter.js +0 -104
  86. package/build/esm/server/instrumentation/reactRouter.js.map +0 -1
  87. package/build/esm/server/instrumentation/util.js +0 -18
  88. package/build/esm/server/instrumentation/util.js.map +0 -1
  89. package/build/esm/server/wrapServerAction.js +0 -54
  90. package/build/esm/server/wrapServerAction.js.map +0 -1
  91. package/build/esm/server/wrapServerLoader.js +0 -54
  92. package/build/esm/server/wrapServerLoader.js.map +0 -1
  93. package/build/types/server/instrumentation/reactRouter.d.ts +0 -19
  94. package/build/types/server/instrumentation/reactRouter.d.ts.map +0 -1
  95. package/build/types/server/instrumentation/util.d.ts +0 -31
  96. package/build/types/server/instrumentation/util.d.ts.map +0 -1
  97. package/build/types/server/wrapServerAction.d.ts +0 -33
  98. package/build/types/server/wrapServerAction.d.ts.map +0 -1
  99. package/build/types/server/wrapServerLoader.d.ts +0 -33
  100. package/build/types/server/wrapServerLoader.d.ts.map +0 -1
@@ -1,56 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
-
3
- const attributes = require('@sentry/conventions/attributes');
4
- const core = require('@sentry/core');
5
- const debugBuild = require('../common/debug-build.js');
6
- const serverGlobals = require('./serverGlobals.js');
7
-
8
- let hasWarnedAboutDuplicateLoaderInstrumentation = false;
9
- function wrapServerLoader(options = {}, loaderFn) {
10
- return async function(args) {
11
- if (serverGlobals.isInstrumentationApiUsed()) {
12
- if (debugBuild.DEBUG_BUILD && !hasWarnedAboutDuplicateLoaderInstrumentation) {
13
- hasWarnedAboutDuplicateLoaderInstrumentation = true;
14
- core.debug.warn(
15
- "wrapServerLoader is redundant when using the instrumentation API. The loader is already instrumented automatically. You can safely remove wrapServerLoader."
16
- );
17
- }
18
- return loaderFn(args);
19
- }
20
- const name = options.name || "Executing Server Loader";
21
- const active = core.getActiveSpan();
22
- if (active) {
23
- const root = core.getRootSpan(active);
24
- const spanData = core.spanToJSON(root);
25
- if (spanData.origin === "auto.http.otel.http") {
26
- const target = spanData.data[attributes.HTTP_TARGET];
27
- if (target) {
28
- core.updateSpanName(root, `${args.request.method} ${target}`);
29
- root.setAttributes({
30
- [core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
31
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.loader"
32
- });
33
- }
34
- }
35
- }
36
- try {
37
- return await core.startSpan(
38
- {
39
- name,
40
- ...options,
41
- attributes: {
42
- [core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.loader",
43
- [core.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.loader",
44
- ...options.attributes
45
- }
46
- },
47
- () => loaderFn(args)
48
- );
49
- } finally {
50
- await core.flushIfServerless();
51
- }
52
- };
53
- }
54
-
55
- exports.wrapServerLoader = wrapServerLoader;
56
- //# sourceMappingURL=wrapServerLoader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import { HTTP_TARGET } from '@sentry/conventions/attributes';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n debug,\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { isInstrumentationApiUsed } from './serverGlobals';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n// Track if we've already warned about duplicate instrumentation\nlet hasWarnedAboutDuplicateLoaderInstrumentation = false;\n\n// todo(v11): Remove this deprecated wrapper in favor of the instrumentation API (`createSentryServerInstrumentation`).\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n *\n * @deprecated Use React Router's instrumentation API instead: export\n * `instrumentations = [createSentryServerInstrumentation()]` from your `entry.server.tsx` to instrument all server\n * loaders without wrapping them individually. This manual wrapper will be removed in a future major.\n *\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>(\n options: SpanOptions = {},\n loaderFn: (args: LoaderFunctionArgs) => Promise<T>,\n): (args: LoaderFunctionArgs) => Promise<T> {\n return async function (args: LoaderFunctionArgs): Promise<T> {\n // Skip instrumentation if instrumentation API is already handling it\n if (isInstrumentationApiUsed()) {\n if (DEBUG_BUILD && !hasWarnedAboutDuplicateLoaderInstrumentation) {\n hasWarnedAboutDuplicateLoaderInstrumentation = true;\n debug.warn(\n 'wrapServerLoader is redundant when using the instrumentation API. ' +\n 'The loader is already instrumented automatically. You can safely remove wrapServerLoader.',\n );\n }\n return loaderFn(args);\n }\n\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line typescript/no-deprecated\n const target = spanData.data[HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n });\n }\n }\n }\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":["isInstrumentationApiUsed","DEBUG_BUILD","debug","getActiveSpan","getRootSpan","spanToJSON","HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_OP","flushIfServerless"],"mappings":";;;;;;;AAwBA,IAAI,4CAAA,GAA+C,KAAA;AA2B5C,SAAS,gBAAA,CACd,OAAA,GAAuB,EAAC,EACxB,QAAA,EAC0C;AAC1C,EAAA,OAAO,eAAgB,IAAA,EAAsC;AAE3D,IAAA,IAAIA,wCAAyB,EAAG;AAC9B,MAAA,IAAIC,sBAAA,IAAe,CAAC,4CAAA,EAA8C;AAChE,QAAA,4CAAA,GAA+C,IAAA;AAC/C,QAAAC,UAAA,CAAM,IAAA;AAAA,UACJ;AAAA,SAEF;AAAA,MACF;AACA,MAAA,OAAO,SAAS,IAAI,CAAA;AAAA,IACtB;AAEA,IAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,yBAAA;AAC7B,IAAA,MAAM,SAASC,kBAAA,EAAc;AAE7B,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,IAAA,GAAOC,iBAAY,MAAM,CAAA;AAC/B,MAAA,MAAM,QAAA,GAAWC,gBAAW,IAAI,CAAA;AAChC,MAAA,IAAI,QAAA,CAAS,WAAW,qBAAA,EAAuB;AAE7C,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,CAAKC,sBAAW,CAAA;AAExC,QAAA,IAAI,MAAA,EAAQ;AAGV,UAAAC,mBAAA,CAAe,MAAM,CAAA,EAAG,IAAA,CAAK,QAAQ,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA;AACvD,UAAA,IAAA,CAAK,aAAA,CAAc;AAAA,YACjB,CAACC,qCAAgC,GAAG,KAAA;AAAA,YACpC,CAACC,qCAAgC,GAAG;AAAA,WACrC,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,OAAO,MAAMC,cAAA;AAAA,QACX;AAAA,UACE,IAAA;AAAA,UACA,GAAG,OAAA;AAAA,UACH,UAAA,EAAY;AAAA,YACV,CAACD,qCAAgC,GAAG,+BAAA;AAAA,YACpC,CAACE,iCAA4B,GAAG,8BAAA;AAAA,YAChC,GAAG,OAAA,CAAQ;AAAA;AACb,SACF;AAAA,QACA,MAAM,SAAS,IAAI;AAAA,OACrB;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAMC,sBAAA,EAAkB;AAAA,IAC1B;AAAA,EACF,CAAA;AACF;;;;"}
@@ -1,104 +0,0 @@
1
- import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
2
- import { HTTP_TARGET } from '@sentry/conventions/attributes';
3
- import { SDK_VERSION, getActiveSpan, getRootSpan, debug, spanToJSON, updateSpanName, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core';
4
- import { DEBUG_BUILD } from '../../common/debug-build.js';
5
- import { isServerBuildLike, setServerBuild } from '../serverBuild.js';
6
- import { isInstrumentationApiUsed, isOtelDataLoaderSpanCreationEnabled } from '../serverGlobals.js';
7
- import { isDataRequest, getOpName, getSpanName } from './util.js';
8
-
9
- const supportedVersions = [">=7.0.0"];
10
- const COMPONENT = "react-router";
11
- class ReactRouterInstrumentation extends InstrumentationBase {
12
- constructor(config = {}) {
13
- super("ReactRouterInstrumentation", SDK_VERSION, config);
14
- }
15
- /**
16
- * Initializes the instrumentation by defining the React Router server modules to be patched.
17
- */
18
- // eslint-disable-next-line @typescript-eslint/naming-convention
19
- init() {
20
- const reactRouterServerModule = new InstrumentationNodeModuleDefinition(
21
- COMPONENT,
22
- supportedVersions,
23
- (moduleExports) => {
24
- return this._createPatchedModuleProxy(moduleExports);
25
- },
26
- (_moduleExports) => {
27
- return _moduleExports;
28
- }
29
- );
30
- return reactRouterServerModule;
31
- }
32
- /**
33
- * Creates a proxy around the React Router module exports that patches the createRequestHandler function.
34
- * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.
35
- */
36
- _createPatchedModuleProxy(moduleExports) {
37
- return new Proxy(moduleExports, {
38
- get(target, prop, receiver) {
39
- if (prop === "createRequestHandler") {
40
- const original = target[prop];
41
- return function sentryWrappedCreateRequestHandler(...args) {
42
- const build = args[0];
43
- if (isServerBuildLike(build)) {
44
- setServerBuild(build);
45
- } else if (typeof build === "function") {
46
- const originalBuildFn = build;
47
- args[0] = async function sentryWrappedBuildFn() {
48
- const resolvedBuild = await originalBuildFn();
49
- if (isServerBuildLike(resolvedBuild)) {
50
- setServerBuild(resolvedBuild);
51
- }
52
- return resolvedBuild;
53
- };
54
- }
55
- const originalRequestHandler = original.apply(this, args);
56
- return async function sentryWrappedRequestHandler(request, initialContext) {
57
- if (isInstrumentationApiUsed() || !isOtelDataLoaderSpanCreationEnabled()) {
58
- return originalRequestHandler(request, initialContext);
59
- }
60
- let url;
61
- try {
62
- url = new URL(request.url);
63
- } catch {
64
- return originalRequestHandler(request, initialContext);
65
- }
66
- if (!isDataRequest(url.pathname)) {
67
- return originalRequestHandler(request, initialContext);
68
- }
69
- const activeSpan = getActiveSpan();
70
- const rootSpan = activeSpan && getRootSpan(activeSpan);
71
- if (!rootSpan) {
72
- DEBUG_BUILD && debug.log("No active root span found, skipping tracing for data request");
73
- return originalRequestHandler(request, initialContext);
74
- }
75
- const spanData = spanToJSON(rootSpan);
76
- const target2 = spanData.data[HTTP_TARGET] || url.pathname;
77
- updateSpanName(rootSpan, `${request.method} ${target2}`);
78
- rootSpan.setAttributes({
79
- [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
80
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.server"
81
- });
82
- return startSpan(
83
- {
84
- name: getSpanName(url.pathname, request.method),
85
- attributes: {
86
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.server",
87
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getOpName(url.pathname, request.method)
88
- }
89
- },
90
- () => {
91
- return originalRequestHandler(request, initialContext);
92
- }
93
- );
94
- };
95
- };
96
- }
97
- return Reflect.get(target, prop, receiver);
98
- }
99
- });
100
- }
101
- }
102
-
103
- export { ReactRouterInstrumentation };
104
- //# sourceMappingURL=reactRouter.js.map
@@ -1 +0,0 @@
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 { HTTP_TARGET } from '@sentry/conventions/attributes';\nimport {\n debug,\n getActiveSpan,\n getRootSpan,\n SDK_VERSION,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type * as reactRouter from 'react-router';\nimport { DEBUG_BUILD } from '../../common/debug-build';\nimport { isServerBuildLike, setServerBuild } from '../serverBuild';\nimport { isInstrumentationApiUsed, isOtelDataLoaderSpanCreationEnabled } from '../serverGlobals';\nimport { getOpName, getSpanName, isDataRequest } 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 // Capture the ServerBuild reference for middleware name lookup\n const build = args[0];\n if (isServerBuildLike(build)) {\n setServerBuild(build);\n } else if (typeof build === 'function') {\n // Build arg can be a factory function (dev mode HMR). Wrap to capture resolved build.\n const originalBuildFn = build as () => unknown;\n args[0] = async function sentryWrappedBuildFn() {\n const resolvedBuild = await originalBuildFn();\n if (isServerBuildLike(resolvedBuild)) {\n setServerBuild(resolvedBuild);\n }\n return resolvedBuild;\n };\n }\n\n const originalRequestHandler = original.apply(this, args);\n\n return async function sentryWrappedRequestHandler(request: Request, initialContext?: unknown) {\n // Skip OTEL span creation when instrumentation API is active or when span creation is not enabled.\n // Checked per-request (not at handler-creation time) because in dev, createRequestHandler runs before entry.server.tsx.\n if (isInstrumentationApiUsed() || !isOtelDataLoaderSpanCreationEnabled()) {\n return originalRequestHandler(request, initialContext);\n }\n\n let url: URL;\n try {\n url = new URL(request.url);\n } catch {\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 && debug.log('No active root span found, skipping tracing for data request');\n return originalRequestHandler(request, initialContext);\n }\n\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n // TODO: try to set derived parameterized route from build here (args[0])\n const spanData = spanToJSON(rootSpan);\n // eslint-disable-next-line typescript/no-deprecated\n const target = spanData.data[HTTP_TARGET] || url.pathname;\n updateSpanName(rootSpan, `${request.method} ${target}`);\n rootSpan.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',\n });\n\n return startSpan(\n {\n name: getSpanName(url.pathname, request.method),\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.server',\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":["target"],"mappings":"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"}
@@ -1,18 +0,0 @@
1
- function getOpName(pathName, requestMethod) {
2
- return isLoaderRequest(pathName, requestMethod) ? "function.react_router.loader" : isActionRequest(pathName, requestMethod) ? "function.react_router.action" : "function.react_router";
3
- }
4
- function getSpanName(pathName, requestMethod) {
5
- return isLoaderRequest(pathName, requestMethod) ? "Executing Server Loader" : isActionRequest(pathName, requestMethod) ? "Executing Server Action" : "Unknown Data Request";
6
- }
7
- function isLoaderRequest(pathname, requestMethod) {
8
- return isDataRequest(pathname) && requestMethod === "GET";
9
- }
10
- function isActionRequest(pathname, requestMethod) {
11
- return isDataRequest(pathname) && requestMethod === "POST";
12
- }
13
- function isDataRequest(pathname) {
14
- return pathname.endsWith(".data");
15
- }
16
-
17
- export { getOpName, getSpanName, isActionRequest, isDataRequest, isLoaderRequest };
18
- //# sourceMappingURL=util.js.map
@@ -1 +0,0 @@
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":"AAKO,SAAS,SAAA,CAAU,UAAkB,aAAA,EAA+B;AACzE,EAAA,OAAO,eAAA,CAAgB,UAAU,aAAa,CAAA,GAC1C,iCACA,eAAA,CAAgB,QAAA,EAAU,aAAa,CAAA,GACrC,8BAAA,GACA,uBAAA;AACR;AAOO,SAAS,WAAA,CAAY,UAAkB,aAAA,EAA+B;AAC3E,EAAA,OAAO,eAAA,CAAgB,UAAU,aAAa,CAAA,GAC1C,4BACA,eAAA,CAAgB,QAAA,EAAU,aAAa,CAAA,GACrC,yBAAA,GACA,sBAAA;AACR;AAOO,SAAS,eAAA,CAAgB,UAAkB,aAAA,EAAgC;AAChF,EAAA,OAAO,aAAA,CAAc,QAAQ,CAAA,IAAK,aAAA,KAAkB,KAAA;AACtD;AAOO,SAAS,eAAA,CAAgB,UAAkB,aAAA,EAAgC;AAChF,EAAA,OAAO,aAAA,CAAc,QAAQ,CAAA,IAAK,aAAA,KAAkB,MAAA;AACtD;AAMO,SAAS,cAAc,QAAA,EAA2B;AACvD,EAAA,OAAO,QAAA,CAAS,SAAS,OAAO,CAAA;AAClC;;;;"}
@@ -1,54 +0,0 @@
1
- import { HTTP_TARGET } from '@sentry/conventions/attributes';
2
- import { debug, getActiveSpan, getRootSpan, spanToJSON, updateSpanName, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_OP, flushIfServerless } from '@sentry/core';
3
- import { DEBUG_BUILD } from '../common/debug-build.js';
4
- import { isInstrumentationApiUsed } from './serverGlobals.js';
5
-
6
- let hasWarnedAboutDuplicateActionInstrumentation = false;
7
- function wrapServerAction(options = {}, actionFn) {
8
- return async function(args) {
9
- if (isInstrumentationApiUsed()) {
10
- if (DEBUG_BUILD && !hasWarnedAboutDuplicateActionInstrumentation) {
11
- hasWarnedAboutDuplicateActionInstrumentation = true;
12
- debug.warn(
13
- "wrapServerAction is redundant when using the instrumentation API. The action is already instrumented automatically. You can safely remove wrapServerAction."
14
- );
15
- }
16
- return actionFn(args);
17
- }
18
- const name = options.name || "Executing Server Action";
19
- const active = getActiveSpan();
20
- if (active) {
21
- const root = getRootSpan(active);
22
- const spanData = spanToJSON(root);
23
- if (spanData.origin === "auto.http.otel.http") {
24
- const target = spanData.data[HTTP_TARGET];
25
- if (target) {
26
- updateSpanName(root, `${args.request.method} ${target}`);
27
- root.setAttributes({
28
- [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
29
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.action"
30
- });
31
- }
32
- }
33
- }
34
- try {
35
- return await startSpan(
36
- {
37
- name,
38
- ...options,
39
- attributes: {
40
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.action",
41
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.action",
42
- ...options.attributes
43
- }
44
- },
45
- () => actionFn(args)
46
- );
47
- } finally {
48
- await flushIfServerless();
49
- }
50
- };
51
- }
52
-
53
- export { wrapServerAction };
54
- //# sourceMappingURL=wrapServerAction.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapServerAction.js","sources":["../../../src/server/wrapServerAction.ts"],"sourcesContent":["import { HTTP_TARGET } from '@sentry/conventions/attributes';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n debug,\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { ActionFunctionArgs } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { isInstrumentationApiUsed } from './serverGlobals';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n// Track if we've already warned about duplicate instrumentation\nlet hasWarnedAboutDuplicateActionInstrumentation = false;\n\n// todo(v11): Remove this deprecated wrapper in favor of the instrumentation API (`createSentryServerInstrumentation`).\n/**\n * Wraps a React Router server action function with Sentry performance monitoring.\n *\n * @deprecated Use React Router's instrumentation API instead: export\n * `instrumentations = [createSentryServerInstrumentation()]` from your `entry.server.tsx` to instrument all server\n * actions without wrapping them individually. This manual wrapper will be removed in a future major.\n *\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>(\n options: SpanOptions = {},\n actionFn: (args: ActionFunctionArgs) => Promise<T>,\n): (args: ActionFunctionArgs) => Promise<T> {\n return async function (args: ActionFunctionArgs): Promise<T> {\n // Skip instrumentation if instrumentation API is already handling it\n if (isInstrumentationApiUsed()) {\n if (DEBUG_BUILD && !hasWarnedAboutDuplicateActionInstrumentation) {\n hasWarnedAboutDuplicateActionInstrumentation = true;\n debug.warn(\n 'wrapServerAction is redundant when using the instrumentation API. ' +\n 'The action is already instrumented automatically. You can safely remove wrapServerAction.',\n );\n }\n return actionFn(args);\n }\n\n const name = options.name || 'Executing Server Action';\n const active = getActiveSpan();\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line typescript/no-deprecated\n const target = spanData.data[HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',\n });\n }\n }\n }\n\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.action',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.action',\n ...options.attributes,\n },\n },\n () => actionFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":[],"mappings":";;;;;AAwBA,IAAI,4CAAA,GAA+C,KAAA;AA2B5C,SAAS,gBAAA,CACd,OAAA,GAAuB,EAAC,EACxB,QAAA,EAC0C;AAC1C,EAAA,OAAO,eAAgB,IAAA,EAAsC;AAE3D,IAAA,IAAI,0BAAyB,EAAG;AAC9B,MAAA,IAAI,WAAA,IAAe,CAAC,4CAAA,EAA8C;AAChE,QAAA,4CAAA,GAA+C,IAAA;AAC/C,QAAA,KAAA,CAAM,IAAA;AAAA,UACJ;AAAA,SAEF;AAAA,MACF;AACA,MAAA,OAAO,SAAS,IAAI,CAAA;AAAA,IACtB;AAEA,IAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,yBAAA;AAC7B,IAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,IAAA,GAAO,YAAY,MAAM,CAAA;AAC/B,MAAA,MAAM,QAAA,GAAW,WAAW,IAAI,CAAA;AAChC,MAAA,IAAI,QAAA,CAAS,WAAW,qBAAA,EAAuB;AAE7C,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,CAAK,WAAW,CAAA;AAExC,QAAA,IAAI,MAAA,EAAQ;AAGV,UAAA,cAAA,CAAe,MAAM,CAAA,EAAG,IAAA,CAAK,QAAQ,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA;AACvD,UAAA,IAAA,CAAK,aAAA,CAAc;AAAA,YACjB,CAAC,gCAAgC,GAAG,KAAA;AAAA,YACpC,CAAC,gCAAgC,GAAG;AAAA,WACrC,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,SAAA;AAAA,QACX;AAAA,UACE,IAAA;AAAA,UACA,GAAG,OAAA;AAAA,UACH,UAAA,EAAY;AAAA,YACV,CAAC,gCAAgC,GAAG,+BAAA;AAAA,YACpC,CAAC,4BAA4B,GAAG,8BAAA;AAAA,YAChC,GAAG,OAAA,CAAQ;AAAA;AACb,SACF;AAAA,QACA,MAAM,SAAS,IAAI;AAAA,OACrB;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAM,iBAAA,EAAkB;AAAA,IAC1B;AAAA,EACF,CAAA;AACF;;;;"}
@@ -1,54 +0,0 @@
1
- import { HTTP_TARGET } from '@sentry/conventions/attributes';
2
- import { debug, getActiveSpan, getRootSpan, spanToJSON, updateSpanName, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, startSpan, SEMANTIC_ATTRIBUTE_SENTRY_OP, flushIfServerless } from '@sentry/core';
3
- import { DEBUG_BUILD } from '../common/debug-build.js';
4
- import { isInstrumentationApiUsed } from './serverGlobals.js';
5
-
6
- let hasWarnedAboutDuplicateLoaderInstrumentation = false;
7
- function wrapServerLoader(options = {}, loaderFn) {
8
- return async function(args) {
9
- if (isInstrumentationApiUsed()) {
10
- if (DEBUG_BUILD && !hasWarnedAboutDuplicateLoaderInstrumentation) {
11
- hasWarnedAboutDuplicateLoaderInstrumentation = true;
12
- debug.warn(
13
- "wrapServerLoader is redundant when using the instrumentation API. The loader is already instrumented automatically. You can safely remove wrapServerLoader."
14
- );
15
- }
16
- return loaderFn(args);
17
- }
18
- const name = options.name || "Executing Server Loader";
19
- const active = getActiveSpan();
20
- if (active) {
21
- const root = getRootSpan(active);
22
- const spanData = spanToJSON(root);
23
- if (spanData.origin === "auto.http.otel.http") {
24
- const target = spanData.data[HTTP_TARGET];
25
- if (target) {
26
- updateSpanName(root, `${args.request.method} ${target}`);
27
- root.setAttributes({
28
- [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: "url",
29
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.loader"
30
- });
31
- }
32
- }
33
- }
34
- try {
35
- return await startSpan(
36
- {
37
- name,
38
- ...options,
39
- attributes: {
40
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.http.react_router.loader",
41
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "function.react_router.loader",
42
- ...options.attributes
43
- }
44
- },
45
- () => loaderFn(args)
46
- );
47
- } finally {
48
- await flushIfServerless();
49
- }
50
- };
51
- }
52
-
53
- export { wrapServerLoader };
54
- //# sourceMappingURL=wrapServerLoader.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapServerLoader.js","sources":["../../../src/server/wrapServerLoader.ts"],"sourcesContent":["import { HTTP_TARGET } from '@sentry/conventions/attributes';\nimport type { SpanAttributes } from '@sentry/core';\nimport {\n debug,\n flushIfServerless,\n getActiveSpan,\n getRootSpan,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n spanToJSON,\n startSpan,\n updateSpanName,\n} from '@sentry/core';\nimport type { LoaderFunctionArgs } from 'react-router';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { isInstrumentationApiUsed } from './serverGlobals';\n\ntype SpanOptions = {\n name?: string;\n attributes?: SpanAttributes;\n};\n\n// Track if we've already warned about duplicate instrumentation\nlet hasWarnedAboutDuplicateLoaderInstrumentation = false;\n\n// todo(v11): Remove this deprecated wrapper in favor of the instrumentation API (`createSentryServerInstrumentation`).\n/**\n * Wraps a React Router server loader function with Sentry performance monitoring.\n *\n * @deprecated Use React Router's instrumentation API instead: export\n * `instrumentations = [createSentryServerInstrumentation()]` from your `entry.server.tsx` to instrument all server\n * loaders without wrapping them individually. This manual wrapper will be removed in a future major.\n *\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>(\n options: SpanOptions = {},\n loaderFn: (args: LoaderFunctionArgs) => Promise<T>,\n): (args: LoaderFunctionArgs) => Promise<T> {\n return async function (args: LoaderFunctionArgs): Promise<T> {\n // Skip instrumentation if instrumentation API is already handling it\n if (isInstrumentationApiUsed()) {\n if (DEBUG_BUILD && !hasWarnedAboutDuplicateLoaderInstrumentation) {\n hasWarnedAboutDuplicateLoaderInstrumentation = true;\n debug.warn(\n 'wrapServerLoader is redundant when using the instrumentation API. ' +\n 'The loader is already instrumented automatically. You can safely remove wrapServerLoader.',\n );\n }\n return loaderFn(args);\n }\n\n const name = options.name || 'Executing Server Loader';\n const active = getActiveSpan();\n\n if (active) {\n const root = getRootSpan(active);\n const spanData = spanToJSON(root);\n if (spanData.origin === 'auto.http.otel.http') {\n // eslint-disable-next-line typescript/no-deprecated\n const target = spanData.data[HTTP_TARGET];\n\n if (target) {\n // We cannot rely on the regular span name inferral here, as the express instrumentation sets `*` as the route\n // So we force this to be a more sensible name here\n updateSpanName(root, `${args.request.method} ${target}`);\n root.setAttributes({\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n });\n }\n }\n }\n try {\n return await startSpan(\n {\n name,\n ...options,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.react_router.loader',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.react_router.loader',\n ...options.attributes,\n },\n },\n () => loaderFn(args),\n );\n } finally {\n await flushIfServerless();\n }\n };\n}\n"],"names":[],"mappings":";;;;;AAwBA,IAAI,4CAAA,GAA+C,KAAA;AA2B5C,SAAS,gBAAA,CACd,OAAA,GAAuB,EAAC,EACxB,QAAA,EAC0C;AAC1C,EAAA,OAAO,eAAgB,IAAA,EAAsC;AAE3D,IAAA,IAAI,0BAAyB,EAAG;AAC9B,MAAA,IAAI,WAAA,IAAe,CAAC,4CAAA,EAA8C;AAChE,QAAA,4CAAA,GAA+C,IAAA;AAC/C,QAAA,KAAA,CAAM,IAAA;AAAA,UACJ;AAAA,SAEF;AAAA,MACF;AACA,MAAA,OAAO,SAAS,IAAI,CAAA;AAAA,IACtB;AAEA,IAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,yBAAA;AAC7B,IAAA,MAAM,SAAS,aAAA,EAAc;AAE7B,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,IAAA,GAAO,YAAY,MAAM,CAAA;AAC/B,MAAA,MAAM,QAAA,GAAW,WAAW,IAAI,CAAA;AAChC,MAAA,IAAI,QAAA,CAAS,WAAW,qBAAA,EAAuB;AAE7C,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,CAAK,WAAW,CAAA;AAExC,QAAA,IAAI,MAAA,EAAQ;AAGV,UAAA,cAAA,CAAe,MAAM,CAAA,EAAG,IAAA,CAAK,QAAQ,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA;AACvD,UAAA,IAAA,CAAK,aAAA,CAAc;AAAA,YACjB,CAAC,gCAAgC,GAAG,KAAA;AAAA,YACpC,CAAC,gCAAgC,GAAG;AAAA,WACrC,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,SAAA;AAAA,QACX;AAAA,UACE,IAAA;AAAA,UACA,GAAG,OAAA;AAAA,UACH,UAAA,EAAY;AAAA,YACV,CAAC,gCAAgC,GAAG,+BAAA;AAAA,YACpC,CAAC,4BAA4B,GAAG,8BAAA;AAAA,YAChC,GAAG,OAAA,CAAQ;AAAA;AACb,SACF;AAAA,QACA,MAAM,SAAS,IAAI;AAAA,OACrB;AAAA,IACF,CAAA,SAAE;AACA,MAAA,MAAM,iBAAA,EAAkB;AAAA,IAC1B;AAAA,EACF,CAAA;AACF;;;;"}
@@ -1,19 +0,0 @@
1
- import type { InstrumentationConfig } from '@opentelemetry/instrumentation';
2
- import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
3
- /**
4
- * Instrumentation for React Router's server request handler.
5
- * This patches the requestHandler function to add Sentry performance monitoring for data loaders.
6
- */
7
- export declare class ReactRouterInstrumentation extends InstrumentationBase<InstrumentationConfig> {
8
- constructor(config?: InstrumentationConfig);
9
- /**
10
- * Initializes the instrumentation by defining the React Router server modules to be patched.
11
- */
12
- protected init(): InstrumentationNodeModuleDefinition;
13
- /**
14
- * Creates a proxy around the React Router module exports that patches the createRequestHandler function.
15
- * This allows us to wrap the request handler to add performance monitoring for data loaders and actions.
16
- */
17
- private _createPatchedModuleProxy;
18
- }
19
- //# sourceMappingURL=reactRouter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactRouter.d.ts","sourceRoot":"","sources":["../../../../src/server/instrumentation/reactRouter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AAyB1G;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,mBAAmB,CAAC,qBAAqB,CAAC;gBACrE,MAAM,GAAE,qBAA0B;IAIrD;;OAEG;IAEH,SAAS,CAAC,IAAI,IAAI,mCAAmC;IAgBrD;;;OAGG;IACH,OAAO,CAAC,yBAAyB;CAkFlC"}
@@ -1,31 +0,0 @@
1
- /**
2
- * Gets the op name for a request based on whether it's a loader or action request.
3
- * @param pathName The URL pathname to check
4
- * @param requestMethod The HTTP request method
5
- */
6
- export declare function getOpName(pathName: string, requestMethod: string): string;
7
- /**
8
- * Gets the span name for a request based on whether it's a loader or action request.
9
- * @param pathName The URL pathname to check
10
- * @param requestMethod The HTTP request method
11
- */
12
- export declare function getSpanName(pathName: string, requestMethod: string): string;
13
- /**
14
- * Checks if the request is a server loader request
15
- * @param pathname The URL pathname to check
16
- * @param requestMethod The HTTP request method
17
- */
18
- export declare function isLoaderRequest(pathname: string, requestMethod: string): boolean;
19
- /**
20
- * Checks if the request is a server action request
21
- * @param pathname The URL pathname to check
22
- * @param requestMethod The HTTP request method
23
- */
24
- export declare function isActionRequest(pathname: string, requestMethod: string): boolean;
25
- /**
26
- * Checks if the request is a react-router data request
27
- * @param pathname The URL pathname to check
28
- */
29
- export declare function isDataRequest(pathname: string): boolean;
30
- export declare const SEMANTIC_ATTRIBUTE_SENTRY_OVERWRITE = "sentry.overwrite-route";
31
- //# sourceMappingURL=util.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../src/server/instrumentation/util.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAMzE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAM3E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEhF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAEhF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,eAAO,MAAM,mCAAmC,2BAA2B,CAAC"}
@@ -1,33 +0,0 @@
1
- import type { SpanAttributes } from '@sentry/core';
2
- import type { ActionFunctionArgs } from 'react-router';
3
- type SpanOptions = {
4
- name?: string;
5
- attributes?: SpanAttributes;
6
- };
7
- /**
8
- * Wraps a React Router server action function with Sentry performance monitoring.
9
- *
10
- * @deprecated Use React Router's instrumentation API instead: export
11
- * `instrumentations = [createSentryServerInstrumentation()]` from your `entry.server.tsx` to instrument all server
12
- * actions without wrapping them individually. This manual wrapper will be removed in a future major.
13
- *
14
- * @param options - Optional span configuration options including name, operation, description and attributes
15
- * @param actionFn - The server action function to wrap
16
- *
17
- * @example
18
- * ```ts
19
- * // Wrap an action function with custom span options
20
- * export const action = wrapServerAction(
21
- * {
22
- * name: 'Submit Form Data',
23
- * description: 'Processes form submission data',
24
- * },
25
- * async ({ request }) => {
26
- * // ... your action logic
27
- * }
28
- * );
29
- * ```
30
- */
31
- export declare function wrapServerAction<T>(options: SpanOptions | undefined, actionFn: (args: ActionFunctionArgs) => Promise<T>): (args: ActionFunctionArgs) => Promise<T>;
32
- export {};
33
- //# sourceMappingURL=wrapServerAction.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapServerAction.d.ts","sourceRoot":"","sources":["../../../src/server/wrapServerAction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAanD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,OAAO,EAAE,WAAW,YAAK,EACzB,QAAQ,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GACjD,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,CAoD1C"}
@@ -1,33 +0,0 @@
1
- import type { SpanAttributes } from '@sentry/core';
2
- import type { LoaderFunctionArgs } from 'react-router';
3
- type SpanOptions = {
4
- name?: string;
5
- attributes?: SpanAttributes;
6
- };
7
- /**
8
- * Wraps a React Router server loader function with Sentry performance monitoring.
9
- *
10
- * @deprecated Use React Router's instrumentation API instead: export
11
- * `instrumentations = [createSentryServerInstrumentation()]` from your `entry.server.tsx` to instrument all server
12
- * loaders without wrapping them individually. This manual wrapper will be removed in a future major.
13
- *
14
- * @param options - Optional span configuration options including name, operation, description and attributes
15
- * @param loaderFn - The server loader function to wrap
16
- *
17
- * @example
18
- * ```ts
19
- * // Wrap a loader function with custom span options
20
- * export const loader = wrapServerLoader(
21
- * {
22
- * name: 'Load Some Data',
23
- * description: 'Loads some data from the db',
24
- * },
25
- * async ({ params }) => {
26
- * // ... your loader logic
27
- * }
28
- * );
29
- * ```
30
- */
31
- export declare function wrapServerLoader<T>(options: SpanOptions | undefined, loaderFn: (args: LoaderFunctionArgs) => Promise<T>): (args: LoaderFunctionArgs) => Promise<T>;
32
- export {};
33
- //# sourceMappingURL=wrapServerLoader.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapServerLoader.d.ts","sourceRoot":"","sources":["../../../src/server/wrapServerLoader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAanD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,OAAO,EAAE,WAAW,YAAK,EACzB,QAAQ,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GACjD,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,CAoD1C"}