diff --git a/packages/bruno-app/src/components/RequestTabPanel/index.js b/packages/bruno-app/src/components/RequestTabPanel/index.js
index 51d3194be..346a64aff 100644
--- a/packages/bruno-app/src/components/RequestTabPanel/index.js
+++ b/packages/bruno-app/src/components/RequestTabPanel/index.js
@@ -20,6 +20,8 @@ import { DocExplorer } from '@usebruno/graphql-docs';
import StyledWrapper from './StyledWrapper';
import SecuritySettings from 'components/SecuritySettings';
import FolderSettings from 'components/FolderSettings';
+import { getGlobalEnvironmentVariables } from 'utils/collections/index';
+import { cloneDeep } from 'lodash';
const MIN_LEFT_PANE_WIDTH = 300;
const MIN_RIGHT_PANE_WIDTH = 350;
@@ -34,6 +36,7 @@ const RequestTabPanel = () => {
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const collections = useSelector((state) => state.collections.collections);
const screenWidth = useSelector((state) => state.app.screenWidth);
+ const { globalEnvironments, activeGlobalEnvironmentUid } = useSelector((state) => state.globalEnvironments);
let asideWidth = useSelector((state) => state.app.leftSidebarWidth);
const focusedTab = find(tabs, (t) => t.uid === activeTabUid);
@@ -117,7 +120,14 @@ const RequestTabPanel = () => {
return
An error occurred!
;
}
- let collection = find(collections, (c) => c.uid === focusedTab.collectionUid);
+ let _collection = find(collections, (c) => c.uid === focusedTab.collectionUid);
+ let collection = cloneDeep(_collection);
+
+ // add selected global env variables to the collection object
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ collection.globalEnvironmentVariables = globalEnvironmentVariables;
+
+
if (!collection || !collection.uid) {
return Collection not found!
;
}
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js
index 9d5648907..28f68a5a7 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js
@@ -8,19 +8,24 @@ import { useSelector } from 'react-redux';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import toast from 'react-hot-toast';
import { IconCopy } from '@tabler/icons';
-import { findCollectionByItemUid } from '../../../../../../../utils/collections/index';
+import { findCollectionByItemUid, getGlobalEnvironmentVariables } from '../../../../../../../utils/collections/index';
import { getAuthHeaders } from '../../../../../../../utils/codegenerator/auth';
const CodeView = ({ language, item }) => {
const { displayedTheme } = useTheme();
const preferences = useSelector((state) => state.app.preferences);
+ const { globalEnvironments, activeGlobalEnvironmentUid } = useSelector((state) => state.globalEnvironments);
const { target, client, language: lang } = language;
const requestHeaders = item.draft ? get(item, 'draft.request.headers') : get(item, 'request.headers');
- const collection = findCollectionByItemUid(
+ let collection = findCollectionByItemUid(
useSelector((state) => state.collections.collections),
item.uid
);
+ // add selected global env variables to the collection object
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ collection.globalEnvironmentVariables = globalEnvironmentVariables;
+
const collectionRootAuth = collection?.root?.request?.auth;
const requestAuth = item.draft ? get(item, 'draft.request.auth') : get(item, 'request.auth');
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
index 777a194ab..4e83b89df 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
@@ -44,6 +44,7 @@ import { parsePathParams, parseQueryParams, splitOnFirst } from 'utils/url/index
import { sendCollectionOauth2Request as _sendCollectionOauth2Request } from 'utils/network/index';
import { name } from 'file-loader';
import slash from 'utils/common/slash';
+import { getGlobalEnvironmentVariables } from 'utils/collections/index';
export const renameCollection = (newName, collectionUid) => (dispatch, getState) => {
const state = getState();
@@ -183,6 +184,7 @@ export const saveFolderRoot = (collectionUid, folderUid) => (dispatch, getState)
export const sendCollectionOauth2Request = (collectionUid, itemUid) => (dispatch, getState) => {
const state = getState();
+ const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
@@ -190,7 +192,11 @@ export const sendCollectionOauth2Request = (collectionUid, itemUid) => (dispatch
return reject(new Error('Collection not found'));
}
- const collectionCopy = cloneDeep(collection);
+ let collectionCopy = cloneDeep(collection);
+
+ // add selected global env variables to the collection object
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ collectionCopy.globalEnvironmentVariables = globalEnvironmentVariables;
const environment = findEnvironmentInCollection(collectionCopy, collection.activeEnvironmentUid);
@@ -212,6 +218,7 @@ export const sendCollectionOauth2Request = (collectionUid, itemUid) => (dispatch
export const sendRequest = (item, collectionUid) => (dispatch, getState) => {
const state = getState();
+ const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
@@ -220,7 +227,11 @@ export const sendRequest = (item, collectionUid) => (dispatch, getState) => {
}
const itemCopy = cloneDeep(item || {});
- const collectionCopy = cloneDeep(collection);
+ let collectionCopy = cloneDeep(collection);
+
+ // add selected global env variables to the collection object
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ collectionCopy.globalEnvironmentVariables = globalEnvironmentVariables;
const environment = findEnvironmentInCollection(collectionCopy, collectionCopy.activeEnvironmentUid);
sendNetworkRequest(itemCopy, collectionCopy, environment, collectionCopy.runtimeVariables)
@@ -285,6 +296,7 @@ export const cancelRunnerExecution = (cancelTokenUid) => (dispatch) => {
export const runCollectionFolder = (collectionUid, folderUid, recursive, delay) => (dispatch, getState) => {
const state = getState();
+ const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
@@ -292,7 +304,12 @@ export const runCollectionFolder = (collectionUid, folderUid, recursive, delay)
return reject(new Error('Collection not found'));
}
- const collectionCopy = cloneDeep(collection);
+ let collectionCopy = cloneDeep(collection);
+
+ // add selected global env variables to the collection object
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ collectionCopy.globalEnvironmentVariables = globalEnvironmentVariables;
+
const folder = findItemInCollection(collectionCopy, folderUid);
if (folderUid && !folder) {
diff --git a/packages/bruno-app/src/utils/collections/index.js b/packages/bruno-app/src/utils/collections/index.js
index 2b2c7d13b..c39a097fb 100644
--- a/packages/bruno-app/src/utils/collections/index.js
+++ b/packages/bruno-app/src/utils/collections/index.js
@@ -782,6 +782,19 @@ export const getDefaultRequestPaneTab = (item) => {
}
};
+export const getGlobalEnvironmentVariables = ({ globalEnvironments, activeGlobalEnvironmentUid }) => {
+ let variables = {};
+ const environment = globalEnvironments?.find(env => env?.uid === activeGlobalEnvironmentUid);
+ if (environment) {
+ each(environment.variables, (variable) => {
+ if (variable.name && variable.value && variable.enabled) {
+ variables[variable.name] = variable.value;
+ }
+ });
+ }
+ return variables;
+};
+
export const getEnvironmentVariables = (collection) => {
let variables = {};
if (collection) {
@@ -798,6 +811,7 @@ export const getEnvironmentVariables = (collection) => {
return variables;
};
+
const getPathParams = (item) => {
let pathParams = {};
if (item && item.request && item.request.params) {
@@ -829,10 +843,12 @@ export const getAllVariables = (collection, item) => {
const requestTreePath = getTreePathFromCollectionToItem(collection, item);
let { collectionVariables, folderVariables, requestVariables } = mergeVars(collection, requestTreePath);
const pathParams = getPathParams(item);
+ const { globalEnvironmentVariables = {} } = collection;
const { processEnvVariables = {}, runtimeVariables = {} } = collection;
return {
+ ...globalEnvironmentVariables,
...collectionVariables,
...envVariables,
...folderVariables,
diff --git a/packages/bruno-electron/src/ipc/network/interpolate-vars.js b/packages/bruno-electron/src/ipc/network/interpolate-vars.js
index 5ea2bf7f4..70150130a 100644
--- a/packages/bruno-electron/src/ipc/network/interpolate-vars.js
+++ b/packages/bruno-electron/src/ipc/network/interpolate-vars.js
@@ -14,6 +14,7 @@ const getContentType = (headers = {}) => {
};
const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, processEnvVars = {}) => {
+ const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
const collectionVariables = request?.collectionVariables || {};
const folderVariables = request?.folderVariables || {};
const requestVariables = request?.requestVariables || {};
@@ -39,6 +40,7 @@ const interpolateVars = (request, envVariables = {}, runtimeVariables = {}, proc
// runtimeVariables take precedence over envVars
const combinedVars = {
+ ...globalEnvironmentVariables,
...collectionVariables,
...envVariables,
...folderVariables,
diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js
index 0bac42af9..1ba52895a 100644
--- a/packages/bruno-electron/src/ipc/network/prepare-request.js
+++ b/packages/bruno-electron/src/ipc/network/prepare-request.js
@@ -370,6 +370,7 @@ const prepareRequest = (item, collection) => {
mergeFolderLevelHeaders(request, requestTreePath);
mergeFolderLevelScripts(request, requestTreePath, scriptFlow);
mergeVars(collection, request, requestTreePath);
+ request.globalEnvironmentVariables = collection?.globalEnvironmentVariables;
}
// Request level headers
@@ -461,6 +462,7 @@ const prepareRequest = (item, collection) => {
axiosRequest.collectionVariables = request.collectionVariables;
axiosRequest.folderVariables = request.folderVariables;
axiosRequest.requestVariables = request.requestVariables;
+ axiosRequest.globalEnvironmentVariables = request.globalEnvironmentVariables;
axiosRequest.assertions = request.assertions;
return axiosRequest;
diff --git a/packages/bruno-js/src/bru.js b/packages/bruno-js/src/bru.js
index 7f24cea14..46c6231ba 100644
--- a/packages/bruno-js/src/bru.js
+++ b/packages/bruno-js/src/bru.js
@@ -4,13 +4,14 @@ const { interpolate } = require('@usebruno/common');
const variableNameRegex = /^[\w-.]*$/;
class Bru {
- constructor(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables) {
+ constructor(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables) {
this.envVariables = envVariables || {};
this.runtimeVariables = runtimeVariables || {};
this.processEnvVars = cloneDeep(processEnvVars || {});
this.collectionVariables = collectionVariables || {};
this.folderVariables = folderVariables || {};
this.requestVariables = requestVariables || {};
+ this.globalEnvironmentVariables = globalEnvironmentVariables || {};
this.collectionPath = collectionPath;
}
@@ -20,6 +21,7 @@ class Bru {
}
const combinedVars = {
+ ...this.globalEnvironmentVariables,
...this.collectionVariables,
...this.envVariables,
...this.folderVariables,
@@ -63,6 +65,18 @@ class Bru {
this.envVariables[key] = value;
}
+ getGlobalEnvVar(key) {
+ return this._interpolate(this.globalEnvironmentVariables[key]);
+ }
+
+ setGlobalEnvVar(key, value) {
+ if (!key) {
+ throw new Error('Creating a env variable without specifying a name is not allowed.');
+ }
+
+ this.globalEnvironmentVariables[key] = value;
+ }
+
hasVar(key) {
return Object.hasOwn(this.runtimeVariables, key);
}
diff --git a/packages/bruno-js/src/interpolate-string.js b/packages/bruno-js/src/interpolate-string.js
index 2692641c2..f75daf57c 100644
--- a/packages/bruno-js/src/interpolate-string.js
+++ b/packages/bruno-js/src/interpolate-string.js
@@ -2,13 +2,14 @@ const { interpolate } = require('@usebruno/common');
const interpolateString = (
str,
- { envVariables = {}, runtimeVariables = {}, processEnvVars = {}, collectionVariables = {}, folderVariables = {}, requestVariables = {} }
+ { envVariables = {}, runtimeVariables = {}, processEnvVars = {}, collectionVariables = {}, folderVariables = {}, requestVariables = {}, globalEnvironmentVariables = {} }
) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
const combinedVars = {
+ ...globalEnvironmentVariables,
...collectionVariables,
...envVariables,
...folderVariables,
diff --git a/packages/bruno-js/src/runtime/assert-runtime.js b/packages/bruno-js/src/runtime/assert-runtime.js
index aafacfe8a..b338730cc 100644
--- a/packages/bruno-js/src/runtime/assert-runtime.js
+++ b/packages/bruno-js/src/runtime/assert-runtime.js
@@ -192,6 +192,7 @@ const evaluateRhsOperand = (rhsOperand, operator, context, runtime) => {
}
const interpolationContext = {
+ globalEnvironmentVariables: context.bru.globalEnvironmentVariables,
collectionVariables: context.bru.collectionVariables,
folderVariables: context.bru.folderVariables,
requestVariables: context.bru.requestVariables,
@@ -240,6 +241,7 @@ class AssertRuntime {
}
runAssertions(assertions, request, response, envVariables, runtimeVariables, processEnvVars) {
+ const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
const collectionVariables = request?.collectionVariables || {};
const folderVariables = request?.folderVariables || {};
const requestVariables = request?.requestVariables || {};
@@ -255,7 +257,8 @@ class AssertRuntime {
undefined,
collectionVariables,
folderVariables,
- requestVariables
+ requestVariables,
+ globalEnvironmentVariables
);
const req = new BrunoRequest(request);
const res = createResponseParser(response);
@@ -267,6 +270,7 @@ class AssertRuntime {
};
const context = {
+ ...globalEnvironmentVariables,
...collectionVariables,
...envVariables,
...folderVariables,
diff --git a/packages/bruno-js/src/runtime/script-runtime.js b/packages/bruno-js/src/runtime/script-runtime.js
index 9dc47a29d..cdccfc4a7 100644
--- a/packages/bruno-js/src/runtime/script-runtime.js
+++ b/packages/bruno-js/src/runtime/script-runtime.js
@@ -47,10 +47,11 @@ class ScriptRuntime {
processEnvVars,
scriptingConfig
) {
+ const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
const collectionVariables = request?.collectionVariables || {};
const folderVariables = request?.folderVariables || {};
const requestVariables = request?.requestVariables || {};
- const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables);
+ const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables);
const req = new BrunoRequest(request);
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
const moduleWhitelist = get(scriptingConfig, 'moduleWhitelist', []);
@@ -164,10 +165,11 @@ class ScriptRuntime {
processEnvVars,
scriptingConfig
) {
+ const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
const collectionVariables = request?.collectionVariables || {};
const folderVariables = request?.folderVariables || {};
const requestVariables = request?.requestVariables || {};
- const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables);
+ const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables);
const req = new BrunoRequest(request);
const res = new BrunoResponse(response);
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);
diff --git a/packages/bruno-js/src/runtime/test-runtime.js b/packages/bruno-js/src/runtime/test-runtime.js
index 53fab05eb..8cd118df2 100644
--- a/packages/bruno-js/src/runtime/test-runtime.js
+++ b/packages/bruno-js/src/runtime/test-runtime.js
@@ -48,10 +48,11 @@ class TestRuntime {
processEnvVars,
scriptingConfig
) {
+ const globalEnvironmentVariables = request?.globalEnvironmentVariables || {};
const collectionVariables = request?.collectionVariables || {};
const folderVariables = request?.folderVariables || {};
const requestVariables = request?.requestVariables || {};
- const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables);
+ const bru = new Bru(envVariables, runtimeVariables, processEnvVars, collectionPath, collectionVariables, folderVariables, requestVariables, globalEnvironmentVariables);
const req = new BrunoRequest(request);
const res = new BrunoResponse(response);
const allowScriptFilesystemAccess = get(scriptingConfig, 'filesystemAccess.allow', false);