Files
diagrams-drawio/scripts/src/actions/page-labels-validation/action.ts
T
oleg-lukasonokandClaude Fable 5 77655d1d97 Restructure to skill-manager conventions
- Move the TypeScript project under scripts/ (src, tsconfig,
  package.json, pnpm lockfile/workspace, canonical .gitignore);
  drop the npm package-lock
- Add scripts/Taskfile.yml aggregator plus .scripts modules
  (loggers, base, cli) with build, run, and validate tasks
- Move the six SKILL-*.md docs into references/ with kebab names
  and extract the connector-routing sections from SKILL.md into
  references/routing-best-practices.md (SKILL.md 666 -> ~310 lines)
- Add license/metadata/compatibility frontmatter, an Available
  scripts section, and update all CLI paths in README and references

skill-manager validate: 13/13 passed, 0 warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 15:20:26 +03:00

78 lines
2.1 KiB
TypeScript

/**
* Action: page-labels-validation
*
* Validates shape labels on a single page and reports three categories of issues:
* 1. empty_label — shape has no label (or whitespace only)
* 2. duplicate_label — two or more shapes share the same label
* 3. long_label — label exceeds MAX_LABEL_LENGTH characters
*
* Edges are excluded (connectors often have no label by design).
*/
import { parseDiagram } from "../../services/drawio-parser/parser.js";
const MAX_LABEL_LENGTH = 80;
export function run(filePath: string): Record<string, unknown> {
const { shapes } = parseDiagram(filePath);
const issues: Record<string, unknown>[] = [];
// Track label → [ids] for duplicate detection
const labelIndex = new Map<string, string[]>();
for (const [id, shape] of shapes) {
const label = shape.label?.trim() ?? "";
// 1. Empty label
if (label === "") {
issues.push({ type: "empty_label", shapeId: id });
continue; // skip further checks for unlabelled shapes
}
// 2. Long label
if (label.length > MAX_LABEL_LENGTH) {
issues.push({
type: "long_label",
shapeId: id,
label,
length: label.length,
maxAllowed: MAX_LABEL_LENGTH,
});
}
// Accumulate for duplicate check
if (!labelIndex.has(label)) labelIndex.set(label, []);
labelIndex.get(label)!.push(id);
}
// 3. Duplicate labels
for (const [label, ids] of labelIndex) {
if (ids.length > 1) {
issues.push({
type: "duplicate_label",
label,
shapeIds: ids,
count: ids.length,
});
}
}
const empty = issues.filter((i) => i["type"] === "empty_label").length;
const duplicate = issues.filter((i) => i["type"] === "duplicate_label").length;
const long = issues.filter((i) => i["type"] === "long_label").length;
return {
action: "page-labels-validation",
file: filePath,
config: { maxLabelLength: MAX_LABEL_LENGTH },
summary: {
emptyLabels: empty,
duplicateLabels: duplicate,
longLabels: long,
totalIssues: issues.length,
},
issues,
};
}