Skip to content

Conversation

@MarcelOlsen
Copy link

@MarcelOlsen MarcelOlsen commented Nov 6, 2025

Problem

Guard schemas defined via guard() do not appear in the generated OpenAPI specification. Routes exist but lack requestBody and parameter schemas.

Current Behavior

app.guard({
  body: t.Object({
    username: t.String(),
    password: t.String()
  })
}, (app) =>
  app
    .post('/sign-up', ({ body }) => body)
    .post('/sign-in', ({ body }) => body)
)

OpenAPI output:

{
  "/sign-up": {
    "post": {
      "operationId": "postSign-up"
      // No requestBody!
    }
  }
}

Root Cause

The plugin reads routes via app.getGlobalRoutes(), which returns guard schemas in standaloneValidator arrays. The plugin only checks direct schema properties like route.hooks.body.

Solution

Use app.getFlattenedRoutes() (added in elysiajs/elysia#1533) which merges standaloneValidator arrays into direct hook properties.

Changes

File: src/openapi.ts, line 298

// Before
const routes = app.getGlobalRoutes()

// After
const routes = app.getFlattenedRoutes?.() ?? app.getGlobalRoutes()

Backward Compatibility

The optional chaining (?.()) ensures compatibility with Elysia versions that don't have getFlattenedRoutes() yet.

After Fix

OpenAPI output:

{
  "/sign-up": {
    "post": {
      "requestBody": {
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "username": { "type": "string" },
                "password": { "type": "string" }
              },
              "required": ["username", "password"]
            }
          }
        },
        "required": true
      },
      "operationId": "postSign-up"
    }
  }
}

Dependencies

Requires: elysiajs/elysia#1533 (adds getFlattenedRoutes() method)

Note on versions:

Demo

Reproduction case and full documentation: https://github.com/MarcelOlsen/elysia-guard-openapi-fix-demo

Testing

The fix has been tested with:

  • Basic guard() schemas
  • Nested guards
  • Mixed guard + direct schemas
  • All schema types (body, query, params, headers, cookie, response)

All schemas now appear correctly in the OpenAPI documentation.

Summary by CodeRabbit

  • Refactor
    • Improved internal route handling logic with better version compatibility support.

… spec

Fixes guard() schemas not appearing in generated OpenAPI documentation.

Changes:
- Replace app.getGlobalRoutes() with app.getFlattenedRoutes?.() ?? app.getGlobalRoutes()
- Maintains backward compatibility with older Elysia versions

This allows the OpenAPI plugin to access guard() schemas that are now
exposed via Elysia's getFlattenedRoutes() method.

Requires: elysiajs/elysia#1533
@coderabbitai
Copy link

coderabbitai bot commented Nov 6, 2025

Walkthrough

The code updates route retrieval in src/openapi.ts to call getFlattenedRoutes() when present, falling back to getGlobalRoutes() for older versions; uses optional chaining and a TypeScript expect-error to access the protected method without changing public signatures.

Changes

Cohort / File(s) Change Summary
Route retrieval fallback mechanism
src/openapi.ts
Replaced direct getGlobalRoutes() usage with conditional call to getFlattenedRoutes() (when available) and fallback to getGlobalRoutes(); added optional chaining and a // @ts-expect-error`` comment to reference the protected API.

Sequence Diagram(s)

sequenceDiagram
    participant OpenAPI as toOpenAPISchema
    participant Server as FastifyInstance
    participant Routes as RouteCollection

    OpenAPI->>Server: request routes
    alt getFlattenedRoutes exists
        Server->>Routes: getFlattenedRoutes()
        note right of Routes `#DFF0D8`: flattened routes returned
    else fallback
        Server->>Routes: getGlobalRoutes()
        note right of Routes `#FFF3CD`: legacy routes returned
    end
    Routes-->>OpenAPI: route list
    OpenAPI->>OpenAPI: extract guards/schemas
    OpenAPI-->>Caller: OpenAPI schema
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

  • Single-file change with a clear compatibility fallback
  • Review focus: correctness of optional chaining and the @ts-expect-error usage; ensure no behavioral regressions when route shapes differ

Poem

🐇 I nibble on code to bridge the old and new,

Flattened paths or classic ways — I'll choose what's true.
With a gentle TS wink and a fallback so neat,
I hop through routes and make their paths meet. ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: replacing getGlobalRoutes() with getFlattenedRoutes() to fix the omission of guard() schemas from OpenAPI specifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9095926 and da02e4d.

📒 Files selected for processing (1)
  • src/openapi.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/openapi.ts

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.

@MarcelOlsen MarcelOlsen marked this pull request as draft November 6, 2025 22:15
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 070919e and 9095926.

📒 Files selected for processing (1)
  • src/openapi.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/openapi.ts (2)
example/gen.ts (1)
  • app (6-77)
test/gen/sample.ts (1)
  • app (5-61)

MarcelOlsen added a commit to MarcelOlsen/elysia-openapi that referenced this pull request Nov 7, 2025
   fix: use @ts-expect-error instead of @ts-ignore

   Addresses coderabbitai feedback on PR elysiajs#300.

   Changed from @ts-ignore to @ts-expect-error for better type safety.
   This ensures the suppression is still necessary - if the error goes
   away in the future (e.g., after types are updated), @ts-expect-error
   will fail the build, alerting us to remove it.

   Also improved the comment to be more descriptive about why the
   suppression is needed.
   Addresses coderabbitai feedback on PR elysiajs#300.

   Changed from @ts-ignore to @ts-expect-error for better type safety.
   This ensures the suppression is still necessary - if the error goes
   away in the future (e.g., after types are updated), @ts-expect-error
   will fail the build, alerting us to remove it.

   Also improved the comment to be more descriptive about why the
   suppression is needed.
@MarcelOlsen MarcelOlsen force-pushed the fix/use-flattened-routes-for-guard-schemas branch from 1fcdb20 to da02e4d Compare November 7, 2025 09:31
@MarcelOlsen
Copy link
Author

MarcelOlsen commented Nov 7, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 7, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

1 similar comment
@coderabbitai
Copy link

coderabbitai bot commented Nov 7, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@MarcelOlsen MarcelOlsen marked this pull request as ready for review November 7, 2025 09:36
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.

1 participant