Skip to content

Commit

Permalink
fix: provide URL encoded paths in RouteLocation (#76)
Browse files Browse the repository at this point in the history
* fix: provide URL encoded paths in RouteLocation

* fix: handle Vue2 routing

Co-authored-by: Bobbie Goede <bobbiegoede@gmail.com>

* refactor: proper typing

* refactor: removed obsolete/wrong imports & docs

---------

Co-authored-by: Bobbie Goede <bobbiegoede@gmail.com>
  • Loading branch information
Achneoder and BobbieGoede authored Oct 23, 2023
1 parent 244902a commit 13e647f
Show file tree
Hide file tree
Showing 4 changed files with 353 additions and 5 deletions.
25 changes: 25 additions & 0 deletions packages/vue-i18n-routing/src/__test__/compatibles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@ describe('switchLocalePath', () => {
},
component: { template: '<div>Category</div>' }
},
{
path: '/count/:id',
name: 'count',
component: { template: '<div>Category</div>' }
},
{
path: '/:pathMatch(.*)*',
name: 'not-found',
Expand Down Expand Up @@ -428,11 +433,31 @@ describe('switchLocalePath', () => {
assert.equal(vm.switchLocalePath('fr'), '/fr/about?foo=1&test=2')
assert.equal(vm.switchLocalePath('en'), '/en/about?foo=1&test=2')

await router.push('/ja/about?foo=bär&four=四&foo=bar')
assert.equal(vm.switchLocalePath('ja'), '/ja/about?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B')
assert.equal(vm.switchLocalePath('fr'), '/fr/about?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B')
assert.equal(vm.switchLocalePath('en'), '/en/about?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B')

await router.push('/ja/about?foo=bär&four=四')
assert.equal(vm.switchLocalePath('ja'), '/ja/about?foo=b%C3%A4r&four=%E5%9B%9B')
assert.equal(vm.switchLocalePath('fr'), '/fr/about?foo=b%C3%A4r&four=%E5%9B%9B')
assert.equal(vm.switchLocalePath('en'), '/en/about?foo=b%C3%A4r&four=%E5%9B%9B')

await router.push('/ja/category/1')
assert.equal(vm.switchLocalePath('ja'), '/ja/category/japanese')
assert.equal(vm.switchLocalePath('en'), '/en/category/english')
assert.equal(vm.switchLocalePath('fr'), '/fr/category/franch')

await router.push('/ja/count/三')
assert.equal(vm.switchLocalePath('ja'), '/ja/count/%E4%B8%89')
assert.equal(vm.switchLocalePath('en'), '/en/count/%E4%B8%89')
assert.equal(vm.switchLocalePath('fr'), '/fr/count/%E4%B8%89')

await router.push('/ja/count/三?foo=bär&four=四&foo=bar')
assert.equal(vm.switchLocalePath('ja'), '/ja/count/%E4%B8%89?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B')
assert.equal(vm.switchLocalePath('fr'), '/fr/count/%E4%B8%89?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B')
assert.equal(vm.switchLocalePath('en'), '/en/count/%E4%B8%89?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B')

await router.push('/ja/foo')
assert.equal(vm.switchLocalePath('ja'), '/ja/not-found-japanese')
assert.equal(vm.switchLocalePath('en'), '/en/not-found-english')
Expand Down
288 changes: 287 additions & 1 deletion packages/vue-i18n-routing/src/__test__/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { describe, it, assert, test } from 'vitest'

import { resolvedRouteToObject } from '../compatibles/utils'
import { adjustRoutePathForTrailingSlash, getLocaleRouteName, findBrowserLocale } from '../utils'

import type { BrowserLocale } from '../utils'

describe('adjustRouteDefinitionForTrailingSlash', function () {
describe('pagePath: /foo/bar', function () {
describe('trailingSlash: faawklse, isChildWithRelativePath: true', function () {
describe('trailingSlash: false, isChildWithRelativePath: true', function () {
it('should be trailed with slash: /foo/bar/', function () {
assert.equal(adjustRoutePathForTrailingSlash('/foo/bar', true, true), '/foo/bar/')
})
Expand Down Expand Up @@ -220,3 +221,288 @@ describe('findBrowserLocale', () => {
assert.ok(locale === 'ja')
})
})

describe('resolvedRouteToObject', () => {
it('should map resolved route without special characters', () => {
const expected = {
fullPath: '/ja/about',
hash: '',
query: {},
name: 'about___ja',
path: '/ja/about',
params: {},
matched: [
{
path: '/ja/about',
redirect: undefined,
name: 'about___ja',
meta: {},
aliasOf: undefined,
beforeEnter: undefined,
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {},
updateGuards: {},
enterCallbacks: {},
components: {
default: {
template: '<div>About</div>'
}
}
}
],
meta: {},
redirectedFrom: undefined,
href: '/ja/about'
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
assert.deepEqual(resolvedRouteToObject(expected as any), expected as any)
})

it('should map resolved route without special characters and query', () => {
const expected = {
fullPath: '/ja/about?foo=1&test=2',
hash: '',
query: {
foo: '1',
test: '2'
},
name: 'about___ja',
path: '/ja/about',
params: {},
matched: [
{
path: '/ja/about',
redirect: undefined,
name: 'about___ja',
meta: {},
aliasOf: undefined,
beforeEnter: undefined,
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {},
updateGuards: {},
enterCallbacks: {},
components: {
default: {
template: '<div>About</div>'
}
}
}
],
meta: {},
redirectedFrom: undefined,
href: '/ja/about?foo=1&test=2'
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
assert.deepEqual(resolvedRouteToObject(expected as any), expected as any)
})

it('should map resolved route without special characters and query with special characters', () => {
const expected = {
fullPath: '/ja/about?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B',
hash: '',
query: {
foo: ['bär', 'bar'],
four: '四'
},
name: 'about___ja',
path: '/ja/about',
params: {},
matched: [
{
path: '/ja/about',
redirect: undefined,
name: 'about___ja',
meta: {},
aliasOf: undefined,
beforeEnter: undefined,
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {},
updateGuards: {},
enterCallbacks: {},
components: {
default: {
template: '<div>About</div>'
}
}
}
],
meta: {},
redirectedFrom: undefined,
href: '/ja/about?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B'
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
assert.deepEqual(resolvedRouteToObject(expected as any), expected as any)
})

it('should map resolved route with special characters and query with special characters', () => {
const provided = {
fullPath: '/ja/count/三?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B',
hash: '',
query: {
foo: ['bär', 'bar'],
four: '四'
},
name: 'count___ja',
path: '/ja/count/三',
params: {
id: '三'
},
matched: [
{
path: '/ja/count/:id',
redirect: undefined,
name: 'count___ja',
meta: {},
aliasOf: undefined,
beforeEnter: undefined,
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {},
updateGuards: {},
enterCallbacks: {},
components: {
default: {
template: '<div>Category</div>'
}
}
}
],
meta: {},
redirectedFrom: undefined,
href: '/ja/count/%E5%9B%9B?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B'
}
const expected = {
fullPath: '/ja/count/%E4%B8%89?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B',
hash: '',
query: {
foo: ['bär', 'bar'],
four: '四'
},
name: 'count___ja',
path: '/ja/count/%E4%B8%89',
params: {
id: '三'
},
matched: [
{
path: '/ja/count/:id',
redirect: undefined,
name: 'count___ja',
meta: {},
aliasOf: undefined,
beforeEnter: undefined,
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {},
updateGuards: {},
enterCallbacks: {},
components: {
default: {
template: '<div>Category</div>'
}
}
}
],
meta: {},
redirectedFrom: undefined,
href: '/ja/count/%E4%B8%89?foo=b%C3%A4r&foo=bar&four=%E5%9B%9B'
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
assert.deepEqual(resolvedRouteToObject(provided as any), expected as any)
})

it('should map resolved route with special characters', () => {
const provided = {
fullPath: '/ja/count/三',
hash: '',
query: {},
name: 'count___ja',
path: '/ja/count/三',
params: {
id: '三'
},
matched: [
{
path: '/ja/count/:id',
redirect: undefined,
name: 'count___ja',
meta: {},
aliasOf: undefined,
beforeEnter: undefined,
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {},
updateGuards: {},
enterCallbacks: {},
components: {
default: {
template: '<div>Category</div>'
}
}
}
],
meta: {},
redirectedFrom: undefined,
href: '/ja/count/三'
}
const expected = {
fullPath: '/ja/count/%E4%B8%89',
hash: '',
query: {},
name: 'count___ja',
path: '/ja/count/%E4%B8%89',
params: {
id: '三'
},
matched: [
{
path: '/ja/count/:id',
redirect: undefined,
name: 'count___ja',
meta: {},
aliasOf: undefined,
beforeEnter: undefined,
props: {
default: false
},
children: [],
instances: {},
leaveGuards: {},
updateGuards: {},
enterCallbacks: {},
components: {
default: {
template: '<div>Category</div>'
}
}
}
],
meta: {},
redirectedFrom: undefined,
href: '/ja/count/%E4%B8%89'
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
assert.deepEqual(resolvedRouteToObject(provided as any), expected as any)
})
})
8 changes: 4 additions & 4 deletions packages/vue-i18n-routing/src/compatibles/routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { isVue3, isRef, unref, isVue2 } from 'vue-demi'
import { DEFAULT_DYNAMIC_PARAMS_KEY } from '../constants'
import { getLocale, getLocaleRouteName, getRouteName } from '../utils'

import { getI18nRoutingOptions, resolve, routeToObject } from './utils'
import { getI18nRoutingOptions, isV4Route, resolve, resolvedRouteToObject, routeToObject } from './utils'

import type { RoutingProxy, PrefixableOptions, SwitchLocalePathIntercepter } from './types'
import type { Strategies, I18nRoutingOptions } from '../types'
Expand Down Expand Up @@ -231,9 +231,9 @@ export function resolveRoute(this: RoutingProxy, route: any, locale?: Locale): a
}

try {
const resolvedRoute = router.resolve(localizedRoute) as any
const resolvedRoute = resolvedRouteToObject(router.resolve(localizedRoute))
// prettier-ignore
if (isVue3
if (isV4Route(resolvedRoute)
? resolvedRoute.name // for vue-router v4
: resolvedRoute.route.name // for vue-router v3
) {
Expand Down Expand Up @@ -321,7 +321,7 @@ export function switchLocalePath(this: RoutingProxy, locale: Locale): string {
const baseRoute = assign({}, routeCopy, _baseRoute)
let path = localePath.call(this, baseRoute, locale)

// custome locale path with intercepter
// custom locale path with interceptor
path = switchLocalePathIntercepter(path, locale)

return path
Expand Down
Loading

0 comments on commit 13e647f

Please sign in to comment.