import { CodeModel , HttpHeader , Operation , Response , SchemaContext , SchemaResponse } from "@autorest/codemodel" ; import { getResponseTypeName , getStatusCode , responseToSchemaResponse } from "./operationHelpers" ; import { InterfaceDeclarationStructure , OptionalKind , Project , PropertySignatureStructure , StructureKind } from "ts-morph" ; import { NameType , normalizeName } from "../utils/nameUtils" ; import { getElementType , getFormatDocs , primitiveSchemaToType } from "./schemaHelpers" ; import { getLanguageMetadata } from "../utils/languageHelpers" ; import { hasOutputModels } from "./helpers/modelHelpers" ; import { getAutorestOptions } from "../autorestSession" ; import * as path from 'path' ; export function generateResponseInterfaces ( model , project ) { const { srcPath } = getAutorestOptions ( ) ; const responsesFile = project . createSourceFile ( path . join ( srcPath , `responses.ts` ) , undefined , { overwrite : true } ) ; let importedModels = new Set < string > ( ) ; const operations = getAllOperationRequests ( model ) ; let hasHeaders = false ; for ( const operation of operations ) { const responses = mergeResponsesAndExceptions ( operation ) ; for ( const response of responses ) { if ( ! response . protocol . http ) { continue ; } let schemaResponse = responseToSchemaResponse ( response ) ; const statusCode = getStatusCode ( schemaResponse ) ; const operationLanguageMetadata = getLanguageMetadata ( operation . language ) ; const baseResponseName = normalizeName ( `${ operationLanguageMetadata . name }${ statusCode }` , NameType . Interface ) ; const headersInterface = getResponseHeaderInterfaceDefinition ( schemaResponse , baseResponseName ) ; if ( headersInterface ) { hasHeaders = true ; responsesFile . addInterface ( headersInterface ) ; } const bodyType = getBodyTypeName ( schemaResponse , importedModels ) ; const bodyDescription = getFormatDocs ( schemaResponse . schema ) ; const responseTypeName = getResponseTypeName ( operation , schemaResponse ) ; const responseTypeDescription = operationLanguageMetadata . description ; const responseProperties = getResponseInterfaceProperties ( schemaResponse , bodyType , headersInterface ?. name , bodyDescription ) ; const responseInterfaceDefinition = { name : responseTypeName , properties : responseProperties , isExported : true , extends : [ "HttpResponse" ] } ; if ( responseTypeDescription ) { responseInterfaceDefinition . docs = [ { description : responseTypeDescription } ] ; } responsesFile . addInterface ( responseInterfaceDefinition ) ; } } if ( hasHeaders ) { responsesFile . addImportDeclarations ( [ { namedImports : [ "RawHttpHeaders" ] , moduleSpecifier : "@azure/core-rest-pipeline" } ] ) ; } responsesFile . addImportDeclarations ( [ { namedImports : [ "HttpResponse" ] , moduleSpecifier : "@azure-rest/core-client" } ] ) ; if ( hasOutputModels ( model ) ) { responsesFile . addImportDeclarations ( [ { namedImports : [ ... importedModels ] , moduleSpecifier : "./outputModels" } ] ) ; } } /**
 * Gets the properties that need to be part of the response interface
 */ function getResponseInterfaceProperties ( response , bodyTypeName ? , headersInterfaceName ? , bodyDescription ? ) { const statusCode = getStatusCode ( response ) ; const responseProperties = [ { name : "status" , type : statusCode === `"default"` ? `"500"` : statusCode , kind : StructureKind . PropertySignature } ] ; if ( bodyTypeName ) { responseProperties . push ( { name : "body" , type : bodyTypeName , kind : StructureKind . PropertySignature , ... ( bodyDescription && { docs : [ { description : bodyDescription } ] } ) } ) ; } if ( headersInterfaceName ) { responseProperties . push ( { name : "headers" , type : `RawHttpHeaders & ${ headersInterfaceName }` , kind : StructureKind . PropertySignature } ) ; } return responseProperties ; } param response param importedModels function getBodyTypeName ( response , importedModels ) { return getElementType ( response . schema , [ SchemaContext . Output , SchemaContext . Exception ] , importedModels ) ; } function getResponseHeaderInterfaceDefinition ( response , baseName ) { const hasDefinedHeaders = Boolean ( response . protocol . http ?. headers ) && Boolean ( response . protocol . http ?. headers . length ) ; if ( hasDefinedHeaders ) { const headersInterfaceName = `${ baseName }Headers` ; return { kind : StructureKind . Interface , isExported : true , name : headersInterfaceName , properties : response . protocol . http ?. headers . map ( ( h ) => { const description = getLanguageMetadata ( h . language ) . description ; return { name : `"${ h . header . toLowerCase ( ) }"` , ... ( description && { docs : [ { description } ] } ) , type : primitiveSchemaToType ( h . schema , [ SchemaContext . Output , SchemaContext . Exception ] ) , hasQuestionToken : true } ; } ) } ; } return undefined ; } function getAllOperationRequests ( model ) { let operations = [ ] ; model . operationGroups . forEach ( og => og . operations . filter ( o => o . requests && o . requests . length ) . forEach ( o => { operations . push ( o ) ; } ) ) ; return operations ; } function mergeResponsesAndExceptions ( operation ) { const responses = [ ] ; if ( operation . responses ) { responses . push ( ... operation . responses ) ; } if ( operation . exceptions ) { responses . push ( ... operation . exceptions ) ; } return responses ; }