core/registries/manifest.registry.ts

core/registries/manifest.registry.ts is a file in GovLab Docs. 100 lines of code and 30 definitions.

import type { CatalogEntry, ManifestModule, ManifestPlugin, PluginContext, QueryCriteria } from "#types/manifest.types";
import { arrayField, recordField, stringField } from "#core/selectors/record.selector";
import { loadPlugins, loadUserManifestPlugins } from "#core/loaders/section.loader";
import type { Manifest } from "#types/readme.types";
import { PACKAGE_SCOPE } from "#configuration/constants/manifest.constants";
import { ROOT } from "@ssot/paths";
import { discoverModules } from "#core/loaders/manifest.loader";
import { isPlainRecord } from "#core/predicates/record.predicate";
import { moduleError } from "#configuration/strings/manifest.strings";
import { validateManifest } from "#core/validators/manifest.validator";

type CriterionCheck = (manifest: Manifest, module: ManifestModule, criteria: QueryCriteria) => boolean;

const VISIBILITY_KEY = "visibility";
const PRIVATE_FLAG = "private";
const HIDDEN_FLAG = "hidden";
const PUBLIC_SCOPE = "public";

const shortName = function shortName(scoped: string): string {
    return scoped.startsWith(PACKAGE_SCOPE) ? scoped.slice(PACKAGE_SCOPE.length) : scoped;
};

const directDeps = function directDeps(pkg: ManifestModule["pkg"]): string[] {
    const deps = pkg["dependencies"];
    return Object.keys(isPlainRecord(deps) ? deps : {})
        .filter((dep) => dep.startsWith(PACKAGE_SCOPE))
        .map(shortName);
};

const visibilityFlag = function visibilityFlag(manifest: Manifest, flag: string): boolean {
    return recordField(manifest, VISIBILITY_KEY)?.[flag] === true;
};

const hasDomain = function hasDomain(manifest: Manifest, domain: string): boolean {
    return arrayField(manifest, "domains").some((entry) => isPlainRecord(entry) && entry["meta"] === domain);
};

const CRITERIA_CHECKS: readonly CriterionCheck[] = [
    (_manifest, module, criteria) => criteria.group === undefined || module.group === criteria.group,
    (manifest, _module, criteria) => criteria.maturity === undefined || manifest["maturity"] === criteria.maturity,
    (manifest, module, criteria) =>
        criteria.ecosystem === undefined ||
        (stringField(manifest, "ecosystem") ?? module.ecosystemHint) === criteria.ecosystem,
    (manifest, _module, criteria) =>
        criteria.capability === undefined || arrayField(manifest, "capabilities").includes(criteria.capability),
    (manifest, _module, criteria) => criteria.domain === undefined || hasDomain(manifest, criteria.domain),
    (manifest, _module, criteria) => criteria.visibility !== PRIVATE_FLAG || visibilityFlag(manifest, PRIVATE_FLAG),
    (manifest, _module, criteria) =>
        criteria.visibility !== PUBLIC_SCOPE ||
        (!visibilityFlag(manifest, PRIVATE_FLAG) && !visibilityFlag(manifest, HIDDEN_FLAG)),
];

const matchesQuery = function matchesQuery(module: ManifestModule, criteria: QueryCriteria): boolean {
    return CRITERIA_CHECKS.every((check) => check(module.manifest, module, criteria));
};

const transitiveRequires = function transitiveRequires(
    slug: string,
    directMap: ReadonlyMap<string, string[]>,
): string[] {
    const found = new Set<string>();
    const stack = [...(directMap.get(slug) ?? [])];
    for (let dep = stack.pop(); dep !== undefined; dep = stack.pop()) {
        if (!found.has(dep) && dep !== slug) {
            found.add(dep);
            stack.push(...(directMap.get(dep) ?? []));
        }
    }
    return [...found].toSorted((left, right) => left.localeCompare(right));
};

export class ManifestRegistry {
    public readonly directMap: ReadonlyMap<string, string[]>;
    public readonly modules: readonly ManifestModule[];
    public readonly plugins: readonly ManifestPlugin[];

    public constructor(modules: readonly ManifestModule[], plugins: readonly ManifestPlugin[]) {
        this.modules = modules;
        this.plugins = plugins;
        this.directMap = new Map(modules.map((module) => [module.slug, directDeps(module.pkg)]));
    }

    public static async create(): Promise<ManifestRegistry> {
        const [corePlugins, userPlugins] = await Promise.all([loadPlugins(), loadUserManifestPlugins(ROOT)]);
        return new ManifestRegistry(discoverModules(), [...corePlugins, ...userPlugins]);
    }

    public validateAll(): string[] {
        return this.modules.flatMap((module) =>
            validateManifest(module.manifest, this.plugins).map((error) => moduleError(module.label, error)),
        );
    }

    public requires(slug: string): string[] {
        return transitiveRequires(slug, this.directMap);
    }

    public query(criteria: QueryCriteria = {}): ManifestModule[] {
        return this.modules.filter((module) => matchesQuery(module, criteria));
    }

    public catalog(): CatalogEntry[] {
        return this.modules
            .filter((module) => !this.plugins.some((plugin) => plugin.filter?.(module.manifest, module) === true))
            .map((module) => this.entryFor(module))
            .toSorted((left, right) => left.value.localeCompare(right.value));
    }

    private entryFor(module: ManifestModule): CatalogEntry {
        const entry: CatalogEntry = { category: module.group, value: module.slug };
        const context: PluginContext = { module, requires: (slug: string) => this.requires(slug) };
        for (const plugin of this.plugins) {
            plugin.contribute?.(module.manifest, entry, context);
        }
        return entry;
    }
}