Merge pull request #589 from premeaswaran/main

Feature: Support Import postman environment - Fixes issue #193
This commit is contained in:
Anoop M D 2023-10-16 02:20:26 +05:30 committed by GitHub
commit 4dd17247d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 156 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import usePrevious from 'hooks/usePrevious';
import EnvironmentDetails from './EnvironmentDetails'; import EnvironmentDetails from './EnvironmentDetails';
import CreateEnvironment from '../CreateEnvironment/index'; import CreateEnvironment from '../CreateEnvironment/index';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
import ImportEnvironment from "components/Environments/EnvironmentSettings/ImportEnvironment";
const EnvironmentList = ({ collection }) => { const EnvironmentList = ({ collection }) => {
const { environments } = collection; const { environments } = collection;
@ -65,6 +66,7 @@ const EnvironmentList = ({ collection }) => {
<div className="btn-create-environment" onClick={() => setOpenCreateModal(true)}> <div className="btn-create-environment" onClick={() => setOpenCreateModal(true)}>
+ <span>Create</span> + <span>Create</span>
</div> </div>
<ImportEnvironment title={"Import"} collectionUid={collection.uid}/>
</div> </div>
</div> </div>
<EnvironmentDetails environment={selectedEnvironment} collection={collection} /> <EnvironmentDetails environment={selectedEnvironment} collection={collection} />

View File

@ -0,0 +1,33 @@
import toast from "react-hot-toast";
import {toastError} from "utils/common/error";
import {useDispatch} from "react-redux";
import {importEnvironment} from "providers/ReduxStore/slices/collections/actions";
import importPostmanEnvironment from "utils/importers/postman-environment";
import React from "react";
const ImportEnvironment = ({title, collectionUid}) => {
const dispatch = useDispatch();
const handleImportPostmanEnvironment = () => {
importPostmanEnvironment()
.then((environment) => {
dispatch(importEnvironment(environment.name, environment.variables, collectionUid))
.then(() => {
toast.success('Environment imported successfully');
})
.catch(() => toast.error('An error occurred while importing the environment'));
})
.catch((err) => toastError(err, 'Postman Import environment failed'));
};
return(
<button
className="btn-create-environment text-link pr-2 py-2 mt-2 select-none"
onClick={handleImportPostmanEnvironment}
>
+ <span>{title}</span>
</button>
);
};
export default ImportEnvironment;

View File

@ -3,6 +3,7 @@ import React, { useState } from 'react';
import CreateEnvironment from './CreateEnvironment'; import CreateEnvironment from './CreateEnvironment';
import EnvironmentList from './EnvironmentList'; import EnvironmentList from './EnvironmentList';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
import ImportEnvironment from "components/Environments/EnvironmentSettings/ImportEnvironment";
const EnvironmentSettings = ({ collection, onClose }) => { const EnvironmentSettings = ({ collection, onClose }) => {
const { environments } = collection; const { environments } = collection;
@ -28,6 +29,7 @@ const EnvironmentSettings = ({ collection, onClose }) => {
> >
+ <span>Create Environment</span> + <span>Create Environment</span>
</button> </button>
<ImportEnvironment title={"Import Postman Environment"} collectionUid={collection.uid}/>
</div> </div>
</Modal> </Modal>
</StyledWrapper> </StyledWrapper>

View File

@ -722,6 +722,32 @@ export const addEnvironment = (name, collectionUid) => (dispatch, getState) => {
}); });
}; };
export const importEnvironment = (name, variables, collectionUid) => (dispatch, getState) => {
return new Promise((resolve, reject) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if (!collection) {
return reject(new Error('Collection not found'));
}
ipcRenderer
.invoke('renderer:import-environment', collection.pathname, name, variables)
.then(
dispatch(
updateLastAction({
collectionUid,
lastAction: {
type: 'ADD_ENVIRONMENT',
payload: name
}
})
)
)
.then(resolve)
.catch(reject);
});
};
export const copyEnvironment = (name, baseEnvUid, collectionUid) => (dispatch, getState) => { export const copyEnvironment = (name, baseEnvUid, collectionUid) => (dispatch, getState) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const state = getState(); const state = getState();

View File

@ -0,0 +1,71 @@
import each from 'lodash/each';
import fileDialog from 'file-dialog';
import { BrunoError } from 'utils/common/error';
const readFile = (files) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = (e) => resolve(e.target.result);
fileReader.onerror = (err) => reject(err);
fileReader.readAsText(files[0]);
});
};
const isSecret = (type) => {
return type === 'secret';
};
const importPostmanEnvironmentVariables = (brunoEnvironment, values) => {
brunoEnvironment.variables = brunoEnvironment.variables || [];
each(values, (i) => {
const brunoEnvironmentVariable = {
name: i.key,
value: i.value,
enabled: i.enabled,
secret: isSecret(i.type)
};
brunoEnvironment.variables.push(brunoEnvironmentVariable);
});
};
const importPostmanEnvironment = (environment) => {
const brunoEnvironment = {
name: environment.name,
variables: []
};
importPostmanEnvironmentVariables(brunoEnvironment, environment.values);
return brunoEnvironment;
};
const parsePostmanEnvironment = (str) => {
return new Promise((resolve, reject) => {
try {
let environment = JSON.parse(str);
return resolve(importPostmanEnvironment(environment));
} catch (err) {
console.log(err);
if (err instanceof BrunoError) {
return reject(err);
}
return reject(new BrunoError('Unable to parse the postman environment json file'));
}
});
};
const importEnvironment = () => {
return new Promise((resolve, reject) => {
fileDialog({ accept: 'application/json' })
.then(readFile)
.then(parsePostmanEnvironment)
.then((environment) => resolve(environment))
.catch((err) => {
console.log(err);
reject(new BrunoError('Import Environment failed'));
});
});
};
export default importEnvironment;

View File

@ -183,6 +183,28 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
} }
}); });
// copy environment
ipcMain.handle('renderer:import-environment', async (event, collectionPathname, name, variables) => {
try {
const envDirPath = path.join(collectionPathname, 'environments');
if (!fs.existsSync(envDirPath)) {
await createDirectory(envDirPath);
}
const envFilePath = path.join(envDirPath, `${name}.bru`);
if (fs.existsSync(envFilePath)) {
throw new Error(`environment: ${envFilePath} already exists`);
}
const content = envJsonToBru({
variables: variables
});
await writeFile(envFilePath, content);
} catch (error) {
return Promise.reject(error);
}
});
// save environment // save environment
ipcMain.handle('renderer:save-environment', async (event, collectionPathname, environment) => { ipcMain.handle('renderer:save-environment', async (event, collectionPathname, environment) => {
try { try {