feat(POSTV1-ASSET-ALL-16): 完整还原归档文字模板素材
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { createServer } from "node:http";
|
||||
import { isAbsolute, join, resolve } from "node:path";
|
||||
|
||||
import { chromium } from "@playwright/test";
|
||||
|
||||
function option(name) {
|
||||
const index = process.argv.indexOf(name);
|
||||
return index >= 0 ? process.argv[index + 1] : undefined;
|
||||
}
|
||||
|
||||
function defaultConfigPath() {
|
||||
if (!process.env.LOCALAPPDATA || !isAbsolute(process.env.LOCALAPPDATA)) {
|
||||
throw new Error("local_app_data_unavailable");
|
||||
}
|
||||
return join(process.env.LOCALAPPDATA, "Dada", "P0A", "config", "instance.json");
|
||||
}
|
||||
|
||||
const manifestPath = resolve(option("--manifest") ?? "config/runtime-assets-manifest.json");
|
||||
const configPath = resolve(option("--config") ?? process.env.DADA_INSTANCE_CONFIG_PATH ?? defaultConfigPath());
|
||||
const manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
|
||||
const configuration = JSON.parse(readFileSync(configPath, "utf8"));
|
||||
if (typeof configuration.asset_root !== "string" || !isAbsolute(configuration.asset_root)) {
|
||||
throw new Error("asset_root_configuration_invalid");
|
||||
}
|
||||
|
||||
const fontEntries = manifest.entries
|
||||
.filter((entry) => entry.assetId.startsWith("TEXT-FONT-") && entry.mimeType.startsWith("font/"))
|
||||
.toSorted((left, right) => left.assetId.localeCompare(right.assetId));
|
||||
const uniqueEntries = [...new Map(fontEntries.map((entry) => [entry.sha256, entry])).values()];
|
||||
const fontPaths = new Map(
|
||||
uniqueEntries.map((entry) => [
|
||||
`/${encodeURIComponent(entry.assetId)}`,
|
||||
{ mimeType: entry.mimeType, path: join(configuration.asset_root, entry.relativePath) },
|
||||
]),
|
||||
);
|
||||
|
||||
const server = createServer((request, response) => {
|
||||
const font = fontPaths.get(request.url ?? "");
|
||||
if (!font) {
|
||||
response.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
||||
response.end("<!doctype html><title>Dada browser font validation</title>");
|
||||
return;
|
||||
}
|
||||
const bytes = readFileSync(font.path);
|
||||
response.writeHead(200, { "Content-Length": bytes.length, "Content-Type": font.mimeType });
|
||||
response.end(bytes);
|
||||
});
|
||||
|
||||
await new Promise((resolveReady) => server.listen(0, "127.0.0.1", resolveReady));
|
||||
const address = server.address();
|
||||
if (!address || typeof address === "string") throw new Error("browser_font_probe_server_unavailable");
|
||||
const origin = `http://127.0.0.1:${address.port}`;
|
||||
const browser = await chromium.launch({ channel: option("--channel") ?? "msedge", headless: true });
|
||||
const failures = [];
|
||||
|
||||
try {
|
||||
let page = await browser.newPage();
|
||||
await page.goto(origin);
|
||||
for (let index = 0; index < uniqueEntries.length; index += 1) {
|
||||
if (index > 0 && index % 25 === 0) {
|
||||
await page.close();
|
||||
page = await browser.newPage();
|
||||
await page.goto(origin);
|
||||
}
|
||||
const entry = uniqueEntries[index];
|
||||
const result = await page.evaluate(async ({ family, url }) => {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) return `http_${response.status}`;
|
||||
await new FontFace(family, await response.arrayBuffer()).load();
|
||||
return "loaded";
|
||||
} catch (error) {
|
||||
return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
||||
}
|
||||
}, { family: `DadaFontProbe${index}`, url: `${origin}/${encodeURIComponent(entry.assetId)}` });
|
||||
if (result !== "loaded") failures.push({ asset_id: entry.assetId, error: result });
|
||||
}
|
||||
} finally {
|
||||
await browser.close();
|
||||
await new Promise((resolveClosed) => server.close(resolveClosed));
|
||||
}
|
||||
|
||||
const result = {
|
||||
checked_entries: fontEntries.length,
|
||||
failed_fonts: failures,
|
||||
status: failures.length === 0 ? "passed" : "failed",
|
||||
unique_fonts: uniqueEntries.length,
|
||||
};
|
||||
process.stdout.write(`${JSON.stringify(result)}\n`);
|
||||
if (failures.length > 0) process.exitCode = 1;
|
||||
Reference in New Issue
Block a user