Skip to content

Commit

Permalink
Merge pull request #2009 from elyobo/stringify-replacer
Browse files Browse the repository at this point in the history
Support JSON stringify replacer argument.
  • Loading branch information
simov committed Mar 26, 2016
2 parents de16611 + 397c76b commit a7ef602
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -749,6 +749,7 @@ The first argument can be either a `url` or an `options` object. The only requir
- `postambleCRLF` - append a newline/CRLF at the end of the boundary of your `multipart/form-data` request.
- `json` - sets `body` to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as JSON.
- `jsonReviver` - a [reviver function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) that will be passed to `JSON.parse()` when parsing a JSON response body.
- `jsonReplacer` - a [replacer function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) that will be passed to `JSON.stringify()` when stringifying a JSON request body.

---

Expand Down
6 changes: 3 additions & 3 deletions lib/helpers.js
Expand Up @@ -24,12 +24,12 @@ function paramsHaveRequestBody(params) {
)
}

function safeStringify (obj) {
function safeStringify (obj, replacer) {
var ret
try {
ret = JSON.stringify(obj)
ret = JSON.stringify(obj, replacer)
} catch (e) {
ret = jsonSafeStringify(obj)
ret = jsonSafeStringify(obj, replacer)
}
return ret
}
Expand Down
8 changes: 6 additions & 2 deletions request.js
Expand Up @@ -1162,11 +1162,15 @@ Request.prototype.json = function (val) {
self.setHeader('accept', 'application/json')
}

if (typeof self.jsonReplacer === 'function') {
self._jsonReplacer = self.jsonReplacer
}

self._json = true
if (typeof val === 'boolean') {
if (self.body !== undefined) {
if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) {
self.body = safeStringify(self.body)
self.body = safeStringify(self.body, self._jsonReplacer)
} else {
self.body = self._qs.rfc3986(self.body)
}
Expand All @@ -1175,7 +1179,7 @@ Request.prototype.json = function (val) {
}
}
} else {
self.body = safeStringify(val)
self.body = safeStringify(val, self._jsonReplacer)
if (!self.hasHeader('content-type')) {
self.setHeader('content-type', 'application/json')
}
Expand Down
29 changes: 29 additions & 0 deletions tests/test-json-request.js
Expand Up @@ -51,6 +51,26 @@ function testJSONValueReviver(testId, value, reviver, revivedValue) {
})
}

function testJSONValueReplacer(testId, value, replacer, replacedValue) {
tape('test ' + testId, function(t) {
var testUrl = '/' + testId
s.on(testUrl, server.createPostJSONValidator(replacedValue, 'application/json'))
var opts = {
method: 'PUT',
uri: s.url + testUrl,
json: true,
jsonReplacer: replacer,
body: value
}
request(opts, function (err, resp, body) {
t.equal(err, null)
t.equal(resp.statusCode, 200)
t.deepEqual(body, replacedValue)
t.end()
})
})
}

testJSONValue('jsonNull', null)
testJSONValue('jsonTrue', true)
testJSONValue('jsonFalse', false)
Expand All @@ -72,6 +92,15 @@ testJSONValueReviver('jsonReviver', -48269.592, function (k, v) {
}, 48269.592)
testJSONValueReviver('jsonReviverInvalid', -48269.592, 'invalid reviver', -48269.592)

testJSONValueReplacer('jsonReplacer', -48269.592, function (k, v) {
return v * -1
}, 48269.592)
testJSONValueReplacer('jsonReplacerInvalid', -48269.592,'invalid replacer', -48269.592)
testJSONValueReplacer('jsonReplacerObject', {foo: 'bar'}, function (k, v) {
return v.toUpperCase ? v.toUpperCase() : v
}, {foo: 'BAR'})


tape('missing body', function (t) {
s.on('/missing-body', function (req, res) {
t.equal(req.headers['content-type'], undefined)
Expand Down

0 comments on commit a7ef602

Please sign in to comment.