core/factories/document.factory.ts
core/factories/document.factory.ts is a file in GovLab Docs. 96 lines of code and 18 definitions.
import type {
ArchPort,
ConceptRecord,
ContextDeps,
Manifest,
ModuleDocs,
ModuleDocsOptions,
PrincipleRecord,
RenderContext,
RepoMetrics,
} from "#types/readme.types";
import type { DocRegistries, LocationOptions } from "#types/location.types";
import { basename, resolve } from "node:path";
import { governConcepts, governPrinciples, ontologyDuplicateFindings } from "#core/validators/governance.validator";
import { governDeclaredDocs, governManifest } from "#core/validators/manifest.prose.validator";
import { readManifest, readPackageJson } from "#core/loaders/manifest.loader";
import { DEFAULT_ROOT_PREFIX } from "#configuration/constants/document.constants";
import { DOC_FORMS } from "#configuration/constants/form.constants";
import { PACKAGE_SCOPE } from "#configuration/constants/manifest.constants";
import { VCS_DIRECTORY } from "#configuration/constants/vcs.constants";
import { declaredDocLocation } from "#core/resolvers/location.resolver";
import { existsSync } from "node:fs";
import { generateModuleDoc } from "#core/formatters/readme.formatter";
import { readPublicSurface } from "#core/analyzers/surface.analyzer";
import { renderDeclaredDoc } from "#core/formatters/document.formatter";
const REPO_METRICS_KEY = "repoMetrics";
const resolvePrinciples = function resolvePrinciples(manifest: Manifest, archRelations: ArchPort): PrincipleRecord[] {
const ids = manifest.governance?.principles;
return Array.isArray(ids) && ids.length > 0 ? archRelations.resolve(ids).principles : [];
};
const resolveConcepts = function resolveConcepts(manifest: Manifest, slug: string, deps: ContextDeps): ConceptRecord[] {
const declared = Array.isArray(manifest.governedBy) && manifest.governedBy.length > 0 ? manifest.governedBy : null;
const ids = declared ?? deps.deriveGovernedBy(slug) ?? [];
return ids.flatMap((id) => {
const concept = deps.conceptMap.get(id);
return concept === undefined ? [] : [{ dimension: concept.dimension, id: concept.id }];
});
};
const repoMetricsFor = function repoMetricsFor(
manifest: Manifest,
moduleDir: string,
deps: ContextDeps,
): RepoMetrics | null {
const derive = deps.deriveRepoMetrics;
if (derive === undefined || manifest[REPO_METRICS_KEY] !== true || !existsSync(resolve(moduleDir, VCS_DIRECTORY))) {
return null;
}
return derive(moduleDir);
};
const buildContext = function buildContext(moduleDir: string, hasCharts: boolean, deps: ContextDeps): RenderContext {
const manifest = readManifest(moduleDir);
const pkg = readPackageJson(moduleDir);
const name = basename(moduleDir);
return {
concepts: resolveConcepts(manifest, name, deps),
docs: manifest.docs ?? {},
domains: Array.isArray(manifest.domains) ? manifest.domains : [],
hasCharts,
maturity: typeof manifest["maturity"] === "string" ? manifest["maturity"] : "",
moduleDir,
name,
pkg,
principles: resolvePrinciples(manifest, deps.archRelations),
repo: repoMetricsFor(manifest, moduleDir, deps),
scoped: pkg.name ?? manifest.label ?? `${PACKAGE_SCOPE}${name}`,
summary: manifest.summary ?? "",
surface: readPublicSurface(moduleDir, pkg).surface,
};
};
export const createModuleDocs = function createModuleDocs(options: ModuleDocsOptions): ModuleDocs {
const { archRelations, conceptMap, consumerRoot, hostTokens } = options;
const registries: DocRegistries = {
concerns: options.docConcerns,
forms: options.docForms ?? DOC_FORMS,
owners: options.docMembers,
};
const locationOptions: LocationOptions = { rootPrefix: DEFAULT_ROOT_PREFIX };
const declaredContext = { consumerRoot, hostTokens, options: locationOptions, registries };
const contextDeps: ContextDeps = {
archRelations,
conceptMap,
deriveGovernedBy: options.deriveGovernedBy,
deriveRepoMetrics: options.deriveRepoMetrics,
};
return {
declaredDocLocation: (doc) => declaredDocLocation(doc, registries, locationOptions),
generateReadme: (moduleDir, hasCharts = false) =>
generateModuleDoc(buildContext(moduleDir, hasCharts, contextDeps)),
governConcepts: (manifest) => governConcepts(manifest, conceptMap),
governDeclaredDocs: (module) => governDeclaredDocs(module, declaredContext),
governManifest: (module) => governManifest(module, consumerRoot, hostTokens),
governPrinciples: (manifest) => governPrinciples(manifest, archRelations),
ontologyDuplicates: () => ontologyDuplicateFindings(archRelations),
renderDeclaredDoc,
};
};