feat(#224): proxy support feature - electron layer

This commit is contained in:
Anoop M D 2023-09-28 00:58:05 +05:30
parent 8780d309ac
commit c0b7dad030
6 changed files with 91 additions and 13 deletions

View File

@ -18,7 +18,7 @@
"@usebruno/lang": "0.4.0", "@usebruno/lang": "0.4.0",
"@usebruno/schema": "0.4.0", "@usebruno/schema": "0.4.0",
"about-window": "^1.15.2", "about-window": "^1.15.2",
"axios": "^0.26.0", "axios": "^1.5.1",
"chai": "^4.3.7", "chai": "^4.3.7",
"chokidar": "^3.5.3", "chokidar": "^3.5.3",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",

View File

@ -5,20 +5,12 @@ const Yup = require('yup');
const { isDirectory, normalizeAndResolvePath } = require('../utils/filesystem'); const { isDirectory, normalizeAndResolvePath } = require('../utils/filesystem');
const { generateUidBasedOnHash } = require('../utils/common'); const { generateUidBasedOnHash } = require('../utils/common');
// uid inside collections is deprecated, but we still need to validate it // todo: bruno.json config schema validation errors must be propagated to the UI
// for backward compatibility
const uidSchema = Yup.string()
.length(21, 'uid must be 21 characters in length')
.matches(/^[a-zA-Z0-9]*$/, 'uid must be alphanumeric');
const configSchema = Yup.object({ const configSchema = Yup.object({
uid: uidSchema, name: Yup.string().max(256, 'name must be 256 characters or less').required('name is required'),
name: Yup.string().nullable().max(256, 'name must be 256 characters or less'),
type: Yup.string().oneOf(['collection']).required('type is required'), type: Yup.string().oneOf(['collection']).required('type is required'),
version: Yup.string().oneOf(['1']).required('type is required') version: Yup.string().oneOf(['1']).required('type is required')
}) });
.noUnknown(true)
.strict();
const readConfigFile = async (pathname) => { const readConfigFile = async (pathname) => {
try { try {

View File

@ -12,6 +12,7 @@ const { uuid } = require('../utils/common');
const { getRequestUid } = require('../cache/requestUids'); const { getRequestUid } = require('../cache/requestUids');
const { decryptString } = require('../utils/encryption'); const { decryptString } = require('../utils/encryption');
const { setDotEnvVars } = require('../store/process-env'); const { setDotEnvVars } = require('../store/process-env');
const { setBrunoConfig } = require('../store/bruno-config');
const EnvironmentSecretsStore = require('../store/env-secrets'); const EnvironmentSecretsStore = require('../store/env-secrets');
const environmentSecretsStore = new EnvironmentSecretsStore(); const environmentSecretsStore = new EnvironmentSecretsStore();
@ -30,6 +31,13 @@ const isDotEnvFile = (pathname, collectionPath) => {
return dirname === collectionPath && basename === '.env'; return dirname === collectionPath && basename === '.env';
}; };
const isBrunoConfigFile = (pathname, collectionPath) => {
const dirname = path.dirname(pathname);
const basename = path.basename(pathname);
return dirname === collectionPath && basename === 'bruno.json';
};
const isBruEnvironmentConfig = (pathname, collectionPath) => { const isBruEnvironmentConfig = (pathname, collectionPath) => {
const dirname = path.dirname(pathname); const dirname = path.dirname(pathname);
const envDirectory = path.join(collectionPath, 'environments'); const envDirectory = path.join(collectionPath, 'environments');
@ -167,6 +175,17 @@ const unlinkEnvironmentFile = async (win, pathname, collectionUid) => {
const add = async (win, pathname, collectionUid, collectionPath) => { const add = async (win, pathname, collectionUid, collectionPath) => {
console.log(`watcher add: ${pathname}`); console.log(`watcher add: ${pathname}`);
if (isBrunoConfigFile(pathname, collectionPath)) {
try {
const content = fs.readFileSync(pathname, 'utf8');
const jsonData = JSON.parse(content);
setBrunoConfig(collectionUid, jsonData);
} catch (err) {
console.error(err);
}
}
if (isDotEnvFile(pathname, collectionPath)) { if (isDotEnvFile(pathname, collectionPath)) {
try { try {
const content = fs.readFileSync(pathname, 'utf8'); const content = fs.readFileSync(pathname, 'utf8');
@ -281,6 +300,17 @@ const addDirectory = (win, pathname, collectionUid, collectionPath) => {
}; };
const change = async (win, pathname, collectionUid, collectionPath) => { const change = async (win, pathname, collectionUid, collectionPath) => {
if (isBrunoConfigFile(pathname, collectionPath)) {
try {
const content = fs.readFileSync(pathname, 'utf8');
const jsonData = JSON.parse(content);
setBrunoConfig(collectionUid, jsonData);
} catch (err) {
console.error(err);
}
}
if (isDotEnvFile(pathname, collectionPath)) { if (isDotEnvFile(pathname, collectionPath)) {
try { try {
const content = fs.readFileSync(pathname, 'utf8'); const content = fs.readFileSync(pathname, 'utf8');
@ -378,7 +408,7 @@ class Watcher {
const watcher = chokidar.watch(watchPath, { const watcher = chokidar.watch(watchPath, {
ignoreInitial: false, ignoreInitial: false,
usePolling: false, usePolling: false,
ignored: (path) => ['node_modules', '.git', 'bruno.json'].some((s) => path.includes(s)), ignored: (path) => ['node_modules', '.git'].some((s) => path.includes(s)),
persistent: true, persistent: true,
ignorePermissionErrors: true, ignorePermissionErrors: true,
awaitWriteFinish: { awaitWriteFinish: {

View File

@ -14,6 +14,7 @@ const interpolateVars = require('./interpolate-vars');
const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper'); const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
const { getPreferences } = require('../../store/preferences'); const { getPreferences } = require('../../store/preferences');
const { getProcessEnvVars } = require('../../store/process-env'); const { getProcessEnvVars } = require('../../store/process-env');
const { getBrunoConfig } = require('../../store/bruno-config');
// override the default escape function to prevent escaping // override the default escape function to prevent escaping
Mustache.escape = function (value) { Mustache.escape = function (value) {
@ -163,6 +164,31 @@ const registerNetworkIpc = (mainWindow) => {
const processEnvVars = getProcessEnvVars(collectionUid); const processEnvVars = getProcessEnvVars(collectionUid);
const brunoConfig = getBrunoConfig(collectionUid);
const proxyEnabled = get(brunoConfig, 'proxy.enabled', false);
if (proxyEnabled) {
const proxyProtocol = get(brunoConfig, 'proxy.protocol');
const proxyHostname = get(brunoConfig, 'proxy.hostname');
const proxyPort = get(brunoConfig, 'proxy.port');
const proxyAuthEnabled = get(brunoConfig, 'proxy.auth.enabled', false);
const proxyConfig = {
protocol: proxyProtocol,
hostname: proxyHostname,
port: proxyPort
};
if (proxyAuthEnabled) {
const proxyAuthUsername = get(brunoConfig, 'proxy.auth.username');
const proxyAuthPassword = get(brunoConfig, 'proxy.auth.password');
proxyConfig.auth = {
username: proxyAuthUsername,
password: proxyAuthPassword
};
}
request.proxy = proxyConfig;
}
interpolateVars(request, envVars, collectionVariables, processEnvVars); interpolateVars(request, envVars, collectionVariables, processEnvVars);
// stringify the request url encoded params // stringify the request url encoded params

View File

@ -84,6 +84,17 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces
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);
if (request.proxy.auth) {
request.proxy.auth.username = interpolate(request.proxy.auth.username);
request.proxy.auth.password = interpolate(request.proxy.auth.password);
}
}
return request; return request;
}; };

View File

@ -0,0 +1,19 @@
/**
* This modules stores the configs loaded from bruno.json
*/
const config = {};
// collectionUid is a hash based on the collection path)
const getBrunoConfig = (collectionUid) => {
return config[collectionUid] || {};
};
const setBrunoConfig = (collectionUid, brunoConfig) => {
config[collectionUid] = brunoConfig;
};
module.exports = {
getBrunoConfig,
setBrunoConfig
};