mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-24 21:25:45 +00:00
Merge pull request #6083 from dawidgora/bugfix/5939_curl-import-fails-for-custom-content-types
bugfix(#5939): curl import fails for custom content-types
This commit is contained in:
29
packages/bruno-app/src/utils/curl/content-type.js
Normal file
29
packages/bruno-app/src/utils/curl/content-type.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const normalizeContentType = (contentType) => {
|
||||
if (!contentType || typeof contentType !== 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return contentType.toLowerCase();
|
||||
};
|
||||
|
||||
export const isJsonLikeContentType = (contentType) => {
|
||||
const normalized = normalizeContentType(contentType);
|
||||
|
||||
return normalized.includes('application/json') || normalized.includes('+json');
|
||||
};
|
||||
|
||||
export const isXmlLikeContentType = (contentType) => {
|
||||
const normalized = normalizeContentType(contentType);
|
||||
|
||||
return normalized.includes('application/xml') || normalized.includes('+xml') || normalized.includes('text/xml');
|
||||
};
|
||||
|
||||
export const isPlainTextContentType = (contentType) => {
|
||||
const normalized = normalizeContentType(contentType);
|
||||
|
||||
return normalized.includes('text/plain');
|
||||
};
|
||||
|
||||
export const isStructuredContentType = (contentType) => {
|
||||
return isJsonLikeContentType(contentType) || isXmlLikeContentType(contentType) || isPlainTextContentType(contentType);
|
||||
};
|
||||
@@ -10,6 +10,7 @@ import parseCurlCommand from './parse-curl';
|
||||
import * as querystring from 'query-string';
|
||||
import * as jsesc from 'jsesc';
|
||||
import { buildQueryString } from '@usebruno/common/utils';
|
||||
import { isStructuredContentType } from './content-type';
|
||||
|
||||
function getContentType(headers = {}) {
|
||||
const contentType = Object.keys(headers).find((key) => key.toLowerCase() === 'content-type');
|
||||
@@ -34,7 +35,7 @@ function getDataString(request) {
|
||||
|
||||
const contentType = getContentType(request.headers);
|
||||
|
||||
if (contentType && (contentType.includes('application/json') || contentType.includes('application/xml') || contentType.includes('text/plain'))) {
|
||||
if (isStructuredContentType(contentType)) {
|
||||
return { data: request.data };
|
||||
}
|
||||
|
||||
|
||||
@@ -120,4 +120,37 @@ describe('curlToJson', () => {
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse custom json content-types', () => {
|
||||
const curlCommand = `curl 'https://api.example.com/test'
|
||||
-H 'content-type: application/x.custom+json;version=1'
|
||||
--data-raw '{"test":"data"}'
|
||||
`;
|
||||
|
||||
const result = curlToJson(curlCommand);
|
||||
|
||||
expect(result).toEqual({
|
||||
url: 'https://api.example.com/test',
|
||||
raw_url: 'https://api.example.com/test',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'content-type': 'application/x.custom+json;version=1'
|
||||
},
|
||||
data: '{"test":"data"}'
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse vendor tree json content-types', () => {
|
||||
const curlCommand = `curl --request POST \\
|
||||
--url https://api.example.com/orders/42/preferences \\
|
||||
--header 'accept: */*' \\
|
||||
--header 'content-type: application/vnd.vendor+json' \\
|
||||
--data '{\\n "data": {\\n "type": "order-preferences",\\n "attributes": {\\n "notes": "Leave at door",\\n "priority": true\\n }\\n }\\n}'`;
|
||||
|
||||
const result = curlToJson(curlCommand);
|
||||
expect(result.data).toContain('"type": "order-preferences"');
|
||||
expect(result.data).toContain('"notes": "Leave at door"');
|
||||
expect(result.data).toContain('"priority": true');
|
||||
expect(result.headers['content-type']).toBe('application/vnd.vendor+json');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { forOwn } from 'lodash';
|
||||
import curlToJson from './curl-to-json';
|
||||
import { prettifyJsonString } from 'utils/common/index';
|
||||
import { isJsonLikeContentType, isPlainTextContentType, isXmlLikeContentType } from './content-type';
|
||||
|
||||
export const getRequestFromCurlCommand = (curlCommand, requestType = 'http-request') => {
|
||||
const parseFormData = (parsedBody) => {
|
||||
@@ -59,25 +60,27 @@ export const getRequestFromCurlCommand = (curlCommand, requestType = 'http-reque
|
||||
};
|
||||
|
||||
if (parsedBody && contentType && typeof contentType === 'string') {
|
||||
if (requestType === 'graphql-request' && (contentType.includes('application/json') || contentType.includes('application/graphql'))) {
|
||||
const normalizedContentType = contentType.toLowerCase();
|
||||
|
||||
if (requestType === 'graphql-request' && (isJsonLikeContentType(contentType) || normalizedContentType.includes('application/graphql'))) {
|
||||
body.mode = 'graphql';
|
||||
body.graphql = parseGraphQL(parsedBody);
|
||||
} else if (requestType === 'http-request' && request.isDataBinary) {
|
||||
body.mode = 'file';
|
||||
body.file = parsedBody;
|
||||
}else if (contentType.includes('application/json')) {
|
||||
} else if (isJsonLikeContentType(contentType)) {
|
||||
body.mode = 'json';
|
||||
body.json = prettifyJsonString(parsedBody);
|
||||
} else if (contentType.includes('xml')) {
|
||||
} else if (isXmlLikeContentType(contentType) || normalizedContentType.includes('xml')) {
|
||||
body.mode = 'xml';
|
||||
body.xml = parsedBody;
|
||||
} else if (contentType.includes('application/x-www-form-urlencoded')) {
|
||||
} else if (normalizedContentType.includes('application/x-www-form-urlencoded')) {
|
||||
body.mode = 'formUrlEncoded';
|
||||
body.formUrlEncoded = parseFormData(parsedBody);
|
||||
} else if (contentType.includes('multipart/form-data')) {
|
||||
} else if (normalizedContentType.includes('multipart/form-data')) {
|
||||
body.mode = 'multipartForm';
|
||||
body.multipartForm = parsedBody;
|
||||
} else if (contentType.includes('text/plain')) {
|
||||
} else if (isPlainTextContentType(contentType)) {
|
||||
body.mode = 'text';
|
||||
body.text = parsedBody;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user