From 40c1c20de0e84f4e43bac9decba49114547e8530 Mon Sep 17 00:00:00 2001 From: Phaired <65019388+Phaired@users.noreply.github.com> Date: Wed, 28 May 2025 10:00:27 +0200 Subject: [PATCH] feat(lenses): enhance content type detection and lens selection logic (#5081) Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com> --- .../src/helpers/lenses/lenses.ts | 52 ++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/packages/hoppscotch-common/src/helpers/lenses/lenses.ts b/packages/hoppscotch-common/src/helpers/lenses/lenses.ts index c0d8cee3..3a912465 100644 --- a/packages/hoppscotch-common/src/helpers/lenses/lenses.ts +++ b/packages/hoppscotch-common/src/helpers/lenses/lenses.ts @@ -43,18 +43,54 @@ export function getSuitableLenses(response: HoppRESTResponse): Lens[] { (h) => h.key.toLowerCase() === "content-type" ) + // If no content type is found, return raw lens as fallback if (!contentType) return [rawLens] - // Check if the response content type includes `text/plain` and the body contains valid JSON - if ( - contentType.value.includes("text/plain") && - response.type === "success" && - isValidJSONResponse(response.body) - ) { - // Append JSON lens to the list of lenses - return [rawLens, jsonLens] + // For successful responses, use a smarter approach + if (response.type === "success") { + // First, get lenses that match the content type + const matchingLenses = lenses.filter((lens) => + lens.isSupportedContentType(contentType.value) + ) + + // For text-based content types, check if content can be parsed as other formats + const isTextBased = + contentType.value.includes("text/") || + contentType.value.includes("application/javascript") || + contentType.value.includes("application/xml") || + contentType.value.includes("application/xhtml+xml") || + htmlLens.isSupportedContentType(contentType.value) + + if (isTextBased && response.body) { + // Check if content is valid JSON + if ( + isValidJSONResponse(response.body) && + !matchingLenses.includes(jsonLens) + ) { + // Add JSON lens as an additional option, but keep it after the original content type lens + // This ensures the original content type lens is selected by default + matchingLenses.push(jsonLens) + } + + // Add other content type detection here if needed + // e.g., check if content is valid XML, HTML, etc. + } + + // If no matching lenses found, include all lenses to give user full control + if (matchingLenses.length === 0) { + return lenses + } + + // Always include raw lens for viewing the raw response + if (!matchingLenses.includes(rawLens)) { + matchingLenses.push(rawLens) + } + + // Return matching lenses plus raw lens + return matchingLenses } + // For other response types, use the standard content type detection const result = [] for (const lens of lenses) { if (lens.isSupportedContentType(contentType.value)) result.push(lens)