Skip to content

fix(theme): serialize supplied request examples - #1678

Merged
sserrata merged 2 commits into
PaloAltoNetworks:mainfrom
fly1d:fix/json-primitive-examples
Oct 28, 2026
Merged

sserrata merged 2 commits into
PaloAltoNetworks:mainfrom
fly1d:fix/json-primitive-examples

Conversation

@fly1d

@fly1d fly1d commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

JSON and XML request examples can be skipped for false/0 or reach LiveEditor as non-string values. JSON-looking strings are also handled differently in single and named examples.

Serialize supplied schema, media-type and named values before rendering. Respect string schema types, including nullable OpenAPI 3.1 string types, while retaining pre-encoded JSON objects/arrays for other schemas. Ignore media-type null placeholders and named entries without an inline value. Keep payload summary fields in the payload; only named Example Object summaries render as Markdown. Supplied XML objects and primitives now produce editor text as well.

Generated samples and the legacy fallback keep main's existing truthy checks and serialization, including the existing generated true and quoted "null" defaults. Jest's jsdom, sampler-source mapping and XML JavaScript transform are confined to the new Body test project; the other 13 suites retain their original settings.

Validation on Node 26.5.0, macOS arm64:

  • yarn test --runInBand: 250 tests, 14 suites and 35 snapshots passed. The 75 mounted component/Redux regressions have 34 failures on the previous PR head and all pass after the fix. Editor and Docusaurus UI shells are substituted; effects, sampler and reducers run normally.
  • NX_SKIP_NX_CACHE=true yarn build-packages: all three packages built. Changed-file ESLint (--max-warnings 0) and Prettier passed.
  • 25 independent component-to-local-HTTP checks passed, through Body callbacks and real request bytes; the previous head passes 9/25.
  • An isolated port retaining Normalize request media types without a new plugin dependency #1676 passes both focused suites (94 tests) without built package output. The same 25 HTTP scenarios also pass with vendor JSON/XML types and charset parameters. Normalize request media types without a new plugin dependency #1676 still needs a configuration/adjacent-hunk reconciliation if it merges first; this PR remains based on main.

Full yarn lint was run and exits 2 at the unknown cypress/globals environment in cypress/.eslintrc.js. An untouched main archive with the same dependencies reports the same error. No Cypress or dependency change is included. The CI platform matrix was not run locally.

@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 fix. Inline comments cover the main issues. Two more items outside the diff:

  • XML branch (~L179–200): still uses truthy checks (if (contentTypeExample), if (example)), so 0/false give an empty editor. Non-string named ex.value goes through format(), falls back to the raw object, and crashes LiveEditor — the same crash this PR fixes for JSON.
  • Lint: please run the full yarn lint (required by AGENTS.md), not only ESLint on changed files.

Items on L154, L157 and L438 can cause regressions and should be fixed before merge.

contentType?.endsWith("+json")
) {
if (contentTypeExample) {
if (contentTypeExample !== undefined) {

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.

contentTypeExample also holds sampler output. With !== undefined, a bare type: integer / type: boolean schema now prefills the editor and Redux body with 0 / true on load, so "Send" sends a value the user never entered. type: "null" yields the string "null" (quoted), not JSON null. Previously the editor was empty.

defBody = JSON.stringify(contentTypeExample, null, 2);
}
if (example) {
if (example !== undefined) {

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.

An explicit example: null now sets exBody to "null". The if (exampleBody) render branch runs before the named-examples branch, so any examples on the same media type are hidden. Swagger 2 converters often emit example: null. Suggest example != null.

}
if (example) {
if (example !== undefined) {
exBody = JSON.stringify(example, null, 2);

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 string example is always stringified, so example: '{"id": 1}' shows as an escaped string. The same value under examples.x.value is treated as pre-encoded and not stringified. The two paths should handle strings the same way.

}
if (examples) {
for (const [key, ex] of Object.entries(examples)) {
let body = ex.value;

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 named example with only externalValue (no value) gives body: undefined, but an entry is still pushed. The result is a tab with a summary and no editor. Suggest skipping entries where ex.value === undefined.

JSON.parse(ex.value);
} catch (e) {
body = JSON.stringify(ex.value, null, 2);
if (typeof body === "string") {

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.

"Parses as JSON → already encoded" is ambiguous for string-typed values like "123", "true", "null". With type: string, value: "123" is sent as the number 123. The new "preserves pre-encoded named JSON" tests lock this in. Consider checking the schema type, or only treating strings that parse to objects/arrays as pre-encoded.

Also, JSON.stringify(body, null, 2) is duplicated in both branches. This can be one condition: if (typeof body !== "string" || !isJson(body)).

{/* @ts-ignore */}
<TabItem label="Example" value="example">
{example.summary && <Markdown>{example.summary}</Markdown>}
{example?.summary && <Markdown>{example.summary}</Markdown>}

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.

Pre-existing, but this line is touched: the media-type example is the payload itself, not an Example Object. A payload with a summary field is rendered as Markdown here, and an object-valued summary throws "Objects are not valid as a React child". This line should be removed rather than made optional-chained.

Comment thread jest.config.js Outdated

module.exports = {
preset: "ts-jest",
preset: "ts-jest/presets/js-with-ts",

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.

This changes Jest config for every suite to support one test file: js-with-ts + allowJs now transforms all .js under the roots, and theme tests resolve the plugin's src instead of the built lib. The createSchemaExample mapping is also duplicated in tsconfig.paths and moduleNameMapper. Since this matches #1676, whichever merges second will conflict. Consider landing the Jest setup once, separately.

@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.

Requesting changes per the review above. Please fix the L154, L157 and L438 items (regression risk) and the XML branch before merge.

@fly1d fly1d changed the title fix(theme): preserve primitive JSON request examples fix(theme): serialize supplied request examples 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 updates. All review items are addressed. yarn test passes locally (250/250).

@github-actions

Copy link
Copy Markdown

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

https://docusaurus-openapi-36b86--pr1678-76ai42ju.web.app

(expires Wed, 04 Nov 2026 19:20:41 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-28T19:25:34.726Z · run 40737471662

@sserrata
sserrata merged commit 76c7c7e into PaloAltoNetworks:main Oct 28, 2026
16 of 18 checks passed

This branch was successfully deployed

2 active deployments
preview — f23a83b6 Deployed Oct 28, 2026 by fly1d via Visual Diff #2420
default — f23a83b6 Deployed Oct 28, 2026 by fly1d via Analyze Unsafe (javascript) #2420
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