import { OpenAPIV3 } from 'openapi-types' ; import { filterDuplicatesRight , partition } from '@sap-cloud-sdk/util' ; import { reservedJsKeywords } from '@sap-cloud-sdk/generator-common/internal' ; import { OpenApiOperation , OpenApiParameter } from '../openapi-types' ; import { parseRequestBody } from './request-body' ; import { OpenApiDocumentRefs } from './refs' ; import { parseSchema } from './schema' ; import { parseResponses } from './responses' ; import { OperationInfo } from './parsing-info' ; import { ensureUniqueNames } from './unique-naming' ; import { ParserOptions } from './options' ; param operationInfo param refs param options returns internal export function parseOperation ( { operation , pathPattern , method , pathItemParameters } , refs , options ) { const requestBody = parseRequestBody ( operation . requestBody , refs , options ) ; const response = parseResponses ( operation . responses , refs , options ) ; const relevantParameters = getRelevantParameters ( [ ... ( pathItemParameters || [ ] ) , ... ( operation . parameters || [ ] ) ] , refs ) ; const [ pathParams , queryParams ] = partition ( relevantParameters , parameter => parameter . in === 'path' ) ; const pathParameters = parsePathParameters ( pathParams , pathPattern , refs , options ) ; return { ... operation , method , requestBody , response , queryParameters : parseParameters ( queryParams , refs , options ) , pathParameters , pathPattern : parsePathPattern ( pathPattern , pathParameters ) , operationId : operation . operationId ! , tags : operation . tags ! } ; } internal export function getRelevantParameters ( parameters , refs ) { const resolvedParameters = parameters . map ( param => refs . resolveObject ( param ) ) . filter ( param => param . in === 'path' || param . in === 'query' ) ; return filterDuplicatesRight ( resolvedParameters , ( left , right ) => left . name === right . name && left . in === right . in ) ; } function isPlaceholder ( pathPart ) { return /^\{.+\}$/ . test ( pathPart ) ; } function isValidPlaceholder ( placeholder ) { return /^\{[^{}]+\}$/ . test ( placeholder ) ; } function isValidPathPattern ( pathPattern , placeholders ) { return ( pathPattern . includes ( '?' ) || placeholders . some ( placeholder => ! isValidPlaceholder ( placeholder ) ) ) ; } function sortPathParameters ( pathParameters , pathPattern ) { const pathParts = pathPattern . split ( '/' ) ; const placeholders = pathParts . filter ( part => isPlaceholder ( part ) ) ; if ( isValidPathPattern ( pathPattern , placeholders ) ) { throw new Error ( `Path pattern '${ pathPattern }' is invalid or not supported.` ) ; } return placeholders . map ( placeholder => { const strippedPlaceholder = placeholder . slice ( 1 , - 1 ) ; const pathParameter = pathParameters . find ( param => param . name === strippedPlaceholder ) ; if ( ! pathParameter ) { throw new Error ( `Path parameter '${ strippedPlaceholder }' provided in path is missing in path parameters.` ) ; } return pathParameter ; } ) ; } internal export function parsePathPattern ( pathPattern , pathParameters ) { const pathParts = pathPattern . split ( '/' ) ; const parameterNames = pathParameters . map ( param => param . name ) ; return pathParts . map ( part => { if ( isPlaceholder ( part ) ) { if ( ! parameterNames . length ) { throw new Error ( `Could not find parameter for placeholder '${ part }'.` ) ; } return `{${ parameterNames . shift ( ) }}` ; } return part ; } ) . join ( '/' ) ; } internal export function parsePathParameters ( pathParameters , pathPattern , refs , options ) { const sortedPathParameters = sortPathParameters ( pathParameters , pathPattern ) ; const parsedParameters = parseParameters ( sortedPathParameters , refs , options ) ; const uniqueNames = ensureUniqueNames ( parsedParameters . map ( ( { originalName } ) => originalName ) , options , { reservedWords : [ 'body' , 'queryParameters' , ... reservedJsKeywords ] } ) ; return parsedParameters . map ( ( param , i ) => { param . name = uniqueNames [ i ] ; return param ; } ) ; } internal export function parseParameters ( pathParameters , refs , options ) { return pathParameters . map ( param => ( { ... param , originalName : param . name , schema : parseSchema ( param . schema , refs , options ) , schemaProperties : { } } ) ) ; }