diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js
index 3c9f27115..b840885de 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js
@@ -6,7 +6,7 @@ import { useDrag, useDrop } from 'react-dnd';
import { IconChevronRight, IconDots } from '@tabler/icons';
import { useSelector, useDispatch } from 'react-redux';
import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs';
-import { moveItem, sendRequest } from 'providers/ReduxStore/slices/collections/actions';
+import { moveItem, revealInFinder, sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import { collectionFolderClicked } from 'providers/ReduxStore/slices/collections';
import Dropdown from 'components/Dropdown';
import NewRequest from 'components/Sidebar/NewRequest';
@@ -220,6 +220,12 @@ const CollectionItem = ({ item, collection, searchText }) => {
}
};
+ const handleReveal = () => {
+ dispatch(revealInFinder(item.pathname)).catch((error) => {
+ toast.error('Error revealing file:', error);
+ });
+ };
+
const requestItems = sortRequestItems(filter(item.items, (i) => isItemARequest(i)));
const folderItems = sortFolderItems(filter(item.items, (i) => isItemAFolder(i)));
@@ -371,6 +377,17 @@ const CollectionItem = ({ item, collection, searchText }) => {
Generate Code
)}
+ {!isFolder && (
+
{
+ dropdownTippyRef.current.hide();
+ handleReveal();
+ }}
+ >
+ Reveal in Finder
+
+ )}
{
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 de9ad78e9..513c2f798 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
@@ -1219,3 +1219,12 @@ export const mountCollection = ({ collectionUid, collectionPathname, brunoConfig
});
});
};
+
+ export const revealInFinder = (collectionPath) => () => {
+ return new Promise((resolve, reject) => {
+ const { ipcRenderer } = window;
+
+ ipcRenderer.invoke('renderer:reveal-in-finder', collectionPath).then(resolve).catch(reject);
+ });
+ };
+
diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js
index b9061a227..f04b49619 100644
--- a/packages/bruno-electron/src/ipc/collection.js
+++ b/packages/bruno-electron/src/ipc/collection.js
@@ -3,6 +3,7 @@ const fs = require('fs');
const fsExtra = require('fs-extra');
const os = require('os');
const path = require('path');
+const { exec } = require('child_process');
const { ipcMain, shell, dialog, app } = require('electron');
const { envJsonToBru, bruToJson, jsonToBruViaWorker, jsonToCollectionBru, bruToJsonViaWorker } = require('../bru');
@@ -909,6 +910,41 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
watcher.addWatcher(mainWindow, collectionPathname, collectionUid, brunoConfig, false, shouldLoadCollectionAsync);
});
+
+ ipcMain.handle('renderer:reveal-in-finder', async (event, filePath) => {
+ try {
+ if (!filePath) {
+ throw new Error('File path is required.');
+ }
+
+ const resolvedPath = path.resolve(filePath);
+
+ if (!fs.existsSync(resolvedPath)) {
+ throw new Error('The specified file does not exist.');
+ }
+
+ console.log(process.platform, "process.platform")
+
+ switch (process.platform) {
+ case 'darwin': // macOS
+ shell.showItemInFolder(resolvedPath);
+ break;
+ case 'win32': // Windows
+ shell.showItemInFolder(resolvedPath);
+ break;
+ case 'linux': // Linux
+ exec(`xdg-open "${resolvedPath}"`);
+ break;
+ default:
+ throw new Error('Unsupported platform.');
+ }
+
+ return { success: true };
+ } catch (error) {
+ console.error('Error in reveal-in-finder:', error);
+ return { success: false, message: error.message };
+ }
+ });
};
const registerMainEventHandlers = (mainWindow, watcher, lastOpenedCollections) => {