Files
api-collections/scripts/generate-http-docs.ps1
T

930 lines
30 KiB
PowerShell

#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 from the provided start directory"
}
$current = $parent
}
}
function Parse-Yaml($text) {
try {
$parsedYaml = ConvertFrom-Yaml $text
return $parsedYaml ?? @{}
} catch {
throw "Failed to parse YAML content : $_"
}
}
function Parse-YamlFile($path) {
return Parse-Yaml (Get-Content -LiteralPath $path -Raw)
}
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"))) { # && trimmed?
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 Sanitize-VarName($name) {
$sanitized = ([string]$name).Trim() -replace '[{}]', '' -replace '[^A-Za-z0-9_]', '_' -replace '^([0-9])', '_$1'
if ([string]::IsNullOrWhiteSpace($sanitized)) {
return 'value'
}
return $sanitized
}
function Parse-PlaceholderContent($content) {
$trimmed = ([string]$content).Trim();
$dotenvMatch = [regex]::Match($trimmed, '^\$dotenv\s+(.+)$', 'IgnoreCase')
if ($dotenvMatch.Success) {
return @{
name = $dotenvMatch.Groups[1].value.Trim()
isDotenv = $true
}
}
return @{
name = $trimmed
isDotenv = $false
}
}
function Collect-Placeholders($value) {
# Se non è stringa → restituisci array vuoto
if ($value -isnot [string]) {
return @()
}
$placeholders = @()
$regex = [regex]'\{\{([^{}]+)\}\}'
$foundMatches = $regex.Matches($value)
foreach ($m in $foundMatches) {
$inner = $m.Groups[1].value
$parsed = Parse-PlaceholderContent $inner
$placeholders += $parsed.name
}
return $placeholders
}
function Find-Block ([string[]]$lines, $keyName) {
for ($i = 0; $i -lt $lines.Count; $i++) {
$trimmed = $lines[$i].Trim()
if ($trimmed -ne $keyName -and -not $trimmed.StartsWith("$($keyName):")) {
continue
}
$lineIndent = ([regex]::Match($lines[$i], '^\s*')).value.Length
$block = @()
for ($j = $i + 1; $j -lt $lines.Count; $j++) {
$currentLine = $lines[$j]
$currentTrimmed = $currentLine.Trim()
if ([string]::IsNullOrWhiteSpace($currentTrimmed)) {
$block += $currentLine
continue
}
$currentIndent = ([regex]::Match($currentLine, '^\s*')).value.Length
# Caso 1: indentazione <= indentazione della chiave e NON inizia con spazio → fine blocco
if ($currentIndent -le $lineIndent -and -not $currentLine.StartsWith(' ')) {
break
}
# Caso 2: indentazione <= indentazione della chiave e riga commento → includi
if ($currentIndent -le $lineIndent -and $currentTrimmed.StartsWith('#')) {
$block += $currentLine
continue
}
# Caso 3: indentazione <= indentazione della chiave → fine blocco
if ($currentIndent -le $lineIndent) {
break
}
# Altrimenti la riga fa parte del blocco
$block += $currentLine
}
return $block
}
return @()
}
function Parse-RequestInfo ($text) {
$lines = $text -split '\r?\n'
$infoLines = Find-Block -Lines $lines -KeyName 'info'
$joined = ($infoLines -join "`n")
$nameMatch = [regex]::Match($joined, '^\s*name:\s*(.+)$', 'Multiline')
if ($nameMatch.Success) {
return Strip-Quotes $nameMatch.Groups[1].value
}
return ''
}
function Parse-HttpBlock ($text) {
# ConvertFrom-Yaml restituisce $null se il testo è vuoto o non valido
$parsed = Parse-Yaml $text
if (-not $parsed) { $parsed = @{} }
$http = $parsed.http
if (-not $http) { $http = @{} }
$headers = @()
$headerList = @()
if ($http.headers -is [System.Collections.IEnumerable]) {
$headerList = $http.headers
}
foreach ($header in $headerList) {
if (-not $header -or $header -isnot [psobject] -and $header -isnot [hashtable]) {
continue
}
$name = ([string]($header.name ?? '')).Trim()
$value = ([string]($header.value ?? '')).Trim()
$headers += @{
name = $name
value = $value
}
}
$params = @()
if ($http.params -is [System.Collections.IEnumerable]) {
$params = $http.params
}
$body = $null
if ($http.body -and ($http.body -is [psobject] -or $http.body -is [hashtable])) {
$body = $http.body
}
return @{
method = $http.method ?? 'GET'
url = $http.url ?? ''
params = $params
headers = $headers
body = $body
}
}
function Format-VariableValue ($value, [hashtable]$RenderContext = @{}) {
if ($null -eq $value) {
return "''"
}
if ($value -is [string]) {
if ($value.Trim() -eq '') {
return "''"
}
$renderedValue = $value
if ($RenderContext.ContainsKey('renderValue') -and $RenderContext.renderValue) {
$renderedValue = $RenderContext.renderValue.Invoke($value)
}
if ($renderedValue -match '\s') {
$escaped = $renderedValue -replace '"', '\"'
return '"' + $escaped + '"'
}
return $renderedValue
}
return ($value | ConvertTo-Json -Depth 20 -Compress)
}
function Merge-RequestConfig ($base, $updates) {
if (-not $updates -or ($updates -isnot [psobject] -and $updates -isnot [hashtable])) {
return $base
}
# Clona base (shallow clone)
$merged = @{}
if ($base -is [psobject] -or $base -is [hashtable]) {
foreach ($key in $base.Keys) {
$merged[$key] = $base[$key]
}
}
if ($updates.ContainsKey('auth')) {
$auth = $updates.auth
if ($auth -eq 'inherit') {
if ($merged.ContainsKey('auth') -and ($merged.auth -is [psobject] -or $merged.auth -is [hashtable])) {
$merged.auth = $merged.auth
}
else {
$merged.Remove('auth')
}
}
elseif ($auth -is [psobject] -or $auth -is [hashtable]) {
$merged.auth = $auth
}
else {
$merged.Remove('auth')
}
}
else {
$merged.Remove('auth')
}
if ($updates.variables -is [System.Collections.IEnumerable]) {
$variables = @()
if ($base.variables -is [System.Collections.IEnumerable]) {
$variables = @($base.variables)
}
# Mappa per nome
$byName = @{}
foreach ($variable in $variables) {
if ($variable -and $variable.name) {
$byName[[string]$variable.name] = $variable
}
}
foreach ($variable in $updates.variables) {
if ($variable -and $variable.name) {
$byName[[string]$variable.name] = $variable
}
}
$merged.variables = $byName.Values
}
return $merged
}
function Get-RequestConfigForFile ($yamlFile, $sourceDir) {
$resolved = @()
$seenFiles = New-Object System.Collections.Generic.HashSet[string]
function Add-File ($FilePath) {
if (-not $FilePath -or $seenFiles.Contains($FilePath)) {
return
}
$seenFiles.Add($FilePath)
if (-not (Test-Path $FilePath)) {
return
}
try {
$parsed = (Get-Content -Raw $FilePath | ConvertFrom-Yaml)
if (-not $parsed) { $parsed = @{} }
$requestConfig = $null
# Caso 1: parsed.request esiste ed è un oggetto
if ($parsed.request -and ($parsed.request -is [psobject] -or $parsed.request -is [hashtable])) {
$requestConfig = $parsed.request
}
# Caso 2: parsed è un oggetto e contiene auth/variables
elseif ($parsed -is [psobject] -or $parsed -is [hashtable]) {
$config = @{}
# auth
if ($parsed.ContainsKey('auth')) {
$config.auth = $parsed.auth
}
elseif ($parsed.http -and ($parsed.http -is [psobject] -or $parsed.http -is [hashtable]) -and $parsed.http.ContainsKey('auth')) {
$config.auth = $parsed.http.auth
}
# variables
if ($parsed.variables -is [System.Collections.IEnumerable]) {
$config.variables = $parsed.variables
}
if ($config.Count -gt 0) {
$requestConfig = $config
}
}
if ($null -ne $requestConfig) {
$resolved += $requestConfig
}
elseif ((Resolve-Path $FilePath).Path -eq (Resolve-Path $yamlFile).Path) {
$resolved += @{}
}
}
catch {
# Ignora file YAML non validi
}
}
# Costruisci la catena delle directory
$dirChain = @()
$currentDir = Split-Path -Parent $yamlFile
while ($true) {
$dirChain = ,$currentDir + $dirChain
if ($currentDir -eq $sourceDir) {
break
}
$parentDir = Split-Path -Parent $currentDir
if ($parentDir -eq $currentDir) {
break
}
$currentDir = $parentDir
}
foreach ($dir in $dirChain) {
Add-File (Join-Path $dir 'opencollection.yml')
Add-File (Join-Path $dir 'folder.yml')
}
# Aggiungi il file principale
Add-File $yamlFile
$result = @{}
foreach ($config in $resolved) {
$result = Merge-RequestConfig $result $config
}
return $result
}
function Build-RequestContent (
$request,
$requestName,
$requestConfig = @{},
[System.Collections.Generic.HashSet[string]]$dotenvVariables = $(New-Object System.Collections.Generic.HashSet[string])
) {
$lines = @()
$variableDefinitions = @()
$commentedVariableDefinitions = @()
$parameterVariableDefinitions = @()
$seenVariables = New-Object System.Collections.Generic.HashSet[string]
function Add-Variable ($Name, $Value) {
if (-not $Name) { return }
$normalized = ([string]$Name).Trim()
if (-not $normalized) { return }
if ($seenVariables.Contains($normalized)) { return }
if ($dotenvVariables.Contains($normalized)) { return }
$seenVariables.Add($normalized)
$variableDefinitions += @{ name=$normalized; value=$Value }
}
function Add-ParameterVariable ($Name, $Value) {
if (-not $Name) { return }
$normalized = ([string]$Name).Trim()
if (-not $normalized) { return }
if ($seenVariables.Contains($normalized)) { return }
if ($dotenvVariables.Contains($normalized)) { return }
$seenVariables.Add($normalized)
$parameterVariableDefinitions += @{ name=$normalized; value=$Value }
}
function Add-CommentedVariable ($Name, $Value) {
if (-not $Name) { return }
$normalized = ([string]$Name).Trim()
if (-not $normalized) { return }
$commentedVariableDefinitions += @{ name=$normalized; value=$Value }
}
function Add-ReferencedVariables ($Value, $FallbackValue = 'YOUR_VALUE_HERE') {
foreach ($placeholder in Collect-Placeholders ([string]$Value)) {
Add-Variable $placeholder $FallbackValue
}
}
function RenderJsonValue ($Value) {
if ($Value -is [string]) {
return Render-Value $Value
}
elseif ($Value -is [System.Collections.IEnumerable]) {
return @($Value | ForEach-Object { RenderJsonValue $_ })
}
elseif ($Value -is [psobject] -or $Value -is [hashtable]) {
$result = @{}
foreach ($key in $Value.Keys) {
$result[$key] = RenderJsonValue $Value[$key]
}
return $result
}
return $Value
}
function Add-ParameterVariables ($Name, $Value) { Add-ParameterVariable $Name $Value }
function Add-CommentedVariables ($Name, $Value) { Add-CommentedVariable $Name $Value }
function Render-Value ($Value) {
if ($Value -isnot [string]) { return $Value }
return ($Value -replace '\{\{([^{}]+)\}\}', {
param($match,$inner)
$placeholder = Parse-PlaceholderContent $inner
if ($placeholder.isDotenv) { return $match }
if ($placeholder.name -and $dotenvVariables.Contains($placeholder.name)) {
return "{{$dotenv $($placeholder.name)}}"
}
return $match
})
}
# -------------------------
# Variabili da requestConfig
# -------------------------
$configVariables = @()
if ($requestConfig.variables -is [System.Collections.IEnumerable]) {
$configVariables = $requestConfig.variables
}
foreach ($variable in $configVariables) {
if ($variable -and $variable.name) {
Add-Variable $variable.name $variable.value
}
}
# -------------------------
# URL
# -------------------------
$url = $request.url ?? ''
if ($url) {
Add-ReferencedVariables $url
$url = ($url -replace ':([A-Za-z0-9_]+)', '{{$1}}')
$url = Render-Value $url
$url = $url.Split('?')[0]
}
# -------------------------
# Headers
# -------------------------
$queryParams = @()
$headers = @()
function Add-Header ($Name, $Value) {
if (-not $Name) { return }
Add-ReferencedVariables ($Value ?? '')
$headers += @{
name = ([string]$Name).Trim()
value = Render-Value ($Value ?? '')
}
}
foreach ($header in ($request.headers ?? @())) {
if ($header -and $header.name) {
Add-Header $header.name ($header.value ?? '')
}
}
foreach ($header in ($requestConfig.headers ?? @())) {
if ($header -and $header.name) {
Add-Header $header.name ($header.value ?? '')
}
}
# -------------------------
# Params
# -------------------------
foreach ($param in ($request.params ?? @())) {
$name = $param.name ?? ''
$value = $param.value ?? ''
$type = ([string]($param.type ?? 'query')).ToLower()
$disabled = ([string]$param.disabled).ToLower() -eq 'true'
if ($disabled) {
Add-CommentedVariables $name $value
continue
}
Add-ReferencedVariables $value
if ($type -eq 'header') {
$headers += @{ name=$name; value=(Render-Value $value) }
}
else {
$queryParams += @{ name=$name; value="{{$name}}" }
Add-ParameterVariables $name $value
}
}
# -------------------------
# Auth
# -------------------------
if ($requestConfig.auth) {
switch ($requestConfig.auth.type) {
'bearer' {
Add-ReferencedVariables ($requestConfig.auth.token ?? '')
Add-Header 'Authorization' ("Bearer " + (Render-Value ($requestConfig.auth.token ?? '')))
}
'basic' {
$username = $requestConfig.auth.username ?? ''
$password = $requestConfig.auth.password ?? ''
Add-ReferencedVariables $username
Add-ReferencedVariables $password
Add-Header 'Authorization' ("Basic " + (Render-Value $username) + ":" + (Render-Value $password))
}
default {
$headers += @{
name = "UNKNOWN_$($requestConfig.auth.type)"
value = "Basic $($requestConfig.auth.token)"
}
}
}
}
# -------------------------
# Commented variables
# -------------------------
if ($commentedVariableDefinitions.Count -gt 0) {
$lines += "# Other variables for $requestName"
foreach ($variable in $commentedVariableDefinitions) {
$lines += "# @$(Sanitize-VarName $variable.name)$VARIABLE_NAME_VALUE_SEPARATOR$(Format-VariableValue $variable.value @{ renderValue = { param($v) Render-Value $v } })"
}
}
# -------------------------
# Parameter variables
# -------------------------
if ($parameterVariableDefinitions.Count -gt 0) {
$lines += "# Parameter variables for $requestName"
foreach ($variable in $parameterVariableDefinitions) {
$lines += "@$(Sanitize-VarName $variable.name)$VARIABLE_NAME_VALUE_SEPARATOR$(Format-VariableValue $variable.value @{ renderValue = { param($v) Render-Value $v } })"
}
}
# -------------------------
# Body
# -------------------------
$requestBody = ''
if ($request.body -and ($request.body -is [psobject] -or $request.body -is [hashtable])) {
$bodyType = ([string]($request.body.type ?? '')).ToLower()
if ($bodyType -eq 'json') {
$jsonData = ConvertFrom-Json -Depth 20 -InputObject ($request.body.data)
if ($jsonData -is [string]) {
$requestBody = Render-Value $jsonData
}
elseif ($jsonData -is [System.Collections.IEnumerable]) {
$requestBody = (ConvertTo-Json (RenderJsonValue $jsonData) -Depth 20)
}
elseif ($jsonData -is [psobject] -or $jsonData -is [hashtable]) {
$requestBody = (ConvertTo-Json (RenderJsonValue $jsonData) -Depth 20)
}
Add-Header 'Content-Type' 'application/json'
}
elseif ($bodyType -eq 'form-urlencoded') {
$parts = @()
foreach ($entry in ($request.body.data ?? @())) {
if (-not $entry -or -not $entry.name) { continue }
Add-ReferencedVariables ($entry.value ?? '')
$parts += "$($entry.name)=$(Render-Value ($entry.value ?? ''))"
}
$requestBody = ($parts -join '&')
Add-Header 'Content-Type' 'application/x-www-form-urlencoded'
}
}
# -------------------------
# Variables
# -------------------------
if ($variableDefinitions.Count -gt 0) {
$lines += "# Variables for $requestName"
foreach ($variable in $variableDefinitions) {
$lines += "@$(Sanitize-VarName $variable.name)$VARIABLE_NAME_VALUE_SEPARATOR$(Format-VariableValue $variable.value @{ renderValue = { param($v) Render-Value $v } })"
}
}
# -------------------------
# Final request line
# -------------------------
$method = ([string]($request.method ?? 'GET')).ToUpper()
$requestUrl = $url
foreach ($param in $queryParams) {
if (-not $param.name) { continue }
$separator = ($requestUrl.Contains('?') ? '&' : '?')
$requestUrl = "$requestUrl$separator$($param.name)=$($param.value)"
}
$lines += ''
$lines += "$method $requestUrl"
foreach ($header in $headers) {
$lines += "$($header.name): $($header.value)"
}
if ($requestBody) {
$lines += ''
$lines += $requestBody
}
return ($lines -join "`n")
}
function Ensure-Dir($path) {
if (-not (Test-Path -LiteralPath $path)) {
New-Item -ItemType Directory -Path $path | Out-Null
}
}
function Walk-YamlFiles($rootDir) {
Get-ChildItem -LiteralPath $rootDir -Recurse -File -Include *.yml, *.yaml |
Where-Object { $_.Name -notmatch '^\.|node_modules' } |
Select-Object -ExpandProperty FullName
}
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 Get-DotenvVariablesForTargetDir ($TargetDir, $OutputRoot, $DotenvVariablesByTarget) {
$variables = New-Object System.Collections.Generic.HashSet[string]
$currentDir = $TargetDir
while ($true) {
if ($DotenvVariablesByTarget.ContainsKey($currentDir)) {
foreach ($variable in $DotenvVariablesByTarget[$currentDir]) {
$variables.Add($variable) | Out-Null
}
}
$parentDir = Split-Path -Parent $currentDir
if ($currentDir -eq $OutputRoot -or $parentDir -eq $currentDir) {
break
}
$currentDir = $parentDir
}
return $variables
}
function Write-EnvironmentTemplates ($sourceDir, $outputRoot) {
$targets = @()
$dotenvVariablesByTarget = @{} # Hashtable: targetDir → HashSet
function Visit ([string]$CurrentDir) {
$entries = Get-ChildItem -LiteralPath $CurrentDir -Force
$hasEnvironmentsDir = $entries | Where-Object {
$_.PSIsContainer -and $_.Name -eq 'environments'
}
if ($hasEnvironmentsDir) {
$targets += $CurrentDir
}
foreach ($entry in $entries) {
if (-not $entry.PSIsContainer) { continue }
if ($entry.Name.StartsWith('.')) { continue }
if ($entry.Name -eq 'node_modules') { continue }
Visit (Join-Path $CurrentDir $entry.Name)
}
}
Visit $sourceDir
foreach ($dir in $targets) {
$relativeDir = [System.IO.Path]::GetRelativePath($sourceDir, $dir)
if ($relativeDir -and $relativeDir -ne '.') {
$targetDir = Join-Path $outputRoot $relativeDir
}
else {
$targetDir = $outputRoot
}
Ensure-Dir $targetDir
$environmentsDir = Join-Path $dir 'environments'
if (-not (Test-Path $environmentsDir)) {
continue
}
$envFiles =
Get-ChildItem -LiteralPath $environmentsDir -Force |
Where-Object { -not $_.PSIsContainer -and $_.Name -match '\.ya?ml$' } |
ForEach-Object { $_.FullName }
$variableNames = @()
$seenNames = New-Object System.Collections.Generic.HashSet[string]
foreach ($envFile in $envFiles) {
$parsed = Parse-Yaml $envFile
if (-not $parsed) { continue }
$variables = @()
if ($parsed.variables -is [System.Collections.IEnumerable]) {
$variables = $parsed.variables
}
foreach ($variable in $variables) {
if (-not $variable -or -not $variable.name) { continue }
$name = ([string]$variable.name).Trim()
if (-not $name) { continue }
if ($seenNames.Contains($name)) { continue }
$seenNames.Add($name)
$variableNames += $name
}
}
if ($variableNames.Count -gt 0) {
$templateContent = ($variableNames | ForEach-Object { "$_=$DEFAULT_ENV_VAR_VALUE" }) -join "`n"
$templateContent += "`n"
}
else {
$templateContent = ""
}
$templatePath = Join-Path $targetDir '.env.template'
Set-Content -Path $templatePath -Value $templateContent -Encoding UTF8
$dotenvVariablesByTarget[$targetDir] = $seenNames
}
return $dotenvVariablesByTarget
}
function Write-JsFiles ($sourceDir, $outputRoot) {
$targets = @()
function Visit ($CurrentDir) {
$entries = Get-ChildItem -LiteralPath $CurrentDir -Force
$hasJsFiles = $entries | Where-Object {
-not $_.PSIsContainer -and $_.Name -match '\.js$'
}
if ($hasJsFiles) {
$targets += $CurrentDir
}
# Visita ricorsivamente le sottodirectory
foreach ($entry in $entries) {
if (-not $entry.PSIsContainer) { continue }
if ($entry.Name.StartsWith('.')) { continue }
if ($entry.Name -eq 'node_modules') { continue }
Visit (Join-Path $CurrentDir $entry.Name)
}
}
Visit $sourceDir
foreach ($dir in $targets) {
$relativeDir = [System.IO.Path]::GetRelativePath($sourceDir, $dir)
if ($relativeDir -and $relativeDir -ne '.') {
$targetDir = Join-Path $outputRoot $relativeDir
}
else {
$targetDir = $outputRoot
}
Ensure-Dir $targetDir
if (-not (Test-Path $dir)) {
continue
}
$jsFiles =
Get-ChildItem -LiteralPath $dir -Force |
Where-Object { -not $_.PSIsContainer -and $_.Name -match '\.js$' } |
ForEach-Object {
@{
Source = $_.FullName
Target = Join-Path $targetDir $_.Name
}
}
foreach ($jsFile in $jsFiles) {
Copy-Item -LiteralPath $jsFile.Source -Destination $jsFile.Target -Force
}
}
return $targets
}
function Invoke-Main {
# Workspace root
$workspaceRoot = Find-WorkspaceRoot $PSScriptRoot
$workspaceFile = Join-Path $workspaceRoot 'workspace.yml'
$workspace = Parse-Workspace $workspaceFile
$collections = @()
if ($workspace.collections -is [System.Collections.IEnumerable]) {
$collections = $workspace.collections
}
if ($collections.Count -eq 0) {
throw "No collections found in workspace.yml"
}
$outputBaseRoot = Join-Path $workspaceRoot 'autogen/httpyac'
Clean-Folder $outputBaseRoot
foreach ($collection in $collections) {
if (-not $collection -or -not $collection.name -or -not $collection.path) {
continue
}
$sourceDir = Join-Path $workspaceRoot $collection.path
if (-not (Test-Path $sourceDir)) {
Write-Warning "Skipping missing collection path: $($collection.path)"
continue
}
$outputRoot = Join-Path $outputBaseRoot $collection.name
Ensure-Dir $outputRoot
# JS files
$writtenJsFiles = Write-JsFiles $sourceDir $outputRoot
# dotenv templates
$dotenvVariablesByTarget = Write-EnvironmentTemplates $sourceDir $outputRoot
# YAML files
$yamlFiles = Walk-YamlFiles $sourceDir
$processed = 0
foreach ($yamlFile in $yamlFiles) {
$content = Get-Content -LiteralPath $yamlFile -Raw
$requestName = Parse-RequestInfo $content
if (-not $requestName) {
$requestName = [System.IO.Path]::GetFileNameWithoutExtension($yamlFile)
}
$httpBlock = Parse-HttpBlock $content
if (-not $httpBlock -or -not $httpBlock.url) {
continue
}
$relativePath = [System.IO.Path]::GetRelativePath($sourceDir, $yamlFile)
$parsedPath = [System.IO.Path]::GetFileNameWithoutExtension($relativePath)
$parsedDir = Split-Path $relativePath -Parent
$targetDir = Join-Path $outputRoot $parsedDir
Ensure-Dir $targetDir
$requestConfig = Get-RequestConfigForFile $yamlFile $sourceDir
$outputFile = Join-Path $targetDir ("$parsedPath.http")
$dotenvVariables = Get-DotenvVariablesForTargetDir $targetDir $outputRoot $dotenvVariablesByTarget
$requestContent = Build-RequestContent $httpBlock $requestName $requestConfig $dotenvVariables
Set-Content -Path $outputFile -Value ($requestContent + "`n") -Encoding UTF8
$processed++
}
$namePadded = $collection.name.PadRight(33)
$httpCount = $processed.ToString().PadLeft(3)
$jsCount = $writtenJsFiles.Count.ToString().PadLeft(3)
Write-Host "$namePadded => generated $httpCount .http file(s) and $jsCount .js file(s)"
}
}
Invoke-Main