Private/Document/ConvertTo-OpenApiOperation.ps1
|
function ConvertTo-OpenApiOperation { <# .SYNOPSIS Builds the Operation object of the document model from a raw operation and its path item. .DESCRIPTION Path-level parameters are merged in; an operation-level parameter replaces a path-level one with the same (Name, In) (header names compared case-insensitively). Security is $null when the operation does not declare it (use the document default), an empty array for 'security: []'. Any external $ref met while building the operation (directly or through a cached schema) sets Unsupported. Deprecated operations give OA060 (Information). #> [CmdletBinding()] [OutputType([pscustomobject])] param( [Parameter(Mandatory)] [pscustomobject]$Context, [Parameter(Mandatory)] [string]$OperationId, [Parameter(Mandatory)] [string]$Method, [Parameter(Mandatory)] [string]$Path, [Parameter(Mandatory)] [System.Collections.IDictionary]$Operation, [Parameter(Mandatory)] [System.Collections.IDictionary]$PathItem, [Parameter(Mandatory)] [AllowEmptyString()] [string]$PathItemPointer ) $Context.CurrentOperation = $OperationId $hitsBefore = $Context.ExternalRefHits $pointer = Join-OpenApiJsonPointer -Pointer $PathItemPointer -Segment $Method.ToLowerInvariant() $parameters = [System.Collections.Specialized.OrderedDictionary]::new([System.StringComparer]::Ordinal) foreach ($source in @(@($PathItem['parameters'], $PathItemPointer), @($Operation['parameters'], $pointer))) { if ($source[0] -isnot [System.Collections.IList]) { continue } $index = 0 foreach ($rawParameter in $source[0]) { $parameterPointer = Join-OpenApiJsonPointer -Pointer $source[1] -Segment 'parameters', ([string]$index) $index++ $resolved = Resolve-OpenApiComponentReference -Context $Context -Node $rawParameter -Pointer $parameterPointer if ($null -eq $resolved -or $resolved.Node -isnot [System.Collections.IDictionary]) { continue } $parameter = ConvertTo-OpenApiParameter -Context $Context -Node $resolved.Node -Pointer $resolved.Pointer $name = $parameter.Name if ($parameter.In -eq 'header') { $name = $name.ToLowerInvariant() } $parameters['{0}|{1}' -f $parameter.In, $name] = $parameter } } $requestBody = $null if ($Operation.Contains('requestBody')) { $resolvedBody = Resolve-OpenApiComponentReference -Context $Context -Node $Operation['requestBody'] -Pointer (Join-OpenApiJsonPointer -Pointer $pointer -Segment 'requestBody') if ($null -ne $resolvedBody -and $resolvedBody.Node -is [System.Collections.IDictionary]) { $requestBody = ConvertTo-OpenApiRequestBody -Context $Context -Node $resolvedBody.Node -Pointer $resolvedBody.Pointer } } $responses = ConvertTo-OpenApiResponseList -Context $Context -Responses $Operation['responses'] -Pointer (Join-OpenApiJsonPointer -Pointer $pointer -Segment 'responses') $security = $null if ($Operation.Contains('security')) { $security = ConvertTo-OpenApiSecurityRequirement -Context $Context -Requirement $Operation['security'] -Pointer (Join-OpenApiJsonPointer -Pointer $pointer -Segment 'security') } $tags = [System.Collections.Generic.List[string]]::new() if ($Operation['tags'] -is [System.Collections.IList]) { foreach ($tag in $Operation['tags']) { if ($null -ne $tag) { $tags.Add([string]$tag) } } } $extensions = [System.Collections.Specialized.OrderedDictionary]::new([System.StringComparer]::Ordinal) foreach ($key in @($Operation.Keys)) { if ($key.StartsWith('x-')) { $extensions[$key] = $Operation[$key] } } $externalDocsUrl = $null if ($Operation['externalDocs'] -is [System.Collections.IDictionary] -and $null -ne $Operation['externalDocs']['url']) { $externalDocsUrl = [string]$Operation['externalDocs']['url'] } $deprecated = $Operation['deprecated'] -eq $true if ($deprecated) { Add-OpenApiFinding -Context $Context -Severity Information -Code 'OA060' -Pointer (Join-OpenApiJsonPointer -Pointer $pointer -Segment 'deprecated') -Message "Operation '$OperationId' is deprecated." } $unsupported = $Context.ExternalRefHits -gt $hitsBefore if ($unsupported) { $reported = @($Context.Findings | Where-Object { $_.Code -eq 'OA020' -and $_.Operation -eq $OperationId }) if ($reported.Count -eq 0) { Add-OpenApiFinding -Context $Context -Severity Error -Code 'OA020' -Pointer $pointer -Message "Operation '$OperationId' uses a schema that contains an external `$ref; it is flagged Unsupported." } } $summary = $null if ($null -ne $Operation['summary']) { $summary = [string]$Operation['summary'] } $description = $null if ($null -ne $Operation['description']) { $description = [string]$Operation['description'] } $result = [pscustomobject]@{ PSTypeName = 'Tcs.OpenApi.Operation' OperationId = $OperationId Method = $Method.ToUpperInvariant() Path = $Path Tags = $tags.ToArray() Summary = $summary Description = $description Deprecated = $deprecated ExternalDocsUrl = $externalDocsUrl Parameters = @($parameters.Values) RequestBody = $requestBody Responses = $responses Security = $security Paging = Get-OpenApiPaging -Operation $Operation -Responses $responses Extensions = $extensions Unsupported = $unsupported } $Context.CurrentOperation = $null return $result } |