acacode / swagger-typescript-api

Generate the API Client for Fetch or Axios from an OpenAPI Specification
MIT License
3.35k stars 361 forks source link

Enums not generated #344

Open AsasInnab opened 2 years ago

AsasInnab commented 2 years ago

I can't seem to get enums to be generated. What I understand from the documentation is that enums should be generated by default.

I'm trying out the petstore example: npx swagger-typescript-api -p https://petstore.swagger.io/v2/swagger.json -o ./generated2 --enum-names-as-values

And I get status as an union type instead of an enum although I have not set --union-enums flag:

export interface Pet {
  /** @format int64 */
  id?: number;
  category?: Category;

  /** @example doggie */
  name: string;
  photoUrls: string[];
  tags?: Tag[];

  /** pet status in the store */
  status?: 'available' | 'pending' | 'sold';
}
dkocich commented 2 years ago

I also noticed this. We have multiple docs and from YAML we get enums successfully but from JSON we do not and there is always string union...

aleshka-maple commented 2 years ago

I guess this happens because enam "status" is defined as a property of Pet with definition { type: 'string', enum: ['available', 'pending', 'sold'] } in swagger.json but this lib generates types relaying on 'components/schemas/...' from swagger.json Working example (swagger.json)

  {
     ...,
     "components": {
          "schemas": {
              "Pet": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "$ref": "#/components/schemas/PetStatusEnum"
                    }
                  }
              },
              "PetStatusEnum": {
                  "type": "string",
                  "enum": ["available", "pending", "sold"]
              }
          }
     }
  }

It also makes PetStatusEnam reusable for other definitions

magersoft commented 2 years ago

I have the same issue, Enums not generated

my swagger schema

{
            "name": "type",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "TEXT",
                "DIGIT",
                "DATE",
                "TABLE"
              ],
              "type": "string"
            }
          },

but generated file

type: 'TEXT' | 'DIGIT' | 'DATE' | 'TABLE'

I have not set --union-enums flag

LintaoAmons commented 2 years ago

Facing the same issue~

wirekang commented 2 years ago

Same here.

wirekang commented 2 years ago

I found solution!

Not working example:

enum MyEnum {
  Asdf = 'asdf',
  Qwer = 'qwer',
}

export class MyClass {
  @ApiProperty({enum: MyEnum })
  my: MyEnum
}

Working example:

enum MyEnum {
  Asdf = 'asdf',
  Qwer = 'qwer',
}

export class MyClass {
  @ApiProperty({enum: MyEnum, enumName: "MyEnum" })
  my: MyEnum
}

If you set enumName property, as @aleshka-maple said, the type generated in components/schemas.

magersoft commented 2 years ago

I try this, but not working. I got same string in the generated file with different enumName property

evtk commented 2 years ago

Any updates on this? Having the exact same issue. Should just work out of the box right?

js2me commented 2 years ago

@evtk @dkocich @aleshka-maple @magersoft will add flag --extract-enums for extracting enums into enum

Currently It's not working as you want because I don't have any name for enums, but I with using --extract-enums flag swagger-typescript-api will generate enum name based on property and schema name

js2me commented 2 years ago

Any ideas of how can I name keys of enum construction based on this schema ?

image

 enum TreeMode {
   100644 = 100644,
   100755= 100755,
   040000= 040000,
   160000= 160000,
   120000= 120000,
 }
dkocich commented 2 years ago

we started naming enums manually based on the generated enum and the property so we can find the generated schema easily and migrate later to generated enums (so ...DTO + State/Type )

image

@js2me I would add an extra character in front of numeric values (something like _ / x / num) but those can be also -1, 0.1, etc. so it might be harder to check

js2me commented 1 year ago

@evtk @dkocich @AsasInnab problem should be fixed in Release 12.0.0.
Reopen this issue if problem is still occurring

evtk commented 1 year ago

Thanks @js2me. I tested out locally, but cannot confirm yet it is working. So I took your test example to verify.

npm ls swagger-typescript-api -> swagger-typescript-api@12.0.1

swagger-typescript-api -p path-to-the.json --output -o output -n api.ts --extract-enums

Expected Result export interface Tree { tree?: { mode?: TreeMode; "mode-num"?: TreeModeNum; type?: TreeType; bereke?: TreeBereke; }[]; }

Actual Result export interface Tree { tree?: { mode?: "100644" | "100755" | "040000" | "160000" | "120000"; "mode-num"?: 100644 | 100755 | 40000 | 160000 | 120000; type?: "blob" | "tree" | "commit"; bereke?: "Bla" | "Blabla" | "Boiler"; }[]; }

evtk commented 1 year ago

@js2me the index.js is missing the mapping for extactEnums inside the generateApi

js2me commented 1 year ago

@evtk sorry about that :)
Fixed in 12.0.2, please check again

evtk commented 1 year ago

@js2me yes confirmed that it now works. Thanks for the quicky!

dkocich commented 1 year ago

@js2me I was checking 12.0.0, it did not work; now with 12.0.2 it is hanging there with no progress s in my two projects (I used it with and without pre/suffixes swagger-typescript-api -p src/docs/swaggerSpecV2.json --extract-enums --type-prefix "prefix" --type-suffix "suffix" --debug -o ./src/gen/api)... with additional --debug I can see only this which does not tell much where the problem is; any clue what might go wrong or how to provide more info?

resolving name with using [ null ]
trying to resolve name with using fallback name generator
resolving name with using [Function (anonymous)]
resolving name with using [ null ]
trying to resolve name with using fallback name generator
resolving name with using [Function (anonymous)]
js2me commented 1 year ago

@dkocich can you share part of your schema where you have the enum which should be extracted ?

dkocich commented 1 year ago

@js2me I tried only with one API route and state which was successfully extracted to the TS file. The problem is somewhere else in the rest of 25000+ lines long API spec which appears to be correct and displayed correctly in web IDE such as https://editor-next.swagger.io/ . I can't share the complete file. I see it hangs in the same state when I tried to run transformation inside the project's repo using "cli:json" NPM script. I will try to debug a give more info in a day or two

{
  "openapi": "3.0.0",
  "paths": {
    "/api/v1/assign-subtype/{subtypeId}": {
      "post": {
        "tags": [""],
        "summary": "",
        "parameters": [
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminUserCardResponseDTO"
                }
              }
            }
          },
          "404": { "description": "" }
        },
        "operationId": "AdminUserCard_addAUserCardSubtypeToAUserCard"
      }
    }
  },
  "components": {
    "schemas": {
      "AdminUserCardResponseDTO": {
        "properties": {
          "id": { "type": "number", "example": "100" },
          "state": {
            "type": "string",
            "enum": [
              "NEW",
              "PENDING"
            ],
            "example": "APPROVED"
          },
        },
        "type": "object",
        "required": [
          "id",
          "state"
        ]
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "apiKey",
        "description": "Value: Bearer {token}",
        "name": "Authorization",
        "in": "header"
      }
    }
  },
  "security": [{ "Bearer": [] }],
  "info": {
    "contact": {
      "name": "",
      "url": "",
      "email": ""
    },
    "description": "",
    "title": "API",
    "version": "1.0.0",
    "license": { "name": "MIT", "url": "https://opensource.org/licenses/MIT" },
    "termsOfService": "",
    "x-logo": { "url": "" },
    "x-tagGroups": [
      {
        "name": "Admin",
        "tags": [
          "Admin User",
          "Admin Feed"
        ]
      },
      {
        "name": "General",
        "tags": [
          "Feed"
        ]
      }
    ]
  }
}
export interface AdminUserCardResponseDTO {
  /** @example "100" */
  id: number;
  /** @example "APPROVED" */
  state: AdminUserCardResponseDtoState;
}

/** @example "APPROVED" */
export enum AdminUserCardResponseDtoState {
  NEW = "NEW",
  PENDING = "PENDING"
}
AlekseyP18 commented 1 year ago

Have the same problem "swagger-typescript-api": "12.0.2"

Config

generateApi({ name: "api-types.ts", output: path.resolve(__dirname, '../src/api'), url: '...', templates: path.resolve(__dirname, '../templates'), modular: true, generateUnionEnums: false, hooks: { onCreateComponent, }, }).catch(e => console.error(e))

My short openapi.json

{ "openapi":"3.0.2", "info":{ "title":"Accounting", "description":"An accounting project", "version":"0.1.0" }, "paths":{ "/api/v1/user/auth/register":{ "post":{ "summary":"Register User", "operationId":"register_user_api_v1_user_auth_register_post", "parameters":[ { "required":false, "schema":{ "title":"Invitation Token", "type":"string" }, "name":"invitation_token", "in":"query" } ], "requestBody":{ "content":{ "application/json":{ "schema":{ "$ref":"#/components/schemas/UserRegisterRequest" } } }, "required":true }, "responses":{ "200":{ "description":"Successful Response", "content":{ "application/json":{ "schema":{ "$ref":"#/components/schemas/UserRegisterResponse" } } } }, "422":{ "description":"Validation Error", "content":{ "application/json":{ "schema":{ "$ref":"#/components/schemas/HTTPValidationError" } } } } } } } }, "components":{ "schemas":{ "UserRegisterData":{ "title":"UserRegisterData", "required":[ "first_name", "last_name", "email", "password", "conf_password", "type", "regime_type", "dpi_number", "nit_number", "business_type", "registration_qa" ], "type":"object", "properties":{ "first_name":{ "title":"First Name", "maxLength":255, "type":"string" }, "last_name":{ "title":"Last Name", "maxLength":255, "type":"string" }, "email":{ "title":"Email", "maxLength":255, "type":"string" }, "password":{ "title":"Password", "maxLength":20, "type":"string" }, "conf_password":{ "title":"Conf Password", "maxLength":20, "type":"string" }, "type":{ "title":"Type", "enum":[ "individual", "company" ], "type":"enum" }, "regime_type":{ "title":"Regime Type", "enum":[ "small_taxpayer", "optional_simplified", "profit_regime" ], "type":"enum" }, "dpi_number":{ "title":"Dpi Number", "maxLength":255, "type":"string" }, "nit_number":{ "title":"Nit Number", "maxLength":255, "type":"string" }, "business_type":{ "title":"Business Type", "enum":[ "producer", "merchant", "services" ], "type":"enum" }, "registration_qa":{ "title":"Registration Qa", "type":"array", "items":{ "type":"object", "additionalProperties":{ "type":"string" } } } } } } } }

I'm getting

` export interface UserRegisterData { /**

AlekseyP18 commented 1 year ago

@js2me

Can you add please --extract-enums flag to generateApi js method

I can't use CLI api because I need use hooks

dkocich commented 1 year ago

FYI I do not experience issues with enums that we had and we can generate them; I guess it disappeared like 1,5 months ago week or two after upgrading to node 18 and/or npm v9... it might be possible that some strange issue causing this also disappeared from our API doc