@sentry/react 10.37.0 → 10.39.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 (34) hide show
  1. package/build/cjs/hoist-non-react-statics.js +4 -4
  2. package/build/cjs/hoist-non-react-statics.js.map +1 -1
  3. package/build/cjs/reactrouter-compat-utils/instrumentation.js +67 -35
  4. package/build/cjs/reactrouter-compat-utils/instrumentation.js.map +1 -1
  5. package/build/cjs/reactrouter-compat-utils/lazy-routes.js +19 -10
  6. package/build/cjs/reactrouter-compat-utils/lazy-routes.js.map +1 -1
  7. package/build/cjs/reactrouter-compat-utils/route-manifest.js +194 -0
  8. package/build/cjs/reactrouter-compat-utils/route-manifest.js.map +1 -0
  9. package/build/cjs/reactrouter-compat-utils/utils.js +16 -31
  10. package/build/cjs/reactrouter-compat-utils/utils.js.map +1 -1
  11. package/build/esm/hoist-non-react-statics.js +4 -4
  12. package/build/esm/hoist-non-react-statics.js.map +1 -1
  13. package/build/esm/package.json +1 -1
  14. package/build/esm/reactrouter-compat-utils/instrumentation.js +68 -36
  15. package/build/esm/reactrouter-compat-utils/instrumentation.js.map +1 -1
  16. package/build/esm/reactrouter-compat-utils/lazy-routes.js +20 -11
  17. package/build/esm/reactrouter-compat-utils/lazy-routes.js.map +1 -1
  18. package/build/esm/reactrouter-compat-utils/route-manifest.js +191 -0
  19. package/build/esm/reactrouter-compat-utils/route-manifest.js.map +1 -0
  20. package/build/esm/reactrouter-compat-utils/utils.js +12 -27
  21. package/build/esm/reactrouter-compat-utils/utils.js.map +1 -1
  22. package/build/esm/reactrouter.js +1 -1
  23. package/build/esm/reactrouterv6.js +1 -1
  24. package/build/types/reactrouter-compat-utils/instrumentation.d.ts +18 -0
  25. package/build/types/reactrouter-compat-utils/instrumentation.d.ts.map +1 -1
  26. package/build/types/reactrouter-compat-utils/lazy-routes.d.ts.map +1 -1
  27. package/build/types/reactrouter-compat-utils/route-manifest.d.ts +13 -0
  28. package/build/types/reactrouter-compat-utils/route-manifest.d.ts.map +1 -0
  29. package/build/types/reactrouter-compat-utils/utils.d.ts +1 -1
  30. package/build/types/reactrouter-compat-utils/utils.d.ts.map +1 -1
  31. package/build/types-ts3.8/reactrouter-compat-utils/instrumentation.d.ts +18 -0
  32. package/build/types-ts3.8/reactrouter-compat-utils/route-manifest.d.ts +13 -0
  33. package/build/types-ts3.8/reactrouter-compat-utils/utils.d.ts +1 -1
  34. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-routes.js","sources":["../../../src/reactrouter-compat-utils/lazy-routes.tsx"],"sourcesContent":["import { WINDOW } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport { addNonEnumerableProperty, debug, isThenable } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Location, RouteObject } from '../types';\nimport { getActiveRootSpan, getNavigationContext } from './utils';\n\n/**\n * Captures location at invocation time. Prefers navigation context over window.location\n * since window.location hasn't updated yet when async handlers are invoked.\n */\nfunction captureCurrentLocation(): Location | null {\n const navContext = getNavigationContext();\n // Only use navigation context if targetPath is defined (it can be undefined\n // if patchRoutesOnNavigation was invoked without a path argument)\n if (navContext?.targetPath) {\n return {\n pathname: navContext.targetPath,\n search: '',\n hash: '',\n state: null,\n key: 'default',\n };\n }\n\n if (typeof WINDOW !== 'undefined') {\n try {\n const windowLocation = WINDOW.location;\n if (windowLocation) {\n return {\n pathname: windowLocation.pathname,\n search: windowLocation.search || '',\n hash: windowLocation.hash || '',\n state: null,\n key: 'default',\n };\n }\n } catch {\n DEBUG_BUILD && debug.warn('[React Router] Could not access window.location');\n }\n }\n return null;\n}\n\n/**\n * Captures the active span at invocation time. Prefers navigation context span\n * to ensure we update the correct span even if another navigation starts.\n */\nfunction captureActiveSpan(): Span | undefined {\n const navContext = getNavigationContext();\n if (navContext) {\n return navContext.span;\n }\n return getActiveRootSpan();\n}\n\n/**\n * Creates a proxy wrapper for an async handler function.\n * Captures both the location and the active span at invocation time to ensure\n * the correct span is updated when the handler resolves.\n */\nexport function createAsyncHandlerProxy(\n originalFunction: (...args: unknown[]) => unknown,\n route: RouteObject,\n handlerKey: string,\n processResolvedRoutes: (\n resolvedRoutes: RouteObject[],\n parentRoute?: RouteObject,\n currentLocation?: Location,\n capturedSpan?: Span,\n ) => void,\n): (...args: unknown[]) => unknown {\n const proxy = new Proxy(originalFunction, {\n apply(target: (...args: unknown[]) => unknown, thisArg, argArray) {\n const locationAtInvocation = captureCurrentLocation();\n const spanAtInvocation = captureActiveSpan();\n const result = target.apply(thisArg, argArray);\n handleAsyncHandlerResult(\n result,\n route,\n handlerKey,\n processResolvedRoutes,\n locationAtInvocation,\n spanAtInvocation,\n );\n return result;\n },\n });\n\n addNonEnumerableProperty(proxy, '__sentry_proxied__', true);\n\n return proxy;\n}\n\n/**\n * Handles the result of an async handler function call.\n * Passes the captured span through to ensure the correct span is updated.\n */\nexport function handleAsyncHandlerResult(\n result: unknown,\n route: RouteObject,\n handlerKey: string,\n processResolvedRoutes: (\n resolvedRoutes: RouteObject[],\n parentRoute?: RouteObject,\n currentLocation?: Location,\n capturedSpan?: Span,\n ) => void,\n currentLocation: Location | null,\n capturedSpan: Span | undefined,\n): void {\n if (isThenable(result)) {\n (result as Promise<unknown>)\n .then((resolvedRoutes: unknown) => {\n if (Array.isArray(resolvedRoutes)) {\n processResolvedRoutes(resolvedRoutes, route, currentLocation ?? undefined, capturedSpan);\n }\n })\n .catch((e: unknown) => {\n DEBUG_BUILD && debug.warn(`Error resolving async handler '${handlerKey}' for route`, route, e);\n });\n } else if (Array.isArray(result)) {\n processResolvedRoutes(result, route, currentLocation ?? undefined, capturedSpan);\n }\n}\n\n/**\n * Recursively checks a route for async handlers and sets up Proxies to add discovered child routes to allRoutes when called.\n */\nexport function checkRouteForAsyncHandler(\n route: RouteObject,\n processResolvedRoutes: (\n resolvedRoutes: RouteObject[],\n parentRoute?: RouteObject,\n currentLocation?: Location,\n capturedSpan?: Span,\n ) => void,\n): void {\n // Set up proxies for any functions in the route's handle\n if (route.handle && typeof route.handle === 'object') {\n for (const key of Object.keys(route.handle)) {\n const maybeFn = route.handle[key];\n if (typeof maybeFn === 'function' && !(maybeFn as { __sentry_proxied__?: boolean }).__sentry_proxied__) {\n route.handle[key] = createAsyncHandlerProxy(maybeFn, route, key, processResolvedRoutes);\n }\n }\n }\n\n // Recursively check child routes\n if (Array.isArray(route.children)) {\n for (const child of route.children) {\n checkRouteForAsyncHandler(child, processResolvedRoutes);\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lazy-routes.js","sources":["../../../src/reactrouter-compat-utils/lazy-routes.tsx"],"sourcesContent":["import { WINDOW } from '@sentry/browser';\nimport type { Span } from '@sentry/core';\nimport { addNonEnumerableProperty, debug, isThenable } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Location, RouteObject } from '../types';\nimport { getActiveRootSpan, getNavigationContext } from './utils';\n\n/**\n * Captures location at invocation time. Prefers navigation context over window.location\n * since window.location hasn't updated yet when async handlers are invoked.\n *\n * When inside a patchRoutesOnNavigation call, uses the captured targetPath. If targetPath\n * is undefined (patchRoutesOnNavigation can be invoked without a path argument), returns\n * null rather than falling back to WINDOW.location which could be stale/wrong after the\n * user navigated away during async loading. Returning null causes the span name update\n * to be skipped, which is safer than using incorrect location data.\n */\nfunction captureCurrentLocation(): Location | null {\n const navContext = getNavigationContext();\n\n if (navContext) {\n if (navContext.targetPath) {\n return {\n pathname: navContext.targetPath,\n search: '',\n hash: '',\n state: null,\n key: 'default',\n };\n }\n // Don't fall back to potentially stale WINDOW.location\n return null;\n }\n\n if (typeof WINDOW !== 'undefined') {\n try {\n const windowLocation = WINDOW.location;\n if (windowLocation) {\n return {\n pathname: windowLocation.pathname,\n search: windowLocation.search || '',\n hash: windowLocation.hash || '',\n state: null,\n key: 'default',\n };\n }\n } catch {\n DEBUG_BUILD && debug.warn('[React Router] Could not access window.location');\n }\n }\n return null;\n}\n\n/**\n * Captures the active span at invocation time. Prefers navigation context span\n * to ensure we update the correct span even if another navigation starts.\n */\nfunction captureActiveSpan(): Span | undefined {\n const navContext = getNavigationContext();\n if (navContext) {\n return navContext.span;\n }\n return getActiveRootSpan();\n}\n\n/**\n * Creates a proxy wrapper for an async handler function.\n * Captures both the location and the active span at invocation time to ensure\n * the correct span is updated when the handler resolves.\n */\nexport function createAsyncHandlerProxy(\n originalFunction: (...args: unknown[]) => unknown,\n route: RouteObject,\n handlerKey: string,\n processResolvedRoutes: (\n resolvedRoutes: RouteObject[],\n parentRoute?: RouteObject,\n currentLocation?: Location,\n capturedSpan?: Span,\n ) => void,\n): (...args: unknown[]) => unknown {\n const proxy = new Proxy(originalFunction, {\n apply(target: (...args: unknown[]) => unknown, thisArg, argArray) {\n const locationAtInvocation = captureCurrentLocation();\n const spanAtInvocation = captureActiveSpan();\n const result = target.apply(thisArg, argArray);\n handleAsyncHandlerResult(\n result,\n route,\n handlerKey,\n processResolvedRoutes,\n locationAtInvocation,\n spanAtInvocation,\n );\n return result;\n },\n });\n\n addNonEnumerableProperty(proxy, '__sentry_proxied__', true);\n\n return proxy;\n}\n\n/**\n * Handles the result of an async handler function call.\n * Passes the captured span through to ensure the correct span is updated.\n */\nexport function handleAsyncHandlerResult(\n result: unknown,\n route: RouteObject,\n handlerKey: string,\n processResolvedRoutes: (\n resolvedRoutes: RouteObject[],\n parentRoute?: RouteObject,\n currentLocation?: Location,\n capturedSpan?: Span,\n ) => void,\n currentLocation: Location | null,\n capturedSpan: Span | undefined,\n): void {\n if (isThenable(result)) {\n (result as Promise<unknown>)\n .then((resolvedRoutes: unknown) => {\n if (Array.isArray(resolvedRoutes)) {\n processResolvedRoutes(resolvedRoutes, route, currentLocation ?? undefined, capturedSpan);\n }\n })\n .catch((e: unknown) => {\n DEBUG_BUILD && debug.warn(`Error resolving async handler '${handlerKey}' for route`, route, e);\n });\n } else if (Array.isArray(result)) {\n processResolvedRoutes(result, route, currentLocation ?? undefined, capturedSpan);\n }\n}\n\n/**\n * Recursively checks a route for async handlers and sets up Proxies to add discovered child routes to allRoutes when called.\n */\nexport function checkRouteForAsyncHandler(\n route: RouteObject,\n processResolvedRoutes: (\n resolvedRoutes: RouteObject[],\n parentRoute?: RouteObject,\n currentLocation?: Location,\n capturedSpan?: Span,\n ) => void,\n): void {\n // Set up proxies for any functions in the route's handle\n if (route.handle && typeof route.handle === 'object') {\n for (const key of Object.keys(route.handle)) {\n const maybeFn = route.handle[key];\n if (typeof maybeFn === 'function' && !(maybeFn as { __sentry_proxied__?: boolean }).__sentry_proxied__) {\n route.handle[key] = createAsyncHandlerProxy(maybeFn, route, key, processResolvedRoutes);\n }\n }\n }\n\n // Recursively check child routes\n if (Array.isArray(route.children)) {\n for (const child of route.children) {\n checkRouteForAsyncHandler(child, processResolvedRoutes);\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,191 @@
1
+ import { debug } from '@sentry/core';
2
+ import { DEBUG_BUILD } from '../debug-build.js';
3
+
4
+ /**
5
+ * Strip the basename from a pathname if exists.
6
+ *
7
+ * Vendored and modified from `react-router`
8
+ * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038
9
+ */
10
+ function stripBasenameFromPathname(pathname, basename) {
11
+ if (!basename || basename === '/') {
12
+ return pathname;
13
+ }
14
+
15
+ if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
16
+ return pathname;
17
+ }
18
+
19
+ // We want to leave trailing slash behavior in the user's control, so if they
20
+ // specify a basename with a trailing slash, we should support it
21
+ const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;
22
+ const nextChar = pathname.charAt(startIndex);
23
+ if (nextChar && nextChar !== '/') {
24
+ // pathname does not start with basename/
25
+ return pathname;
26
+ }
27
+
28
+ return pathname.slice(startIndex) || '/';
29
+ }
30
+
31
+ // Cache for sorted manifests - keyed by manifest array reference
32
+ const SORTED_MANIFEST_CACHE = new WeakMap();
33
+
34
+ /**
35
+ * Matches a pathname against a route manifest and returns the matching pattern.
36
+ * Optionally strips a basename prefix before matching.
37
+ */
38
+ function matchRouteManifest(pathname, manifest, basename) {
39
+ if (!pathname || !manifest || !manifest.length) {
40
+ return null;
41
+ }
42
+
43
+ const normalizedPathname = basename ? stripBasenameFromPathname(pathname, basename) : pathname;
44
+
45
+ let sorted = SORTED_MANIFEST_CACHE.get(manifest);
46
+ if (!sorted) {
47
+ sorted = sortBySpecificity(manifest);
48
+ SORTED_MANIFEST_CACHE.set(manifest, sorted);
49
+ DEBUG_BUILD && debug.log('[React Router] Sorted route manifest by specificity:', sorted.length, 'patterns');
50
+ }
51
+
52
+ for (const pattern of sorted) {
53
+ if (matchesPattern(normalizedPathname, pattern)) {
54
+ DEBUG_BUILD && debug.log('[React Router] Matched pathname', normalizedPathname, 'to pattern', pattern);
55
+ return pattern;
56
+ }
57
+ }
58
+
59
+ DEBUG_BUILD && debug.log('[React Router] No manifest match found for pathname:', normalizedPathname);
60
+ return null;
61
+ }
62
+
63
+ /**
64
+ * Checks if a pathname matches a route pattern.
65
+ */
66
+ function matchesPattern(pathname, pattern) {
67
+ // Handle root path special case
68
+ if (pattern === '/') {
69
+ return pathname === '/' || pathname === '';
70
+ }
71
+
72
+ const pathSegments = splitPath(pathname);
73
+ const patternSegments = splitPath(pattern);
74
+
75
+ // Handle wildcard at end
76
+ const hasWildcard = patternSegments.length > 0 && patternSegments[patternSegments.length - 1] === '*';
77
+
78
+ if (hasWildcard) {
79
+ // Pattern with wildcard: path must have at least as many segments as pattern (minus wildcard)
80
+ const patternSegmentsWithoutWildcard = patternSegments.slice(0, -1);
81
+ if (pathSegments.length < patternSegmentsWithoutWildcard.length) {
82
+ return false;
83
+ }
84
+ for (const [i, patternSegment] of patternSegmentsWithoutWildcard.entries()) {
85
+ if (!segmentMatches(pathSegments[i], patternSegment)) {
86
+ return false;
87
+ }
88
+ }
89
+ return true;
90
+ }
91
+
92
+ // Exact segment count match required
93
+ if (pathSegments.length !== patternSegments.length) {
94
+ return false;
95
+ }
96
+
97
+ for (const [i, patternSegment] of patternSegments.entries()) {
98
+ if (!segmentMatches(pathSegments[i], patternSegment)) {
99
+ return false;
100
+ }
101
+ }
102
+
103
+ return true;
104
+ }
105
+
106
+ /**
107
+ * Checks if a path segment matches a pattern segment.
108
+ */
109
+ function segmentMatches(pathSegment, patternSegment) {
110
+ if (pathSegment === undefined || patternSegment === undefined) {
111
+ return false;
112
+ }
113
+ // Parameter matches anything
114
+ if (PARAM_RE.test(patternSegment)) {
115
+ return true;
116
+ }
117
+ // Literal must match exactly
118
+ return pathSegment === patternSegment;
119
+ }
120
+
121
+ /**
122
+ * Splits a path into segments, filtering out empty strings.
123
+ */
124
+ function splitPath(path) {
125
+ return path.split('/').filter(Boolean);
126
+ }
127
+
128
+ /**
129
+ * React Router scoring weights and param detection.
130
+ * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts
131
+ */
132
+ const PARAM_RE = /^:[\w-]+$/;
133
+ const STATIC_SEGMENT_SCORE = 10;
134
+ const DYNAMIC_SEGMENT_SCORE = 3;
135
+ const EMPTY_SEGMENT_SCORE = 1;
136
+ const SPLAT_PENALTY = -2;
137
+
138
+ /**
139
+ * Computes a specificity score for a route pattern.
140
+ * Matches React Router's computeScore() algorithm exactly.
141
+ */
142
+ function computeScore(pattern) {
143
+ const segments = pattern.split('/');
144
+
145
+ // Base score is segment count (including empty segment from leading slash)
146
+ let score = segments.length;
147
+
148
+ // Apply splat penalty once if pattern contains wildcard
149
+ if (segments.includes('*')) {
150
+ score += SPLAT_PENALTY;
151
+ }
152
+
153
+ for (const segment of segments) {
154
+ if (segment === '*') {
155
+ // Splat penalty already applied globally above
156
+ continue;
157
+ } else if (PARAM_RE.test(segment)) {
158
+ score += DYNAMIC_SEGMENT_SCORE;
159
+ } else if (segment === '') {
160
+ score += EMPTY_SEGMENT_SCORE;
161
+ } else {
162
+ score += STATIC_SEGMENT_SCORE;
163
+ }
164
+ }
165
+
166
+ return score;
167
+ }
168
+
169
+ /**
170
+ * Sorts route patterns by specificity (most specific first).
171
+ * Implements React Router's ranking algorithm from computeScore():
172
+ * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts
173
+ *
174
+ * React Router scoring: base=segments.length, static=+10, dynamic=+3, empty=+1, splat=-2 (once)
175
+ * Higher score = more specific pattern.
176
+ * Equal scores preserve manifest order (same as React Router).
177
+ *
178
+ * Note: Users should order their manifest from most specific to least specific
179
+ * when patterns have equal specificity (e.g., `/users/:id/settings` and `/:type/123/settings`).
180
+ */
181
+ function sortBySpecificity(manifest) {
182
+ return [...manifest].sort((a, b) => {
183
+ const aScore = computeScore(a);
184
+ const bScore = computeScore(b);
185
+
186
+ return bScore - aScore;
187
+ });
188
+ }
189
+
190
+ export { matchRouteManifest, stripBasenameFromPathname };
191
+ //# sourceMappingURL=route-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-manifest.js","sources":["../../../src/reactrouter-compat-utils/route-manifest.ts"],"sourcesContent":["import { debug } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Strip the basename from a pathname if exists.\n *\n * Vendored and modified from `react-router`\n * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038\n */\nexport function stripBasenameFromPathname(pathname: string, basename: string): string {\n if (!basename || basename === '/') {\n return pathname;\n }\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return pathname;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;\n const nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== '/') {\n // pathname does not start with basename/\n return pathname;\n }\n\n return pathname.slice(startIndex) || '/';\n}\n\n// Cache for sorted manifests - keyed by manifest array reference\nconst SORTED_MANIFEST_CACHE = new WeakMap<string[], string[]>();\n\n/**\n * Matches a pathname against a route manifest and returns the matching pattern.\n * Optionally strips a basename prefix before matching.\n */\nexport function matchRouteManifest(pathname: string, manifest: string[], basename?: string): string | null {\n if (!pathname || !manifest || !manifest.length) {\n return null;\n }\n\n const normalizedPathname = basename ? stripBasenameFromPathname(pathname, basename) : pathname;\n\n let sorted = SORTED_MANIFEST_CACHE.get(manifest);\n if (!sorted) {\n sorted = sortBySpecificity(manifest);\n SORTED_MANIFEST_CACHE.set(manifest, sorted);\n DEBUG_BUILD && debug.log('[React Router] Sorted route manifest by specificity:', sorted.length, 'patterns');\n }\n\n for (const pattern of sorted) {\n if (matchesPattern(normalizedPathname, pattern)) {\n DEBUG_BUILD && debug.log('[React Router] Matched pathname', normalizedPathname, 'to pattern', pattern);\n return pattern;\n }\n }\n\n DEBUG_BUILD && debug.log('[React Router] No manifest match found for pathname:', normalizedPathname);\n return null;\n}\n\n/**\n * Checks if a pathname matches a route pattern.\n */\nfunction matchesPattern(pathname: string, pattern: string): boolean {\n // Handle root path special case\n if (pattern === '/') {\n return pathname === '/' || pathname === '';\n }\n\n const pathSegments = splitPath(pathname);\n const patternSegments = splitPath(pattern);\n\n // Handle wildcard at end\n const hasWildcard = patternSegments.length > 0 && patternSegments[patternSegments.length - 1] === '*';\n\n if (hasWildcard) {\n // Pattern with wildcard: path must have at least as many segments as pattern (minus wildcard)\n const patternSegmentsWithoutWildcard = patternSegments.slice(0, -1);\n if (pathSegments.length < patternSegmentsWithoutWildcard.length) {\n return false;\n }\n for (const [i, patternSegment] of patternSegmentsWithoutWildcard.entries()) {\n if (!segmentMatches(pathSegments[i], patternSegment)) {\n return false;\n }\n }\n return true;\n }\n\n // Exact segment count match required\n if (pathSegments.length !== patternSegments.length) {\n return false;\n }\n\n for (const [i, patternSegment] of patternSegments.entries()) {\n if (!segmentMatches(pathSegments[i], patternSegment)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Checks if a path segment matches a pattern segment.\n */\nfunction segmentMatches(pathSegment: string | undefined, patternSegment: string | undefined): boolean {\n if (pathSegment === undefined || patternSegment === undefined) {\n return false;\n }\n // Parameter matches anything\n if (PARAM_RE.test(patternSegment)) {\n return true;\n }\n // Literal must match exactly\n return pathSegment === patternSegment;\n}\n\n/**\n * Splits a path into segments, filtering out empty strings.\n */\nfunction splitPath(path: string): string[] {\n return path.split('/').filter(Boolean);\n}\n\n/**\n * React Router scoring weights and param detection.\n * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts\n */\nconst PARAM_RE = /^:[\\w-]+$/;\nconst STATIC_SEGMENT_SCORE = 10;\nconst DYNAMIC_SEGMENT_SCORE = 3;\nconst EMPTY_SEGMENT_SCORE = 1;\nconst SPLAT_PENALTY = -2;\n\n/**\n * Computes a specificity score for a route pattern.\n * Matches React Router's computeScore() algorithm exactly.\n */\nfunction computeScore(pattern: string): number {\n const segments = pattern.split('/');\n\n // Base score is segment count (including empty segment from leading slash)\n let score = segments.length;\n\n // Apply splat penalty once if pattern contains wildcard\n if (segments.includes('*')) {\n score += SPLAT_PENALTY;\n }\n\n for (const segment of segments) {\n if (segment === '*') {\n // Splat penalty already applied globally above\n continue;\n } else if (PARAM_RE.test(segment)) {\n score += DYNAMIC_SEGMENT_SCORE;\n } else if (segment === '') {\n score += EMPTY_SEGMENT_SCORE;\n } else {\n score += STATIC_SEGMENT_SCORE;\n }\n }\n\n return score;\n}\n\n/**\n * Sorts route patterns by specificity (most specific first).\n * Implements React Router's ranking algorithm from computeScore():\n * https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/router/utils.ts\n *\n * React Router scoring: base=segments.length, static=+10, dynamic=+3, empty=+1, splat=-2 (once)\n * Higher score = more specific pattern.\n * Equal scores preserve manifest order (same as React Router).\n *\n * Note: Users should order their manifest from most specific to least specific\n * when patterns have equal specificity (e.g., `/users/:id/settings` and `/:type/123/settings`).\n */\nfunction sortBySpecificity(manifest: string[]): string[] {\n return [...manifest].sort((a, b) => {\n const aScore = computeScore(a);\n const bScore = computeScore(b);\n\n return bScore - aScore;\n });\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { getActiveSpan, getRootSpan, spanToJSON, debug } from '@sentry/core';
2
2
  import { DEBUG_BUILD } from '../debug-build.js';
3
+ import { matchRouteManifest, stripBasenameFromPathname } from './route-manifest.js';
3
4
 
4
5
  // Global variables that these utilities depend on
5
6
  let _matchRoutes;
@@ -127,33 +128,6 @@ function getNumberOfUrlSegments(url) {
127
128
  return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length;
128
129
  }
129
130
 
130
- /**
131
- * Strip the basename from a pathname if exists.
132
- *
133
- * Vendored and modified from `react-router`
134
- * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038
135
- */
136
- function stripBasenameFromPathname(pathname, basename) {
137
- if (!basename || basename === '/') {
138
- return pathname;
139
- }
140
-
141
- if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
142
- return pathname;
143
- }
144
-
145
- // We want to leave trailing slash behavior in the user's control, so if they
146
- // specify a basename with a trailing slash, we should support it
147
- const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;
148
- const nextChar = pathname.charAt(startIndex);
149
- if (nextChar && nextChar !== '/') {
150
- // pathname does not start with basename/
151
- return pathname;
152
- }
153
-
154
- return pathname.slice(startIndex) || '/';
155
- }
156
-
157
131
  // Exported utility functions
158
132
 
159
133
  /**
@@ -296,7 +270,18 @@ function resolveRouteNameAndSource(
296
270
  allRoutes,
297
271
  branches,
298
272
  basename = '',
273
+ lazyRouteManifest,
274
+ enableAsyncRouteHandlers,
299
275
  ) {
276
+ // When lazy route manifest is provided, use it as the primary source for transaction names
277
+ if (enableAsyncRouteHandlers && lazyRouteManifest && lazyRouteManifest.length > 0) {
278
+ const manifestMatch = matchRouteManifest(location.pathname, lazyRouteManifest, basename);
279
+ if (manifestMatch) {
280
+ return [(_stripBasename ? '' : basename) + manifestMatch, 'route'];
281
+ }
282
+ }
283
+
284
+ // Fall back to React Router route matching
300
285
  let name;
301
286
  let source = 'url';
302
287
 
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/reactrouter-compat-utils/utils.ts"],"sourcesContent":["import type { Span, TransactionSource } from '@sentry/core';\nimport { debug, getActiveSpan, getRootSpan, spanToJSON } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Location, MatchRoutes, RouteMatch, RouteObject } from '../types';\n\n// Global variables that these utilities depend on\nlet _matchRoutes: MatchRoutes;\nlet _stripBasename: boolean = false;\n\n// Navigation context stack for nested/concurrent patchRoutesOnNavigation calls.\n// Required because window.location hasn't updated yet when handlers are invoked.\ninterface NavigationContext {\n token: object;\n targetPath: string | undefined;\n span: Span | undefined;\n}\n\nconst _navigationContextStack: NavigationContext[] = [];\nconst MAX_CONTEXT_STACK_SIZE = 10;\n\n/**\n * Pushes a navigation context and returns a unique token for cleanup.\n * The token uses object identity for uniqueness (no counter needed).\n */\nexport function setNavigationContext(targetPath: string | undefined, span: Span | undefined): object {\n const token = {};\n // Prevent unbounded stack growth - oldest (likely stale) contexts are evicted first\n if (_navigationContextStack.length >= MAX_CONTEXT_STACK_SIZE) {\n DEBUG_BUILD && debug.warn('[React Router] Navigation context stack overflow - removing oldest context');\n _navigationContextStack.shift();\n }\n _navigationContextStack.push({ token, targetPath, span });\n return token;\n}\n\n/**\n * Clears the navigation context if it's on top of the stack (LIFO).\n * If our context is not on top (out-of-order completion), we leave it -\n * it will be cleaned up by overflow protection when the stack fills up.\n */\nexport function clearNavigationContext(token: object): void {\n const top = _navigationContextStack[_navigationContextStack.length - 1];\n if (top?.token === token) {\n _navigationContextStack.pop();\n }\n}\n\n/** Gets the current (most recent) navigation context if inside a patchRoutesOnNavigation call. */\nexport function getNavigationContext(): NavigationContext | null {\n const length = _navigationContextStack.length;\n // The `?? null` converts undefined (from array access) to null to match return type\n return length > 0 ? (_navigationContextStack[length - 1] ?? null) : null;\n}\n\n/**\n * Initialize function to set dependencies that the router utilities need.\n * Must be called before using any of the exported utility functions.\n */\nexport function initializeRouterUtils(matchRoutes: MatchRoutes, stripBasename: boolean = false): void {\n _matchRoutes = matchRoutes;\n _stripBasename = stripBasename;\n}\n\n// Helper functions\nfunction pickPath(match: RouteMatch): string {\n return trimWildcard(match.route.path || '');\n}\n\nfunction pickSplat(match: RouteMatch): string {\n return match.params['*'] || '';\n}\n\nfunction trimWildcard(path: string): string {\n return path[path.length - 1] === '*' ? path.slice(0, -1) : path;\n}\n\nfunction trimSlash(path: string): string {\n return path[path.length - 1] === '/' ? path.slice(0, -1) : path;\n}\n\n/**\n * Checks if a path ends with a wildcard character (*).\n */\nexport function pathEndsWithWildcard(path: string): boolean {\n return path.endsWith('*');\n}\n\n/** Checks if transaction name has wildcard (/* or ends with *). */\nexport function transactionNameHasWildcard(name: string): boolean {\n return name.includes('/*') || name.endsWith('*');\n}\n\n/**\n * Checks if a path is a wildcard and has child routes.\n */\nexport function pathIsWildcardAndHasChildren(path: string, branch: RouteMatch<string>): boolean {\n return (pathEndsWithWildcard(path) && !!branch.route.children?.length) || false;\n}\n\n/** Check if route is in descendant route (<Routes> within <Routes>) */\nexport function routeIsDescendant(route: RouteObject): boolean {\n return !!(!route.children && route.element && route.path?.endsWith('/*'));\n}\n\nfunction sendIndexPath(pathBuilder: string, pathname: string, basename: string): [string, TransactionSource] {\n const reconstructedPath =\n pathBuilder && pathBuilder.length > 0\n ? pathBuilder\n : _stripBasename\n ? stripBasenameFromPathname(pathname, basename)\n : pathname;\n\n let formattedPath =\n // If the path ends with a wildcard suffix, remove both the slash and the asterisk\n reconstructedPath.slice(-2) === '/*' ? reconstructedPath.slice(0, -2) : reconstructedPath;\n\n // If the path ends with a slash, remove it (but keep single '/')\n if (formattedPath.length > 1 && formattedPath[formattedPath.length - 1] === '/') {\n formattedPath = formattedPath.slice(0, -1);\n }\n\n return [formattedPath, 'route'];\n}\n\n/**\n * Returns the number of URL segments in the given URL string.\n * Splits at '/' or '\\/' to handle regex URLs correctly.\n *\n * @param url - The URL string to segment.\n * @returns The number of segments in the URL.\n */\nexport function getNumberOfUrlSegments(url: string): number {\n // split at '/' or at '\\/' to split regex urls correctly\n return url.split(/\\\\?\\//).filter(s => s.length > 0 && s !== ',').length;\n}\n\n/**\n * Strip the basename from a pathname if exists.\n *\n * Vendored and modified from `react-router`\n * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038\n */\nfunction stripBasenameFromPathname(pathname: string, basename: string): string {\n if (!basename || basename === '/') {\n return pathname;\n }\n\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return pathname;\n }\n\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;\n const nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== '/') {\n // pathname does not start with basename/\n return pathname;\n }\n\n return pathname.slice(startIndex) || '/';\n}\n\n// Exported utility functions\n\n/**\n * Ensures a path string starts with a forward slash.\n */\nexport function prefixWithSlash(path: string): string {\n return path[0] === '/' ? path : `/${path}`;\n}\n\n/**\n * Rebuilds the route path from all available routes by matching against the current location.\n */\nexport function rebuildRoutePathFromAllRoutes(allRoutes: RouteObject[], location: Location): string {\n const matchedRoutes = _matchRoutes(allRoutes, location) as RouteMatch[];\n\n if (!matchedRoutes || matchedRoutes.length === 0) {\n return '';\n }\n\n for (const match of matchedRoutes) {\n if (match.route.path && match.route.path !== '*') {\n const path = pickPath(match);\n const strippedPath = stripBasenameFromPathname(location.pathname, prefixWithSlash(match.pathnameBase));\n\n if (location.pathname === strippedPath) {\n return trimSlash(strippedPath);\n }\n\n return trimSlash(\n trimSlash(path || '') +\n prefixWithSlash(\n rebuildRoutePathFromAllRoutes(\n allRoutes.filter(route => route !== match.route),\n {\n pathname: strippedPath,\n },\n ),\n ),\n );\n }\n }\n\n return '';\n}\n\n/**\n * Checks if the current location is inside a descendant route (route with splat parameter).\n */\nexport function locationIsInsideDescendantRoute(location: Location, routes: RouteObject[]): boolean {\n const matchedRoutes = _matchRoutes(routes, location) as RouteMatch[];\n\n if (matchedRoutes) {\n for (const match of matchedRoutes) {\n if (routeIsDescendant(match.route) && pickSplat(match)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Returns a fallback transaction name from location pathname.\n */\nfunction getFallbackTransactionName(location: Location, basename: string): string {\n return _stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname || '';\n}\n\n/**\n * Gets a normalized route name and transaction source from the current routes and location.\n */\nexport function getNormalizedName(\n routes: RouteObject[],\n location: Location,\n branches: RouteMatch[],\n basename: string = '',\n): [string, TransactionSource] {\n if (!routes || routes.length === 0) {\n return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url'];\n }\n\n if (!branches) {\n return [getFallbackTransactionName(location, basename), 'url'];\n }\n\n let pathBuilder = '';\n\n for (const branch of branches) {\n const route = branch.route;\n if (!route) {\n continue;\n }\n\n // Early return for index routes\n if (route.index) {\n return sendIndexPath(pathBuilder, branch.pathname, basename);\n }\n\n const path = route.path;\n if (!path || pathIsWildcardAndHasChildren(path, branch)) {\n continue;\n }\n\n // Build the route path\n const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`;\n pathBuilder = trimSlash(pathBuilder) + prefixWithSlash(newPath);\n\n // Check if this path matches the current location\n if (trimSlash(location.pathname) !== trimSlash(basename + branch.pathname)) {\n continue;\n }\n\n // Check if this is a parameterized route like /stores/:storeId/products/:productId\n if (\n getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) &&\n !pathEndsWithWildcard(pathBuilder)\n ) {\n return [(_stripBasename ? '' : basename) + newPath, 'route'];\n }\n\n // Handle wildcard routes with children - strip trailing wildcard\n if (pathIsWildcardAndHasChildren(pathBuilder, branch)) {\n pathBuilder = pathBuilder.slice(0, -1);\n }\n\n return [(_stripBasename ? '' : basename) + pathBuilder, 'route'];\n }\n\n // Fallback when no matching route found\n return [getFallbackTransactionName(location, basename), 'url'];\n}\n\n/**\n * Shared helper function to resolve route name and source\n */\nexport function resolveRouteNameAndSource(\n location: Location,\n routes: RouteObject[],\n allRoutes: RouteObject[],\n branches: RouteMatch[],\n basename: string = '',\n): [string, TransactionSource] {\n let name: string | undefined;\n let source: TransactionSource = 'url';\n\n const isInDescendantRoute = locationIsInsideDescendantRoute(location, allRoutes);\n\n if (isInDescendantRoute) {\n name = prefixWithSlash(rebuildRoutePathFromAllRoutes(allRoutes, location));\n source = 'route';\n }\n\n if (!isInDescendantRoute || !name) {\n [name, source] = getNormalizedName(routes, location, branches, basename);\n }\n\n return [name || location.pathname, source];\n}\n\n/**\n * Gets the active root span if it's a pageload or navigation span.\n */\nexport function getActiveRootSpan(): Span | undefined {\n const span = getActiveSpan();\n const rootSpan = span ? getRootSpan(span) : undefined;\n\n if (!rootSpan) {\n return undefined;\n }\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/reactrouter-compat-utils/utils.ts"],"sourcesContent":["import type { Span, TransactionSource } from '@sentry/core';\nimport { debug, getActiveSpan, getRootSpan, spanToJSON } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport type { Location, MatchRoutes, RouteMatch, RouteObject } from '../types';\nimport { matchRouteManifest, stripBasenameFromPathname } from './route-manifest';\n\n// Global variables that these utilities depend on\nlet _matchRoutes: MatchRoutes;\nlet _stripBasename: boolean = false;\n\n// Navigation context stack for nested/concurrent patchRoutesOnNavigation calls.\n// Required because window.location hasn't updated yet when handlers are invoked.\ninterface NavigationContext {\n token: object;\n targetPath: string | undefined;\n span: Span | undefined;\n}\n\nconst _navigationContextStack: NavigationContext[] = [];\nconst MAX_CONTEXT_STACK_SIZE = 10;\n\n/**\n * Pushes a navigation context and returns a unique token for cleanup.\n * The token uses object identity for uniqueness (no counter needed).\n */\nexport function setNavigationContext(targetPath: string | undefined, span: Span | undefined): object {\n const token = {};\n // Prevent unbounded stack growth - oldest (likely stale) contexts are evicted first\n if (_navigationContextStack.length >= MAX_CONTEXT_STACK_SIZE) {\n DEBUG_BUILD && debug.warn('[React Router] Navigation context stack overflow - removing oldest context');\n _navigationContextStack.shift();\n }\n _navigationContextStack.push({ token, targetPath, span });\n return token;\n}\n\n/**\n * Clears the navigation context if it's on top of the stack (LIFO).\n * If our context is not on top (out-of-order completion), we leave it -\n * it will be cleaned up by overflow protection when the stack fills up.\n */\nexport function clearNavigationContext(token: object): void {\n const top = _navigationContextStack[_navigationContextStack.length - 1];\n if (top?.token === token) {\n _navigationContextStack.pop();\n }\n}\n\n/** Gets the current (most recent) navigation context if inside a patchRoutesOnNavigation call. */\nexport function getNavigationContext(): NavigationContext | null {\n const length = _navigationContextStack.length;\n // The `?? null` converts undefined (from array access) to null to match return type\n return length > 0 ? (_navigationContextStack[length - 1] ?? null) : null;\n}\n\n/**\n * Initialize function to set dependencies that the router utilities need.\n * Must be called before using any of the exported utility functions.\n */\nexport function initializeRouterUtils(matchRoutes: MatchRoutes, stripBasename: boolean = false): void {\n _matchRoutes = matchRoutes;\n _stripBasename = stripBasename;\n}\n\n// Helper functions\nfunction pickPath(match: RouteMatch): string {\n return trimWildcard(match.route.path || '');\n}\n\nfunction pickSplat(match: RouteMatch): string {\n return match.params['*'] || '';\n}\n\nfunction trimWildcard(path: string): string {\n return path[path.length - 1] === '*' ? path.slice(0, -1) : path;\n}\n\nfunction trimSlash(path: string): string {\n return path[path.length - 1] === '/' ? path.slice(0, -1) : path;\n}\n\n/**\n * Checks if a path ends with a wildcard character (*).\n */\nexport function pathEndsWithWildcard(path: string): boolean {\n return path.endsWith('*');\n}\n\n/** Checks if transaction name has wildcard (/* or ends with *). */\nexport function transactionNameHasWildcard(name: string): boolean {\n return name.includes('/*') || name.endsWith('*');\n}\n\n/**\n * Checks if a path is a wildcard and has child routes.\n */\nexport function pathIsWildcardAndHasChildren(path: string, branch: RouteMatch<string>): boolean {\n return (pathEndsWithWildcard(path) && !!branch.route.children?.length) || false;\n}\n\n/** Check if route is in descendant route (<Routes> within <Routes>) */\nexport function routeIsDescendant(route: RouteObject): boolean {\n return !!(!route.children && route.element && route.path?.endsWith('/*'));\n}\n\nfunction sendIndexPath(pathBuilder: string, pathname: string, basename: string): [string, TransactionSource] {\n const reconstructedPath =\n pathBuilder && pathBuilder.length > 0\n ? pathBuilder\n : _stripBasename\n ? stripBasenameFromPathname(pathname, basename)\n : pathname;\n\n let formattedPath =\n // If the path ends with a wildcard suffix, remove both the slash and the asterisk\n reconstructedPath.slice(-2) === '/*' ? reconstructedPath.slice(0, -2) : reconstructedPath;\n\n // If the path ends with a slash, remove it (but keep single '/')\n if (formattedPath.length > 1 && formattedPath[formattedPath.length - 1] === '/') {\n formattedPath = formattedPath.slice(0, -1);\n }\n\n return [formattedPath, 'route'];\n}\n\n/**\n * Returns the number of URL segments in the given URL string.\n * Splits at '/' or '\\/' to handle regex URLs correctly.\n *\n * @param url - The URL string to segment.\n * @returns The number of segments in the URL.\n */\nexport function getNumberOfUrlSegments(url: string): number {\n // split at '/' or at '\\/' to split regex urls correctly\n return url.split(/\\\\?\\//).filter(s => s.length > 0 && s !== ',').length;\n}\n\n// Exported utility functions\n\n/**\n * Ensures a path string starts with a forward slash.\n */\nexport function prefixWithSlash(path: string): string {\n return path[0] === '/' ? path : `/${path}`;\n}\n\n/**\n * Rebuilds the route path from all available routes by matching against the current location.\n */\nexport function rebuildRoutePathFromAllRoutes(allRoutes: RouteObject[], location: Location): string {\n const matchedRoutes = _matchRoutes(allRoutes, location) as RouteMatch[];\n\n if (!matchedRoutes || matchedRoutes.length === 0) {\n return '';\n }\n\n for (const match of matchedRoutes) {\n if (match.route.path && match.route.path !== '*') {\n const path = pickPath(match);\n const strippedPath = stripBasenameFromPathname(location.pathname, prefixWithSlash(match.pathnameBase));\n\n if (location.pathname === strippedPath) {\n return trimSlash(strippedPath);\n }\n\n return trimSlash(\n trimSlash(path || '') +\n prefixWithSlash(\n rebuildRoutePathFromAllRoutes(\n allRoutes.filter(route => route !== match.route),\n {\n pathname: strippedPath,\n },\n ),\n ),\n );\n }\n }\n\n return '';\n}\n\n/**\n * Checks if the current location is inside a descendant route (route with splat parameter).\n */\nexport function locationIsInsideDescendantRoute(location: Location, routes: RouteObject[]): boolean {\n const matchedRoutes = _matchRoutes(routes, location) as RouteMatch[];\n\n if (matchedRoutes) {\n for (const match of matchedRoutes) {\n if (routeIsDescendant(match.route) && pickSplat(match)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Returns a fallback transaction name from location pathname.\n */\nfunction getFallbackTransactionName(location: Location, basename: string): string {\n return _stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname || '';\n}\n\n/**\n * Gets a normalized route name and transaction source from the current routes and location.\n */\nexport function getNormalizedName(\n routes: RouteObject[],\n location: Location,\n branches: RouteMatch[],\n basename: string = '',\n): [string, TransactionSource] {\n if (!routes || routes.length === 0) {\n return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url'];\n }\n\n if (!branches) {\n return [getFallbackTransactionName(location, basename), 'url'];\n }\n\n let pathBuilder = '';\n\n for (const branch of branches) {\n const route = branch.route;\n if (!route) {\n continue;\n }\n\n // Early return for index routes\n if (route.index) {\n return sendIndexPath(pathBuilder, branch.pathname, basename);\n }\n\n const path = route.path;\n if (!path || pathIsWildcardAndHasChildren(path, branch)) {\n continue;\n }\n\n // Build the route path\n const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`;\n pathBuilder = trimSlash(pathBuilder) + prefixWithSlash(newPath);\n\n // Check if this path matches the current location\n if (trimSlash(location.pathname) !== trimSlash(basename + branch.pathname)) {\n continue;\n }\n\n // Check if this is a parameterized route like /stores/:storeId/products/:productId\n if (\n getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) &&\n !pathEndsWithWildcard(pathBuilder)\n ) {\n return [(_stripBasename ? '' : basename) + newPath, 'route'];\n }\n\n // Handle wildcard routes with children - strip trailing wildcard\n if (pathIsWildcardAndHasChildren(pathBuilder, branch)) {\n pathBuilder = pathBuilder.slice(0, -1);\n }\n\n return [(_stripBasename ? '' : basename) + pathBuilder, 'route'];\n }\n\n // Fallback when no matching route found\n return [getFallbackTransactionName(location, basename), 'url'];\n}\n\n/**\n * Shared helper function to resolve route name and source\n */\nexport function resolveRouteNameAndSource(\n location: Location,\n routes: RouteObject[],\n allRoutes: RouteObject[],\n branches: RouteMatch[],\n basename: string = '',\n lazyRouteManifest?: string[],\n enableAsyncRouteHandlers?: boolean,\n): [string, TransactionSource] {\n // When lazy route manifest is provided, use it as the primary source for transaction names\n if (enableAsyncRouteHandlers && lazyRouteManifest && lazyRouteManifest.length > 0) {\n const manifestMatch = matchRouteManifest(location.pathname, lazyRouteManifest, basename);\n if (manifestMatch) {\n return [(_stripBasename ? '' : basename) + manifestMatch, 'route'];\n }\n }\n\n // Fall back to React Router route matching\n let name: string | undefined;\n let source: TransactionSource = 'url';\n\n const isInDescendantRoute = locationIsInsideDescendantRoute(location, allRoutes);\n\n if (isInDescendantRoute) {\n name = prefixWithSlash(rebuildRoutePathFromAllRoutes(allRoutes, location));\n source = 'route';\n }\n\n if (!isInDescendantRoute || !name) {\n [name, source] = getNormalizedName(routes, location, branches, basename);\n }\n\n return [name || location.pathname, source];\n}\n\n/**\n * Gets the active root span if it's a pageload or navigation span.\n */\nexport function getActiveRootSpan(): Span | undefined {\n const span = getActiveSpan();\n const rootSpan = span ? getRootSpan(span) : undefined;\n\n if (!rootSpan) {\n return undefined;\n }\n\n const op = spanToJSON(rootSpan).op;\n\n // Only use this root span if it is a pageload or navigation span\n return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;\n}\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { browserTracingIntegration, startBrowserTracingPageLoadSpan, startBrowserTracingNavigationSpan, WINDOW } from '@sentry/browser';
2
- import { getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, getActiveSpan, getRootSpan, spanToJSON } from '@sentry/core';
2
+ import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_OP, getCurrentScope, getActiveSpan, getRootSpan, spanToJSON } from '@sentry/core';
3
3
  import * as React from 'react';
4
4
  import { hoistNonReactStatics } from './hoist-non-react-statics.js';
5
5
 
@@ -1,4 +1,4 @@
1
- import { createReactRouterV6CompatibleTracingIntegration, createV6CompatibleWithSentryReactRouterRouting, createV6CompatibleWrapUseRoutes, createV6CompatibleWrapCreateBrowserRouter, createV6CompatibleWrapCreateMemoryRouter } from './reactrouter-compat-utils/instrumentation.js';
1
+ import { createReactRouterV6CompatibleTracingIntegration, createV6CompatibleWithSentryReactRouterRouting, createV6CompatibleWrapCreateBrowserRouter, createV6CompatibleWrapCreateMemoryRouter, createV6CompatibleWrapUseRoutes } from './reactrouter-compat-utils/instrumentation.js';
2
2
  import '@sentry/core';
3
3
  import '@sentry/browser';
4
4
 
@@ -58,6 +58,24 @@ export interface ReactRouterOptions {
58
58
  * @default idleTimeout * 3
59
59
  */
60
60
  lazyRouteTimeout?: number;
61
+ /**
62
+ * Static route manifest for resolving parameterized route names with lazy routes.
63
+ *
64
+ * Requires `enableAsyncRouteHandlers: true`. When provided, the manifest is used
65
+ * as the primary source for determining transaction names. This is more reliable
66
+ * than depending on React Router's lazy route resolution timing.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * lazyRouteManifest: [
71
+ * '/',
72
+ * '/users',
73
+ * '/users/:userId',
74
+ * '/org/:orgSlug/projects/:projectId',
75
+ * ]
76
+ * ```
77
+ */
78
+ lazyRouteManifest?: string[];
61
79
  }
62
80
  type V6CompatibleVersion = '6' | '7';
63
81
  export declare function addResolvedRoutesToParent(resolvedRoutes: RouteObject[], parentRoute: RouteObject): void;
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../../src/reactrouter-compat-utils/instrumentation.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../../src/reactrouter-compat-utils/instrumentation.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-routes.d.ts","sourceRoot":"","sources":["../../../src/reactrouter-compat-utils/lazy-routes.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAoDtD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EACjD,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,EAClB,qBAAqB,EAAE,CACrB,cAAc,EAAE,WAAW,EAAE,EAC7B,WAAW,CAAC,EAAE,WAAW,EACzB,eAAe,CAAC,EAAE,QAAQ,EAC1B,YAAY,CAAC,EAAE,IAAI,KAChB,IAAI,GACR,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAqBjC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,EAClB,qBAAqB,EAAE,CACrB,cAAc,EAAE,WAAW,EAAE,EAC7B,WAAW,CAAC,EAAE,WAAW,EACzB,eAAe,CAAC,EAAE,QAAQ,EAC1B,YAAY,CAAC,EAAE,IAAI,KAChB,IAAI,EACT,eAAe,EAAE,QAAQ,GAAG,IAAI,EAChC,YAAY,EAAE,IAAI,GAAG,SAAS,GAC7B,IAAI,CAcN;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,WAAW,EAClB,qBAAqB,EAAE,CACrB,cAAc,EAAE,WAAW,EAAE,EAC7B,WAAW,CAAC,EAAE,WAAW,EACzB,eAAe,CAAC,EAAE,QAAQ,EAC1B,YAAY,CAAC,EAAE,IAAI,KAChB,IAAI,GACR,IAAI,CAiBN"}
1
+ {"version":3,"file":"lazy-routes.d.ts","sourceRoot":"","sources":["../../../src/reactrouter-compat-utils/lazy-routes.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA6DtD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EACjD,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,EAClB,qBAAqB,EAAE,CACrB,cAAc,EAAE,WAAW,EAAE,EAC7B,WAAW,CAAC,EAAE,WAAW,EACzB,eAAe,CAAC,EAAE,QAAQ,EAC1B,YAAY,CAAC,EAAE,IAAI,KAChB,IAAI,GACR,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAqBjC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,EAClB,qBAAqB,EAAE,CACrB,cAAc,EAAE,WAAW,EAAE,EAC7B,WAAW,CAAC,EAAE,WAAW,EACzB,eAAe,CAAC,EAAE,QAAQ,EAC1B,YAAY,CAAC,EAAE,IAAI,KAChB,IAAI,EACT,eAAe,EAAE,QAAQ,GAAG,IAAI,EAChC,YAAY,EAAE,IAAI,GAAG,SAAS,GAC7B,IAAI,CAcN;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,WAAW,EAClB,qBAAqB,EAAE,CACrB,cAAc,EAAE,WAAW,EAAE,EAC7B,WAAW,CAAC,EAAE,WAAW,EACzB,eAAe,CAAC,EAAE,QAAQ,EAC1B,YAAY,CAAC,EAAE,IAAI,KAChB,IAAI,GACR,IAAI,CAiBN"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Strip the basename from a pathname if exists.
3
+ *
4
+ * Vendored and modified from `react-router`
5
+ * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038
6
+ */
7
+ export declare function stripBasenameFromPathname(pathname: string, basename: string): string;
8
+ /**
9
+ * Matches a pathname against a route manifest and returns the matching pattern.
10
+ * Optionally strips a basename prefix before matching.
11
+ */
12
+ export declare function matchRouteManifest(pathname: string, manifest: string[], basename?: string): string | null;
13
+ //# sourceMappingURL=route-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-manifest.d.ts","sourceRoot":"","sources":["../../../src/reactrouter-compat-utils/route-manifest.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBpF;AAKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBzG"}
@@ -62,7 +62,7 @@ export declare function getNormalizedName(routes: RouteObject[], location: Locat
62
62
  /**
63
63
  * Shared helper function to resolve route name and source
64
64
  */
65
- export declare function resolveRouteNameAndSource(location: Location, routes: RouteObject[], allRoutes: RouteObject[], branches: RouteMatch[], basename?: string): [string, TransactionSource];
65
+ export declare function resolveRouteNameAndSource(location: Location, routes: RouteObject[], allRoutes: RouteObject[], branches: RouteMatch[], basename?: string, lazyRouteManifest?: string[], enableAsyncRouteHandlers?: boolean): [string, TransactionSource];
66
66
  /**
67
67
  * Gets the active root span if it's a pageload or navigation span.
68
68
  */
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/reactrouter-compat-utils/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAG5D,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQ/E,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;CACxB;AAKD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,MAAM,CASnG;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK1D;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,IAAI,CAI/D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,GAAE,OAAe,GAAG,IAAI,CAGpG;AAmBD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,mEAAmE;AACnE,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,OAAO,CAE9F;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE7D;AAsBD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1D;AA+BD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA+BlG;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAYlG;AASD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EAAE,EACrB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,UAAU,EAAE,EACtB,QAAQ,GAAE,MAAW,GACpB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAsD7B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,EAAE,EACrB,SAAS,EAAE,WAAW,EAAE,EACxB,QAAQ,EAAE,UAAU,EAAE,EACtB,QAAQ,GAAE,MAAW,GACpB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAgB7B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,GAAG,SAAS,CAYpD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/reactrouter-compat-utils/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAG5D,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAS/E,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;CACxB;AAKD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,MAAM,CASnG;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAK1D;AAED,kGAAkG;AAClG,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,IAAI,CAI/D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,GAAE,OAAe,GAAG,IAAI,CAGpG;AAmBD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,mEAAmE;AACnE,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,OAAO,CAE9F;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAE7D;AAsBD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1D;AAID;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA+BlG;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAYlG;AASD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EAAE,EACrB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,UAAU,EAAE,EACtB,QAAQ,GAAE,MAAW,GACpB,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAsD7B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,EAAE,EACrB,SAAS,EAAE,WAAW,EAAE,EACxB,QAAQ,EAAE,UAAU,EAAE,EACtB,QAAQ,GAAE,MAAW,EACrB,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAC5B,wBAAwB,CAAC,EAAE,OAAO,GACjC,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAyB7B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,GAAG,SAAS,CAYpD"}
@@ -58,6 +58,24 @@ export interface ReactRouterOptions {
58
58
  * @default idleTimeout * 3
59
59
  */
60
60
  lazyRouteTimeout?: number;
61
+ /**
62
+ * Static route manifest for resolving parameterized route names with lazy routes.
63
+ *
64
+ * Requires `enableAsyncRouteHandlers: true`. When provided, the manifest is used
65
+ * as the primary source for determining transaction names. This is more reliable
66
+ * than depending on React Router's lazy route resolution timing.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * lazyRouteManifest: [
71
+ * '/',
72
+ * '/users',
73
+ * '/users/:userId',
74
+ * '/org/:orgSlug/projects/:projectId',
75
+ * ]
76
+ * ```
77
+ */
78
+ lazyRouteManifest?: string[];
61
79
  }
62
80
  type V6CompatibleVersion = '6' | '7';
63
81
  export declare function addResolvedRoutesToParent(resolvedRoutes: RouteObject[], parentRoute: RouteObject): void;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Strip the basename from a pathname if exists.
3
+ *
4
+ * Vendored and modified from `react-router`
5
+ * https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038
6
+ */
7
+ export declare function stripBasenameFromPathname(pathname: string, basename: string): string;
8
+ /**
9
+ * Matches a pathname against a route manifest and returns the matching pattern.
10
+ * Optionally strips a basename prefix before matching.
11
+ */
12
+ export declare function matchRouteManifest(pathname: string, manifest: string[], basename?: string): string | null;
13
+ //# sourceMappingURL=route-manifest.d.ts.map
@@ -65,7 +65,7 @@ export declare function getNormalizedName(routes: RouteObject[], location: Locat
65
65
  /**
66
66
  * Shared helper function to resolve route name and source
67
67
  */
68
- export declare function resolveRouteNameAndSource(location: Location, routes: RouteObject[], allRoutes: RouteObject[], branches: RouteMatch[], basename?: string): [
68
+ export declare function resolveRouteNameAndSource(location: Location, routes: RouteObject[], allRoutes: RouteObject[], branches: RouteMatch[], basename?: string, lazyRouteManifest?: string[], enableAsyncRouteHandlers?: boolean): [
69
69
  string,
70
70
  TransactionSource
71
71
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/react",
3
- "version": "10.37.0",
3
+ "version": "10.39.0-alpha.0",
4
4
  "description": "Official Sentry SDK for React.js",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react",
@@ -39,8 +39,8 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@sentry/browser": "10.37.0",
43
- "@sentry/core": "10.37.0"
42
+ "@sentry/browser": "10.39.0-alpha.0",
43
+ "@sentry/core": "10.39.0-alpha.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "react": "^16.14.0 || 17.x || 18.x || 19.x"
@@ -62,8 +62,8 @@
62
62
  "react-dom": "^18.3.1",
63
63
  "react-router-3": "npm:react-router@3.2.0",
64
64
  "react-router-4": "npm:react-router@4.1.0",
65
- "react-router-5": "npm:react-router@5.0.0",
66
- "react-router-6": "npm:react-router@6.28.0",
65
+ "react-router-5": "npm:react-router@5.3.4",
66
+ "react-router-6": "npm:react-router@6.30.3",
67
67
  "redux": "^4.0.5"
68
68
  },
69
69
  "scripts": {