-import { parseQuery } from '../src/history/common'
+import { parseQuery } from '../src/utils/query'
import { mockWarn } from './mockWarn'
describe('parseQuery', () => {
mockWarn()
+
+ it('works with leading ?', () => {
+ expect(parseQuery('?foo=a')).toEqual({
+ foo: 'a',
+ })
+ })
+
+ it('works without leading ?', () => {
+ expect(parseQuery('foo=a')).toEqual({
+ foo: 'a',
+ })
+ })
+
+ it('works with an empty string', () => {
+ const emptyQuery = parseQuery('')
+ expect(Object.keys(emptyQuery)).toHaveLength(0)
+ expect(emptyQuery).toEqual({})
+ expect(parseQuery('?')).toEqual({})
+ })
+
it('decodes values in query', () => {
expect(parseQuery('e=%25')).toEqual({
e: '%',
+++ /dev/null
-import { parseQuery } from '../src/history/common'
-
-describe('parseQuery', () => {
- it('works with leading ?', () => {
- expect(parseQuery('?foo=a')).toEqual({
- foo: 'a',
- })
- })
-
- it('works without leading ?', () => {
- expect(parseQuery('foo=a')).toEqual({
- foo: 'a',
- })
- })
-
- it('works with an empty string', () => {
- const emptyQuery = parseQuery('')
- expect(Object.keys(emptyQuery)).toHaveLength(0)
- expect(emptyQuery).toEqual({})
- expect(parseQuery('?')).toEqual({})
- })
-})
-import { stringifyQuery } from '../src/history/common'
+import { stringifyQuery } from '../src/utils/query'
import { mockWarn } from './mockWarn'
describe('stringifyQuery', () => {
import {
parseURL as originalParseURL,
stringifyURL as originalStringifyURL,
- parseQuery,
- stringifyQuery,
normalizeHistoryLocation as normalizeLocation,
} from '../src/history/common'
+import { parseQuery, stringifyQuery } from '../src/utils/query'
describe('parseURL', () => {
let parseURL = originalParseURL.bind(null, parseQuery)
import { ListenerRemover } from '../types'
-import { decode, encodeQueryProperty } from '../utils/encoding'
-// import { encodeQueryProperty, encodeHash } from '../utils/encoding'
-
-type HistoryQueryValue = string | null
-type RawHistoryQueryValue = HistoryQueryValue | number | undefined
-export type HistoryQuery = Record<
- string,
- HistoryQueryValue | HistoryQueryValue[]
->
-export type RawHistoryQuery = Record<
- string | number,
- RawHistoryQueryValue | RawHistoryQueryValue[]
->
+import { RawHistoryQuery, HistoryQuery } from '../utils/query'
interface HistoryLocation {
fullPath: string
return location.path + (query && '?') + query + (location.hash || '')
}
-/**
- * Transform a queryString into a query object. Accept both, a version with the leading `?` and without
- * Should work as URLSearchParams
- * @param search
- * @returns a query object
- */
-export function parseQuery(search: string): HistoryQuery {
- const query: HistoryQuery = {}
- // avoid creating an object with an empty key and empty value
- // because of split('&')
- if (search === '' || search === '?') return query
- const hasLeadingIM = search[0] === '?'
- const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&')
- for (let i = 0; i < searchParams.length; ++i) {
- let [key, rawValue] = searchParams[i].split('=') as [
- string,
- string | undefined
- ]
- key = decode(key)
- // avoid decoding null
- let value = rawValue == null ? null : decode(rawValue)
- if (key in query) {
- // an extra variable for ts types
- let currentValue = query[key]
- if (!Array.isArray(currentValue)) {
- currentValue = query[key] = [currentValue]
- }
- currentValue.push(value)
- } else {
- query[key] = value
- }
- }
- return query
-}
-/**
- * Stringify an object query. Works like URLSearchParams. Doesn't prepend a `?`
- * @param query
- */
-export function stringifyQuery(query: RawHistoryQuery): string {
- let search = ''
- for (let key in query) {
- if (search.length) search += '&'
- const value = query[key]
- key = encodeQueryProperty(key)
- if (value == null) {
- // only null adds the value
- if (value !== undefined) search += key
- continue
- }
- // keep null values
- let values: RawHistoryQueryValue[] = Array.isArray(value)
- ? value.map(v => v && encodeQueryProperty(v))
- : [value && encodeQueryProperty(value)]
-
- for (let i = 0; i < values.length; i++) {
- // only append & with i > 0
- search += (i ? '&' : '') + key
- if (values[i] != null) search += ('=' + values[i]) as string
- }
- }
-
- return search
-}
-
-/**
- * Transforms a RawQuery intoe a NormalizedQuery by casting numbers into
- * strings, removing keys with an undefined value and replacing undefined with
- * null in arrays
- * @param query
- */
-export function normalizeQuery(query: RawHistoryQuery): HistoryQuery {
- const normalizedQuery: HistoryQuery = {}
-
- for (let key in query) {
- let value = query[key]
- if (value !== undefined) {
- normalizedQuery[key] = Array.isArray(value)
- ? value.map(v => (v == null ? null : '' + v))
- : value == null
- ? value
- : '' + value
- }
- }
-
- return normalizedQuery
-}
-
/**
* Strips off the base from the beginning of a location.pathname
* @param pathname location.pathname
Immutable,
RouteParams,
} from './types'
-import {
- RouterHistory,
- parseQuery,
- parseURL,
- stringifyQuery,
- stringifyURL,
- normalizeQuery,
-} from './history/common'
+import { RouterHistory, parseURL, stringifyURL } from './history/common'
import {
ScrollToPosition,
ScrollPosition,
import { extractComponentsGuards, guardToPromiseFn } from './utils'
import { useCallbacks } from './utils/callbacks'
import { encodeParam, decode } from './utils/encoding'
+import { normalizeQuery, parseQuery, stringifyQuery } from './utils/query'
import { ref, Ref, markNonReactive, nextTick, App } from 'vue'
import { RouteRecordMatched } from './matcher/types'
import Link from './components/Link'
-import { HistoryQuery, RawHistoryQuery } from '../history/common'
+import { HistoryQuery, RawHistoryQuery } from '../utils/query'
import { PathParserOptions } from '../matcher/path-parser-ranker'
import { markNonReactive } from 'vue'
import { RouteRecordMatched } from '../matcher/types'