Skip to content

Commit d11899b

Browse files
refactor: normalize common options for all parsers (#551)
Co-authored-by: Ulises Gascón <[email protected]>
1 parent f27f2ce commit d11899b

File tree

7 files changed

+239
-165
lines changed

7 files changed

+239
-165
lines changed

HISTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
unreleased
22
=========================
33

4+
* refactor: normalize common options for all parsers
45
* deps:
56
* iconv-lite@^0.6.3
67

lib/types/json.js

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@
1212
* @private
1313
*/
1414

15-
var bytes = require('bytes')
16-
var contentType = require('content-type')
1715
var createError = require('http-errors')
1816
var debug = require('debug')('body-parser:json')
1917
var isFinished = require('on-finished').isFinished
2018
var read = require('../read')
2119
var typeis = require('type-is')
20+
var { getCharset, normalizeOptions } = require('../utils')
2221

2322
/**
2423
* Module exports.
@@ -53,24 +52,10 @@ var JSON_SYNTAX_REGEXP = /#+/g
5352

5453
function json (options) {
5554
var opts = options || {}
55+
var { inflate, limit, verify, shouldParse } = normalizeOptions(opts, 'application/json')
5656

57-
var limit = typeof opts.limit !== 'number'
58-
? bytes.parse(opts.limit || '100kb')
59-
: opts.limit
60-
var inflate = opts.inflate !== false
6157
var reviver = opts.reviver
6258
var strict = opts.strict !== false
63-
var type = opts.type || 'application/json'
64-
var verify = opts.verify || false
65-
66-
if (verify !== false && typeof verify !== 'function') {
67-
throw new TypeError('option verify must be function')
68-
}
69-
70-
// create the appropriate type checking function
71-
var shouldParse = typeof type !== 'function'
72-
? typeChecker(type)
73-
: type
7459

7560
function parse (body) {
7661
if (body.length === 0) {
@@ -196,21 +181,6 @@ function firstchar (str) {
196181
: undefined
197182
}
198183

199-
/**
200-
* Get the charset of a request.
201-
*
202-
* @param {object} req
203-
* @api private
204-
*/
205-
206-
function getCharset (req) {
207-
try {
208-
return (contentType.parse(req).parameters.charset || '').toLowerCase()
209-
} catch (e) {
210-
return undefined
211-
}
212-
}
213-
214184
/**
215185
* Normalize a SyntaxError for JSON.parse.
216186
*
@@ -235,16 +205,3 @@ function normalizeJsonSyntaxError (error, obj) {
235205

236206
return error
237207
}
238-
239-
/**
240-
* Get the simple type checker.
241-
*
242-
* @param {string} type
243-
* @return {function}
244-
*/
245-
246-
function typeChecker (type) {
247-
return function checkType (req) {
248-
return Boolean(typeis(req, type))
249-
}
250-
}

lib/types/raw.js

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
* Module dependencies.
1111
*/
1212

13-
var bytes = require('bytes')
1413
var debug = require('debug')('body-parser:raw')
1514
var isFinished = require('on-finished').isFinished
1615
var read = require('../read')
1716
var typeis = require('type-is')
17+
var { normalizeOptions } = require('../utils')
1818

1919
/**
2020
* Module exports.
@@ -32,22 +32,7 @@ module.exports = raw
3232

3333
function raw (options) {
3434
var opts = options || {}
35-
36-
var inflate = opts.inflate !== false
37-
var limit = typeof opts.limit !== 'number'
38-
? bytes.parse(opts.limit || '100kb')
39-
: opts.limit
40-
var type = opts.type || 'application/octet-stream'
41-
var verify = opts.verify || false
42-
43-
if (verify !== false && typeof verify !== 'function') {
44-
throw new TypeError('option verify must be function')
45-
}
46-
47-
// create the appropriate type checking function
48-
var shouldParse = typeof type !== 'function'
49-
? typeChecker(type)
50-
: type
35+
var { inflate, limit, verify, shouldParse } = normalizeOptions(opts, 'application/octet-stream')
5136

5237
function parse (buf) {
5338
return buf
@@ -89,16 +74,3 @@ function raw (options) {
8974
})
9075
}
9176
}
92-
93-
/**
94-
* Get the simple type checker.
95-
*
96-
* @param {string} type
97-
* @return {function}
98-
*/
99-
100-
function typeChecker (type) {
101-
return function checkType (req) {
102-
return Boolean(typeis(req, type))
103-
}
104-
}

lib/types/text.js

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@
1010
* Module dependencies.
1111
*/
1212

13-
var bytes = require('bytes')
14-
var contentType = require('content-type')
1513
var debug = require('debug')('body-parser:text')
1614
var isFinished = require('on-finished').isFinished
1715
var read = require('../read')
1816
var typeis = require('type-is')
17+
var { getCharset, normalizeOptions } = require('../utils')
1918

2019
/**
2120
* Module exports.
@@ -33,23 +32,9 @@ module.exports = text
3332

3433
function text (options) {
3534
var opts = options || {}
35+
var { inflate, limit, verify, shouldParse } = normalizeOptions(opts, 'text/plain')
3636

3737
var defaultCharset = opts.defaultCharset || 'utf-8'
38-
var inflate = opts.inflate !== false
39-
var limit = typeof opts.limit !== 'number'
40-
? bytes.parse(opts.limit || '100kb')
41-
: opts.limit
42-
var type = opts.type || 'text/plain'
43-
var verify = opts.verify || false
44-
45-
if (verify !== false && typeof verify !== 'function') {
46-
throw new TypeError('option verify must be function')
47-
}
48-
49-
// create the appropriate type checking function
50-
var shouldParse = typeof type !== 'function'
51-
? typeChecker(type)
52-
: type
5338

5439
function parse (buf) {
5540
return buf
@@ -94,31 +79,3 @@ function text (options) {
9479
})
9580
}
9681
}
97-
98-
/**
99-
* Get the charset of a request.
100-
*
101-
* @param {object} req
102-
* @api private
103-
*/
104-
105-
function getCharset (req) {
106-
try {
107-
return (contentType.parse(req).parameters.charset || '').toLowerCase()
108-
} catch (e) {
109-
return undefined
110-
}
111-
}
112-
113-
/**
114-
* Get the simple type checker.
115-
*
116-
* @param {string} type
117-
* @return {function}
118-
*/
119-
120-
function typeChecker (type) {
121-
return function checkType (req) {
122-
return Boolean(typeis(req, type))
123-
}
124-
}

lib/types/urlencoded.js

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212
* @private
1313
*/
1414

15-
var bytes = require('bytes')
16-
var contentType = require('content-type')
1715
var createError = require('http-errors')
1816
var debug = require('debug')('body-parser:urlencoded')
1917
var isFinished = require('on-finished').isFinished
2018
var read = require('../read')
2119
var typeis = require('type-is')
2220
var qs = require('qs')
21+
var { getCharset, normalizeOptions } = require('../utils')
2322

2423
/**
2524
* Module exports.
@@ -37,21 +36,12 @@ module.exports = urlencoded
3736

3837
function urlencoded (options) {
3938
var opts = options || {}
39+
var { inflate, limit, verify, shouldParse } = normalizeOptions(opts, 'application/x-www-form-urlencoded')
4040

4141
var extended = Boolean(opts.extended)
42-
var inflate = opts.inflate !== false
43-
var limit = typeof opts.limit !== 'number'
44-
? bytes.parse(opts.limit || '100kb')
45-
: opts.limit
46-
var type = opts.type || 'application/x-www-form-urlencoded'
47-
var verify = opts.verify || false
4842
var charsetSentinel = opts.charsetSentinel
4943
var interpretNumericEntities = opts.interpretNumericEntities
5044

51-
if (verify !== false && typeof verify !== 'function') {
52-
throw new TypeError('option verify must be function')
53-
}
54-
5545
var defaultCharset = opts.defaultCharset || 'utf-8'
5646
if (defaultCharset !== 'utf-8' && defaultCharset !== 'iso-8859-1') {
5747
throw new TypeError('option defaultCharset must be either utf-8 or iso-8859-1')
@@ -60,11 +50,6 @@ function urlencoded (options) {
6050
// create the appropriate query parser
6151
var queryparse = createQueryParser(opts, extended)
6252

63-
// create the appropriate type checking function
64-
var shouldParse = typeof type !== 'function'
65-
? typeChecker(type)
66-
: type
67-
6853
function parse (body, encoding) {
6954
return body.length
7055
? queryparse(body, encoding)
@@ -184,21 +169,6 @@ function createQueryParser (options, extended) {
184169
}
185170
}
186171

187-
/**
188-
* Get the charset of a request.
189-
*
190-
* @param {object} req
191-
* @api private
192-
*/
193-
194-
function getCharset (req) {
195-
try {
196-
return (contentType.parse(req).parameters.charset || '').toLowerCase()
197-
} catch (e) {
198-
return undefined
199-
}
200-
}
201-
202172
/**
203173
* Count the number of parameters, stopping once limit reached
204174
*
@@ -212,16 +182,3 @@ function parameterCount (body, limit) {
212182

213183
return len > limit ? undefined : len - 1
214184
}
215-
216-
/**
217-
* Get the simple type checker.
218-
*
219-
* @param {string} type
220-
* @return {function}
221-
*/
222-
223-
function typeChecker (type) {
224-
return function checkType (req) {
225-
return Boolean(typeis(req, type))
226-
}
227-
}

lib/utils.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
'use strict'
2+
3+
/**
4+
* Module dependencies.
5+
*/
6+
7+
var bytes = require('bytes')
8+
var contentType = require('content-type')
9+
var typeis = require('type-is')
10+
11+
/**
12+
* Module exports.
13+
*/
14+
15+
module.exports = {
16+
getCharset,
17+
normalizeOptions
18+
}
19+
20+
/**
21+
* Get the charset of a request.
22+
*
23+
* @param {object} req
24+
* @api private
25+
*/
26+
27+
function getCharset (req) {
28+
try {
29+
return (contentType.parse(req).parameters.charset || '').toLowerCase()
30+
} catch {
31+
return undefined
32+
}
33+
}
34+
35+
/**
36+
* Get the simple type checker.
37+
*
38+
* @param {string | string[]} type
39+
* @return {function}
40+
*/
41+
42+
function typeChecker (type) {
43+
return function checkType (req) {
44+
return Boolean(typeis(req, type))
45+
}
46+
}
47+
48+
/**
49+
* Normalizes the common options for all parsers.
50+
*
51+
* @param {object} options options to normalize
52+
* @param {string | string[] | function} defaultType default content type(s) or a function to determine it
53+
* @returns {object}
54+
*/
55+
function normalizeOptions (options, defaultType) {
56+
if (!defaultType) {
57+
// Parsers must define a default content type
58+
throw new TypeError('defaultType must be provided')
59+
}
60+
61+
var inflate = options?.inflate !== false
62+
var limit = typeof options?.limit !== 'number'
63+
? bytes.parse(options?.limit || '100kb')
64+
: options?.limit
65+
var type = options?.type || defaultType
66+
var verify = options?.verify || false
67+
68+
if (verify !== false && typeof verify !== 'function') {
69+
throw new TypeError('option verify must be function')
70+
}
71+
72+
// create the appropriate type checking function
73+
var shouldParse = typeof type !== 'function'
74+
? typeChecker(type)
75+
: type
76+
77+
return {
78+
inflate,
79+
limit,
80+
verify,
81+
shouldParse
82+
}
83+
}

0 commit comments

Comments
 (0)