Skip to content

Normalize request media types without a new plugin dependency - #1676

Open
fly1d wants to merge 4 commits into
PaloAltoNetworks:mainfrom
fly1d:fix/content-type-parameters
Open

fly1d wants to merge 4 commits into
PaloAltoNetworks:mainfrom
fly1d:fix/content-type-parameters

Conversation

@fly1d

@fly1d fly1d commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Refs #603.

Normalize media types with a theme-local helper and keep plugin-side normalization local. Parameterized forms and JSON/XML examples work consistently; API and webhook sampling prefer exact application/json, then +json, before the existing JSON-family fallback. The theme does not require a new plugin-internal export.

Include the main-branch changes through #1677, retaining its body-mode selection and named-file validation. Only final formdata mode omits the multipart boundary. Pre-encoded raw strings and nonform file uploads retain their supplied boundary and bytes. The two old unnamed multipart-file controls now use supported nonform file uploads; the raw-string multipart controls and upstream multipart validation tests remain intact.

Validation on Node 26.5.0/macOS: full yarn test passes 372 tests across 20 suites, with 35 snapshots. All three packages build without cache; strict changed-file ESLint, Prettier and diff checks pass. The builder is byte-identical to the #1677 merge, af7bee5.

Required full yarn lint still exits 2 at the existing Cypress cypress/globals configuration error. No browser or hosted CI matrix result is claimed.

@sserrata sserrata left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks. This PR now has a merge conflict with main because of #1678 (jest.config.js, Body/index.tsx). Please rebase. The media-type handling is also incomplete. Please add one shared helper (for example, getMediaType(contentType): remove parameters, change to lower case) and use it in Body, buildPostmanRequest and the plugin. #1677 needs the same helper.

Other items (outside the diff):

  • packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/Body/index.tsx: The form checks (here and in the render branch) still compare the raw contentType with ===. multipart/form-data; boundary=x or application/x-www-form-urlencoded; charset=utf-8 still gets an empty plaintext editor. Use the parsed mediaType.
  • packages/docusaurus-theme-openapi-docs/src/theme/ApiExplorer/buildPostmanRequest.ts: The form mode is selected by an exact match on the raw contentType. A urlencoded type that has parameters keeps the old mode.
  • packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.ts: The plugin's jsonRequestBodyExample still uses raw-key checks. application/json;charset=UTF-8 and application/problem+json; charset=utf-8 get no example, so the plugin and theme do not agree.

contentType?.includes("application/json") ||
contentType?.endsWith("+json")
) {
if (mediaType === "application/json" || mediaType?.endsWith("+json")) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Regression: an exact match drops JSON handling for application/json-seq, application/jsonl and similar types that the old includes("application/json") matched. These now get an empty plaintext editor.

@fly1d fly1d changed the title fix(theme): handle parameters in JSON and XML content types fix: share request media type handling Oct 28, 2026

@sserrata sserrata left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the update. The shared helper, the form branches and the json-seq fix look good. Some new problems must be fixed before merge:

Other items (outside the diff):

  • packages/docusaurus-plugin-openapi-docs/src/openapi/utils/utils/openapi.ts: isFormUrlEncoded still uses an exact match, so the plugin and theme do not agree for application/x-www-form-urlencoded; charset=utf-8.

import SchemaTabs from "@theme/SchemaTabs";
import TabItem from "@theme/TabItem";
import { sampleFromSchema } from "docusaurus-plugin-openapi-docs/lib/openapi/createSchemaExample";
import { getMediaType } from "docusaurus-plugin-openapi-docs/lib/utils/mediaType";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Peer dependency break: the theme imports docusaurus-plugin-openapi-docs/lib/utils/mediaType, which is new in this PR, but the theme peer range is still ^5.0.0. A user who upgrades only the theme gets "Module not found". Move getMediaType into the theme (for example, ApiExplorer/utils). Then the plugin change and the special Jest mappings are also not necessary. #1677 needs the same helper. The plugin version (or the existing code at openapi/utils/utils/openapi.ts:509) can stay separate.

key.toLowerCase() === "application/json" ||
key.toLowerCase() === "application/json; charset=utf-8"
) {
if (getMediaType(key).startsWith("application/json")) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

startsWith("application/json") now selects the first application/json* key. With {application/jsonl, application/json}, the example comes from the jsonl schema. Use an exact application/json match first, then +json. The webhook branch (line 358) has the same problem.


if (body.type === "form") {
const mediaType = getMediaType(contentType);
if (mediaType === "multipart/form-data") {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A boundary= from the selected content type goes into the Content-Type header of the snippets, but the client makes its own boundary. The copied curl command then sends a body that the server cannot parse. Remove boundary from the header for formdata.

return;
}

if (body.type === "form") {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

After a mode change, the old raw, urlencoded or formdata data stays on the cloned body, and toJSON() includes it. Clear the inactive fields.

@fly1d fly1d changed the title fix: share request media type handling Normalize request media types without a new plugin dependency Oct 29, 2026

@sserrata sserrata left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks. All review items are addressed. Note: this PR and #1677 change the same lines in buildPostmanRequest.ts, so the PR that merges second needs a rebase.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit a3a0963):

https://docusaurus-openapi-36b86--pr1676-ua544npm.web.app

(expires Fri, 06 Nov 2026 15:56:06 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: bf293780ee827f578864d92193b8c2866acd459f

@github-actions

Copy link
Copy Markdown

📸 Visual Diff Report

Snapshot comparison against https://docusaurus-openapi.tryingpan.dev/

Total ✅ Match ❌ Diff ⏭ Skip
228 228 0 0

✅ No visual regressions detected.

Updated at 2026-10-30T16:01:14.079Z · run 40927256913

@sserrata

Copy link
Copy Markdown
Member

This PR now conflicts with main after #1677 merged (buildPostmanRequest.ts, jest.config.js, utils/mediaType.test.ts). #1677 already added utils/mediaType.ts and setBodyMode, so please rebase onto main, reuse those, and remove the duplicate mode-selection logic. Thanks.

This branch is waiting to be deployed

1 active (outdated) and 1 waiting deployments
default — 7238bb27 Waiting Oct 31, 2026 by fly1d via Analyze Unsafe (javascript) #2445
preview — a3a09634 Deployed Oct 30, 2026 by fly1d via Visual Diff #2431
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants