mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Release v3.8.24 — see CHANGELOG.md [3.8.24] for the full notes and the PR description for the contributors hall. Integration of release/v3.8.24 into main.
109 lines
3.6 KiB
JavaScript
109 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
|
// scripts/check/check-type-coverage.mjs
|
|
// Type-coverage ratchet (Task 6 of Fase 7).
|
|
//
|
|
// Measures the % of typed symbols across the codebase using the `type-coverage`
|
|
// tool and prints `typeCoveragePct=<N>`. This is advisory in Phase-INT (exits 0)
|
|
// — it complements the per-file explicit-any budget in check-t11-any-budget.mjs
|
|
// with a project-wide %-typed view.
|
|
//
|
|
// tsconfig used: open-sse/tsconfig.json
|
|
// - Rationale: the only tsconfig that covers the full open-sse workspace
|
|
// (src+open-sse together). `tsconfig.json` excludes open-sse; the
|
|
// `tsconfig.typecheck-core.json` only lists 26 explicit files (partial).
|
|
// open-sse/tsconfig.json sets `baseUrl: ".."` and path aliases so it
|
|
// resolves both workspaces correctly and yields a representative global %.
|
|
//
|
|
// Direction: up (% can only improve; ratchet blocks drops once wired into INT).
|
|
//
|
|
// Run:
|
|
// node scripts/check/check-type-coverage.mjs
|
|
// node scripts/check/check-type-coverage.mjs --update # ratchet baseline up
|
|
//
|
|
// Exit codes: 0 = advisory pass (current version), 1 = ratchet regression.
|
|
|
|
import { execFileSync } from "node:child_process";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const ROOT = process.cwd();
|
|
const TSCONFIG = path.join(ROOT, "open-sse", "tsconfig.json");
|
|
|
|
/**
|
|
* Parse the JSON output produced by `type-coverage --json-output`.
|
|
* Returns the coverage percentage as a number (e.g. 91.66).
|
|
* Throws if the output cannot be parsed or has unexpected shape.
|
|
*
|
|
* Exported for unit-testing against synthetic output.
|
|
*/
|
|
export function parseTypeCoverageOutput(jsonText) {
|
|
let parsed;
|
|
try {
|
|
parsed = JSON.parse(jsonText);
|
|
} catch (err) {
|
|
throw new Error(`[type-coverage] Failed to parse JSON output: ${err.message}`);
|
|
}
|
|
|
|
if (typeof parsed.percent !== "number") {
|
|
throw new Error(
|
|
`[type-coverage] Unexpected output shape — missing numeric 'percent' field. Got: ${JSON.stringify(parsed)}`
|
|
);
|
|
}
|
|
|
|
return parsed.percent;
|
|
}
|
|
|
|
function runTypeCoverage() {
|
|
const typeCoverageBin = path.join(ROOT, "node_modules", ".bin", "type-coverage");
|
|
|
|
if (!fs.existsSync(typeCoverageBin)) {
|
|
throw new Error(`[type-coverage] Binary not found at ${typeCoverageBin}`);
|
|
}
|
|
if (!fs.existsSync(TSCONFIG)) {
|
|
throw new Error(`[type-coverage] tsconfig not found at ${TSCONFIG}`);
|
|
}
|
|
|
|
let stdout;
|
|
try {
|
|
stdout = execFileSync(typeCoverageBin, ["--json-output", "-p", TSCONFIG], {
|
|
encoding: "utf8",
|
|
maxBuffer: 32 * 1024 * 1024,
|
|
cwd: ROOT,
|
|
});
|
|
} catch (err) {
|
|
// type-coverage exits non-zero when --at-least check fails, but we don't use that.
|
|
// If there is stdout, try to parse it anyway.
|
|
stdout = err.stdout ? String(err.stdout) : "";
|
|
if (!stdout.trim()) throw err;
|
|
}
|
|
|
|
return parseTypeCoverageOutput(stdout.trim());
|
|
}
|
|
|
|
function main() {
|
|
console.log("[type-coverage] Running type-coverage (this may take ~30-60 s)…");
|
|
console.log(`[type-coverage] tsconfig: ${path.relative(ROOT, TSCONFIG)}`);
|
|
|
|
let pct;
|
|
try {
|
|
pct = runTypeCoverage();
|
|
} catch (err) {
|
|
console.error(`[type-coverage] FAIL — ${err.message}`);
|
|
// Advisory: exit 0 so CI is not blocked until INT wiring.
|
|
process.exit(0);
|
|
}
|
|
|
|
// Canonical output line consumed by collect-metrics.mjs and shell scripts.
|
|
console.log(`typeCoveragePct=${pct}`);
|
|
console.log(`[type-coverage] Advisory OK — ${pct}% symbols typed (direction: up)`);
|
|
|
|
// Advisory: always exit 0 in this version.
|
|
// Once wired into quality-baseline.json (INT), exit 1 on regression here.
|
|
process.exit(0);
|
|
}
|
|
|
|
if (import.meta.url === pathToFileURL(process.argv[1] || "").href) {
|
|
main();
|
|
}
|