Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/helpers/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,23 @@ module.exports = {
*/
hasHeader: (headers, name) => {
return Boolean(Object.keys(headers).find(k => k.toLowerCase() === name.toLowerCase()))
},

/**
* Determines if a given mimetype is JSON, or a variant of such.
*
* @param {string}} mimeType
* @returns {boolean}
*/
isMimeTypeJson: (mimeType) => {
return [
'application/json',
'application/x-json',
'text/json',
'text/x-json',
'+json'
].some(function (type) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: you could condense lines 53-55 to:

      ].some(mimeType.includes.bind(mimeType))

return mimeType.indexOf(type) > -1
})
}
}
38 changes: 33 additions & 5 deletions src/targets/shell/curl.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
'use strict'

const util = require('util')
const helpers = require('../../helpers/shell')
const helpers = require('./helpers')
const headerHelpers = require('../../helpers/headers')
const CodeBuilder = require('../../helpers/code-builder')

Expand Down Expand Up @@ -100,10 +100,38 @@ module.exports = function (source, options) {
default:
// raw request body
if (source.postData.text) {
code.push(
'%s %s', opts.binary ? '--data-binary' : (opts.short ? '-d' : '--data'),
helpers.quote(source.postData.text)
)
let builtPayload = false

// If we're dealing with a JSON variant, and our payload is JSON let's make it look a little nicer.
if (headerHelpers.isMimeTypeJson(source.postData.mimeType)) {
// If our postData is less than 20 characters, let's keep it all on one line so as to not make the snippet
// overly lengthy.
if (source.postData.text.length > 20) {
try {
const jsonPayload = JSON.parse(source.postData.text)

// If the JSON object has a single quote we should prepare it inside of a HEREDOC because the single
// quote in something like `string's` can't be escaped when used with `--data`.
//
// Basically this boils down to `--data @- <<EOF...EOF` vs `--data '...'`.
builtPayload = true
code.push(
source.postData.text.indexOf("'") > 0 ? '%s @- <<EOF\n%s\nEOF' : "%s '\n%s\n'",
opts.binary ? '--data-binary' : (opts.short ? '-d' : '--data'),
JSON.stringify(jsonPayload, null, opts.indent)
)
} catch (err) {
// no-op
}
}
}

if (!builtPayload) {
code.push(
'%s %s', opts.binary ? '--data-binary' : (opts.short ? '-d' : '--data'),
helpers.quote(source.postData.text)
)
}
}
}

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/targets/shell/httpie.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
'use strict'

const util = require('util')
const shell = require('../../helpers/shell')
const shell = require('./helpers')
const CodeBuilder = require('../../helpers/code-builder')

module.exports = function (source, options) {
Expand Down
2 changes: 1 addition & 1 deletion src/targets/shell/wget.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
'use strict'

const util = require('util')
const helpers = require('../../helpers/shell')
const helpers = require('./helpers')
const CodeBuilder = require('../../helpers/code-builder')

module.exports = function (source, options) {
Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/curl/jsonObj-short.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"url": "http://mockbin.com/har",
"method": "POST",
"headers": [
{
"name": "content-type",
"value": "application/json"
}
],
"postData": {
"text": "{\"foo\": \"bar\"}",
"mimeType": "application/json"
}
}
14 changes: 14 additions & 0 deletions test/fixtures/curl/jsonObj-with-singlequotes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"method": "POST",
"url": "http://mockbin.com/har",
"headers": [
{
"name": "content-type",
"value": "application/json"
}
],
"postData": {
"mimeType": "application/json",
"text": "{\"number\":1,\"string\":\"f'oo\"}"
}
}
23 changes: 22 additions & 1 deletion test/fixtures/output/shell/curl/application-json.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
curl --request POST \
--url http://mockbin.com/har \
--header 'content-type: application/json' \
--data '{"number":1,"string":"f\"oo","arr":[1,2,3],"nested":{"a":"b"},"arr_mix":[1,"a",{"arr_mix_nested":{}}],"boolean":false}'
--data '
{
"number": 1,
"string": "f\"oo",
"arr": [
1,
2,
3
],
"nested": {
"a": "b"
},
"arr_mix": [
1,
"a",
{
"arr_mix_nested": {}
}
],
"boolean": false
}
'
14 changes: 14 additions & 0 deletions test/targets/shell/curl.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,18 @@ module.exports = function (HTTPSnippet, fixtures) {
result.should.be.a.String()
result.replace(/\\\n/g, '').should.eql("curl --request POST @--url 'http://mockbin.com/har?foo=bar&foo=baz&baz=abc&key=value' @--header 'accept: application/json' @--header 'content-type: application/x-www-form-urlencoded' @--cookie 'foo=bar; bar=baz' @--data foo=bar")
})

it('should send JSON-encoded data with single quotes within a HEREDOC', function () {
var result = new HTTPSnippet(fixtures.curl['jsonObj-with-singlequotes']).convert('shell', 'curl')

result.should.be.a.String()
result.replace(/\\\n/g, '').replace(/\n/g, '').should.eql("curl --request POST --url http://mockbin.com/har --header 'content-type: application/json' --data @- <<EOF{ \"number\": 1, \"string\": \"f'oo\"}EOF")
})

it('should keep JSON payloads that are smaller than 20 characters on one line', function () {
var result = new HTTPSnippet(fixtures.curl['jsonObj-short']).convert('shell', 'curl')

result.should.be.a.String()
result.replace(/\\\n/g, '').replace(/\n/g, '').should.eql("curl --request POST --url http://mockbin.com/har --header 'content-type: application/json' --data '{\"foo\": \"bar\"}'")
})
}