mirror of
https://github.com/usebruno/bruno.git
synced 2025-06-26 15:01:40 +02:00
feat: collection variables
This commit is contained in:
parent
37b1c043eb
commit
6f6dedbb9c
@ -8,7 +8,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
import MD from 'markdown-it';
|
import MD from 'markdown-it';
|
||||||
import { getEnvironmentVariables } from 'utils/collections';
|
import { getAllVariables } from 'utils/collections';
|
||||||
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
|
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ export default class QueryEditor extends React.Component {
|
|||||||
mode: 'graphql',
|
mode: 'graphql',
|
||||||
// mode: 'brunovariables',
|
// mode: 'brunovariables',
|
||||||
brunoVarInfo: {
|
brunoVarInfo: {
|
||||||
variables: getEnvironmentVariables(this.props.collection),
|
variables: getAllVariables(this.props.collection),
|
||||||
},
|
},
|
||||||
theme: this.props.editorTheme || 'graphiql',
|
theme: this.props.editorTheme || 'graphiql',
|
||||||
theme: this.props.theme === 'dark' ? 'monokai' : 'default',
|
theme: this.props.theme === 'dark' ? 'monokai' : 'default',
|
||||||
@ -160,7 +160,7 @@ export default class QueryEditor extends React.Component {
|
|||||||
if (this.props.theme !== prevProps.theme && this.editor) {
|
if (this.props.theme !== prevProps.theme && this.editor) {
|
||||||
this.editor.setOption('theme', this.props.theme === 'dark' ? 'monokai' : 'default');
|
this.editor.setOption('theme', this.props.theme === 'dark' ? 'monokai' : 'default');
|
||||||
}
|
}
|
||||||
let variables = getEnvironmentVariables(this.props.collection);
|
let variables = getAllVariables(this.props.collection);
|
||||||
if (!isEqual(variables, this.variables)) {
|
if (!isEqual(variables, this.variables)) {
|
||||||
this.editor.options.brunoVarInfo.variables = variables;
|
this.editor.options.brunoVarInfo.variables = variables;
|
||||||
this.addOverlay();
|
this.addOverlay();
|
||||||
@ -180,7 +180,7 @@ export default class QueryEditor extends React.Component {
|
|||||||
// Todo: Overlay is messing up with schema hint
|
// Todo: Overlay is messing up with schema hint
|
||||||
// Fix this
|
// Fix this
|
||||||
addOverlay = () => {
|
addOverlay = () => {
|
||||||
// let variables = getEnvironmentVariables(this.props.collection);
|
// let variables = getAllVariables(this.props.collection);
|
||||||
// this.variables = variables;
|
// this.variables = variables;
|
||||||
|
|
||||||
// defineCodeMirrorBrunoVariablesMode(variables, 'graphql');
|
// defineCodeMirrorBrunoVariablesMode(variables, 'graphql');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
import { getEnvironmentVariables } from 'utils/collections';
|
import { getAllVariables } from 'utils/collections';
|
||||||
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
|
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ class SingleLineEditor extends Component {
|
|||||||
theme: this.props.theme === 'dark' ? 'monokai' : 'default',
|
theme: this.props.theme === 'dark' ? 'monokai' : 'default',
|
||||||
mode: "brunovariables",
|
mode: "brunovariables",
|
||||||
brunoVarInfo: {
|
brunoVarInfo: {
|
||||||
variables: getEnvironmentVariables(this.props.collection),
|
variables: getAllVariables(this.props.collection),
|
||||||
},
|
},
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
"Enter": () => {
|
"Enter": () => {
|
||||||
@ -92,7 +92,7 @@ class SingleLineEditor extends Component {
|
|||||||
// event loop.
|
// event loop.
|
||||||
this.ignoreChangeEvent = true;
|
this.ignoreChangeEvent = true;
|
||||||
|
|
||||||
let variables = getEnvironmentVariables(this.props.collection);
|
let variables = getAllVariables(this.props.collection);
|
||||||
if (!isEqual(variables, this.variables)) {
|
if (!isEqual(variables, this.variables)) {
|
||||||
this.editor.options.brunoVarInfo.variables = variables;
|
this.editor.options.brunoVarInfo.variables = variables;
|
||||||
this.addOverlay();
|
this.addOverlay();
|
||||||
@ -112,7 +112,7 @@ class SingleLineEditor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addOverlay = () => {
|
addOverlay = () => {
|
||||||
let variables = getEnvironmentVariables(this.props.collection);
|
let variables = getAllVariables(this.props.collection);
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
|
|
||||||
defineCodeMirrorBrunoVariablesMode(variables, "text/plain");
|
defineCodeMirrorBrunoVariablesMode(variables, "text/plain");
|
||||||
|
@ -20,7 +20,6 @@ import {
|
|||||||
} from 'utils/collections';
|
} from 'utils/collections';
|
||||||
import { collectionSchema, itemSchema, environmentSchema, environmentsSchema } from '@usebruno/schema';
|
import { collectionSchema, itemSchema, environmentSchema, environmentsSchema } from '@usebruno/schema';
|
||||||
import { waitForNextTick } from 'utils/common';
|
import { waitForNextTick } from 'utils/common';
|
||||||
import { saveCollectionToIdb } from 'utils/idb';
|
|
||||||
import { sendNetworkRequest, cancelNetworkRequest } from 'utils/network';
|
import { sendNetworkRequest, cancelNetworkRequest } from 'utils/network';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -100,7 +99,7 @@ export const sendRequest = (item, collectionUid) => (dispatch, getState) => {
|
|||||||
|
|
||||||
const environment = findEnvironmentInCollection(collectionCopy, collection.activeEnvironmentUid);
|
const environment = findEnvironmentInCollection(collectionCopy, collection.activeEnvironmentUid);
|
||||||
|
|
||||||
sendNetworkRequest(itemCopy, collection, environment)
|
sendNetworkRequest(itemCopy, collection, environment, collectionCopy.collectionVariables)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return dispatch(
|
return dispatch(
|
||||||
responseReceived({
|
responseReceived({
|
||||||
@ -716,7 +715,8 @@ export const openCollectionEvent = (uid, pathname, name) => (dispatch, getState)
|
|||||||
name: name,
|
name: name,
|
||||||
pathname: pathname,
|
pathname: pathname,
|
||||||
items: [],
|
items: [],
|
||||||
showRunner: false
|
showRunner: false,
|
||||||
|
collectionVariables: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -176,7 +176,7 @@ export const collectionsSlice = createSlice({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
scriptEnvironmentUpdateEvent: (state, action) => {
|
scriptEnvironmentUpdateEvent: (state, action) => {
|
||||||
const { collectionUid, environment } = action.payload;
|
const { collectionUid, environment, collectionVariables } = action.payload;
|
||||||
const collection = findCollectionByUid(state.collections, collectionUid);
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
@ -192,6 +192,9 @@ export const collectionsSlice = createSlice({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
collection.collectionVariables = collectionVariables;
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
requestCancelled: (state, action) => {
|
requestCancelled: (state, action) => {
|
||||||
|
@ -517,3 +517,12 @@ export const getEnvironmentVariables = (collection) => {
|
|||||||
|
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getAllVariables = (collection) => {
|
||||||
|
const environmentVariables = getEnvironmentVariables(collection);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...environmentVariables,
|
||||||
|
...collection.collectionVariables
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
export const sendNetworkRequest = async (item, collection, environment) => {
|
export const sendNetworkRequest = async (item, collection, environment, collectionVariables) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (['http-request', 'graphql-request'].includes(item.type)) {
|
if (['http-request', 'graphql-request'].includes(item.type)) {
|
||||||
const timeStart = Date.now();
|
const timeStart = Date.now();
|
||||||
sendHttpRequest(item, collection, environment)
|
sendHttpRequest(item, collection, environment, collectionVariables)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const timeEnd = Date.now();
|
const timeEnd = Date.now();
|
||||||
resolve({
|
resolve({
|
||||||
@ -20,12 +20,12 @@ export const sendNetworkRequest = async (item, collection, environment) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendHttpRequest = async (item, collection, environment) => {
|
const sendHttpRequest = async (item, collection, environment, collectionVariables) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const { ipcRenderer } = window;
|
const { ipcRenderer } = window;
|
||||||
|
|
||||||
ipcRenderer
|
ipcRenderer
|
||||||
.invoke('send-http-request', item, collection.uid, collection.pathname, environment)
|
.invoke('send-http-request', item, collection.uid, collection.pathname, environment, collectionVariables)
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
|
@ -69,7 +69,7 @@ const getSize = (data) => {
|
|||||||
|
|
||||||
const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
||||||
// handler for sending http request
|
// handler for sending http request
|
||||||
ipcMain.handle('send-http-request', async (event, item, collectionUid, collectionPath, environment) => {
|
ipcMain.handle('send-http-request', async (event, item, collectionUid, collectionPath, environment, collectionVariables) => {
|
||||||
const cancelTokenUid = uuid();
|
const cancelTokenUid = uuid();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -102,15 +102,16 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
if(request.script && request.script.length) {
|
if(request.script && request.script.length) {
|
||||||
let script = request.script + '\n if (typeof onRequest === "function") {onRequest(__brunoRequest);}';
|
let script = request.script + '\n if (typeof onRequest === "function") {onRequest(__brunoRequest);}';
|
||||||
const scriptRuntime = new ScriptRuntime();
|
const scriptRuntime = new ScriptRuntime();
|
||||||
const result = scriptRuntime.runRequestScript(script, request, envVars, collectionPath);
|
const result = scriptRuntime.runRequestScript(script, request, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
mainWindow.webContents.send('main:script-environment-update', {
|
mainWindow.webContents.send('main:script-environment-update', {
|
||||||
environment: result.environment,
|
environment: result.environment,
|
||||||
|
collectionVariables: result.collectionVariables,
|
||||||
collectionUid
|
collectionUid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolateVars(request, envVars);
|
interpolateVars(request, envVars, collectionVariables);
|
||||||
|
|
||||||
// todo:
|
// todo:
|
||||||
// i have no clue why electron can't send the request object
|
// i have no clue why electron can't send the request object
|
||||||
@ -132,10 +133,11 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
if(request.script && request.script.length) {
|
if(request.script && request.script.length) {
|
||||||
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(__brunoResponse);}';
|
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(__brunoResponse);}';
|
||||||
const scriptRuntime = new ScriptRuntime();
|
const scriptRuntime = new ScriptRuntime();
|
||||||
const result = scriptRuntime.runResponseScript(script, response, envVars, collectionPath);
|
const result = scriptRuntime.runResponseScript(script, response, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
mainWindow.webContents.send('main:script-environment-update', {
|
mainWindow.webContents.send('main:script-environment-update', {
|
||||||
environment: result.environment,
|
environment: result.environment,
|
||||||
|
collectionVariables: result.collectionVariables,
|
||||||
collectionUid
|
collectionUid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -143,7 +145,7 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
const testFile = get(item, 'request.tests');
|
const testFile = get(item, 'request.tests');
|
||||||
if(testFile && testFile.length) {
|
if(testFile && testFile.length) {
|
||||||
const testRuntime = new TestRuntime();
|
const testRuntime = new TestRuntime();
|
||||||
const result = testRuntime.runTests(testFile, request, response, envVars, collectionPath);
|
const result = testRuntime.runTests(testFile, request, response, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
mainWindow.webContents.send('main:test-results', {
|
mainWindow.webContents.send('main:test-results', {
|
||||||
results: result.results,
|
results: result.results,
|
||||||
@ -275,7 +277,19 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
request.data = form;
|
request.data = form;
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolateVars(request, envVars);
|
if(request.script && request.script.length) {
|
||||||
|
let script = request.script + '\n if (typeof onRequest === "function") {onRequest(__brunoRequest);}';
|
||||||
|
const scriptRuntime = new ScriptRuntime();
|
||||||
|
const result = scriptRuntime.runRequestScript(script, request, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
|
mainWindow.webContents.send('main:script-environment-update', {
|
||||||
|
environment: result.environment,
|
||||||
|
collectionVariables: result.collectionVariables,
|
||||||
|
collectionUid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolateVars(request, envVars, collectionVariables);
|
||||||
|
|
||||||
// todo:
|
// todo:
|
||||||
// i have no clue why electron can't send the request object
|
// i have no clue why electron can't send the request object
|
||||||
@ -298,10 +312,11 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
if(request.script && request.script.length) {
|
if(request.script && request.script.length) {
|
||||||
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(__brunoResponse);}';
|
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(__brunoResponse);}';
|
||||||
const scriptRuntime = new ScriptRuntime();
|
const scriptRuntime = new ScriptRuntime();
|
||||||
const result = scriptRuntime.runResponseScript(script, response, envVars, collectionPath);
|
const result = scriptRuntime.runResponseScript(script, response, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
mainWindow.webContents.send('main:script-environment-update', {
|
mainWindow.webContents.send('main:script-environment-update', {
|
||||||
environment: result.environment,
|
environment: result.environment,
|
||||||
|
collectionVariables: result.collectionVariables,
|
||||||
collectionUid
|
collectionUid
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -309,7 +324,7 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
const testFile = get(item, 'request.tests');
|
const testFile = get(item, 'request.tests');
|
||||||
if(testFile && testFile.length) {
|
if(testFile && testFile.length) {
|
||||||
const testRuntime = new TestRuntime();
|
const testRuntime = new TestRuntime();
|
||||||
const result = testRuntime.runTests(testFile, request, response, envVars, collectionPath);
|
const result = testRuntime.runTests(testFile, request, response, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
mainWindow.webContents.send('main:run-folder-event', {
|
mainWindow.webContents.send('main:run-folder-event', {
|
||||||
type: 'test-results',
|
type: 'test-results',
|
||||||
|
@ -6,13 +6,19 @@ Mustache.escape = function (value) {
|
|||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
const interpolateVars = (request, envVars = {}) => {
|
const interpolateVars = (request, envVars = {}, collectionVariables ={}) => {
|
||||||
const interpolate = (str) => {
|
const interpolate = (str) => {
|
||||||
if(!str || !str.length || typeof str !== "string") {
|
if(!str || !str.length || typeof str !== "string") {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mustache.render(str, envVars);
|
// collectionVariables take precedence over envVars
|
||||||
|
const combinedVars = {
|
||||||
|
...envVars,
|
||||||
|
...collectionVariables
|
||||||
|
};
|
||||||
|
|
||||||
|
return Mustache.render(str, combinedVars);
|
||||||
};
|
};
|
||||||
|
|
||||||
request.url = interpolate(request.url);
|
request.url = interpolate(request.url);
|
||||||
|
@ -9,8 +9,9 @@ const nanoid = require('nanoid');
|
|||||||
const CryptoJS = require('crypto-js');
|
const CryptoJS = require('crypto-js');
|
||||||
|
|
||||||
class Bru {
|
class Bru {
|
||||||
constructor(environment) {
|
constructor(environment, collectionVariables) {
|
||||||
this._environment = environment;
|
this._environment = environment;
|
||||||
|
this._collectionVariables = collectionVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
require(module) {
|
require(module) {
|
||||||
@ -50,6 +51,18 @@ class Bru {
|
|||||||
|
|
||||||
this._environment[key] = value;
|
this._environment[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setVar(key, value) {
|
||||||
|
if(!key) {
|
||||||
|
throw new Error('Key is required');
|
||||||
|
}
|
||||||
|
|
||||||
|
this._collectionVariables[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVar(key) {
|
||||||
|
return this._collectionVariables[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Bru;
|
module.exports = Bru;
|
@ -8,8 +8,8 @@ class ScriptRuntime {
|
|||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
runRequestScript(script, request, environment, collectionPath) {
|
runRequestScript(script, request, environment, collectionVariables, collectionPath) {
|
||||||
const bru = new Bru(environment);
|
const bru = new Bru(environment, collectionVariables);
|
||||||
const __brunoRequest = new BrunoRequest(request);
|
const __brunoRequest = new BrunoRequest(request);
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
@ -29,12 +29,13 @@ class ScriptRuntime {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
request,
|
request,
|
||||||
environment
|
environment,
|
||||||
|
collectionVariables
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
runResponseScript(script, response, environment, collectionPath) {
|
runResponseScript(script, response, environment, collectionVariables, collectionPath) {
|
||||||
const bru = new Bru(environment);
|
const bru = new Bru(environment, collectionVariables);
|
||||||
const __brunoResponse = new BrunoResponse(response);
|
const __brunoResponse = new BrunoResponse(response);
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
@ -54,7 +55,8 @@ class ScriptRuntime {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
response,
|
response,
|
||||||
environment
|
environment,
|
||||||
|
collectionVariables
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ class TestRuntime {
|
|||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
runTests(testsFile, request, response, environment, collectionPath) {
|
runTests(testsFile, request, response, environment, collectionVariables, collectionPath) {
|
||||||
const bru = new Bru(environment);
|
const bru = new Bru(environment, collectionVariables);
|
||||||
const req = new BrunoRequest(request);
|
const req = new BrunoRequest(request);
|
||||||
const res = new BrunoResponse(response);
|
const res = new BrunoResponse(response);
|
||||||
|
|
||||||
@ -45,6 +45,7 @@ class TestRuntime {
|
|||||||
request,
|
request,
|
||||||
response,
|
response,
|
||||||
environment,
|
environment,
|
||||||
|
collectionVariables,
|
||||||
results: __brunoTestResults.getResults()
|
results: __brunoTestResults.getResults()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,8 @@ const collectionSchema = Yup.object({
|
|||||||
showRunner: Yup.boolean(),
|
showRunner: Yup.boolean(),
|
||||||
runnerResult: Yup.object({
|
runnerResult: Yup.object({
|
||||||
items: Yup.array()
|
items: Yup.array()
|
||||||
})
|
}),
|
||||||
|
collectionVariables: Yup.object()
|
||||||
}).noUnknown(true).strict();
|
}).noUnknown(true).strict();
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user