Skip to content

feat: OpenAPI Cyclic Types support#7283

Merged
Nick-Lucas merged 13 commits into
mainfrom
openapi-recursive-types
Mar 28, 2026
Merged

feat: OpenAPI Cyclic Types support#7283
Nick-Lucas merged 13 commits into
mainfrom
openapi-recursive-types

Conversation

@Nick-Lucas

@Nick-Lucas Nick-Lucas commented Mar 23, 2026

Copy link
Copy Markdown
Contributor
  • Drops the depth limit of 20, and significantly hardens cyclic-type support for both inference and Zod
  • Support zod.lazy via Standard Schema fallback
  • Strip symbols from output (no more weird async generator output until we can do that right)
  • Add more comprehensive types for the OpenAPI doc from the official package (now a dependency) and apply some patches to these types because they're slightly outdated
  • Fixes several issues with gathering schema descriptions, such as consuming jsdoc comments from node_modules types

🎯 Changes

What changes are made in this PR? Is it a feature or a bug fix?

✅ Checklist

  • I have followed the steps listed in the Contributing guide.
  • If necessary, I have added documentation related to the changes made.
  • I have added or updated the tests related to the changes made.

Summary by CodeRabbit

  • New Features
    • Enhanced OpenAPI 3.1 typing and schema generation; added generated typed clients, SDK, SSE client, and utility helpers for query/path/body serialization.
  • Bug Fixes
    • Fixed recursive/schema generation: removed depth truncation, improved $ref resolution, preserved non-empty component schemas and nested descriptions.
  • Tests
    • Added comprehensive tests covering recursive, mutual, nullable and edge-case schema generation and OpenAPI structure.
  • Documentation
    • README TODO updated; added plan for z.lazy() handling and async-generator investigation.

@Nick-Lucas
Nick-Lucas requested a review from a team as a code owner March 23, 2026 20:30
Copilot AI review requested due to automatic review settings March 23, 2026 20:30
@railway-app
railway-app Bot temporarily deployed to trpc-sse-and-websockets / trpc-pr-7283 March 23, 2026 20:31 Destroyed
@railway-app

railway-app Bot commented Mar 23, 2026

Copy link
Copy Markdown

🚅 Deployed to the trpc-pr-7283 environment in trpc-sse-and-websockets

Service Status Web Updated (UTC)
next-prisma-websockets-starter ✅ Success (View Logs) Mar 28, 2026 at 9:56 am
next-sse-chat ✅ Success (View Logs) Web Mar 28, 2026 at 9:51 am

@coderabbitai

coderabbitai Bot commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Switched the OpenAPI generator to use a project-local OpenAPI 3.1 type layer, improved recursive/schema registration to emit stable $refs (removed depth>20 truncation), tightened schema/operation types, added helpers for schema traversal, and introduced extensive cyclic/edge-case tests plus many autogenerated client/SDK fixtures and test utilities.

Changes

Cohort / File(s) Summary
Readme & package
packages/openapi/README.md, packages/openapi/package.json
README TODO updated; added openapi-types devDependency.
OpenAPI types module
packages/openapi/src/types.ts
New project-local OpenAPI 3.1 TypeScript layer built on openapi-types; defines stricter SchemaObject, Document, ComponentsObject, etc.
Generator core
packages/openapi/src/generate.ts
Replaced local JsonSchema/OpenAPIDocument shapes with imported/./types types; removed depth>20 fallback; implemented placeholder registration and post-conversion filling for cyclic refs; adjusted recursion visitation and property-symbol skipping; improved procedure input recovery and pre-registration. Public return type now Promise<Document>.
Barrel exports
packages/openapi/src/index.ts
Narrowed barrel exports (removed JsonSchema/OpenAPIDocument) and re-exported ./types as OpenAPIV3_1.
Schema extraction
packages/openapi/src/schemaExtraction.ts
APIs migrated to SchemaObject; added getArrayItemsSchema/getPropertySchema; changed nested-description traversal and added safe handling for Zod lazy() with cycle detection.
Test helpers
packages/openapi/test/types.ts
New shared test utilities for Document/schema traversal, $ref resolution, input/output extraction, and required getters used across tests.
Tests refactor & additions
packages/openapi/test/{generate.test.ts,edgeCases.test.ts,schemaExtraction.test.ts,openApiCompat.test.ts}
Refactored tests to use Document and new helpers; removed local ref-resolvers; added compile-time compatibility test vs OpenAPIV3_1.Document.
Cyclic fixtures & tests
packages/openapi/test/cyclicTypes.test.ts, packages/openapi/test/routers/cyclicTypesRouter.ts, packages/openapi/test/routers/cyclicTypesRouter.ts.json
Added router, OpenAPI fixture and a comprehensive Vitest suite validating many recursive/mutual-recursive TypeScript and Zod shapes, ensuring concrete component schemas and correct $ref wiring (no empty {} schemas).
Generated client/SDK fixtures
packages/openapi/test/routers/cyclicTypesRouter-heyapi/*
Added many autogenerated client modules (client factory, types, utils: query/path/body serializers, interceptors, SSE client, params, SDK, index). Complex control flow—review interceptors, SSE retry/backoff, auth, serializers, and URL/body merging.
Edge-case generator artifacts
packages/openapi/test/routers/edgeCaseRouter-heyapi/types.gen.ts, packages/openapi/test/routers/edgeCaseRouter.ts.json
Simplified AsyncIterable schema (removed explicit symbol-like property) and updated generated JSON schema.
Small updates / config
.coderabbit.yaml, packages/openapi/README.md, packages/openapi/test/routers/appRouter-heyapi/types.gen.ts, packages/openapi/test/routers/appRouter.ts.json
Added reviewer path config; README TODO changes; fixed request input type to Category and corresponding OpenAPI param schema.
Test fixtures updates
packages/openapi/test/schemaExtraction.test.ts, other tests
Refactors to use new helper getters and SchemaObject signatures; added tests covering recursive z.lazy() description extraction.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant BeforeRequest as beforeRequest
  participant Interceptors
  participant Fetch as fetch
  participant Parser as parse/validate

  Client->>BeforeRequest: normalize options (merge headers, auth, body, serializedBody)
  BeforeRequest->>Interceptors: run request interceptors
  Interceptors->>Fetch: perform fetch(url, request)
  Fetch-->>Interceptors: raw Response or network error
  Interceptors->>Parser: run response or error interceptors
  Parser->>Client: parse/validate/transform and return data or throw
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • KATT
  • juliusmarminge
  • ixahmedxi

Poem

🐰
I hopped through refs and chased each looping bend,
Registered placeholders until every cycle did mend.
Tests hum like crickets, clients sprint and yield,
A rabbit cheers: recursive schemas now revealed! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning PR description is largely incomplete and does not follow the template structure; the Changes and Checklist sections lack substantive detail and the checklist items are unchecked. Provide a detailed summary of the changes under the Changes section and mark completed checklist items with [x]. Clarify which changes are features vs bug fixes, and document any breaking changes or migration guidance.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: OpenAPI Cyclic Types support' directly matches the main feature being added - comprehensive cyclic/recursive type support in the OpenAPI generator.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch openapi-recursive-types

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@vercel

vercel Bot commented Mar 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
next-prisma-starter Ready Ready Preview Mar 28, 2026 9:47am
og-image Ready Ready Preview, Comment Mar 28, 2026 9:47am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR extends @trpc/openapi’s generator and test suite to better support cyclic/recursive TypeScript and Zod types, while tightening the exported OpenAPI type surface to align with openapi-types (OpenAPI v3.1).

Changes:

  • Add a new cyclic-types router fixture and a dedicated test suite to validate recursive schema emission.
  • Refactor schema typing across generator/tests to use the new src/types.ts OpenAPI v3.1 type wrappers.
  • Update generator recursion handling and add an OpenAPI type compatibility test against openapi-types.

Reviewed changes

Copilot reviewed 32 out of 33 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/openapi/src/generate.ts Updates schema generation to use new OpenAPI v3.1 types and adjusts recursion handling.
packages/openapi/src/types.ts Introduces shared OpenAPI v3.1 type wrappers (Document/SchemaObject/etc.) based on openapi-types.
packages/openapi/src/schemaExtraction.ts Switches description overlay logic to operate on SchemaObject.
packages/openapi/src/index.ts Changes package type exports to expose OpenAPIV3_1 types.
packages/openapi/test/types.ts Adds shared test helpers for inspecting OpenAPI documents/schemas.
packages/openapi/test/generate.test.ts / edgeCases.test.ts / schemaExtraction.test.ts Refactors tests to use the new helper utilities and new OpenAPI types.
packages/openapi/test/cyclicTypes.test.ts Adds a new test suite for cyclic types.
packages/openapi/test/routers/cyclicTypesRouter.ts (+ snapshots + hey-api output) Adds a new router fixture and generated OpenAPI/hey-api outputs for cyclic types.
packages/openapi/test/openApiCompat.test.ts Adds a type-level compatibility check vs published openapi-types.
packages/openapi/package.json / pnpm-lock.yaml Adds openapi-types dependency and updates lockfile.
packages/openapi/README.md Updates TODO list related to recursion/async generator investigation.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/openapi/test/cyclicTypes.test.ts Outdated
Comment thread packages/openapi/test/routers/cyclicTypesRouter-heyapi/types.gen.ts Outdated
Comment thread packages/openapi/test/routers/cyclicTypesRouter.ts.json Outdated
Comment thread packages/openapi/src/generate.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 37 out of 38 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

packages/openapi/package.json:97

  • openapi-types is imported from src/types.ts and re-exported (via export * as OpenAPIV3_1 from './types'). Since these types are part of the published .d.ts surface, consumers will need openapi-types installed to typecheck. Listing it only under devDependencies may cause downstream TS resolution errors; it should be in dependencies (or peerDependencies if you want consumers to provide it).
  "devDependencies": {
    "@hey-api/openapi-ts": "^0.94.1",
    "@swagger-api/apidom-ls": "^1.6.0",
    "@tanstack/intent": "^0.0.23",
    "@trpc/server": "11.15.0",
    "@types/node": "^22.13.5",
    "bson": "^7.2.0",
    "eslint": "^9.26.0",
    "ion-js": "^5.2.1",
    "openapi-types": "^12.1.3",
    "superjson": "^1.12.4",
    "tsdown": "0.12.7",
    "typescript": "^5.9.2",
    "vscode-languageserver-textdocument": "^1.0.12",
    "zod": "^4.2.1"
  },
  "peerDependencies": {
    "@hey-api/openapi-ts": ">=0.13.0",
    "@trpc/server": "11.15.0",
    "typescript": ">=5.7.2",
    "zod": ">=4.0.0"
  },

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/openapi/src/schemaExtraction.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 40 out of 41 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 44 out of 45 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/openapi/src/schemaExtraction.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 44 out of 45 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 64 out of 65 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been locked because we are very unlikely to see comments on closed issues. If you think, this PR is still necessary, create a new one with the same branch. Thank you.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants