From 1bece021dc3082c7a138b4e0ef54c59080a52709 Mon Sep 17 00:00:00 2001 From: Martin Zajic Date: Tue, 11 Apr 2017 14:40:31 +0200 Subject: [PATCH 1/4] Add support for encoded brackets --- README.md | 2 ++ index.js | 4 +-- test.js | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 228d331..f99238f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ output ####a=1&b[]=1&b[]=2&c=3 +*object and arrays with encoded brackets like %5B%5D* + output ``` diff --git a/index.js b/index.js index e6f4da2..8f55d18 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ var _ = require('lodash'); module.exports = function(query) { if( ! query ) return {}; if( typeof query == 'string' ) { - if( ! query.match(/\[\w*\]/) ) return native_qs.parse(query); + if( ! query.match(/(\[|\%5B)\w*(\]|\%5D)/) ) return native_qs.parse(query); query = native_qs.parse(query); } return parse( query ) @@ -19,7 +19,7 @@ function parse( query ){ for( var key in query ) { var value = query[key]; if( typeof value == 'string' && !isNaN(1*value) ) value = 1*value; - if( matches = key.match(/^(.+)(\[[^\]]*\])$/) ){ + if( matches = key.match(/^(.+)((\[|\%5B)[^\]]*(\]|\%5D))$/) ){ var parent = matches[1]; var child = matches[2]; if( child.match(/^\[\s*\]$/) ) { diff --git a/test.js b/test.js index 4a8c0d4..ed652bf 100644 --- a/test.js +++ b/test.js @@ -19,6 +19,13 @@ describe("querystring", function(){ c:3 }); }) + it("array encoded: ?a=1&b%5B%5D=1&b%5B%5D=2&c=3", function(){ + expect(qs("a=1&b%5B%5D=1&b%5B%5D=2&c=3")).to.be.eql({ + a:1, + b:[1,2], + c:3 + }); + }) it("array with single value: ?a=1&b[]=1&c=3", function(){ expect(qs("a=1&b[]=1&c=3")).to.be.eql({ a:1, @@ -26,6 +33,13 @@ describe("querystring", function(){ c:3 }); }) + it("array with single value encoded: ?a=1&b%5B%5D=1&c=3", function(){ + expect(qs("a=1&b%5B%5D=1&c=3")).to.be.eql({ + a:1, + b:[1], + c:3 + }); + }) it("object of number key: ?a=1&b[1]=1&c[3]=2&c=3", function(){ expect(qs("a=1&b[1]=1&c[3]=2&c=3")).to.be.eql({ a:1, @@ -33,6 +47,13 @@ describe("querystring", function(){ c:{3:2} }); }) + it("object of number key encoded: ?a=1&b%5B1%5D=1&c%5B3%5D=2&c=3", function(){ + expect(qs("a=1&b%5B1%5D=1&c%5B3%5D=2&c=3")).to.be.eql({ + a:1, + b:{1:1}, + c:{3:2} + }); + }) it("object with single key: ?a=1&b[eric]=dum&c[stive]=jobs&c=3", function(){ expect(qs("a=1&b[eric]=dum&c[stive]=jobs&c=3")).to.be.eql({ a:1, @@ -44,6 +65,17 @@ describe("querystring", function(){ } }); }) + it("object with single key encoded: ?a=1&b%5Beric%5D=dum&c%5Bstive%5D=jobs&c=3", function(){ + expect(qs("a=1&b%5Beric%5D=dum&c%5Bstive%5D=jobs&c=3")).to.be.eql({ + a:1, + b:{ + eric:"dum" + }, + c:{ + stive:"jobs" + } + }); + }) it("object with multiple key: ?a=1&b[eric]=dum&b[stive]=jobs&c=3", function(){ expect(qs("a=1&b[eric]=dum&b[stive]=jobs&c=3")).to.be.eql({ a:1, @@ -54,6 +86,16 @@ describe("querystring", function(){ c:3 }); }) + it("object with multiple key encoded: ?a=1&b%5Beric%5D=dum&b%5Bstive%5D=jobs&c=3", function(){ + expect(qs("a=1&b%5Beric%5D=dum&b%5Bstive%5D=jobs&c=3")).to.be.eql({ + a:1, + b:{ + eric:"dum", + stive:"jobs" + }, + c:3 + }); + }) it("array in object: ?a=1&b[eric][]=dum&b[stive][]=jobs&b[stive][]=fans&c=3", function(){ expect(qs("a=1&b[eric][]=dum&b[stive][]=jobs&b[stive][]=fans&c=3")).to.be.eql({ a:1, @@ -67,6 +109,19 @@ describe("querystring", function(){ c:3 }); }) + it("array in object encoded: ?a=1&b%5Beric%5D%5B%5D=dum&b%5Bstive%5D%5B%5D=jobs&b%5Bstive%5D%5B%5D=fans&c=3", function(){ + expect(qs("a=1&b%5Beric%5D%5B%5D=dum&b%5Bstive%5D%5B%5D=jobs&b%5Bstive%5D%5B%5D=fans&c=3")).to.be.eql({ + a:1, + b:{ + eric:["dum"], + stive: [ + "jobs", + "fans" + ] + }, + c:3 + }); + }) it("x.y[c][$d]=3m&x.y[a][]=c&x.y[b][]=1&x2.y2[c][$d]=3m&x.y3[c][$d]=3m&x.y3[a]=c&x.y3[b][]=1", function(){ expect(qs("x.y[c][$d]=3m&x.y[a][]=c&x.y[b][]=1&x2.y2[c][$d]=3m&x.y3[c][$d]=3m&x.y3[a]=c&x.y3[b][]=1")).to.be.eql({ 'x.y': { @@ -90,6 +145,29 @@ describe("querystring", function(){ } }); }) + it("x.y%5Bc%5D%5B$d%5D=3m&x.y%5Ba%5D%5B%5D=c&x.y%5Bb%5D%5B%5D=1&x2.y2%5Bc%5D%5B$d%5D=3m&x.y3%5Bc%5D%5B$d%5D=3m&x.y3%5Ba%5D=c&x.y3%5Bb%5D%5B%5D=1 encoded", function(){ + expect(qs("x.y%5Bc%5D%5B$d%5D=3m&x.y%5Ba%5D%5B%5D=c&x.y%5Bb%5D%5B%5D=1&x2.y2%5Bc%5D%5B$d%5D=3m&x.y3%5Bc%5D%5B$d%5D=3m&x.y3%5Ba%5D=c&x.y3%5Bb%5D%5B%5D=1")).to.be.eql({ + 'x.y': { + c: { + '$d': '3m' + }, + a: ['c'], + b: [1] + }, + 'x2.y2': { + c: { + '$d': '3m' + } + }, + 'x.y3': { + c: { + '$d': '3m' + }, + a: 'c', + b: [1] + } + }); + }) }); describe("querystring.stringify", function(){ it("normal: ?a=1&b=2", function(){ From f919ce075cda68150009a71fd9ae6907ad58d3f2 Mon Sep 17 00:00:00 2001 From: Martin Zajic Date: Wed, 1 Nov 2017 13:56:11 +0100 Subject: [PATCH 2/4] update deps --- package-lock.json | 209 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 +- 2 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9a4e1b3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,209 @@ +{ + "name": "query-string-object", + "version": "0.2.5", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "expect.js": { + "version": "https://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz", + "integrity": "sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", + "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "querystring-browser": { + "version": "https://registry.npmjs.org/querystring-browser/-/querystring-browser-1.0.4.tgz", + "integrity": "sha1-8uNYgYQKgZvHsb9Zf68JeeZiLcY=" + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 71d0d0a..743dfb7 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,11 @@ "test": "./node_modules/.bin/mocha --reporter tap test.js" }, "devDependencies": { - "mocha": "*", - "expect.js": "*" + "expect.js": "*", + "mocha": "^4.0.1" }, "dependencies": { - "lodash": "~3.8.0", + "lodash": "^4.17.4", "querystring-browser": "^1.0.4" } } From fa0e13ef830b368650878cab600cc45bb364e034 Mon Sep 17 00:00:00 2001 From: Martin Zajic Date: Wed, 1 Nov 2017 13:58:27 +0100 Subject: [PATCH 3/4] fix state when value in query is 0 which was threated as nullable --- index.js | 2 +- test.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 8f55d18..fd9ef48 100644 --- a/index.js +++ b/index.js @@ -47,7 +47,7 @@ module.exports.stringify = function(obj) { result.push(stringifyArray(key, val)); } else if (_.isObject(val)) { result.push(stringifyObject(key, val)); - } else if (val) { + } else if (val || val === 0) { result.push(key+'='+native_qs.escape(val)); } }); diff --git a/test.js b/test.js index ed652bf..10ddc11 100644 --- a/test.js +++ b/test.js @@ -267,8 +267,9 @@ describe("querystring.stringify", function(){ }, "zzz": {}, "www": '', + z:0, x:1, y:2 - })).to.be.eql("x=1&y=2"); + })).to.be.eql("z=0&x=1&y=2"); }) }); From 6e8a17540bd308bd5a0f4df91f171b07f46c32bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Zaj=C3=ADc?= Date: Wed, 24 Jan 2018 09:48:40 +0100 Subject: [PATCH 4/4] stringify false value --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index fd9ef48..9ffa25f 100644 --- a/index.js +++ b/index.js @@ -47,7 +47,7 @@ module.exports.stringify = function(obj) { result.push(stringifyArray(key, val)); } else if (_.isObject(val)) { result.push(stringifyObject(key, val)); - } else if (val || val === 0) { + } else if (val || val === 0 || val === false) { result.push(key+'='+native_qs.escape(val)); } });