diff --git a/lib/querystring.js b/lib/querystring.js index 36be1b0..5e17a65 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -35,15 +35,7 @@ function parse(parts, parent, key, val) { var part = parts.shift(); // end if (!part) { - if (Array.isArray(parent[key])) { - parent[key].push(val); - } else if ('object' == typeof parent[key]) { - parent[key] = val; - } else if ('undefined' == typeof parent[key]) { - parent[key] = val; - } else { - parent[key] = [parent[key], val]; - } + set(parent, key, val); // array } else { var obj = parent[key] = parent[key] || []; @@ -95,8 +87,8 @@ function merge(parent, key, val){ * Parse the given obj. */ -function parseObject(obj){ - var ret = { base: {} }; +function parseObject(obj, base){ + var ret = { base: base || {} }; Object.keys(obj).forEach(function(name){ merge(ret, name, obj[name]); }); @@ -232,10 +224,13 @@ function stringifyObject(obj, prefix) { function set(obj, key, val) { var v = obj[key]; - if (undefined === v) { + if ('undefined' == typeof v) { obj[key] = val; } else if (Array.isArray(v)) { - v.push(val); + obj[key] = v.concat(val); + } else if (('object' == typeof v) && ('[object Object]' == toString.call(val))) { + // partially parsed object + parseObject(val, v); } else { obj[key] = [v, val]; } diff --git a/test/parse.js b/test/parse.js index 2a28cf3..1469d65 100644 --- a/test/parse.js +++ b/test/parse.js @@ -139,6 +139,29 @@ module.exports = { 'test malformed uri': function(){ qs.parse('{%:%}').should.eql({ '{%:%}': '' }); qs.parse('foo=%:%}').should.eql({ 'foo': '%:%}' }); + }, + + 'test partially parsed objects': function(){ + qs.parse({ 'foo[0]': 'bar', 'foo[1]': 'baz' }) + .should.eql({ foo: ['bar', 'baz'] }); + + qs.parse({ 'foo[items]': [], foo: { items: ['bar'] } }) + .should.eql({ foo: { items: ['bar'] } }) + + qs.parse({ foo: { items: ['bar'] }, 'foo[items]': [] }) + .should.eql({ foo: { items: ['bar'] } }) + + qs.parse({ 'foo[base64]': 'RAWR', 'foo[64base]': 'RAWR' }) + .should.eql({ foo: { base64: 'RAWR', '64base': 'RAWR' } }); + + qs.parse({ 'user[name][first]': ['tj', 'TJ'] }) + .should.eql({ user: { name: { first: ['tj', 'TJ'] } } }); + + qs.parse({ 'user[name]': { first: 'tj' }, 'user': { name: { last: 'holowaychuk' } } }) + .should.eql({ user: { name: { first: 'tj', last: 'holowaychuk' } } }); + + qs.parse({ 'user': { name: { last: 'holowaychuk' } }, 'user[name]': { first: 'tj' } }) + .should.eql({ user: { name: { last: 'holowaychuk', first: 'tj' } } }); } // 'test complex': function(){