import getAvailablePort from 'get-port' ; import got from 'got' ; import http from 'http' ; import onExit from 'signal-exit' ; import url from 'url' ; import { AsyncReturnType } from 'vtils/types' ; import { isEmpty } from 'vtils' ; import { swaggerJsonToYApiData } from './swaggerJsonToYApiData' ; import { OpenAPIV2 as SwaggerType } from 'openapi-types' ; export interface SwaggerToYApiServerOptions { swaggerJsonUrl : string ; } export class SwaggerToYApiServer { private port = 0 ; private swaggerJson : SwaggerType . Document = { } as any ; private httpServer : http . Server | null = null ; private yapiData : AsyncReturnType < typeof swaggerJsonToYApiData > = { } as any ; constructor ( private readonly options ) { } async getPort ( ) { if ( this . port === 0 ) { this . port = await getAvailablePort ( { port : 50505 , } ) ; } return this . port ; } async getUrl ( ) { return `http://127.0.0.1:${ await this . getPort ( ) }` ; } async getSwaggerJson ( ) { if ( isEmpty ( this . swaggerJson ) ) { const res = await got . get < SwaggerType . Document > ( this . options . swaggerJsonUrl , { responseType : 'json' , } ) ; this . swaggerJson = res . body ; } return this . swaggerJson ; } async getYApiData ( ) { if ( isEmpty ( this . yapiData ) ) { this . yapiData = await swaggerJsonToYApiData ( await this . getSwaggerJson ( ) ) ; } return this . yapiData ; } async start ( ) { const yapiData = await this . getYApiData ( ) ; await new Promise < void > ( async ( resolve ) => { this . httpServer = http . createServer ( async ( req , res ) => { const { pathname } = url . parse ( req . url || '' ) ; res . setHeader ( 'Content-Type' , 'application/json' ) ; if ( pathname ! . includes ( '/api/plugin/export' ) ) { res . end ( JSON . stringify ( yapiData . cats . map ( cat => ( { ... cat , list : yapiData . interfaces . filter ( item => item . catid === cat . _id ) , } ) ) ) ) ; } else if ( pathname ! . includes ( '/api/interface/getCatMenu' ) ) { res . end ( JSON . stringify ( { errcode : 0 , errmsg : '成功！' , data : yapiData . cats , } ) ) ; } else if ( pathname ! . includes ( '/api/project/get' ) ) { res . end ( JSON . stringify ( { errcode : 0 , errmsg : '成功！' , data : yapiData . project , } ) ) ; } res . end ( '404' ) ; } ) . listen ( await this . getPort ( ) , '127.0.0.1' , ( ) => { onExit ( ( ) => this . stop ( ) ) ; resolve ( ) ; } ) ; } ) ; return this . getUrl ( ) ; } async stop ( ) { return new Promise ( ( resolve , reject ) => { if ( ! this . httpServer ) { resolve ( ) ; } else { this . httpServer . close ( err => { if ( err ) { reject ( err ) ; } else { resolve ( ) ; } } ) ; } } ) ; } }