Use OpenAPI examples in generated snippets#143
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughRequest body example generation now prefers named OpenAPI examples, with request-body rendering updated to avoid repeating standalone examples. Documentation, tests, and related metadata were adjusted to match the new output. ChangesNamed OpenAPI example selection and request-body rendering
Estimated code review effort: 2 (Simple) | ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — folds OpenAPI request-body examples into the generated cURL/fetch snippets instead of also rendering them as a standalone block before the code samples.
- Prefer named examples in snippets — new
preferredMediaExampleinpackages/leadtype/src/openapi/index.tspicksexamples.default, else the firstexamplesentry, elseexample;sampleRequestBodynow uses it. Safe becausenormalizeExamplesMapalready unwraps each Example object's.valueandhasNamedExamplesguarantees a non-empty map. - Suppress standalone request-body examples — an
includeExamplesflag is threaded symmetrically throughrenderMediaType(markdown/plugins/openapi.ts) and theMediaTypecomponents inapps/fumadocs-example/lib/mdx-components.tsxandapps/tanstack/src/components/docs-mdx/api.tsx; it defaults totrueso response examples are unchanged, and request bodies passfalse. - Docs + lock refresh —
docs/reference/openapi.mdxprose anddocs/paths.lock.jsonhashes updated to match. - Test coverage —
openapi.test.tsasserts the named example lands in both cURL andfetchsnippets and that the standaloneExample: defaultblock is gone.
ℹ️ Request bodies with multiple named examples now show only one
Previously every named request-body example rendered as its own standalone block; now the standalone blocks are suppressed and only the preferred (default, or first) example flows into the snippet. Specs that document several alternative request payloads will lose the non-preferred ones from the output entirely.
This is consistent with the PR's "tidy" intent and is not a bug — flagging only so the drop of alternative examples is a deliberate, known tradeoff rather than an accident.
Technical details
# Request bodies with multiple named examples now show only one
## Affected sites
- `packages/leadtype/src/openapi/index.ts:1168` — `preferredMediaExample` returns a single value (default / first entry).
- `packages/leadtype/src/markdown/plugins/openapi.ts:249` and the `MediaType` request-body call sites in `apps/fumadocs-example/lib/mdx-components.tsx` / `apps/tanstack/src/components/docs-mdx/api.tsx` — pass `includeExamples: false`, so the remaining named examples are no longer rendered anywhere.
## Required outcome
- No change required if losing non-preferred request examples is acceptable.
## Open questions for the human
- Do any specs in scope ship more than one named request-body example? If so, is dropping the alternatives from the reference intended, or should multiple examples still surface (e.g. as tabs or a collapsed block)?Claude Opus | 𝕏
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 51b05e40f5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (Object.hasOwn(media.examples, "default")) { | ||
| return media.examples.default; | ||
| } | ||
| return Object.values(media.examples)[0]; |
There was a problem hiding this comment.
Don't use external-only Example objects as bodies
When a request body's examples.default is an OpenAPI Example Object that only has externalValue/metadata and no inline value, normalizeExamplesMap leaves that object in media.examples; this new return then makes generated cURL/fetch snippets post the metadata object itself instead of falling back to the schema/example payload. Guard named examples to only use actual inline values, or fall back when the selected example is external-only.
Useful? React with 👍 / 👎.
| for (const media of body.content) { | ||
| nodes.push(...renderMediaType(media)); | ||
| nodes.push(...renderMediaType(media, { includeExamples: false })); |
There was a problem hiding this comment.
Keep non-selected request examples visible
When a request body defines multiple named examples, this suppresses the entire request-section example list, but the generated snippets only include one preferred example, so the remaining named examples disappear from the flattened markdown output. Keep the non-selected examples rendered somewhere, or only suppress the single example duplicated by the generated snippets.
Useful? React with 👍 / 👎.
51b05e4 to
647c882
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
apps/tanstack/src/components/docs-mdx/api.tsx (1)
136-165: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winSame empty-
examplesfallthrough issue asapps/fumadocs-example/lib/mdx-components.tsx.
media.examples || includeSingleExampletreats an emptyexamples: {}as truthy, soMediaTypeExamplescan still fall back to renderingmedia.exampleeven whenincludeSingleExample={false}(used byApiRequestBody). Same fix as suggested for the fumadocs component: checkObject.keys(media.examples ?? {}).length > 0instead of relying on object truthiness.🤖 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 `@apps/tanstack/src/components/docs-mdx/api.tsx` around lines 136 - 165, The MediaType component still uses truthiness for media.examples, so an empty examples object can incorrectly trigger MediaTypeExamples and fall back to media.example even when includeSingleExample is false. Update the conditional in MediaType to explicitly check whether media.examples has any keys, using the same pattern as the fumadocs component, so ApiRequestBody does not render a single example for empty examples.apps/fumadocs-example/lib/mdx-components.tsx (1)
354-383: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winEmpty
examples: {}can leak the single example even whenincludeSingleExampleis false.
media.examples || includeSingleExampleis truthy whenevermedia.examplesis any object, including an empty one ({}). In that edge caseMediaTypeExamplesstill renders, and sincenamedExamples.lengthis0, it falls through to renderingmedia.example— defeatingincludeSingleExample={false}used byApiRequestBodyto avoid duplicating the request-body example that's now shown in the code sample.🐛 Proposed fix
- {media.examples || includeSingleExample ? ( + {(media.examples && Object.keys(media.examples).length > 0) || + includeSingleExample ? ( <MediaTypeExamples media={media} omittedExampleName={omittedExampleName} /> ) : null}🤖 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 `@apps/fumadocs-example/lib/mdx-components.tsx` around lines 354 - 383, The MediaType conditional currently treats any object in media.examples as truthy, so an empty examples map still renders MediaTypeExamples and leaks media.example even when includeSingleExample is false. Update the render guard in MediaType to only show examples when there is at least one named example or includeSingleExample is true, and ensure MediaTypeExamples is only reached when it should actually display a single example; this will preserve the ApiRequestBody behavior that suppresses the duplicate request-body example.packages/leadtype/src/openapi/index.ts (1)
1193-1206: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated example-selection logic across 4 files.
isExternalOnlyExampleObject/preferredNamedExampleName-style logic is re-implemented nearly verbatim here, inpackages/leadtype/src/markdown/plugins/openapi.ts,apps/fumadocs-example/lib/mdx-components.tsx, andapps/tanstack/src/components/docs-mdx/api.tsx. Any future fix (including the potential wrapping bug above) needs to be applied in 4 places. Consider exporting the shared helpers from this module (or a small shared utils file) and importing them in the other three consumers, sinceApiMediaTypeis already aliased fromOpenApiMediaType.🤖 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/leadtype/src/openapi/index.ts` around lines 1193 - 1206, The example-selection logic in sampleRequestBody and its related helper flow is duplicated across multiple consumers, so update this module to expose the shared media-example helpers (including preferredMediaExample and the isExternalOnlyExampleObject/preferredNamedExampleName behavior) from a common place and have the other OpenAPI renderers import them instead of reimplementing the same selection logic. Keep the behavior centralized around OpenApiOperation/OpenApiMediaType so packages/leadtype/src/markdown/plugins/openapi.ts, apps/fumadocs-example/lib/mdx-components.tsx, and apps/tanstack/src/components/docs-mdx/api.tsx all use the same implementation.
🤖 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.
Inline comments:
In `@packages/leadtype/src/openapi/openapi.test.ts`:
- Around line 676-742: The test in openapi.test.ts for generated request body
examples is too permissive and can miss a nested example wrapper regression.
Update the assertions around generateFixturePages, convertMdxToMarkdown, and the
extracted cURL/JavaScript snippets to parse the request body JSON and verify its
exact shape, or explicitly assert that no top-level "value" wrapper is present.
Use the existing sample lookup logic for the cURL and JavaScript codeSamples to
locate the payload before asserting on the unwrapped example contents.
---
Outside diff comments:
In `@apps/fumadocs-example/lib/mdx-components.tsx`:
- Around line 354-383: The MediaType conditional currently treats any object in
media.examples as truthy, so an empty examples map still renders
MediaTypeExamples and leaks media.example even when includeSingleExample is
false. Update the render guard in MediaType to only show examples when there is
at least one named example or includeSingleExample is true, and ensure
MediaTypeExamples is only reached when it should actually display a single
example; this will preserve the ApiRequestBody behavior that suppresses the
duplicate request-body example.
In `@apps/tanstack/src/components/docs-mdx/api.tsx`:
- Around line 136-165: The MediaType component still uses truthiness for
media.examples, so an empty examples object can incorrectly trigger
MediaTypeExamples and fall back to media.example even when includeSingleExample
is false. Update the conditional in MediaType to explicitly check whether
media.examples has any keys, using the same pattern as the fumadocs component,
so ApiRequestBody does not render a single example for empty examples.
In `@packages/leadtype/src/openapi/index.ts`:
- Around line 1193-1206: The example-selection logic in sampleRequestBody and
its related helper flow is duplicated across multiple consumers, so update this
module to expose the shared media-example helpers (including
preferredMediaExample and the
isExternalOnlyExampleObject/preferredNamedExampleName behavior) from a common
place and have the other OpenAPI renderers import them instead of reimplementing
the same selection logic. Keep the behavior centralized around
OpenApiOperation/OpenApiMediaType so
packages/leadtype/src/markdown/plugins/openapi.ts,
apps/fumadocs-example/lib/mdx-components.tsx, and
apps/tanstack/src/components/docs-mdx/api.tsx all use the same implementation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 12a02dc1-908c-4060-9582-eeea5f67997f
📒 Files selected for processing (8)
.changeset/tidy-openapi-examples.mdapps/fumadocs-example/lib/mdx-components.tsxapps/tanstack/src/components/docs-mdx/api.tsxdocs/paths.lock.jsondocs/reference/openapi.mdxpackages/leadtype/src/markdown/plugins/openapi.tspackages/leadtype/src/openapi/index.tspackages/leadtype/src/openapi/openapi.test.ts
📜 Review details
⚠️ CI failures not shown inline (2)
GitHub Actions: CI / 0_Validate & test.txt: Use OpenAPI examples in generated snippets
Conclusion: failure
Current runner version: '2.335.1'
##[group]Runner Image Provisioner
Hosted Compute Agent
Version: 20260624.560
Commit: 925d229a51159bc391ae97e54a2dd1fe20af789d
Build Date:
Worker ID: {73c54a00-2beb-4a19-8e35-f036b72343d3}
Azure Region: northcentralus
##[endgroup]
##[group]Operating System
Ubuntu
24.04.4
LTS
##[endgroup]
##[group]Runner Image
Image: ubuntu-24.04
Version: 20260628.225.1
Included Software: https://github.com/actions/runner-images/blob/ubuntu24/20260628.225/images/ubuntu/Ubuntu2404-Readme.md
Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu24%2F20260628.225
##[endgroup]
##[group]GITHUB_TOKEN Permissions
Contents: read
Metadata: read
##[endgroup]
Secret source: Actions
Prepare workflow directory
Prepare all required actions
Getting action download info
Download action repository 'actions/checkout@v4' (SHA:34e114876b0b11c390a56381ad16ebd13914f8d5)
Download action repository 'oven-sh/setup-bun@v2' (SHA:0c5077e51419868618aeaa5fe8019c62421857d6)
Complete job name: Validate & test
Node 20 is being deprecated. This workflow is running with Node 24 by default. If you need to temporarily use Node 20, you can set the ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true environment variable. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
##[group]Run actions/checkout@v4
with:
repository: inthhq/leadtype
***REDACTED***
ssh-strict: true
ssh-user: git
persist-credentials: true
clean: true
sparse-checkout-cone-mode: true
fetch-depth: 1
fetch-tags: false
show-progress: true
lfs: false
submodules: false
set-safe-directory: true
##[endgroup]
Syncing repository: inthhq/leadtype
##[group]Getting Git version info
Working directory is '/home/runner/work/leadtype/leadtype'
[command]/usr/bin/git version
git version 2.54.0
##[endgroup]
Temporarily overriding HOME='/home/runner/work/_temp/3fdaa38c-0bbd-471d-9e2...
GitHub Actions: CI / Validate & test: Use OpenAPI examples in generated snippets
Conclusion: failure
##[group]Run bun run --filter leadtype test
�[36;1mbun run --filter leadtype test�[0m
shell: /usr/bin/bash -e {0}
##[endgroup]
leadtype test:
leadtype test: �[1m�[30m�[46m RUN �[49m�[39m�[22m �[36mv4.1.5 �[39m�[90m/home/runner/work/leadtype/leadtype/packages/leadtype�[39m
leadtype test:
leadtype test: �[32m✓�[39m src/llm/llm.test.ts �[2m(�[22m�[2m86 tests�[22m�[2m)�[22m�[32m 269�[2mms�[22m�[39m
leadtype test: �[32m✓�[39m src/openapi/openapi.test.ts �[2m(�[22m�[2m34 tests�[22m�[2m)�[22m�[33m 411�[2mms�[22m�[39m
leadtype test: �[32m✓�[39m src/lint/lint.test.ts �[2m(�[22m�[2m45 tests�[22m�[2m)�[22m�[33m 1054�[2mms�[22m�[39m
leadtype test: �[33m�[2m✓�[22m�[39m warns on rendered components with no flattener but not on code-block examples �[33m 316�[2mms�[22m�[39m
leadtype test: Converted 1 docs in 39 ms
leadtype test: Converted 2 docs in 7 ms
leadtype test: Converted 2 docs in 5 ms
leadtype test: Pruned 1 orphaned .md file(s) from /tmp/leadtype-convert-PNSl2i/public
leadtype test: Converted 2 docs in 9 ms
leadtype test: Converted 1 docs in 1 ms
leadtype test: Pruned 2 orphaned .md file(s) from /tmp/leadtype-convert-YAVyba/public
leadtype test: Converted 1 docs in 5 ms
leadtype test: Pruned 1 orphaned .md file(s) from /tmp/leadtype-convert-hi6Ssl/public
leadtype test: Converted 1 docs in 2 ms
leadtype test: Pruned 1 orphaned .md file(s) from /tmp/leadtype-convert-W33Dcj/public
leadtype test: Converted 1 docs in 4 ms
leadtype test: Error: failed to process /tmp/leadtype-convert-ScpIOU/docs/broken.mdx: 3:1: Unexpected character after `<`, expected a valid JSX tag (note: to create a link in MDX, use `[text](url)`) (mdx-jsx:unexpected-character)
leadtype test: Converted 1 docs in 2 ms (1 failed)
leadtype test: Warning: prune skipped: 1 file(s) failed to convert, so the expected output set is incomplete.
leadtype test: Warning: prune skipped: no .mdx sources under /tmp/leadtype-convert-ZN2U8H/empty-docs — refusing to treat every output in /...
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use explicit types for function parameters and return values when they enhance clarity
Preferunknownoveranywhen the type is genuinely unknown
Use const assertions (as const) for immutable values and literal types
Leverage TypeScript's type narrowing instead of type assertions
Files:
packages/leadtype/src/openapi/openapi.test.tsapps/tanstack/src/components/docs-mdx/api.tsxpackages/leadtype/src/markdown/plugins/openapi.tsapps/fumadocs-example/lib/mdx-components.tsxpackages/leadtype/src/openapi/index.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use meaningful variable names instead of magic numbers - extract constants with descriptive names
Use arrow functions for callbacks and short functions
Preferfor...ofloops over.forEach()and indexedforloops
Use optional chaining (?.) and nullish coalescing (??) for safer property access
Prefer template literals over string concatenation
Use destructuring for object and array assignments
Useconstby default,letonly when reassignment is needed, nevervar
Alwaysawaitpromises in async functions - don't forget to use the return value
Useasync/awaitsyntax instead of promise chains for better readability
Handle errors appropriately in async code with try-catch blocks
Don't use async functions as Promise executors
Removeconsole.log,debugger, andalertstatements from production code
ThrowErrorobjects with descriptive messages, not strings or other values
Usetry-catchblocks meaningfully - don't catch errors just to rethrow them
Prefer early returns over nested conditionals for error cases
Extract complex conditions into well-named boolean variables
Use early returns to reduce nesting
Prefer simple conditionals over nested ternary operators
Don't useeval()or assign directly todocument.cookie
Avoid spread syntax in accumulators within loops
Use top-level regex literals instead of creating them in loops
Prefer specific imports over namespace imports
Use descriptive names for functions, variables, and types for meaningful naming
Add comments for complex logic, but prefer self-documenting code
Files:
packages/leadtype/src/openapi/openapi.test.tsapps/tanstack/src/components/docs-mdx/api.tsxpackages/leadtype/src/markdown/plugins/openapi.tsapps/fumadocs-example/lib/mdx-components.tsxpackages/leadtype/src/openapi/index.ts
**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{test,spec}.{js,ts,jsx,tsx}: Write assertions insideit()ortest()blocks
Avoid done callbacks in async tests - use async/await instead
Don't use.onlyor.skipin committed code
Keep test suites reasonably flat - avoid excessivedescribenesting
Files:
packages/leadtype/src/openapi/openapi.test.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx}: Use function components over class components in React
Call hooks at the top level only, never conditionally
Specify all dependencies in hook dependency arrays correctly
Use thekeyprop for elements in iterables (prefer unique IDs over array indices)
Nest children between opening and closing tags instead of passing as props
Don't define components inside other components
AvoiddangerouslySetInnerHTMLunless absolutely necessary
Use proper image components (e.g., Next.js<Image>) over<img>tags
Use Next.js<Image>component for images
Usenext/heador App Router metadata API for head elements in Next.js
Use Server Components for async data fetching instead of async Client Components in Next.js
Use ref as a prop instead ofReact.forwardRefin React 19+
Files:
apps/tanstack/src/components/docs-mdx/api.tsxapps/fumadocs-example/lib/mdx-components.tsx
**/*.{jsx,tsx,html}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{jsx,tsx,html}: Use semantic HTML and ARIA attributes for accessibility: provide meaningful alt text for images, use proper heading hierarchy, add labels for form inputs, include keyboard event handlers alongside mouse events, use semantic elements instead of divs with roles
Addrel="noopener"when usingtarget="_blank"on links
Files:
apps/tanstack/src/components/docs-mdx/api.tsxapps/fumadocs-example/lib/mdx-components.tsx
**/index.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid barrel files (index files that re-export everything)
Files:
packages/leadtype/src/openapi/index.ts
🧠 Learnings (1)
📚 Learning: 2026-06-09T18:30:08.038Z
Learnt from: KayleeWilliams
Repo: inthhq/leadtype PR: 97
File: .changeset/search-prototype-safety-and-scaling.md:5-5
Timestamp: 2026-06-09T18:30:08.038Z
Learning: In this repo, `.changeset/*.md` files must not start the body with an H1/first-line heading (`#`) immediately after the YAML frontmatter. The changesets tool inlines the body as bullet entries into `CHANGELOG.md` during release, and a leading `#` heading would break the generated changelog format. As a result, MD041 (`first-line-heading`) warnings for files under `.changeset/` are expected false positives and should be ignored.
Applied to files:
.changeset/tidy-openapi-examples.md
🪛 ast-grep (0.44.1)
packages/leadtype/src/openapi/index.ts
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFile } from "node:child_process";
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🪛 markdownlint-cli2 (0.22.1)
.changeset/tidy-openapi-examples.md
[warning] 5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🔇 Additional comments (13)
packages/leadtype/src/markdown/plugins/openapi.ts (3)
80-111: 📐 Maintainability & Code Quality | ⚡ Quick winDuplicate of the helpers in
packages/leadtype/src/openapi/index.ts.
isRecord,isExternalOnlyExampleObject, and the "preferred example" selection logic mirrorpackages/leadtype/src/openapi/index.tsalmost exactly. See the duplication comment on that file; consolidating would reduce the maintenance surface for this logic.
128-142: LGTM!
267-290: LGTM!apps/fumadocs-example/lib/mdx-components.tsx (2)
302-352: 📐 Maintainability & Code Quality | ⚡ Quick winDuplicate of the helper logic used elsewhere.
Same
isRecord/isExternalOnlyExampleObject/preferredNamedExampleNameimplementation as inpackages/leadtype/src/openapi/index.tsandpackages/leadtype/src/markdown/plugins/openapi.tsandapps/tanstack/src/components/docs-mdx/api.tsx. Worth consolidating into one shared exported utility.
394-399: LGTM!apps/tanstack/src/components/docs-mdx/api.tsx (2)
84-134: 📐 Maintainability & Code Quality | ⚡ Quick winDuplicate of the helper logic used elsewhere.
Identical
isRecord/isExternalOnlyExampleObject/preferredNamedExampleNameimplementation as inapps/fumadocs-example/lib/mdx-components.tsx,packages/leadtype/src/markdown/plugins/openapi.ts, andpackages/leadtype/src/openapi/index.ts. Recommend consolidating into a single shared utility exported frompackages/leadtype.
289-294: LGTM!.changeset/tidy-openapi-examples.md (1)
1-6: Expected MD041 false positive.The markdownlint MD041 warning about a missing first-line heading is expected for
.changeset/*.mdfiles in this repo, since the changesets tool inlines the body as bullet entries intoCHANGELOG.mdand a leading#would break the format. Based on learnings, this warning should be ignored.Source: Learnings
packages/leadtype/src/openapi/index.ts (2)
1185-1191: LGTM!
1168-1183: 🗄️ Data Integrity & IntegrationNo bug here:
media.examplesis already unwrapped.normalizeExamplesMap()converts each OpenAPI Example Object to its.value, sopreferredMediaExample()returns the payload directly, not a nested{ value: ... }object.> Likely an incorrect or invalid review comment.packages/leadtype/src/openapi/openapi.test.ts (1)
744-780: LGTM!docs/reference/openapi.mdx (1)
102-108: LGTM!docs/paths.lock.json (1)
158-158: LGTM!Also applies to: 190-190
| it("uses named request body examples in generated snippets", async () => { | ||
| const spec = ` | ||
| openapi: 3.1.0 | ||
| info: { title: Examples, version: 1.0.0 } | ||
| servers: | ||
| - url: https://api.example.com | ||
| paths: | ||
| /sites: | ||
| post: | ||
| operationId: createSite | ||
| requestBody: | ||
| required: true | ||
| content: | ||
| application/json: | ||
| schema: | ||
| type: object | ||
| required: [organizationId, name] | ||
| properties: | ||
| organizationId: | ||
| type: string | ||
| name: | ||
| type: string | ||
| region: | ||
| type: string | ||
| consent: | ||
| type: object | ||
| properties: | ||
| branding: | ||
| type: string | ||
| examples: | ||
| default: | ||
| value: | ||
| organizationId: org_123 | ||
| name: Website | ||
| region: us-east-1 | ||
| consent: | ||
| branding: inth | ||
| enterprise: | ||
| value: | ||
| organizationId: org_456 | ||
| name: Enterprise | ||
| region: eu-west-1 | ||
| consent: | ||
| branding: custom | ||
| responses: { "201": { description: created } } | ||
| `; | ||
| const { result } = await generateFixturePages(spec); | ||
| const samples = result.pages[0]?.operation.codeSamples ?? []; | ||
| const curl = samples.find((sample) => sample.label === "cURL")?.code ?? ""; | ||
| const fetch = | ||
| samples.find((sample) => sample.label === "JavaScript")?.code ?? ""; | ||
|
|
||
| expect(curl).toContain('"organizationId": "org_123"'); | ||
| expect(curl).toContain('"branding": "inth"'); | ||
| expect(curl).not.toContain('"organizationId": "string"'); | ||
| expect(fetch).toContain('"organizationId": "org_123"'); | ||
| expect(fetch).toContain('"branding": "inth"'); | ||
|
|
||
| const converted = await convertMdxToMarkdown( | ||
| result.pages[0]?.filePath ?? "", | ||
| defaultMarkdownTransforms | ||
| ); | ||
| expect(converted.markdown).not.toContain("Example: default"); | ||
| expect(converted.markdown).toContain("Example: enterprise"); | ||
| expect(converted.markdown).toContain('"organizationId": "org_456"'); | ||
| expect(converted.markdown).toContain('"organizationId": "org_123"'); | ||
| }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
Assertions are too loose to catch an example-wrapping regression.
toContain('"organizationId": "org_123"') would still pass even if the generated body were incorrectly nested (e.g. {"value": {"organizationId": "org_123", ...}}) rather than flat, since it's only a substring check. Consider parsing the extracted JSON payload from the snippet and asserting on its exact shape (e.g. expect(JSON.parse(extractedBody)).toEqual({ organizationId: "org_123", ... })), or at least assert the absence of a wrapping "value": key, to guard against the example object being used verbatim instead of its unwrapped payload.
🤖 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/leadtype/src/openapi/openapi.test.ts` around lines 676 - 742, The
test in openapi.test.ts for generated request body examples is too permissive
and can miss a nested example wrapper regression. Update the assertions around
generateFixturePages, convertMdxToMarkdown, and the extracted cURL/JavaScript
snippets to parse the request body JSON and verify its exact shape, or
explicitly assert that no top-level "value" wrapper is present. Use the existing
sample lookup logic for the cURL and JavaScript codeSamples to locate the
payload before asserting on the unwrapped example contents.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the branch was rebased into a single commit that reworks how request-body examples are rendered and adds handling for external-only OpenAPI Example Objects, since the prior pullfrog review at 51b05e4.
- Preserve non-preferred named examples — request bodies previously suppressed every standalone example (
includeExamples: false); now only the example that flows into the snippet is omitted (omitExampleName/omittedExampleName), and the remaining named examples still render as standalone blocks. This resolves the prior review's note that alternative named examples were being dropped. - Skip external-only examples — a shared
isExternalOnlyExampleObjecthelper (added topackages/leadtype/src/openapi/index.ts,markdown/plugins/openapi.ts, and bothMediaTyperenderers) detects Example Objects withexternalValuebut no inlinevalue;preferredMediaExampleskips them andsampleRequestBodyfalls back to a schema-synthesized payload. - Renamed renderer prop —
includeExamples→includeSingleExample, with a newpreferredNamedExampleNamein each renderer mirroringpreferredMediaExample's selection order so the omitted standalone example matches the one used in the snippet. - Test coverage — the
uses named request body examplestest now asserts a secondenterpriseexample still surfaces standalone, and a newignores external-only request body examplestest asserts external-only payloads are excluded from both cURL andfetchsnippets. Full 34-test openapi suite passes.
ℹ️ External-only examples still render as standalone JSON in request bodies
The new isExternalOnlyExampleObject guard keeps external-only Example Objects out of the generated snippet, but the standalone renderers don't apply the same filter. When a request body has a non-preferred named example that is external-only, MediaTypeExamples (fumadocs/tanstack) and renderMediaType (markdown) still emit it as an Example: <name> block whose JSON body is the raw { "summary": ..., "externalValue": "https://..." } Example Object rather than an actual payload.
This is mergeable as-is — external-only request examples are rare, and surfacing the reference isn't strictly wrong — but the snippet-vs-standalone asymmetry may be unintended given the PR explicitly added the external-only guard for the snippet path.
Technical details
# External-only examples still render as standalone JSON in request bodies
## Affected sites
- `apps/fumadocs-example/lib/mdx-components.tsx` — `MediaTypeExamples` maps over `namedExamples` filtering only `omittedExampleName`; an external-only entry that isn't the preferred one is rendered via `<JsonExample value={value} />` where `value` is the intact `{ summary, externalValue }` object.
- `apps/tanstack/src/components/docs-mdx/api.tsx` — same `MediaTypeExamples` shape.
- `packages/leadtype/src/markdown/plugins/openapi.ts` — `renderMediaType` iterates `media.examples` skipping only `omitExampleName`; external-only entries reach `renderJsonExample(value)`.
## Required outcome
- Decide whether external-only examples should appear as standalone blocks at all in the request-body context; if not, skip entries where `isExternalOnlyExampleObject(value)` in the same three sites (and/or render the external URL as a link rather than a JSON dump).
## Open questions for the human
- Is dumping the raw `externalValue` Example Object as JSON intended, or should external-only examples be linked / omitted from the standalone render the way they're already excluded from the snippet?Claude Opus | 𝕏

Summary
examples.default, when generating cURL and JavaScript snippets.Why
Request body examples were shown once as
Example: defaultand then generated snippets could still use synthesized placeholder payloads. That made the API reference repetitive and sometimes inconsistent. The request payload now appears where users copy it: in the generated snippets.Validation
bun test packages/leadtype/src/openapi/openapi.test.tsbun x ultracite check .changeset/tidy-openapi-examples.md apps/fumadocs-example/lib/mdx-components.tsx apps/tanstack/src/components/docs-mdx/api.tsx docs/paths.lock.json docs/reference/openapi.mdx packages/leadtype/src/markdown/plugins/openapi.ts packages/leadtype/src/openapi/index.ts packages/leadtype/src/openapi/openapi.test.tsNote: the local pre-commit full-suite hook was not used for the final commit because
leadtype CLI > runs lint against this repo's docsfails in this checkout with existing docs snippet type-resolution errors for Node/React/leadtype types outside this patch.