tools/core/resolvers/dependency.resolver.ts

tools/core/resolvers/dependency.resolver.ts is a file in Coordination Surface. 155 lines of code and 29 definitions.

import {
    BIN_FIELD,
    DEPENDENCY_FIELDS,
    INSTALL_ROOT,
    REACH_EXTENSIONS,
    SCRIPTS_FIELD,
    SPECIFIER_SEPARATOR,
    TYPE_PACKAGE_PREFIX,
} from "../constants/dependency.constants.ts";
import { basename, resolve } from "node:path";

import { existsSync, readFileSync } from "node:fs";
import { hasPrefix, splitWords } from "../predicates/text.predicate.ts";
import type { DependencyReach } from "../types/dependency.types.ts";
import { NODE_MODULES } from "../constants/path.constants.ts";
import { isObject } from "../predicates/schema.predicate.ts";
import { isUnreadableJson } from "../predicates/file.predicate.ts";
import { slotText } from "../../../config/surface.config.ts";
import { stringLiterals } from "../predicates/literal.predicate.ts";
import { walk } from "../iterators/file.iterator.ts";

const record = function record(value: unknown): Record<string, unknown> | null {
    return isObject(value) ? value : null;
};

const parse = function parse(path: string): Record<string, unknown> | null {
    try {
        return record(JSON.parse(readFileSync(path, "utf8")));
    } catch (error) {
        if (isUnreadableJson(error)) {
            return null;
        }
        throw error;
    }
};

export const declaredDependencies = function declaredDependencies(manifest: Record<string, unknown>): string[] {
    const out: string[] = [];
    for (const field of DEPENDENCY_FIELDS) {
        const held = record(manifest[field]);
        if (held === null) {
            continue;
        }
        for (const name of Object.keys(held)) {
            out.push(name);
        }
    }
    return out;
};

const invocableNames = function invocableNames(packageDir: string, name: string): string[] | null {
    const installed = parse(resolve(packageDir, INSTALL_ROOT, ...name.split(SPECIFIER_SEPARATOR), "package.json"));
    if (installed === null) {
        return null;
    }

    const bin = installed[BIN_FIELD];
    if (typeof bin === "string") {
        return [basename(bin), name];
    }

    const map = record(bin);
    if (map === null) {
        return [name];
    }
    return [...Object.keys(map), name];
};

const scriptTokens = function scriptTokens(manifest: Record<string, unknown>): string[] {
    const scripts = record(manifest[SCRIPTS_FIELD]);
    if (scripts === null) {
        return [];
    }

    const out: string[] = [];
    for (const command of Object.values(scripts)) {
        if (typeof command !== "string") {
            continue;
        }
        for (const token of splitWords(command)) {
            out.push(token);
        }
    }
    return out;
};

const corpusLiterals = function corpusLiterals(
    packageDir: string,
    manifestPath: string,
): { literals: Set<string>; tokens: Set<string>; corpus: string[] } {
    const literals = new Set<string>();
    const tokens = new Set<string>();
    const corpus: string[] = [];
    const skip = [NODE_MODULES, slotText("surface", "generated")];

    for (const file of walk({ extensions: REACH_EXTENSIONS, ignored: skip, root: packageDir })) {
        if (file === manifestPath) {
            continue;
        }
        corpus.push(file);
        for (const literal of stringLiterals(readFileSync(file, "utf8"))) {
            literals.add(literal.value);
            for (const word of splitWords(literal.value)) {
                tokens.add(word);
            }
        }
    }

    return { corpus, literals, tokens };
};

const reachedBySpecifier = function reachedBySpecifier(literals: ReadonlySet<string>, name: string): boolean {
    if (literals.has(name)) {
        return true;
    }
    const scoped = name + SPECIFIER_SEPARATOR;
    for (const literal of literals) {
        if (hasPrefix(literal, scoped)) {
            return true;
        }
    }
    return false;
};

const reachedAsTypePackage = function reachedAsTypePackage(literals: ReadonlySet<string>, name: string): boolean {
    if (!hasPrefix(name, TYPE_PACKAGE_PREFIX)) {
        return false;
    }
    return literals.has(name.slice(TYPE_PACKAGE_PREFIX.length));
};

type ReachState = "reached" | "undetermined" | "unreached";

const reachOf = function reachOf(
    packageDir: string,
    name: string,
    literals: ReadonlySet<string>,
    tokens: ReadonlySet<string>,
): ReachState {
    if (reachedBySpecifier(literals, name) || reachedAsTypePackage(literals, name) || tokens.has(name)) {
        return "reached";
    }

    const invocable = invocableNames(packageDir, name);
    if (invocable === null) {
        return "undetermined";
    }
    return invocable.some((invocation) => tokens.has(invocation)) ? "reached" : "unreached";
};

export const dependencyReach = function dependencyReach(packageDir: string, manifestPath: string): DependencyReach {
    const manifest = parse(manifestPath);
    if (manifest === null) {
        return { corpus: [], declared: [], reached: [], undetermined: [], unreached: [] };
    }

    const declared = declaredDependencies(manifest);
    const { literals, tokens, corpus } = corpusLiterals(packageDir, manifestPath);
    for (const token of scriptTokens(manifest)) {
        tokens.add(token);
    }

    const states = new Map(declared.map((name) => [name, reachOf(packageDir, name, literals, tokens)]));
    const named = (state: ReachState): string[] => declared.filter((name) => states.get(name) === state);

    return {
        corpus,
        declared,
        reached: named("reached"),
        undetermined: named("undetermined"),
        unreached: named("unreached"),
    };
};

export const installRootPresent = function installRootPresent(packageDir: string): boolean {
    return existsSync(resolve(packageDir, INSTALL_ROOT));
};