import { OpenAPI2 , OpenAPI3 , ReferenceObject } from "./types" ; type CommentObject = { const ? : boolean ; default ? : string ; deprecated ? : boolean ; description ? : string ; enum ? : boolean ; example ? : string ; format ? : string ; nullable ? : boolean ; title ? : string ; type : string ; } ; see { comment } returns export function prepareComment ( v ) { const commentsArray = [ ] ; if ( v . title ) commentsArray . push ( `${ v . title } ` ) ; if ( v . format ) commentsArray . push ( `Format: ${ v . format } ` ) ; if ( v . deprecated ) commentsArray . push ( `@deprecated ` ) ; const supportedJsDocTags = [ "description" , "default" , "example" ] ; for ( let index = 0 ; index < supportedJsDocTags . length ; index ++ ) { const field = supportedJsDocTags [ index ] ; if ( v [ field ] ) commentsArray . push ( `@${ field } ${ v [ field ] } ` ) ; } if ( v . const ) commentsArray . push ( `@constant ` ) ; if ( v . enum ) { const canBeNull = v . nullable ? `|${ null }` : "" ; commentsArray . push ( `@enum {${ v . type }${ canBeNull }}` ) ; } if ( ! commentsArray . length ) return ; return comment ( commentsArray . join ( "\n" ) ) ; } export function comment ( text ) { const commentText = text . trim ( ) . replace ( /\*\//g , "*\\/" ) ; if ( commentText . indexOf ( "\n" ) === - 1 ) { return `/** ${ commentText } */\n` ; } return `/**
  * ${ commentText . replace ( /\r?\n/g , "\n  * " ) }
  */\n` ; } export function parseRef ( ref ) { if ( typeof ref !== "string" || ! ref . includes ( "#" ) ) return { parts : [ ] } ; const [ url , parts ] = ref . split ( "#" ) ; return { url : url || undefined , parts : parts . split ( "/" ) . filter ( ( p ) => ! ! p ) . map ( decodeRef ) , } ; } /** Is this a ReferenceObject? (note: this is just a TypeScript helper for nodeType() below) */ export function isRef ( obj ) { return ! ! obj . $ref ; } export type ParsedSimpleValue = string | number | boolean ; param value param isNodeNullable returns export function parseSingleSimpleValue ( value , isNodeNullable = false ) { if ( typeof value === "string" ) return `'${ value . replace ( /'/g , "\\'" ) }'` ; if ( typeof value === "number" || typeof value === "boolean" ) return value ; if ( value === null && ! isNodeNullable ) return "null" ; return `${ value }` ; } /** Return type of node (works for v2 or v3, as there are no conflicting types) */ type SchemaObjectType = "anyOf" | "array" | "boolean" | "enum" | "number" | "object" | "oneOf" | "ref" | "string" | "const" | "unknown" ; export function nodeType ( obj ) { if ( ! obj || typeof obj !== "object" ) { return "unknown" ; } if ( obj . $ref ) { return "ref" ; } if ( obj . const ) { return "const" ; } if ( Array . isArray ( obj . enum ) && obj . enum . length ) { return "enum" ; } if ( obj . type === "boolean" ) { return "boolean" ; } if ( [ "binary" , "byte" , "date" , "dateTime" , "password" , "string" ] . includes ( obj . type ) ) { return "string" ; } if ( [ "double" , "float" , "integer" , "number" ] . includes ( obj . type ) ) { return "number" ; } if ( obj . type === "array" || obj . items ) { return "array" ; } if ( obj . type === "object" || obj . hasOwnProperty ( "allOf" ) || obj . hasOwnProperty ( "anyOf" ) || obj . hasOwnProperty ( "oneOf" ) || obj . hasOwnProperty ( "properties" ) || obj . hasOwnProperty ( "additionalProperties" ) ) { return "object" ; } return "unknown" ; } /** Return OpenAPI version from definition */ export function swaggerVersion ( definition ) { if ( "openapi" in definition ) { if ( parseInt ( definition . openapi , 10 ) === 3 ) { return 3 ; } } if ( "swagger" in definition ) { if ( typeof definition . swagger === "number" && Math . round ( definition . swagger as number ) === 2 ) { return 2 ; } if ( parseInt ( definition . swagger , 10 ) === 2 ) { return 2 ; } } throw new Error ( `✘  version missing from schema; specify whether this is OpenAPI v3 or v2 https://swagger.io/specification` ) ; } /** Decode $ref (https://swagger.io/docs/specification/using-ref/#escape) */ export function decodeRef ( ref ) { return ref . replace ( /\~0/g , "~" ) . replace ( /\~1/g , "/" ) . replace ( /"/g , '\\"' ) ; } /** Encode $ref (https://swagger.io/docs/specification/using-ref/#escape) */ export function encodeRef ( ref ) { return ref . replace ( /\~/g , "~0" ) . replace ( /\//g , "~1" ) ; } /** Convert T into T[]; */ export function tsArrayOf ( type ) { return `(${ type })[]` ; } /** Convert array of types into [T, A, B, ...] */ export function tsTupleOf ( types ) { return `[${ types . join ( ", " ) }]` ; } /** Convert T, U into T & U; */ export function tsIntersectionOf ( types ) { const typesWithValues = types . filter ( Boolean ) ; if ( ! typesWithValues . length ) return "undefined" ; if ( typesWithValues . length === 1 ) return typesWithValues [ 0 ] ; return `(${ typesWithValues . join ( ") & (" ) })` ; } /** Convert T into Partial<T> */ export function tsPartial ( type ) { return `Partial<${ type }>` ; } export function tsReadonly ( immutable ) { return immutable ? "readonly " : "" ; } /** Convert [X, Y, Z] into X | Y | Z */ export function tsUnionOf ( types ) { if ( ! types . length ) return "undefined" ; if ( types . length === 1 ) return `${ types [ 0 ] }` ; return `(${ types . join ( ") | (" ) })` ; }