core/validators/reason.reference.validator.ts
core/validators/reason.reference.validator.ts is a file in GovLab Context. 73 lines of code and 9 definitions.
import type { CollectionRefFaces, TargetResolverFaces } from "#types/reference.types";
import { ID_LABEL_SEPARATORS, LABEL_SPACE } from "#configuration/constants/reference.constants";
import {
answerShapeMismatch,
collidingCell,
danglingConcept,
danglingEdgeSource,
danglingReasonField,
danglingTransition,
duplicateReasonId,
emptyReasonField,
unresolvedModelStep,
} from "#configuration/strings/validation.strings";
import { collectionRefResolver, resolveTarget } from "#core/resolvers/reference.resolver";
import type { ReasonOntologyIssues } from "#types/reason.types";
type EdgeFaces = TargetResolverFaces & { reason: { edges: () => { to?: string }[] } };
type LensFaces = TargetResolverFaces & { reason: { lenses: () => { detectedBy?: string[]; id: string }[] } };
export const unresolvedReasonEdgesOf = function unresolvedReasonEdgesOf(faces: EdgeFaces): string[] {
return faces.reason
.edges()
.filter((edge) => typeof edge.to === "string" && !resolveTarget(faces, edge.to))
.map((edge) => edge.to ?? "")
.toSorted((a, b) => a.localeCompare(b));
};
export const reasonDefectLines = function reasonDefectLines(issues: ReasonOntologyIssues): string[] {
return [
...issues.duplicateIds.map(duplicateReasonId),
...issues.danglingConcepts.map((entry) => danglingConcept(entry.node, entry.concept)),
...issues.danglingFields.map(danglingReasonField),
...issues.emptyFields.map(emptyReasonField),
...issues.danglingTransitions.map(danglingTransition),
...issues.danglingEdgeSources.map(danglingEdgeSource),
...issues.collidingSurfaceCells.map((entry) => collidingCell(entry.cell, entry.surfaces)),
...issues.answerShapeMismatches.map(answerShapeMismatch),
...issues.unresolvedModelSteps.map(unresolvedModelStep),
];
};
export const unresolvedLensDetectorsOf = function unresolvedLensDetectorsOf(
faces: LensFaces,
): { lens: string; target: string }[] {
return faces.reason
.lenses()
.flatMap((lens) =>
(lens.detectedBy ?? [])
.filter((target) => !resolveTarget(faces, target))
.map((target) => ({ lens: lens.id, target })),
);
};
export const unresolvedShapeInstancesOf = function unresolvedShapeInstancesOf(
faces: CollectionRefFaces & { reason: { failureShapes: () => { id: string; instances: readonly string[] }[] } },
): { shape: string; instance: string }[] {
const resolve = collectionRefResolver(faces);
return faces.reason
.failureShapes()
.flatMap((shape) =>
shape.instances.filter((instance) => !resolve(instance)).map((instance) => ({ instance, shape: shape.id })),
);
};
const isIdShaped = function isIdShaped(label: string): boolean {
return !label.includes(LABEL_SPACE) && ID_LABEL_SEPARATORS.some((separator) => label.includes(separator));
};
export const idShapedEdgeLabelsOf = function idShapedEdgeLabelsOf(
faces: CollectionRefFaces & { reason: { edges: () => { from: string; label?: string }[] } },
): { from: string; label: string }[] {
const resolve = collectionRefResolver(faces);
return faces.reason
.edges()
.flatMap((edge) =>
typeof edge.label === "string" && isIdShaped(edge.label) && !resolve(edge.label)
? [{ from: edge.from, label: edge.label }]
: [],
);
};