-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
88 lines (76 loc) · 2.9 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import cj from 'color-json';
const hasOwnProperty = (object, property) => Object.prototype.hasOwnProperty.call(object, property);
/**
* Builds a curl command and returns the string.
* @param {String} url Endpoint
* @param {Object} options Object with headers, etc. (fetch format)
* @param {Object} [curlStringOptions={colorJson:true,jsonIndentWidth:2}] Formatting options
* @return {String} cURL command
*/
export default function curlString(
url,
options,
curlStringOptions = { colorJson: true, jsonIndentWidth: 2 }
) {
const method =
options && options.method && typeof options.method === 'string'
? options.method.toUpperCase()
: 'GET';
const hasHeaders =
options && options.headers && typeof options.headers === 'object';
const hasBody = options && options.body;
let curl = `curl --request ${method} \\\n--url ${url.replace(/\s/g, '%20')}${hasHeaders || hasBody ? ' \\' : ''
}`;
if (hasHeaders) {
Object.entries(options.headers).forEach(([key, value], i) => {
curl += `\n--header '${key}: ${value}'${hasBody || i < Object.keys(options.headers).length - 1 ? ' \\' : ''
}`;
});
}
if (hasBody) {
curl += `\n--data '${bodyToDataString(options, curlStringOptions)}'`
}
return curl;
}
function getHeader(options, headerKeyName) {
// return header that matches case, but if not found fall back to header that does not match case
return options.headers[headerKeyName] || options.headers[Object.keys(options.headers).find(key => key.toLowerCase() === headerKeyName.toLowerCase())]
}
function hasHeader(options, headerKeyName) {
return hasOwnProperty(options, 'headers') &&
Object.keys(options.headers)
.find(header => headerKeyName === header.toLowerCase());
}
/**
* Constructs a body string for use inside --data
* @param {Object} options Object with headers, etc. (fetch format)
* @param {Object} curlStringOptions Formatting options
* @return {String} cURL command data string
*/
function bodyToDataString(options, curlStringOptions) {
let parsedData;
try {
parsedData = JSON.parse(options.body);
} catch (e) {
// fall back to original body if it could not be parsed as JSON
parsedData = options.body;
}
// return an ampersand delimited string
if (hasHeader(options, 'content-type') &&
getHeader(options, 'content-type').toLowerCase() === 'application/x-www-form-urlencoded') {
if (typeof parsedData === 'string') {
return parsedData;
} else {
return Object.entries(parsedData)
.map(([key, val]) => `${key}=${val}`)
.join('&');
}
} else {
const colorJson = curlStringOptions && curlStringOptions.colorJson;
const jsonIndentWidth =
(curlStringOptions && curlStringOptions.jsonIndentWidth) || 2;
return colorJson
? cj(parsedData)
: JSON.stringify(parsedData, null, jsonIndentWidth);
}
}