forked from utily/cloudly-http
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSearch.ts
More file actions
38 lines (38 loc) · 1.64 KB
/
Search.ts
File metadata and controls
38 lines (38 loc) · 1.64 KB
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
export function stringify(data: { [key: string]: any }): string {
const result: string[] = []
const map = (key: string, value: any) => {
switch (typeof value) {
default:
case "bigint":
case "boolean":
case "number":
case "string":
result.push(`${key}=${encodeURIComponent(value.toString())}`)
break
case "undefined":
break
case "object":
for (const property in value)
if (Object.prototype.hasOwnProperty.call(value, property))
map(key ? key + `[${property}]` : property, value[property])
break
}
}
map("", data)
return result.join("&")
}
export function parse(data: string): { [key: string]: any } {
const convertArrays =( target: Record<string, any> ): Record<string, any> | any[] => {
return (typeof target == "object" && Object.keys(target).sort().every((k, i) => `${k}` == `${i}`))
? (Object.entries(target).sort().map(entry => typeof entry[1] == "object" ? convertArrays(entry[1]) : entry[1]) )
: (typeof target == "object" ? Object.fromEntries(Object.entries(target).map(entry => [entry[0], convertArrays(entry[1])])) : target)
}
const insert = (target: { [key: string]: any }, key: string[], value: string): any => {
target[key[0]] = key.length > 1 ? insert(target[key[0]] ?? {}, key.slice(1), value) : value
return target
}
const entries = data.split("&")
.map<[string, string]>(d => d.split("=", 2) as [string, string])
.map<[string[], string]>(([k, v]) => [decodeURIComponent(k).split("[").map(p => p.replace("]", "")), decodeURIComponent(v.replace(/\+/g, " "))])
return entries.reduce<{ [key: string]: any }>((result, [key, value]) => convertArrays(insert(result, key, value)), {})
}