From 55c3003d6b04ca9689bc790c5285e57c055d781c Mon Sep 17 00:00:00 2001 From: Chirag Chandrashekhar Date: Wed, 8 Jul 2026 21:59:31 +0530 Subject: [PATCH] fix(mount): persist raw file content in file-index for file mode (#8531) --- .../ReduxStore/slices/collections/index.js | 1 + .../src/services/mount/file-index.js | 30 ++++++++++++++----- .../src/services/mount/manager.js | 5 ++-- .../src/services/mount/tree-builder.js | 1 + .../src/services/pool/jobs/parse-file.js | 4 +-- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js index ef2fed1a4..19ef90f6f 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js @@ -35,6 +35,7 @@ const FILE_DERIVED_REQUEST_FIELDS = [ 'request', 'settings', 'examples', + 'raw', 'filename', 'pathname', 'partial', diff --git a/packages/bruno-electron/src/services/mount/file-index.js b/packages/bruno-electron/src/services/mount/file-index.js index 8ea183e39..986832833 100644 --- a/packages/bruno-electron/src/services/mount/file-index.js +++ b/packages/bruno-electron/src/services/mount/file-index.js @@ -27,9 +27,21 @@ const MIGRATIONS = [ ) WITHOUT ROWID; CREATE INDEX IF NOT EXISTS idx_collection_path ON file_index_entries(collection_path); ` + }, + { + version: 2, + up: ` + ALTER TABLE file_index_entries ADD COLUMN raw TEXT; + UPDATE file_index_entries SET mtime = 0, hash = ''; + ALTER TABLE file_index_entries ADD COLUMN created_at INTEGER; + ALTER TABLE file_index_entries ADD COLUMN updated_at INTEGER; + UPDATE file_index_entries SET created_at = unixepoch(), updated_at = unixepoch(); + ` } ]; +// TODO: Check for trigger (ON UPDATE) and then see if we can use that to update updated_at + class FileIndex { #db; #dbPath; @@ -102,12 +114,12 @@ class FileIndex { entries(collectionPath) { const root = normalize(collectionPath); const rows = this.#db.all( - 'SELECT relative_path AS relativePath, data FROM file_index_entries WHERE collection_path = ?', + 'SELECT relative_path AS relativePath, data, raw FROM file_index_entries WHERE collection_path = ?', root ); const map = new Map(); for (const row of rows) { - map.set(row.relativePath, { data: JSON.parse(row.data) }); + map.set(row.relativePath, { data: JSON.parse(row.data), raw: row.raw }); } return map; } @@ -125,23 +137,26 @@ class FileIndex { return; } - const { mtime, hash, data } = entry; + const { mtime, hash, data, raw } = entry; const id = idForAbsolutePath(path.join(root, relativePath)); this.#db.run( ` - INSERT INTO file_index_entries (collection_path, relative_path, id, mtime, hash, data) - VALUES (?, ?, ?, ?, ?, ?) + INSERT INTO file_index_entries (collection_path, relative_path, id, mtime, hash, data, raw, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, ?, ?, unixepoch(), unixepoch()) ON CONFLICT(collection_path, relative_path) DO UPDATE SET mtime = excluded.mtime, hash = excluded.hash, - data = excluded.data + data = excluded.data, + raw = excluded.raw, + updated_at = unixepoch() `, root, relativePath, id, mtime, hash, - JSON.stringify(data) + JSON.stringify(data), + raw ?? null ); } @@ -155,6 +170,7 @@ class FileIndex { relativePath, mtime: stat.mtimeNs, hash: hashFile(absolutePath), + raw: fs.readFileSync(absolutePath, 'utf8'), data }); } diff --git a/packages/bruno-electron/src/services/mount/manager.js b/packages/bruno-electron/src/services/mount/manager.js index 3943dda39..1e028d3c5 100644 --- a/packages/bruno-electron/src/services/mount/manager.js +++ b/packages/bruno-electron/src/services/mount/manager.js @@ -192,13 +192,14 @@ class MountManager { entry.state.set(e.relativePath, { data: result.data, error: result.error }); continue; } - entry.state.set(e.relativePath, { data: result.data }); + entry.state.set(e.relativePath, { data: result.data, raw: result.raw }); this.#getIndex().stage(entry.collectionPath, { op: 'add', relativePath: e.relativePath, mtime: result.mtime, hash: result.hash, - data: result.data + data: result.data, + raw: result.raw }); } for (const e of removed) { diff --git a/packages/bruno-electron/src/services/mount/tree-builder.js b/packages/bruno-electron/src/services/mount/tree-builder.js index 7caae6ba6..d8275b5e6 100644 --- a/packages/bruno-electron/src/services/mount/tree-builder.js +++ b/packages/bruno-electron/src/services/mount/tree-builder.js @@ -128,6 +128,7 @@ const buildRequestNode = (absolutePath, basename, entry, uidOverrides, uidFor) = request: data.request, settings: data.settings, examples: data.examples, + raw: entry.raw ?? null, filename: basename, pathname: absolutePath, draft: null, diff --git a/packages/bruno-electron/src/services/pool/jobs/parse-file.js b/packages/bruno-electron/src/services/pool/jobs/parse-file.js index e0e94074e..3ddbfbab9 100644 --- a/packages/bruno-electron/src/services/pool/jobs/parse-file.js +++ b/packages/bruno-electron/src/services/pool/jobs/parse-file.js @@ -69,10 +69,10 @@ const parseFile = ({ collectionPath, relativePath, format, type }) => { const content = buf.toString('utf8'); try { const data = parseContent(content, format, type, buf.length); - return { relativePath, mtime, hash, data, format, type }; + return { relativePath, mtime, hash, data, format, type, raw: content }; } catch (err) { const data = format === 'bru' && type === 'request' ? extractBruMeta(content) : {}; - return { relativePath, mtime, hash, data, format, type, partial: true, error: { message: err.message, stack: err.stack } }; + return { relativePath, mtime, hash, data, format, type, raw: content, partial: true, error: { message: err.message, stack: err.stack } }; } };