dsherret / ts-morph

TypeScript Compiler API wrapper for static analysis and programmatic code changes.
https://ts-morph.com
MIT License
4.88k stars 194 forks source link

Question: Is there swagger code gen example? #566

Open Liero opened 5 years ago

Liero commented 5 years ago

I believe I'm not the first one who is trying to get some custom code gen from swagger.json.

It would be very nice to have some example of how to generate the type definitions based on swagger input. I believe it would be perfect demonstration of the ts-morph capabilities and perfect learning source.

dsherret commented 5 years ago

Thanks for the idea @Liero! I will add some help pages with examples for code generation specifically. There's a way to do it extremely fast that I'm not even using in my code generation scripts. It would be a good exercise to do to find any shortcomings.

Liero commented 5 years ago

I wanted to have classes instead of interfaces, for example. I needed to handle generic types (definitions). I wanted to have class property to have a default value, when defined in swagger,etc..

seancheung commented 5 years ago

I have implemented a CLI tool with ts-morph to generate OpenAPI 3.0 definitions. It seems easier to do the reversal. Here are my Doc and Schema typings which might help a bit:

declare namespace JsonSchema {
    interface SchemaDef {
      $ref?: string;
      default?: any;
      description?: string;
    }
    interface TypedSchema extends SchemaDef {
      type: string;
    }
    interface BasicSchema extends TypedSchema {
      type: 'string' | 'number' | 'boolean';
    }
    interface ArraySchema extends TypedSchema {
      type: 'array';
      items: Schema;
    }
    interface LiteralSchema extends TypedSchema {
      type: 'string' | 'number' | 'boolean';
      const: any;
    }
    interface EnumSchema extends TypedSchema {
      type: 'string' | 'number' | 'boolean';
      enum: any[];
    }
    interface ObjectSchema extends TypedSchema {
      type: 'object';
      properties?: Record<string, Schema>;
      required?: string[];
    }
    interface UnionSchema extends SchemaDef {
      oneOf: Schema[];
      default?: any;
      description?: string;
    }
    interface MixedSchema extends SchemaDef {
      allOf: Schema[];
      default?: any;
      description?: string;
    }
    type Schema =
      | SchemaDef
      | BasicSchema
      | ArraySchema
      | LiteralSchema
      | EnumSchema
      | ObjectSchema
      | UnionSchema
      | MixedSchema;
  }
  type JsonSchema = JsonSchema.Schema;
  interface Doc {
    openapi: string;
    info: Doc.Info;
    servers?: Doc.Server[];
    paths: Doc.Paths;
    components?: Doc.Components;
    security?: Record<string, string[]>;
    tags?: Doc.Tag[];
  }
  declare namespace Doc {
    interface Info {
      title: string;
      version: string;
      description?: string;
    }
    interface Server {
      url: string;
      description?: string;
    }
    type Paths = Record<
      string,
      Doc.Path & Record<'get' | 'put' | 'post' | 'delete' | 'head' | 'patch', Doc.Endpoint>
    >;
    interface Path {
      summary?: string;
      description?: string;
    }
    interface Endpoint {
      requestBody: RequestBody;
      responses: Record<'default' | number, Response>;
      parameters?: Parameter[];
      tags?: string[];
      summary?: string;
      description?: string;
      security?: Array<Record<string, any>>;
      deprecated?: boolean;
    }
    interface Parameter {
      name: string;
      in: 'query' | 'header' | 'path' | 'cookie';
      description?: string;
      required?: boolean;
      deprecated?: boolean;
      $ref?: string;
      schema?: JsonSchema;
    }
    interface RequestBody {
      content: Record<string, Content>;
      description?: string;
      $ref?: string;
    }
    interface Content {
      schema?: JsonSchema;
      examples?: Record<string, Example>;
      example?: Example;
    }
    interface Example {
      summary?: string;
      description?: string;
      value?: any;
      $ref?: string;
    }
    interface Response {
      description?: string;
      headers?: Record<string, Header>;
      $ref?: string;
      content: Record<string, Content>;
    }
    interface Header {
      description?: string;
      required?: boolean;
      deprecated?: boolean;
      schema?: JsonSchema;
    }
    interface Tag {
      name: string;
      description?: string;
    }
    interface Components {
      schemas?: Record<string, JsonSchema>;
      securitySchemes?: Record<string, SecurityScheme>;
    }
    interface SecurityScheme {
      type: 'apiKey';
      name: string;
      in: 'header' | 'query' | 'cookie';
      description?: string;
    }
  }
yantrab commented 3 years ago

https://github.com/yantrab/strongly/blob/master/src/utils/typescript-service.ts

this is very old issue, but maybe it will help someone, i generate ajv/swagger schema from typescript.

peterarusanoff commented 8 months ago

sounds like you should switch to nest JS