feat: collection variables

This commit is contained in:
Anoop M D 2023-02-01 17:56:13 +05:30
parent 37b1c043eb
commit 6f6dedbb9c
12 changed files with 86 additions and 36 deletions

View File

@ -8,7 +8,7 @@
import React from 'react';
import isEqual from 'lodash/isEqual';
import MD from 'markdown-it';
import { getEnvironmentVariables } from 'utils/collections';
import { getAllVariables } from 'utils/collections';
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
import StyledWrapper from './StyledWrapper';
@ -43,7 +43,7 @@ export default class QueryEditor extends React.Component {
mode: 'graphql',
// mode: 'brunovariables',
brunoVarInfo: {
variables: getEnvironmentVariables(this.props.collection),
variables: getAllVariables(this.props.collection),
},
theme: this.props.editorTheme || 'graphiql',
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) {
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)) {
this.editor.options.brunoVarInfo.variables = variables;
this.addOverlay();
@ -180,7 +180,7 @@ export default class QueryEditor extends React.Component {
// Todo: Overlay is messing up with schema hint
// Fix this
addOverlay = () => {
// let variables = getEnvironmentVariables(this.props.collection);
// let variables = getAllVariables(this.props.collection);
// this.variables = variables;
// defineCodeMirrorBrunoVariablesMode(variables, 'graphql');

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import isEqual from 'lodash/isEqual';
import { getEnvironmentVariables } from 'utils/collections';
import { getAllVariables } from 'utils/collections';
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
import StyledWrapper from './StyledWrapper';
@ -29,7 +29,7 @@ class SingleLineEditor extends Component {
theme: this.props.theme === 'dark' ? 'monokai' : 'default',
mode: "brunovariables",
brunoVarInfo: {
variables: getEnvironmentVariables(this.props.collection),
variables: getAllVariables(this.props.collection),
},
extraKeys: {
"Enter": () => {
@ -92,7 +92,7 @@ class SingleLineEditor extends Component {
// event loop.
this.ignoreChangeEvent = true;
let variables = getEnvironmentVariables(this.props.collection);
let variables = getAllVariables(this.props.collection);
if (!isEqual(variables, this.variables)) {
this.editor.options.brunoVarInfo.variables = variables;
this.addOverlay();
@ -112,7 +112,7 @@ class SingleLineEditor extends Component {
}
addOverlay = () => {
let variables = getEnvironmentVariables(this.props.collection);
let variables = getAllVariables(this.props.collection);
this.variables = variables;
defineCodeMirrorBrunoVariablesMode(variables, "text/plain");

View File

@ -20,7 +20,6 @@ import {
} from 'utils/collections';
import { collectionSchema, itemSchema, environmentSchema, environmentsSchema } from '@usebruno/schema';
import { waitForNextTick } from 'utils/common';
import { saveCollectionToIdb } from 'utils/idb';
import { sendNetworkRequest, cancelNetworkRequest } from 'utils/network';
import {
@ -100,7 +99,7 @@ export const sendRequest = (item, collectionUid) => (dispatch, getState) => {
const environment = findEnvironmentInCollection(collectionCopy, collection.activeEnvironmentUid);
sendNetworkRequest(itemCopy, collection, environment)
sendNetworkRequest(itemCopy, collection, environment, collectionCopy.collectionVariables)
.then((response) => {
return dispatch(
responseReceived({
@ -716,7 +715,8 @@ export const openCollectionEvent = (uid, pathname, name) => (dispatch, getState)
name: name,
pathname: pathname,
items: [],
showRunner: false
showRunner: false,
collectionVariables: {}
};
return new Promise((resolve, reject) => {

View File

@ -176,7 +176,7 @@ export const collectionsSlice = createSlice({
}
},
scriptEnvironmentUpdateEvent: (state, action) => {
const { collectionUid, environment } = action.payload;
const { collectionUid, environment, collectionVariables } = action.payload;
const collection = findCollectionByUid(state.collections, collectionUid);
if (collection) {
@ -192,6 +192,9 @@ export const collectionsSlice = createSlice({
}
});
}
collection.collectionVariables = collectionVariables;
}
},
requestCancelled: (state, action) => {

View File

@ -517,3 +517,12 @@ export const getEnvironmentVariables = (collection) => {
return variables;
}
export const getAllVariables = (collection) => {
const environmentVariables = getEnvironmentVariables(collection);
return {
...environmentVariables,
...collection.collectionVariables
};
}

View File

@ -1,8 +1,8 @@
export const sendNetworkRequest = async (item, collection, environment) => {
export const sendNetworkRequest = async (item, collection, environment, collectionVariables) => {
return new Promise((resolve, reject) => {
if (['http-request', 'graphql-request'].includes(item.type)) {
const timeStart = Date.now();
sendHttpRequest(item, collection, environment)
sendHttpRequest(item, collection, environment, collectionVariables)
.then((response) => {
const timeEnd = Date.now();
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) => {
const { ipcRenderer } = window;
ipcRenderer
.invoke('send-http-request', item, collection.uid, collection.pathname, environment)
.invoke('send-http-request', item, collection.uid, collection.pathname, environment, collectionVariables)
.then(resolve)
.catch(reject);
});

View File

@ -69,7 +69,7 @@ const getSize = (data) => {
const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
// 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();
try {
@ -102,15 +102,16 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
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, collectionPath);
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);
interpolateVars(request, envVars, collectionVariables);
// todo:
// 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) {
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(__brunoResponse);}';
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', {
environment: result.environment,
collectionVariables: result.collectionVariables,
collectionUid
});
}
@ -143,7 +145,7 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
const testFile = get(item, 'request.tests');
if(testFile && testFile.length) {
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', {
results: result.results,
@ -275,7 +277,19 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
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:
// 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) {
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(__brunoResponse);}';
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', {
environment: result.environment,
collectionVariables: result.collectionVariables,
collectionUid
});
}
@ -309,7 +324,7 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
const testFile = get(item, 'request.tests');
if(testFile && testFile.length) {
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', {
type: 'test-results',

View File

@ -6,13 +6,19 @@ Mustache.escape = function (value) {
return value;
};
const interpolateVars = (request, envVars = {}) => {
const interpolateVars = (request, envVars = {}, collectionVariables ={}) => {
const interpolate = (str) => {
if(!str || !str.length || typeof str !== "string") {
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);

View File

@ -9,8 +9,9 @@ const nanoid = require('nanoid');
const CryptoJS = require('crypto-js');
class Bru {
constructor(environment) {
constructor(environment, collectionVariables) {
this._environment = environment;
this._collectionVariables = collectionVariables;
}
require(module) {
@ -50,6 +51,18 @@ class Bru {
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;

View File

@ -8,8 +8,8 @@ class ScriptRuntime {
constructor() {
}
runRequestScript(script, request, environment, collectionPath) {
const bru = new Bru(environment);
runRequestScript(script, request, environment, collectionVariables, collectionPath) {
const bru = new Bru(environment, collectionVariables);
const __brunoRequest = new BrunoRequest(request);
const context = {
@ -29,12 +29,13 @@ class ScriptRuntime {
return {
request,
environment
environment,
collectionVariables
};
}
runResponseScript(script, response, environment, collectionPath) {
const bru = new Bru(environment);
runResponseScript(script, response, environment, collectionVariables, collectionPath) {
const bru = new Bru(environment, collectionVariables);
const __brunoResponse = new BrunoResponse(response);
const context = {
@ -54,7 +55,8 @@ class ScriptRuntime {
return {
response,
environment
environment,
collectionVariables
};
}
}

View File

@ -11,8 +11,8 @@ class TestRuntime {
constructor() {
}
runTests(testsFile, request, response, environment, collectionPath) {
const bru = new Bru(environment);
runTests(testsFile, request, response, environment, collectionVariables, collectionPath) {
const bru = new Bru(environment, collectionVariables);
const req = new BrunoRequest(request);
const res = new BrunoResponse(response);
@ -45,6 +45,7 @@ class TestRuntime {
request,
response,
environment,
collectionVariables,
results: __brunoTestResults.getResults()
};
}

View File

@ -89,7 +89,8 @@ const collectionSchema = Yup.object({
showRunner: Yup.boolean(),
runnerResult: Yup.object({
items: Yup.array()
})
}),
collectionVariables: Yup.object()
}).noUnknown(true).strict();