Skip to content

feat(openapi-sync): preserve user-configured request values on sync#8204

Open
sundram-bruno wants to merge 1 commit into
usebruno:mainfrom
sundram-bruno:feature/openapi-sync-preserve-values
Open

feat(openapi-sync): preserve user-configured request values on sync#8204
sundram-bruno wants to merge 1 commit into
usebruno:mainfrom
sundram-bruno:feature/openapi-sync-preserve-values

Conversation

@sundram-bruno

@sundram-bruno sundram-bruno commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Description

Discussion: #7401

On the Spec Updates sync, Bruno currently overwrites a request's body, params, headers and auth wholesale, destroying user-entered values and {{envVar}} references whenever the spec changes shape. This PR makes sync reconcile the request structure against the spec while preserving the user's values for fields that still exist.

JIRA : https://usebruno.atlassian.net/browse/BRU-3205

A "Preserve values" toggle (default ON) on the Spec Updates review toolbar controls this. With it on, your edits are kept and only the spec's structural additions/removals are applied; with it off, spec values overwrite (the seam for an explicit "take the spec's version"). The diff preview's EXPECTED column shows the post-merge result, so unchanged values no longer render as changes.

What changed

Backend — packages/bruno-electron/src/ipc/openapi-sync.js

  • Field-level merge: JSON body merged by key path; form fields and params/headers merged by name (duplicate names paired positionally), preserving value + enabled.
  • {{var}} masking so an interpolated body can be parsed, merged and restored safely — using a private-use sentinel that never collides with body text and never reaches disk.
  • Auth merged by mode: same mode keeps the user's values and adds spec-introduced fields; a mode change takes the spec. compareRequestFields now compares auth by mode only, so preserved auth values no longer keep the collection permanently "out of sync".
  • preserveValues (default true) threaded through renderer:apply-openapi-sync and renderer:get-endpoint-diff-data. Reset path left unchanged; scripts/tests/assertions preserved in both sync and reset.

Frontend — OpenAPISyncTab

  • "Preserve values" toggle on the Spec Updates review; per-endpoint preview re-fetches when toggled; the flag is forwarded to apply.

Note for reviewers — one intended behavior change: compareRequestFields no longer flags auth config differences (e.g. apikey placement, oauth2 url/scope) when the auth mode is unchanged; only a mode change is drift. This is required so preserved auth values don't perpetually re-flag the endpoint.

Tests: 67 unit tests in packages/bruno-electron/tests/ipc/openapi-sync-merge.spec.js covering the merge helpers and {{var}} masking edge cases (string boundaries, object keys, nested/array bodies, many vars, dual-side). Full bruno-electron and bruno-app suites pass.

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes — see the auth drift-detection note above (behavior change, not an API break).
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.OpenAPI sync shouldn't override certain values #7548

Note: Keeping the PR small and focused helps make it easier to review and merge.

Summary by CodeRabbit

  • New Features
    • "Preserve values" toggle in OpenAPI sync review and row-level controls; applies to bulk apply actions and preserves user-edited request data when enabled (default on, accessible with tooltip).
  • Bug Fixes
    • More reliable diff loading and UI: stale async results ignored, spinner/error shown only on initial loads to avoid flicker during refetches.
  • Tests
    • Comprehensive tests validating merge/preserve behaviors across bodies, fields, auth, and sync/apply flows.
  • Style
    • New compact "preserve values" chip and switch styling.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 55171997-9dea-4300-a071-c1a8a79ae736

📥 Commits

Reviewing files that changed from the base of the PR and between 1caa8b3 and cce8319.

📒 Files selected for processing (6)
  • packages/bruno-app/src/components/OpenAPISyncTab/EndpointChangeSection/ExpandableEndpointRow.js
  • packages/bruno-app/src/components/OpenAPISyncTab/StyledWrapper.js
  • packages/bruno-app/src/components/OpenAPISyncTab/SyncReviewPage/index.js
  • packages/bruno-app/src/components/OpenAPISyncTab/hooks/useSyncFlow.js
  • packages/bruno-electron/src/ipc/openapi-sync.js
  • packages/bruno-electron/tests/ipc/openapi-sync-merge.spec.js
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/bruno-app/src/components/OpenAPISyncTab/StyledWrapper.js
  • packages/bruno-app/src/components/OpenAPISyncTab/hooks/useSyncFlow.js
  • packages/bruno-app/src/components/OpenAPISyncTab/EndpointChangeSection/ExpandableEndpointRow.js
  • packages/bruno-app/src/components/OpenAPISyncTab/SyncReviewPage/index.js
  • packages/bruno-electron/src/ipc/openapi-sync.js
  • packages/bruno-electron/tests/ipc/openapi-sync-merge.spec.js

Walkthrough

Adds a preserveValues toggle in the SyncReviewPage UI and threads that choice into ExpandableEndpointRow, useSyncFlow, and Electron IPC handlers; implements preserve-aware masking and merge helpers in main-process code, exports helpers for tests, and adds extensive Jest coverage. ExpandableEndpointRow also suppresses stale diff responses with a requestIdRef.

Changes

OpenAPI Preserve Values Synchronization

Layer / File(s) Summary
Preserve Values UI Toggle and Prop Threading
packages/bruno-app/src/components/OpenAPISyncTab/SyncReviewPage/index.js, packages/bruno-app/src/components/OpenAPISyncTab/StyledWrapper.js
SyncReviewPage adds preserveValues state with a compact “Preserve values” toggle, includes preserveValues in onApplySync payload, and forwards it into ExpandableEndpointRow instances; new styles for the control are added.
ExpandableEndpointRow Stale Request Suppression
packages/bruno-app/src/components/OpenAPISyncTab/EndpointChangeSection/ExpandableEndpointRow.js
Component accepts preserveValues (default true), forwards it to renderer:get-endpoint-diff-data, uses a monotonic requestIdRef to ignore superseded IPC responses, reacts to preserveValues changes by refetching or invalidating cached diff state, and adjusts loading/error visibility to avoid flicker.
useSyncFlow IPC Invocation Wiring
packages/bruno-app/src/components/OpenAPISyncTab/hooks/useSyncFlow.js
performSync gains a preserveValues argument and includes it in the renderer:apply-openapi-sync IPC payload; handleApplySync forwards selections?.preserveValues.
Core Merge Helpers and Request Reconciliation
packages/bruno-electron/src/ipc/openapi-sync.js (lines ~436–694, 791–845)
Adds sentinel masking/unmasking for {{...}} in JSON and implements preserve-aware merge helpers (JSON merge, body merge, field-list preserving merge, auth merge, mergeBody), updates mergeSpecIntoRequest to accept { preserveValues }, and simplifies auth diff detection in compareRequestFields.
IPC Handler Integration for Diff and Apply
packages/bruno-electron/src/ipc/openapi-sync.js (lines ~1250–1600)
renderer:get-endpoint-diff-data now computes the expected/new preview by merging actual request with spec using mergeSpecIntoRequest(..., { preserveValues }). renderer:apply-openapi-sync accepts preserveValues and uses it when merging existing requests for added/modified endpoints.
Test-only Exports for Helpers
packages/bruno-electron/src/ipc/openapi-sync.js (lines ~1896–1910)
When NODE_ENV === 'test', internal helpers are exported under module.exports._test to enable unit testing of merge/mask functions.
Comprehensive Merge Helper Test Suite
packages/bruno-electron/tests/ipc/openapi-sync-merge.spec.js
Adds ~550 lines of Jest tests covering mask/unmask, JSON merge semantics, field-list merging, auth merging, body-mode dispatch, mergeSpecIntoRequest sync/fullReset behaviors, and compareRequestFields auth diffs.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • usebruno/bruno#7483: Introduces/changes compareRequestFields logic that overlaps with this PR's simplification of auth-config drift detection.

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno
  • sid-bruno

Poem

🌊 Specs and local edits in a dance,
preserveValues gives your changes a chance—
JSON masks tucked safely out of sight,
merges keep user fields and make things right,
stale replies ignored, the UI stays bright.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main feature: adding a preserve-values mechanism to OpenAPI sync that keeps user-configured request values while applying spec changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/bruno-app/src/components/OpenAPISyncTab/SyncReviewPage/index.js (1)

243-251: ⚡ Quick win

Add data-testid for Playwright testing.

The toggle button is a key user interaction point but lacks a test identifier.

🧪 Suggested fix
                <button
                  className={`bulk-btn ${preserveValues ? 'active' : ''}`}
                  onClick={() => setPreserveValues((v) => !v)}
                  aria-pressed={preserveValues}
                  title="When on, your edited values (body, params, headers, auth, {{vars}}) are kept; only fields the spec adds or removes change. When off, spec values overwrite yours."
+                 data-testid="preserve-values-toggle"
                >

As per coding guidelines: "Add data-testid to testable elements for Playwright".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bruno-app/src/components/OpenAPISyncTab/SyncReviewPage/index.js`
around lines 243 - 251, The toggle button in SyncReviewPage lacks a Playwright
test id; add a data-testid attribute to the button element that contains the
preserveValues state and setPreserveValues handler (the button rendering the
IconCheck/IconInfoCircle) — e.g., data-testid="preserve-values-toggle" — so
tests can reliably select it; ensure the attribute is added on the same button
that uses preserveValues, setPreserveValues, IconCheck and IconInfoCircle.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/bruno-app/src/components/OpenAPISyncTab/SyncReviewPage/index.js`:
- Around line 243-251: The toggle button in SyncReviewPage lacks a Playwright
test id; add a data-testid attribute to the button element that contains the
preserveValues state and setPreserveValues handler (the button rendering the
IconCheck/IconInfoCircle) — e.g., data-testid="preserve-values-toggle" — so
tests can reliably select it; ensure the attribute is added on the same button
that uses preserveValues, setPreserveValues, IconCheck and IconInfoCircle.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1ddce66d-4c18-4b24-8452-a9b0a7f89b0f

📥 Commits

Reviewing files that changed from the base of the PR and between b9ee1ee and 6b4ee77.

📒 Files selected for processing (5)
  • packages/bruno-app/src/components/OpenAPISyncTab/EndpointChangeSection/ExpandableEndpointRow.js
  • packages/bruno-app/src/components/OpenAPISyncTab/SyncReviewPage/index.js
  • packages/bruno-app/src/components/OpenAPISyncTab/hooks/useSyncFlow.js
  • packages/bruno-electron/src/ipc/openapi-sync.js
  • packages/bruno-electron/tests/ipc/openapi-sync-merge.spec.js

@sundram-bruno sundram-bruno force-pushed the feature/openapi-sync-preserve-values branch 2 times, most recently from f3a2f51 to 1caa8b3 Compare June 8, 2026 20:28
Reconcile request structure against the spec on sync while preserving the
user's values (JSON body, params, headers, auth) and {{var}} references for
fields that still exist. A "Preserve values" toggle (default on) on the Spec
Updates review controls it; turning it off lets spec values overwrite. The diff
preview's EXPECTED column shows the post-merge result so unchanged values do not
render as changes.

- field-level merge for JSON body (by key path), form fields and params/headers
  (by name, duplicate names paired positionally), preserving value + enabled
- {{var}} masking so interpolated bodies parse, merge and restore safely,
  using a private-use sentinel that never collides with body text
- auth merged by mode: same mode keeps the user's values and adds spec-introduced
  fields; a mode change takes the spec. compareRequestFields compares auth by
  mode only, so preserved auth values no longer mark the collection out of sync
- preserveValues threaded through apply and diff-preview IPC handlers
- reset path left unchanged; scripts/tests/assertions preserved in sync and reset
- 67 unit tests covering the merge helpers and masking edge cases
@sundram-bruno sundram-bruno force-pushed the feature/openapi-sync-preserve-values branch from 1caa8b3 to cce8319 Compare June 9, 2026 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant