UNPKG

3.03 kBJavaScriptView Raw
1var util = require('./util/util');
2var isArray = util.isArray;
3
4/**
5 * Decode the URI Component encoded query string to object
6 *
7 * @param {string} The URI Component encoded query string
8 * @returns {Object.<string, string>} Returns the decoded object
9 */
10function decode(string) {
11 var object = {};
12 var cache = {};
13 var keyValueArray;
14 var index;
15 var length;
16 var keyValue;
17 var key;
18 var value;
19
20 // do not decode empty string or something that is not string
21 if (string && typeof string === 'string') {
22 keyValueArray = string.split('&');
23 index = 0;
24 length = keyValueArray.length;
25
26 while (index < length) {
27 keyValue = keyValueArray[index].split('=');
28 key = decodeURIComponent(keyValue[0]);
29 value = keyValue[1];
30
31 if (typeof value === 'string') {
32 value = decodeURIComponent(value);
33 } else {
34 value = null;
35 }
36
37 decodeKey(object, cache, key, value);
38
39 index += 1;
40 }
41 }
42
43 return object;
44}
45
46/**
47 * Decode the specefied key
48 *
49 * @param {Object.<string, string>} object The object to hold the decoded data
50 * @param {Object.<string, *>} cache The object to hold cache data
51 * @param {string} key The key name to decode
52 * @param {any} value The value to decode
53 */
54function decodeKey(object, cache, key, value) {
55 var rBracket = /\[([^\[]*?)?\]$/;
56 var rIndex = /(^0$)|(^[1-9]\d*$)/;
57 var indexOrKeyOrEmpty;
58 var parentKey;
59 var arrayOrObject;
60 var keyIsIndex;
61 var keyIsEmpty;
62 var valueIsInArray;
63 var dataArray;
64 var length;
65
66 // check whether key is something like `person[name]` or `colors[]` or
67 // `colors[1]`
68 if ( rBracket.test(key) ) {
69 indexOrKeyOrEmpty = RegExp.$1;
70 parentKey = key.replace(rBracket, '');
71 arrayOrObject = cache[parentKey];
72
73 keyIsIndex = rIndex.test(indexOrKeyOrEmpty);
74 keyIsEmpty = indexOrKeyOrEmpty === '';
75 valueIsInArray = keyIsIndex || keyIsEmpty;
76
77 if (arrayOrObject) {
78 // convert the array to object
79 if ( (! valueIsInArray) && isArray(arrayOrObject) ) {
80 dataArray = arrayOrObject;
81 length = dataArray.length;
82 arrayOrObject = {};
83
84 while (length--) {
85 if (arrayOrObject[length] !== undefined) {
86 arrayOrObject[length] = dataArray[length];
87 }
88 }
89 }
90 } else {
91 arrayOrObject = valueIsInArray ? [] : {};
92 }
93
94 if ( keyIsEmpty && isArray(arrayOrObject) ) {
95 arrayOrObject.push(value);
96 } else {
97 // arrayOrObject is array or object here
98 arrayOrObject[indexOrKeyOrEmpty] = value;
99 }
100
101 cache[parentKey] = arrayOrObject;
102
103 decodeKey(object, cache, parentKey, arrayOrObject);
104 } else {
105 object[key] = value;
106 }
107}
108
109module.exports = decode;