Skip to content

Commit

Permalink
feat: 新增 parseURIQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Jul 3, 2019
1 parent 4e75293 commit 6eca769
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/URI.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import qs from 'qs'
import { createURIQuery } from './URI'
import { createURIQuery, parseURIQuery } from './URI'
import { jestExpectEqual } from './enhanceJest'

test('createURIQuery', () => {
Expand All @@ -15,3 +15,38 @@ test('createURIQuery', () => {
parameters,
)
})

test('parseURIQuery', () => {
const parameters = {
'x': '1//$%6',
'2': 'xxx',
'0': '0 = & ?😁',
'😁🥳': 'hello',
'age': 20,
}
const query = qs.stringify(parameters)

jestExpectEqual(
qs.parse(query),
parseURIQuery(query),
)

jestExpectEqual(
qs.parse(query),
parseURIQuery(`?${query}`),
)

jestExpectEqual(
{
...qs.parse(query),
age: 20,
},
parseURIQuery<typeof parameters>(
query,
ps => ({
...ps,
age: Number(ps.age),
}),
),
)
})
38 changes: 38 additions & 0 deletions src/URI.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AnyObject } from './enhanceType'
import { forOwn } from './forOwn'
import { isFunction } from './is'

/**
* 创建 URI 查询字符串。
Expand All @@ -20,3 +21,40 @@ export function createURIQuery(parameters: AnyObject) {
})
return parts.join('&')
}

export interface ParseURIQueryFormat<T extends Record<string, any>> {
(parameters: Record<keyof T, string>): T,
}

/**
* 解析 URI 查询字符串。
*
* 兼容以 `?` 开头的查询字符串,因此你可以直接传入 `location.search` 的值。
*
* @param query 查询字符串
* @param format 格式化查询参数
* @returns 返回 URI 查询参数
* @example
* ```ts
* parseURIQuery('x=1&y=z') // => { x: '1', y: 'z' }
* parseURIQuery('?x=1&y=z') // => { x: '1', y: 'z' }
* parseURIQuery(
* 'x=1&y=z',
* parameters => ({
* ...parameters,
* x: Number(parameters.x),
* }),
* ) // => { x: 1, y: 'z' }
* ```
*/
export function parseURIQuery<T extends Record<string, any> = Record<string, any>>(query: string, format?: ParseURIQueryFormat<T>): T {
const parameters: T = {} as any
query = query.charAt(0) === '?' ? query.substring(1) : query
query.split('&').forEach(pair => {
const [key, value] = pair.split('=')
const decodedKey = decodeURIComponent(key)
const decodedValue = decodeURIComponent(value)
;(parameters as any)[decodedKey] = decodedValue
})
return isFunction(format) ? format(parameters) : parameters
}

0 comments on commit 6eca769

Please sign in to comment.