feat(map): add persistent gateway and ontology package
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { access, readFile, stat } from "node:fs/promises";
|
||||
import { dirname, isAbsolute, join, resolve } from "node:path";
|
||||
|
||||
const manifestPath = resolve(process.argv[2] || "");
|
||||
if (!process.argv[2]) {
|
||||
console.error("Usage: npm run audit:engine-cache -- /absolute/path/to/cesium/manifest.json");
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
await audit(manifestPath);
|
||||
}
|
||||
|
||||
async function audit(path) {
|
||||
let manifest;
|
||||
try {
|
||||
manifest = JSON.parse(await readFile(path, "utf8"));
|
||||
} catch (error) {
|
||||
throw new Error(`Cannot read legacy cache manifest: ${error instanceof Error ? error.message : "unknown error"}`);
|
||||
}
|
||||
|
||||
const root = dirname(path);
|
||||
const entries = Object.entries(manifest?.entries || {});
|
||||
const providers = new Map();
|
||||
let bytesFromManifest = 0;
|
||||
let presentFiles = 0;
|
||||
let missingFiles = 0;
|
||||
let bytesOnDisk = 0;
|
||||
|
||||
for (const [rawUrl, entry] of entries) {
|
||||
let hostname = "invalid-url";
|
||||
try { hostname = new URL(rawUrl).hostname.toLowerCase() || "invalid-url"; } catch {}
|
||||
const provider = providers.get(hostname) || { entries: 0, bytes: 0, presentFiles: 0, missingFiles: 0 };
|
||||
const entryBytes = Math.max(0, Number(entry?.size || 0));
|
||||
provider.entries += 1;
|
||||
provider.bytes += entryBytes;
|
||||
bytesFromManifest += entryBytes;
|
||||
|
||||
const relativeFile = String(entry?.path || "");
|
||||
const candidate = resolve(root, relativeFile);
|
||||
if (!relativeFile || !candidate.startsWith(`${root}/`) || isAbsolute(relativeFile) || !(await fileExists(candidate))) {
|
||||
provider.missingFiles += 1;
|
||||
missingFiles += 1;
|
||||
providers.set(hostname, provider);
|
||||
continue;
|
||||
}
|
||||
|
||||
const fileInfo = await stat(candidate);
|
||||
presentFiles += 1;
|
||||
provider.presentFiles += 1;
|
||||
bytesOnDisk += fileInfo.size;
|
||||
providers.set(hostname, provider);
|
||||
}
|
||||
|
||||
const report = {
|
||||
kind: "nodedc-legacy-cesium-cache-audit",
|
||||
generatedAt: new Date().toISOString(),
|
||||
manifestPath: path,
|
||||
manifestVersion: manifest?.version ?? null,
|
||||
entries: entries.length,
|
||||
declaredBytes: bytesFromManifest,
|
||||
declaredMegabytes: toMegabytes(bytesFromManifest),
|
||||
presentFiles,
|
||||
missingFiles,
|
||||
bytesOnDisk,
|
||||
megabytesOnDisk: toMegabytes(bytesOnDisk),
|
||||
providers: [...providers.entries()]
|
||||
.map(([hostname, value]) => ({ hostname, ...value, megabytes: toMegabytes(value.bytes) }))
|
||||
.sort((left, right) => right.bytes - left.bytes),
|
||||
migrationPolicy: {
|
||||
automaticImport: false,
|
||||
reason: "Audit only. Import requires an explicit licence/provider decision for every source host and must preserve required attribution.",
|
||||
target: "Map Gateway persistent volume or approved object storage; never Git history or a Docker image layer."
|
||||
}
|
||||
};
|
||||
|
||||
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
||||
}
|
||||
|
||||
async function fileExists(path) {
|
||||
try {
|
||||
await access(path);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function toMegabytes(bytes) {
|
||||
return Number((bytes / 1024 / 1024).toFixed(2));
|
||||
}
|
||||
Reference in New Issue
Block a user