@@ -22,12 +22,8 @@ import {
2222 spanToJSON ,
2323} from '@sentry/core' ;
2424import * 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' ;
3127import 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
4853let _useEffect : UseEffect ;
4954let _useLocation : UseLocation ;
5055let _useNavigationType : UseNavigationType ;
5156let _createRoutesFromChildren : CreateRoutesFromChildren ;
5257let _matchRoutes : MatchRoutes ;
53- let _stripBasename : boolean = false ;
5458let _enableAsyncRouteHandlers : boolean = false ;
5559
5660const 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-
641570function 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-
781598function 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- }
0 commit comments