diff --git a/packages/bruno-app/src/components/RequestPane/RequestBody/RequestBodyMode/index.js b/packages/bruno-app/src/components/RequestPane/RequestBody/RequestBodyMode/index.js index 1d33d9b70..a378e65e8 100644 --- a/packages/bruno-app/src/components/RequestPane/RequestBody/RequestBodyMode/index.js +++ b/packages/bruno-app/src/components/RequestPane/RequestBody/RequestBodyMode/index.js @@ -8,7 +8,7 @@ import { humanizeRequestBodyMode } from 'utils/collections'; import StyledWrapper from './StyledWrapper'; import { updateRequestBody } from 'providers/ReduxStore/slices/collections/index'; import { toastError } from 'utils/common/error'; -import { format, applyEdits } from 'jsonc-parser'; +import { prettifyJSON } from 'utils/common'; import xmlFormat from 'xml-formatter'; const RequestBodyMode = ({ item, collection }) => { @@ -39,8 +39,7 @@ const RequestBodyMode = ({ item, collection }) => { const onPrettify = () => { if (body?.json && bodyMode === 'json') { try { - const edits = format(body.json, undefined, { tabSize: 2, insertSpaces: true }); - const prettyBodyJson = applyEdits(body.json, edits); + const prettyBodyJson = prettifyJSON(body.json); dispatch( updateRequestBody({ content: prettyBodyJson, diff --git a/packages/bruno-app/src/utils/common/index.js b/packages/bruno-app/src/utils/common/index.js index 1c647ae28..6f00eca02 100644 --- a/packages/bruno-app/src/utils/common/index.js +++ b/packages/bruno-app/src/utils/common/index.js @@ -54,10 +54,27 @@ export const safeStringifyJSON = (obj, indent = false) => { export const prettifyJSON = (obj, spaces = 2) => { try { - const formatted = obj.replace(/\\"/g, '"').replace(/\\'/g, "'"); - const edits = format(formatted, undefined, { tabSize: spaces, insertSpaces: true }); + const text = obj.replace(/\\"/g, '"').replace(/\\'/g, "'"); - return applyEdits(formatted, edits); + const placeholders = []; + const modifiedJson = text.replace(/"[^"]*?"|{{[^{}]+}}/g, (match) => { + if (match.startsWith('{{')) { + const placeholder = `__BRUNO_VAR_PLACEHOLDER_${placeholders.length}__`; + placeholders.push(match); + return `"${placeholder}"`; // Wrap bare variable in quotes to make it a valid JSON string + } + return match; + }); + + const edits = format(modifiedJson, undefined, { tabSize: spaces, insertSpaces: true }); + let result = applyEdits(modifiedJson, edits); + + for (let i = 0; i < placeholders.length; i++) { + const placeholder = `__BRUNO_VAR_PLACEHOLDER_${i}__`; + result = result.replace(`"${placeholder}"`, placeholders[i]); + } + + return result; } catch (e) { return obj; } diff --git a/packages/bruno-app/src/utils/common/index.spec.js b/packages/bruno-app/src/utils/common/index.spec.js index 89eeebf2e..0b56d89f1 100644 --- a/packages/bruno-app/src/utils/common/index.spec.js +++ b/packages/bruno-app/src/utils/common/index.spec.js @@ -1,6 +1,14 @@ const { describe, it, expect } = require('@jest/globals'); -import { normalizeFileName, startsWith, humanizeDate, relativeDate, getContentType, formatSize } from './index'; +import { + normalizeFileName, + startsWith, + humanizeDate, + relativeDate, + getContentType, + formatSize, + prettifyJSON +} from './index'; describe('common utils', () => { describe('normalizeFileName', () => { @@ -184,4 +192,30 @@ describe('common utils', () => { expect(formatSize(NaN)).toBe('0B'); }); }); + + describe('prettifyJSON', () => { + it('should prettify a standard JSON string', () => { + const input = '{"key":"value","number":123}'; + const expected = '{\n "key": "value",\n "number": 123\n}'; + expect(prettifyJSON(input)).toBe(expected); + }); + + it('should handle JSON with a Bruno variable as a value', () => { + const input = '{"id":{{request_id}}}'; + const expected = '{\n "id": {{request_id}}\n}'; + expect(prettifyJSON(input)).toBe(expected); + }); + + it('should handle JSON with a Bruno variable inside a string value', () => { + const input = '{"url":"https://example.com/{{path}}"}'; + const expected = '{\n "url": "https://example.com/{{path}}"\n}'; + expect(prettifyJSON(input)).toBe(expected); + }); + + it('should return the original string for invalid JSON', () => { + const input = '{"key":"value",'; + const expected = '{\n "key": "value",'; + expect(prettifyJSON(input)).toBe(expected); + }); + }); });