core/factories/context.factory.ts
core/factories/context.factory.ts is a file in GovLab Patterns. 43 lines of code and 11 definitions.
import type { ModuleEdge, ModuleUnit } from "#types/code.types";
import type { ModuleScope, RepoContext } from "#types/package.types";
import { buildPackageMap, sourceFiles } from "#core/loaders/package.loader";
import { relative, sep } from "node:path";
import { crossModuleFanIn } from "#core/counters/dependency.counter";
import { ingestImports } from "#core/parsers/code.parser";
import { moduleImportCycleFindings } from "#core/analyzers/dependency.analyzer";
import { readSourceOrEmpty } from "#core/loaders/source.loader";
const PATH_SEP = "/";
const importsOf = async function importsOf(moduleDir: string, scope: ModuleScope): Promise<ModuleUnit> {
const files = sourceFiles(moduleDir, scope.pruned);
const perFile = await Promise.all(files.map(async (file) => ingestImports(readSourceOrEmpty(file), file)));
return { imports: perFile.flat(), moduleDir };
};
const importEdges = function importEdges(
units: readonly ModuleUnit[],
packageMap: ReadonlyMap<string, string>,
): ModuleEdge[] {
return units.flatMap((unit) =>
unit.imports.flatMap((binding) => {
const target = packageMap.get(binding.source);
return target !== undefined && target !== unit.moduleDir ? [{ from: unit.moduleDir, to: target }] : [];
}),
);
};
export const buildContext = async function buildContext(
modules: readonly string[],
scope: ModuleScope,
): Promise<RepoContext> {
const packageMap = buildPackageMap(modules);
const units = await Promise.all(modules.map(async (moduleDir) => importsOf(moduleDir, scope)));
const repoRel = function repoRel(file: string): string {
return relative(scope.root, file).split(sep).join(PATH_SEP);
};
return {
fanIn: crossModuleFanIn(units, packageMap),
importCycles: moduleImportCycleFindings(importEdges(units, packageMap), repoRel),
packageMap,
};
};
export const emptyContext = function emptyContext(): RepoContext {
return { fanIn: new Map(), importCycles: new Map(), packageMap: new Map() };
};