import ts , { skipPartiallyEmittedExpressions } from "typescript" ; import type { OpenApi } from "../../../types" ; import { FeatureDevelopmentError } from "../../Exception" ; import { Factory } from "../../TsGenerator" ; import * as ConvertContext from "../ConverterContext" ; import * as Guard from "../Guard" ; import * as ToTypeNode from "../toTypeNode" ; import type { AnySchema , ArraySchema , ObjectSchema , PrimitiveSchema } from "../types" ; import type * as Walker from "../Walker" ; import * as ExternalDocumentation from "./ExternalDocumentation" ; export const generatePropertySignatures = ( entryPoint , currentPoint , factory , schema , context , convertContext ) : ts . PropertySignature [ ] => { if ( ! schema . properties ) { return [ ] ; } const required = schema . required || [ ] ; return Object . entries ( schema . properties ) . map ( ( [ propertyName , property ] ) => { if ( ! property ) { return factory . PropertySignature . create ( { name : convertContext . escapePropertySignatureName ( propertyName ) , optional : ! required . includes ( propertyName ) , comment : schema . description , type : factory . TypeNode . create ( { type : "any" , } ) , } ) ; } return factory . PropertySignature . create ( { name : convertContext . escapePropertySignatureName ( propertyName ) , optional : ! required . includes ( propertyName ) , type : ToTypeNode . convert ( entryPoint , currentPoint , factory , property , context , convertContext , { parent : schema } ) , comment : typeof property !== "boolean" ? property . description : undefined , } ) ; } ) ; } ; export const generateInterface = ( entryPoint , currentPoint , factory , name , schema , context , convertContext ) : ts . InterfaceDeclaration => { if ( schema . type !== "object" ) { throw new FeatureDevelopmentError ( "Please use generateTypeAlias" ) ; } let members = [ ] ; const propertySignatures = generatePropertySignatures ( entryPoint , currentPoint , factory , schema , context , convertContext ) ; if ( Guard . isObjectSchemaWithAdditionalProperties ( schema ) ) { const additionalProperties = ToTypeNode . convertAdditionalProperties ( entryPoint , currentPoint , factory , schema , context , convertContext ) ; if ( schema . additionalProperties === true ) { members = members . concat ( additionalProperties ) ; } else { members = [ ... propertySignatures , additionalProperties ] ; } } else { members = propertySignatures ; } return factory . InterfaceDeclaration . create ( { export : true , name : convertContext . escapeDeclarationText ( name ) , members , comment : ExternalDocumentation . addComment ( schema . description , schema . externalDocs ) , } ) ; } ; export const generateArrayTypeAlias = ( entryPoint , currentPoint , factory , name , schema , context , convertContext ) : ts . TypeAliasDeclaration => { return factory . TypeAliasDeclaration . create ( { export : true , name : convertContext . escapeDeclarationText ( name ) , comment : schema . description , type : ToTypeNode . convert ( entryPoint , currentPoint , factory , schema , context , convertContext ) , } ) ; } ; const createNullableTypeNodeOrAny = ( factory , schema ) => { const typeNode = factory . TypeNode . create ( { type : "any" , } ) ; if ( ! schema . type && typeof schema . nullable === "boolean" ) { return factory . TypeNode . create ( { type : "null" , } ) ; } return typeNode ; } ; /**
 * 型定義が特定できなかった場合に利用する
 */ export const generateNotInferedTypeAlias = ( entryPoint , currentPoint , factory , name , schema , convertContext ) => { const typeNode = createNullableTypeNodeOrAny ( factory , schema ) ; return factory . TypeAliasDeclaration . create ( { export : true , name : convertContext . escapeDeclarationText ( name ) , type : typeNode , comment : schema . description , } ) ; } ; export const generateTypeAlias = ( entryPoint , currentPoint , factory , name , schema , convertContext ) : ts . TypeAliasDeclaration => { let type ; let formatTypeNode ; if ( schema . format && schema . type !== "any" ) { formatTypeNode = convertContext . convertFormatTypeNode ( schema ) ; } if ( formatTypeNode ) { type = formatTypeNode ; } else if ( schema . enum ) { if ( Guard . isNumberArray ( schema . enum ) && ( schema . type === "number" || schema . type === "integer" ) ) { type = factory . TypeNode . create ( { type : schema . type , enum : schema . enum , } ) ; } else if ( Guard . isStringArray ( schema . enum ) && schema . type === "string" ) { type = factory . TypeNode . create ( { type : schema . type , enum : schema . enum , } ) ; } else { type = factory . TypeNode . create ( { type : schema . type , } ) ; } } else { type = factory . TypeNode . create ( { type : schema . type , } ) ; } return factory . TypeAliasDeclaration . create ( { export : true , name : convertContext . escapeDeclarationText ( name ) , type , comment : schema . description , } ) ; } ; export const generateMultiTypeAlias = ( entryPoint , currentPoint , factory , name , schemas , context , multiType , convertContext ) : ts . TypeAliasDeclaration => { const type = ToTypeNode . generateMultiTypeNode ( entryPoint , currentPoint , factory , schemas , context , ToTypeNode . convert , convertContext , multiType ) ; return factory . TypeAliasDeclaration . create ( { export : true , name : convertContext . escapeDeclarationText ( name ) , type , } ) ; } ; export const addSchema = ( entryPoint , currentPoint , store , factory , targetPoint , declarationName , schema , context , convertContext ) : void => { if ( ! schema ) { return ; } if ( Guard . isAllOfSchema ( schema ) ) { store . addStatement ( targetPoint , { kind : "typeAlias" , name : convertContext . escapeDeclarationText ( declarationName ) , value : generateMultiTypeAlias ( entryPoint , currentPoint , factory , declarationName , schema . allOf , context , "allOf" , convertContext ) , } ) ; } else if ( Guard . isOneOfSchema ( schema ) ) { store . addStatement ( targetPoint , { kind : "typeAlias" , name : convertContext . escapeDeclarationText ( declarationName ) , value : generateMultiTypeAlias ( entryPoint , currentPoint , factory , declarationName , schema . oneOf , context , "oneOf" , convertContext ) , } ) ; } else if ( Guard . isAnyOfSchema ( schema ) ) { store . addStatement ( targetPoint , { kind : "typeAlias" , name : convertContext . escapeDeclarationText ( declarationName ) , value : generateMultiTypeAlias ( entryPoint , currentPoint , factory , declarationName , schema . anyOf , context , "allOf" , convertContext ) , } ) ; } else if ( Guard . isArraySchema ( schema ) ) { store . addStatement ( targetPoint , { kind : "typeAlias" , name : convertContext . escapeDeclarationText ( declarationName ) , value : generateArrayTypeAlias ( entryPoint , currentPoint , factory , declarationName , schema , context , convertContext ) , } ) ; } else if ( Guard . isObjectSchema ( schema ) ) { store . addStatement ( targetPoint , { kind : "interface" , name : convertContext . escapeDeclarationText ( declarationName ) , value : generateInterface ( entryPoint , currentPoint , factory , declarationName , schema , context , convertContext ) , } ) ; } else if ( Guard . isPrimitiveSchema ( schema ) ) { store . addStatement ( targetPoint , { kind : "typeAlias" , name : convertContext . escapeDeclarationText ( declarationName ) , value : generateTypeAlias ( entryPoint , currentPoint , factory , declarationName , schema , convertContext ) , } ) ; } } ;