@sentry/react-router 10.41.0-beta.0 → 10.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/client/createClientInstrumentation.js +18 -1
- package/build/cjs/client/createClientInstrumentation.js.map +1 -1
- package/build/cjs/server/createServerInstrumentation.js +73 -49
- package/build/cjs/server/createServerInstrumentation.js.map +1 -1
- package/build/cjs/server/instrumentation/reactRouter.js +23 -7
- package/build/cjs/server/instrumentation/reactRouter.js.map +1 -1
- package/build/cjs/server/integration/reactRouterServer.js +11 -8
- package/build/cjs/server/integration/reactRouterServer.js.map +1 -1
- package/build/cjs/server/serverBuild.js +54 -0
- package/build/cjs/server/serverBuild.js.map +1 -0
- package/build/cjs/server/serverGlobals.js +19 -0
- package/build/cjs/server/serverGlobals.js.map +1 -1
- package/build/cjs/vite/makeServerBuildCapturePlugin.js +43 -0
- package/build/cjs/vite/makeServerBuildCapturePlugin.js.map +1 -0
- package/build/cjs/vite/plugin.js +2 -0
- package/build/cjs/vite/plugin.js.map +1 -1
- package/build/esm/client/createClientInstrumentation.js +18 -1
- package/build/esm/client/createClientInstrumentation.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/server/createServerInstrumentation.js +74 -50
- package/build/esm/server/createServerInstrumentation.js.map +1 -1
- package/build/esm/server/instrumentation/reactRouter.js +25 -9
- package/build/esm/server/instrumentation/reactRouter.js.map +1 -1
- package/build/esm/server/integration/reactRouterServer.js +12 -9
- package/build/esm/server/integration/reactRouterServer.js.map +1 -1
- package/build/esm/server/serverBuild.js +48 -0
- package/build/esm/server/serverBuild.js.map +1 -0
- package/build/esm/server/serverGlobals.js +18 -1
- package/build/esm/server/serverGlobals.js.map +1 -1
- package/build/esm/vite/makeServerBuildCapturePlugin.js +41 -0
- package/build/esm/vite/makeServerBuildCapturePlugin.js.map +1 -0
- package/build/esm/vite/plugin.js +2 -0
- package/build/esm/vite/plugin.js.map +1 -1
- package/build/types/client/createClientInstrumentation.d.ts.map +1 -1
- package/build/types/server/createServerInstrumentation.d.ts.map +1 -1
- package/build/types/server/instrumentation/reactRouter.d.ts.map +1 -1
- package/build/types/server/integration/reactRouterServer.d.ts.map +1 -1
- package/build/types/server/serverBuild.d.ts +28 -0
- package/build/types/server/serverBuild.d.ts.map +1 -0
- package/build/types/server/serverGlobals.d.ts +10 -0
- package/build/types/server/serverGlobals.d.ts.map +1 -1
- package/build/types/vite/makeServerBuildCapturePlugin.d.ts +6 -0
- package/build/types/vite/makeServerBuildCapturePlugin.d.ts.map +1 -0
- package/build/types/vite/plugin.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
|
|
2
2
|
import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';
|
|
3
|
-
import { SDK_VERSION,
|
|
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
4
|
import { DEBUG_BUILD } from '../../common/debug-build.js';
|
|
5
|
-
import {
|
|
5
|
+
import { isServerBuildLike, setServerBuild } from '../serverBuild.js';
|
|
6
|
+
import { isInstrumentationApiUsed, isOtelDataLoaderSpanCreationEnabled } from '../serverGlobals.js';
|
|
6
7
|
import { isDataRequest, getOpName, getSpanName } from './util.js';
|
|
7
8
|
|
|
8
9
|
const supportedVersions = ['>=7.0.0'];
|
|
@@ -47,9 +48,31 @@ class ReactRouterInstrumentation extends InstrumentationBase {
|
|
|
47
48
|
if (prop === 'createRequestHandler') {
|
|
48
49
|
const original = target[prop];
|
|
49
50
|
return function sentryWrappedCreateRequestHandler( ...args) {
|
|
51
|
+
// Capture the ServerBuild reference for middleware name lookup
|
|
52
|
+
const build = args[0];
|
|
53
|
+
if (isServerBuildLike(build)) {
|
|
54
|
+
setServerBuild(build);
|
|
55
|
+
} else if (typeof build === 'function') {
|
|
56
|
+
// Build arg can be a factory function (dev mode HMR). Wrap to capture resolved build.
|
|
57
|
+
const originalBuildFn = build ;
|
|
58
|
+
args[0] = async function sentryWrappedBuildFn() {
|
|
59
|
+
const resolvedBuild = await originalBuildFn();
|
|
60
|
+
if (isServerBuildLike(resolvedBuild)) {
|
|
61
|
+
setServerBuild(resolvedBuild);
|
|
62
|
+
}
|
|
63
|
+
return resolvedBuild;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
50
67
|
const originalRequestHandler = original.apply(this, args);
|
|
51
68
|
|
|
52
69
|
return async function sentryWrappedRequestHandler(request, initialContext) {
|
|
70
|
+
// Skip OTEL span creation when instrumentation API is active or when span creation is not enabled.
|
|
71
|
+
// Checked per-request (not at handler-creation time) because in dev, createRequestHandler runs before entry.server.tsx.
|
|
72
|
+
if (isInstrumentationApiUsed() || !isOtelDataLoaderSpanCreationEnabled()) {
|
|
73
|
+
return originalRequestHandler(request, initialContext);
|
|
74
|
+
}
|
|
75
|
+
|
|
53
76
|
let url;
|
|
54
77
|
try {
|
|
55
78
|
url = new URL(request.url);
|
|
@@ -62,13 +85,6 @@ class ReactRouterInstrumentation extends InstrumentationBase {
|
|
|
62
85
|
return originalRequestHandler(request, initialContext);
|
|
63
86
|
}
|
|
64
87
|
|
|
65
|
-
// Skip OTEL instrumentation if instrumentation API is being used
|
|
66
|
-
// as it handles loader/action spans itself
|
|
67
|
-
if (isInstrumentationApiUsed()) {
|
|
68
|
-
DEBUG_BUILD && debug.log('Skipping OTEL loader/action instrumentation - using instrumentation API');
|
|
69
|
-
return originalRequestHandler(request, initialContext);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
88
|
const activeSpan = getActiveSpan();
|
|
73
89
|
const rootSpan = activeSpan && getRootSpan(activeSpan);
|
|
74
90
|
|
|
@@ -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 { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\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 { isInstrumentationApiUsed } 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 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 {\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
|
|
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 { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';\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 deprecation/deprecation\n const target = spanData.data[SEMATTRS_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":[],"mappings":"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"}
|
|
@@ -2,7 +2,8 @@ import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
|
|
|
2
2
|
import { defineIntegration } from '@sentry/core';
|
|
3
3
|
import { generateInstrumentOnce, NODE_VERSION } from '@sentry/node';
|
|
4
4
|
import { ReactRouterInstrumentation } from '../instrumentation/reactRouter.js';
|
|
5
|
-
import {
|
|
5
|
+
import { registerServerBuildGlobal } from '../serverBuild.js';
|
|
6
|
+
import { enableOtelDataLoaderSpanCreation } from '../serverGlobals.js';
|
|
6
7
|
|
|
7
8
|
const INTEGRATION_NAME = 'ReactRouterServer';
|
|
8
9
|
|
|
@@ -13,6 +14,8 @@ const instrumentReactRouter = generateInstrumentOnce(INTEGRATION_NAME, () => {
|
|
|
13
14
|
const instrumentReactRouterServer = Object.assign(
|
|
14
15
|
() => {
|
|
15
16
|
instrumentReactRouter();
|
|
17
|
+
// Register global for Vite plugin ServerBuild capture
|
|
18
|
+
registerServerBuildGlobal();
|
|
16
19
|
},
|
|
17
20
|
{ id: INTEGRATION_NAME },
|
|
18
21
|
);
|
|
@@ -24,17 +27,17 @@ const reactRouterServerIntegration = defineIntegration(() => {
|
|
|
24
27
|
return {
|
|
25
28
|
name: INTEGRATION_NAME,
|
|
26
29
|
setupOnce() {
|
|
27
|
-
//
|
|
28
|
-
if (isInstrumentationApiUsed()) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
30
|
+
// Enable OTEL data-loader spans only on Node versions without the diagnostics_channel-based instrumentation API.
|
|
32
31
|
if (
|
|
33
|
-
(NODE_VERSION.major === 20 && NODE_VERSION.minor < 19) ||
|
|
34
|
-
(NODE_VERSION.major === 22 && NODE_VERSION.minor < 12)
|
|
32
|
+
(NODE_VERSION.major === 20 && NODE_VERSION.minor < 19) ||
|
|
33
|
+
(NODE_VERSION.major === 22 && NODE_VERSION.minor < 12)
|
|
35
34
|
) {
|
|
36
|
-
|
|
35
|
+
enableOtelDataLoaderSpanCreation();
|
|
37
36
|
}
|
|
37
|
+
|
|
38
|
+
// Always install to capture ServerBuild for middleware names.
|
|
39
|
+
// Skips per-request wrapping when instrumentation API is active or OTEL span creation is disabled.
|
|
40
|
+
instrumentReactRouterServer();
|
|
38
41
|
},
|
|
39
42
|
processEvent(event) {
|
|
40
43
|
// Express generates bogus `*` routes for data loaders, which we want to remove here
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactRouterServer.js","sources":["../../../../src/server/integration/reactRouterServer.ts"],"sourcesContent":["import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce, NODE_VERSION } from '@sentry/node';\nimport { ReactRouterInstrumentation } from '../instrumentation/reactRouter';\nimport {
|
|
1
|
+
{"version":3,"file":"reactRouterServer.js","sources":["../../../../src/server/integration/reactRouterServer.ts"],"sourcesContent":["import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport { defineIntegration } from '@sentry/core';\nimport { generateInstrumentOnce, NODE_VERSION } from '@sentry/node';\nimport { ReactRouterInstrumentation } from '../instrumentation/reactRouter';\nimport { registerServerBuildGlobal } from '../serverBuild';\nimport { enableOtelDataLoaderSpanCreation } from '../serverGlobals';\n\nconst INTEGRATION_NAME = 'ReactRouterServer';\n\nconst instrumentReactRouter = generateInstrumentOnce(INTEGRATION_NAME, () => {\n return new ReactRouterInstrumentation();\n});\n\nexport const instrumentReactRouterServer = Object.assign(\n (): void => {\n instrumentReactRouter();\n // Register global for Vite plugin ServerBuild capture\n registerServerBuildGlobal();\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 // Enable OTEL data-loader spans only on Node versions without the diagnostics_channel-based instrumentation API.\n if (\n (NODE_VERSION.major === 20 && NODE_VERSION.minor < 19) ||\n (NODE_VERSION.major === 22 && NODE_VERSION.minor < 12)\n ) {\n enableOtelDataLoaderSpanCreation();\n }\n\n // Always install to capture ServerBuild for middleware names.\n // Skips per-request wrapping when instrumentation API is active or OTEL span creation is disabled.\n instrumentReactRouterServer();\n },\n processEvent(event) {\n // Express generates bogus `*` routes for data loaders, which we want to remove here\n // we cannot do this earlier because some OTEL instrumentation adds this at some unexpected point\n if (\n event.type === 'transaction' &&\n event.contexts?.trace?.data &&\n event.contexts.trace.data[ATTR_HTTP_ROUTE] === '*'\n ) {\n const origin = event.contexts.trace.origin;\n const isInstrumentationApiOrigin = origin?.includes('instrumentation_api');\n\n // For instrumentation_api, always clean up bogus `*` route since we set better names\n // For legacy, only clean up if the name has been adjusted (not METHOD *)\n if (isInstrumentationApiOrigin || !event.transaction?.endsWith(' *')) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete event.contexts.trace.data[ATTR_HTTP_ROUTE];\n }\n }\n\n return event;\n },\n };\n});\n"],"names":[],"mappings":";;;;;;;AAOA,MAAM,gBAAA,GAAmB,mBAAmB;;AAE5C,MAAM,qBAAA,GAAwB,sBAAsB,CAAC,gBAAgB,EAAE,MAAM;AAC7E,EAAE,OAAO,IAAI,0BAA0B,EAAE;AACzC,CAAC,CAAC;;AAEK,MAAM,2BAAA,GAA8B,MAAM,CAAC,MAAM;AACxD,EAAE,MAAY;AACd,IAAI,qBAAqB,EAAE;AAC3B;AACA,IAAI,yBAAyB,EAAE;AAC/B,EAAE,CAAC;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;AACA,MAAM;AACN,QAAQ,CAAC,YAAY,CAAC,KAAA,KAAU,EAAA,IAAM,YAAY,CAAC,KAAA,GAAQ,EAAE;AAC7D,SAAS,YAAY,CAAC,KAAA,KAAU,EAAA,IAAM,YAAY,CAAC,KAAA,GAAQ,EAAE;AAC7D,QAAQ;AACR,QAAQ,gCAAgC,EAAE;AAC1C,MAAM;;AAEN;AACA;AACA,MAAM,2BAA2B,EAAE;AACnC,IAAI,CAAC;AACL,IAAI,YAAY,CAAC,KAAK,EAAE;AACxB;AACA;AACA,MAAM;AACN,QAAQ,KAAK,CAAC,IAAA,KAAS,aAAA;AACvB,QAAQ,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAA;AAC/B,QAAQ,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAA,KAAM;AACvD,QAAQ;AACR,QAAQ,MAAM,SAAS,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM;AAClD,QAAQ,MAAM,6BAA6B,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC;;AAElF;AACA;AACA,QAAQ,IAAI,0BAAA,IAA8B,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE;AAC9E;AACA,UAAU,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;AAC3D,QAAQ;AACR,MAAM;;AAEN,MAAM,OAAO,KAAK;AAClB,IAAI,CAAC;AACL,GAAG;AACH,CAAC;;;;"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GLOBAL_OBJ } from '@sentry/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Subset of ServerBuild shape for middleware name lookup.
|
|
5
|
+
* The official React Router types don't expose `middleware` on route modules yet.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** @internal */
|
|
10
|
+
const GLOBAL_KEY = '__sentrySetServerBuild';
|
|
11
|
+
|
|
12
|
+
// ServerBuild reference for middleware name lookup. Updated on each createRequestHandler call.
|
|
13
|
+
let _serverBuild;
|
|
14
|
+
|
|
15
|
+
/** @internal */
|
|
16
|
+
function isServerBuildLike(build) {
|
|
17
|
+
return (
|
|
18
|
+
build !== null &&
|
|
19
|
+
typeof build === 'object' &&
|
|
20
|
+
'routes' in build &&
|
|
21
|
+
build.routes !== null &&
|
|
22
|
+
typeof build.routes === 'object'
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** @internal */
|
|
27
|
+
function setServerBuild(build) {
|
|
28
|
+
_serverBuild = build;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @internal */
|
|
32
|
+
function getMiddlewareName(routeId, index) {
|
|
33
|
+
if (!_serverBuild?.routes) return undefined;
|
|
34
|
+
|
|
35
|
+
const route = _serverBuild.routes[routeId];
|
|
36
|
+
if (!route?.module?.middleware) return undefined;
|
|
37
|
+
|
|
38
|
+
const middlewareFn = route.module.middleware[index];
|
|
39
|
+
return middlewareFn?.name || undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** @internal */
|
|
43
|
+
function registerServerBuildGlobal() {
|
|
44
|
+
(GLOBAL_OBJ )[GLOBAL_KEY] = setServerBuild;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { GLOBAL_KEY, getMiddlewareName, isServerBuildLike, registerServerBuildGlobal, setServerBuild };
|
|
48
|
+
//# sourceMappingURL=serverBuild.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverBuild.js","sources":["../../../src/server/serverBuild.ts"],"sourcesContent":["import { GLOBAL_OBJ } from '@sentry/core';\n\n/**\n * Subset of ServerBuild shape for middleware name lookup.\n * The official React Router types don't expose `middleware` on route modules yet.\n * @internal\n */\ninterface ServerBuildLike {\n routes?: Record<\n string,\n {\n module?: {\n middleware?: Array<{ name?: string }>;\n };\n }\n >;\n}\n\n/** @internal */\nexport const GLOBAL_KEY = '__sentrySetServerBuild';\n\ntype GlobalObjWithBuildCapture = typeof GLOBAL_OBJ & {\n [GLOBAL_KEY]?: (build: ServerBuildLike) => void;\n};\n\n// ServerBuild reference for middleware name lookup. Updated on each createRequestHandler call.\nlet _serverBuild: ServerBuildLike | undefined;\n\n/** @internal */\nexport function isServerBuildLike(build: unknown): build is ServerBuildLike {\n return (\n build !== null &&\n typeof build === 'object' &&\n 'routes' in build &&\n build.routes !== null &&\n typeof build.routes === 'object'\n );\n}\n\n/** @internal */\nexport function setServerBuild(build: ServerBuildLike): void {\n _serverBuild = build;\n}\n\n/** @internal */\nexport function getMiddlewareName(routeId: string, index: number): string | undefined {\n if (!_serverBuild?.routes) return undefined;\n\n const route = _serverBuild.routes[routeId];\n if (!route?.module?.middleware) return undefined;\n\n const middlewareFn = route.module.middleware[index];\n return middlewareFn?.name || undefined;\n}\n\n/** @internal */\nexport function registerServerBuildGlobal(): void {\n (GLOBAL_OBJ as GlobalObjWithBuildCapture)[GLOBAL_KEY] = setServerBuild;\n}\n\n/** @internal Exported for testing. */\nexport function _resetServerBuild(): void {\n _serverBuild = undefined;\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete (GLOBAL_OBJ as GlobalObjWithBuildCapture)[GLOBAL_KEY];\n}\n"],"names":[],"mappings":";;AAEA;AACA;AACA;AACA;AACA;;AAYA;AACO,MAAM,UAAA,GAAa;;AAM1B;AACA,IAAI,YAAY;;AAEhB;AACO,SAAS,iBAAiB,CAAC,KAAK,EAAqC;AAC5E,EAAE;AACF,IAAI,KAAA,KAAU,IAAA;AACd,IAAI,OAAO,KAAA,KAAU,QAAA;AACrB,IAAI,QAAA,IAAY,KAAA;AAChB,IAAI,KAAK,CAAC,MAAA,KAAW,IAAA;AACrB,IAAI,OAAO,KAAK,CAAC,MAAA,KAAW;AAC5B;AACA;;AAEA;AACO,SAAS,cAAc,CAAC,KAAK,EAAyB;AAC7D,EAAE,YAAA,GAAe,KAAK;AACtB;;AAEA;AACO,SAAS,iBAAiB,CAAC,OAAO,EAAU,KAAK,EAA8B;AACtF,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,SAAS;;AAE7C,EAAE,MAAM,QAAQ,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;AAC5C,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,SAAS;;AAElD,EAAE,MAAM,YAAA,GAAe,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;AACrD,EAAE,OAAO,YAAY,EAAE,IAAA,IAAQ,SAAS;AACxC;;AAEA;AACO,SAAS,yBAAyB,GAAS;AAClD,EAAE,CAAC,UAAA,GAAyC,UAAU,CAAA,GAAI,cAAc;AACxE;;;;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { GLOBAL_OBJ } from '@sentry/core';
|
|
2
2
|
|
|
3
3
|
const SENTRY_SERVER_INSTRUMENTATION_FLAG = '__sentryReactRouterServerInstrumentationUsed';
|
|
4
|
+
const SENTRY_OTEL_SPAN_CREATION_FLAG = '__sentryReactRouterOtelSpanCreationEnabled';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Mark that the React Router instrumentation API is being used on the server.
|
|
@@ -18,5 +19,21 @@ function isInstrumentationApiUsed() {
|
|
|
18
19
|
return !!(GLOBAL_OBJ )[SENTRY_SERVER_INSTRUMENTATION_FLAG];
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Enable OTEL data-loader span creation for React Router server.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
function enableOtelDataLoaderSpanCreation() {
|
|
27
|
+
(GLOBAL_OBJ )[SENTRY_OTEL_SPAN_CREATION_FLAG] = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if OTEL data-loader span creation is enabled for React Router server.
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
function isOtelDataLoaderSpanCreationEnabled() {
|
|
35
|
+
return !!(GLOBAL_OBJ )[SENTRY_OTEL_SPAN_CREATION_FLAG];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { enableOtelDataLoaderSpanCreation, isInstrumentationApiUsed, isOtelDataLoaderSpanCreationEnabled, markInstrumentationApiUsed };
|
|
22
39
|
//# sourceMappingURL=serverGlobals.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverGlobals.js","sources":["../../../src/server/serverGlobals.ts"],"sourcesContent":["import { GLOBAL_OBJ } from '@sentry/core';\n\nconst SENTRY_SERVER_INSTRUMENTATION_FLAG = '__sentryReactRouterServerInstrumentationUsed';\n\ntype GlobalObjWithFlag = typeof GLOBAL_OBJ & {\n [SENTRY_SERVER_INSTRUMENTATION_FLAG]?: boolean;\n};\n\n/**\n * Mark that the React Router instrumentation API is being used on the server.\n * @internal\n */\nexport function markInstrumentationApiUsed(): void {\n (GLOBAL_OBJ as GlobalObjWithFlag)[SENTRY_SERVER_INSTRUMENTATION_FLAG] = true;\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the server.\n * @experimental\n */\nexport function isInstrumentationApiUsed(): boolean {\n return !!(GLOBAL_OBJ as GlobalObjWithFlag)[SENTRY_SERVER_INSTRUMENTATION_FLAG];\n}\n"],"names":[],"mappings":";;AAEA,MAAM,kCAAA,GAAqC,8CAA8C;;
|
|
1
|
+
{"version":3,"file":"serverGlobals.js","sources":["../../../src/server/serverGlobals.ts"],"sourcesContent":["import { GLOBAL_OBJ } from '@sentry/core';\n\nconst SENTRY_SERVER_INSTRUMENTATION_FLAG = '__sentryReactRouterServerInstrumentationUsed';\nconst SENTRY_OTEL_SPAN_CREATION_FLAG = '__sentryReactRouterOtelSpanCreationEnabled';\n\ntype GlobalObjWithFlag = typeof GLOBAL_OBJ & {\n [SENTRY_SERVER_INSTRUMENTATION_FLAG]?: boolean;\n [SENTRY_OTEL_SPAN_CREATION_FLAG]?: boolean;\n};\n\n/**\n * Mark that the React Router instrumentation API is being used on the server.\n * @internal\n */\nexport function markInstrumentationApiUsed(): void {\n (GLOBAL_OBJ as GlobalObjWithFlag)[SENTRY_SERVER_INSTRUMENTATION_FLAG] = true;\n}\n\n/**\n * Check if React Router's instrumentation API is being used on the server.\n * @experimental\n */\nexport function isInstrumentationApiUsed(): boolean {\n return !!(GLOBAL_OBJ as GlobalObjWithFlag)[SENTRY_SERVER_INSTRUMENTATION_FLAG];\n}\n\n/**\n * Enable OTEL data-loader span creation for React Router server.\n * @internal\n */\nexport function enableOtelDataLoaderSpanCreation(): void {\n (GLOBAL_OBJ as GlobalObjWithFlag)[SENTRY_OTEL_SPAN_CREATION_FLAG] = true;\n}\n\n/**\n * Check if OTEL data-loader span creation is enabled for React Router server.\n * @internal\n */\nexport function isOtelDataLoaderSpanCreationEnabled(): boolean {\n return !!(GLOBAL_OBJ as GlobalObjWithFlag)[SENTRY_OTEL_SPAN_CREATION_FLAG];\n}\n"],"names":[],"mappings":";;AAEA,MAAM,kCAAA,GAAqC,8CAA8C;AACzF,MAAM,8BAAA,GAAiC,4CAA4C;;AAOnF;AACA;AACA;AACA;AACO,SAAS,0BAA0B,GAAS;AACnD,EAAE,CAAC,UAAA,GAAiC,kCAAkC,CAAA,GAAI,IAAI;AAC9E;;AAEA;AACA;AACA;AACA;AACO,SAAS,wBAAwB,GAAY;AACpD,EAAE,OAAO,CAAC,CAAC,CAAC,aAAiC,kCAAkC,CAAC;AAChF;;AAEA;AACA;AACA;AACA;AACO,SAAS,gCAAgC,GAAS;AACzD,EAAE,CAAC,UAAA,GAAiC,8BAA8B,CAAA,GAAI,IAAI;AAC1E;;AAEA;AACA;AACA;AACA;AACO,SAAS,mCAAmC,GAAY;AAC/D,EAAE,OAAO,CAAC,CAAC,CAAC,aAAiC,8BAA8B,CAAC;AAC5E;;;;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { GLOBAL_KEY } from '../server/serverBuild.js';
|
|
2
|
+
|
|
3
|
+
const SERVER_BUILD_MODULE_ID = 'virtual:react-router/server-build';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A Sentry plugin for React Router to capture the server build for middleware name resolution.
|
|
7
|
+
*/
|
|
8
|
+
function makeServerBuildCapturePlugin() {
|
|
9
|
+
let isSsrBuild = false;
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
name: 'sentry-react-router-server-build-capture',
|
|
13
|
+
enforce: 'post',
|
|
14
|
+
|
|
15
|
+
configResolved(config) {
|
|
16
|
+
isSsrBuild = !!config.build.ssr;
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
transform(code, id) {
|
|
20
|
+
if (!isSsrBuild) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!id.includes(SERVER_BUILD_MODULE_ID)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// `routes` is a module-scope export in the virtual:react-router/server-build module
|
|
29
|
+
const injectedCode = `${code}
|
|
30
|
+
if (typeof globalThis !== 'undefined' && typeof globalThis["${GLOBAL_KEY}"] === 'function') {
|
|
31
|
+
globalThis["${GLOBAL_KEY}"]({ routes });
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
return { code: injectedCode, map: null };
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { makeServerBuildCapturePlugin };
|
|
41
|
+
//# sourceMappingURL=makeServerBuildCapturePlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"makeServerBuildCapturePlugin.js","sources":["../../../src/vite/makeServerBuildCapturePlugin.ts"],"sourcesContent":["import { type Plugin } from 'vite';\nimport { GLOBAL_KEY } from '../server/serverBuild';\n\nconst SERVER_BUILD_MODULE_ID = 'virtual:react-router/server-build';\n\n/**\n * A Sentry plugin for React Router to capture the server build for middleware name resolution.\n */\nexport function makeServerBuildCapturePlugin(): Plugin {\n let isSsrBuild = false;\n\n return {\n name: 'sentry-react-router-server-build-capture',\n enforce: 'post',\n\n configResolved(config) {\n isSsrBuild = !!config.build.ssr;\n },\n\n transform(code, id) {\n if (!isSsrBuild) {\n return null;\n }\n\n if (!id.includes(SERVER_BUILD_MODULE_ID)) {\n return null;\n }\n\n // `routes` is a module-scope export in the virtual:react-router/server-build module\n const injectedCode = `${code}\nif (typeof globalThis !== 'undefined' && typeof globalThis[\"${GLOBAL_KEY}\"] === 'function') {\n globalThis[\"${GLOBAL_KEY}\"]({ routes });\n}\n`;\n\n return { code: injectedCode, map: null };\n },\n };\n}\n"],"names":[],"mappings":";;AAGA,MAAM,sBAAA,GAAyB,mCAAmC;;AAElE;AACA;AACA;AACO,SAAS,4BAA4B,GAAW;AACvD,EAAE,IAAI,UAAA,GAAa,KAAK;;AAExB,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,0CAA0C;AACpD,IAAI,OAAO,EAAE,MAAM;;AAEnB,IAAI,cAAc,CAAC,MAAM,EAAE;AAC3B,MAAM,UAAA,GAAa,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG;AACrC,IAAI,CAAC;;AAEL,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE;AACxB,MAAM,IAAI,CAAC,UAAU,EAAE;AACvB,QAAQ,OAAO,IAAI;AACnB,MAAM;;AAEN,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE;AAChD,QAAQ,OAAO,IAAI;AACnB,MAAM;;AAEN;AACA,MAAM,MAAM,YAAA,GAAe,CAAC,EAAA,IAAA;AACA,4DAAA,EAAA,UAAA,CAAA;AACA,cAAA,EAAA,UAAA,CAAA;AACA;AACA,CAAA;;AAEA,MAAA,OAAA,EAAA,IAAA,EAAA,YAAA,EAAA,GAAA,EAAA,IAAA,EAAA;AACA,IAAA,CAAA;AACA,GAAA;AACA;;;;"}
|
package/build/esm/vite/plugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { makeConfigInjectorPlugin } from './makeConfigInjectorPlugin.js';
|
|
2
2
|
import { makeCustomSentryVitePlugins } from './makeCustomSentryVitePlugins.js';
|
|
3
3
|
import { makeEnableSourceMapsPlugin } from './makeEnableSourceMapsPlugin.js';
|
|
4
|
+
import { makeServerBuildCapturePlugin } from './makeServerBuildCapturePlugin.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* A Vite plugin for Sentry that handles source map uploads and bundle size optimizations.
|
|
@@ -16,6 +17,7 @@ async function sentryReactRouter(
|
|
|
16
17
|
const plugins = [];
|
|
17
18
|
|
|
18
19
|
plugins.push(makeConfigInjectorPlugin(options));
|
|
20
|
+
plugins.push(makeServerBuildCapturePlugin());
|
|
19
21
|
|
|
20
22
|
if (process.env.NODE_ENV !== 'development' && viteConfig.command === 'build' && viteConfig.mode !== 'development') {
|
|
21
23
|
plugins.push(makeEnableSourceMapsPlugin(options));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import type { ConfigEnv, 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 viteConfig: ConfigEnv,\n): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n\n plugins.push(makeConfigInjectorPlugin(options));\n\n if (process.env.NODE_ENV !== 'development' && viteConfig.command === 'build' && viteConfig.mode !== 'development') {\n plugins.push(makeEnableSourceMapsPlugin(options));\n plugins.push(...(await makeCustomSentryVitePlugins(options)));\n }\n\n return plugins;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import type { ConfigEnv, Plugin } from 'vite';\nimport { makeConfigInjectorPlugin } from './makeConfigInjectorPlugin';\nimport { makeCustomSentryVitePlugins } from './makeCustomSentryVitePlugins';\nimport { makeEnableSourceMapsPlugin } from './makeEnableSourceMapsPlugin';\nimport { makeServerBuildCapturePlugin } from './makeServerBuildCapturePlugin';\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 viteConfig: ConfigEnv,\n): Promise<Plugin[]> {\n const plugins: Plugin[] = [];\n\n plugins.push(makeConfigInjectorPlugin(options));\n plugins.push(makeServerBuildCapturePlugin());\n\n if (process.env.NODE_ENV !== 'development' && viteConfig.command === 'build' && viteConfig.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,UAAU;AACZ,EAAqB;AACrB,EAAE,MAAM,OAAO,GAAa,EAAE;;AAE9B,EAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;AACjD,EAAE,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC;;AAE9C,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAA,KAAa,aAAA,IAAiB,UAAU,CAAC,OAAA,KAAY,OAAA,IAAW,UAAU,CAAC,IAAA,KAAS,aAAa,EAAE;AACrH,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,EAAE;;AAEF,EAAE,OAAO,OAAO;AAChB;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createClientInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/client/createClientInstrumentation.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,qBAAqB,EAA6C,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"createClientInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/client/createClientInstrumentation.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,qBAAqB,EAA6C,MAAM,iBAAiB,CAAC;AAwBxG;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,GAAE,wCAA6C,GACrD,qBAAqB,CAgRvB;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,IAAI,OAAO,CAExD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createServerInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/server/createServerInstrumentation.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAqD,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"createServerInstrumentation.d.ts","sourceRoot":"","sources":["../../../src/server/createServerInstrumentation.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAqD,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAQhH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,wCAAwC;IACvD;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,GAAE,wCAA6C,GACrD,qBAAqB,CAmMvB"}
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactRouterServer.d.ts","sourceRoot":"","sources":["../../../../src/server/integration/reactRouterServer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reactRouterServer.d.ts","sourceRoot":"","sources":["../../../../src/server/integration/reactRouterServer.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,2BAA2B,SAClC,IAAI;;CAMT,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,4BAA4B,0CAsCvC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subset of ServerBuild shape for middleware name lookup.
|
|
3
|
+
* The official React Router types don't expose `middleware` on route modules yet.
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
interface ServerBuildLike {
|
|
7
|
+
routes?: Record<string, {
|
|
8
|
+
module?: {
|
|
9
|
+
middleware?: Array<{
|
|
10
|
+
name?: string;
|
|
11
|
+
}>;
|
|
12
|
+
};
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
/** @internal */
|
|
16
|
+
export declare const GLOBAL_KEY = "__sentrySetServerBuild";
|
|
17
|
+
/** @internal */
|
|
18
|
+
export declare function isServerBuildLike(build: unknown): build is ServerBuildLike;
|
|
19
|
+
/** @internal */
|
|
20
|
+
export declare function setServerBuild(build: ServerBuildLike): void;
|
|
21
|
+
/** @internal */
|
|
22
|
+
export declare function getMiddlewareName(routeId: string, index: number): string | undefined;
|
|
23
|
+
/** @internal */
|
|
24
|
+
export declare function registerServerBuildGlobal(): void;
|
|
25
|
+
/** @internal Exported for testing. */
|
|
26
|
+
export declare function _resetServerBuild(): void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=serverBuild.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serverBuild.d.ts","sourceRoot":"","sources":["../../../src/server/serverBuild.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN;QACE,MAAM,CAAC,EAAE;YACP,UAAU,CAAC,EAAE,KAAK,CAAC;gBAAE,IAAI,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SACvC,CAAC;KACH,CACF,CAAC;CACH;AAED,gBAAgB;AAChB,eAAO,MAAM,UAAU,2BAA2B,CAAC;AASnD,gBAAgB;AAChB,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAQ1E;AAED,gBAAgB;AAChB,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE3D;AAED,gBAAgB;AAChB,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQpF;AAED,gBAAgB;AAChB,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,sCAAsC;AACtC,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC"}
|
|
@@ -8,4 +8,14 @@ export declare function markInstrumentationApiUsed(): void;
|
|
|
8
8
|
* @experimental
|
|
9
9
|
*/
|
|
10
10
|
export declare function isInstrumentationApiUsed(): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Enable OTEL data-loader span creation for React Router server.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export declare function enableOtelDataLoaderSpanCreation(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Check if OTEL data-loader span creation is enabled for React Router server.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare function isOtelDataLoaderSpanCreationEnabled(): boolean;
|
|
11
21
|
//# sourceMappingURL=serverGlobals.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverGlobals.d.ts","sourceRoot":"","sources":["../../../src/server/serverGlobals.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serverGlobals.d.ts","sourceRoot":"","sources":["../../../src/server/serverGlobals.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,IAAI,IAAI,CAEvD;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,IAAI,OAAO,CAE7D"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type Plugin } from 'vite';
|
|
2
|
+
/**
|
|
3
|
+
* A Sentry plugin for React Router to capture the server build for middleware name resolution.
|
|
4
|
+
*/
|
|
5
|
+
export declare function makeServerBuildCapturePlugin(): Plugin;
|
|
6
|
+
//# sourceMappingURL=makeServerBuildCapturePlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"makeServerBuildCapturePlugin.d.ts","sourceRoot":"","sources":["../../../src/vite/makeServerBuildCapturePlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CA8BrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/vite/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/vite/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAK9C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AAE7D;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,6BAA6B,YAAK,EAC3C,UAAU,EAAE,SAAS,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAYnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/react-router",
|
|
3
|
-
"version": "10.41.0
|
|
3
|
+
"version": "10.41.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",
|
|
@@ -49,11 +49,11 @@
|
|
|
49
49
|
"@opentelemetry/core": "^2.5.1",
|
|
50
50
|
"@opentelemetry/instrumentation": "^0.211.0",
|
|
51
51
|
"@opentelemetry/semantic-conventions": "^1.39.0",
|
|
52
|
-
"@sentry/browser": "10.41.0
|
|
52
|
+
"@sentry/browser": "10.41.0",
|
|
53
53
|
"@sentry/cli": "^2.58.5",
|
|
54
|
-
"@sentry/core": "10.41.0
|
|
55
|
-
"@sentry/node": "10.41.0
|
|
56
|
-
"@sentry/react": "10.41.0
|
|
54
|
+
"@sentry/core": "10.41.0",
|
|
55
|
+
"@sentry/node": "10.41.0",
|
|
56
|
+
"@sentry/react": "10.41.0",
|
|
57
57
|
"@sentry/vite-plugin": "^5.1.0",
|
|
58
58
|
"glob": "^13.0.6"
|
|
59
59
|
},
|