Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

TypeScript code generator via OpenAPI scheme.

License

NotificationsYou must be signed in to change notification settings

Himenon/openapi-typescript-code-generator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

日本語

This library provides TypeScript type definitions and extracted parameters from OpenAPI v3.0.x compliant specifications.TypeScript AST is used to generate the code, which is accurately converted to TypeScript code.Since 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.

Playground

Installation

npm  i   -D @himenon/openapi-typescript-code-generator# orpnpm i   -D @himenon/openapi-typescript-code-generator# oryarn add -D @himenon/openapi-typescript-code-generator

DEMO

Usage

The example shown here can be cloned from theDEMO repository to see how it works.

Generate typedef-only code

import*asfsfrom"fs";import{CodeGenerator}from"@himenon/openapi-typescript-code-generator";constmain=()=>{constcodeGenerator=newCodeGenerator("your/openapi/spec.yml");constcode=codeGenerator.generateTypeDefinition();fs.writeFileSync("client.ts",code,{encoding:"utf-8"});};main();

Generate code containing the API Client

import*asfsfrom"fs";import{CodeGenerator}from"@himenon/openapi-typescript-code-generator";import*asTemplatesfrom"@himenon/openapi-typescript-code-generator/dist/templates";importtype*asTypesfrom"@himenon/openapi-typescript-code-generator/dist/types";constmain=()=>{constcodeGenerator=newCodeGenerator("your/openapi/spec.yml");constapiClientGeneratorTemplate:Types.CodeGenerator.CustomGenerator<Templates.FunctionalApiClient.Option>={generator:Templates.FunctionalApiClient.generator,option:{},};constcode=codeGenerator.generateTypeDefinition([codeGenerator.getAdditionalTypeDefinitionCustomCodeGenerator(),apiClientGeneratorTemplate,]);fs.writeFileSync("client.ts",code,{encoding:"utf-8"});};main();

The variation of template code

This library provides three types of templates

import*asTemplatesfrom"@himenon/openapi-typescript-code-generator/dist/templates";Templates.ClassApiClient.generator;Templates.FunctionalApiClient.generator;Templates.CurryingFunctionalApiClient.generator;

Templates.ClassApiClient.generator

We provide a class-based API client. Please inject the API client dependency and use it instead ofconstructor.

exportinterfaceRequestArgs{httpMethod:HttpMethod;url:string;headers:ObjectLike|any;requestBody?:ObjectLike|any;requestBodyEncoding?:Record<string,Encoding>;queryParameters?:QueryParameters|undefined;}exportinterfaceApiClient<RequestOption>{request:<T=SuccessResponses>(requestArgs:RequestArgs,options?:RequestOption)=>Promise<T>;}exportclassClient<RequestOption>{privatebaseUrl:string;constructor(privateapiClient:ApiClient<RequestOption>,baseUrl:string,){this.baseUrl=baseUrl.replace(/\/$/,"");}publicasynccreatePublisherV2<RequestContentTypeextendsRequestContentType$createPublisherV2>(params:Params$createPublisherV2<RequestContentType>,option?:RequestOption,):Promise<Response$createPublisherV2$Status$200["application/json"]>{consturl=this.baseUrl+`/create/v2/publisher/{id}`;constheaders={"Content-Type":params.headers["Content-Type"],Accept:"application/json",};constrequestEncodings={"application/x-www-form-urlencoded":{color:{style:"form",explode:false,},},"application/json":{color:{style:"form",explode:false,},},};returnthis.apiClient.request({httpMethod:"POST",        url,        headers,requestBody:params.requestBody,requestBodyEncoding:requestEncodings[params.headers["Content-Type"]],},option,);}}

Templates.FunctionalApiClient.generator

We also provide a function-based API client that replaces the class-based API client withcreateClient. Please inject the API client dependency and use it.

exportinterfaceRequestArgs{httpMethod:HttpMethod;url:string;headers:ObjectLike|any;requestBody?:ObjectLike|any;requestBodyEncoding?:Record<string,Encoding>;queryParameters?:QueryParameters|undefined;}exportinterfaceApiClient<RequestOption>{request:<T=SuccessResponses>(requestArgs:RequestArgs,options?:RequestOption)=>Promise<T>;}exportconstcreateClient=<RequestOption>(apiClient:ApiClient<RequestOption>,baseUrl:string)=>{const_baseUrl=baseUrl.replace(/\/$/,"");return{createPublisherV2:<RequestContentTypeextendsRequestContentType$createPublisherV2>(params:Params$createPublisherV2<RequestContentType>,option?:RequestOption,):Promise<Response$createPublisherV2$Status$200["application/json"]>=>{consturl=_baseUrl+`/create/v2/publisher/{id}`;constheaders={"Content-Type":params.headers["Content-Type"],Accept:"application/json",};constrequestEncodings={"application/x-www-form-urlencoded":{color:{style:"form",explode:false,},},"application/json":{color:{style:"form",explode:false,},},};returnapiClient.request({httpMethod:"POST",          url,          headers,requestBody:params.requestBody,requestBodyEncoding:requestEncodings[params.headers["Content-Type"]],},option,);},};};

Templates.CurryingFunctionalApiClient.generator

Tree shaking support

We also provide a curried function-based API client that requires injection of API client for eachoperationId. The first function argument demandsApiClient while the second function argument demandsRequestArgs. TheApiClient interface is different from the others, as it requiresuri as an argument.

This is designed for use cases that utilizetree shaking.

exportinterfaceRequestArgs{httpMethod:HttpMethod;uri:string;// <------------------ Note that the uriheaders:ObjectLike|any;requestBody?:ObjectLike|any;requestBodyEncoding?:Record<string,Encoding>;queryParameters?:QueryParameters|undefined;}exportinterfaceApiClient<RequestOption>{request:<T=SuccessResponses>(requestArgs:RequestArgs,options?:RequestOption)=>Promise<T>;}exportconstcreatePublisherV2=<RequestOption>(apiClient:ApiClient<RequestOption>)=><RequestContentTypeextendsRequestContentType$createPublisherV2>(params:Params$createPublisherV2<RequestContentType>,option?:RequestOption,):Promise<Response$createPublisherV2$Status$200["application/json"]>=>{consturi=`/create/v2/publisher/{id}`;constheaders={"Content-Type":params.headers["Content-Type"],Accept:"application/json",};constrequestEncodings={"application/x-www-form-urlencoded":{color:{style:"form",explode:false,},},"application/json":{color:{style:"form",explode:false,},},};returnapiClient.request({httpMethod:"POST",        uri,        headers,requestBody:params.requestBody,requestBodyEncoding:requestEncodings[params.headers["Content-Type"]],},option,);};

Split the type definition file and the API Client implementation

import*asfsfrom"fs";import{CodeGenerator}from"@himenon/openapi-typescript-code-generator";import*asTemplatesfrom"@himenon/openapi-typescript-code-generator/dist/templates";importtype*asTypesfrom"@himenon/openapi-typescript-code-generator/dist/types";constmain=()=>{constcodeGenerator=newCodeGenerator("your/openapi/spec.yml");constapiClientGeneratorTemplate:Types.CodeGenerator.CustomGenerator<Templates.FunctionalApiClient.Option>={generator:Templates.FunctionalApiClient.generator,option:{},};consttypeDefCode=codeGenerator.generateTypeDefinition();constapiClientCode=codeGenerator.generateCode([{generator:()=>{return[`import { Schemas, Responses } from "./types";`];},},codeGenerator.getAdditionalTypeDefinitionCustomCodeGenerator(),apiClientGeneratorTemplate,]);fs.writeFileSync("types.ts",typeDefCode,{encoding:"utf-8"});fs.writeFileSync("apiClient.ts",apiClientCode,{encoding:"utf-8"});};main();

Create a Code Template

The examples in this section can be used in the following ways

import*asfsfrom"fs";import{CodeGenerator}from"@himenon/openapi-typescript-code-generator";importtype*asTypesfrom"@himenon/openapi-typescript-code-generator/dist/types";/** Write the definition of the Code Template here. */constcustomGenerator:Types.CodeGenerator.CustomGenerator<{}>={/** .... */};constcodeGenerator=newCodeGenerator("your/openapi/spec.yml");constcode=codeGenerator.generateCode([customGenerator]);fs.writeFileSync("output/file/name",code,{encoding:"utf-8"});

Define a text-based code template

A self-defined code generator can return an array ofstring.

import*asTypesfrom"@himenon/openapi-typescript-code-generator/dist/types";interfaceOption{showLog?:boolean;}constgenerator:Types.CodeGenerator.GenerateFunction<Option>=(payload:Types.CodeGenerator.Params[],option):string[]=>{if(option&&option.showLog){console.log("show log message");}return["Hello world"];};constcustomGenerator:Types.CodeGenerator.CustomGenerator<Option>={generator:generator,option:{},};

Define using the information extracted from OpenAPI Schema

The self-defined code generator can accept parameters extracted from OpenAPI Schema.See Type definitions for available parameters.

import*asTypesfrom"@himenon/openapi-typescript-code-generator/dist/types";interfaceOption{}constgenerator:Types.CodeGenerator.GenerateFunction<Option>=(payload:Types.CodeGenerator.Params[],option):string[]=>{returnpayload.map(params=>{return`function${params.operationId}() { console.log("${params.comment}") }`;});};constcustomGenerator:Types.CodeGenerator.CustomGenerator<Option>={generator:generator,option:{},};

Define any Data Types Format

Convert a Data Type with the followingformat to any type definition.

components:schemas:Binary:type:stringformat:binaryIntOrString:type:stringformat:int-or-stringAandB:type:stringformat:A-and-B

The option to convert the Data Type Format to an arbitrary type definition is defined as follows.

import{CodeGenerator,Option}from"@himenon/openapi-typescript-code-generator";constoption:Option={convertOption:{formatConversions:[{selector:{format:"binary",},output:{type:["Blob"],},},{selector:{format:"int-or-string",},output:{type:["number","string"],},},{selector:{format:"A-and-B",},output:{type:["A","B"],multiType:"allOf",},},],},};constcodeGenerator=newCodeGenerator(inputFilename,option);

The typedef generated by this will look like this

exportnamespaceSchemas{exporttypeBinary=Blob;exporttypeIntOrString=number|string;exporttypeAandB=A&B;}

Define a code template with TypeScript AST

You can extend your code using the API of TypeScript AST.You can directly use the API of TypeScript AST or use the wrapper API of TypeScript AST provided by this library.

import*asTypesfrom"@himenon/openapi-typescript-code-generator/dist/types";import{TsGenerator}from"@himenon/openapi-typescript-code-generator/dist/api";interfaceOption{}constfactory=TsGenerator.Factory.create();constgenerator:Types.CodeGenerator.GenerateFunction<Option>=(payload:Types.CodeGenerator.Params[],option,):Types.CodeGenerator.IntermediateCode[]=>{returnpayload.map(params=>{returnfactory.InterfaceDeclaration.create({export:true,name:params.functionName,members:[],});});};constcustomGenerator:Types.CodeGenerator.CustomGenerator<Option>={generator:generator,option:{},};

API

CodeGenerator

import{CodeGenerator}from"@himenon/openapi-typescript-code-generator";

validateOpenApiSchema

Performs validation of the input OpenAPI Schema.

generateTypeDefinition

Generates code that converts OpenAPI Schema to TypeScript type definitions.

generateCode

You can specify several of your own code generators, and the generators can use parameters extracted from OpenAPI Schema.It internally performs the conversion of an array ofstring orts.Statement as a string.

For example, creating a generator in units of file divisions increases the reusability of the generator.

getCodeGeneratorParamsArray

It provides parameters extracted from OpenAPI Schema.

getAdditionalTypeDefinitionCustomCodeGenerator

This is a type definition file forTemplates.FunctionalApiClient. The reason it is not included ingenerateTypeDefinition is that you may not use the type definition generated by this function depending on your usage.

※ The reason it is not included ingenerateTypeDefinition is that you may not use the type definitions generated by this function depending on your application.

TsGenerator

import{TsGenerator}from"@himenon/openapi-typescript-code-generator/dist/api";

This is a wrapper API for the TypeScript AST used internally.It is subject to change without notice.

OpenApiTools

import{OpenApiTools}from"@himenon/openapi-typescript-code-generator/dist/api";

Parser

  • OpenApiTools.Parser

This is the API for parsing OpenAPI Schema.It is subject to change without notice.

Restrictions

Directory Restrictions for Remote Reference

There is a limitation on the directory structure supported.To simplify implementation when converting directory structures to TypeScript namespaces, Remote References using$ref should only be defined in the following directory structures.If you want to extend it, please fork this repository and do it yourself.

spec.yml // entry filecomponents/  headers/  parameters/  pathItems/  requestBodies/  responses/  schemas/  paths/

HTTP communication restrictions for Remote Reference

$ref: http://.... Currently not supported. We hope to support it in the future.

Contributions

First of all, thank you for your interest.When converting from the API specification to TypeScript code, resolving reference relationships can be particularly challenging, and there may not be enough test cases.Adding test cases is a very powerful support for stabilizing the behavior, so please report any bugs you find that are behaving strangely.Also, 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.If your changes are in line with the design concept, please submit a pull request or issue!

Design Concept

  • Be typedef first.
  • Typedefs should not contain any entities (file size should be 0 when typedefs are converted to.js)
  • The directory structure should be mapped to the typedef structure.
  • No dependency on any API client library.
  • Can be extended by TypeScript AST.
  • Conform to the OpenAPI specification.
  • It should be a single file to maintain portability.

Development

git clone https://github.com/Himenon/openapi-typescript-code-generator.gitcd openapi-typescript-code-generatorpnpm i#### your changepnpm buildpnpm run test:code:genpnpm run update:snapshot# if you changedpnpm runtest

Useful development tools

TypeScript AST

LICENCE

@himenon/openapi-typescript-code-generator, MIT

Reference implementation

Validation Design


[8]ページ先頭

©2009-2025 Movatter.jp