Skip to content

Commit

Permalink
Merge pull request #1358 from mdaneri/openapi-fixes
Browse files Browse the repository at this point in the history
Fixes [ordered] comparisons in PowerShell 5.1; Fixes OpenAPI version validation check in PowerShell 5.1; Fixes for various OpenAPI issues
  • Loading branch information
Badgerati authored Jul 20, 2024
2 parents b946dc3 + abf41cb commit d8a35f1
Show file tree
Hide file tree
Showing 19 changed files with 69 additions and 32 deletions.
1 change: 1 addition & 0 deletions src/Locales/ar/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'مدة Access-Control-Max-Age غير صالحة المقدمة: {0}. يجب أن تكون أكبر من 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'تعريف OpenAPI باسم {0} موجود بالفعل.'
renamePodeOADefinitionTagExceptionMessage = "لا يمكن استخدام Rename-PodeOADefinitionTag داخل Select-PodeOADefinition 'ScriptBlock'."
DefinitionTagChangeNotAllowedExceptionMessage = 'لا يمكن تغيير علامة التعريف لمسار.'
}
1 change: 1 addition & 0 deletions src/Locales/de/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Ungültige Access-Control-Max-Age-Dauer angegeben: {0}. Sollte größer als 0 sein.'
openApiDefinitionAlreadyExistsExceptionMessage = 'Die OpenAPI-Definition mit dem Namen {0} existiert bereits.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag kann nicht innerhalb eines 'ScriptBlock' von Select-PodeOADefinition verwendet werden."
DefinitionTagChangeNotAllowedExceptionMessage = 'Definitionstag für eine Route kann nicht geändert werden.'
}
1 change: 1 addition & 0 deletions src/Locales/en-us/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Invalid Access-Control-Max-Age duration supplied: {0}. Should be greater than 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'OpenAPI definition named {0} already exists.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag cannot be used inside a Select-PodeOADefinition 'ScriptBlock'."
DefinitionTagChangeNotAllowedExceptionMessage = 'Definition Tag for a Route cannot be changed.'
}
3 changes: 2 additions & 1 deletion src/Locales/en/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
requestLoggingAlreadyEnabledExceptionMessage = 'Request Logging has already been enabled.'
invalidAccessControlMaxAgeDurationExceptionMessage = 'Invalid Access-Control-Max-Age duration supplied: {0}. Should be greater than 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'OpenAPI definition named {0} already exists.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag cannot be used inside a Select-PodeOADefinition 'ScriptBlock'."
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag cannot be used inside a Select-PodeOADefinition 'ScriptBlock'."
DefinitionTagChangeNotAllowedExceptionMessage = 'Definition Tag for a Route cannot be changed.'
}

4 changes: 2 additions & 2 deletions src/Locales/es/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,5 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Duración inválida para Access-Control-Max-Age proporcionada: {0}. Debe ser mayor que 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'La definición de OpenAPI con el nombre {0} ya existe.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag no se puede usar dentro de un 'ScriptBlock' de Select-PodeOADefinition."
}

DefinitionTagChangeNotAllowedExceptionMessage = 'La etiqueta de definición para una Route no se puede cambiar.'
}
1 change: 1 addition & 0 deletions src/Locales/fr/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,5 +285,6 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Durée Access-Control-Max-Age invalide fournie : {0}. Doit être supérieure à 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'La définition OpenAPI nommée {0} existe déjà.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag ne peut pas être utilisé à l'intérieur d'un 'ScriptBlock' de Select-PodeOADefinition."
DefinitionTagChangeNotAllowedExceptionMessage = 'Le tag de définition pour une Route ne peut pas être modifié.'
}

1 change: 1 addition & 0 deletions src/Locales/it/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Durata non valida fornita per Access-Control-Max-Age: {0}. Deve essere maggiore di 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'La definizione OpenAPI denominata {0} esiste già.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag non può essere utilizzato all'interno di un 'ScriptBlock' di Select-PodeOADefinition."
DefinitionTagChangeNotAllowedExceptionMessage = 'Il tag di definizione per una Route non può essere cambiato.'
}
2 changes: 2 additions & 0 deletions src/Locales/ja/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,6 @@
invalidAccessControlMaxAgeDurationExceptionMessage = '無効な Access-Control-Max-Age 期間が提供されました:{0}。0 より大きくする必要があります。'
openApiDefinitionAlreadyExistsExceptionMessage = '名前が {0} の OpenAPI 定義は既に存在します。'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag は Select-PodeOADefinition 'ScriptBlock' 内で使用できません。"
DefinitionTagChangeNotAllowedExceptionMessage = 'Routeの定義タグは変更できません。'
}

1 change: 1 addition & 0 deletions src/Locales/ko/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = '잘못된 Access-Control-Max-Age 기간이 제공되었습니다: {0}. 0보다 커야 합니다.'
openApiDefinitionAlreadyExistsExceptionMessage = '이름이 {0}인 OpenAPI 정의가 이미 존재합니다.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag은 Select-PodeOADefinition 'ScriptBlock' 내에서 사용할 수 없습니다."
DefinitionTagChangeNotAllowedExceptionMessage = 'Route에 대한 정의 태그는 변경할 수 없습니다.'
}
1 change: 1 addition & 0 deletions src/Locales/nl/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,5 +285,6 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Ongeldige Access-Control-Max-Age duur opgegeven: {0}. Moet groter zijn dan 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'OpenAPI-definitie met de naam {0} bestaat al.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag kan niet worden gebruikt binnen een Select-PodeOADefinition 'ScriptBlock'."
DefinitionTagChangeNotAllowedExceptionMessage = 'Definitietag voor een route kan niet worden gewijzigd.'
}

2 changes: 2 additions & 0 deletions src/Locales/pl/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,6 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Podano nieprawidłowy czas trwania Access-Control-Max-Age: {0}. Powinien być większy niż 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'Definicja OpenAPI o nazwie {0} już istnieje.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag nie może być używany wewnątrz 'ScriptBlock' Select-PodeOADefinition."
DefinitionTagChangeNotAllowedExceptionMessage = 'Tag definicji dla Route nie może zostać zmieniony.'
}

1 change: 1 addition & 0 deletions src/Locales/pt/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = 'Duração inválida fornecida para Access-Control-Max-Age: {0}. Deve ser maior que 0.'
openApiDefinitionAlreadyExistsExceptionMessage = 'A definição OpenAPI com o nome {0} já existe.'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag não pode ser usado dentro de um 'ScriptBlock' Select-PodeOADefinition."
DefinitionTagChangeNotAllowedExceptionMessage = 'A Tag de definição para uma Route não pode ser alterada.'
}
4 changes: 2 additions & 2 deletions src/Locales/zh/Pode.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -285,5 +285,5 @@
invalidAccessControlMaxAgeDurationExceptionMessage = '提供的 Access-Control-Max-Age 时长无效:{0}。应大于 0。'
openApiDefinitionAlreadyExistsExceptionMessage = '名为 {0} 的 OpenAPI 定义已存在。'
renamePodeOADefinitionTagExceptionMessage = "Rename-PodeOADefinitionTag 不能在 Select-PodeOADefinition 'ScriptBlock' 内使用。"
}

DefinitionTagChangeNotAllowedExceptionMessage = 'Route的定义标签无法更改。'
}
10 changes: 8 additions & 2 deletions src/Private/OpenApi.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,13 @@ function ConvertTo-PodeOASchemaProperty {
}
#Fix an issue when additionalProperties has an assigned value of $false
if ($Property.ContainsKey('additionalProperties')) {
$schema['additionalProperties'] = $Property.additionalProperties
if ($Property.additionalProperties) {
$schema['additionalProperties'] = $Property.additionalProperties | ConvertTo-PodeOASchemaProperty -DefinitionTag $DefinitionTag
}
else {
#the value is $false
$schema['additionalProperties'] = $false
}
}

if ($Property.discriminator) {
Expand Down Expand Up @@ -1926,7 +1932,7 @@ function New-PodeOResponseInternal {
$_headers = $null
if ($null -ne $Params.Headers) {
if ($Params.Headers -is [System.Object[]] -or $Params.Headers -is [string] -or $Params.Headers -is [string[]]) {
if ($Params.Headers -is [System.Object[]] -and $Params.Headers.Count -gt 0 -and ($Params.Headers[0] -is [hashtable] -or $Params.Headers[0] -is [ordered])) {
if ($Params.Headers -is [System.Object[]] -and $Params.Headers.Count -gt 0 -and ($Params.Headers[0] -is [hashtable] -or $Params.Headers[0] -is [System.Collections.Specialized.OrderedDictionary])) {
$_headers = ConvertTo-PodeOAHeaderProperty -Headers $Params.Headers
}
else {
Expand Down
2 changes: 1 addition & 1 deletion src/Private/Secrets.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ function Protect-PodeSecretValueType {
$Value = [string]::Empty
}

if ($Value -is [ordered]) {
if ($Value -is [System.Collections.Specialized.OrderedDictionary]) {
$Value = [hashtable]$Value
}

Expand Down
4 changes: 2 additions & 2 deletions src/Public/OAComponents.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -785,8 +785,8 @@ Test-PodeOAVersion -Version 3.1 -DefinitionTag 'default'
function Test-PodeOAVersion {
param (
[Parameter(Mandatory = $true)]
[ValidateSet( 3.1 , 3.0 )]
[decimal]
[ValidateSet( '3.1' , '3.0' )]
[string]
$Version,

[Parameter(Mandatory = $true)]
Expand Down
24 changes: 17 additions & 7 deletions src/Public/OpenApi.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ function Add-PodeOAResponse {
[Alias('HeaderSchemas')]
[AllowEmptyString()]
[ValidateNotNullOrEmpty()]
[ValidateScript({ $_ -is [string] -or $_ -is [string[]] -or $_ -is [hashtable] -or $_ -is [ordered] })]
[ValidateScript({ $_ -is [string] -or $_ -is [string[]] -or $_ -is [hashtable] -or $_ -is [System.Collections.Specialized.OrderedDictionary] })]
$Headers,

[Parameter(Mandatory = $false, ParameterSetName = 'Schema')]
Expand Down Expand Up @@ -882,10 +882,6 @@ function New-PodeOARequestBody {

$DefinitionTag = Test-PodeOADefinitionTag -Tag $DefinitionTag

if ($Example -and $Examples) {
# Parameters 'Examples' and 'Example' are mutually exclusive
throw ($PodeLocale.parametersMutuallyExclusiveExceptionMessage -f 'Example', 'Examples')
}
$result = @{}
foreach ($tag in $DefinitionTag) {
switch ($PSCmdlet.ParameterSetName.ToLowerInvariant()) {
Expand Down Expand Up @@ -1302,6 +1298,12 @@ function ConvertTo-PodeOAParameter {
$prop['allowReserved'] = $AllowReserved.IsPresent
}

if ($Example ) {
$prop.example = $Example
}
elseif ($Examples) {
$prop.examples = $Examples
}
}
}
elseif ($PSCmdlet.ParameterSetName -ieq 'Reference') {
Expand Down Expand Up @@ -1559,8 +1561,16 @@ function Set-PodeOARouteInfo {
$DefinitionTag = Test-PodeOADefinitionTag -Tag $DefinitionTag

foreach ($r in @($Route)) {

$r.OpenApi.DefinitionTag = $DefinitionTag
if ((Compare-Object -ReferenceObject $r.OpenApi.DefinitionTag -DifferenceObject $DefinitionTag).Count -ne 0) {
if ($r.OpenApi.IsDefTagConfigured ) {
# Definition Tag for a Route cannot be changed.
throw ($PodeLocale.DefinitionTagChangeNotAllowedExceptionMessage)
}
else {
$r.OpenApi.DefinitionTag = $DefinitionTag
$r.OpenApi.IsDefTagConfigured = $true
}
}

if ($Summary) {
$r.OpenApi.Summary = $Summary
Expand Down
30 changes: 18 additions & 12 deletions src/Public/Routes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -431,14 +431,15 @@ function Add-PodeRoute {
Method = $_method
Path = $Path
OpenApi = @{
Path = $OpenApiPath
Responses = $DefaultResponse
Parameters = $null
RequestBody = $null
CallBacks = @{}
Authentication = @()
Servers = @()
DefinitionTag = $DefinitionTag
Path = $OpenApiPath
Responses = $DefaultResponse
Parameters = $null
RequestBody = $null
CallBacks = @{}
Authentication = @()
Servers = @()
DefinitionTag = $DefinitionTag
IsDefTagConfigured = ($null -ne $OADefinitionTag) #Definition Tag has been configured (Not default)
}
IsStatic = $false
Metrics = @{
Expand Down Expand Up @@ -1692,11 +1693,16 @@ function Remove-PodeRoute {
return
}

# select the candidate route for deletion
$route = @($PodeContext.Server.Routes[$Method][$Path] | Where-Object {
$_.Endpoint.Name -ine $EndpointName
})

# remove the operationId from the openapi operationId list
if ($PodeContext.Server.Routes[$Method][$Path].OpenAPI) {
foreach ( $tag in $PodeContext.Server.Routes[$Method][$Path].OpenAPI.DefinitionTag) {
if ($tag -and ($PodeContext.Server.OpenAPI.Definitions[$tag].hiddenComponents.operationId -ccontains $PodeContext.Server.Routes[$Method][$Path].OpenAPI.OperationId)) {
$PodeContext.Server.OpenAPI.Definitions[$tag].hiddenComponents.operationId = $PodeContext.Server.OpenAPI.Definitions[$tag].hiddenComponents.operationId | Where-Object { $_ -ne $PodeContext.Server.Routes[$Method][$Path].OpenAPI.OperationId }
if ($route.OpenAPI) {
foreach ( $tag in $route.OpenAPI.DefinitionTag) {
if ($tag -and ($PodeContext.Server.OpenAPI.Definitions[$tag].hiddenComponents.operationId -ccontains $route.OpenAPI.OperationId)) {
$PodeContext.Server.OpenAPI.Definitions[$tag].hiddenComponents.operationId = $PodeContext.Server.OpenAPI.Definitions[$tag].hiddenComponents.operationId | Where-Object { $_ -ne $route.OpenAPI.OperationId }
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions tests/unit/OpenApi.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2193,9 +2193,11 @@ Describe 'OpenApi' {
'200' = @{ description = 'OK' }
'default' = @{ description = 'Internal server error' }
}
Parameters = $null
RequestBody = $null
Authentication = @()
Parameters = $null
RequestBody = $null
Authentication = @()
DefinitionTag = @('Default')
IsDefTagConfigured = $false
}
}

Expand Down

0 comments on commit d8a35f1

Please sign in to comment.