routerKey,
routerViewLocationKey,
} from '../injectionSymbols'
-import { MatcherLocationAsPathAbsolute } from '../new-route-resolver/matcher-location'
/**
* resolve, reject arguments of Promise constructor
currentLocation && assign({}, currentLocation || currentRoute.value)
// currentLocation = assign({}, currentLocation || currentRoute.value)
- const locationObject = locationAsObject(
- rawLocation,
- currentRoute.value.path
- )
-
if (__DEV__) {
if (!isRouteLocation(rawLocation)) {
warn(
return resolve({})
}
- if (!locationObject.hash?.startsWith('#')) {
+ if (
+ typeof rawLocation === 'object' &&
+ rawLocation.hash?.startsWith('#')
+ ) {
warn(
- `A \`hash\` should always start with the character "#". Replace "${locationObject.hash}" with "#${locationObject.hash}".`
+ `A \`hash\` should always start with the character "#". Replace "${rawLocation.hash}" with "#${rawLocation.hash}".`
)
}
}
// }
const matchedRoute = matcher.resolve(
- // FIXME: should be ok
- // locationObject as MatcherLocationAsPathRelative,
- // locationObject as MatcherLocationAsRelative,
- // locationObject as MatcherLocationAsName, // TODO: this one doesn't allow an undefined currentLocation, the other ones work
- locationObject as MatcherLocationAsPathAbsolute,
- currentLocation as unknown as NEW_LocationResolved<EXPERIMENTAL_RouteRecordNormalized>
+ // incompatible types
+ rawLocation as any,
+ // incompatible `matched` requires casting
+ currentLocation as any
)
const href = routerHistory.createHref(matchedRoute.fullPath)
expectTypeOf(matcher.resolve({ path: '/foo' })).toEqualTypeOf<
NEW_LocationResolved<TMatcherRecord>
>()
+ expectTypeOf(matcher.resolve('/foo')).toEqualTypeOf<
+ NEW_LocationResolved<TMatcherRecord>
+ >()
})
it('fails on non absolute location without a currentLocation', () => {
// @ts-expect-error: needs currentLocation
matcher.resolve('foo')
+ // @ts-expect-error: needs currentLocation
+ matcher.resolve({ path: 'foo' })
})
it('resolves relative locations', () => {
{} as NEW_LocationResolved<TMatcherRecord>
)
).toEqualTypeOf<NEW_LocationResolved<TMatcherRecord>>()
+ expectTypeOf(
+ matcher.resolve('foo', {} as NEW_LocationResolved<TMatcherRecord>)
+ ).toEqualTypeOf<NEW_LocationResolved<TMatcherRecord>>()
})
it('resolved named locations', () => {
it('fails on object relative location without a currentLocation', () => {
// @ts-expect-error: needs currentLocation
- matcher.resolve({ params: { id: 1 } })
+ matcher.resolve({ params: { id: '1' } })
+ // @ts-expect-error: needs currentLocation
+ matcher.resolve({ query: { id: '1' } })
})
it('resolves object relative locations with a currentLocation', () => {
it('does not allow a name + path', () => {
matcher.resolve({
- // ...({} as NEW_LocationResolved),
+ // ...({} as NEW_LocationResolved<TMatcherRecord>),
name: 'foo',
params: {},
// @ts-expect-error: name + path
path: '/e',
})
- // @ts-expect-error: name + currentLocation
- matcher.resolve({ name: 'a', params: {} }, {} as NEW_LocationResolved)
+ matcher.resolve(
+ // @ts-expect-error: name + currentLocation
+ { name: 'a', params: {} },
+ //
+ {} as NEW_LocationResolved<TMatcherRecord>
+ )
})
})
-import { type LocationQuery, normalizeQuery, stringifyQuery } from '../query'
+import {
+ type LocationQuery,
+ normalizeQuery,
+ parseQuery,
+ stringifyQuery,
+} from '../query'
import type {
MatcherPatternHash,
MatcherPatternPath,
} from './matcher-pattern'
import { warn } from '../warning'
import { encodeQueryValue as _encodeQueryValue, encodeParam } from '../encoding'
-import { NEW_stringifyURL, resolveRelativePath } from '../location'
+import {
+ LocationNormalized,
+ NEW_stringifyURL,
+ parseURL,
+ resolveRelativePath,
+} from '../location'
import type {
MatcherLocationAsNamed,
MatcherLocationAsPathAbsolute,
/**
* Resolves an absolute location (like `/path/to/somewhere`).
*/
- // resolve(
- // absoluteLocation: `/${string}`,
- // currentLocation?: undefined | NEW_LocationResolved<TMatcherRecord>
- // ): NEW_LocationResolved<TMatcherRecord>
+ resolve(
+ absoluteLocation: `/${string}`,
+ currentLocation?: undefined
+ ): NEW_LocationResolved<TMatcherRecord>
/**
* Resolves a string location relative to another location. A relative location can be `./same-folder`,
* `../parent-folder`, `same-folder`, or even `?page=2`.
*/
- // resolve(
- // relativeLocation: string,
- // currentLocation: NEW_LocationResolved<TMatcherRecord>
- // ): NEW_LocationResolved<TMatcherRecord>
+ resolve(
+ relativeLocation: string,
+ currentLocation: NEW_LocationResolved<TMatcherRecord>
+ ): NEW_LocationResolved<TMatcherRecord>
/**
* Resolves a location by its name. Any required params or query must be passed in the `options` argument.
location: MatcherLocationAsNamed,
// TODO: is this useful?
currentLocation?: undefined
+ // currentLocation?: undefined | NEW_LocationResolved<TMatcherRecord>
): NEW_LocationResolved<TMatcherRecord>
/**
location: MatcherLocationAsPathAbsolute,
// TODO: is this useful?
currentLocation?: undefined
- // currentLocation?: NEW_LocationResolved<TMatcherRecord>
+ // currentLocation?: NEW_LocationResolved<TMatcherRecord> | undefined
): NEW_LocationResolved<TMatcherRecord>
resolve(
*/
export type MatcherLocationRaw =
// | `/${string}`
- // | string
+ | string
| MatcherLocationAsNamed
| MatcherLocationAsPathAbsolute
| MatcherLocationAsPathRelative
// NOTE: because of the overloads, we need to manually type the arguments
type MatcherResolveArgs =
- // | [
- // absoluteLocation: `/${string}`,
- // currentLocation?: undefined | NEW_LocationResolved<TMatcherRecord>
- // ]
- // | [
- // relativeLocation: string,
- // currentLocation: NEW_LocationResolved<TMatcherRecord>
- // ]
+ | [absoluteLocation: `/${string}`, currentLocation?: undefined]
+ | [
+ relativeLocation: string,
+ currentLocation: NEW_LocationResolved<TMatcherRecord>
+ ]
| [
absoluteLocation: MatcherLocationAsPathAbsolute,
+ // Same as above
+ // currentLocation?: NEW_LocationResolved<TMatcherRecord> | undefined
currentLocation?: undefined
]
| [
relativeLocation: MatcherLocationAsPathRelative,
currentLocation: NEW_LocationResolved<TMatcherRecord>
]
- | [location: MatcherLocationAsNamed, currentLocation?: undefined]
+ | [
+ location: MatcherLocationAsNamed,
+ // Same as above
+ // currentLocation?: NEW_LocationResolved<TMatcherRecord> | undefined
+ currentLocation?: undefined
+ ]
| [
relativeLocation: MatcherLocationAsRelative,
currentLocation: NEW_LocationResolved<TMatcherRecord>
): NEW_LocationResolved<TMatcherRecord> {
const [to, currentLocation] = args
- if (to.name || to.path == null) {
+ if (typeof to === 'object' && (to.name || to.path == null)) {
// relative location or by name
if (__DEV__ && to.name == null && currentLocation == null) {
console.warn(
// string location, e.g. '/foo', '../bar', 'baz', '?page=1'
} else {
// parseURL handles relative paths
- // parseURL(to.path, currentLocation?.path)
- const query = normalizeQuery(to.query)
- const url = {
- fullPath: NEW_stringifyURL(stringifyQuery, to.path, query, to.hash),
- path: resolveRelativePath(to.path, currentLocation?.path || '/'),
- query,
- hash: to.hash || '',
+ let url: LocationNormalized
+ if (typeof to === 'string') {
+ url = parseURL(parseQuery, to, currentLocation?.path)
+ } else {
+ const query = normalizeQuery(to.query)
+ url = {
+ fullPath: NEW_stringifyURL(stringifyQuery, to.path, query, to.hash),
+ path: resolveRelativePath(to.path, currentLocation?.path || '/'),
+ query,
+ hash: to.hash || '',
+ }
}
let matcher: TMatcherRecord | undefined