Skip to content

Commit

Permalink
fix(encoding): encode partial params
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Aug 6, 2020
1 parent faf0aab commit eb04117
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
13 changes: 8 additions & 5 deletions __tests__/urlEncoding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const routes: RouteRecordRaw[] = [
{ path: '/to-p/:p', redirect: to => `/p/${to.params.p}` },
{ path: '/p/:p', component: components.Bar, name: 'params' },
{ path: '/p/:p+', component: components.Bar, name: 'repeat' },
{ path: '/optional/:a/:b?', component: components.Bar, name: 'optional' },
]

function createRouter() {
Expand Down Expand Up @@ -42,7 +43,8 @@ describe('URL Encoding', () => {
const router = createRouter()
await router.push('/p/bar')
await router.push({ params: { p: 'foo' } })
expect(encoding.encodeParam).toHaveBeenCalledTimes(1)
expect(encoding.encodeParam).toHaveBeenCalledTimes(2)
expect(encoding.encodeParam).toHaveBeenCalledWith('bar')
expect(encoding.encodeParam).toHaveBeenCalledWith('foo')
})

Expand Down Expand Up @@ -75,16 +77,17 @@ describe('URL Encoding', () => {
expect(encoding.decode).toHaveBeenNthCalledWith(2, 'bar', 1, ['foo', 'bar'])
})

it('keeps decoded values in params', async () => {
it('decodes values in params', async () => {
// @ts-ignore: override to make the difference
encoding.decode = () => 'd'
// @ts-ignore
encoding.encodeParam = () => 'e'
const router = createRouter()
await router.push({ name: 'params', params: { p: '%' } })
await router.push({ name: 'optional', params: { a: 'a%' } })
await router.push({ params: { b: 'b%' } })
expect(router.currentRoute.value).toMatchObject({
fullPath: '/p/e',
params: { p: '%' },
fullPath: '/optional/e/e',
params: { b: 'd', a: 'd' },
})
})

Expand Down
17 changes: 10 additions & 7 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,11 @@ export function createRouter(options: RouterOptions): Router {

function resolve(
rawLocation: Readonly<RouteLocationRaw>,
currentLocation?: Readonly<RouteLocationNormalizedLoaded>
currentLocation?: RouteLocationNormalizedLoaded
): RouteLocation & { href: string } {
// const objectLocation = routerLocationAsObject(rawLocation)
currentLocation = currentLocation || currentRoute.value
// we create a copy to modify it later
currentLocation = { ...(currentLocation || currentRoute.value) }
if (typeof rawLocation === 'string') {
let locationNormalized = parseURL(
parseQuery,
Expand Down Expand Up @@ -293,9 +294,13 @@ export function createRouter(options: RouterOptions): Router {
path: parseURL(parseQuery, rawLocation.path, currentLocation.path).path,
})
} else {
// pass encoded values to the matcher so it can produce encoded path and fullPath
matcherLocation = assign({}, rawLocation, {
params: encodeParams(rawLocation.params),
})
// current location params are decoded, we need to encode them in case the
// matcher merges the params
currentLocation.params = encodeParams(currentLocation.params)
}

let matchedRoute = matcher.resolve(matcherLocation, currentLocation)
Expand All @@ -307,11 +312,9 @@ export function createRouter(options: RouterOptions): Router {
)
}

// put back the unencoded params as given by the user (avoid the cost of decoding them)
matchedRoute.params =
'params' in rawLocation
? normalizeParams(rawLocation.params)
: decodeParams(matchedRoute.params)
// decoding them) the matcher might have merged current location params so
// we need to run the decoding again
matchedRoute.params = normalizeParams(decodeParams(matchedRoute.params))

const fullPath = stringifyURL(
stringifyQuery,
Expand Down

0 comments on commit eb04117

Please sign in to comment.