collab/mermaid/packages/parser/src/language/treemap/treemap-validator.tsblame
View source
6dd74de1import type { ValidationAcceptor, ValidationChecks } from 'langium';
6dd74de2import type { MermaidAstType, Treemap } from '../generated/ast.js';
6dd74de3import type { TreemapServices } from './module.js';
6dd74de4
6dd74de5/**
6dd74de6 * Register custom validation checks.
6dd74de7 */
6dd74de8export function registerValidationChecks(services: TreemapServices) {
6dd74de9 const validator = services.validation.TreemapValidator;
6dd74de10 const registry = services.validation.ValidationRegistry;
6dd74de11 if (registry) {
6dd74de12 // Use any to bypass type checking since we know Treemap is part of the AST
6dd74de13 // but the type system is having trouble with it
6dd74de14 const checks: ValidationChecks<MermaidAstType> = {
6dd74de15 Treemap: validator.checkSingleRoot.bind(validator),
6dd74de16 // Remove unused validation for TreemapRow
6dd74de17 };
6dd74de18 registry.register(checks, validator);
6dd74de19 }
6dd74de20}
6dd74de21
6dd74de22/**
6dd74de23 * Implementation of custom validations.
6dd74de24 */
6dd74de25export class TreemapValidator {
6dd74de26 /**
6dd74de27 * Validates that a treemap has only one root node.
6dd74de28 * A root node is defined as a node that has no indentation.
6dd74de29 */
6dd74de30 checkSingleRoot(doc: Treemap, accept: ValidationAcceptor): void {
6dd74de31 let rootNodeIndentation;
6dd74de32
6dd74de33 for (const row of doc.TreemapRows) {
6dd74de34 // Skip non-node items or items without a type
6dd74de35 if (!row.item) {
6dd74de36 continue;
6dd74de37 }
6dd74de38
6dd74de39 if (
6dd74de40 rootNodeIndentation === undefined && // Check if this is a root node (no indentation)
6dd74de41 row.indent === undefined
6dd74de42 ) {
6dd74de43 rootNodeIndentation = 0;
6dd74de44 } else if (row.indent === undefined) {
6dd74de45 // If we've already found a root node, report an error
6dd74de46 accept('error', 'Multiple root nodes are not allowed in a treemap.', {
6dd74de47 node: row,
6dd74de48 property: 'item',
6dd74de49 });
6dd74de50 } else if (
6dd74de51 rootNodeIndentation !== undefined &&
6dd74de52 rootNodeIndentation >= parseInt(row.indent, 10)
6dd74de53 ) {
6dd74de54 accept('error', 'Multiple root nodes are not allowed in a treemap.', {
6dd74de55 node: row,
6dd74de56 property: 'item',
6dd74de57 });
6dd74de58 }
6dd74de59 }
6dd74de60 }
6dd74de61}