diff --git a/packages/bruno-app/src/components/RequestPane/QueryParams/index.js b/packages/bruno-app/src/components/RequestPane/QueryParams/index.js index a1099f4fd..c190c30dc 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryParams/index.js +++ b/packages/bruno-app/src/components/RequestPane/QueryParams/index.js @@ -18,6 +18,7 @@ import { saveRequest, sendRequest } from 'providers/ReduxStore/slices/collection import StyledWrapper from './StyledWrapper'; import Table from 'components/Table/index'; import ReorderTable from 'components/ReorderTable'; +import MultiLineEditor from 'components/MultiLineEditor/index'; const QueryParams = ({ item, collection }) => { const dispatch = useDispatch(); @@ -142,14 +143,16 @@ const QueryParams = ({ item, collection }) => { /> - handleQueryParamChange({ target: { value: newValue } }, param, 'value')} onRun={handleRun} + allowNewlines={true} collection={collection} variablesAutocomplete={true} + item={item} /> diff --git a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js index f6d4ff308..ad11ac94e 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js +++ b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js @@ -11,6 +11,7 @@ import { isMacOS } from 'utils/common/platform'; import StyledWrapper from './StyledWrapper'; import GenerateCodeItem from 'components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/index'; import toast from 'react-hot-toast'; +import { escapeNewlines, unescapeNewlines } from 'utils/url/index'; const QueryUrl = ({ item, collection, handleRun }) => { const { theme, storedTheme } = useTheme(); @@ -35,6 +36,7 @@ const QueryUrl = ({ item, collection, handleRun }) => { const onUrlChange = (value) => { if (!editorRef.current?.editor) return; + value = unescapeNewlines(value); const editor = editorRef.current.editor; const cursor = editor.getCursor(); @@ -92,7 +94,7 @@ const QueryUrl = ({ item, collection, handleRun }) => { > onSave(finalValue)} theme={storedTheme} onChange={(newValue) => onUrlChange(newValue)} diff --git a/packages/bruno-app/src/utils/url/index.js b/packages/bruno-app/src/utils/url/index.js index 8785df00b..326bd2a26 100644 --- a/packages/bruno-app/src/utils/url/index.js +++ b/packages/bruno-app/src/utils/url/index.js @@ -156,3 +156,12 @@ export const interpolateUrlPathParams = (url, params) => { return `${uri.origin}${basePath}${uri?.search || ''}`; }; + + +export const escapeNewlines = (str = '') => { + return str?.replace(/\n/g, '\\n') +} + +export const unescapeNewlines = (str = '') => { + return str?.replace(/\\n/g, '\n'); +} \ No newline at end of file diff --git a/packages/bruno-lang/v1/src/utils.js b/packages/bruno-lang/v1/src/utils.js index 74b22c952..c691379a4 100644 --- a/packages/bruno-lang/v1/src/utils.js +++ b/packages/bruno-lang/v1/src/utils.js @@ -29,8 +29,18 @@ const outdentString = (str) => { .join('\n'); }; +const escapeNewlines = (str = '') => { + return str?.replace(/\n/g, '\\n') +} + +const unescapeNewlines = (str = '') => { + return str?.replace(/\\n/g, '\n'); +} + module.exports = { safeParseJson, indentString, - outdentString + outdentString, + escapeNewlines, + unescapeNewlines }; diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index 84890c92f..e184b92d3 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -1,6 +1,6 @@ const ohm = require('ohm-js'); const _ = require('lodash'); -const { outdentString } = require('../../v1/src/utils'); +const { outdentString, unescapeNewlines } = require('../../v1/src/utils'); /** * A Bru file is made up of blocks. @@ -187,6 +187,14 @@ const mapPairListToKeyValPair = (pairList = []) => { return _.merge({}, ...pairList[0]); }; +const mapHttpPairListToKeyValPair = (pairList = []) => { + const { url, ...rest } = mapPairListToKeyValPair(pairList); + return { + url: unescapeNewlines(url), + ...rest + } +}; + const sem = grammar.createSemantics().addAttribute('ast', { BruFile(tags) { if (!tags || !tags.ast || !tags.ast.length) { @@ -285,7 +293,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'get', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, @@ -293,7 +301,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'post', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, @@ -301,7 +309,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'put', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, @@ -309,7 +317,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'delete', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, @@ -317,7 +325,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'patch', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, @@ -325,7 +333,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'options', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, @@ -333,7 +341,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'head', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, @@ -341,7 +349,7 @@ const sem = grammar.createSemantics().addAttribute('ast', { return { http: { method: 'connect', - ...mapPairListToKeyValPair(dictionary.ast) + ...mapHttpPairListToKeyValPair(dictionary.ast) } }; }, diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index 30bec13ef..74f969852 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -1,6 +1,6 @@ const _ = require('lodash'); -const { indentString } = require('../../v1/src/utils'); +const { indentString, escapeNewlines } = require('../../v1/src/utils'); const enabled = (items = []) => items.filter((item) => item.enabled); const disabled = (items = []) => items.filter((item) => !item.enabled); @@ -44,7 +44,7 @@ const jsonToBru = (json) => { if (http && http.method) { bru += `${http.method} { - url: ${http.url}`; + url: ${escapeNewlines(http.url)}`; if (http.body && http.body.length) { bru += ` @@ -71,7 +71,7 @@ const jsonToBru = (json) => { if (enabled(queryParams).length) { bru += `\n${indentString( enabled(queryParams) - .map((item) => `${item.name}: ${item.value}`) + .map((item) => `${item.name}: ${getValueString(item.value)}`) .join('\n') )}`; } @@ -79,7 +79,7 @@ const jsonToBru = (json) => { if (disabled(queryParams).length) { bru += `\n${indentString( disabled(queryParams) - .map((item) => `~${item.name}: ${item.value}`) + .map((item) => `~${item.name}: ${getValueString(item.value)}`) .join('\n') )}`; }