feat(#199): bru cli updates to load .env vars

This commit is contained in:
Anoop M D 2023-09-25 02:10:12 +05:30
parent eb010adeac
commit eb6b75ff98
8 changed files with 91 additions and 20 deletions

View File

@ -1,9 +1,14 @@
# Changelog
## 0.8.0
- `--env-var` flag to set environment variables
- loading environment variables from `.env` file
## 0.7.1
* `--cacert` flag to support custom CA certificates
- `--cacert` flag to support custom CA certificates
## 0.7.0
* `--insecure` flag to disable SSL verification
- `--insecure` flag to disable SSL verification

View File

@ -1,6 +1,6 @@
{
"name": "@usebruno/cli",
"version": "0.7.1",
"version": "0.8.0",
"main": "src/index.js",
"bin": {
"bru": "./bin/bru.js"
@ -20,13 +20,14 @@
"package.json"
],
"dependencies": {
"@usebruno/js": "0.4.0",
"@usebruno/lang": "0.3.0",
"@usebruno/js": "0.5.0",
"@usebruno/lang": "0.4.0",
"axios": "^1.3.2",
"chai": "^4.3.7",
"chalk": "^3.0.0",
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"handlebars": "^4.7.8",
"inquirer": "^9.1.4",
"lodash": "^4.17.21",
"mustache": "^4.2.0",

View File

@ -1,11 +1,13 @@
const fs = require('fs');
const chalk = require('chalk');
const path = require('path');
const { forOwn } = require('lodash');
const { exists, isFile, isDirectory } = require('../utils/filesystem');
const { runSingleRequest } = require('../runner/run-single-request');
const { bruToEnvJson, getEnvVars } = require('../utils/bru');
const { rpad } = require('../utils/common');
const { bruToJson, getOptions } = require('../utils/bru');
const { dotenvToJson } = require('@usebruno/lang');
const command = 'run [filename]';
const desc = 'Run a request';
@ -225,12 +227,34 @@ const handler = async function (argv) {
}
}
// load .env file at root of collection if it exists
const dotEnvPath = path.join(collectionPath, '.env');
const dotEnvExists = await exists(dotEnvPath);
const processEnvVars = {
...process.env
};
if (dotEnvExists) {
const content = fs.readFileSync(dotEnvPath, 'utf8');
const jsonData = dotenvToJson(content);
forOwn(jsonData, (value, key) => {
processEnvVars[key] = value;
});
}
const _isFile = await isFile(filename);
if (_isFile) {
console.log(chalk.yellow('Running Request \n'));
const bruContent = fs.readFileSync(filename, 'utf8');
const bruJson = bruToJson(bruContent);
const result = await runSingleRequest(filename, bruJson, collectionPath, collectionVariables, envVars);
const result = await runSingleRequest(
filename,
bruJson,
collectionPath,
collectionVariables,
envVars,
processEnvVars
);
if (result) {
const { assertionResults, testResults } = result;
@ -281,7 +305,14 @@ const handler = async function (argv) {
for (const iter of bruJsons) {
const { bruFilepath, bruJson } = iter;
const result = await runSingleRequest(bruFilepath, bruJson, collectionPath, collectionVariables, envVars);
const result = await runSingleRequest(
bruFilepath,
bruJson,
collectionPath,
collectionVariables,
envVars,
processEnvVars
);
if (result) {
const { assertionResults: _assertionResults, testResults: _testResults } = result;

View File

@ -1,24 +1,51 @@
const Mustache = require('mustache');
const { each, forOwn } = require('lodash');
const Handlebars = require('handlebars');
const { each, forOwn, cloneDeep } = require('lodash');
// override the default escape function to prevent escaping
Mustache.escape = function (value) {
return value;
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 interpolateVars = (request, envVars = {}, collectionVariables = {}) => {
const interpolateVars = (request, envVars = {}, collectionVariables = {}, processEnvVars = {}) => {
// we clone envVars because we don't want to modify the original object
envVars = cloneDeep(envVars);
// 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);
});
const interpolate = (str) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
const template = Handlebars.compile(str, { noEscape: true });
// collectionVariables take precedence over envVars
const combinedVars = {
...envVars,
...collectionVariables
...collectionVariables,
process: {
env: {
...processEnvVars
}
}
};
return Mustache.render(str, combinedVars);
return template(combinedVars);
};
request.url = interpolate(request.url);

View File

@ -11,7 +11,14 @@ const { ScriptRuntime, TestRuntime, VarsRuntime, AssertRuntime } = require('@use
const { stripExtension } = require('../utils/filesystem');
const { getOptions } = require('../utils/bru');
const runSingleRequest = async function (filename, bruJson, collectionPath, collectionVariables, envVariables) {
const runSingleRequest = async function (
filename,
bruJson,
collectionPath,
collectionVariables,
envVariables,
processEnvVars
) {
let request;
try {
@ -49,7 +56,7 @@ const runSingleRequest = async function (filename, bruJson, collectionPath, coll
}
// interpolate variables inside request
interpolateVars(request, envVariables, collectionVariables);
interpolateVars(request, envVariables, collectionVariables, processEnvVars);
const options = getOptions();
const insecure = get(options, 'insecure', false);

View File

@ -1,6 +1,6 @@
{
"name": "@usebruno/js",
"version": "0.4.0",
"version": "0.5.0",
"main": "src/index.js",
"files": [
"src",

View File

@ -1,6 +1,6 @@
{
"name": "@usebruno/lang",
"version": "0.3.0",
"version": "0.4.0",
"main": "src/index.js",
"files": [
"src",

View File

@ -1,6 +1,6 @@
{
"name": "@usebruno/schema",
"version": "0.3.1",
"version": "0.4.0",
"main": "src/index.js",
"files": [
"src",