feat: vars runtime in UI

This commit is contained in:
Anoop M D 2023-02-21 15:26:12 +05:30
parent d58e92205b
commit 224b8c3cc4
9 changed files with 121 additions and 20 deletions

View File

@ -183,7 +183,7 @@ export const collectionsSlice = createSlice({
} }
}, },
scriptEnvironmentUpdateEvent: (state, action) => { scriptEnvironmentUpdateEvent: (state, action) => {
const { collectionUid, environment, collectionVariables } = action.payload; const { collectionUid, envVariables, collectionVariables } = action.payload;
const collection = findCollectionByUid(state.collections, collectionUid); const collection = findCollectionByUid(state.collections, collectionUid);
if (collection) { if (collection) {
@ -191,7 +191,7 @@ export const collectionsSlice = createSlice({
const activeEnvironment = findEnvironmentInCollection(collection, activeEnvironmentUid); const activeEnvironment = findEnvironmentInCollection(collection, activeEnvironmentUid);
if (activeEnvironment) { if (activeEnvironment) {
forOwn(environment, (value, key) => { forOwn(envVariables, (value, key) => {
const variable = find(activeEnvironment.variables, (v) => v.name === key); const variable = find(activeEnvironment.variables, (v) => v.name === key);
if (variable) { if (variable) {
@ -201,7 +201,6 @@ export const collectionsSlice = createSlice({
} }
collection.collectionVariables = collectionVariables; collection.collectionVariables = collectionVariables;
} }
}, },
requestCancelled: (state, action) => { requestCancelled: (state, action) => {

View File

@ -13,7 +13,7 @@
"pack-app": "electron-builder --dir" "pack-app": "electron-builder --dir"
}, },
"dependencies": { "dependencies": {
"@usebruno/js": "0.1.0", "@usebruno/js": "0.2.0",
"@usebruno/lang": "0.2.2", "@usebruno/lang": "0.2.2",
"@usebruno/schema": "0.3.1", "@usebruno/schema": "0.3.1",
"axios": "^0.26.0", "axios": "^0.26.0",

View File

@ -42,6 +42,7 @@ const hydrateRequestWithUuid = (request, pathname) => {
const headers = _.get(request, 'request.headers', []); const headers = _.get(request, 'request.headers', []);
const requestVars = _.get(request, 'request.vars.req', []); const requestVars = _.get(request, 'request.vars.req', []);
const responseVars = _.get(request, 'request.vars.res', []); const responseVars = _.get(request, 'request.vars.res', []);
const assertions = _.get(request, 'request.assertions', []);
const bodyFormUrlEncoded = _.get(request, 'request.body.formUrlEncoded', []); const bodyFormUrlEncoded = _.get(request, 'request.body.formUrlEncoded', []);
const bodyMultipartForm = _.get(request, 'request.body.multipartForm', []); const bodyMultipartForm = _.get(request, 'request.body.multipartForm', []);
@ -49,6 +50,7 @@ const hydrateRequestWithUuid = (request, pathname) => {
headers.forEach((header) => header.uid = uuid()); headers.forEach((header) => header.uid = uuid());
requestVars.forEach((variable) => variable.uid = uuid()); requestVars.forEach((variable) => variable.uid = uuid());
responseVars.forEach((variable) => variable.uid = uuid()); responseVars.forEach((variable) => variable.uid = uuid());
assertions.forEach((assertion) => assertion.uid = uuid());
bodyFormUrlEncoded.forEach((param) => param.uid = uuid()); bodyFormUrlEncoded.forEach((param) => param.uid = uuid());
bodyMultipartForm.forEach((param) => param.uid = uuid()); bodyMultipartForm.forEach((param) => param.uid = uuid());

View File

@ -3,7 +3,7 @@ const Mustache = require('mustache');
const FormData = require('form-data'); const FormData = require('form-data');
const { ipcMain } = require('electron'); const { ipcMain } = require('electron');
const { forOwn, extend, each, get } = require('lodash'); const { forOwn, extend, each, get } = require('lodash');
const { ScriptRuntime, TestRuntime } = require('@usebruno/js'); const { VarsRuntime, AssertRuntime, ScriptRuntime, TestRuntime } = require('@usebruno/js');
const prepareRequest = require('./prepare-request'); const prepareRequest = require('./prepare-request');
const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request'); const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request');
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token'); const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
@ -96,13 +96,27 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
const envVars = getEnvVars(environment); const envVars = getEnvVars(environment);
// run pre-request vars
const preRequestVars = get(request, 'vars.req', []);
if(preRequestVars && preRequestVars.length) {
const varsRuntime = new VarsRuntime();
const result = varsRuntime.runPreRequestVars(preRequestVars, request, envVars, collectionVariables, collectionPath);
mainWindow.webContents.send('main:script-environment-update', {
envVariables: result.envVariables,
collectionVariables: result.collectionVariables,
collectionUid
});
}
// run pre-request script
const requestScript = get(request, 'script.req'); const requestScript = get(request, 'script.req');
if(requestScript && requestScript.length) { if(requestScript && requestScript.length) {
const scriptRuntime = new ScriptRuntime(); const scriptRuntime = new ScriptRuntime();
const result = scriptRuntime.runRequestScript(requestScript, request, envVars, collectionVariables, collectionPath); const result = scriptRuntime.runRequestScript(requestScript, request, envVars, collectionVariables, collectionPath);
mainWindow.webContents.send('main:script-environment-update', { mainWindow.webContents.send('main:script-environment-update', {
environment: result.environment, envVariables: result.envVariables,
collectionVariables: result.collectionVariables, collectionVariables: result.collectionVariables,
collectionUid collectionUid
}); });
@ -127,18 +141,33 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
const response = await axios(request); const response = await axios(request);
// run post-response vars
const postResponseVars = get(request, 'vars.res', []);
if(postResponseVars && postResponseVars.length) {
const varsRuntime = new VarsRuntime();
const result = varsRuntime.runPostResponseVars(postResponseVars, request, response, envVars, collectionVariables, collectionPath);
mainWindow.webContents.send('main:script-environment-update', {
envVariables: result.envVariables,
collectionVariables: result.collectionVariables,
collectionUid
});
}
// run post-response script
const responseScript = get(request, 'script.res'); const responseScript = get(request, 'script.res');
if(responseScript && responseScript.length) { if(responseScript && responseScript.length) {
const scriptRuntime = new ScriptRuntime(); const scriptRuntime = new ScriptRuntime();
const result = scriptRuntime.runResponseScript(responseScript, request, response, envVars, collectionVariables, collectionPath); const result = scriptRuntime.runResponseScript(responseScript, request, response, envVars, collectionVariables, collectionPath);
mainWindow.webContents.send('main:script-environment-update', { mainWindow.webContents.send('main:script-environment-update', {
environment: result.environment, envVariables: result.envVariables,
collectionVariables: result.collectionVariables, collectionVariables: result.collectionVariables,
collectionUid collectionUid
}); });
} }
// run tests
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();
@ -284,18 +313,27 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
request.data = form; request.data = form;
} }
// run pre-request vars
const preRequestVars = get(request, 'vars.req', []);
if(preRequestVars && preRequestVars.length) {
const varsRuntime = new VarsRuntime();
varsRuntime.runPreRequestVars(preRequestVars, request, envVars, collectionVariables, collectionPath);
}
// run pre-request script
const requestScript = get(request, 'script.req'); const requestScript = get(request, 'script.req');
if(requestScript && requestScript.length) { if(requestScript && requestScript.length) {
const scriptRuntime = new ScriptRuntime(); const scriptRuntime = new ScriptRuntime();
const result = scriptRuntime.runRequestScript(requestScript, request, envVars, collectionVariables, collectionPath); const result = scriptRuntime.runRequestScript(requestScript, request, envVars, collectionVariables, collectionPath);
mainWindow.webContents.send('main:script-environment-update', { mainWindow.webContents.send('main:script-environment-update', {
environment: result.environment, envVariables: result.envVariables,
collectionVariables: result.collectionVariables, collectionVariables: result.collectionVariables,
collectionUid collectionUid
}); });
} }
// interpolate variables inside request
interpolateVars(request, envVars, collectionVariables); interpolateVars(request, envVars, collectionVariables);
// todo: // todo:
@ -312,17 +350,26 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
...eventData ...eventData
}); });
// send request
timeStart = Date.now(); timeStart = Date.now();
const response = await axios(request); const response = await axios(request);
timeEnd = Date.now(); timeEnd = Date.now();
// run post-response vars
const postResponseVars = get(request, 'vars.res', []);
if(postResponseVars && postResponseVars.length) {
const varsRuntime = new VarsRuntime();
varsRuntime.runPostResponseVars(postResponseVars, request, response, envVars, collectionVariables, collectionPath);
}
// run response script
const responseScript = get(request, 'script.res'); const responseScript = get(request, 'script.res');
if(responseScript && responseScript.length) { if(responseScript && responseScript.length) {
const scriptRuntime = new ScriptRuntime(); const scriptRuntime = new ScriptRuntime();
const result = scriptRuntime.runResponseScript(responseScript, request, response, envVars, collectionVariables, collectionPath); const result = scriptRuntime.runResponseScript(responseScript, request, response, envVars, collectionVariables, collectionPath);
mainWindow.webContents.send('main:script-environment-update', { mainWindow.webContents.send('main:script-environment-update', {
environment: result.environment, envVariables: result.envVariables,
collectionVariables: result.collectionVariables, collectionVariables: result.collectionVariables,
collectionUid collectionUid
}); });

View File

@ -63,6 +63,9 @@ const prepareRequest = (request) => {
axiosRequest.script = request.script; axiosRequest.script = request.script;
} }
axiosRequest.vars = request.vars;
axiosRequest.assertions = request.assertions;
return axiosRequest; return axiosRequest;
}; };

View File

@ -17,8 +17,8 @@ class ScriptRuntime {
constructor() { constructor() {
} }
runRequestScript(script, request, environment, collectionVariables, collectionPath) { runRequestScript(script, request, envVariables, collectionVariables, collectionPath) {
const bru = new Bru(environment, collectionVariables); const bru = new Bru(envVariables, collectionVariables);
const req = new BrunoRequest(request); const req = new BrunoRequest(request);
const context = { const context = {
@ -47,13 +47,13 @@ class ScriptRuntime {
return { return {
request, request,
environment, envVariables,
collectionVariables collectionVariables
}; };
} }
runResponseScript(script, request, response, environment, collectionVariables, collectionPath) { runResponseScript(script, request, response, envVariables, collectionVariables, collectionPath) {
const bru = new Bru(environment, collectionVariables); const bru = new Bru(envVariables, collectionVariables);
const req = new BrunoRequest(request); const req = new BrunoRequest(request);
const res = new BrunoResponse(response); const res = new BrunoResponse(response);
@ -84,7 +84,7 @@ class ScriptRuntime {
return { return {
response, response,
environment, envVariables,
collectionVariables collectionVariables
}; };
} }

View File

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

View File

@ -1,7 +1,7 @@
const _ = require('lodash'); const _ = require('lodash');
const Bru = require('../bru'); const Bru = require('../bru');
const BrunoRequest = require('../bruno-request'); const BrunoRequest = require('../bruno-request');
const { evaluateJsExpression, createResponseParser } = require('../utils'); const { evaluateJsTemplateLiteral, evaluateJsExpression, createResponseParser } = require('../utils');
class VarsRuntime { class VarsRuntime {
runPreRequestVars(vars, request, envVariables, collectionVariables, collectionPath) { runPreRequestVars(vars, request, envVariables, collectionVariables, collectionPath) {
@ -25,9 +25,13 @@ class VarsRuntime {
} }
_.each(enabledVars, (v) => { _.each(enabledVars, (v) => {
const value = evaluateJsExpression(v.value, context); const value = evaluateJsTemplateLiteral(v.value, context);
bru.setVar(v.name, value); bru.setVar(v.name, value);
}); });
return {
collectionVariables
};
} }
runPostResponseVars(vars, request, response, envVariables, collectionVariables, collectionPath) { runPostResponseVars(vars, request, response, envVariables, collectionVariables, collectionPath) {
@ -56,6 +60,11 @@ class VarsRuntime {
const value = evaluateJsExpression(v.value, context); const value = evaluateJsExpression(v.value, context);
bru.setVar(v.name, value); bru.setVar(v.name, value);
}); });
return {
envVariables,
collectionVariables
};
} }
} }

View File

@ -60,6 +60,46 @@ const evaluateJsExpression = (expression, context) => {
return fn(context); return fn(context);
}; };
const evaluateJsTemplateLiteral = (templateLiteral, context) => {
if(!templateLiteral || !templateLiteral.length || typeof templateLiteral !== 'string') {
return templateLiteral;
}
templateLiteral = templateLiteral.trim();
if(templateLiteral === 'true') {
return true;
}
if(templateLiteral === 'false') {
return false;
}
if(templateLiteral === 'null') {
return null;
}
if(templateLiteral === 'undefined') {
return undefined;
}
if(templateLiteral.startsWith('"') && templateLiteral.endsWith('"')) {
return templateLiteral.slice(1, -1);
}
if(templateLiteral.startsWith("'") && templateLiteral.endsWith("'")) {
return templateLiteral.slice(1, -1);
}
if(!isNaN(templateLiteral)) {
return Number(templateLiteral);
}
templateLiteral = "`" + templateLiteral + "`";
return evaluateJsExpression(templateLiteral, context);
};
const createResponseParser = (response = {}) => { const createResponseParser = (response = {}) => {
const res = (expr, ...fns) => { const res = (expr, ...fns) => {
return get(response.data, expr, ...fns); return get(response.data, expr, ...fns);
@ -80,6 +120,7 @@ const createResponseParser = (response = {}) => {
module.exports = { module.exports = {
evaluateJsExpression, evaluateJsExpression,
evaluateJsTemplateLiteral,
createResponseParser, createResponseParser,
internalExpressionCache internalExpressionCache
}; };