feat(#1460): use new interpolation lib in app, electron, cli

This commit is contained in:
Anoop M D 2024-01-29 17:17:24 +05:30
parent c5986896d1
commit 7ba9b839da
22 changed files with 378 additions and 239 deletions

77
package-lock.json generated
View File

@ -15,7 +15,6 @@
"packages/bruno-js",
"packages/bruno-lang",
"packages/bruno-tests",
"packages/bruno-testbench",
"packages/bruno-toml",
"packages/bruno-graphql-docs"
],
@ -5418,10 +5417,6 @@
"resolved": "packages/bruno-schema",
"link": true
},
"node_modules/@usebruno/testbench": {
"resolved": "packages/bruno-testbench",
"link": true
},
"node_modules/@usebruno/tests": {
"resolved": "packages/bruno-tests",
"link": true
@ -7392,16 +7387,6 @@
"version": "4.0.0",
"license": "ISC"
},
"node_modules/config": {
"version": "3.3.9",
"license": "MIT",
"dependencies": {
"json5": "^2.2.3"
},
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/config-chain": {
"version": "1.1.13",
"dev": true,
@ -11914,6 +11899,7 @@
},
"node_modules/json5": {
"version": "2.2.3",
"dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@ -17928,6 +17914,7 @@
"@reduxjs/toolkit": "^1.8.0",
"@tabler/icons": "^1.46.0",
"@tippyjs/react": "^4.2.6",
"@usebruno/common": "0.1.0",
"@usebruno/graphql-docs": "0.1.0",
"@usebruno/schema": "0.6.0",
"axios": "^1.5.1",
@ -17944,7 +17931,6 @@
"graphiql": "^1.5.9",
"graphql": "^16.6.0",
"graphql-request": "^3.7.0",
"handlebars": "^4.7.8",
"httpsnippet": "^3.0.1",
"idb": "^7.0.0",
"immer": "^9.0.15",
@ -18145,6 +18131,7 @@
"version": "1.3.0",
"license": "MIT",
"dependencies": {
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.9.4",
"@usebruno/lang": "0.9.0",
"axios": "^1.5.1",
@ -18153,7 +18140,6 @@
"decomment": "^0.9.5",
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"handlebars": "^4.7.8",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"inquirer": "^9.1.4",
@ -18253,6 +18239,7 @@
"dependencies": {
"@aws-sdk/credential-providers": "^3.425.0",
"@n8n/vm2": "^3.9.23",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.9.4",
"@usebruno/lang": "0.9.0",
"@usebruno/schema": "0.6.0",
@ -18271,7 +18258,6 @@
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"graphql": "^16.6.0",
"handlebars": "^4.7.8",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"is-valid-path": "^0.1.1",
@ -18603,6 +18589,7 @@
"packages/bruno-testbench": {
"name": "@usebruno/testbench",
"version": "1.0.0",
"extraneous": true,
"license": "ISC",
"dependencies": {
"body-parser": "^1.20.0",
@ -18615,21 +18602,8 @@
"multer": "^1.4.5-lts.1"
}
},
"packages/bruno-testbench/node_modules/argparse": {
"version": "2.0.1",
"license": "Python-2.0"
},
"packages/bruno-testbench/node_modules/js-yaml": {
"version": "4.1.0",
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"packages/bruno-tests": {
"name": "@usebruno/tests",
"version": "0.0.1",
"license": "MIT",
"dependencies": {
@ -22559,6 +22533,7 @@
"@reduxjs/toolkit": "^1.8.0",
"@tabler/icons": "^1.46.0",
"@tippyjs/react": "^4.2.6",
"@usebruno/common": "0.1.0",
"@usebruno/graphql-docs": "0.1.0",
"@usebruno/schema": "0.6.0",
"axios": "^1.5.1",
@ -22579,7 +22554,6 @@
"graphiql": "^1.5.9",
"graphql": "^16.6.0",
"graphql-request": "^3.7.0",
"handlebars": "^4.7.8",
"html-loader": "^3.0.1",
"html-webpack-plugin": "^5.5.0",
"httpsnippet": "^3.0.1",
@ -22709,6 +22683,7 @@
"@usebruno/cli": {
"version": "file:packages/bruno-cli",
"requires": {
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.9.4",
"@usebruno/lang": "0.9.0",
"axios": "^1.5.1",
@ -22717,7 +22692,6 @@
"decomment": "^0.9.5",
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"handlebars": "^4.7.8",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"inquirer": "^9.1.4",
@ -22885,30 +22859,6 @@
"version": "file:packages/bruno-schema",
"requires": {}
},
"@usebruno/testbench": {
"version": "file:packages/bruno-testbench",
"requires": {
"body-parser": "^1.20.0",
"config": "^3.3.8",
"cors": "^2.8.5",
"express": "^4.18.1",
"express-xml-bodyparser": "^0.3.0",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"multer": "^1.4.5-lts.1"
},
"dependencies": {
"argparse": {
"version": "2.0.1"
},
"js-yaml": {
"version": "4.1.0",
"requires": {
"argparse": "^2.0.1"
}
}
}
},
"@usebruno/tests": {
"version": "file:packages/bruno-tests",
"requires": {
@ -23753,6 +23703,7 @@
"requires": {
"@aws-sdk/credential-providers": "^3.425.0",
"@n8n/vm2": "^3.9.23",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.9.4",
"@usebruno/lang": "0.9.0",
"@usebruno/schema": "0.6.0",
@ -23775,7 +23726,6 @@
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"graphql": "^16.6.0",
"handlebars": "^4.7.8",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"is-valid-path": "^0.1.1",
@ -24373,12 +24323,6 @@
}
}
},
"config": {
"version": "3.3.9",
"requires": {
"json5": "^2.2.3"
}
},
"config-chain": {
"version": "1.1.13",
"dev": true,
@ -27310,7 +27254,8 @@
"version": "5.0.1"
},
"json5": {
"version": "2.2.3"
"version": "2.2.3",
"dev": true
},
"jsonfile": {
"version": "6.1.0",

View File

@ -18,6 +18,7 @@
"@reduxjs/toolkit": "^1.8.0",
"@tabler/icons": "^1.46.0",
"@tippyjs/react": "^4.2.6",
"@usebruno/common": "0.1.0",
"@usebruno/graphql-docs": "0.1.0",
"@usebruno/schema": "0.6.0",
"axios": "^1.5.1",
@ -34,7 +35,6 @@
"graphiql": "^1.5.9",
"graphql": "^16.6.0",
"graphql-request": "^3.7.0",
"handlebars": "^4.7.8",
"httpsnippet": "^3.0.1",
"idb": "^7.0.0",
"immer": "^9.0.15",

View File

@ -4,17 +4,19 @@ import CodeView from './CodeView';
import StyledWrapper from './StyledWrapper';
import { isValidUrl } from 'utils/url/index';
import get from 'lodash/get';
import handlebars from 'handlebars';
import { findEnvironmentInCollection } from 'utils/collections';
// Todo: Fix this
// import { interpolate } from '@usebruno/common';
const brunoCommon = require('@usebruno/common');
const { interpolate } = brunoCommon.default;
const interpolateUrl = ({ url, envVars, collectionVariables, processEnvVars }) => {
if (!url || !url.length || typeof url !== 'string') {
return;
}
const template = handlebars.compile(url, { noEscape: true });
return template({
return interpolate(url, {
...envVars,
...collectionVariables,
process: {

View File

@ -24,6 +24,7 @@
"package.json"
],
"dependencies": {
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.9.4",
"@usebruno/lang": "0.9.0",
"axios": "^1.5.1",
@ -32,7 +33,6 @@
"decomment": "^0.9.5",
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"handlebars": "^4.7.8",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"inquirer": "^9.1.4",

View File

@ -1,21 +1,5 @@
const Handlebars = require('handlebars');
const { forOwn, cloneDeep } = require('lodash');
const interpolateEnvVars = (str, processEnvVars) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
const template = Handlebars.compile(str, { noEscape: true });
return template({
process: {
env: {
...processEnvVars
}
}
});
};
const { interpolate } = require('@usebruno/common');
const interpolateString = (str, { envVars, collectionVariables, processEnvVars }) => {
if (!str || !str.length || typeof str !== 'string') {
@ -31,10 +15,14 @@ const interpolateString = (str, { envVars, collectionVariables, processEnvVars }
// envVars can inturn have values as {{process.env.VAR_NAME}}
// so we need to interpolate envVars first with processEnvVars
forOwn(envVars, (value, key) => {
envVars[key] = interpolateEnvVars(value, processEnvVars);
envVars[key] = interpolate(value, {
process: {
env: {
...processEnvVars
}
}
});
});
const template = Handlebars.compile(str, { noEscape: true });
// collectionVariables take precedence over envVars
const combinedVars = {
@ -47,7 +35,7 @@ const interpolateString = (str, { envVars, collectionVariables, processEnvVars }
}
};
return template(combinedVars);
return interpolate(str, combinedVars);
};
module.exports = {

View File

@ -1,4 +1,4 @@
const Handlebars = require('handlebars');
const { interpolate } = require('@usebruno/common');
const { each, forOwn, cloneDeep } = require('lodash');
const getContentType = (headers = {}) => {
@ -12,24 +12,6 @@ const getContentType = (headers = {}) => {
return contentType;
};
const interpolateEnvVars = (str, processEnvVars) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
const template = Handlebars.compile(str, { noEscape: true });
return template({
process: {
env: {
...processEnvVars
}
}
});
};
const varsRegex = /(?<!\\)\{\{(?!process\.env\.\w+)(.*\..*)\}\}/g;
const interpolateVars = (request, envVars = {}, collectionVariables = {}, processEnvVars = {}) => {
// we clone envVars because we don't want to modify the original object
envVars = cloneDeep(envVars);
@ -37,20 +19,20 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
// envVars can inturn have values as {{process.env.VAR_NAME}}
// so we need to interpolate envVars first with processEnvVars
forOwn(envVars, (value, key) => {
envVars[key] = interpolateEnvVars(value, processEnvVars);
envVars[key] = interpolate(value, {
process: {
env: {
...processEnvVars
}
}
});
});
const interpolate = (str) => {
const _interpolate = (str) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
if (varsRegex.test(str)) {
// Handlebars doesn't allow dots as identifiers, so we need to use literal segments
str = str.replaceAll(varsRegex, '{{[$1]}}');
}
const template = Handlebars.compile(str, { noEscape: true });
// collectionVariables take precedence over envVars
const combinedVars = {
...envVars,
@ -62,14 +44,14 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
}
};
return template(combinedVars);
return interpolate(str, combinedVars);
};
request.url = interpolate(request.url);
request.url = _interpolate(request.url);
forOwn(request.headers, (value, key) => {
delete request.headers[key];
request.headers[interpolate(key)] = interpolate(value);
request.headers[_interpolate(key)] = _interpolate(value);
});
const contentType = getContentType(request.headers);
@ -78,40 +60,40 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
if (typeof request.data === 'object') {
try {
let parsed = JSON.stringify(request.data);
parsed = interpolate(parsed);
parsed = _interpolate(parsed);
request.data = JSON.parse(parsed);
} catch (err) {}
}
if (typeof request.data === 'string') {
if (request.data.length) {
request.data = interpolate(request.data);
request.data = _interpolate(request.data);
}
}
} else if (contentType === 'application/x-www-form-urlencoded') {
if (typeof request.data === 'object') {
try {
let parsed = JSON.stringify(request.data);
parsed = interpolate(parsed);
parsed = _interpolate(parsed);
request.data = JSON.parse(parsed);
} catch (err) {}
}
} else {
request.data = interpolate(request.data);
request.data = _interpolate(request.data);
}
each(request.params, (param) => {
param.value = interpolate(param.value);
param.value = _interpolate(param.value);
});
if (request.proxy) {
request.proxy.protocol = interpolate(request.proxy.protocol);
request.proxy.hostname = interpolate(request.proxy.hostname);
request.proxy.port = interpolate(request.proxy.port);
request.proxy.protocol = _interpolate(request.proxy.protocol);
request.proxy.hostname = _interpolate(request.proxy.hostname);
request.proxy.port = _interpolate(request.proxy.port);
if (request.proxy.auth) {
request.proxy.auth.username = interpolate(request.proxy.auth.username);
request.proxy.auth.password = interpolate(request.proxy.auth.password);
request.proxy.auth.username = _interpolate(request.proxy.auth.username);
request.proxy.auth.password = _interpolate(request.proxy.auth.password);
}
}
@ -119,8 +101,8 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
// need to refactor this in the future
// the request.auth (basic auth) object gets set inside the prepare-request.js file
if (request.auth) {
const username = interpolate(request.auth.username) || '';
const password = interpolate(request.auth.password) || '';
const username = _interpolate(request.auth.username) || '';
const password = _interpolate(request.auth.password) || '';
// use auth header based approach and delete the request.auth object
request.headers['authorization'] = `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`;

View File

@ -82,3 +82,90 @@ describe('interpolate', () => {
expect(result).toBe('Hello, my name is Not Bruno and I am 4 years old');
});
});
describe('interpolate - template edge cases', () => {
it('should return the input string if the template is not a string', () => {
const inputString = 123;
const inputObject = {
user: 'Bruno'
};
const result = interpolate(inputString as any, inputObject);
expect(result).toBe(inputString);
});
it('should return the input string if the template is null', () => {
const inputString = null;
const inputObject = {
user: 'Bruno'
};
const result = interpolate(inputString as any, inputObject);
expect(result).toBe(inputString);
});
it('should return the input string if the template is undefined', () => {
const inputString = undefined;
const inputObject = {
user: 'Bruno'
};
const result = interpolate(inputString as any, inputObject);
expect(result).toBe(inputString);
});
it('should return the input string if the template is empty', () => {
const inputString = '';
const inputObject = {
user: 'Bruno'
};
const result = interpolate(inputString, inputObject);
expect(result).toBe(inputString);
});
it('should return preserve whitespaces', () => {
const inputString = ' ';
const inputObject = {
user: 'Bruno'
};
const result = interpolate(inputString, inputObject);
expect(result).toBe(inputString);
});
});
describe('interpolate - value edge cases', () => {
it('should return the input string if the value is not an object', () => {
const inputString = 'Hello, my name is {{user.name}}';
const inputObject = 123;
const result = interpolate(inputString, inputObject as any);
expect(result).toBe(inputString);
});
it('should return the input string if the value is null', () => {
const inputString = 'Hello, my name is {{user.name}}';
const inputObject = null;
const result = interpolate(inputString, inputObject as any);
expect(result).toBe(inputString);
});
it('should return the input string if the value is undefined', () => {
const inputString = 'Hello, my name is {{user.name}}';
const inputObject = undefined;
const result = interpolate(inputString, inputObject as any);
expect(result).toBe(inputString);
});
it('should return the input string if the value is empty', () => {
const inputString = 'Hello, my name is {{user.name}}';
const inputObject = {};
const result = interpolate(inputString, inputObject);
expect(result).toBe(inputString);
});
});

View File

@ -20,6 +20,7 @@
},
"dependencies": {
"@aws-sdk/credential-providers": "^3.425.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.9.4",
"@usebruno/lang": "0.9.0",
"@usebruno/schema": "0.6.0",
@ -38,7 +39,6 @@
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"graphql": "^16.6.0",
"handlebars": "^4.7.8",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.2",
"is-valid-path": "^0.1.1",

View File

@ -1,21 +1,5 @@
const Handlebars = require('handlebars');
const { forOwn, cloneDeep } = require('lodash');
const interpolateEnvVars = (str, processEnvVars) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
const template = Handlebars.compile(str, { noEscape: true });
return template({
process: {
env: {
...processEnvVars
}
}
});
};
const { interpolate } = require('@usebruno/common');
const interpolateString = (str, { envVars, collectionVariables, processEnvVars }) => {
if (!str || !str.length || typeof str !== 'string') {
@ -31,10 +15,14 @@ const interpolateString = (str, { envVars, collectionVariables, processEnvVars }
// envVars can inturn have values as {{process.env.VAR_NAME}}
// so we need to interpolate envVars first with processEnvVars
forOwn(envVars, (value, key) => {
envVars[key] = interpolateEnvVars(value, processEnvVars);
envVars[key] = interpolate(value, {
process: {
env: {
...processEnvVars
}
}
});
});
const template = Handlebars.compile(str, { noEscape: true });
// collectionVariables take precedence over envVars
const combinedVars = {
@ -47,7 +35,7 @@ const interpolateString = (str, { envVars, collectionVariables, processEnvVars }
}
};
return template(combinedVars);
return interpolate(str, combinedVars);
};
module.exports = {

View File

@ -1,4 +1,4 @@
const Handlebars = require('handlebars');
const { interpolate } = require('@usebruno/common');
const { each, forOwn, cloneDeep } = require('lodash');
const getContentType = (headers = {}) => {
@ -12,24 +12,6 @@ const getContentType = (headers = {}) => {
return contentType;
};
const interpolateEnvVars = (str, processEnvVars) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
const template = Handlebars.compile(str, { noEscape: true });
return template({
process: {
env: {
...processEnvVars
}
}
});
};
const varsRegex = /(?<!\\)\{\{(?!process\.env\.\w+)(.*\..*)\}\}/g;
const interpolateVars = (request, envVars = {}, collectionVariables = {}, processEnvVars = {}) => {
// we clone envVars because we don't want to modify the original object
envVars = cloneDeep(envVars);
@ -37,20 +19,20 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
// envVars can inturn have values as {{process.env.VAR_NAME}}
// so we need to interpolate envVars first with processEnvVars
forOwn(envVars, (value, key) => {
envVars[key] = interpolateEnvVars(value, processEnvVars);
envVars[key] = interpolate(value, {
process: {
env: {
...processEnvVars
}
}
});
});
const interpolate = (str) => {
const _interpolate = (str) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
if (varsRegex.test(str)) {
// Handlebars doesn't allow dots as identifiers, so we need to use literal segments
str = str.replaceAll(varsRegex, '{{[$1]}}');
}
const template = Handlebars.compile(str, { noEscape: true });
// collectionVariables take precedence over envVars
const combinedVars = {
...envVars,
@ -62,14 +44,14 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
}
};
return template(combinedVars);
return interpolate(str, combinedVars);
};
request.url = interpolate(request.url);
request.url = _interpolate(request.url);
forOwn(request.headers, (value, key) => {
delete request.headers[key];
request.headers[interpolate(key)] = interpolate(value);
request.headers[_interpolate(key)] = _interpolate(value);
});
const contentType = getContentType(request.headers);
@ -78,40 +60,40 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
if (typeof request.data === 'object') {
try {
let parsed = JSON.stringify(request.data);
parsed = interpolate(parsed);
parsed = _interpolate(parsed);
request.data = JSON.parse(parsed);
} catch (err) {}
}
if (typeof request.data === 'string') {
if (request.data.length) {
request.data = interpolate(request.data);
request.data = _interpolate(request.data);
}
}
} else if (contentType === 'application/x-www-form-urlencoded') {
if (typeof request.data === 'object') {
try {
let parsed = JSON.stringify(request.data);
parsed = interpolate(parsed);
parsed = _interpolate(parsed);
request.data = JSON.parse(parsed);
} catch (err) {}
}
} else {
request.data = interpolate(request.data);
request.data = _interpolate(request.data);
}
each(request.params, (param) => {
param.value = interpolate(param.value);
param.value = _interpolate(param.value);
});
if (request.proxy) {
request.proxy.protocol = interpolate(request.proxy.protocol);
request.proxy.hostname = interpolate(request.proxy.hostname);
request.proxy.port = interpolate(request.proxy.port);
request.proxy.protocol = _interpolate(request.proxy.protocol);
request.proxy.hostname = _interpolate(request.proxy.hostname);
request.proxy.port = _interpolate(request.proxy.port);
if (request.proxy.auth) {
request.proxy.auth.username = interpolate(request.proxy.auth.username);
request.proxy.auth.password = interpolate(request.proxy.auth.password);
request.proxy.auth.username = _interpolate(request.proxy.auth.username);
request.proxy.auth.password = _interpolate(request.proxy.auth.password);
}
}
@ -119,8 +101,8 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
// need to refactor this in the future
// the request.auth (basic auth) object gets set inside the prepare-request.js file
if (request.auth) {
const username = interpolate(request.auth.username) || '';
const password = interpolate(request.auth.password) || '';
const username = _interpolate(request.auth.username) || '';
const password = _interpolate(request.auth.password) || '';
// use auth header based approach and delete the request.auth object
request.headers['authorization'] = `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`;
@ -129,18 +111,18 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
// interpolate vars for aws sigv4 auth
if (request.awsv4config) {
request.awsv4config.accessKeyId = interpolate(request.awsv4config.accessKeyId) || '';
request.awsv4config.secretAccessKey = interpolate(request.awsv4config.secretAccessKey) || '';
request.awsv4config.sessionToken = interpolate(request.awsv4config.sessionToken) || '';
request.awsv4config.service = interpolate(request.awsv4config.service) || '';
request.awsv4config.region = interpolate(request.awsv4config.region) || '';
request.awsv4config.profileName = interpolate(request.awsv4config.profileName) || '';
request.awsv4config.accessKeyId = _interpolate(request.awsv4config.accessKeyId) || '';
request.awsv4config.secretAccessKey = _interpolate(request.awsv4config.secretAccessKey) || '';
request.awsv4config.sessionToken = _interpolate(request.awsv4config.sessionToken) || '';
request.awsv4config.service = _interpolate(request.awsv4config.service) || '';
request.awsv4config.region = _interpolate(request.awsv4config.region) || '';
request.awsv4config.profileName = _interpolate(request.awsv4config.profileName) || '';
}
// interpolate vars for digest auth
if (request.digestConfig) {
request.digestConfig.username = interpolate(request.digestConfig.username) || '';
request.digestConfig.password = interpolate(request.digestConfig.password) || '';
request.digestConfig.username = _interpolate(request.digestConfig.username) || '';
request.digestConfig.password = _interpolate(request.digestConfig.password) || '';
}
return request;

View File

@ -1,10 +1,10 @@
const Handlebars = require('handlebars');
const { interpolate } = require('@usebruno/common');
const { getIntrospectionQuery } = require('graphql');
const { setAuthHeaders } = require('./prepare-request');
const prepareGqlIntrospectionRequest = (endpoint, envVars, request, collectionRoot) => {
if (endpoint && endpoint.length) {
endpoint = Handlebars.compile(endpoint, { noEscape: true })(envVars);
endpoint = interpolate(endpoint, envVars);
}
const queryParams = {

View File

@ -70,13 +70,6 @@ describe('interpolate-vars: interpolateVars', () => {
describe('Does NOT interpolate string', () => {
describe('With environment variables', () => {
it('If the var is escaped', async () => {
const request = { method: 'GET', url: `\\{{test.url}}` };
const result = interpolateVars(request, { 'test.url': 'test.com' }, null, null);
expect(result.url).toEqual('{{test.url}}');
});
it("If it's not a var (no braces)", async () => {
const request = { method: 'GET', url: 'test' };
@ -106,25 +99,5 @@ describe('interpolate-vars: interpolateVars', () => {
expect(result.data).toEqual(gqlBody);
});
});
describe('With process environment variables', () => {
it("If there's a var that doesn't start with 'process.env.'", async () => {
const request = { method: 'GET', url: '{{process-env-TEST_VAR}}' };
const result = interpolateVars(request, null, null, { TEST_VAR: 'test.com' });
expect(result.url).toEqual('');
});
});
});
describe('Throws an error', () => {
it("If there's a var with an invalid character in its name", async () => {
'!@#%^&*()[{]}=+,<>;\\|'.split('').forEach((character) => {
const request = { method: 'GET', url: `{{test${character}Url}}` };
expect(() => interpolateVars(request, { [`test${character}Url`]: 'test.com' }, null, null)).toThrow(
/Parse error.*/
);
});
});
});
});

View File

@ -0,0 +1 @@
PROC_ENV_VAR=woof

View File

@ -0,0 +1 @@
!.env

View File

@ -1,7 +1,7 @@
meta {
name: echo plaintext
type: http
seq: 3
seq: 2
}
post {

View File

@ -1,7 +1,7 @@
meta {
name: echo xml parsed
type: http
seq: 4
seq: 3
}
post {

View File

@ -1,7 +1,7 @@
meta {
name: echo xml raw
type: http
seq: 5
seq: 4
}
post {

View File

@ -2,4 +2,7 @@ vars {
host: http://localhost:80
bearer_auth_token: your_secret_token
basic_auth_password: della
env.var1: envVar1
env-var2: envVar2
bark: {{process.env.PROC_ENV_VAR}}
}

View File

@ -0,0 +1,41 @@
meta {
name: env vars
type: http
seq: 2
}
post {
url: {{host}}/api/echo/json
body: json
auth: none
}
auth:basic {
username: asd
password: j
}
auth:bearer {
token:
}
body:json {
{
"envVar1": "{{env.var1}}",
"envVar2": "{{env-var2}}"
}
}
assert {
res.status: eq 200
}
tests {
test("should return json", function() {
expect(res.getBody()).to.eql({
"envVar1": "envVar1",
"envVar2": "envVar2"
});
});
}

View File

@ -0,0 +1,47 @@
meta {
name: missing values
type: http
seq: 1
}
post {
url: {{host}}/api/echo/json?foo={{undefinedVar}}
body: json
auth: none
}
query {
foo: {{undefinedVar}}
}
auth:basic {
username: asd
password: j
}
auth:bearer {
token:
}
body:json {
{
"hello": "{{undefinedVar2}}"
}
}
assert {
res.status: eq 200
}
tests {
test("should return json", function() {
const url = req.getUrl();
expect(url).to.equal("http://localhost:80/api/echo/json?foo={{undefinedVar}}");
const data = res.getBody();
expect(res.getBody()).to.eql({
"hello": "{{undefinedVar2}}"
});
});
}

View File

@ -0,0 +1,41 @@
meta {
name: process env vars
type: http
seq: 4
}
post {
url: {{host}}/api/echo/json
body: json
auth: none
}
auth:basic {
username: asd
password: j
}
auth:bearer {
token:
}
body:json {
{
"bark": "{{bark}}",
"bark2": "{{process.env.PROC_ENV_VAR}}"
}
}
assert {
res.status: eq 200
}
tests {
test("should return json", function() {
expect(res.getBody()).to.eql({
"bark": "woof",
"bark2": "woof"
});
});
}

View File

@ -0,0 +1,58 @@
meta {
name: runtime vars
type: http
seq: 3
}
post {
url: {{host}}/api/echo/text
body: text
auth: none
}
auth:basic {
username: asd
password: j
}
auth:bearer {
token:
}
body:json {
{
"envVar1": "{{env.var1}}",
"envVar2": "{{env-var2}}"
}
}
body:text {
Hi, I am {{rUser.full_name}},
I am {{rUser.age}} years old.
My favorite food is {{rUser.fav-food[0]}} and {{rUser.fav-food[1]}}.
I like attention: {{rUser.want.attention}}
}
assert {
res.status: eq 200
}
script:pre-request {
bru.setVar("rUser", {
full_name: 'Bruno',
age: 4,
'fav-food': ['egg', 'meat'],
'want.attention': true
});
}
tests {
test("should return json", function() {
const expectedResponse = `Hi, I am Bruno,
I am 4 years old.
My favorite food is egg and meat.
I like attention: true`;
expect(res.getBody()).to.equal(expectedResponse);
});
}