From 397c76bd2fc916b1943a384bed5bfd16de9fe8cf Mon Sep 17 00:00:00 2001 From: Liam O'Boyle Date: Thu, 14 Jan 2016 08:37:58 +1100 Subject: [PATCH] Support JSON stringify replacer argument. Adds support for the replacer argument of JSON.stringify, in the same way that request already supports the revivier argument for JSON.parse. Change jsonReplacer arg to jsonStringifier. Revert "Change jsonReplacer arg to jsonStringifier." This reverts commit 40c03af35ede54c29ac7cd72aa3a2b50c42a59ff. --- README.md | 1 + lib/helpers.js | 6 +++--- request.js | 8 ++++++-- tests/test-json-request.js | 29 +++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8de982ad6..64c43e742 100644 --- a/README.md +++ b/README.md @@ -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. --- diff --git a/lib/helpers.js b/lib/helpers.js index 5e8594606..356ff748e 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -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 } diff --git a/request.js b/request.js index cb3862b0e..6310e0a6b 100644 --- a/request.js +++ b/request.js @@ -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) } @@ -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') } diff --git a/tests/test-json-request.js b/tests/test-json-request.js index e7f39556e..aa117e216 100644 --- a/tests/test-json-request.js +++ b/tests/test-json-request.js @@ -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) @@ -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)