From c950806541288213e7f2712547567805a20c9b1d Mon Sep 17 00:00:00 2001 From: ramki-bruno Date: Fri, 11 Apr 2025 12:33:36 +0530 Subject: [PATCH 1/2] Fix: Falsy values from `$` built-ins are not getting interpolated. --- packages/bruno-electron/src/ipc/network/interpolate-vars.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/bruno-electron/src/ipc/network/interpolate-vars.js b/packages/bruno-electron/src/ipc/network/interpolate-vars.js index 932753fed..afa24690b 100644 --- a/packages/bruno-electron/src/ipc/network/interpolate-vars.js +++ b/packages/bruno-electron/src/ipc/network/interpolate-vars.js @@ -18,7 +18,9 @@ const interpolateMockVars = (str) => { const patternRegex = /\{\{\$(\w+)\}\}/g; return str.replace(patternRegex, (match, keyword) => { const replacement = mockDataFunctions[keyword]?.(); - return replacement || match; + + if (replacement === undefined) return match; + return String(replacement); }); }; From 6ff49589befdc6c8ca8f9016d5947667bd53577c Mon Sep 17 00:00:00 2001 From: ramki-bruno Date: Fri, 11 Apr 2025 12:34:19 +0530 Subject: [PATCH 2/2] Fix: Line-breaks in `$` built-ins are breaking JSON req body --- .../src/ipc/network/interpolate-vars.js | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/bruno-electron/src/ipc/network/interpolate-vars.js b/packages/bruno-electron/src/ipc/network/interpolate-vars.js index afa24690b..e2a5534d7 100644 --- a/packages/bruno-electron/src/ipc/network/interpolate-vars.js +++ b/packages/bruno-electron/src/ipc/network/interpolate-vars.js @@ -14,13 +14,25 @@ const getContentType = (headers = {}) => { return contentType; }; -const interpolateMockVars = (str) => { +const interpolateMockVars = (str, { escapeJSONStrings }) => { const patternRegex = /\{\{\$(\w+)\}\}/g; return str.replace(patternRegex, (match, keyword) => { - const replacement = mockDataFunctions[keyword]?.(); + let replacement = mockDataFunctions[keyword]?.(); if (replacement === undefined) return match; - return String(replacement); + replacement = String(replacement); + + if (!escapeJSONStrings) return replacement; + // All the below chars inside of a JSON String field + // will make it invalid JSON. So we will have to escape them with `\`. + // This is not exhaustive but selective to what faker-js can output. + if (!/[\\\n\r\t\"]/.test(replacement)) return replacement; + return replacement + .replace(/\\/g, '\\\\') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/\t/g, '\\t') + .replace(/\"/g, '\\"'); }); }; @@ -45,7 +57,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc }); }); - const _interpolate = (str) => { + const _interpolate = (str, { escapeJSONStrings } = {}) => { if (!str || !str.length || typeof str !== 'string') { return str; } @@ -66,7 +78,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc } }; - return interpolateMockVars(interpolate(str, combinedVars)); + return interpolateMockVars(interpolate(str, combinedVars), { escapeJSONStrings }); }; request.url = _interpolate(request.url); @@ -85,12 +97,12 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc if (contentType.includes('json') && !Buffer.isBuffer(request.data)) { if (typeof request.data === 'string') { if (request.data.length) { - request.data = _interpolate(request.data); + request.data = _interpolate(request.data, { escapeJSONStrings: true }); } } else if (typeof request.data === 'object') { try { - let parsed = JSON.stringify(request.data); - parsed = _interpolate(parsed); + const jsonDoc = JSON.stringify(request.data); + const parsed = _interpolate(jsonDoc, { escapeJSONStrings: true }); request.data = JSON.parse(parsed); } catch (err) {} }