diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js index e6d6f94a8..4093dfcf9 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js @@ -3,10 +3,12 @@ import CodeEditor from 'components/CodeEditor'; import { useTheme } from 'providers/Theme'; import { useDispatch } from 'react-redux'; import { sendRequest } from 'providers/ReduxStore/slices/collections/actions'; +import { getContentType, safeStringifyJSON, safeParseXML } from 'utils/common'; +import { getCodeMirrorModeBasedOnContentType } from 'utils/common/codemirror'; import StyledWrapper from './StyledWrapper'; -const QueryResult = ({ item, collection, value, width, disableRunEventListener, mode }) => { +const QueryResult = ({ item, collection, data, width, disableRunEventListener, headers }) => { const { storedTheme } = useTheme(); const dispatch = useDispatch(); @@ -17,17 +19,50 @@ const QueryResult = ({ item, collection, value, width, disableRunEventListener, dispatch(sendRequest(item, collection.uid)); }; + const contentType = getContentType(headers); + const mode = getCodeMirrorModeBasedOnContentType(contentType); + + const formatResponse = (data, mode) => { + if (!data) { + return ''; + } + + if (mode.includes('json')) { + return safeStringifyJSON(data, true); + } + + if (mode.includes('xml')) { + let parsed = safeParseXML(data, { collapseContent: true }); + + if (typeof parsed === 'string') { + return parsed; + } + + return safeStringifyJSON(parsed, true); + } + + if (['text', 'html'].includes(mode)) { + if (typeof data === 'string') { + return data; + } + + return safeStringifyJSON(data); + } + + // final fallback + if (typeof data === 'string') { + return data; + } + + return safeStringifyJSON(data); + }; + + const value = formatResponse(data, mode); + return (
- +
); diff --git a/packages/bruno-app/src/components/ResponsePane/index.js b/packages/bruno-app/src/components/ResponsePane/index.js index c8e071625..0b56840fa 100644 --- a/packages/bruno-app/src/components/ResponsePane/index.js +++ b/packages/bruno-app/src/components/ResponsePane/index.js @@ -2,7 +2,6 @@ import React from 'react'; import find from 'lodash/find'; import classnames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; -import { getContentType, formatResponse } from 'utils/common'; import { updateResponsePaneTab } from 'providers/ReduxStore/slices/tabs'; import QueryResult from './QueryResult'; import Overlay from './Overlay'; @@ -41,8 +40,8 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => { item={item} collection={collection} width={rightPaneWidth} - value={response.data ? formatResponse(response) : ''} - mode={getContentType(response.headers)} + data={response.data} + headers={response.headers} /> ); } diff --git a/packages/bruno-app/src/components/RunnerResults/ResponsePane/index.js b/packages/bruno-app/src/components/RunnerResults/ResponsePane/index.js index ba87fcaf9..2c4f28b20 100644 --- a/packages/bruno-app/src/components/RunnerResults/ResponsePane/index.js +++ b/packages/bruno-app/src/components/RunnerResults/ResponsePane/index.js @@ -33,7 +33,8 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => { collection={collection} width={rightPaneWidth} disableRunEventListener={true} - value={responseReceived && responseReceived.data ? safeStringifyJSON(responseReceived.data, true) : ''} + data={responseReceived.data} + headers={responseReceived.headers} /> ); } diff --git a/packages/bruno-app/src/utils/common/codemirror.js b/packages/bruno-app/src/utils/common/codemirror.js index b1b60568c..aa4ba0519 100644 --- a/packages/bruno-app/src/utils/common/codemirror.js +++ b/packages/bruno-app/src/utils/common/codemirror.js @@ -42,3 +42,25 @@ export const defineCodeMirrorBrunoVariablesMode = (variables, mode) => { return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || mode), variablesOverlay); }); }; + +export const getCodeMirrorModeBasedOnContentType = (contentType) => { + if (!contentType || typeof contentType !== 'string') { + return 'application/text'; + } + + if (contentType.includes('json')) { + return 'application/ld+json'; + } else if (contentType.includes('xml')) { + return 'application/xml'; + } else if (contentType.includes('html')) { + return 'application/html'; + } else if (contentType.includes('text')) { + return 'application/text'; + } else if (contentType.includes('application/edn')) { + return 'application/xml'; + } else if (mimeType.includes('yaml')) { + return 'application/yaml'; + } else { + return 'application/text'; + } +}; diff --git a/packages/bruno-app/src/utils/common/index.js b/packages/bruno-app/src/utils/common/index.js index 84725332f..c5eaa93ab 100644 --- a/packages/bruno-app/src/utils/common/index.js +++ b/packages/bruno-app/src/utils/common/index.js @@ -51,6 +51,17 @@ export const safeStringifyJSON = (obj, indent = false) => { } }; +export const safeParseXML = (str) => { + if (!str || !str.length || typeof str !== 'string') { + return str; + } + try { + return xmlFormat(str); + } catch (e) { + return str; + } +}; + // Remove any characters that are not alphanumeric, spaces, hyphens, or underscores export const normalizeFileName = (name) => { if (!name) { @@ -80,16 +91,6 @@ export const getContentType = (headers) => { return contentType[0]; } } + return ''; }; - -export const formatResponse = (response) => { - let type = getContentType(response.headers); - if (type.includes('json')) { - return safeStringifyJSON(response.data, true); - } - if (type.includes('xml')) { - return xmlFormat(response.data, { collapseContent: true }); - } - return response.data; -};