Release 0.0.17

This commit is contained in:
2026-04-20 22:26:34 +00:00
parent 15ca8078a3
commit 2ab4f4d033
5 changed files with 115 additions and 53 deletions

View File

@@ -267,23 +267,11 @@ function renderGroupedFindingList(groupedFindings, hasAnalysis, loading, showAll
sections.push(renderGroupedSection(
localize("KSA.Section.UnanchoredPackageTargets"),
localize("KSA.Section.UnanchoredPackageTargetsDesc"),
groupedFindings.nonPackageToPackage,
group => `
<article class="storage-audit__finding severity-${group.severity}">
<header>
<span class="storage-audit__severity">${severityLabel(group.severity)}</span>
<strong>${formatCount(group.count, "KSA.Summary.References")}</strong>
</header>
<p><code>${escapeHtml(group.target)}</code></p>
<p>${escapeHtml(group.shortReason)}</p>
<dl>
<div><dt>${localize("KSA.Field.OwnerPackage")}</dt><dd><code>${escapeHtml(group.ownerLabel)}</code></dd></div>
<div><dt>${localize("KSA.Field.Assessment")}</dt><dd>${escapeHtml(group.explanation)}</dd></div>
</dl>
<p class="storage-audit__recommendation">${escapeHtml(group.recommendation)}</p>
${renderSampleSources(group.sources)}
</article>
`
renderGroupedTable(groupedFindings.nonPackageToPackage, {
includeOwner: true,
includeReason: true,
includeSources: true
})
));
}
@@ -291,20 +279,11 @@ function renderGroupedFindingList(groupedFindings, hasAnalysis, loading, showAll
sections.push(renderGroupedSection(
localize("KSA.Section.BrokenTargets"),
localize("KSA.Section.BrokenTargetsDesc"),
groupedFindings.brokenReferences,
group => `
<article class="storage-audit__finding severity-${group.severity}">
<header>
<span class="storage-audit__severity">${severityLabel(group.severity)}</span>
<strong>${formatCount(group.count, "KSA.Summary.References")}</strong>
</header>
<p><code>${escapeHtml(group.target)}</code></p>
<p>${escapeHtml(group.shortReason)}</p>
${group.targetKind === "wildcard" ? `<p>${localize("KSA.Finding.WildcardNoMatch")}</p>` : ""}
<p class="storage-audit__recommendation">${escapeHtml(group.recommendation)}</p>
${renderSampleSources(group.sources)}
</article>
`
renderGroupedTable(groupedFindings.brokenReferences, {
includeOwner: false,
includeReason: true,
includeSources: true
})
));
}
@@ -312,18 +291,11 @@ function renderGroupedFindingList(groupedFindings, hasAnalysis, loading, showAll
sections.push(renderGroupedSection(
localize("KSA.Section.OrphanCandidates"),
localize("KSA.Section.OrphanCandidatesDesc"),
groupedFindings.orphans,
group => `
<article class="storage-audit__finding severity-${group.severity}">
<header>
<span class="storage-audit__severity">${severityLabel(group.severity)}</span>
<code>${humanizeKind(group.kind)}</code>
</header>
<p><code>${escapeHtml(group.target)}</code></p>
<p>${escapeHtml(group.reason)}</p>
<p class="storage-audit__recommendation">${escapeHtml(group.recommendation)}</p>
</article>
`
renderGroupedTable(groupedFindings.orphans, {
includeOwner: false,
includeReason: true,
includeSources: false
})
));
}
@@ -341,19 +313,60 @@ function renderGroupedFindingList(groupedFindings, hasAnalysis, loading, showAll
return `<section class="storage-audit__grouped">${sections.join("")}</section>`;
}
function renderGroupedSection(title, description, groups, renderGroup) {
const items = groups.map(renderGroup).join("");
function renderGroupedSection(title, description, content) {
return `
<section class="storage-audit__group">
<div class="storage-audit__group-header">
<h3>${title}</h3>
<p>${description}</p>
</div>
<div class="storage-audit__list">${items}</div>
<div class="storage-audit__table-wrap">${content}</div>
</section>
`;
}
function renderGroupedTable(groups, { includeOwner=false, includeReason=false, includeSources=false }={}) {
const headers = [
`<th>${localize("KSA.Table.Severity")}</th>`,
`<th>${localize("KSA.Field.Target")}</th>`,
`<th>${localize("KSA.Table.References")}</th>`
];
if (includeOwner) headers.push(`<th>${localize("KSA.Field.OwnerPackage")}</th>`);
if (includeReason) headers.push(`<th>${localize("KSA.Table.Note")}</th>`);
if (includeSources) headers.push(`<th>${localize("KSA.Field.Source")}</th>`);
const rows = groups.map(group => {
const cells = [
`<td><span class="storage-audit__severity storage-audit__severity--inline severity-${group.severity}">${severityLabel(group.severity)}</span></td>`,
`<td><code>${escapeHtml(group.target)}</code></td>`,
`<td>${group.count ?? ""}</td>`
];
if (includeOwner) cells.push(`<td><code>${escapeHtml(group.ownerLabel ?? "")}</code></td>`);
if (includeReason) {
const note = group.targetKind === "wildcard"
? `${group.shortReason ?? group.reason ?? ""} ${localize("KSA.Finding.WildcardNoMatch")}`
: (group.shortReason ?? group.reason ?? "");
cells.push(`<td>${escapeHtml(note.trim())}</td>`);
}
if (includeSources) {
cells.push(`<td>${renderGroupedSourcesCell(group.sources ?? [])}</td>`);
}
return `<tr>${cells.join("")}</tr>`;
}).join("");
return `
<table class="storage-audit__table">
<thead><tr>${headers.join("")}</tr></thead>
<tbody>${rows}</tbody>
</table>
`;
}
function renderGroupedSourcesCell(sources) {
if (!sources.length) return "";
return `<div class="storage-audit__source-list">${sources.map(source => `<div>${source.renderedSource ?? renderPlainSourceLabel(source)}</div>`).join("")}</div>`;
}
function renderFindingList(findings, hasAnalysis, loading, showAll, showRaw) {
if (loading) {
return `<section class="storage-audit__list"><p>${localize("KSA.Section.Running")}</p></section>`;
@@ -391,12 +404,6 @@ function renderFindingList(findings, hasAnalysis, loading, showAll, showRaw) {
`;
}
function renderSampleSources(sources) {
if (!sources.length) return "";
const rows = sources.map(source => `<li>${source.renderedSource ?? renderPlainSourceLabel(source)}</li>`).join("");
return `<div class="storage-audit__samples"><span>${localize("KSA.Section.Samples")}</span><ul>${rows}</ul></div>`;
}
function groupFindings(findings) {
return {
brokenReferences: groupByTarget(findings.filter(f => f.kind === "broken-reference")),