fastify / fastify-swagger

Swagger documentation generator for Fastify
MIT License
910 stars 200 forks source link

Add support for readonly schemas #729

Closed SkeLLLa closed 1 year ago

SkeLLLa commented 1 year ago

Prerequisites

🚀 Feature Proposal

Add support for readonly arrays tags, consumes, produces, security in schema.

Motivation

Currently fastify-swagger extends FastifySchema interface with following properties:

  interface FastifySchema {
    hide?: boolean;
    deprecated?: boolean;
    tags?: string[];
    description?: string;
    summary?: string;
    consumes?: string[];
    produces?: string[];
    externalDocs?: OpenAPIV2.ExternalDocumentationObject | OpenAPIV3.ExternalDocumentationObject;
    security?: Array<{ [securityLabel: string]: string[] }>;
    /**
     * OpenAPI operation unique identifier
     */
    operationId?: string;
  }

It contains arrays like tags, consumes, produces, security.

Also fastify supports "Type-Providers" and json-schema-to-ts requires schema to be readonly.

Example

Short example that demonstrates current behavior with error:

import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts'

import fastify from 'fastify'
import { fastifySwagger } from '@fastify/swagger';

const server = fastify().withTypeProvider<JsonSchemaToTsProvider>()
await server.register(fastifySwagger)

server.get('/route', {
    schema: {
        tags: ['foo'], // TS error
        querystring: {
            type: 'object',
            properties: {
                foo: { type: 'number' },
                bar: { type: 'string' },
            },
            required: ['foo', 'bar']
        }
    } as const // don't forget to use const !

}, (request, reply) => {

    // type Query = { foo: number, bar: string }

    const { foo, bar } = request.query // type safe!
})

It might be that's all that should be done is just to make interface like that, correct me if I'm wrong.

  interface FastifySchema {
    hide?: boolean;
    deprecated?: boolean;
    tags?: readonly string[];
    description?: string;
    summary?: string;
    consumes?: readonly string[];
    produces?: readonly string[];
    externalDocs?: OpenAPIV2.ExternalDocumentationObject | OpenAPIV3.ExternalDocumentationObject;
    security?: readonly Array<{ [securityLabel: string]: readonly string[] }>;
    /**
     * OpenAPI operation unique identifier
     */
    operationId?: string;
  }