core/emitters/tool.emitter.ts

core/emitters/tool.emitter.ts is a file in GovLab Quality. 100 lines of code and 27 definitions.

import type {
    ActiveConcept,
    ConfigValue,
    DescriptorFile,
    EmitDescriptor,
    EmitFile,
    EmitTokens,
} from "#types/emitter.types";
import { loadDescriptors, loadEmitTokens, loadFormatters } from "#core/loaders/emitter.loader";
import { ruleIdsFor, toolTokensOf } from "#core/selectors/emitter.selector";
import { TOGGLE_KNOB } from "#configuration/constants/emitter.constants";
import type { ToolResolution } from "#types/plan.types";
import { formatterFor } from "#core/registries/formatter.registry";
import { loadCanonicalData } from "#core/loaders/canon.loader";
import { missingFormatter } from "#configuration/strings/emitter.strings";

type SurfaceMap = Map<string, string[]>;
type ToolTokens = EmitTokens[string];

interface ToolConfigCtx {
    descriptor: EmitDescriptor;
    resolution: ToolResolution;
    surfaceMap: SurfaceMap;
    tokens: EmitTokens;
    tool: string;
}

interface EmitOptions {
    descriptorFile?: DescriptorFile | undefined;
    onSkip?: ((tool: string) => void) | undefined;
    tokens?: EmitTokens | undefined;
}

const UNSERIALIZABLE = new Set(["bigint", "function", "symbol", "undefined"]);

const isConfigValue = function isConfigValue(value: unknown): value is ConfigValue {
    return !UNSERIALIZABLE.has(typeof value);
};

const buildSurfaceMap = function buildSurfaceMap(): SurfaceMap {
    const map: SurfaceMap = new Map();
    for (const setting of loadCanonicalData().settings) {
        map.set(setting.surface, [...(map.get(setting.surface) ?? []), setting.id]);
    }
    return map;
};

const disabledRuleIds = function disabledRuleIds(
    disabledSurfaces: string[],
    surfaceMap: SurfaceMap,
    toolTokens: ToolTokens,
): string[] {
    const ids = disabledSurfaces.flatMap((surface) =>
        (surfaceMap.get(surface) ?? []).flatMap((canonicalId) => ruleIdsFor(toolTokens, canonicalId)),
    );
    return [...new Set(ids)].sort((a, b) => a.localeCompare(b));
};

const conceptFor = function conceptFor(
    resolution: ToolResolution,
    canonicalId: string,
    entry: ToolTokens[string],
): ActiveConcept | null {
    const isValueKnob = entry.knob !== null && entry.knob !== TOGGLE_KNOB;
    const raw = resolution.knobs[canonicalId];
    const base = { canonicalId, knob: isValueKnob ? entry.knob : null, ruleIds: entry.ruleIds };
    if (isValueKnob && isConfigValue(raw)) {
        return { ...base, value: raw };
    }
    return resolution.enabledIntents.includes(canonicalId) ? base : null;
};

const activeConcepts = function activeConcepts(resolution: ToolResolution, toolTokens: ToolTokens): ActiveConcept[] {
    return Object.entries(toolTokens)
        .map(([canonicalId, entry]) => conceptFor(resolution, canonicalId, entry))
        .filter((concept): concept is ActiveConcept => concept !== null);
};

export const emitToolConfig = function emitToolConfig(ctx: ToolConfigCtx): EmitFile {
    const formatter = formatterFor(ctx.descriptor.format);
    if (!formatter) {
        throw new Error(missingFormatter(ctx.descriptor.format, ctx.tool));
    }
    const toolTokens = toolTokensOf(ctx.tokens, ctx.tool);
    const concepts = activeConcepts(ctx.resolution, toolTokens);
    const ignore = disabledRuleIds(ctx.resolution.disabledSurfaces, ctx.surfaceMap, toolTokens);
    return {
        content: formatter.render({ concepts, descriptor: ctx.descriptor, ignore }),
        path: ctx.descriptor.configTarget,
    };
};

export const emitConfigs = async function emitConfigs(
    perToolConfig: Record<string, ToolResolution>,
    options: EmitOptions = {},
): Promise<EmitFile[]> {
    await loadFormatters();
    const descriptorFile = options.descriptorFile ?? loadDescriptors();
    const tokens = options.tokens ?? loadEmitTokens();
    const byTool = new Map(descriptorFile.descriptors.map((descriptor) => [descriptor.tool, descriptor]));
    const surfaceMap = buildSurfaceMap();
    return Object.entries(perToolConfig).flatMap(([tool, resolution]) => {
        const parent = descriptorFile.pluginParent[tool] ?? tool;
        const descriptor = byTool.get(parent);
        if (!descriptor) {
            options.onSkip?.(tool);
            return [];
        }
        return [emitToolConfig({ descriptor, resolution, surfaceMap, tokens, tool: parent })];
    });
};