function Get-PublicEnvValue { param([string]$Content, [string]$Key) $match = [regex]::Match($Content, "(?m)^$([regex]::Escape($Key))=(.*)$") if (-not $match.Success) { return "" } $value = $match.Groups[1].Value.Trim() if ($value.Length -ge 2) { $first = $value.Substring(0, 1) $last = $value.Substring($value.Length - 1, 1) if (($first -eq "'" -and $last -eq "'") -or ($first -eq '"' -and $last -eq '"')) { return $value.Substring(1, $value.Length - 2) } } return $value } function Set-PublicEnvValue { param([string]$Content, [string]$Key, [string]$Value) $pattern = "(?m)^$([regex]::Escape($Key))=.*(?:\r?\n)?" $replacement = "$Key=$Value`r`n" if ([regex]::IsMatch($Content, $pattern)) { return [regex]::Replace($Content, $pattern, $replacement, 1) } if ($Content -and -not $Content.EndsWith("`n")) { $Content += "`r`n" } return $Content + $replacement } function ConvertTo-PublicApiBaseUrl { param([string]$Value) $normalized = if ($null -eq $Value) { "" } else { $Value.Trim().TrimEnd('/') } if (-not $normalized) { return $null } $uri = $null if (-not [Uri]::TryCreate($normalized, [UriKind]::Absolute, [ref]$uri)) { return $null } if ($uri.Scheme -notin @("http", "https")) { return $null } if ($uri.UserInfo -or $uri.Query -or $uri.Fragment) { return $null } if (-not $uri.Host -or $uri.Port -lt 1 -or $uri.Port -gt 65535) { return $null } return $normalized } function Get-DerivedPublicApiBaseUrl { param([string]$Content) $apiUrl = Get-PublicEnvValue $Content "NUXT_PUBLIC_BASE_APIURL" $absoluteApiUrl = ConvertTo-PublicApiBaseUrl $apiUrl if ($absoluteApiUrl) { return $absoluteApiUrl } if (-not $apiUrl.StartsWith('/')) { return $null } $origin = $null $socketUrl = Get-PublicEnvValue $Content "NUXT_PUBLIC_BASE_SOCKETURL" $socketUri = $null if ([Uri]::TryCreate($socketUrl, [UriKind]::Absolute, [ref]$socketUri) -and $socketUri.Scheme -in @("ws", "wss")) { $scheme = if ($socketUri.Scheme -eq "wss") { "https" } else { "http" } $origin = "${scheme}://$($socketUri.Authority)" } if (-not $origin) { $securityOrigin = (Get-PublicEnvValue $Content "CONFIG_SECURITY_ORIGIN").Split(',')[0].Trim() $securityUri = $null if ([Uri]::TryCreate($securityOrigin, [UriKind]::Absolute, [ref]$securityUri) -and $securityUri.Scheme -in @("http", "https")) { $origin = "$($securityUri.Scheme)://$($securityUri.Authority)" } } if (-not $origin) { return $null } return ConvertTo-PublicApiBaseUrl "$($origin.TrimEnd('/'))$apiUrl" } function Initialize-PublicApiBaseUrl { param( [Parameter(Mandatory = $true)][string]$Path, [ValidateSet("configure", "upgrade")][string]$Mode = "upgrade", [string]$Override = $env:DEPLOY_PUBLIC_API_BASE_URL ) if (-not (Test-Path $Path)) { throw "Environment file not found: $Path" } $content = Get-Content $Path -Raw -Encoding UTF8 if ($null -eq $content) { $content = "" } if (-not $Override) { $Override = Get-PublicEnvValue $content "DEPLOY_PUBLIC_API_BASE_URL" } $current = Get-PublicEnvValue $content "CONFIG_PUBLIC_API_BASE_URL" if ($Override) { $selected = ConvertTo-PublicApiBaseUrl $Override if (-not $selected) { throw "Invalid public API base URL: $Override" } } elseif ($current) { if (-not (ConvertTo-PublicApiBaseUrl $current)) { throw "Invalid CONFIG_PUBLIC_API_BASE_URL: $current" } return } else { $selected = Get-DerivedPublicApiBaseUrl $content if (-not $selected) { throw "Cannot derive CONFIG_PUBLIC_API_BASE_URL. Set a full URL such as https://example.com/api" } } $content = Set-PublicEnvValue $content "CONFIG_PUBLIC_API_BASE_URL" $selected [System.IO.File]::WriteAllText( (Resolve-Path $Path), $content, [System.Text.UTF8Encoding]::new($false) ) Write-Host " [OK] Public API base URL: $selected" -ForegroundColor Green }