@@ -54,7 +54,6 @@ import type {
5454 RouteRecordNameGeneric ,
5555} from '../typed-routes'
5656import {
57- isRouteLocation ,
5857 Lazy ,
5958 RawRouteComponent ,
6059 RouteLocationOptions ,
@@ -84,6 +83,12 @@ import {
8483 EXPERIMENTAL_ResolverRecord_Matchable ,
8584 EXPERIMENTAL_ResolverStatic ,
8685} from './route-resolver/resolver-static'
86+ import {
87+ ResolverLocationAsNamed ,
88+ ResolverLocationAsPathRelative ,
89+ ResolverLocationAsRelative ,
90+ ResolverLocationResolved ,
91+ } from './route-resolver/resolver-abstract'
8792
8893/**
8994 * resolve, reject arguments of Promise constructor
@@ -636,38 +641,51 @@ export function experimental_createRouter(
636641 : to
637642 }
638643
644+ // NOTE: to support multiple overloads
645+ type TRecord = EXPERIMENTAL_RouteRecordNormalized
646+ type _resolveArgs =
647+ // TODO: is it worth suppoting the absolute location variants?
648+ // | [absoluteLocation: `/${string}`, currentLocation?: undefined]
649+ | [
650+ relativeLocation : string ,
651+ // FIXME: use router locations
652+ currentLocation ?: ResolverLocationResolved < TRecord > ,
653+ ]
654+ // | [
655+ // absoluteLocation: ResolverLocationAsPathAbsolute,
656+ // // Same as above
657+ // // currentLocation?: NEW_LocationResolved<TRecord> | undefined
658+ // currentLocation?: undefined,
659+ // ]
660+ | [
661+ relativeLocation : ResolverLocationAsPathRelative ,
662+ currentLocation : ResolverLocationResolved < TRecord > ,
663+ ]
664+ | [
665+ location : ResolverLocationAsNamed ,
666+ // Same as above
667+ // currentLocation?: NEW_LocationResolved<TRecord> | undefined
668+ currentLocation ?: undefined ,
669+ ]
670+ | [
671+ relativeLocation : ResolverLocationAsRelative ,
672+ currentLocation : ResolverLocationResolved < TRecord > ,
673+ ]
674+ | [ resolvedLocation : RouteLocationResolved , currentLocation ?: undefined ]
675+
639676 function resolve (
640- rawLocation : RouteLocationRaw ,
641- currentLocation ?: RouteLocationNormalizedLoaded
677+ ...[ to , currentLocation ] : _resolveArgs
642678 ) : RouteLocationResolved {
643679 // const resolve: Router['resolve'] = (rawLocation: RouteLocationRaw, currentLocation) => {
644680 // const objectLocation = routerLocationAsObject(rawLocation)
645681 // we create a copy to modify it later
646682 // TODO: in the experimental version, allow configuring this
647683 currentLocation =
684+ // TODO: || currentRoute.value never evaluated
648685 currentLocation && assign ( { } , currentLocation || currentRoute . value )
649686 // currentLocation = assign({}, currentLocation || currentRoute.value)
650687
651- if ( __DEV__ ) {
652- if ( ! isRouteLocation ( rawLocation ) ) {
653- warn (
654- `router.resolve() was passed an invalid location. This will fail in production.\n- Location:` ,
655- rawLocation
656- )
657- return resolve ( { } )
658- }
659-
660- if (
661- typeof rawLocation === 'object' &&
662- rawLocation . hash ?. startsWith ( '#' )
663- ) {
664- warn (
665- `A \`hash\` should always start with the character "#". Replace "${ rawLocation . hash } " with "#${ rawLocation . hash } ".`
666- )
667- }
668- }
669-
670- // FIXME: is this achieved by matchers?
688+ // FIXME: should this be achieved by matchers?
671689 // remove any nullish param
672690 // if ('params' in rawLocation) {
673691 // const targetParams = assign({}, rawLocation.params)
@@ -680,28 +698,28 @@ export function experimental_createRouter(
680698 // }
681699
682700 const matchedRoute = resolver . resolve (
683- // FIXME: incompatible types
684- rawLocation as any ,
701+ // @ts -expect-error FIXME: incompatible types
702+ to ,
685703 // FIXME: incompatible `matched` requires casting
686- currentLocation as any
704+ currentLocation
687705 )
688706 const href = routerHistory . createHref ( matchedRoute . fullPath )
689707
690708 if ( __DEV__ ) {
691709 if ( href . startsWith ( '//' ) ) {
692710 warn (
693711 `Location ${ JSON . stringify (
694- rawLocation
712+ to
695713 ) } resolved to "${ href } ". A resolved location cannot start with multiple slashes.`
696714 )
697715 }
698716 if ( ! matchedRoute . matched . length ) {
699- warn ( `No match found for location with path "${ rawLocation } "` )
717+ warn ( `No match found for location with path "${ to } "` )
700718 }
701719 }
702720
703721 // matchedRoute is always a new object
704- // @ts -expect-error: the `matched` property is different
722+ // @ts -expect-error: FIXME: the `matched` property is different
705723 return assign ( matchedRoute , {
706724 redirectedFrom : undefined ,
707725 href,
@@ -724,13 +742,10 @@ export function experimental_createRouter(
724742 }
725743 }
726744
727- function push ( to : RouteLocationRaw ) {
728- return pushWithRedirect ( to )
729- }
745+ const push = ( ...args : _resolveArgs ) => pushWithRedirect ( resolve ( ...args ) )
730746
731- function replace ( to : RouteLocationRaw ) {
732- return pushWithRedirect ( to , true )
733- }
747+ const replace = ( ...args : _resolveArgs ) =>
748+ pushWithRedirect ( resolve ( ...args ) , true )
734749
735750 function handleRedirectRecord ( to : RouteLocation ) : RouteLocationRaw | void {
736751 const lastMatched = to . matched [ to . matched . length - 1 ]
@@ -780,40 +795,42 @@ export function experimental_createRouter(
780795 }
781796
782797 function pushWithRedirect (
783- to : RouteLocationRaw | RouteLocation ,
784- _replace ?: boolean ,
798+ to : RouteLocationResolved ,
799+ replace ?: boolean ,
785800 redirectedFrom ?: RouteLocation
786801 ) : Promise < NavigationFailure | void | undefined > {
787- const targetLocation : RouteLocation = ( pendingLocation = resolve ( to ) )
802+ replace = to . replace ?? replace
803+ pendingLocation = to
788804 const from = currentRoute . value
789805 const data : HistoryState | undefined = ( to as RouteLocationOptions ) . state
790806 const force : boolean | undefined = ( to as RouteLocationOptions ) . force
791- const replace = targetLocation . replace ?? _replace
792- console . log ( { replace } )
793807
794- const shouldRedirect = handleRedirectRecord ( targetLocation )
808+ const shouldRedirect = handleRedirectRecord ( to )
795809
796- if ( shouldRedirect )
810+ if ( shouldRedirect ) {
797811 return pushWithRedirect (
798- assign ( locationAsObject ( shouldRedirect ) , {
812+ {
813+ // @ts -expect-error: FIXME: refactor location types
814+ ...resolve ( shouldRedirect , currentRoute . value ) ,
799815 state :
800816 typeof shouldRedirect === 'object'
801817 ? assign ( { } , data , shouldRedirect . state )
802818 : data ,
803819 force,
804- } ) ,
820+ } ,
805821 replace ,
806822 // keep original redirectedFrom if it exists
807- redirectedFrom || targetLocation
823+ redirectedFrom || to
808824 )
825+ }
809826
810827 // if it was a redirect we already called `pushWithRedirect` above
811- const toLocation = targetLocation as RouteLocationNormalized
828+ const toLocation = to as RouteLocationNormalized
812829
813830 toLocation . redirectedFrom = redirectedFrom
814831 let failure : NavigationFailure | void | undefined
815832
816- if ( ! force && isSameRouteLocation ( stringifyQuery , from , targetLocation ) ) {
833+ if ( ! force && isSameRouteLocation ( stringifyQuery , from , to ) ) {
817834 failure = createRouterError < NavigationFailure > (
818835 ErrorTypes . NAVIGATION_DUPLICATED ,
819836 { to : toLocation , from }
@@ -851,6 +868,7 @@ export function experimental_createRouter(
851868 // we are redirecting to the same location we were already at
852869 isSameRouteLocation (
853870 stringifyQuery ,
871+ // @ts -expect-error: FIXME: failure.to should not contain relative locations
854872 resolve ( failure . to ) ,
855873 toLocation
856874 ) &&
@@ -871,14 +889,15 @@ export function experimental_createRouter(
871889 }
872890
873891 return pushWithRedirect (
874- // keep options
875- assign ( locationAsObject ( failure . to ) , {
892+ {
893+ // @ts -expect-error: FIXME: refactor location types
894+ ...resolve ( shouldRedirect , currentRoute . value ) ,
876895 state :
877896 typeof failure . to === 'object'
878897 ? assign ( { } , data , failure . to . state )
879898 : data ,
880899 force,
881- } ) ,
900+ } ,
882901 // preserve an existing replacement but allow the redirect to override it
883902 replace ,
884903 // preserve the original redirectedFrom if any
@@ -1123,7 +1142,11 @@ export function experimental_createRouter(
11231142 const shouldRedirect = handleRedirectRecord ( toLocation )
11241143 if ( shouldRedirect ) {
11251144 pushWithRedirect (
1126- assign ( shouldRedirect , { force : true } ) ,
1145+ assign (
1146+ // @ts -expect-error: FIXME: refactor location types
1147+ resolve ( shouldRedirect ) ,
1148+ { force : true }
1149+ ) ,
11271150 true ,
11281151 toLocation
11291152 ) . catch ( noop )
@@ -1165,9 +1188,15 @@ export function experimental_createRouter(
11651188 // the error is already handled by router.push we just want to avoid
11661189 // logging the error
11671190 pushWithRedirect (
1168- assign ( locationAsObject ( ( error as NavigationRedirectError ) . to ) , {
1169- force : true ,
1170- } ) ,
1191+ assign (
1192+ resolve (
1193+ // @ts -expect-error: to should be an absolute location
1194+ ( error as NavigationRedirectError ) . to
1195+ ) ,
1196+ {
1197+ force : true ,
1198+ }
1199+ ) ,
11711200 undefined ,
11721201 toLocation
11731202 // avoid an uncaught rejection, let push call triggerError
@@ -1337,10 +1366,13 @@ export function experimental_createRouter(
13371366
13381367 hasRoute,
13391368 getRoutes,
1369+ // @ts -expect-error FIXME: update EXPERIMENTAL_Router types
13401370 resolve,
13411371 options,
13421372
1373+ // @ts -expect-error FIXME: update EXPERIMENTAL_Router types
13431374 push,
1375+ // @ts -expect-error FIXME: update EXPERIMENTAL_Router types
13441376 replace,
13451377 go,
13461378 back : ( ) => go ( - 1 ) ,
0 commit comments