Skip to content

Commit

Permalink
option strictNullHandling
Browse files Browse the repository at this point in the history
  • Loading branch information
pierot committed May 21, 2015
1 parent b60f281 commit d0b4c87
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 18 deletions.
11 changes: 9 additions & 2 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ var internals = {
delimiter: '&',
depth: 5,
arrayLimit: 20,
parameterLimit: 1000
parameterLimit: 1000,
strictNullHandling: false
};


Expand All @@ -23,7 +24,11 @@ internals.parseValues = function (str, options) {
var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;

if (pos === -1) {
obj[Utils.decode(part)] = null;
obj[Utils.decode(part)] = '';

if (options.strictNullHandling) {
obj[Utils.decode(part)] = null;
}
}
else {
var key = Utils.decode(part.slice(0, pos));
Expand Down Expand Up @@ -140,6 +145,8 @@ module.exports = function (str, options) {
options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;


var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
var obj = {};
Expand Down
19 changes: 12 additions & 7 deletions lib/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ var internals = {

return prefix;
}
}
},
strictNullHandling: false
};


internals.stringify = function (obj, prefix, generateArrayPrefix) {
internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling) {

if (Utils.isBuffer(obj)) {
obj = obj.toString();
Expand All @@ -33,9 +34,11 @@ internals.stringify = function (obj, prefix, generateArrayPrefix) {
obj = obj.toISOString();
}
else if (obj === null) {
// obj = '';
if (strictNullHandling) {
return encodeURIComponent(prefix);
}

return encodeURIComponent(prefix);
obj = '';
}

if (typeof obj === 'string' ||
Expand All @@ -54,11 +57,12 @@ internals.stringify = function (obj, prefix, generateArrayPrefix) {
var objKeys = Object.keys(obj);
for (var i = 0, il = objKeys.length; i < il; ++i) {
var key = objKeys[i];

if (Array.isArray(obj)) {
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix));
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling));
}
else {
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix));
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling));
}
}

Expand All @@ -70,6 +74,7 @@ module.exports = function (obj, options) {

options = options || {};
var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;

var keys = [];

Expand All @@ -95,7 +100,7 @@ module.exports = function (obj, options) {
var objKeys = Object.keys(obj);
for (var i = 0, il = objKeys.length; i < il; ++i) {
var key = objKeys[i];
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix));
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling));
}

return keys.join(delimiter);
Expand Down
14 changes: 8 additions & 6 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ describe('parse()', function () {
expect(Qs.parse('a[>=]=23')).to.deep.equal({ a: { '>=': '23' } });
expect(Qs.parse('a[<=>]==23')).to.deep.equal({ a: { '<=>': '=23' } });
expect(Qs.parse('a[==]=23')).to.deep.equal({ a: { '==': '23' } });
expect(Qs.parse('foo')).to.deep.equal({ foo: null });
expect(Qs.parse('foo', {strictNullHandling: true})).to.deep.equal({ foo: null });
expect(Qs.parse('foo' )).to.deep.equal({ foo: '' });
expect(Qs.parse('foo=')).to.deep.equal({ foo: '' });
expect(Qs.parse('foo=bar')).to.deep.equal({ foo: 'bar' });
expect(Qs.parse(' foo = bar = baz ')).to.deep.equal({ ' foo ': ' bar = baz ' });
expect(Qs.parse('foo=bar=baz')).to.deep.equal({ foo: 'bar=baz' });
expect(Qs.parse('foo=bar&bar=baz')).to.deep.equal({ foo: 'bar', bar: 'baz' });
expect(Qs.parse('foo2=bar2&baz2=')).to.deep.equal({ foo2: 'bar2', baz2: '' });
expect(Qs.parse('foo=bar&baz')).to.deep.equal({ foo: 'bar', baz: null });
expect(Qs.parse('foo=bar&baz', {strictNullHandling: true})).to.deep.equal({ foo: 'bar', baz: null });
expect(Qs.parse('foo=bar&baz')).to.deep.equal({ foo: 'bar', baz: '' });
expect(Qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World')).to.deep.equal({
cht: 'p3',
chd: 't:60,40',
Expand Down Expand Up @@ -176,7 +178,7 @@ describe('parse()', function () {

it('supports malformed uri characters', function (done) {

expect(Qs.parse('{%:%}')).to.deep.equal({ '{%:%}': null });
expect(Qs.parse('{%:%}', {strictNullHandling: true})).to.deep.equal({ '{%:%}': null });
expect(Qs.parse('{%:%}=')).to.deep.equal({ '{%:%}': '' });
expect(Qs.parse('foo=%:%}')).to.deep.equal({ foo: '%:%}' });
done();
Expand Down Expand Up @@ -216,8 +218,8 @@ describe('parse()', function () {
it('allows for empty strings in arrays', function (done) {

expect(Qs.parse('a[]=b&a[]=&a[]=c')).to.deep.equal({ a: ['b', '', 'c'] });
expect(Qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=')).to.deep.equal({ a: ['b', null, 'c', ''] });
expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]')).to.deep.equal({ a: ['b', '', 'c', null] });
expect(Qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', {strictNullHandling: true})).to.deep.equal({ a: ['b', null, 'c', ''] });
expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', {strictNullHandling: true})).to.deep.equal({ a: ['b', '', 'c', null] });
expect(Qs.parse('a[]=&a[]=b&a[]=c')).to.deep.equal({ a: ['', 'b', 'c'] });
done();
});
Expand Down Expand Up @@ -245,7 +247,7 @@ describe('parse()', function () {
it('continues parsing when no parent is found', function (done) {

expect(Qs.parse('[]=&a=b')).to.deep.equal({ '0': '', a: 'b' });
expect(Qs.parse('[]&a=b')).to.deep.equal({ '0': null, a: 'b' });
expect(Qs.parse('[]&a=b', {strictNullHandling: true})).to.deep.equal({ '0': null, a: 'b' });
expect(Qs.parse('[foo]=bar')).to.deep.equal({ foo: 'bar' });
done();
});
Expand Down
7 changes: 4 additions & 3 deletions test/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ describe('stringify()', function () {

expect(Qs.stringify({ a: '' })).to.equal('a=');
expect(Qs.stringify({ a: '', b: '' })).to.equal('a=&b=');
expect(Qs.stringify({ a: null })).to.equal('a');
expect(Qs.stringify({ a: { b: null } })).to.equal('a%5Bb%5D');
expect(Qs.stringify({ a: null }, {strictNullHandling: true})).to.equal('a');
expect(Qs.stringify({ a: { b: null } }, {strictNullHandling: true})).to.equal('a%5Bb%5D');
expect(Qs.stringify({ a: { b: '' } })).to.equal('a%5Bb%5D=');
done();
});
Expand Down Expand Up @@ -144,7 +144,8 @@ describe('stringify()', function () {
it('drops keys with a value of undefined', function (done) {

expect(Qs.stringify({ a: undefined })).to.equal('');
expect(Qs.stringify({ a: { b: undefined, c: null } })).to.equal('a%5Bc%5D');
expect(Qs.stringify({ a: { b: undefined, c: null } }, {strictNullHandling: true})).to.equal('a%5Bc%5D');
expect(Qs.stringify({ a: { b: undefined, c: '' } })).to.equal('a%5Bc%5D=');
done();
});

Expand Down

0 comments on commit d0b4c87

Please sign in to comment.