Fix storage root fallback for references
This commit is contained in:
@@ -8,9 +8,9 @@
|
||||
},
|
||||
"Hero": {
|
||||
"Title": "Kosmos Storage Audit",
|
||||
"Intro1": "Prüft Medienreferenzen und markiert primär benutzerrelevante Risiken in den Foundry-Roots {dataRoot} und {publicRoot}.",
|
||||
"Intro2": "Orphans werden bewusst nicht global für den gesamten {dataRoot}-Root behauptet, sondern nur in klar weltlokalen oder explizit riskanten Bereichen.",
|
||||
"Intro3": "Weltverweise auf Modul- oder Systemassets gelten nicht pauschal als Problem. Relevant sind vor allem Ziele, die im Owner-Paket selbst nicht sichtbar referenziert werden."
|
||||
"Intro1": "Prüft lokale Medienpfade aus Weltdokumenten, Paket-Packs und Manifesten gegen {dataRoot} und {publicRoot} und meldet nur broken-reference, non-package-to-package-reference und orphan-file.",
|
||||
"Intro2": "Nicht gemeldet werden reguläre Weltverweise auf Modul- oder Systemassets, wenn das Ziel im Owner-Paket selbst sichtbar referenziert ist; Wildcards gelten als gültig, sobald mindestens eine Datei passt.",
|
||||
"Intro3": "orphan-file wird nur in weltlokalen oder explizit riskanten Bereichen gebildet, nie global für den gesamten {dataRoot}-Root; ChatMessages und andere flüchtige Quellen werden nicht geprüft."
|
||||
},
|
||||
"Action": {
|
||||
"Run": "Analyse starten",
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
},
|
||||
"Hero": {
|
||||
"Title": "Kosmos Storage Audit",
|
||||
"Intro1": "Audits media references and highlights primarily user-relevant risks in the Foundry roots {dataRoot} and {publicRoot}.",
|
||||
"Intro2": "Orphans are intentionally not claimed globally for the entire {dataRoot} root, but only in clearly world-local or explicitly risky areas.",
|
||||
"Intro3": "World references to module or system assets are not treated as a problem by default. The main focus is on targets that are not visibly referenced by their owning package."
|
||||
"Intro1": "Checks local media paths from world documents, package packs, and manifests against {dataRoot} and {publicRoot}, and only reports broken-reference, non-package-to-package-reference, and orphan-file.",
|
||||
"Intro2": "Regular world references to module or system assets are not reported if the target is visibly referenced by its owning package; wildcards are treated as valid as soon as at least one file matches.",
|
||||
"Intro3": "orphan-file is only produced for world-local or explicitly risky areas, never globally for the entire {dataRoot} root; ChatMessages and other transient sources are excluded."
|
||||
},
|
||||
"Action": {
|
||||
"Run": "Start Analysis",
|
||||
|
||||
@@ -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.18",
|
||||
"version": "0.0.19",
|
||||
"compatibility": {
|
||||
"minimum": "13",
|
||||
"verified": "13"
|
||||
|
||||
@@ -39,11 +39,12 @@ export function buildFindings({ files, references, i18n }={}) {
|
||||
path: file.path,
|
||||
locator: createCanonicalLocator(file.storage, file.path)
|
||||
}));
|
||||
const resolvedReferences = references.map(reference => resolveReferenceTarget(reference, fileByLocator, fileLocators));
|
||||
const refsByLocator = new Map();
|
||||
const wildcardReferences = [];
|
||||
const findings = [];
|
||||
|
||||
for (const reference of references) {
|
||||
for (const reference of resolvedReferences) {
|
||||
const normalized = reference.normalized;
|
||||
if (!normalized) continue;
|
||||
if (normalized.targetKind === "wildcard") {
|
||||
@@ -56,7 +57,7 @@ export function buildFindings({ files, references, i18n }={}) {
|
||||
refsByLocator.set(normalizedLocator, bucket);
|
||||
}
|
||||
|
||||
for (const reference of references) {
|
||||
for (const reference of resolvedReferences) {
|
||||
const normalized = reference.normalized;
|
||||
if (!normalized) continue;
|
||||
const normalizedLocator = createCanonicalLocator(normalized.storage, normalized.path);
|
||||
@@ -117,7 +118,7 @@ export function buildFindings({ files, references, i18n }={}) {
|
||||
if (detectMediaKind(file.path) === "other") continue;
|
||||
const refs = matchingReferencesForFile(file, refsByLocator, wildcardReferences);
|
||||
if (refs.length) continue;
|
||||
if (!shouldReportOrphan(file, references)) continue;
|
||||
if (!shouldReportOrphan(file, resolvedReferences)) continue;
|
||||
|
||||
const severity = (file.riskClass === "package-module") || (file.riskClass === "package-system") || (file.riskClass === "release-public")
|
||||
? "warning"
|
||||
@@ -139,6 +140,41 @@ export function buildFindings({ files, references, i18n }={}) {
|
||||
return findings;
|
||||
}
|
||||
|
||||
function resolveReferenceTarget(reference, fileByLocator, fileLocators) {
|
||||
const normalized = reference.normalized;
|
||||
if (!normalized) return reference;
|
||||
|
||||
const currentLocator = createCanonicalLocator(normalized.storage, normalized.path);
|
||||
if (fileByLocator.has(currentLocator)) return reference;
|
||||
|
||||
const alternateStorage = normalized.storage === "data"
|
||||
? "public"
|
||||
: normalized.storage === "public"
|
||||
? "data"
|
||||
: null;
|
||||
if (!alternateStorage) return reference;
|
||||
|
||||
const alternateLocator = createCanonicalLocator(alternateStorage, normalized.path);
|
||||
if (normalized.targetKind === "wildcard") {
|
||||
const alternateTarget = { ...normalized, storage: alternateStorage, locator: alternateLocator };
|
||||
if (!wildcardMatchesAny(alternateTarget, fileLocators)) return reference;
|
||||
return {
|
||||
...reference,
|
||||
normalized: alternateTarget
|
||||
};
|
||||
}
|
||||
|
||||
if (!fileByLocator.has(alternateLocator)) return reference;
|
||||
return {
|
||||
...reference,
|
||||
normalized: {
|
||||
...normalized,
|
||||
storage: alternateStorage,
|
||||
locator: alternateLocator
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isAnchoredInOwningPackage(file, references) {
|
||||
const ownerType = file.ownerHint.ownerType;
|
||||
const ownerId = file.ownerHint.ownerId;
|
||||
|
||||
30
tests/storage-root-resolution-test.mjs
Normal file
30
tests/storage-root-resolution-test.mjs
Normal file
@@ -0,0 +1,30 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { buildFindings, createFileRecord } from "../scripts/core/finding-engine.js";
|
||||
import { createFileLocator } from "../scripts/core/path-utils.js";
|
||||
|
||||
const files = [
|
||||
createFileRecord(createFileLocator("data", "canvas/background_paper_16x9_4k.webp"), 1234)
|
||||
];
|
||||
|
||||
const references = [
|
||||
{
|
||||
sourceType: "world-document",
|
||||
sourceScope: { ownerType: "world", ownerId: "demo-world", systemId: "demo-system", subtype: "scenes" },
|
||||
sourceLabel: "Scene demo",
|
||||
rawValue: "canvas/background_paper_16x9_4k.webp",
|
||||
normalized: {
|
||||
...createFileLocator("public", "canvas/background_paper_16x9_4k.webp"),
|
||||
targetKind: "local-file"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const findings = buildFindings({ files, references });
|
||||
|
||||
assert.equal(
|
||||
findings.some(finding => finding.kind === "broken-reference" && finding.target.locator === "public:canvas/background_paper_16x9_4k.webp"),
|
||||
false,
|
||||
"references should be remapped to the existing storage root before reporting a broken target"
|
||||
);
|
||||
|
||||
console.log("storage-root-resolution-test: ok");
|
||||
Reference in New Issue
Block a user