feat(playground): response body formatting, preview, and format selector (BRU-3764) - #8
Merged
arpit-bruno merged 21 commits intoJul 29, 2026
Conversation
Wire the response-format flow in the docs playground: - Format the editor body per format via formatResponse (JSON/XML/HTML/JS prettify, hex dump, base64 passthrough, raw), and feed Monaco only real grammars (raw/hex/base64 -> plaintext). - Extract the preview-mode mapping into a pure previewMode helper and reconcile its spec. - Hide structured formats for binary responses (image/video/audio/pdf/zip; SVG stays text) via getResponseFormatOptions. - Keep the preview toggle sticky across same-response re-renders, and ignore a stale format choice that no longer applies to the current body. Adds unit coverage (dataFormatter hex/base64, getResponseFormatOptions) and Playwright coverage (format switching + binary option hiding).
…rmatting
Follow-up polish to the response-format flow:
- Resolve content-type once per render in ResponsePane and thread it into
useResponseFormatter and ResponseBodyTab, replacing three independent
sniff+header-parse call sites.
- Skip formatResponse (a full base64 decode) while the preview view is
active, and narrow formatResponse to return string (drops the call-site
coercion).
- Single-source the structured/byte format-id arrays from response.ts.
- Extract the repeated large-response fallback in dataFormatter into one
helper; drop a stray console.log.
- Replace the fragile contentType.replace(/\;(.*)/) data-URI parse with
split(';') (also clears a no-useless-escape lint error); remove a dead
PreviewMode re-export, an unused import, and a no-op Omit/cast.
vasharma05-bruno
marked this pull request as draft
July 27, 2026 09:03
Behavior-preserving improvements to the response-detection utilities in utils/response.ts: hoist the per-call-recompiled content-type regexes and the getDefaultResponseFormat rules table to module scope, and add unit tests locking getContentType, getDefaultResponseFormat, detectContentTypeFromBuffer, and detectContentTypeFromBase64 behavior.
vasharma05-bruno
force-pushed
the
bru-3764-response-formatter
branch
from
July 27, 2026 09:08
e6fc6ad to
896b811
Compare
Remove restatement/banner/narration comments (mostly carried over with the bruno-app port) from response.ts, dataFormatter.ts, and ResponsePane.tsx. Rationale/invariant/provenance comments are kept.
Mirror bruno-app: when a response body exceeds 10 MB, show a LargeResponseWarning (current size + a View action) instead of rendering the body, and skip the full base64 decode/formatting until the user reveals it. The reveal resets when the response changes.
vasharma05-bruno
marked this pull request as ready for review
July 27, 2026 13:46
sachin-bruno
approved these changes
Jul 28, 2026
arpit-bruno
requested changes
Jul 28, 2026
- QueryResultPreview.spec: correct relative import depth (../../../, not ../../../../) - runner/index.spec: provide arrayBuffer() on fetch mocks to match the new Response parsing contract (base64Data via response.arrayBuffer()) - response-body e2e: intercept the real request URL (**/api/users**) instead of a nonexistent /__proxy; reach the Headers tab via the response-tab overflow menu - response-pane POM: normalise Monaco's non-breaking spaces in bodyText()
…arse time Addresses review feedback about eagerly base64-encoding every response body. - RequestExecutor.parseResponse: take size from arrayBuffer.byteLength (no Buffer copy just to measure); sniff the content type from the bytes once and store it as `detectedContentType`; skip base64 for reconstructable text (plain/SVG string bodies) and for oversized (>10MB) bodies. Binary, JSON, and non-ASCII/ambiguous bodies keep base64 — previews and precise formatting need the faithful bytes. - response.ts: extract byte-based detectContentTypeFromBytes and route detectContentTypeFromBase64 through it; export isByteFormatContentType; drop two dead imports. - useInitialResponseFormat: prefer response.detectedContentType (base64 sniff fallback). - dataFormatter.formatResponse: format from `data` when no base64 buffer is present and derive hex/base64 from the text body; keep fast-json-format for JSON (it preserves bigint precision — not redundant with safeStringifyJSON). - Tests: parse-time content-type handling (PNG/JSON/text/SVG + lying header), detectContentTypeFromBytes / isByteFormatContentType, and the data-only formatter path.
Contributor
Author
|
Hi @arpit-bruno, As per our discussion, we can take the work on replacing the |
…he sticky-preview e2e The response tab bar keeps only the active tab visible and overflows the rest into a menu; which tabs overflow depends on viewport/font metrics, so the tab-switch re-render was flaky in CI (clicking the now-overflowed Response tab timed out on a not-visible element). Re-fetch the identical image response instead — a stable, always-visible trigger that exercises the same guard (sticky-preview survives an unchanged content type).
…e pdf.js worker
react-pdf's <Page> rendered a text layer on top of the canvas, but the required
TextLayer CSS was never imported ("TextLayer styles not found"), so the unstyled
text layer painted a second, visible copy of each page's content — the page appeared
rendered twice. The preview is read-only, so disable the text (and keep the annotation)
layer: only the canvas renders now.
Also set pdfjs.GlobalWorkerOptions.workerSrc to the bundled worker — without it react-pdf
fell back to a fake worker that failed to resolve in a Vite build, so PDFs didn't render
at all. Verified: pages render once, unit suite green, and the production build emits the
worker asset.
…o bru-3764-response-formatter
arpit-bruno
previously approved these changes
Jul 29, 2026
arpit-bruno
approved these changes
Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Wires up the response-format flow in the docs playground so the response body is formatted, previewable, and selectable by format — porting the mature behaviour from the Bruno Electron app, adapted for a browser/SSR environment.
Changes
formatResponse(JSON/XML/HTML/JS prettify, hex dump, base64 passthrough, raw decode) instead of a naiveJSON.stringify. Monaco is only ever handed a real grammar (raw/hex/base64→plaintext). This wires in the previously-orphanedutils/dataFormatter.ts.previewMode.ts(formatToPreviewMode) and reconciled its spec.getResponseFormatOptionshides the structured formats (JSON/HTML/XML/JS) for binary responses (image/video/audio/pdf/zip); SVG stays text.Tests
dataFormatterhex/base64 cases andgetResponseFormatOptionscoverage; reconciledQueryResultPreview.spec.tsx(was red on the branch).Screenshots
Responses greater than 10MB
HTML
JavaScript
XML
Video