@sentry/react-router 9.39.0 → 10.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.
- package/build/cjs/server/instrumentation/reactRouter.js +2 -2
- package/build/cjs/server/instrumentation/reactRouter.js.map +1 -1
- package/build/cjs/server/integration/lowQualityTransactionsFilterIntegration.js +1 -1
- package/build/cjs/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
- package/build/cjs/server/sdk.js +2 -2
- package/build/cjs/server/sdk.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/server/instrumentation/reactRouter.js +3 -3
- package/build/esm/server/instrumentation/reactRouter.js.map +1 -1
- package/build/esm/server/integration/lowQualityTransactionsFilterIntegration.js +2 -2
- package/build/esm/server/integration/lowQualityTransactionsFilterIntegration.js.map +1 -1
- package/build/esm/server/sdk.js +3 -3
- package/build/esm/server/sdk.js.map +1 -1
- package/package.json +7 -7
|
@@ -54,7 +54,7 @@ class ReactRouterInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
54
54
|
let url;
|
|
55
55
|
try {
|
|
56
56
|
url = new URL(request.url);
|
|
57
|
-
} catch
|
|
57
|
+
} catch {
|
|
58
58
|
return originalRequestHandler(request, initialContext);
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -67,7 +67,7 @@ class ReactRouterInstrumentation extends instrumentation.InstrumentationBase {
|
|
|
67
67
|
const rootSpan = activeSpan && core.getRootSpan(activeSpan);
|
|
68
68
|
|
|
69
69
|
if (!rootSpan) {
|
|
70
|
-
debugBuild.DEBUG_BUILD && core.
|
|
70
|
+
debugBuild.DEBUG_BUILD && core.debug.log('No active root span found, skipping tracing for data request');
|
|
71
71
|
return originalRequestHandler(request, initialContext);
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -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
|
|
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 { 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 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":["InstrumentationBase","SDK_VERSION","InstrumentationNodeModuleDefinition","isDataRequest","getActiveSpan","getRootSpan","DEBUG_BUILD","debug","spanToJSON","SEMATTRS_HTTP_TARGET","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","startSpan","getSpanName","SEMANTIC_ATTRIBUTE_SENTRY_OP","getOpName"],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ function _lowQualityTransactionsFilterIntegration(options)
|
|
|
23
23
|
const transaction = event.transaction;
|
|
24
24
|
|
|
25
25
|
if (matchedRegexes.some(regex => transaction.match(regex))) {
|
|
26
|
-
options.debug && core.
|
|
26
|
+
options.debug && core.debug.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint,
|
|
1
|
+
{"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint, debug, defineIntegration } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node';\n\n/**\n * Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/\n *\n */\n\nfunction _lowQualityTransactionsFilterIntegration(options: NodeOptions): {\n name: string;\n processEvent: (event: Event, hint: EventHint, client: Client) => Event | null;\n} {\n const matchedRegexes = [/GET \\/node_modules\\//, /GET \\/favicon\\.ico/, /GET \\/@id\\//, /GET \\/__manifest\\?/];\n\n return {\n name: 'LowQualityTransactionsFilter',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event | null {\n if (event.type !== 'transaction' || !event.transaction) {\n return event;\n }\n\n const transaction = event.transaction;\n\n if (matchedRegexes.some(regex => transaction.match(regex))) {\n options.debug && debug.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);\n return null;\n }\n\n return event;\n },\n };\n}\n\nexport const lowQualityTransactionsFilterIntegration = defineIntegration((options: NodeOptions) =>\n _lowQualityTransactionsFilterIntegration(options),\n);\n"],"names":["debug","defineIntegration"],"mappings":";;;;AAGA;AACA;AACA;AACA;;AAEA,SAAS,wCAAwC,CAAC,OAAO;;AAGzD,CAAE;AACF,EAAE,MAAM,cAAA,GAAiB,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,aAAa,EAAE,oBAAoB,CAAC;;AAE5G,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,8BAA8B;;AAExC,IAAI,YAAY,CAAC,KAAK,EAAS,KAAK,EAAa,OAAO,EAAwB;AAChF,MAAM,IAAI,KAAK,CAAC,IAAA,KAAS,aAAA,IAAiB,CAAC,KAAK,CAAC,WAAW,EAAE;AAC9D,QAAQ,OAAO,KAAK;AACpB;;AAEA,MAAM,MAAM,WAAA,GAAc,KAAK,CAAC,WAAW;;AAE3C,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,KAAA,IAAS,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;AAClE,QAAQ,OAAO,CAAC,KAAA,IAASA,UAAK,CAAC,GAAG,CAAC,kDAAkD,EAAE,KAAK,CAAC,WAAW,CAAC;AACzG,QAAQ,OAAO,IAAI;AACnB;;AAEA,MAAM,OAAO,KAAK;AAClB,KAAK;AACL,GAAG;AACH;;MAEa,uCAAA,GAA0CC,sBAAiB,CAAC,CAAC,OAAO;AACjF,EAAE,wCAAwC,CAAC,OAAO,CAAC;AACnD;;;;"}
|
package/build/cjs/server/sdk.js
CHANGED
|
@@ -27,7 +27,7 @@ function init(options) {
|
|
|
27
27
|
defaultIntegrations: getDefaultReactRouterServerIntegrations(options),
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
debugBuild.DEBUG_BUILD && core.
|
|
30
|
+
debugBuild.DEBUG_BUILD && core.debug.log('Initializing SDK...');
|
|
31
31
|
|
|
32
32
|
core.applySdkMetadata(opts, 'react-router', ['react-router', 'node']);
|
|
33
33
|
|
|
@@ -35,7 +35,7 @@ function init(options) {
|
|
|
35
35
|
|
|
36
36
|
core.setTag('runtime', 'node');
|
|
37
37
|
|
|
38
|
-
debugBuild.DEBUG_BUILD && core.
|
|
38
|
+
debugBuild.DEBUG_BUILD && core.debug.log('SDK successfully initialized');
|
|
39
39
|
|
|
40
40
|
return client;
|
|
41
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { applySdkMetadata,
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { applySdkMetadata, debug, setTag } from '@sentry/core';\nimport type { NodeClient, NodeOptions } from '@sentry/node';\nimport { getDefaultIntegrations as getNodeDefaultIntegrations, init as initNodeSdk } from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { lowQualityTransactionsFilterIntegration } from './integration/lowQualityTransactionsFilterIntegration';\nimport { reactRouterServerIntegration } from './integration/reactRouterServer';\n\n/**\n * Returns the default integrations for the React Router SDK.\n * @param options The options for the SDK.\n */\nexport function getDefaultReactRouterServerIntegrations(options: NodeOptions): Integration[] {\n return [\n ...getNodeDefaultIntegrations(options),\n lowQualityTransactionsFilterIntegration(options),\n reactRouterServerIntegration(),\n ];\n}\n\n/**\n * Initializes the server side of the React Router SDK\n */\nexport function init(options: NodeOptions): NodeClient | undefined {\n const opts: NodeOptions = {\n ...options,\n defaultIntegrations: getDefaultReactRouterServerIntegrations(options),\n };\n\n DEBUG_BUILD && debug.log('Initializing SDK...');\n\n applySdkMetadata(opts, 'react-router', ['react-router', 'node']);\n\n const client = initNodeSdk(opts);\n\n setTag('runtime', 'node');\n\n DEBUG_BUILD && debug.log('SDK successfully initialized');\n\n return client;\n}\n"],"names":["getNodeDefaultIntegrations","lowQualityTransactionsFilterIntegration","reactRouterServerIntegration","DEBUG_BUILD","debug","applySdkMetadata","initNodeSdk","setTag"],"mappings":";;;;;;;;AAQA;AACA;AACA;AACA;AACO,SAAS,uCAAuC,CAAC,OAAO,EAA8B;AAC7F,EAAE,OAAO;AACT,IAAI,GAAGA,2BAA0B,CAAC,OAAO,CAAC;AAC1C,IAAIC,+EAAuC,CAAC,OAAO,CAAC;AACpD,IAAIC,8CAA4B,EAAE;AAClC,GAAG;AACH;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAuC;AACnE,EAAE,MAAM,IAAI,GAAgB;AAC5B,IAAI,GAAG,OAAO;AACd,IAAI,mBAAmB,EAAE,uCAAuC,CAAC,OAAO,CAAC;AACzE,GAAG;;AAEH,EAAEC,0BAAeC,UAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC;;AAEjD,EAAEC,qBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;;AAElE,EAAE,MAAM,MAAA,GAASC,SAAW,CAAC,IAAI,CAAC;;AAElC,EAAEC,WAAM,CAAC,SAAS,EAAE,MAAM,CAAC;;AAE3B,EAAEJ,0BAAeC,UAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC;;AAE1D,EAAE,OAAO,MAAM;AACf;;;;;"}
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"
|
|
1
|
+
{"type":"module","version":"10.0.0-alpha.0"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InstrumentationBase, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
|
|
2
2
|
import { SEMATTRS_HTTP_TARGET } from '@opentelemetry/semantic-conventions';
|
|
3
|
-
import { SDK_VERSION, getActiveSpan, getRootSpan,
|
|
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
5
|
import { isDataRequest, getOpName, getSpanName } from './util.js';
|
|
6
6
|
|
|
@@ -52,7 +52,7 @@ class ReactRouterInstrumentation extends InstrumentationBase {
|
|
|
52
52
|
let url;
|
|
53
53
|
try {
|
|
54
54
|
url = new URL(request.url);
|
|
55
|
-
} catch
|
|
55
|
+
} catch {
|
|
56
56
|
return originalRequestHandler(request, initialContext);
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -65,7 +65,7 @@ class ReactRouterInstrumentation extends InstrumentationBase {
|
|
|
65
65
|
const rootSpan = activeSpan && getRootSpan(activeSpan);
|
|
66
66
|
|
|
67
67
|
if (!rootSpan) {
|
|
68
|
-
DEBUG_BUILD &&
|
|
68
|
+
DEBUG_BUILD && debug.log('No active root span found, skipping tracing for data request');
|
|
69
69
|
return originalRequestHandler(request, initialContext);
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -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
|
|
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 { 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 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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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineIntegration,
|
|
1
|
+
import { defineIntegration, debug } from '@sentry/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/
|
|
@@ -21,7 +21,7 @@ function _lowQualityTransactionsFilterIntegration(options)
|
|
|
21
21
|
const transaction = event.transaction;
|
|
22
22
|
|
|
23
23
|
if (matchedRegexes.some(regex => transaction.match(regex))) {
|
|
24
|
-
options.debug &&
|
|
24
|
+
options.debug && debug.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);
|
|
25
25
|
return null;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint,
|
|
1
|
+
{"version":3,"file":"lowQualityTransactionsFilterIntegration.js","sources":["../../../../src/server/integration/lowQualityTransactionsFilterIntegration.ts"],"sourcesContent":["import { type Client, type Event, type EventHint, debug, defineIntegration } from '@sentry/core';\nimport type { NodeOptions } from '@sentry/node';\n\n/**\n * Integration that filters out noisy http transactions such as requests to node_modules, favicon.ico, @id/\n *\n */\n\nfunction _lowQualityTransactionsFilterIntegration(options: NodeOptions): {\n name: string;\n processEvent: (event: Event, hint: EventHint, client: Client) => Event | null;\n} {\n const matchedRegexes = [/GET \\/node_modules\\//, /GET \\/favicon\\.ico/, /GET \\/@id\\//, /GET \\/__manifest\\?/];\n\n return {\n name: 'LowQualityTransactionsFilter',\n\n processEvent(event: Event, _hint: EventHint, _client: Client): Event | null {\n if (event.type !== 'transaction' || !event.transaction) {\n return event;\n }\n\n const transaction = event.transaction;\n\n if (matchedRegexes.some(regex => transaction.match(regex))) {\n options.debug && debug.log('[ReactRouter] Filtered node_modules transaction:', event.transaction);\n return null;\n }\n\n return event;\n },\n };\n}\n\nexport const lowQualityTransactionsFilterIntegration = defineIntegration((options: NodeOptions) =>\n _lowQualityTransactionsFilterIntegration(options),\n);\n"],"names":[],"mappings":";;AAGA;AACA;AACA;AACA;;AAEA,SAAS,wCAAwC,CAAC,OAAO;;AAGzD,CAAE;AACF,EAAE,MAAM,cAAA,GAAiB,CAAC,sBAAsB,EAAE,oBAAoB,EAAE,aAAa,EAAE,oBAAoB,CAAC;;AAE5G,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,8BAA8B;;AAExC,IAAI,YAAY,CAAC,KAAK,EAAS,KAAK,EAAa,OAAO,EAAwB;AAChF,MAAM,IAAI,KAAK,CAAC,IAAA,KAAS,aAAA,IAAiB,CAAC,KAAK,CAAC,WAAW,EAAE;AAC9D,QAAQ,OAAO,KAAK;AACpB;;AAEA,MAAM,MAAM,WAAA,GAAc,KAAK,CAAC,WAAW;;AAE3C,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,KAAA,IAAS,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;AAClE,QAAQ,OAAO,CAAC,KAAA,IAAS,KAAK,CAAC,GAAG,CAAC,kDAAkD,EAAE,KAAK,CAAC,WAAW,CAAC;AACzG,QAAQ,OAAO,IAAI;AACnB;;AAEA,MAAM,OAAO,KAAK;AAClB,KAAK;AACL,GAAG;AACH;;MAEa,uCAAA,GAA0C,iBAAiB,CAAC,CAAC,OAAO;AACjF,EAAE,wCAAwC,CAAC,OAAO,CAAC;AACnD;;;;"}
|
package/build/esm/server/sdk.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { debug, applySdkMetadata, setTag } from '@sentry/core';
|
|
2
2
|
import { init as init$1, getDefaultIntegrations } from '@sentry/node';
|
|
3
3
|
import { DEBUG_BUILD } from '../common/debug-build.js';
|
|
4
4
|
import { lowQualityTransactionsFilterIntegration } from './integration/lowQualityTransactionsFilterIntegration.js';
|
|
@@ -25,7 +25,7 @@ function init(options) {
|
|
|
25
25
|
defaultIntegrations: getDefaultReactRouterServerIntegrations(options),
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
DEBUG_BUILD &&
|
|
28
|
+
DEBUG_BUILD && debug.log('Initializing SDK...');
|
|
29
29
|
|
|
30
30
|
applySdkMetadata(opts, 'react-router', ['react-router', 'node']);
|
|
31
31
|
|
|
@@ -33,7 +33,7 @@ function init(options) {
|
|
|
33
33
|
|
|
34
34
|
setTag('runtime', 'node');
|
|
35
35
|
|
|
36
|
-
DEBUG_BUILD &&
|
|
36
|
+
DEBUG_BUILD && debug.log('SDK successfully initialized');
|
|
37
37
|
|
|
38
38
|
return client;
|
|
39
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { applySdkMetadata,
|
|
1
|
+
{"version":3,"file":"sdk.js","sources":["../../../src/server/sdk.ts"],"sourcesContent":["import type { Integration } from '@sentry/core';\nimport { applySdkMetadata, debug, setTag } from '@sentry/core';\nimport type { NodeClient, NodeOptions } from '@sentry/node';\nimport { getDefaultIntegrations as getNodeDefaultIntegrations, init as initNodeSdk } from '@sentry/node';\nimport { DEBUG_BUILD } from '../common/debug-build';\nimport { lowQualityTransactionsFilterIntegration } from './integration/lowQualityTransactionsFilterIntegration';\nimport { reactRouterServerIntegration } from './integration/reactRouterServer';\n\n/**\n * Returns the default integrations for the React Router SDK.\n * @param options The options for the SDK.\n */\nexport function getDefaultReactRouterServerIntegrations(options: NodeOptions): Integration[] {\n return [\n ...getNodeDefaultIntegrations(options),\n lowQualityTransactionsFilterIntegration(options),\n reactRouterServerIntegration(),\n ];\n}\n\n/**\n * Initializes the server side of the React Router SDK\n */\nexport function init(options: NodeOptions): NodeClient | undefined {\n const opts: NodeOptions = {\n ...options,\n defaultIntegrations: getDefaultReactRouterServerIntegrations(options),\n };\n\n DEBUG_BUILD && debug.log('Initializing SDK...');\n\n applySdkMetadata(opts, 'react-router', ['react-router', 'node']);\n\n const client = initNodeSdk(opts);\n\n setTag('runtime', 'node');\n\n DEBUG_BUILD && debug.log('SDK successfully initialized');\n\n return client;\n}\n"],"names":["getNodeDefaultIntegrations","initNodeSdk"],"mappings":";;;;;;AAQA;AACA;AACA;AACA;AACO,SAAS,uCAAuC,CAAC,OAAO,EAA8B;AAC7F,EAAE,OAAO;AACT,IAAI,GAAGA,sBAA0B,CAAC,OAAO,CAAC;AAC1C,IAAI,uCAAuC,CAAC,OAAO,CAAC;AACpD,IAAI,4BAA4B,EAAE;AAClC,GAAG;AACH;;AAEA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAuC;AACnE,EAAE,MAAM,IAAI,GAAgB;AAC5B,IAAI,GAAG,OAAO;AACd,IAAI,mBAAmB,EAAE,uCAAuC,CAAC,OAAO,CAAC;AACzE,GAAG;;AAEH,EAAE,eAAe,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC;;AAEjD,EAAE,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;;AAElE,EAAE,MAAM,MAAA,GAASC,MAAW,CAAC,IAAI,CAAC;;AAElC,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC;;AAE3B,EAAE,eAAe,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC;;AAE1D,EAAE,OAAO,MAAM;AACf;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/react-router",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0-alpha.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",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@opentelemetry/api": "^1.9.0",
|
|
38
|
-
"@opentelemetry/core": "^
|
|
39
|
-
"@opentelemetry/instrumentation": "0.
|
|
38
|
+
"@opentelemetry/core": "^2.0.0",
|
|
39
|
+
"@opentelemetry/instrumentation": "^0.203.0",
|
|
40
40
|
"@opentelemetry/semantic-conventions": "^1.34.0",
|
|
41
|
-
"@sentry/browser": "
|
|
41
|
+
"@sentry/browser": "10.0.0-alpha.0",
|
|
42
42
|
"@sentry/cli": "^2.46.0",
|
|
43
|
-
"@sentry/core": "
|
|
44
|
-
"@sentry/node": "
|
|
45
|
-
"@sentry/react": "
|
|
43
|
+
"@sentry/core": "10.0.0-alpha.0",
|
|
44
|
+
"@sentry/node": "10.0.0-alpha.0",
|
|
45
|
+
"@sentry/react": "10.0.0-alpha.0",
|
|
46
46
|
"@sentry/vite-plugin": "^3.5.0",
|
|
47
47
|
"glob": "11.0.1"
|
|
48
48
|
},
|