/
query.ts
54 lines (48 loc) 路 1.43 KB
/
query.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import {
decode,
decodeQueryValue,
encodeQueryKey,
encodeQueryValue
} from './encoding'
export type QueryValue = string | string[] | undefined | null
export type QueryObject = Record<string, QueryValue>
export function parseQuery (paramsStr: string = ''): QueryObject {
const obj: QueryObject = {}
if (paramsStr[0] === '?') {
paramsStr = paramsStr.substr(1)
}
for (const param of paramsStr.split('&')) {
const s = (param.match(/([^=]+)=?(.*)/) || [])
if (s.length < 2) { continue }
const key = decode(s[1])
if (key === '__proto__' || key === 'constructor') {
continue
}
const value = decodeQueryValue(s[2] || '')
if (obj[key]) {
if (Array.isArray(obj[key])) {
(obj[key] as string[]).push(value)
} else {
obj[key] = [obj[key] as string, value]
}
} else {
obj[key] = value
}
}
return obj
}
export function encodeQueryItem (key: string, val: QueryValue): string {
if (typeof val === 'number' || typeof val === 'boolean') {
val = String(val)
}
if (!val) {
return encodeQueryKey(key)
}
if (Array.isArray(val)) {
return val.map(_val => `${encodeQueryKey(key)}=${encodeQueryValue(_val)}`).join('&')
}
return `${encodeQueryKey(key)}=${encodeQueryValue(val)}`
}
export function stringifyQuery (query: QueryObject) {
return Object.keys(query).filter(k => query[k] !== undefined).map(k => encodeQueryItem(k, query[k])).join('&')
}