core/converters/report.converter.ts

core/converters/report.converter.ts is a file in Bane's Lab Build Scripts. 86 lines of code and 14 definitions.

import type { AnatomyStats, DefinitionRef, DefinitionView, FindingView } from "@banes-lab/web/types/anatomy.types.js";
import type { CodeFinding, DefinitionRecord, ModuleReport } from "@govlab/patterns";
import type { DiskFile } from "#types/structure.types";

const KEY_SEPARATOR = "::";
const CYCLE_KIND = "call-cycle";

export const definitionKey = function definitionKey(file: string, name: string): string {
    return file + KEY_SEPARATOR + name;
};

const refOf = function refOf(key: string): DefinitionRef {
    const cut = key.lastIndexOf(KEY_SEPARATOR);
    return { file: key.slice(0, cut), id: key, name: key.slice(cut + KEY_SEPARATOR.length) };
};

const definitionView = function definitionView(record: DefinitionRecord): DefinitionView {
    return {
        callable: record.callable,
        callees: record.callees.map(refOf),
        callers: record.callers.map(refOf),
        exported: record.exported,
        file: record.file,
        flow: record.flow,
        id: definitionKey(record.file, record.name),
        inDegree: record.inDegree,
        kind: record.kind,
        line: record.line,
        local: record.local,
        name: record.name,
        outDegree: record.outDegree,
    };
};

export const definitionsByFile = function definitionsByFile(report: ModuleReport): Map<string, DefinitionView[]> {
    const byFile = new Map<string, DefinitionView[]>();
    for (const record of report.definitions) {
        byFile.set(record.file, [...(byFile.get(record.file) ?? []), definitionView(record)]);
    }
    return byFile;
};

export const findingView = function findingView(finding: CodeFinding): FindingView {
    return {
        confidence: finding.confidence,
        detail: finding.detail,
        file: finding.file,
        kind: finding.kind,
        line: finding.line,
        name: finding.name,
        remedy: finding.remedy,
        severity: finding.severity,
    };
};

export const flaggedOf = function flaggedOf(findings: readonly CodeFinding[]): Map<string, string> {
    const flagged = new Map<string, string>();
    for (const finding of findings) {
        if (finding.kind === CYCLE_KIND) {
            for (const member of finding.members) {
                flagged.set(member, finding.severity);
            }
        } else {
            flagged.set(definitionKey(finding.file, finding.name), finding.severity);
        }
    }
    return flagged;
};

const tally = function tally(values: readonly string[]): Record<string, number> {
    const counts: Record<string, number> = {};
    for (const value of values) {
        counts[value] = (counts[value] ?? 0) + 1;
    }
    return counts;
};

export const fileStatsOf = function fileStatsOf(
    file: DiskFile,
    definitions: readonly DefinitionView[],
    edges: number,
    findings: readonly FindingView[],
): AnatomyStats {
    return {
        bytes: file.bytes,
        callable: definitions.filter((definition) => definition.callable).length,
        definitions: definitions.length,
        edges,
        exported: definitions.filter((definition) => definition.exported).length,
        files: 1,
        findings: tally(findings.map((finding) => finding.kind)),
        flows: tally(definitions.map((definition) => definition.flow)),
        lines: file.lines,
    };
};