-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
86 lines (72 loc) · 2.16 KB
/
index.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
const parseValue = (value: string): any => {
if (value.toUpperCase() === "TRUE") return true;
if (value.toUpperCase() === "FALSE") return false;
return isNaN(Number(value)) ? value : Number(value);
};
const dec = (list: any[], isArray = false): object => {
let obj: any = isArray ? [] : {};
let recs: any[] = list.filter((item) => {
if (item.keys.length > 1) return true;
obj[item.keys[0]] = parseValue(item.value);
});
let attrs: any = {};
recs
.map((item) => {
item.key = item.keys.shift();
attrs[item.key] = [];
return item;
})
.forEach((item) => attrs[item.key].push(item));
Object.keys(attrs).forEach((attr) => {
let nextKey = attrs[attr][0].keys[0];
obj[attr] = dec(attrs[attr], typeof nextKey === "number");
});
return obj;
};
const reducer = (obj: any, parentPrefix: null | string = null) => {
return function (prev: any[], key: string) {
const val = obj[key];
key = encodeURIComponent(key);
const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key;
if (val == null || typeof val === "function") {
prev.push(`${prefix}=`);
return prev;
}
if (typeof val === "boolean") {
prev.push(`${prefix}=${val.toString().toUpperCase()}`);
return prev;
}
if (["number", "string"].includes(typeof val)) {
prev.push(`${prefix}=${encodeURIComponent(val)}`);
return prev;
}
prev.push(Object.keys(val).reduce(reducer(val, prefix), []).join("&"));
return prev;
};
};
function decode(querystring: string): object {
if (querystring.length > 0 && querystring[0] === "?") {
querystring = querystring.slice(1);
}
return dec(
querystring
.split("&")
.map((item) => item.split("=").map((x) => decodeURIComponent(x)))
.map((item) => {
return {
keys: item[0]
.split(/[\[\]]/g)
.filter((n) => n)
.map((key) => (isNaN(Number(key)) ? key : Number(key))),
value: item[1],
};
})
);
}
function encode(object: object): string {
return Object.keys(object).reduce(reducer(object), []).join("&");
}
export default {
parseQuery: decode,
parseJSON: encode,
};