Public/Collections/ConvertTo-RequestQuery.ps1
|
<#
.SYNOPSIS Builds a query-string hashtable from a function's bound parameters. .DESCRIPTION The query-string counterpart to ConvertTo-RequestBody. Loops through the calling function's parameter metadata and adds every parameter that was actually bound (present in $PSBoundParameters) to the returned hashtable, keyed by its query-string name: - A parameter decorated with [QueryProperty('query_name')] is keyed by that name. - A parameter with no [QueryProperty()] attribute is keyed by its own name in lowercase. - A parameter decorated with [QueryIgnore()] is skipped entirely. Use this for route/path parameters such as -Id that belong in the URL rather than the query string. - PowerShell's common parameters (-Verbose, -WhatIf, -ErrorAction, etc.) are always skipped. Value types (int, bool, switch, etc.) are always included when bound, even when they hold their default value. Reference types (strings, arrays, objects) are only included when Test-HasValue returns $true. The result is a plain hashtable of typed values. Pipe it to ConvertTo-StringDictionary to get the Dictionary[string, string] that the C# client methods expect, with booleans rendered as lowercase 'true'/'false'. .PARAMETER BoundParameters The $PSBoundParameters dictionary from the calling function. .PARAMETER ParameterMetadata The calling function's parameter metadata, typically $MyInvocation.MyCommand.Parameters. .EXAMPLE function Get-HuduWidget { [CmdletBinding()] param( [QueryProperty('company_id')] [Parameter()] [int] $CompanyId, [QueryProperty('archived')] [Parameter()] [bool] $Archived ) $query = ConvertTo-RequestQuery -BoundParameters $PSBoundParameters ` -ParameterMetadata $MyInvocation.MyCommand.Parameters | ConvertTo-StringDictionary } Get-HuduWidget -CompanyId 5 -Archived $false Inside the function, $query is a Dictionary[string, string] containing company_id = '5' and archived = 'false'. .OUTPUTS System.Collections.Hashtable #> function ConvertTo-RequestQuery { [OutputType([hashtable])] [CmdletBinding()] param( [Parameter(Mandatory)] [System.Collections.IDictionary] $BoundParameters, [Parameter(Mandatory)] [System.Collections.Generic.Dictionary[string, System.Management.Automation.ParameterMetadata]] $ParameterMetadata ) # PowerShell's built-in parameters (-Verbose, -WhatIf, -ErrorAction, etc.) show up in both # ParameterMetadata and PSBoundParameters just like the function's own parameters, so they # have to be excluded explicitly - there's no metadata flag that marks them as "common". $commonParams = [System.Management.Automation.Cmdlet]::CommonParameters + [System.Management.Automation.Cmdlet]::OptionalCommonParameters $query = @{} foreach ($paramName in $ParameterMetadata.Keys) { if ($commonParams -contains $paramName) { continue } if (-not $BoundParameters.ContainsKey($paramName)) { continue } $attributes = $ParameterMetadata[$paramName].Attributes if ($attributes | Where-Object { $_ -is [QueryIgnore] }) { continue } $value = $BoundParameters[$paramName] if ($value -isnot [ValueType] -and -not (Test-HasValue -Value $value)) { continue } $queryAttr = $attributes | Where-Object { $_ -is [QueryProperty] } | Select-Object -First 1 $key = if ($null -ne $queryAttr) { $queryAttr.Name } else { $paramName.ToLowerInvariant() } $query[$key] = $value } return $query } |