function assertNoRedirect(response, label) {
if (response.status >= 300 && response.status < 400) {
throw new Error(`${label} redirected; deployment verification fails closed on redirects`)
}
}
async function fetchChecked(fetchImpl, url, label, timeoutMs) {
const signal = AbortSignal.timeout(timeoutMs)
let response
try {
response = await fetchImpl(url, { redirect: 'manual', signal })
} catch (error) {
if (signal.aborted) {
throw new Error(`${label} timed out after ${timeoutMs}ms`, { cause: error })
}
throw error
}
assertNoRedirect(response, label)
if (!response.ok) {
throw new Error(`${label} request failed with ${response.status}`)
}
return response
}
function collectLocalAssets(html, origin) {
const candidates = []
let hasExecutableBootstrap = false
const attribute = (tag, name) => tag.match(new RegExp(`\\b${name}=["']([^"']+)["']`, 'i'))?.[1]
for (const match of html.matchAll(/]*>/gi)) {
const tag = match[0]
const rel = attribute(tag, 'rel')?.toLowerCase().split(/\s+/) ?? []
const href = attribute(tag, 'href')
if (href && (rel.includes('stylesheet') || rel.includes('modulepreload'))) {
candidates.push({ href, kind: rel.includes('stylesheet') ? 'stylesheet' : 'preload' })
}
}
for (const match of html.matchAll(/