fastify / fastify-swagger

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

Extensions for the info object are not supported (at least in Typescript) #618

Open dgg opened 2 years ago

dgg commented 2 years ago

Prerequisites

Fastify version

4.0.0

Plugin version

7.2.0

Node.js version

16.15.0

Operating system

macOS

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

12.4 Monterey

Description

We are using Fastify-Swagger to generate an Open API specification for our API and we want to use Open API extensions to extend the Info Object. In particular we want to use the "x-logo" extension property. WE are using Typescript and when the extension is added to the openapi.info object, the typescript compiler fails as the InfoObject interface definition does not allow extensions.

Steps to Reproduce

Add a property x-logo: {} to the openapi.info object and compile the code.

Expected Behavior

I would expect that both the type allows the usage of other property names than the ones in the specification, but also allow the usage of extensions.

Such extensions should be passed as-is when the specification is built.

mcollina commented 2 years ago

I think this would work as planned in JS but it's failing in TS.

Would you like to send a Pull Request to address this issue? Remember to add unit tests.

climba03003 commented 2 years ago

The types is provided by openapi-types. Please extends the module declaration under openapi-types, not @fastify/swagger. I think it should works currently without modification.

mcollina commented 2 years ago

Maybe we should document this in the README?

dgg commented 2 years ago

I'll give it a shot and see if I can send a PR

dgg commented 2 years ago

@mcollina you were right, it works and it is "only a type issue"

Looking into @fastify/swagger and openapi-types gave me the idea on how to solve my issue without having to change any code. I could extend the type for the .info property to have the desired ´x-logo´ property.

First, define the type for the x-logo property:

interface XLogo {
    url: string
    altText?: string
}

Then extended what it would be the InfoObject if types from openapi-types were to be exposed by @fastify/swagger, but with a little bit of type trickery we can achieve the same without having to install extra packages:

type ExtendedInfo = Exclude<FastifyDynamicSwaggerOptions["openapi"], undefined>["info"] & {
    "x-logo": XLogo
}

From then on, we can define an object with that extended type:

const info: ExtendedInfo = {
    "title": "the_title",
    "version": "the_version",
    "description": "the_description",
    "x-logo": {
        url: "/reference/logo.svg",
        altText: "the_alt_text"
    }
}

Which, then, can be assigned to the OpenApi options:

const swaggerOptions: FastifyDynamicSwaggerOptions = {
    openapi: {
        info,
        ...
    },
...
}

I hope this helps someone in the same situation.

I would still consider submitting a PR to the openapi-types project to allow easier extensions, but it is a little bit clunky with all those generics rippling out everywhere.

Shall I mark the issue as done?

climba03003 commented 2 years ago

Shall I mark the issue as done?

You can provide a PR (update the document) for the solution you found.

dgg commented 2 years ago

Well, I can add a test to showcase how it can be done. There is no code change per se. I'll do that if you think it is useful

On Thu, 16 Jun 2022, 14:40 KaKa, @.***> wrote:

Shall I mark the issue as done?

You can provide a PR (update the document) for the solution you found.

— Reply to this email directly, view it on GitHub https://github.com/fastify/fastify-swagger/issues/618#issuecomment-1157614289, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHWFMGXIVEQXADV4M67DQ3VPMOFFANCNFSM5YTPR22Q . You are receiving this because you authored the thread.Message ID: @.***>