Files

99 lines
3.3 KiB
PowerShell

<#
.SYNOPSIS
Low-level Gitea REST API wrapper (curl-based, BOM-safe).
.DESCRIPTION
Mirrors Invoke-GitHubApi.ps1's design: uses curl.exe so JSON bodies are
written via --data-binary @file (no PowerShell Set-Content BOM, which
Gitea rejects with "invalid character '\u00ef' looking for beginning of
value"). Reads GITEA_URL + GITEA_TOKEN from the environment.
.PARAMETER Method
HTTP verb. Default GET.
.PARAMETER Path
Path under /api/v1 (with or without leading slash). Query params allowed.
.PARAMETER BodyJson
JSON body for write verbs. Validated as JSON before sending.
.PARAMETER Raw
Return a pscustomobject with Status, Headers, Body instead of parsed JSON.
.EXAMPLE
.\Invoke-GiteaApi.ps1 -Path "/version"
.\Invoke-GiteaApi.ps1 -Path "/user"
.\Invoke-GiteaApi.ps1 -Method POST -Path "/user/repos" -BodyJson $json
#>
param(
[ValidateSet("GET", "POST", "PATCH", "PUT", "DELETE")]
[string]$Method = "GET",
[Parameter(Mandatory = $true)]
[string]$Path,
[string]$BodyJson,
[switch]$Raw
)
$ErrorActionPreference = "Stop"
if ([string]::IsNullOrWhiteSpace($env:GITEA_TOKEN)) {
throw "Set GITEA_TOKEN before calling the Gitea API. Store it in .env.local.ps1 (gitignored)."
}
if (-not (Get-Command curl.exe -ErrorAction SilentlyContinue)) {
throw "curl.exe not found in PATH."
}
$base = if ($env:GITEA_URL) { $env:GITEA_URL.TrimEnd("/") } else { "https://gitea-hjwh0svsoo9p5w5kj2j6b1bd.urieljareth.org" }
$base = "$base/api/v1"
$cleanPath = $Path.TrimStart("/")
$uri = "$base/$cleanPath"
# Gitea accepts "token <T>" (canonical) and "Bearer <T>" (since 1.16+).
$curlArgs = @(
"-sS", "-i",
"-X", $Method.ToUpper(),
"-H", "Authorization: token $env:GITEA_TOKEN",
"-H", "Accept: application/json",
"-H", "User-Agent: gitea-skill"
)
$tmpBody = $null
if ($PSBoundParameters.ContainsKey("BodyJson")) {
try { $null = $BodyJson | ConvertFrom-Json } catch { throw "BodyJson is not valid JSON: $($_.Exception.Message)" }
$tmpBody = [System.IO.Path]::GetTempFileName()
[System.IO.File]::WriteAllText($tmpBody, $BodyJson, (New-Object System.Text.UTF8Encoding($false)))
$curlArgs += @("--data-binary", "@$tmpBody", "-H", "Content-Type: application/json")
}
try {
$output = & curl.exe @curlArgs $uri
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) { throw "Gitea API request failed with exit code $exitCode." }
$rawStr = ($output | Out-String)
$parts = $rawStr -split "(?:`r`n`r`n|`n`n)", 2
$headersBlock = if ($parts.Count -ge 1) { $parts[0] } else { "" }
$bodyBlock = if ($parts.Count -ge 2) { $parts[1] } else { "{}" }
$statusLine = ($headersBlock -split "`n" | Select-Object -First 1).Trim()
if ($statusLine -notmatch " 20[04-9] ") {
$snippet = $bodyBlock.Trim()
if ($snippet.Length -gt 500) { $snippet = $snippet.Substring(0, 500) + "..." }
throw "Gitea API HTTP error: $statusLine`nURI: $uri`nBody: $snippet"
}
if ($Raw) {
[pscustomobject]@{ Status = $statusLine; Headers = $headersBlock; Body = $bodyBlock }
} else {
try { $bodyBlock | ConvertFrom-Json }
catch { $bodyBlock }
}
}
finally {
if ($tmpBody -and (Test-Path -LiteralPath $tmpBody)) {
Remove-Item -LiteralPath $tmpBody -Force -ErrorAction SilentlyContinue
}
}