import { setFilter , iterableFirst , mapMap , setMap } from "collection-utils" ; import { TypeGraph , TypeRef } from "../TypeGraph" ; import { StringTypeMapping } from "../TypeBuilder" ; import { GraphRewriteBuilder } from "../GraphRewriting" ; import { ObjectType , ClassProperty } from "../Type" ; import { defined } from "../support/Support" ; import { emptyTypeAttributes } from "../attributes/TypeAttributes" ; export function replaceObjectType ( graph , stringTypeMapping , _conflateNumbers , leaveFullObjects , debugPrintReconstitution ) { function replace ( setOfOneType , builder , forwardingRef ) { const o = defined ( iterableFirst ( setOfOneType ) ) ; const attributes = o . getAttributes ( ) ; const properties = o . getProperties ( ) ; const additionalProperties = o . getAdditionalProperties ( ) ; function reconstituteProperties ( ) { return mapMap ( properties , cp => builder . makeClassProperty ( builder . reconstituteTypeRef ( cp . typeRef ) , cp . isOptional ) ) ; } function makeClass ( ) { return builder . getUniqueClassType ( attributes , true , reconstituteProperties ( ) , forwardingRef ) ; } function reconstituteAdditionalProperties ( ) { return builder . reconstituteType ( defined ( additionalProperties ) ) ; } if ( additionalProperties === undefined ) { return makeClass ( ) ; } if ( properties . size === 0 ) { return builder . getMapType ( attributes , reconstituteAdditionalProperties ( ) , forwardingRef ) ; } if ( additionalProperties . kind === "any" ) { builder . setLostTypeAttributes ( ) ; return makeClass ( ) ; } const propertyTypes = setMap ( properties . values ( ) , cp => cp . type ) . add ( additionalProperties ) ; let union = builder . lookupTypeRefs ( Array . from ( propertyTypes ) . map ( t => t . typeRef ) ) ; if ( union === undefined ) { const reconstitutedTypes = setMap ( propertyTypes , t => builder . reconstituteType ( t ) ) ; union = builder . getUniqueUnionType ( emptyTypeAttributes , new Set ( reconstitutedTypes ) ) ; } return builder . getMapType ( attributes , union , forwardingRef ) ; } const allObjectTypes = setFilter ( graph . allTypesUnordered ( ) , t => t . kind === "object" ) as Set < ObjectType > ; const objectTypesToReplace = leaveFullObjects ? setFilter ( allObjectTypes , o => o . getProperties ( ) . size === 0 || o . getAdditionalProperties ( ) === undefined ) : allObjectTypes ; const groups = Array . from ( objectTypesToReplace ) . map ( t => [ t ] ) ; return graph . rewrite ( "replace object type" , stringTypeMapping , false , groups , debugPrintReconstitution , replace ) ; }