src/private/Invoke-GitHubApi-BodyFile.ps1
#!/usr/bin/env pwsh $ErrorActionPreference = "Stop" Set-StrictMode -Version Latest function Invoke-GitHubApi-BodyFile { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [ValidateScript({ $_ -in [System.Net.Http.HttpMethod]::Get, [System.Net.Http.HttpMethod]::Post, [System.Net.Http.HttpMethod]::Put, [System.Net.Http.HttpMethod]::Patch, [System.Net.Http.HttpMethod]::Delete, [System.Net.Http.HttpMethod]::Head, [System.Net.Http.HttpMethod]::Options, [System.Net.Http.HttpMethod]::Trace, [System.Net.Http.HttpMethod]::Connect})] [System.Net.Http.HttpMethod] $Method, [Parameter(Mandatory = $true, Position = 1)] [ValidateNotNullOrEmpty()] [string] $Route, [Parameter(Mandatory = $false, Position = 2)] [hashtable] $Query = @{}, [Parameter(Mandatory = $true, Position = 3)] [switch] $File, [Parameter(Mandatory = $true)] [Alias("InputObject")] $Body, [Parameter(Mandatory = $false, Position = 6)] [ValidateNotNullOrEmpty()] [string] $ContentType, [Parameter(Mandatory = $false, Position = 11)] [ValidateNotNull()] [hashtable] $Headers = @{}, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $Hostname = $null, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $jq = $null, [Parameter(Mandatory = $false)] [switch] $Paginate, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string[]] $Previews = @(), [Parameter(Mandatory = $false, Position = 16)] [switch] $OutputRaw, [Parameter(Mandatory = $false)] [switch] $OutputAsHashtable, [Parameter(Mandatory = $false)] [ValidateRange(0, [int]::MaxValue)] [Nullable[int]] $OutputDepth, [Parameter(Mandatory = $false)] [switch] $OutputNoEnumerate ) Begin { if ($OutputRaw) { if ($OutputAsHashtable) { throw "OutputRaw and OutputAsHashtable cannot be used together." } if ($OutputDepth) { throw "OutputRaw and OutputDepth cannot be used together." } if ($OutputNoEnumerate) { throw "OutputRaw and OutputNoEnumerate cannot be used together." } } # [PSCommand] $command $ghCommand = [System.Management.Automation.PSCommand]::new() $ghCommand.AddCommand("gh") # --cache duration Cache the response, e.g. "3600s", "60m", "1h" # -F, --field key=value Add a typed parameter in key=value format # -H, --header key:value Add a HTTP request header in key:value format # --hostname string The GitHub hostname for the request (default "github.com") # -i, --include Include HTTP response status line and headers in the output # --input file The file to use as body for the HTTP request (use "-" to read from standard input) # -q, --jq string Query to select values from the response using jq syntax # -X, --method string The HTTP method for the request (default "GET") # --paginate Make additional HTTP requests to fetch all pages of results # -p, --preview names GitHub API preview names to request (without the "-preview" suffix) # -f, --raw-field key=value Add a string parameter in key=value format # --silent Do not print the response body # -t, --template string Format JSON output using a Go template; see "gh help formatting" # --verbose Include full HTTP request and response in the output $ghCommand = $ghCommand.AddArgument("api") [System.Text.StringBuilder] $routeFinal = [System.Text.StringBuilder]::new() $routeFinal.Append($Route) [bool] $firstQueryStringParameter = $true foreach ($key in $Query.Keys) { if ($firstQueryStringParameter) { $routeFinal.Append("?") $firstQueryStringParameter = $false } else { $routeFinal.Append("&") } $routeFinal.Append([System.Uri]::EscapeDataString($key)) $routeFinal.Append("=") $routeFinal.Append([System.Uri]::EscapeDataString($Query[$key])) } $ghCommand = $ghCommand.AddArgument($routeFinal.ToString()) if ($Method -ne [System.Net.Http.HttpMethod]::Get) { $ghCommand = $ghCommand.AddArgument("-X") $ghCommand = $ghCommand.AddArgument($Method.ToString().ToUpperInvariant()) } [hashtable] $headersFinal = @{ "Accept" = "application/vnd.github+json"; } + $headers if ($null -ne $ContentType) { $headersFinal["Content-Type"] = $ContentType } foreach ($headerKey in $headersFinal.Keys) { $ghCommand = $ghCommand.AddArgument("--header") [string] $escapedHeaderKey = [System.Uri]::EscapeDataString($headerKey) [string] $escapedHeaderValue = [System.Uri]::EscapeDataString($headersFinal[$headerKey]) $ghCommand = $ghCommand.AddArgument("${escapedHeaderKey}: ${escapedHeaderValue}") } if ($Hostname) { $ghCommand = $ghCommand.AddArgument("--hostname") $ghCommand = $ghCommand.AddArgument($Hostname) } if ($jq) { $ghCommand = $ghCommand.AddArgument("--jq") $ghCommand = $ghCommand.AddArgument($jq) } if ($Paginate) { $ghCommand = $ghCommand.AddArgument("--paginate") } if ($Previews) { $ghCommand = $ghCommand.AddArgument("--preview") $ghCommand = $ghCommand.AddArgument($Previews -join ",") } $outputHandlingCommand = $null -as [System.Management.Automation.PSCommand] if (-not $OutputRaw) { $outputHandlingCommand = [System.Management.Automation.PSCommand]::new() $outputHandlingCommand.AddCommand("ConvertFrom-Json") if ($OutputAsHashtable) { $outputHandlingCommand = $outputHandlingCommand.AddArgument("-AsHashtable") } if ($OutputDepth) { $outputHandlingCommand = $outputHandlingCommand.AddArgument("-Depth") $outputHandlingCommand = $outputHandlingCommand.AddArgument($OutputDepth) } if ($OutputNoEnumerate) { $outputHandlingCommand = $outputHandlingCommand.AddArgument("-NoEnumerate") } } } Process { [System.Management.Automation.PSCommand] $commandFinal = $ghCommand.Clone() if ($Fields) { [hashtable] $BodyFields = $Body -as [hashtable] if ($null -eq $BodyFields) { throw "Body must be a hashtable when using the Fields parameter." } foreach ($key in $BodyFields.Keys) { $commandFinal = $commandFinal.AddArgument("--raw-field") [string] $escapedFieldName = [System.Uri]::EscapeDataString($key) [string] $escapedFieldValue = [System.Uri]::EscapeDataString($BodyFields[$key]) $commandFinal = $commandFinal.AddArgument("${escapedFieldName}=${escapedFieldValue}") } } elseif ($File) { [System.IO.FileInfo] $File = $Body -as [System.IO.FileInfo] if ($null -eq $File) { throw "Body must be a FileInfo when using the File parameter." } $commandFinal = $commandFinal.AddArgument("--input") $commandFinal = $commandFinal.AddArgument($File.FullName) } elseif ($Raw -or $Json) { $commandFinal = $commandFinal.AddArgument("--input") $commandFinal = $commandFinal.AddArgument("-") [System.Management.Automation.PSCommand] $inputHandlingCommand = [System.Management.Automation.PSCommand]::new() if ($PSCmdlet.MyInvocation.ExpectingInput) { # $input | Invoke-Command $commandFinal $inputHandlingCommand = $inputHandlingCommand.AddArgument($input) } else { # $Body | Invoke-Command $commandFinal $inputHandlingCommand = $inputHandlingCommand.AddArgument($Body) } if ($Json) { $inputHandlingCommand = $inputHandlingCommand.AddCommand("ConvertTo-Json") if ($InputAsArray) { $inputHandlingCommand = $inputHandlingCommand.AddArgument("-AsArray") } if ($InputCompress) { $inputHandlingCommand = $inputHandlingCommand.AddArgument("-Compress") } if ($null -ne $InputDepth) { $inputHandlingCommand = $inputHandlingCommand.AddArgument("-Depth") $inputHandlingCommand = $inputHandlingCommand.AddArgument($InputDepth) } if ($InputEnumsAsStrings) { $inputHandlingCommand = $inputHandlingCommand.AddArgument("-EnumsAsStrings") } if ($null -ne $InputEscapeHandling) { $inputHandlingCommand = $inputHandlingCommand.AddArgument("-EscapeHandling") $inputHandlingCommand = $inputHandlingCommand.AddArgument($InputEscapeHandling) } } $commandFinal = $inputHandlingCommand.AddCommand($commandFinal) } if ($null -ne $outputHandlingCommand) { $commandFinal = $commandFinal.AddCommand($outputHandlingCommand) } Invoke-Command $commandFinal } End { } } |