arnaucube
arnaucube/socketioMEANseedPublic Self-hosted repository
socketioMEANseed/www/node_modules/qs/lib/parse.js
www/node_modules/qs/lib/parse.jsRaw
  1// Load modules
  2
  3var Utils = require('./utils');
  4
  5
  6// Declare internals
  7
  8var internals = {
  9    delimiter: '&',
 10    depth: 5,
 11    arrayLimit: 20,
 12    parameterLimit: 1000
 13};
 14
 15
 16internals.parseValues = function (str, options) {
 17
 18    var obj = {};
 19    var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
 20
 21    for (var i = 0, il = parts.length; i < il; ++i) {
 22        var part = parts[i];
 23        var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
 24
 25        if (pos === -1) {
 26            obj[Utils.decode(part)] = '';
 27        }
 28        else {
 29            var key = Utils.decode(part.slice(0, pos));
 30            var val = Utils.decode(part.slice(pos + 1));
 31
 32            if (!obj.hasOwnProperty(key)) {
 33                obj[key] = val;
 34            }
 35            else {
 36                obj[key] = [].concat(obj[key]).concat(val);
 37            }
 38        }
 39    }
 40
 41    return obj;
 42};
 43
 44
 45internals.parseObject = function (chain, val, options) {
 46
 47    if (!chain.length) {
 48        return val;
 49    }
 50
 51    var root = chain.shift();
 52
 53    var obj = {};
 54    if (root === '[]') {
 55        obj = [];
 56        obj = obj.concat(internals.parseObject(chain, val, options));
 57    }
 58    else {
 59        var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
 60        var index = parseInt(cleanRoot, 10);
 61        var indexString = '' + index;
 62        if (!isNaN(index) &&
 63            root !== cleanRoot &&
 64            indexString === cleanRoot &&
 65            index >= 0 &&
 66            index <= options.arrayLimit) {
 67
 68            obj = [];
 69            obj[index] = internals.parseObject(chain, val, options);
 70        }
 71        else {
 72            obj[cleanRoot] = internals.parseObject(chain, val, options);
 73        }
 74    }
 75
 76    return obj;
 77};
 78
 79
 80internals.parseKeys = function (key, val, options) {
 81
 82    if (!key) {
 83        return;
 84    }
 85
 86    // The regex chunks
 87
 88    var parent = /^([^\[\]]*)/;
 89    var child = /(\[[^\[\]]*\])/g;
 90
 91    // Get the parent
 92
 93    var segment = parent.exec(key);
 94
 95    // Don't allow them to overwrite object prototype properties
 96
 97    if (Object.prototype.hasOwnProperty(segment[1])) {
 98        return;
 99    }
100
101    // Stash the parent if it exists
102
103    var keys = [];
104    if (segment[1]) {
105        keys.push(segment[1]);
106    }
107
108    // Loop through children appending to the array until we hit depth
109
110    var i = 0;
111    while ((segment = child.exec(key)) !== null && i < options.depth) {
112
113        ++i;
114        if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
115            keys.push(segment[1]);
116        }
117    }
118
119    // If there's a remainder, just add whatever is left
120
121    if (segment) {
122        keys.push('[' + key.slice(segment.index) + ']');
123    }
124
125    return internals.parseObject(keys, val, options);
126};
127
128
129module.exports = function (str, options) {
130
131    if (str === '' ||
132        str === null ||
133        typeof str === 'undefined') {
134
135        return {};
136    }
137
138    options = options || {};
139    options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
140    options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
141    options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
142    options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
143
144    var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
145    var obj = {};
146
147    // Iterate over the keys and setup the new object
148
149    var keys = Object.keys(tempObj);
150    for (var i = 0, il = keys.length; i < il; ++i) {
151        var key = keys[i];
152        var newObj = internals.parseKeys(key, tempObj[key], options);
153        obj = Utils.merge(obj, newObj);
154    }
155
156    return Utils.compact(obj);
157};