mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-09 06:55:03 +00:00
212 lines
5.7 KiB
JavaScript
212 lines
5.7 KiB
JavaScript
/**
|
|
* Copyright (c) 2014-2016 Nick Carneiro
|
|
* https://github.com/curlconverter/curlconverter
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import parseCurlCommand from './parse-curl';
|
|
import * as querystring from 'query-string';
|
|
import * as jsesc from 'jsesc';
|
|
|
|
function getContentType(headers = {}) {
|
|
const contentType = Object.keys(headers).find((key) => key.toLowerCase() === 'content-type');
|
|
|
|
return contentType ? headers[contentType] : null;
|
|
}
|
|
|
|
function repr(value, isKey) {
|
|
return isKey ? "'" + jsesc(value, { quotes: 'single' }) + "'" : value;
|
|
}
|
|
|
|
function getQueries(request) {
|
|
const queries = {};
|
|
for (const paramName in request.query) {
|
|
const rawValue = request.query[paramName];
|
|
let paramValue;
|
|
if (Array.isArray(rawValue)) {
|
|
paramValue = rawValue.map(repr);
|
|
} else {
|
|
paramValue = repr(rawValue);
|
|
}
|
|
queries[repr(paramName)] = paramValue;
|
|
}
|
|
|
|
return queries;
|
|
}
|
|
|
|
/**
|
|
* Converts request data to a string based on its content type.
|
|
*
|
|
* @param {Object} request - The request object containing data and headers.
|
|
* @returns {Object} An object containing the data string.
|
|
*/
|
|
function getDataString(request) {
|
|
if (typeof request.data === 'number') {
|
|
request.data = request.data.toString();
|
|
}
|
|
|
|
const contentType = getContentType(request.headers);
|
|
|
|
if (contentType && contentType.includes('application/json')) {
|
|
try {
|
|
const parsedData = JSON.parse(request.data);
|
|
return { data: JSON.stringify(parsedData) };
|
|
} catch (error) {
|
|
console.error('Failed to parse JSON data:', error);
|
|
return { data: request.data.toString() };
|
|
}
|
|
} else if (contentType && (contentType.includes('application/xml') || contentType.includes('text/plain'))) {
|
|
return { data: request.data };
|
|
}
|
|
|
|
const parsedQueryString = querystring.parse(request.data, { sort: false });
|
|
// if missing `=`, `query-string` will set value as `null`. Reset value as empty string ('') here.
|
|
// https://github.com/sindresorhus/query-string/blob/3d8fbf2328220c06e45f166cdf58e70617c7ee68/base.js#L364-L366
|
|
Object.keys(parsedQueryString).forEach((key) => {
|
|
if (parsedQueryString[key] === null) {
|
|
parsedQueryString[key] = '';
|
|
}
|
|
});
|
|
const keyCount = Object.keys(parsedQueryString).length;
|
|
const singleKeyOnly = keyCount === 1 && !parsedQueryString[Object.keys(parsedQueryString)[0]];
|
|
const singularData = request.isDataBinary || singleKeyOnly;
|
|
if (singularData) {
|
|
const data = {};
|
|
data[repr(request.data)] = '';
|
|
return { data: data };
|
|
} else {
|
|
return getMultipleDataString(request, parsedQueryString);
|
|
}
|
|
}
|
|
|
|
function getMultipleDataString(request, parsedQueryString) {
|
|
const data = {};
|
|
|
|
for (const key in parsedQueryString) {
|
|
const value = parsedQueryString[key];
|
|
if (Array.isArray(value)) {
|
|
data[repr(key)] = value;
|
|
} else {
|
|
data[repr(key)] = repr(value);
|
|
}
|
|
}
|
|
|
|
return { data: data };
|
|
}
|
|
|
|
function getFilesString(request) {
|
|
const data = {};
|
|
|
|
data.data = {};
|
|
|
|
if (request.isDataBinary) {
|
|
let filePath = '';
|
|
|
|
if (request.data.startsWith('@')) {
|
|
filePath = request.data.slice(1);
|
|
} else {
|
|
filePath = request.data;
|
|
}
|
|
|
|
data.data = [
|
|
{
|
|
filePath: repr(filePath),
|
|
contentType: request.headers['Content-Type'],
|
|
selected: true,
|
|
}
|
|
];
|
|
|
|
return data;
|
|
}
|
|
|
|
data.files = {};
|
|
|
|
for (const multipartKey in request.multipartUploads) {
|
|
const multipartValue = request.multipartUploads[multipartKey];
|
|
if (multipartValue.startsWith('@')) {
|
|
const fileName = multipartValue.slice(1);
|
|
data.files[repr(multipartKey)] = repr(fileName);
|
|
} else {
|
|
data.data[repr(multipartKey)] = repr(multipartValue);
|
|
}
|
|
}
|
|
|
|
if (Object.keys(data.files).length === 0) {
|
|
delete data.files;
|
|
}
|
|
|
|
if (Object.keys(data.data).length === 0) {
|
|
delete data.data;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
const curlToJson = (curlCommand) => {
|
|
const request = parseCurlCommand(curlCommand);
|
|
|
|
const requestJson = {};
|
|
|
|
// curl automatically prepends 'http' if the scheme is missing, but python fails and returns an error
|
|
// we tack it on here to mimic curl
|
|
if (!request.url.match(/https?:/)) {
|
|
request.url = 'http://' + request.url;
|
|
}
|
|
if (!request.urlWithoutQuery.match(/https?:/)) {
|
|
request.urlWithoutQuery = 'http://' + request.urlWithoutQuery;
|
|
}
|
|
|
|
requestJson.url = request.urlWithoutQuery;
|
|
requestJson.raw_url = request.url;
|
|
requestJson.method = request.method;
|
|
requestJson.isDataBinary = request.isDataBinary;
|
|
|
|
if (request.cookies) {
|
|
const cookies = {};
|
|
for (const cookieName in request.cookies) {
|
|
cookies[repr(cookieName)] = repr(request.cookies[cookieName]);
|
|
}
|
|
|
|
requestJson.cookies = cookies;
|
|
}
|
|
|
|
if (request.headers) {
|
|
const headers = {};
|
|
for (const headerName in request.headers) {
|
|
headers[repr(headerName)] = repr(request.headers[headerName]);
|
|
}
|
|
|
|
requestJson.headers = headers;
|
|
}
|
|
|
|
if (request.query) {
|
|
requestJson.queries = getQueries(request);
|
|
} else if (request.multipartUploads || request.isDataBinary) {
|
|
Object.assign(requestJson, getFilesString(request));
|
|
} else if (typeof request.data === 'string' || typeof request.data === 'number') {
|
|
Object.assign(requestJson, getDataString(request));
|
|
}
|
|
|
|
if (request.insecure) {
|
|
requestJson.insecure = false;
|
|
}
|
|
|
|
if (request.auth) {
|
|
if (request.auth.mode === 'basic') {
|
|
requestJson.auth = {
|
|
mode: 'basic',
|
|
basic: {
|
|
username: repr(request.auth.basic?.username),
|
|
password: repr(request.auth.basic?.password)
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
return Object.keys(requestJson).length ? requestJson : {};
|
|
};
|
|
|
|
export default curlToJson;
|