Skip to content

Commit 0e85f9b

Browse files
committed
Move under folder
1 parent a0e44bd commit 0e85f9b

File tree

6 files changed

+89
-241
lines changed

6 files changed

+89
-241
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Main exports from instrumentation
2+
export type { ReactRouterOptions } from './instrumentation';
3+
export {
4+
createReactRouterV6CompatibleTracingIntegration,
5+
createV6CompatibleWithSentryReactRouterRouting,
6+
createV6CompatibleWrapCreateBrowserRouter,
7+
createV6CompatibleWrapCreateMemoryRouter,
8+
createV6CompatibleWrapUseRoutes,
9+
handleNavigation,
10+
handleExistingNavigationSpan,
11+
createNewNavigationSpan,
12+
addResolvedRoutesToParent,
13+
} from './instrumentation';
14+
15+
// Utility exports
16+
export {
17+
initializeRouterUtils,
18+
prefixWithSlash,
19+
rebuildRoutePathFromAllRoutes,
20+
locationIsInsideDescendantRoute,
21+
getNormalizedName,
22+
resolveRouteNameAndSource,
23+
pathEndsWithWildcard,
24+
pathIsWildcardAndHasChildren,
25+
} from './utils';
26+
27+
// Lazy route exports
28+
export {
29+
updateNavigationSpanWithLazyRoutes,
30+
createAsyncHandlerProxy,
31+
handleAsyncHandlerResult,
32+
checkRouteForAsyncHandler,
33+
} from './lazy-routes';

packages/react/src/reactrouterv6-compat-utils.tsx renamed to packages/react/src/reactrouter-compat-utils/instrumentation.tsx

Lines changed: 13 additions & 231 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,8 @@ import {
2222
spanToJSON,
2323
} from '@sentry/core';
2424
import * as React from 'react';
25-
import { DEBUG_BUILD } from './debug-build';
26-
import { hoistNonReactStatics } from './hoist-non-react-statics';
27-
import { checkRouteForAsyncHandler, updateNavigationSpanWithLazyRoutes } from './lazy-route-utils';
28-
import {
29-
initializeRouterUtils,
30-
} from './reactrouterv6-utils';
25+
import { DEBUG_BUILD } from '../debug-build';
26+
import { hoistNonReactStatics } from '../hoist-non-react-statics';
3127
import type {
3228
Action,
3329
AgnosticDataRouteMatch,
@@ -43,14 +39,22 @@ import type {
4339
UseLocation,
4440
UseNavigationType,
4541
UseRoutes,
46-
} from './types';
42+
} from '../types';
43+
import { checkRouteForAsyncHandler, updateNavigationSpanWithLazyRoutes } from './lazy-routes';
44+
import {
45+
getNormalizedName,
46+
initializeRouterUtils,
47+
locationIsInsideDescendantRoute,
48+
prefixWithSlash,
49+
rebuildRoutePathFromAllRoutes,
50+
resolveRouteNameAndSource,
51+
} from './utils';
4752

4853
let _useEffect: UseEffect;
4954
let _useLocation: UseLocation;
5055
let _useNavigationType: UseNavigationType;
5156
let _createRoutesFromChildren: CreateRoutesFromChildren;
5257
let _matchRoutes: MatchRoutes;
53-
let _stripBasename: boolean = false;
5458
let _enableAsyncRouteHandlers: boolean = false;
5559

5660
const CLIENTS_WITH_INSTRUMENT_NAVIGATION = new WeakSet<Client>();
@@ -152,13 +156,7 @@ function processResolvedRoutes(
152156
);
153157
} else if (spanOp === 'navigation') {
154158
// For navigation spans, update the name with the newly loaded routes
155-
updateNavigationSpanWithLazyRoutes(
156-
activeRootSpan,
157-
location,
158-
Array.from(allRoutes),
159-
false,
160-
_matchRoutes,
161-
);
159+
updateNavigationSpanWithLazyRoutes(activeRootSpan, location, Array.from(allRoutes), false, _matchRoutes);
162160
}
163161
}
164162
}
@@ -440,7 +438,6 @@ export function createReactRouterV6CompatibleTracingIntegration(
440438
_useNavigationType = useNavigationType;
441439
_matchRoutes = matchRoutes;
442440
_createRoutesFromChildren = createRoutesFromChildren;
443-
_stripBasename = stripBasename || false;
444441
_enableAsyncRouteHandlers = enableAsyncRouteHandlers;
445442

446443
// Initialize the router utils with the required dependencies
@@ -570,74 +567,6 @@ export function handleNavigation(opts: {
570567
}
571568
}
572569

573-
/**
574-
* Strip the basename from a pathname if exists.
575-
*
576-
* Vendored and modified from `react-router`
577-
* https://github.com/remix-run/react-router/blob/462bb712156a3f739d6139a0f14810b76b002df6/packages/router/utils.ts#L1038
578-
*/
579-
function stripBasenameFromPathname(pathname: string, basename: string): string {
580-
if (!basename || basename === '/') {
581-
return pathname;
582-
}
583-
584-
if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
585-
return pathname;
586-
}
587-
588-
// We want to leave trailing slash behavior in the user's control, so if they
589-
// specify a basename with a trailing slash, we should support it
590-
const startIndex = basename.endsWith('/') ? basename.length - 1 : basename.length;
591-
const nextChar = pathname.charAt(startIndex);
592-
if (nextChar && nextChar !== '/') {
593-
// pathname does not start with basename/
594-
return pathname;
595-
}
596-
597-
return pathname.slice(startIndex) || '/';
598-
}
599-
600-
function sendIndexPath(pathBuilder: string, pathname: string, basename: string): [string, TransactionSource] {
601-
const reconstructedPath = pathBuilder || _stripBasename ? stripBasenameFromPathname(pathname, basename) : pathname;
602-
603-
const formattedPath =
604-
// If the path ends with a slash, remove it
605-
reconstructedPath[reconstructedPath.length - 1] === '/'
606-
? reconstructedPath.slice(0, -1)
607-
: // If the path ends with a wildcard, remove it
608-
reconstructedPath.slice(-2) === '/*'
609-
? reconstructedPath.slice(0, -1)
610-
: reconstructedPath;
611-
612-
return [formattedPath, 'route'];
613-
}
614-
615-
function pathEndsWithWildcard(path: string): boolean {
616-
return path.endsWith('*');
617-
}
618-
619-
function pathIsWildcardAndHasChildren(path: string, branch: RouteMatch<string>): boolean {
620-
return (pathEndsWithWildcard(path) && !!branch.route.children?.length) || false;
621-
}
622-
623-
function routeIsDescendant(route: RouteObject): boolean {
624-
return !!(!route.children && route.element && route.path?.endsWith('/*'));
625-
}
626-
627-
function locationIsInsideDescendantRoute(location: Location, routes: RouteObject[]): boolean {
628-
const matchedRoutes = _matchRoutes(routes, location) as RouteMatch[];
629-
630-
if (matchedRoutes) {
631-
for (const match of matchedRoutes) {
632-
if (routeIsDescendant(match.route) && pickSplat(match)) {
633-
return true;
634-
}
635-
}
636-
}
637-
638-
return false;
639-
}
640-
641570
function addRoutesToAllRoutes(routes: RouteObject[]): void {
642571
routes.forEach(route => {
643572
const extractedChildRoutes = getChildRoutesRecursively(route);
@@ -666,118 +595,6 @@ function getChildRoutesRecursively(route: RouteObject, allRoutes: Set<RouteObjec
666595
return allRoutes;
667596
}
668597

669-
function pickPath(match: RouteMatch): string {
670-
return trimWildcard(match.route.path || '');
671-
}
672-
673-
function pickSplat(match: RouteMatch): string {
674-
return match.params['*'] || '';
675-
}
676-
677-
function trimWildcard(path: string): string {
678-
return path[path.length - 1] === '*' ? path.slice(0, -1) : path;
679-
}
680-
681-
function trimSlash(path: string): string {
682-
return path[path.length - 1] === '/' ? path.slice(0, -1) : path;
683-
}
684-
685-
function prefixWithSlash(path: string): string {
686-
return path[0] === '/' ? path : `/${path}`;
687-
}
688-
689-
function rebuildRoutePathFromAllRoutes(allRoutes: RouteObject[], location: Location): string {
690-
const matchedRoutes = _matchRoutes(allRoutes, location) as RouteMatch[];
691-
692-
if (!matchedRoutes || matchedRoutes.length === 0) {
693-
return '';
694-
}
695-
696-
for (const match of matchedRoutes) {
697-
if (match.route.path && match.route.path !== '*') {
698-
const path = pickPath(match);
699-
const strippedPath = stripBasenameFromPathname(location.pathname, prefixWithSlash(match.pathnameBase));
700-
701-
if (location.pathname === strippedPath) {
702-
return trimSlash(strippedPath);
703-
}
704-
705-
return trimSlash(
706-
trimSlash(path || '') +
707-
prefixWithSlash(
708-
rebuildRoutePathFromAllRoutes(
709-
allRoutes.filter(route => route !== match.route),
710-
{
711-
pathname: strippedPath,
712-
},
713-
),
714-
),
715-
);
716-
}
717-
}
718-
719-
return '';
720-
}
721-
722-
function getNormalizedName(
723-
routes: RouteObject[],
724-
location: Location,
725-
branches: RouteMatch[],
726-
basename: string = '',
727-
): [string, TransactionSource] {
728-
if (!routes || routes.length === 0) {
729-
return [_stripBasename ? stripBasenameFromPathname(location.pathname, basename) : location.pathname, 'url'];
730-
}
731-
732-
let pathBuilder = '';
733-
734-
if (branches) {
735-
for (const branch of branches) {
736-
const route = branch.route;
737-
if (route) {
738-
// Early return if index route
739-
if (route.index) {
740-
return sendIndexPath(pathBuilder, branch.pathname, basename);
741-
}
742-
const path = route.path;
743-
744-
// If path is not a wildcard and has no child routes, append the path
745-
if (path && !pathIsWildcardAndHasChildren(path, branch)) {
746-
const newPath = path[0] === '/' || pathBuilder[pathBuilder.length - 1] === '/' ? path : `/${path}`;
747-
pathBuilder = trimSlash(pathBuilder) + prefixWithSlash(newPath);
748-
749-
// If the path matches the current location, return the path
750-
if (trimSlash(location.pathname) === trimSlash(basename + branch.pathname)) {
751-
if (
752-
// If the route defined on the element is something like
753-
// <Route path="/stores/:storeId/products/:productId" element={<div>Product</div>} />
754-
// We should check against the branch.pathname for the number of / separators
755-
getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname) &&
756-
// We should not count wildcard operators in the url segments calculation
757-
!pathEndsWithWildcard(pathBuilder)
758-
) {
759-
return [(_stripBasename ? '' : basename) + newPath, 'route'];
760-
}
761-
762-
// if the last character of the pathbuilder is a wildcard and there are children, remove the wildcard
763-
if (pathIsWildcardAndHasChildren(pathBuilder, branch)) {
764-
pathBuilder = pathBuilder.slice(0, -1);
765-
}
766-
767-
return [(_stripBasename ? '' : basename) + pathBuilder, 'route'];
768-
}
769-
}
770-
}
771-
}
772-
}
773-
774-
const fallbackTransactionName = _stripBasename
775-
? stripBasenameFromPathname(location.pathname, basename)
776-
: location.pathname;
777-
778-
return [fallbackTransactionName, 'url'];
779-
}
780-
781598
function updatePageloadTransaction(
782599
activeRootSpan: Span | undefined,
783600
location: Location,
@@ -884,33 +701,6 @@ function getActiveRootSpan(): Span | undefined {
884701
return op === 'navigation' || op === 'pageload' ? rootSpan : undefined;
885702
}
886703

887-
/**
888-
* Shared helper function to resolve route name and source
889-
*/
890-
export function resolveRouteNameAndSource(
891-
location: Location,
892-
routes: RouteObject[],
893-
allRoutes: RouteObject[],
894-
branches: RouteMatch[],
895-
basename: string = '',
896-
): [string, TransactionSource] {
897-
let name: string | undefined;
898-
let source: TransactionSource = 'url';
899-
900-
const isInDescendantRoute = locationIsInsideDescendantRoute(location, allRoutes);
901-
902-
if (isInDescendantRoute) {
903-
name = prefixWithSlash(rebuildRoutePathFromAllRoutes(allRoutes, location));
904-
source = 'route';
905-
}
906-
907-
if (!isInDescendantRoute || !name) {
908-
[name, source] = getNormalizedName(routes, location, branches, basename);
909-
}
910-
911-
return [name || location.pathname, source];
912-
}
913-
914704
/**
915705
* Handles updating an existing navigation span
916706
*/
@@ -997,11 +787,3 @@ export function addResolvedRoutesToParent(resolvedRoutes: RouteObject[], parentR
997787
parentRoute.children = [...existingChildren, ...newRoutes];
998788
}
999789
}
1000-
1001-
/**
1002-
* Returns number of URL segments of a passed string URL.
1003-
*/
1004-
export function getNumberOfUrlSegments(url: string): number {
1005-
// split at '/' or at '\/' to split regex urls correctly
1006-
return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length;
1007-
}

packages/react/src/lazy-route-utils.tsx renamed to packages/react/src/reactrouter-compat-utils/lazy-routes.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Span } from '@sentry/core';
22
import { addNonEnumerableProperty, debug, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, spanToJSON } from '@sentry/core';
3-
import { DEBUG_BUILD } from './debug-build';
4-
import { resolveRouteNameAndSource } from './reactrouterv6-compat-utils';
5-
import type { Location, MatchRoutes, RouteMatch, RouteObject } from './types';
3+
import { DEBUG_BUILD } from '../debug-build';
4+
import type { Location, MatchRoutes, RouteMatch, RouteObject } from '../types';
5+
import { resolveRouteNameAndSource } from './utils';
66

77
/**
88
* Updates a navigation span with the correct route name after lazy routes have been loaded.

0 commit comments

Comments
 (0)