handleConfirmCollectionImportUpdate(true)}
+ onCancel={() => handleConfirmCollectionImportUpdate(false)}
+ />
+ ) : null}
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
index 75c6f2cb90..981141ad8e 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
@@ -185,7 +185,7 @@ export const saveFolderRoot = (collectionUid, folderUid) => (dispatch, getState)
export const sendCollectionOauth2Request = (collectionUid, itemUid) => (dispatch, getState) => {
const state = getState();
- const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
+ const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
@@ -196,7 +196,10 @@ export const sendCollectionOauth2Request = (collectionUid, itemUid) => (dispatch
let collectionCopy = cloneDeep(collection);
// add selected global env variables to the collection object
- const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({
+ globalEnvironments,
+ activeGlobalEnvironmentUid
+ });
collectionCopy.globalEnvironmentVariables = globalEnvironmentVariables;
const environment = findEnvironmentInCollection(collectionCopy, collection.activeEnvironmentUid);
@@ -219,7 +222,7 @@ export const sendCollectionOauth2Request = (collectionUid, itemUid) => (dispatch
export const sendRequest = (item, collectionUid) => (dispatch, getState) => {
const state = getState();
- const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
+ const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
@@ -231,7 +234,10 @@ export const sendRequest = (item, collectionUid) => (dispatch, getState) => {
let collectionCopy = cloneDeep(collection);
// add selected global env variables to the collection object
- const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({
+ globalEnvironments,
+ activeGlobalEnvironmentUid
+ });
collectionCopy.globalEnvironmentVariables = globalEnvironmentVariables;
const environment = findEnvironmentInCollection(collectionCopy, collectionCopy.activeEnvironmentUid);
@@ -297,7 +303,7 @@ export const cancelRunnerExecution = (cancelTokenUid) => (dispatch) => {
export const runCollectionFolder = (collectionUid, folderUid, recursive, delay) => (dispatch, getState) => {
const state = getState();
- const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
+ const { globalEnvironments, activeGlobalEnvironmentUid } = state.globalEnvironments;
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
@@ -308,7 +314,10 @@ export const runCollectionFolder = (collectionUid, folderUid, recursive, delay)
let collectionCopy = cloneDeep(collection);
// add selected global env variables to the collection object
- const globalEnvironmentVariables = getGlobalEnvironmentVariables({ globalEnvironments, activeGlobalEnvironmentUid });
+ const globalEnvironmentVariables = getGlobalEnvironmentVariables({
+ globalEnvironments,
+ activeGlobalEnvironmentUid
+ });
collectionCopy.globalEnvironmentVariables = globalEnvironmentVariables;
const folder = findItemInCollection(collectionCopy, folderUid);
@@ -989,15 +998,16 @@ export const selectEnvironment = (environmentUid, collectionUid) => (dispatch, g
const collectionCopy = cloneDeep(collection);
- const environmentName = environmentUid
- ? findEnvironmentInCollection(collectionCopy, environmentUid)?.name
- : null;
+ const environmentName = environmentUid ? findEnvironmentInCollection(collectionCopy, environmentUid)?.name : null;
if (environmentUid && !environmentName) {
return reject(new Error('Environment not found'));
- }
-
- ipcRenderer.invoke('renderer:update-ui-state-snapshot', { type: 'COLLECTION_ENVIRONMENT', data: { collectionPath: collection?.pathname, environmentName }});
+ }
+
+ ipcRenderer.invoke('renderer:update-ui-state-snapshot', {
+ type: 'COLLECTION_ENVIRONMENT',
+ data: { collectionPath: collection?.pathname, environmentName }
+ });
dispatch(_selectEnvironment({ environmentUid, collectionUid }));
resolve();
@@ -1140,11 +1150,14 @@ export const collectionAddEnvFileEvent = (payload) => (dispatch, getState) => {
});
};
-export const importCollection = (collection, collectionLocation) => (dispatch, getState) => {
+export const importCollection = (collection, collectionLocation, updateExistingCollection) => (dispatch, getState) => {
return new Promise((resolve, reject) => {
const { ipcRenderer } = window;
- ipcRenderer.invoke('renderer:import-collection', collection, collectionLocation).then(resolve).catch(reject);
+ ipcRenderer
+ .invoke('renderer:import-collection', collection, collectionLocation, updateExistingCollection)
+ .then(resolve)
+ .catch(reject);
});
};
@@ -1164,32 +1177,30 @@ export const saveCollectionSecurityConfig = (collectionUid, securityConfig) => (
});
};
-
export const hydrateCollectionWithUiStateSnapshot = (payload) => (dispatch, getState) => {
- const collectionSnapshotData = payload;
- return new Promise((resolve, reject) => {
- const state = getState();
- try {
- if(!collectionSnapshotData) resolve();
- const { pathname, selectedEnvironment } = collectionSnapshotData;
- const collection = findCollectionByPathname(state.collections.collections, pathname);
- const collectionCopy = cloneDeep(collection);
- const collectionUid = collectionCopy?.uid;
-
- // update selected environment
- if (selectedEnvironment) {
- const environment = findEnvironmentInCollectionByName(collectionCopy, selectedEnvironment);
- if (environment) {
- dispatch(_selectEnvironment({ environmentUid: environment?.uid, collectionUid }));
- }
+ const collectionSnapshotData = payload;
+ return new Promise((resolve, reject) => {
+ const state = getState();
+ try {
+ if (!collectionSnapshotData) resolve();
+ const { pathname, selectedEnvironment } = collectionSnapshotData;
+ const collection = findCollectionByPathname(state.collections.collections, pathname);
+ const collectionCopy = cloneDeep(collection);
+ const collectionUid = collectionCopy?.uid;
+
+ // update selected environment
+ if (selectedEnvironment) {
+ const environment = findEnvironmentInCollectionByName(collectionCopy, selectedEnvironment);
+ if (environment) {
+ dispatch(_selectEnvironment({ environmentUid: environment?.uid, collectionUid }));
}
-
- // todo: add any other redux state that you want to save
-
- resolve();
- }
- catch(error) {
- reject(error);
}
- });
- };
\ No newline at end of file
+
+ // todo: add any other redux state that you want to save
+
+ resolve();
+ } catch (error) {
+ reject(error);
+ }
+ });
+};
diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js
index 38261cdb7d..d173fa5676 100644
--- a/packages/bruno-electron/src/ipc/collection.js
+++ b/packages/bruno-electron/src/ipc/collection.js
@@ -459,100 +459,127 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
}
});
- ipcMain.handle('renderer:import-collection', async (event, collection, collectionLocation) => {
- try {
- let collectionName = sanitizeDirectoryName(collection.name);
- let collectionPath = path.join(collectionLocation, collectionName);
+ ipcMain.handle(
+ 'renderer:import-collection',
+ async (event, collection, collectionLocation, updateExistingCollection = false) => {
+ try {
+ let collectionName = sanitizeDirectoryName(collection.name);
+ let collectionPath = path.join(collectionLocation, collectionName);
- if (fs.existsSync(collectionPath)) {
- throw new Error(`collection: ${collectionPath} already exists`);
- }
+ if (fs.existsSync(collectionPath) && !updateExistingCollection) {
+ throw new Error(`collection already exists: ${collectionPath}`);
+ }
- // Recursive function to parse the collection items and create files/folders
- const parseCollectionItems = (items = [], currentPath) => {
- items.forEach((item) => {
- if (['http-request', 'graphql-request'].includes(item.type)) {
- const content = jsonToBru(item);
- const filePath = path.join(currentPath, `${item.name}.bru`);
+ /**
+ * @returns whether the the given file was written. If this method returns,
+ * the file now definitely exists
+ */
+ const writeContentIfFileDoesNotExist = (filePath, content) => {
+ if (fs.existsSync(filePath)) {
+ return false;
+ } else {
fs.writeFileSync(filePath, content);
+ return true;
}
- if (item.type === 'folder') {
- const folderPath = path.join(currentPath, item.name);
+ };
+
+ /**
+ * @returns whether the the given directory was created. If this method returns,
+ * the directory now definitely exists
+ */
+ const createDirectoryIfDirectoryDoesNotExist = (folderPath) => {
+ if (!fs.existsSync(folderPath)) {
fs.mkdirSync(folderPath);
+ return true;
+ } else {
+ return false;
+ }
+ };
- if (item?.root?.meta?.name) {
- const folderBruFilePath = path.join(folderPath, 'folder.bru');
- const folderContent = jsonToCollectionBru(
- item.root,
- true // isFolder
- );
- fs.writeFileSync(folderBruFilePath, folderContent);
+ // Recursive function to parse the collection items and create files/folders
+ const parseCollectionItems = (items = [], currentPath) => {
+ items.forEach((item) => {
+ if (['http-request', 'graphql-request'].includes(item.type)) {
+ const content = jsonToBru(item);
+ const filePath = path.join(currentPath, `${item.name}.bru`);
+ writeContentIfFileDoesNotExist(filePath, content);
}
+ if (item.type === 'folder') {
+ const folderPath = path.join(currentPath, item.name);
+ createDirectoryIfDirectoryDoesNotExist(folderPath);
+
+ if (item?.root?.meta?.name) {
+ const folderBruFilePath = path.join(folderPath, 'folder.bru');
+ const folderContent = jsonToCollectionBru(
+ item.root,
+ true // isFolder
+ );
+ writeContentIfFileDoesNotExist(folderBruFilePath, folderContent);
+ }
- if (item.items && item.items.length) {
- parseCollectionItems(item.items, folderPath);
+ if (item.items && item.items.length) {
+ parseCollectionItems(item.items, folderPath);
+ }
}
- }
- // Handle items of type 'js'
- if (item.type === 'js') {
- const filePath = path.join(currentPath, `${item.name}.js`);
- fs.writeFileSync(filePath, item.fileContent);
- }
- });
- };
+ // Handle items of type 'js'
+ if (item.type === 'js') {
+ const filePath = path.join(currentPath, `${item.name}.js`);
+ writeContentIfFileDoesNotExist(filePath, item.fileContent);
+ }
+ });
+ };
- const parseEnvironments = (environments = [], collectionPath) => {
- const envDirPath = path.join(collectionPath, 'environments');
- if (!fs.existsSync(envDirPath)) {
- fs.mkdirSync(envDirPath);
- }
+ const parseEnvironments = (environments = [], collectionPath) => {
+ const envDirPath = path.join(collectionPath, 'environments');
+ createDirectoryIfDirectoryDoesNotExist(envDirPath);
- environments.forEach((env) => {
- const content = envJsonToBru(env);
- const filePath = path.join(envDirPath, `${env.name}.bru`);
- fs.writeFileSync(filePath, content);
- });
- };
+ environments.forEach((env) => {
+ const content = envJsonToBru(env);
+ const filePath = path.join(envDirPath, `${env.name}.bru`);
+ writeContentIfFileDoesNotExist(filePath, content);
+ });
+ };
- const getBrunoJsonConfig = (collection) => {
- let brunoConfig = collection.brunoConfig;
+ const getBrunoJsonConfig = (collection) => {
+ let brunoConfig = collection.brunoConfig;
- if (!brunoConfig) {
- brunoConfig = {
- version: '1',
- name: collection.name,
- type: 'collection',
- ignore: ['node_modules', '.git']
- };
- }
+ if (!brunoConfig) {
+ brunoConfig = {
+ version: '1',
+ name: collection.name,
+ type: 'collection',
+ ignore: ['node_modules', '.git']
+ };
+ }
- return brunoConfig;
- };
+ return brunoConfig;
+ };
- await createDirectory(collectionPath);
+ createDirectoryIfDirectoryDoesNotExist(collectionPath);
- const uid = generateUidBasedOnHash(collectionPath);
- const brunoConfig = getBrunoJsonConfig(collection);
- const stringifiedBrunoConfig = await stringifyJson(brunoConfig);
+ const uid = generateUidBasedOnHash(collectionPath);
+ const brunoConfig = getBrunoJsonConfig(collection);
+ const stringifiedBrunoConfig = await stringifyJson(brunoConfig);
- // Write the Bruno configuration to a file
- await writeFile(path.join(collectionPath, 'bruno.json'), stringifiedBrunoConfig);
+ // Write the Bruno configuration to a file
+ writeContentIfFileDoesNotExist(path.join(collectionPath, 'bruno.json'), stringifiedBrunoConfig);
- const collectionContent = jsonToCollectionBru(collection.root);
- await writeFile(path.join(collectionPath, 'collection.bru'), collectionContent);
+ const collectionContent = jsonToCollectionBru(collection.root);
+ writeContentIfFileDoesNotExist(path.join(collectionPath, 'collection.bru'), collectionContent);
- mainWindow.webContents.send('main:collection-opened', collectionPath, uid, brunoConfig);
- ipcMain.emit('main:collection-opened', mainWindow, collectionPath, uid, brunoConfig);
+ mainWindow.webContents.send('main:collection-opened', collectionPath, uid, brunoConfig);
+ ipcMain.emit('main:collection-opened', mainWindow, collectionPath, uid, brunoConfig);
- lastOpenedCollections.add(collectionPath);
+ lastOpenedCollections.add(collectionPath);
- // create folder and files based on collection
- await parseCollectionItems(collection.items, collectionPath);
- await parseEnvironments(collection.environments, collectionPath);
- } catch (error) {
- return Promise.reject(error);
+ // create folder and files based on collection
+ parseCollectionItems(collection.items, collectionPath);
+ parseEnvironments(collection.environments, collectionPath);
+ } catch (error) {
+ return Promise.reject(error);
+ }
}
- });
+ );
ipcMain.handle('renderer:clone-folder', async (event, itemFolder, collectionPath) => {
try {