Private/Testing/Get-SwaggerSchema.ps1
|
function Get-SwaggerSchema { <# .SYNOPSIS Retrieves the schema for an API endpoint from swagger files. .DESCRIPTION Parses the swagger JSON files to find endpoint definitions and extract response schemas. Resolves $ref references to component schemas. .PARAMETER SwaggerPath The API path to look up (e.g., "/rest-api/v1/accounts/{accountId}/host-pool") .PARAMETER Method HTTP method (GET, POST, PUT, DELETE). Default is GET. .PARAMETER ApiVersion API version: 'v1' or 'v1-beta'. Default is 'v1'. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$SwaggerPath, [Parameter()] [ValidateSet('GET', 'POST', 'PUT', 'DELETE', 'PATCH')] [string]$Method = 'GET', [Parameter()] [ValidateSet('v1', 'v1-beta')] [string]$ApiVersion = 'v1' ) # Determine swagger file path $moduleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) $swaggerFile = Join-Path $moduleRoot ".swagger" "$ApiVersion.json" if (-not (Test-Path $swaggerFile)) { Write-Warning "Swagger file not found: $swaggerFile" return $null } # Load and parse swagger JSON $swagger = Get-Content $swaggerFile -Raw | ConvertFrom-Json -AsHashtable # Normalize path for lookup (swagger uses lowercase method keys) $methodKey = $Method.ToLower() # Find the endpoint in paths $pathEntry = $null foreach ($path in $swagger.paths.Keys) { # Normalize both paths for comparison (handle parameter placeholders) $normalizedSwaggerPath = $path -replace '\{[^}]+\}', '{param}' $normalizedInputPath = $SwaggerPath -replace '\{[^}]+\}', '{param}' if ($normalizedSwaggerPath -eq $normalizedInputPath) { $pathEntry = $swagger.paths[$path] break } } if (-not $pathEntry) { Write-Warning "Endpoint not found in swagger: $SwaggerPath" return $null } # Get the method definition $methodDef = $pathEntry[$methodKey] if (-not $methodDef) { Write-Warning "Method $Method not found for endpoint: $SwaggerPath" return $null } # Extract response schema (typically from 200 response) $responseSchema = $null $responses = $methodDef.responses if ($responses.'200'.content.'application/json'.schema) { $responseSchema = $responses.'200'.content.'application/json'.schema } elseif ($responses.'200'.content.'text/plain'.schema) { $responseSchema = $responses.'200'.content.'text/plain'.schema } # Resolve $ref if present if ($responseSchema.'$ref') { $responseSchema = Resolve-SwaggerRef -Swagger $swagger -Ref $responseSchema.'$ref' } # Extract request body schema if POST/PUT $requestSchema = $null if ($methodDef.requestBody.content.'application/json'.schema) { $requestSchema = $methodDef.requestBody.content.'application/json'.schema if ($requestSchema.'$ref') { $requestSchema = Resolve-SwaggerRef -Swagger $swagger -Ref $requestSchema.'$ref' } } # Build result object return [PSCustomObject]@{ Path = $SwaggerPath Method = $Method Summary = $methodDef.summary Description = $methodDef.description Tags = $methodDef.tags Parameters = $methodDef.parameters RequestSchema = $requestSchema ResponseSchema = $responseSchema ResponseExample = $responses.'200'.content.'application/json'.example } } function Resolve-SwaggerRef { <# .SYNOPSIS Resolves a $ref reference in swagger to its actual schema definition. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [hashtable]$Swagger, [Parameter(Mandatory = $true)] [string]$Ref ) # Parse ref path (e.g., "#/components/schemas/AccountModel") $refPath = $Ref -replace '^#/', '' -split '/' $current = $Swagger foreach ($segment in $refPath) { if ($current -is [hashtable] -and $current.ContainsKey($segment)) { $current = $current[$segment] } else { Write-Warning "Could not resolve ref segment: $segment in $Ref" return $null } } return $current } function Get-SchemaProperties { <# .SYNOPSIS Extracts all property names from a swagger schema, including nested properties. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] $Schema, [Parameter()] [hashtable]$Swagger, [Parameter()] [string]$Prefix = '' ) $properties = @() if (-not $Schema) { return $properties } # Handle $ref if ($Schema.'$ref' -and $Swagger) { $Schema = Resolve-SwaggerRef -Swagger $Swagger -Ref $Schema.'$ref' } # Handle array type if ($Schema.type -eq 'array' -and $Schema.items) { $itemSchema = $Schema.items if ($itemSchema.'$ref' -and $Swagger) { $itemSchema = Resolve-SwaggerRef -Swagger $Swagger -Ref $itemSchema.'$ref' } if ($itemSchema.properties) { foreach ($propName in $itemSchema.properties.Keys) { $fullName = if ($Prefix) { "$Prefix.$propName" } else { $propName } $properties += $fullName } } return $properties } # Handle object type with properties if ($Schema.properties) { foreach ($propName in $Schema.properties.Keys) { $fullName = if ($Prefix) { "$Prefix.$propName" } else { $propName } $properties += $fullName } } # Handle allOf (combined schemas) if ($Schema.allOf) { foreach ($subSchema in $Schema.allOf) { $properties += Get-SchemaProperties -Schema $subSchema -Swagger $Swagger -Prefix $Prefix } } return $properties | Select-Object -Unique } |