Files
clean-architecture-frontend…/scripts/check-diagnostics.ts
T

121 lines
4.6 KiB
TypeScript

import { mkdir, readFile, readdir } from "node:fs/promises";
import { diagnosticsReportArtifactSchema } from "./contracts/release-artifacts.ts";
import { writeValidatedJsonArtifact } from "./lib/validated-json-artifact.ts";
import path from "node:path";
import { DIAGNOSTIC_EVENT_REGISTRY } from "../src/contracts/diagnostics.ts";
import { TELEMETRY_REGISTRY } from "../src/contracts/telemetry.ts";
const fixtureMode = process.argv.includes("--fixture");
const failures: string[] = [];
const extensions = /\.(?:ts|tsx|mts|cts)$/;
async function filesBelow(directory: string): Promise<string[]> {
const result: string[] = [];
for (const entry of await readdir(directory, { withFileTypes: true })) {
const target = path.join(directory, entry.name);
if (entry.isDirectory()) result.push(...(await filesBelow(target)));
else if (extensions.test(entry.name)) result.push(target);
}
return result;
}
const telemetryProducerFiles: Readonly<Record<string, string>> = {
"app.boot.failed": "src/adapters/diagnostics/bounded-diagnostics.ts",
"api.request.failed": "src/adapters/http/client.ts",
"ui.render.failed": "src/application/create-application.ts",
"release.mismatch.detected": "src/application/create-application.ts",
"telemetry.delivery.dropped":
"src/adapters/telemetry/best-effort-telemetry.ts",
};
const diagnosticProducerFiles: Readonly<Record<string, string>> = {
"app.boot.failed": "src/adapters/diagnostics/bounded-diagnostics.ts",
"http.request.completed": "src/adapters/http/client.ts",
"cache.operation.failed":
"src/adapters/query-cache/tanstack-query-cache.ts",
"storage.operation.failed":
"src/adapters/storage/browser-storage-adapter.ts",
"route.changed": "src/application/create-application.ts",
"ui.render.failed": "src/application/create-application.ts",
"release.mismatch.detected": "src/application/create-application.ts",
"telemetry.delivery.dropped": "src/bootstrap/runtime-adapters.ts",
};
if (!fixtureMode) {
for (const eventName of Object.keys(TELEMETRY_REGISTRY)) {
const producer = telemetryProducerFiles[eventName];
if (!producer) {
failures.push(`telemetry event has no declared producer: ${eventName}`);
continue;
}
const source = await readFile(producer, "utf8");
if (!source.includes(`"${eventName}"`)) {
failures.push(`telemetry producer is not executable: ${eventName}`);
}
}
for (const eventId of Object.keys(DIAGNOSTIC_EVENT_REGISTRY)) {
const producer = diagnosticProducerFiles[eventId];
if (!producer) {
failures.push(`diagnostic event has no declared producer: ${eventId}`);
continue;
}
const source = await readFile(producer, "utf8");
if (!source.includes(`"${eventId}"`)) {
failures.push(`diagnostic producer is not executable: ${eventId}`);
}
}
}
const sources = fixtureMode
? await filesBelow("tests/fixtures/diagnostics/forbidden")
: await filesBelow("src");
const sensitiveContext =
/\b(?:authorization|cookie|access_token|refresh_token|request_body|response_body|raw_url|query_string|email|user_name)\b/i;
for (const file of sources) {
const source = await readFile(file, "utf8");
if (file.includes("contracts/telemetry.ts")) continue;
if (source.includes("console.")) {
failures.push(`direct console diagnostics bypass in ${file}`);
}
const calls = source.match(
/(?:\.record\(\{|\.emit\()[\s\S]{0,700}?(?:\}\)|\}\);)/g,
) ?? [];
if (calls.some((call) => sensitiveContext.test(call))) {
failures.push(`sensitive diagnostic or telemetry context in ${file}`);
}
if (
file.includes("tests/fixtures/diagnostics/forbidden") &&
source.includes("UNKNOWN_DIAGNOSTIC_EVENT")
) {
failures.push(`unknown diagnostic event in ${file}`);
}
}
const report = diagnosticsReportArtifactSchema.parse({
schemaVersion: 1,
mode: fixtureMode ? "negative-fixture" : "source",
telemetryEventCount: Object.keys(TELEMETRY_REGISTRY).length,
diagnosticEventCount: Object.keys(DIAGNOSTIC_EVENT_REGISTRY).length,
checkedFiles: sources.length,
failures,
passed: failures.length === 0,
});
await mkdir("artifacts/quality", { recursive: true });
await writeValidatedJsonArtifact({
path: fixtureMode
? "artifacts/quality/diagnostics-fixture.json"
: "artifacts/quality/diagnostics.json",
schema: diagnosticsReportArtifactSchema,
value: report,
});
if (failures.length > 0) {
process.stderr.write(
`Diagnostics contract failed:\n${failures.join("\n")}\n`,
);
process.exit(1);
}
process.stdout.write(
`Diagnostics contract: ${report.diagnosticEventCount} diagnostics and ${report.telemetryEventCount} telemetry producers PASS\n`,
);