-
Notifications
You must be signed in to change notification settings - Fork 42
/
query.ts
69 lines (63 loc) · 1.65 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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import {
decode,
decodeQueryValue,
encodeQueryKey,
encodeQueryValue,
} from "./encoding";
export type QueryValue =
| string
| number
| undefined
| null
| Record<string, any>;
export type QueryObject = Record<string, QueryValue | QueryValue[]>;
export function parseQuery(parametersString = ""): QueryObject {
const object: QueryObject = {};
if (parametersString[0] === "?") {
parametersString = parametersString.slice(1);
}
for (const parameter of parametersString.split("&")) {
const s = parameter.match(/([^=]+)=?(.*)/) || [];
if (s.length < 2) {
continue;
}
const key = decode(s[1]);
if (key === "__proto__" || key === "constructor") {
continue;
}
const value = decodeQueryValue(s[2] || "");
if (typeof object[key] !== "undefined") {
if (Array.isArray(object[key])) {
(object[key] as string[]).push(value);
} else {
object[key] = [object[key] as string, value];
}
} else {
object[key] = value;
}
}
return object;
}
export function encodeQueryItem(
key: string,
value: QueryValue | QueryValue[]
): string {
if (typeof value === "number" || typeof value === "boolean") {
value = String(value);
}
if (!value) {
return encodeQueryKey(key);
}
if (Array.isArray(value)) {
return value
.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`)
.join("&");
}
return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
}
export function stringifyQuery(query: QueryObject) {
return Object.keys(query)
.filter((k) => query[k] !== undefined)
.map((k) => encodeQueryItem(k, query[k]))
.join("&");
}