fastify / fastify-swagger

Swagger documentation generator for Fastify
MIT License
941 stars 209 forks source link

OpenAPI resolve-schema-reference searches #/definitions/, not #/components/schemas #836

Open steveatkoan opened 21 hours ago

steveatkoan commented 21 hours ago

Prerequisites

Fastify version

5

Plugin version

5.1.0

Node.js version

22

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

latest

Description

I see an error TypeError: Cannot read properties of undefined (reading 'Success') at resolveSchemaReference (.../node_modules/@fastify/swagger/lib/util/resolve-schema-reference.js:13:39)

The error occurs because https://github.com/fastify/fastify-swagger/blob/master/lib/util/resolve-schema-reference.js#L7 which assumes that a $ref will have format '#/definitions/SchemaName'. But all my $refs are '#/components/schemas/SchemaName', so this line always fails with the above error. I could not see how to register '#/definitions'

May I suggest the following change?

  // const schemaId = resolvedReference?.$ref?.split('/', 3)[2]
  if (!resolvedReference) return undefined;
  const $ref = resolvedReference.$ref;
  const schemaId = $ref.startsWith('#/components') ? $ref.split('/', 3)[3] : $ref.split('/', 3)[2]

which fixes the problem for me. It may also fix #799

Expected Behavior

No error when rendering openapi 3 with zod and a custom transformer

steveatkoan commented 17 hours ago

If it helps: my SwaggerOptions are

 {
    mode: 'dynamic',
    openapi: {
      info: {
        title: 'foo',
        description: 'bar',
        version: '1.0.0',
        license: {
          name: 'private',
          url: 'https://www.example.com'
        }
      },
      servers: [
        {url: 'https://api.example.com', description: 'Production server'},
      ],
      components: {
        securitySchemes: {
          bearerAuth: {
            type: 'http',
            scheme: 'bearer',
            bearerFormat: 'Token',
            description: 'Token Authorisation using the Bearer scheme'
          }
        },
        schemas: schemaRegistry.getComponentSchemas()
      },
      tags: routeRegistry.getTags(),
    },
    transform: transformSchemas(schemaRegistry), // converts nested schemas in queries and responses to $refs
  };