Skip to content

Commit 7cf1462

Browse files
authored
Feat: Replace node querystring with URLSearchParams (#1828)
Fix #1570 Replace node querystring with URLSearchParams it mimics the way that querystring works ## Checklist - [x] I have ensured my pull request is not behind the main or master branch of the original repository. - [x] I have rebased all commits where necessary so that reviewing this pull request can be done without having to merge it first. - [x] I have written a commit message that passes commitlint linting. - [x] I have ensured that my code changes pass linting tests. - [x] I have ensured that my code changes pass unit tests. - [x] I have described my pull request and the reasons for code changes along with context if necessary.
1 parent d0f8543 commit 7cf1462

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

__tests__/lib/search-params.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
const sp = require('../../lib/search-params')
2+
const assert = require('assert')
3+
4+
describe('search-params', () => {
5+
describe('stringify', () => {
6+
it('Should stringify a simple object', () => {
7+
assert.deepStrictEqual(sp.stringify({ a: 1, b: 'b' }), 'a=1&b=b')
8+
})
9+
10+
it('Should stringify an object with an array', () => {
11+
assert.deepStrictEqual(sp.stringify({ a: [1, 2] }), 'a=1&a=2')
12+
})
13+
14+
it('Should stringify an object with an array with a single value', () => {
15+
assert.deepStrictEqual(sp.stringify({ a: [1] }), 'a=1')
16+
})
17+
18+
it('Stringify an object with an array with a single empty value', () => {
19+
assert.deepStrictEqual(sp.stringify({ a: [''] }), 'a=')
20+
})
21+
22+
it('Should not stringify an object with a nested object', () => {
23+
assert.deepStrictEqual(sp.stringify({ a: { b: 1 } }), 'a=')
24+
})
25+
})
26+
27+
describe('parse', () => {
28+
it('Should parse a simple query string', () => {
29+
assert.deepStrictEqual(sp.parse('a=1&b=2'), { a: '1', b: '2' })
30+
})
31+
32+
it('Should parse a query string with same key and multiple values', () => {
33+
assert.deepEqual(sp.parse('a=1&a=2'), { a: ['1', '2'] })
34+
})
35+
36+
it('Should parse a query string with an array with a single empty value', () => {
37+
assert.deepStrictEqual(sp.parse('a='), { a: '' })
38+
})
39+
})
40+
})

lib/request.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const accepts = require('accepts')
1010
const contentType = require('content-type')
1111
const stringify = require('url').format
1212
const parse = require('parseurl')
13-
const qs = require('querystring')
13+
const sp = require('./search-params.js')
14+
1415
const typeis = require('type-is')
1516
const fresh = require('fresh')
1617
const only = require('./only.js')
@@ -171,7 +172,7 @@ module.exports = {
171172
get query () {
172173
const str = this.querystring
173174
const c = this._querycache = this._querycache || {}
174-
return c[str] || (c[str] = qs.parse(str))
175+
return c[str] || (c[str] = sp.parse(str))
175176
},
176177

177178
/**
@@ -182,7 +183,7 @@ module.exports = {
182183
*/
183184

184185
set query (obj) {
185-
this.querystring = qs.stringify(obj)
186+
this.querystring = sp.stringify(obj)
186187
},
187188

188189
/**
@@ -210,7 +211,6 @@ module.exports = {
210211

211212
url.search = str
212213
url.path = null
213-
214214
this.url = stringify(url)
215215
},
216216

lib/search-params.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const URLSearchParams = require('url').URLSearchParams
2+
3+
module.exports = {
4+
stringify: (obj) => {
5+
const searchParams = new URLSearchParams()
6+
const addKey = (k, v, params) => {
7+
const val = typeof v === 'string' || typeof v === 'number' ? v : ''
8+
params.append(k, val)
9+
}
10+
11+
for (const [key, value] of Object.entries(obj)) {
12+
if (Array.isArray(value)) {
13+
const lgth = value.length
14+
for (let i = 0; i < lgth; i++) {
15+
addKey(key, value[i], searchParams)
16+
}
17+
} else {
18+
addKey(key, value, searchParams)
19+
}
20+
}
21+
return searchParams.toString()
22+
},
23+
24+
parse: (str) => {
25+
const searchParams = new URLSearchParams(str)
26+
const obj = {}
27+
for (const key of searchParams.keys()) {
28+
const values = searchParams.getAll(key)
29+
obj[key] = values.length <= 1 ? values[0] : values
30+
}
31+
return obj
32+
}
33+
}

0 commit comments

Comments
 (0)