121 lines
4.5 KiB
JavaScript
121 lines
4.5 KiB
JavaScript
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
|
|
// @ts-expect-error Node 24 executes erasable TypeScript for this build-time gate.
|
|
import { DIAGNOSTIC_EVENT_REGISTRY } from "../src/contracts/diagnostics.ts";
|
|
import { TELEMETRY_REGISTRY } from "../src/contracts/telemetry.js";
|
|
|
|
const fixtureMode = process.argv.includes("--fixture");
|
|
const failures = [];
|
|
const extensions = /\.(?:js|jsx|mjs|ts|tsx|mts)$/;
|
|
|
|
/** @param {string} directory @returns {Promise<string[]>} */
|
|
async function filesBelow(directory) {
|
|
const result = [];
|
|
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 =
|
|
/** @type {Readonly<Record<string, string>>} */ ({
|
|
"app.boot.failed": "src/adapters/diagnostics/bounded-diagnostics.ts",
|
|
"api.request.failed": "src/adapters/http/client.js",
|
|
"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.js",
|
|
});
|
|
const diagnosticProducerFiles =
|
|
/** @type {Readonly<Record<string, string>>} */ ({
|
|
"app.boot.failed": "src/adapters/diagnostics/bounded-diagnostics.ts",
|
|
"http.request.completed": "src/adapters/http/client.js",
|
|
"cache.operation.failed":
|
|
"src/adapters/query-cache/tanstack-query-cache.js",
|
|
"storage.operation.failed":
|
|
"src/adapters/storage/browser-storage-adapter.js",
|
|
"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.js",
|
|
});
|
|
|
|
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.js")) 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 = {
|
|
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 writeFile(
|
|
fixtureMode
|
|
? "artifacts/quality/diagnostics-fixture.json"
|
|
: "artifacts/quality/diagnostics.json",
|
|
`${JSON.stringify(report, null, 2)}\n`,
|
|
);
|
|
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`,
|
|
);
|