103 lines
3.2 KiB
PowerShell
103 lines
3.2 KiB
PowerShell
param(
|
|
[string]$DistPath = "D:\workspace\vignette\apps\web\dist",
|
|
[string[]]$DeploymentBases = @(
|
|
"https://1b3b6d5b.vignette-b1q.pages.dev",
|
|
"https://0a339b77.vignette-b1q.pages.dev",
|
|
"https://f323a41d.vignette-b1q.pages.dev",
|
|
"https://1332ccbe.vignette-b1q.pages.dev",
|
|
"https://564dbed9.vignette-b1q.pages.dev"
|
|
)
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
|
|
$OutputEncoding = [System.Text.UTF8Encoding]::new($false)
|
|
|
|
$distRoot = [IO.Path]::GetFullPath((Resolve-Path -LiteralPath $DistPath).Path)
|
|
$distPrefix = $distRoot.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
|
|
$totalAdded = 0
|
|
|
|
function Resolve-DistTarget {
|
|
param([string]$AssetPath)
|
|
|
|
$relative = $AssetPath.TrimStart("/").Replace("/", [IO.Path]::DirectorySeparatorChar)
|
|
$target = [IO.Path]::GetFullPath((Join-Path $distRoot $relative))
|
|
if (!$target.StartsWith($distPrefix, [StringComparison]::OrdinalIgnoreCase)) {
|
|
throw "Asset target escaped the deployment directory: $AssetPath"
|
|
}
|
|
return $target
|
|
}
|
|
|
|
foreach ($base in $DeploymentBases) {
|
|
$origin = $base.TrimEnd("/")
|
|
$seen = [System.Collections.Generic.HashSet[string]]::new(
|
|
[System.StringComparer]::OrdinalIgnoreCase
|
|
)
|
|
$queue = [System.Collections.Generic.Queue[string]]::new()
|
|
$html = (
|
|
Invoke-WebRequest `
|
|
-Uri "$origin/login?preserve=$([guid]::NewGuid().ToString('N'))" `
|
|
-UseBasicParsing `
|
|
-TimeoutSec 30
|
|
).Content
|
|
|
|
foreach ($match in [regex]::Matches(
|
|
$html,
|
|
'(?:src|href)="(/assets/[^\"]+\.(?:js|css))"'
|
|
)) {
|
|
$queue.Enqueue($match.Groups[1].Value)
|
|
}
|
|
|
|
$added = 0
|
|
while ($queue.Count -gt 0) {
|
|
$asset = $queue.Dequeue()
|
|
if (!$seen.Add($asset)) {
|
|
continue
|
|
}
|
|
|
|
$target = Resolve-DistTarget -AssetPath $asset
|
|
$parent = Split-Path -Parent $target
|
|
if (!(Test-Path -LiteralPath $parent)) {
|
|
New-Item -ItemType Directory -Path $parent -Force | Out-Null
|
|
}
|
|
|
|
$download = "$target.download"
|
|
$response = Invoke-WebRequest `
|
|
-Uri "$origin$asset" `
|
|
-UseBasicParsing `
|
|
-TimeoutSec 30 `
|
|
-OutFile $download `
|
|
-PassThru
|
|
$contentType = [string]$response.Headers["Content-Type"]
|
|
if ($asset.EndsWith(".js") -and $contentType -notmatch "javascript") {
|
|
Remove-Item -LiteralPath $download -Force
|
|
throw "Expected JavaScript response: $origin$asset ($contentType)"
|
|
}
|
|
if ($asset.EndsWith(".css") -and $contentType -notmatch "text/css") {
|
|
Remove-Item -LiteralPath $download -Force
|
|
throw "Expected CSS response: $origin$asset ($contentType)"
|
|
}
|
|
|
|
if (Test-Path -LiteralPath $target) {
|
|
Remove-Item -LiteralPath $download -Force
|
|
} else {
|
|
Move-Item -LiteralPath $download -Destination $target
|
|
$added += 1
|
|
$totalAdded += 1
|
|
}
|
|
|
|
if ($asset -match '\.(?:js|css)$') {
|
|
$source = Get-Content -LiteralPath $target -Raw -Encoding UTF8
|
|
foreach ($match in [regex]::Matches(
|
|
$source,
|
|
'(?:(?:/assets/)|(?:\./))([A-Za-z0-9_.-]+\.(?:js|css))'
|
|
)) {
|
|
$queue.Enqueue("/assets/$($match.Groups[1].Value)")
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-Output "Preserved $origin (graph=$($seen.Count), added=$added)"
|
|
}
|
|
|
|
Write-Output "Total previous deployment assets added: $totalAdded"
|