From 525d4f4cf0cc788ce694a2e60c646f040dd79a99 Mon Sep 17 00:00:00 2001 From: Pier-Paolo Mammi Date: Tue, 30 Jun 2026 11:12:02 +0200 Subject: [PATCH] add equivalent powershell script --- scripts/generate-http-docs.ps1 | 327 +++++++++++++++++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 scripts/generate-http-docs.ps1 diff --git a/scripts/generate-http-docs.ps1 b/scripts/generate-http-docs.ps1 new file mode 100644 index 0000000..9f0821c --- /dev/null +++ b/scripts/generate-http-docs.ps1 @@ -0,0 +1,327 @@ +#requires -Modules powershell-yaml + +param( + [string]$StartDir = (Split-Path -Parent $MyInvocation.MyCommand.Path) +) + +function Find-WorkspaceRoot($startDir) { + $current = $startDir + while ($true) { + if (Test-Path -LiteralPath (Join-Path $current 'workspace.yml')) { + return $current + } + $parent = Split-Path -Parent $current + if ($parent -eq $current) { + throw "workspace.yml not found" + } + $current = $parent + } +} + +function Parse-YamlFile($path) { + try { + return ConvertFrom-Yaml (Get-Content -LiteralPath $path -Raw) + } catch { + throw "Failed to parse YAML file $path : $_" + } +} + +function Strip-Quotes($value) { + $trim = $value.Trim() + if (($trim.StartsWith('"') -and $trim.EndsWith('"')) -or + ($trim.StartsWith("'") -and $trim.EndsWith("'"))) { + return $trim.Substring(1, $trim.Length - 2) + } + return $trim +} + +function Parse-Workspace($workspacePath) { + $lines = Get-Content -LiteralPath $workspacePath + $collections = @() + $inCollections = $false + $current = $null + + foreach ($line in $lines) { + $trim = $line.Trim() + + if (-not $inCollections -and $trim -eq 'collections:') { + $inCollections = $true + continue + } + + if (-not $inCollections) { continue } + + if (-not ($line.StartsWith(' ') -or $line.StartsWith("`t"))) { + break + } + + if ($line -match '^\s*-\s+name:\s*(.+)$') { + $name = Strip-Quotes $Matches[1] + $current = [ordered]@{ name = $name } + $collections += $current + continue + } + + if ($line -match '^\s*path:\s*(.+)$' -and $current) { + $current.path = Strip-Quotes $Matches[1] + } + } + + return @{ collections = $collections } +} + +function Walk-YamlFiles($rootDir) { + Get-ChildItem -LiteralPath $rootDir -Recurse -File -Include *.yml, *.yaml | + Where-Object { $_.Name -notmatch '^\.|node_modules' } | + Select-Object -ExpandProperty FullName +} + +function Ensure-Dir($path) { + if (-not (Test-Path -LiteralPath $path)) { + New-Item -ItemType Directory -Path $path | Out-Null + } +} + +function Clean-Folder($dir) { + if (-not (Test-Path -LiteralPath $dir)) { return } + + foreach ($entry in Get-ChildItem -LiteralPath $dir) { + if ($entry.PSIsContainer) { + Clean-Folder $entry.FullName + $children = Get-ChildItem -LiteralPath $entry.FullName + if ($children.Count -eq 0) { + Remove-Item -LiteralPath $entry.FullName -Force + } + } else { + if (!$entry.PSIsContainer -and $entry.Name -match '\.js$|\.http$|\.env\.template$') { + Remove-Item -LiteralPath $entry.FullName -Force + } + } + } +} + +function Parse-HttpBlock($text) { + $parsed = ConvertFrom-Yaml $text + $http = $parsed.http + + $headers = @() + foreach ($h in ($http.headers | Where-Object { $_ })) { + $headers += [ordered]@{ + name = $h.name + value = $h.value + } + } + + return @{ + method = $http.method + url = $http.url + params = $http.params + headers = $headers + body = $http.body + } +} + +function Build-RequestContent($http, $name, $config, $dotenvVars) { + $lines = @() + $vars = @() + $paramsVars = @() + $commentVars = @() + $seen = New-Object System.Collections.Generic.HashSet[string] + + function Add-Var($n, $v) { + if (-not $n) { return } + if ($seen.Contains($n)) { return } + if ($dotenvVars.Contains($n)) { return } + $seen.Add($n) | Out-Null + $vars += @{ name = $n; value = $v } + } + + function Add-ParamVar($n, $v) { + if (-not $n) { return } + if ($seen.Contains($n)) { return } + if ($dotenvVars.Contains($n)) { return } + $seen.Add($n) | Out-Null + $paramsVars += @{ name = $n; value = $v } + } + + function Add-CommentVar($n, $v) { + if (-not $n) { return } + $commentVars += @{ name = $n; value = $v } + } + + # Variables from config + foreach ($v in ($config.variables | Where-Object { $_ })) { + Add-Var $v.name $v.value + } + + # URL + $url = $http.url + if ($url) { + $url = $url -replace ':(\w+)', '{{$1}}' + $url = $url.Split('?')[0] + } + + # Params + $queryParams = @() + $headers = @() + + foreach ($h in $http.headers) { + $headers += $h + } + + foreach ($p in $http.params) { + $name = $p.name + $value = $p.value + $type = ($p.type).ToLower() + $disabled = ($p.disabled -eq $true) + + if ($disabled) { + Add-CommentVar $name $value + continue + } + + if ($type -eq 'header') { + $headers += @{ name = $name; value = $value } + } else { + $queryParams += @{ name = $name; value = "{{$name}}" } + Add-ParamVar $name $value + } + } + + # Auth + if ($config.auth) { + switch ($config.auth.type) { + 'bearer' { + $headers += @{ name = 'Authorization'; value = "Bearer $($config.auth.token)" } + } + 'basic' { + $headers += @{ name = 'Authorization'; value = "Basic $($config.auth.username):$($config.auth.password)" } + } + } + } + + # Commented vars + if ($commentVars.Count -gt 0) { + $lines += "# Other variables for $name" + foreach ($v in $commentVars) { + $lines += "# @$($v.name)=$($v.value)" + } + } + + # Parameter vars + if ($paramsVars.Count -gt 0) { + $lines += "# Parameter variables for $name" + foreach ($v in $paramsVars) { + $lines += "@$($v.name)=$($v.value)" + } + } + + # Vars + if ($vars.Count -gt 0) { + $lines += "# Variables for $name" + foreach ($v in $vars) { + $lines += "@$($v.name)=$($v.value)" + } + } + + # Build URL + foreach ($qp in $queryParams) { + $sep = ($url.Contains('?')) ? '&' : '?' + $url = "$url$sep$($qp.name)=$($qp.value)" + } + + $lines += "" + $lines += "$($http.method.ToUpper()) $url" + + foreach ($h in $headers) { + $lines += "$($h.name): $($h.value)" + } + + if ($http.body) { + $lines += "" + $lines += ($http.body.data | ConvertTo-Json -Depth 10) + } + + return ($lines -join "`n") +} + +function Main { + $workspaceRoot = Find-WorkspaceRoot $StartDir + $workspace = Parse-Workspace (Join-Path $workspaceRoot 'workspace.yml') + $collections = $workspace.collections + + $outputBase = Join-Path $workspaceRoot 'autogen/httpyac_ps1' + Clean-Folder $outputBase + + foreach ($col in $collections) { + $sourceDir = Join-Path $workspaceRoot $col.path + if (-not (Test-Path -LiteralPath $sourceDir)) { + Write-Warning "Skipping missing collection path: $($col.path)" + continue + } + + $outputRoot = Join-Path $outputBase $col.name + Ensure-Dir $outputRoot + + # Copy JS + Get-ChildItem $sourceDir -Recurse -File -Include *.js | + ForEach-Object { + $rel = $_.FullName.Substring($sourceDir.Length).TrimStart('\') + $dest = Join-Path $outputRoot $rel + Ensure-Dir (Split-Path -Parent $dest) + Copy-Item $_.FullName $dest -Force + } + + # Env templates + $envDir = Join-Path $sourceDir 'environments' + $dotenvVars = New-Object System.Collections.Generic.HashSet[string] + + if (Test-Path -LiteralPath $envDir) { + $vars = @() + foreach ($f in Get-ChildItem $envDir -File -Include *.yml, *.yaml) { + $parsed = Parse-YamlFile $f.FullName + foreach ($v in ($parsed.variables | Where-Object { $_ })) { + if (-not $dotenvVars.Contains($v.name)) { + $dotenvVars.Add($v.name) | Out-Null + $vars += $v.name + } + } + } + + $template = ($vars | ForEach-Object { "$_=`"EDIT_VALUE_HERE`"" }) -join "`n" + Set-Content -LiteralPath (Join-Path $outputRoot '.env.template') -Value $template + } + + # YAML → .http + $yamlFiles = Walk-YamlFiles $sourceDir + $count = 0 + + foreach ($file in $yamlFiles) { + $content = Get-Content -LiteralPath $file -Raw + $http = Parse-HttpBlock $content + if (-not $http.url) { continue } + + $rel = $file.Substring($sourceDir.Length).TrimStart('\') + $parsed = Split-Path $rel -LeafBase + $dir = Split-Path $rel -Parent + + $targetDir = Join-Path $outputRoot $dir + Ensure-Dir $targetDir + + $requestName = $parsed + $config = @{ variables = @(); auth = $null } + + $dotenv = $dotenvVars + $outFile = Join-Path $targetDir "$parsed.http" + + $reqContent = Build-RequestContent $http $requestName $config $dotenv + Set-Content -LiteralPath $outFile -Value $reqContent + + $count++ + } + + Write-Host ("{0,-33} => generated {1,3} .http file(s)" -f $col.name, $count) + } +} + +Main