Release 0.0.17
This commit is contained in:
@@ -76,6 +76,11 @@
|
||||
"Target": "Ziel",
|
||||
"Source": "Quelle"
|
||||
},
|
||||
"Table": {
|
||||
"Severity": "Stufe",
|
||||
"References": "Refs",
|
||||
"Note": "Hinweis"
|
||||
},
|
||||
"FindingKind": {
|
||||
"non-package-to-package-reference": "Unverankerte Paketziele",
|
||||
"broken-reference": "Kaputte Ziele",
|
||||
|
||||
@@ -76,6 +76,11 @@
|
||||
"Target": "Target",
|
||||
"Source": "Source"
|
||||
},
|
||||
"Table": {
|
||||
"Severity": "Severity",
|
||||
"References": "Refs",
|
||||
"Note": "Note"
|
||||
},
|
||||
"FindingKind": {
|
||||
"non-package-to-package-reference": "Unanchored package targets",
|
||||
"broken-reference": "Broken targets",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"id": "kosmos-storage-audit",
|
||||
"title": "Kosmos Storage Audit",
|
||||
"description": "Analyzes media references and risky storage locations across Foundry data and public roots.",
|
||||
"version": "0.0.16",
|
||||
"version": "0.0.17",
|
||||
"compatibility": {
|
||||
"minimum": "13",
|
||||
"verified": "13"
|
||||
|
||||
@@ -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")),
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.storage-audit__table-wrap {
|
||||
padding: 0 1.1rem 1.1rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.storage-audit__progress {
|
||||
padding: 1rem 1.1rem;
|
||||
}
|
||||
@@ -194,6 +199,42 @@
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.storage-audit__table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.storage-audit__table th,
|
||||
.storage-audit__table td {
|
||||
padding: 0.55rem 0.5rem;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
border-top: 1px solid color-mix(in srgb, currentColor 10%, transparent);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.storage-audit__table thead th {
|
||||
border-top: 0;
|
||||
opacity: 0.75;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.storage-audit__table td:first-child,
|
||||
.storage-audit__table th:first-child {
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
.storage-audit__table td:nth-child(3),
|
||||
.storage-audit__table th:nth-child(3) {
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
.storage-audit__source-list {
|
||||
display: grid;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.storage-audit__list--raw h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -223,6 +264,10 @@
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.storage-audit__severity--inline {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.severity-high .storage-audit__severity {
|
||||
background: color-mix(in srgb, #b03e29 80%, transparent);
|
||||
color: white;
|
||||
|
||||
Reference in New Issue
Block a user