{"id":15046024,"url":"https://github.com/himenon/openapi-typescript-code-generator","last_synced_at":"2025-05-15T18:03:57.529Z","repository":{"id":37298314,"uuid":"321679344","full_name":"Himenon/openapi-typescript-code-generator","owner":"Himenon","description":"TypeScript code generator via OpenAPI scheme.","archived":false,"fork":false,"pushed_at":"2024-12-22T03:12:05.000Z","size":3761,"stargazers_count":199,"open_issues_count":5,"forks_count":16,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-15T18:03:52.190Z","etag":null,"topics":["ast","deno","openapi","openapi-codegen","openapi-generator","openapi-typescript","openapi3","swagger","typedefs","typescript","typescript-ast"],"latest_commit_sha":null,"homepage":"https://openapi-typescript-code-generator.netlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Himenon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-15T13:40:09.000Z","updated_at":"2025-03-29T09:49:44.000Z","dependencies_parsed_at":"2024-06-18T15:34:46.399Z","dependency_job_id":"bcfa0a8c-83e5-4853-baa6-90ffea7a2bb5","html_url":"https://github.com/Himenon/openapi-typescript-code-generator","commit_stats":{"total_commits":153,"total_committers":8,"mean_commits":19.125,"dds":0.5490196078431373,"last_synced_commit":"c8fffc939490b34fa53c9684a7737382af48c1f7"},"previous_names":[],"tags_count":88,"template":false,"template_full_name":"Himenon/template-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Himenon%2Fopenapi-typescript-code-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Himenon%2Fopenapi-typescript-code-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Himenon%2Fopenapi-typescript-code-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Himenon%2Fopenapi-typescript-code-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Himenon","download_url":"https://codeload.github.com/Himenon/openapi-typescript-code-generator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254394720,"owners_count":22063984,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","deno","openapi","openapi-codegen","openapi-generator","openapi-typescript","openapi3","swagger","typedefs","typescript","typescript-ast"],"created_at":"2024-09-24T20:52:36.371Z","updated_at":"2025-05-15T18:03:57.509Z","avatar_url":"https://github.com/Himenon.png","language":"TypeScript","readme":"# @himenon/openapi-typescript-code-generator\n\n[日本語](./docs/ja/README-ja.md)\n\nThis library provides TypeScript type definitions and extracted parameters from OpenAPI v3.0.x compliant specifications.\nTypeScript AST is used to generate the code, which is accurately converted to TypeScript code.\nSince the parameters extracted from OpenAPI can be used freely, it can be used for automatic generation of API Client and Server Side code, load balancer configuration files, etc.\n\n## Playground\n\n- [Playground](https://openapi-typescript-code-generator.netlify.app/)\n\n## Installation\n\n```bash\nnpm  i   -D @himenon/openapi-typescript-code-generator\n# or\npnpm i   -D @himenon/openapi-typescript-code-generator\n# or\nyarn add -D @himenon/openapi-typescript-code-generator\n```\n\n## DEMO\n\n- [Short DEMO](https://github.com/Himenon/openapi-typescript-code-generator-demo-project)\n- [DEMO: github/rest-api-client code generate](https://github.com/Himenon/github-rest-api-client/tree/master/source)\n  - https://github.com/github/rest-api-description\n\n## Usage\n\nThe example shown here can be cloned from the [DEMO repository](https://github.com/Himenon/openapi-typescript-code-generator-demo-project) to see how it works.\n\n### Generate typedef-only code\n\n```ts\nimport * as fs from \"fs\";\n\nimport { CodeGenerator } from \"@himenon/openapi-typescript-code-generator\";\n\nconst main = () =\u003e {\n  const codeGenerator = new CodeGenerator(\"your/openapi/spec.yml\");\n  const code = codeGenerator.generateTypeDefinition();\n  fs.writeFileSync(\"client.ts\", code, { encoding: \"utf-8\" });\n};\n\nmain();\n```\n\n### Generate code containing the API Client\n\n```ts\nimport * as fs from \"fs\";\n\nimport { CodeGenerator } from \"@himenon/openapi-typescript-code-generator\";\nimport * as Templates from \"@himenon/openapi-typescript-code-generator/dist/templates\";\nimport type * as Types from \"@himenon/openapi-typescript-code-generator/dist/types\";\n\nconst main = () =\u003e {\n  const codeGenerator = new CodeGenerator(\"your/openapi/spec.yml\");\n\n  const apiClientGeneratorTemplate: Types.CodeGenerator.CustomGenerator\u003cTemplates.FunctionalApiClient.Option\u003e = {\n    generator: Templates.FunctionalApiClient.generator,\n    option: {},\n  };\n\n  const code = codeGenerator.generateTypeDefinition([\n    codeGenerator.getAdditionalTypeDefinitionCustomCodeGenerator(),\n    apiClientGeneratorTemplate,\n  ]);\n\n  fs.writeFileSync(\"client.ts\", code, { encoding: \"utf-8\" });\n};\n\nmain();\n```\n\n### The variation of template code\n\nThis library provides three types of templates\n\n```ts\nimport * as Templates from \"@himenon/openapi-typescript-code-generator/dist/templates\";\n\nTemplates.ClassApiClient.generator;\nTemplates.FunctionalApiClient.generator;\nTemplates.CurryingFunctionalApiClient.generator;\n```\n\n#### `Templates.ClassApiClient.generator`\n\nWe provide a class-based API client. Please inject the API client dependency and use it instead of `constructor`.\n\n```ts\nexport interface RequestArgs {\n  httpMethod: HttpMethod;\n  url: string;\n  headers: ObjectLike | any;\n  requestBody?: ObjectLike | any;\n  requestBodyEncoding?: Record\u003cstring, Encoding\u003e;\n  queryParameters?: QueryParameters | undefined;\n}\n\nexport interface ApiClient\u003cRequestOption\u003e {\n  request: \u003cT = SuccessResponses\u003e(requestArgs: RequestArgs, options?: RequestOption) =\u003e Promise\u003cT\u003e;\n}\n\nexport class Client\u003cRequestOption\u003e {\n  private baseUrl: string;\n  constructor(\n    private apiClient: ApiClient\u003cRequestOption\u003e,\n    baseUrl: string,\n  ) {\n    this.baseUrl = baseUrl.replace(/\\/$/, \"\");\n  }\n\n  public async createPublisherV2\u003cRequestContentType extends RequestContentType$createPublisherV2\u003e(\n    params: Params$createPublisherV2\u003cRequestContentType\u003e,\n    option?: RequestOption,\n  ): Promise\u003cResponse$createPublisherV2$Status$200[\"application/json\"]\u003e {\n    const url = this.baseUrl + `/create/v2/publisher/{id}`;\n    const headers = {\n      \"Content-Type\": params.headers[\"Content-Type\"],\n      Accept: \"application/json\",\n    };\n    const requestEncodings = {\n      \"application/x-www-form-urlencoded\": {\n        color: {\n          style: \"form\",\n          explode: false,\n        },\n      },\n      \"application/json\": {\n        color: {\n          style: \"form\",\n          explode: false,\n        },\n      },\n    };\n    return this.apiClient.request(\n      {\n        httpMethod: \"POST\",\n        url,\n        headers,\n        requestBody: params.requestBody,\n        requestBodyEncoding: requestEncodings[params.headers[\"Content-Type\"]],\n      },\n      option,\n    );\n  }\n}\n```\n\n#### `Templates.FunctionalApiClient.generator`\n\nWe also provide a function-based API client that replaces the class-based API client with `createClient`. Please inject the API client dependency and use it.\n\n```ts\nexport interface RequestArgs {\n  httpMethod: HttpMethod;\n  url: string;\n  headers: ObjectLike | any;\n  requestBody?: ObjectLike | any;\n  requestBodyEncoding?: Record\u003cstring, Encoding\u003e;\n  queryParameters?: QueryParameters | undefined;\n}\n\nexport interface ApiClient\u003cRequestOption\u003e {\n  request: \u003cT = SuccessResponses\u003e(requestArgs: RequestArgs, options?: RequestOption) =\u003e Promise\u003cT\u003e;\n}\n\nexport const createClient = \u003cRequestOption\u003e(apiClient: ApiClient\u003cRequestOption\u003e, baseUrl: string) =\u003e {\n  const _baseUrl = baseUrl.replace(/\\/$/, \"\");\n  return {\n    createPublisherV2: \u003cRequestContentType extends RequestContentType$createPublisherV2\u003e(\n      params: Params$createPublisherV2\u003cRequestContentType\u003e,\n      option?: RequestOption,\n    ): Promise\u003cResponse$createPublisherV2$Status$200[\"application/json\"]\u003e =\u003e {\n      const url = _baseUrl + `/create/v2/publisher/{id}`;\n      const headers = {\n        \"Content-Type\": params.headers[\"Content-Type\"],\n        Accept: \"application/json\",\n      };\n      const requestEncodings = {\n        \"application/x-www-form-urlencoded\": {\n          color: {\n            style: \"form\",\n            explode: false,\n          },\n        },\n        \"application/json\": {\n          color: {\n            style: \"form\",\n            explode: false,\n          },\n        },\n      };\n      return apiClient.request(\n        {\n          httpMethod: \"POST\",\n          url,\n          headers,\n          requestBody: params.requestBody,\n          requestBodyEncoding: requestEncodings[params.headers[\"Content-Type\"]],\n        },\n        option,\n      );\n    },\n  };\n};\n```\n\n#### `Templates.CurryingFunctionalApiClient.generator`\n\n**Tree shaking support**\n\nWe also provide a curried function-based API client that requires injection of API client for each `operationId`. The first function argument demands `ApiClient` while the second function argument demands `RequestArgs`. The `ApiClient` interface is different from the others, as it requires `uri` as an argument.\n\nThis is designed for use cases that utilize **tree shaking**.\n\n```ts\nexport interface RequestArgs {\n  httpMethod: HttpMethod;\n  uri: string; // \u003c------------------ Note that the uri\n  headers: ObjectLike | any;\n  requestBody?: ObjectLike | any;\n  requestBodyEncoding?: Record\u003cstring, Encoding\u003e;\n  queryParameters?: QueryParameters | undefined;\n}\nexport interface ApiClient\u003cRequestOption\u003e {\n  request: \u003cT = SuccessResponses\u003e(requestArgs: RequestArgs, options?: RequestOption) =\u003e Promise\u003cT\u003e;\n}\nexport const createPublisherV2 =\n  \u003cRequestOption\u003e(apiClient: ApiClient\u003cRequestOption\u003e) =\u003e\n  \u003cRequestContentType extends RequestContentType$createPublisherV2\u003e(\n    params: Params$createPublisherV2\u003cRequestContentType\u003e,\n    option?: RequestOption,\n  ): Promise\u003cResponse$createPublisherV2$Status$200[\"application/json\"]\u003e =\u003e {\n    const uri = `/create/v2/publisher/{id}`;\n    const headers = {\n      \"Content-Type\": params.headers[\"Content-Type\"],\n      Accept: \"application/json\",\n    };\n    const requestEncodings = {\n      \"application/x-www-form-urlencoded\": {\n        color: {\n          style: \"form\",\n          explode: false,\n        },\n      },\n      \"application/json\": {\n        color: {\n          style: \"form\",\n          explode: false,\n        },\n      },\n    };\n    return apiClient.request(\n      {\n        httpMethod: \"POST\",\n        uri,\n        headers,\n        requestBody: params.requestBody,\n        requestBodyEncoding: requestEncodings[params.headers[\"Content-Type\"]],\n      },\n      option,\n    );\n  };\n```\n\n### Split the type definition file and the API Client implementation\n\n```ts\nimport * as fs from \"fs\";\n\nimport { CodeGenerator } from \"@himenon/openapi-typescript-code-generator\";\nimport * as Templates from \"@himenon/openapi-typescript-code-generator/dist/templates\";\nimport type * as Types from \"@himenon/openapi-typescript-code-generator/dist/types\";\n\nconst main = () =\u003e {\n  const codeGenerator = new CodeGenerator(\"your/openapi/spec.yml\");\n\n  const apiClientGeneratorTemplate: Types.CodeGenerator.CustomGenerator\u003cTemplates.FunctionalApiClient.Option\u003e = {\n    generator: Templates.FunctionalApiClient.generator,\n    option: {},\n  };\n\n  const typeDefCode = codeGenerator.generateTypeDefinition();\n  const apiClientCode = codeGenerator.generateCode([\n    {\n      generator: () =\u003e {\n        return [`import { Schemas, Responses } from \"./types\";`];\n      },\n    },\n    codeGenerator.getAdditionalTypeDefinitionCustomCodeGenerator(),\n    apiClientGeneratorTemplate,\n  ]);\n\n  fs.writeFileSync(\"types.ts\", typeDefCode, { encoding: \"utf-8\" });\n  fs.writeFileSync(\"apiClient.ts\", apiClientCode, { encoding: \"utf-8\" });\n};\n\nmain();\n```\n\n## Create a Code Template\n\nThe examples in this section can be used in the following ways\n\n```ts\nimport * as fs from \"fs\";\n\nimport { CodeGenerator } from \"@himenon/openapi-typescript-code-generator\";\nimport type * as Types from \"@himenon/openapi-typescript-code-generator/dist/types\";\n\n/** Write the definition of the Code Template here. */\nconst customGenerator: Types.CodeGenerator.CustomGenerator\u003c{}\u003e = {\n  /** .... */\n};\n\nconst codeGenerator = new CodeGenerator(\"your/openapi/spec.yml\");\n\nconst code = codeGenerator.generateCode([customGenerator]);\n\nfs.writeFileSync(\"output/file/name\", code, { encoding: \"utf-8\" });\n```\n\n### Define a text-based code template\n\nA self-defined code generator can return an array of `string`.\n\n```ts\nimport * as Types from \"@himenon/openapi-typescript-code-generator/dist/types\";\n\ninterface Option {\n  showLog?: boolean;\n}\n\nconst generator: Types.CodeGenerator.GenerateFunction\u003cOption\u003e = (payload: Types.CodeGenerator.Params[], option): string[] =\u003e {\n  if (option \u0026\u0026 option.showLog) {\n    console.log(\"show log message\");\n  }\n  return [\"Hello world\"];\n};\n\nconst customGenerator: Types.CodeGenerator.CustomGenerator\u003cOption\u003e = {\n  generator: generator,\n  option: {},\n};\n```\n\n### Define using the information extracted from OpenAPI Schema\n\nThe self-defined code generator can accept parameters extracted from OpenAPI Schema.\nSee Type definitions for available parameters.\n\n```ts\nimport * as Types from \"@himenon/openapi-typescript-code-generator/dist/types\";\n\ninterface Option {}\n\nconst generator: Types.CodeGenerator.GenerateFunction\u003cOption\u003e = (payload: Types.CodeGenerator.Params[], option): string[] =\u003e {\n  return payload.map(params =\u003e {\n    return `function ${params.operationId}() { console.log(\"${params.comment}\") }`;\n  });\n};\n\nconst customGenerator: Types.CodeGenerator.CustomGenerator\u003cOption\u003e = {\n  generator: generator,\n  option: {},\n};\n```\n\n### Define any Data Types Format\n\nConvert a Data Type with the following `format` to any type definition.\n\n```yaml\ncomponents:\n  schemas:\n    Binary:\n      type: string\n      format: binary\n    IntOrString:\n      type: string\n      format: int-or-string\n    AandB:\n      type: string\n      format: A-and-B\n```\n\nThe option to convert the Data Type Format to an arbitrary type definition is defined as follows.\n\n```ts\nimport { CodeGenerator, Option } from \"@himenon/openapi-typescript-code-generator\";\nconst option: Option = {\n  convertOption: {\n    formatConversions: [\n      {\n        selector: {\n          format: \"binary\",\n        },\n        output: {\n          type: [\"Blob\"],\n        },\n      },\n      {\n        selector: {\n          format: \"int-or-string\",\n        },\n        output: {\n          type: [\"number\", \"string\"],\n        },\n      },\n      {\n        selector: {\n          format: \"A-and-B\",\n        },\n        output: {\n          type: [\"A\", \"B\"],\n          multiType: \"allOf\",\n        },\n      },\n    ],\n  },\n};\nconst codeGenerator = new CodeGenerator(inputFilename, option);\n```\n\nThe typedef generated by this will look like this\n\n```ts\nexport namespace Schemas {\n  export type Binary = Blob;\n  export type IntOrString = number | string;\n  export type AandB = A \u0026 B;\n}\n```\n\n### Define a code template with TypeScript AST\n\nYou can extend your code using the API of TypeScript AST.\nYou can directly use the API of TypeScript AST or use the wrapper API of TypeScript AST provided by this library.\n\n```ts\nimport * as Types from \"@himenon/openapi-typescript-code-generator/dist/types\";\nimport { TsGenerator } from \"@himenon/openapi-typescript-code-generator/dist/api\";\n\ninterface Option {}\n\nconst factory = TsGenerator.Factory.create();\n\nconst generator: Types.CodeGenerator.GenerateFunction\u003cOption\u003e = (\n  payload: Types.CodeGenerator.Params[],\n  option,\n): Types.CodeGenerator.IntermediateCode[] =\u003e {\n  return payload.map(params =\u003e {\n    return factory.InterfaceDeclaration.create({\n      export: true,\n      name: params.functionName,\n      members: [],\n    });\n  });\n};\n\nconst customGenerator: Types.CodeGenerator.CustomGenerator\u003cOption\u003e = {\n  generator: generator,\n  option: {},\n};\n```\n\n## API\n\n### CodeGenerator\n\n```ts\nimport { CodeGenerator } from \"@himenon/openapi-typescript-code-generator\";\n```\n\n#### validateOpenApiSchema\n\nPerforms validation of the input OpenAPI Schema.\n\n#### generateTypeDefinition\n\nGenerates code that converts OpenAPI Schema to TypeScript type definitions.\n\n#### generateCode\n\nYou can specify several of your own code generators, and the generators can use parameters extracted from OpenAPI Schema.\nIt internally performs the conversion of an array of `string` or `ts.Statement` as a string.\n\nFor example, creating a generator in units of file divisions increases the reusability of the generator.\n\n#### getCodeGeneratorParamsArray\n\nIt provides parameters extracted from OpenAPI Schema.\n\n#### getAdditionalTypeDefinitionCustomCodeGenerator\n\nThis is a type definition file for `Templates.FunctionalApiClient`. The reason it is not included in `generateTypeDefinition` is that you may not use the type definition generated by this function depending on your usage.\n\n※ The reason it is not included in `generateTypeDefinition` is that you may not use the type definitions generated by this function depending on your application.\n\n### TsGenerator\n\n```ts\nimport { TsGenerator } from \"@himenon/openapi-typescript-code-generator/dist/api\";\n```\n\nThis is a wrapper API for the TypeScript AST used internally.\nIt is subject to change without notice.\n\n### OpenApiTools\n\n```ts\nimport { OpenApiTools } from \"@himenon/openapi-typescript-code-generator/dist/api\";\n```\n\n#### Parser\n\n- `OpenApiTools.Parser`\n\nThis is the API for parsing OpenAPI Schema.\nIt is subject to change without notice.\n\n## Restrictions\n\n### Directory Restrictions for Remote Reference\n\nThere is a limitation on the directory structure supported.\nTo simplify implementation when converting directory structures to TypeScript namespaces, Remote References using `$ref` should only be defined in the following directory structures.\nIf you want to extend it, please fork this repository and do it yourself.\n\n```\nspec.yml // entry file\ncomponents/\n  headers/\n  parameters/\n  pathItems/\n  requestBodies/\n  responses/\n  schemas/\n  paths/\n```\n\n### HTTP communication restrictions for Remote Reference\n\n`$ref: http://....` Currently not supported. We hope to support it in the future.\n\n## Contributions\n\nFirst of all, thank you for your interest.\nWhen converting from the API specification to TypeScript code, resolving reference relationships can be particularly challenging, and there may not be enough test cases.\nAdding test cases is a very powerful support for stabilizing the behavior, so please report any bugs you find that are behaving strangely.\nAlso, the basic design concepts of this repository can be found below. If you want to make changes that do not follow these concepts, please fork and extend them.\nIf your changes are in line with the design concept, please submit a pull request or issue!\n\n## Design Concept\n\n- Be typedef first.\n- Typedefs should not contain any entities (file size should be 0 when typedefs are converted to `.js`)\n- The directory structure should be mapped to the typedef structure.\n- No dependency on any API client library.\n- Can be extended by TypeScript AST.\n- Conform to the OpenAPI specification.\n- It should be a single file to maintain portability.\n\n## Development\n\n```bash\ngit clone https://github.com/Himenon/openapi-typescript-code-generator.git\ncd openapi-typescript-code-generator\npnpm i\n#### your change\npnpm build\npnpm run test:code:gen\npnpm run update:snapshot # if you changed\npnpm run test\n```\n\n## Useful development tools\n\nTypeScript AST\n\n- https://ts-ast-viewer.com\n\n## LICENCE\n\n[@himenon/openapi-typescript-code-generator](https://github.com/Himenon/typescript-codegen), MIT\n\n### Reference implementation\n\nValidation Design\n\n- Copyright (c) 2018 Kogo Software LLC - [https://github.com/kogosoftwarellc/open-api/tree/master/packages/openapi-schema-validator#readme](openapi-schema-validator)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhimenon%2Fopenapi-typescript-code-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhimenon%2Fopenapi-typescript-code-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhimenon%2Fopenapi-typescript-code-generator/lists"}