import { Operation , SchemaResponse , SchemaType , ObjectSchema , CodeModel } from "@autorest/codemodel" ; import { isEqual } from "lodash" ; import { PaginationDetails } from "../models/operationDetails" ; import { getLanguageMetadata , PaginationExtension } from "./languageHelpers" ; import { getTypeForSchema , isSchemaResponse } from "./schemaHelpers" ; import { TypeDetails } from "../models/modelDetails" ; param operation export function extractPaginationDetails ( operation ) { const languageMetadata = getLanguageMetadata ( operation . language ) ; const paginationExtension = languageMetadata . paging ; if ( ! paginationExtension ) { return ; } paginationExtension . itemName = paginationExtension . itemName || "value" ; const nextLinkName = typeof paginationExtension . nextLinkName === "string" ? paginationExtension . nextLinkName : null ; let nextLinkOperationName = "" ; if ( paginationExtension . nextLinkOperation ) { nextLinkOperationName = getLanguageMetadata ( paginationExtension . nextLinkOperation . language ) . name ; } if ( ! nextLinkOperationName && nextLinkName ) { nextLinkOperationName = `${ languageMetadata . name }Next` ; } let itemName = getItemName ( paginationExtension , operation ) ; return { group : paginationExtension . group , member : paginationExtension . member , nextLinkName , itemName , itemTypes : getItemTypes ( operation , itemName ) , nextLinkOperationName , isNextLinkMethod : Boolean ( paginationExtension . isNextLinkMethod ) } ; } function getItemName ( paginationExtension , operation ) { let itemName = paginationExtension . itemName ?? "value" ; for ( const response of operation . responses || [ ] ) { if ( isSchemaResponse ( response ) ) { const valuesProperty = ( response . schema as ObjectSchema ) . properties ?. find ( p => p . serializedName === itemName && p . schema . type === SchemaType . Array ) ; itemName = valuesProperty ? getLanguageMetadata ( valuesProperty . language ) . name : itemName ; } } return itemName ; } /**
 * Gets the types of the iterable field across all responses.
 */ function getItemTypes ( operation , itemName ) { const operationName = getLanguageMetadata ( operation . language ) . name ; const operationResponses = operation . responses ?? [ ] ; const itemTypes = [ ] ; for ( const response of operationResponses ) { if ( ! isSchemaResponse ( response ) ) { continue ; } const status = response . protocol . http ?. status ; const typeDetails = getResponseItemType ( response , operationName , status , itemName ) ; const typeDetailsAlreadyFound = itemTypes . some ( itemType => { return isEqual ( itemType , typeDetails ) ; } ) ; if ( ! typeDetailsAlreadyFound ) { itemTypes . push ( { ... typeDetails } ) ; } } return itemTypes ; } /**
 * Gets the type of the iterable field.
 */ function getResponseItemType ( response , operationName , status , itemName ) { const responseSchema = response . schema ; if ( ! isObjectSchema ( responseSchema ) ) { throw new Error ( `Response for "${ operationName }" and status ${ status } has "x-ms-pageable" but is not of type "object".` ) ; } const itemProperty = responseSchema . properties ?. find ( property => { const propertyName = getLanguageMetadata ( property . language ) . name ; return propertyName === itemName || itemName === property . serializedName ; } ) ; if ( ! itemProperty ) { throw new Error ( `Possible malformed Swagger. Response for status "${ status }" in Operation "${ operationName }" doesn't have a(n) "${ itemName }" property.` ) ; } if ( itemProperty . schema . type !== SchemaType . Array ) { throw new Error ( `Possible malformed Swagger. Response for status "${ status }" in Operation "${ operationName }", expected property "${ itemName }" to be of type array.` ) ; } return getTypeForSchema ( itemProperty . schema ) ; } /**
 * Function to determine if any of the operations in the code model has at least one pageable operatio
 */ export function hasPagingOperations ( model ) { for ( const group of model . operationGroups ) { const hasAnyPageable = group . operations . some ( o => o . extensions && o . extensions [ "x-ms-pageable" ] ) ; if ( hasAnyPageable ) { return true ; } } return false ; } function isObjectSchema ( schema ) { return schema && schema . type === SchemaType . Object ; }