feat: 운영 안정성과 세션 음성 경험 개선
This commit is contained in:
parent
facc4ad2d9
commit
c788343467
95 changed files with 8431 additions and 1785 deletions
103
scripts/preserve-pages-assets.ps1
Normal file
103
scripts/preserve-pages-assets.ps1
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue