feat: complete 2.0.7.12 platform overhaul
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { readFile, stat } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
|
||||
const root = path.resolve(process.argv[2] || "web/admin/dist");
|
||||
|
||||
function resolveOutput(name) {
|
||||
const normalized = String(name || "").replaceAll("\\", "/");
|
||||
if (!normalized || normalized.startsWith("/") || normalized.split("/").includes("..")) {
|
||||
throw new Error(`Invalid asset path in manifest: ${JSON.stringify(name)}`);
|
||||
}
|
||||
const resolved = path.resolve(root, ...normalized.split("/"));
|
||||
if (resolved !== root && !resolved.startsWith(`${root}${path.sep}`)) {
|
||||
throw new Error(`Asset path escapes dist: ${JSON.stringify(name)}`);
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
async function requireFile(name) {
|
||||
const file = resolveOutput(name);
|
||||
const info = await stat(file);
|
||||
if (!info.isFile() || info.size === 0) {
|
||||
throw new Error(`Missing or empty admin asset: ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
const manifest = JSON.parse(await readFile(path.join(root, "asset-manifest.json"), "utf8"));
|
||||
const build = JSON.parse(await readFile(path.join(root, "admin-build.json"), "utf8"));
|
||||
|
||||
if (!build.buildId || typeof build.buildId !== "string") {
|
||||
throw new Error("admin-build.json does not contain a buildId");
|
||||
}
|
||||
if (!manifest || typeof manifest !== "object" || Object.keys(manifest).length === 0) {
|
||||
throw new Error("asset-manifest.json is empty");
|
||||
}
|
||||
|
||||
await requireFile("index.html");
|
||||
for (const [key, entry] of Object.entries(manifest)) {
|
||||
if (!entry?.file) throw new Error(`Manifest entry ${key} has no output file`);
|
||||
for (const dependency of [...(entry.imports || []), ...(entry.dynamicImports || [])]) {
|
||||
if (!manifest[dependency]) throw new Error(`Manifest entry ${key} references missing entry ${dependency}`);
|
||||
}
|
||||
for (const file of [entry.file, ...(entry.css || []), ...(entry.assets || [])]) {
|
||||
await requireFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
process.stdout.write(`Admin build ${build.buildId}: ${Object.keys(manifest).length} manifest entries verified.\n`);
|
||||
Reference in New Issue
Block a user