From 1cf2bbf8cf1d26a4449171a4bbb689310dc9036b Mon Sep 17 00:00:00 2001 From: Philipp Beck Date: Thu, 22 Jun 2017 14:07:46 +0200 Subject: [PATCH] Support Array with the `json` option (#335) --- index.js | 9 +++++---- readme.md | 4 ++-- test/post.js | 20 ++++++++++++++++++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index cae5ce7..4ad2067 100644 --- a/index.js +++ b/index.js @@ -315,17 +315,18 @@ function normalizeArguments(url, opts) { throw new TypeError('options.body must be a ReadableStream, string, Buffer or plain Object'); } - if ((opts.form || opts.json) && !isPlainObj(body)) { - throw new TypeError('options.body must be a plain Object when options.form or options.json is used'); + const canBodyBeStringified = isPlainObj(body) || Array.isArray(body); + if ((opts.form || opts.json) && !canBodyBeStringified) { + throw new TypeError('options.body must be a plain Object or Array when options.form or options.json is used'); } if (isStream(body) && typeof body.getBoundary === 'function') { // Special case for https://github.com/form-data/form-data headers['content-type'] = headers['content-type'] || `multipart/form-data; boundary=${body.getBoundary()}`; - } else if (opts.form && isPlainObj(body)) { + } else if (opts.form && canBodyBeStringified) { headers['content-type'] = headers['content-type'] || 'application/x-www-form-urlencoded'; opts.body = querystring.stringify(body); - } else if (opts.json && isPlainObj(body)) { + } else if (opts.json && canBodyBeStringified) { headers['content-type'] = headers['content-type'] || 'application/json'; opts.body = JSON.stringify(body); } diff --git a/readme.md b/readme.md index 4508e9c..074530f 100644 --- a/readme.md +++ b/readme.md @@ -110,7 +110,7 @@ Default: `false` If set to `true` and `Content-Type` header is not set, it will be set to `application/x-www-form-urlencoded`. -`body` must be a plain object and will be stringified. +`body` must be a plain object or array and will be stringified. ###### json @@ -123,7 +123,7 @@ If set to `true` and `Content-Type` header is not set, it will be set to `applic Parse response body with `JSON.parse` and set `accept` header to `application/json`. If used in conjunction with the `form` option, the `body` will the stringified as querystring and the response parsed as JSON. -`body` must be a plain object and will be stringified. +`body` must be a plain object or array and will be stringified. ###### query diff --git a/test/post.js b/test/post.js index 4912e21..3b4af84 100644 --- a/test/post.js +++ b/test/post.js @@ -53,6 +53,14 @@ test('sends plain objects as forms', async t => { t.is(body, 'such=wow'); }); +test('sends arrays as forms', async t => { + const {body} = await got(s.url, { + body: ['such', 'wow'], + form: true + }); + t.is(body, '0=such&1=wow'); +}); + test('sends plain objects as JSON', async t => { const {body} = await got(s.url, { body: {such: 'wow'}, @@ -61,6 +69,14 @@ test('sends plain objects as JSON', async t => { t.deepEqual(body, {such: 'wow'}); }); +test('sends arrays as JSON', async t => { + const {body} = await got(s.url, { + body: ['such', 'wow'], + json: true + }); + t.deepEqual(body, ['such', 'wow']); +}); + test('works with empty post response', async t => { const {body} = await got(`${s.url}/empty`, {body: 'wow'}); t.is(body, ''); @@ -121,11 +137,11 @@ test('content-type header is not overriden when object in options.body', async t t.is(headers['content-type'], 'doge'); }); -test('throws when json body is not a plain object', async t => { +test('throws when json body is not a plain object or array', async t => { await t.throws(got(`${s.url}`, {body: '{}', json: true}), TypeError); }); -test('throws when form body is not a plain object', async t => { +test('throws when form body is not a plain object or array', async t => { await t.throws(got(`${s.url}`, {body: 'such=wow', form: true}), TypeError); });