169 lines
5.7 KiB
Markdown
169 lines
5.7 KiB
Markdown
# drawio-main
|
||
|
||
TypeScript tools for deterministic YAML-to-Draw.io generation, analysis, and verification.
|
||
|
||
Built with TypeScript using [`@maxgraph/core`](https://github.com/maxGraph/maxGraph) — the official TypeScript successor to mxGraph (the library draw.io is built on) — for accurate XML parsing and absolute coordinate resolution.
|
||
|
||
## Stack
|
||
|
||
| Concern | Choice |
|
||
|---|---|
|
||
| Language | TypeScript (ESM, `NodeNext`) |
|
||
| Package manager | pnpm |
|
||
| XML / model parsing | `@maxgraph/core` v0.23 |
|
||
| Node.js DOM polyfill | `jsdom` |
|
||
| `<mxfile>` decoding | `pako` (base64 + deflate) |
|
||
| Output | YAML (via `js-yaml`) |
|
||
|
||
## Install
|
||
|
||
```bash
|
||
cd scripts
|
||
pnpm install
|
||
```
|
||
|
||
## Build
|
||
|
||
```bash
|
||
cd scripts
|
||
task build # or: pnpm run build
|
||
# compiled output → scripts/dist/
|
||
```
|
||
|
||
## Usage
|
||
|
||
```bash
|
||
cd scripts
|
||
task run -- --file="diagram.drawio" --action=<action> [--page <index>]
|
||
# or directly:
|
||
node dist/cli/commands.js --file diagram.drawio --action <action> [--page <index>]
|
||
|
||
# Build from semantic YAML Diagram IR:
|
||
node dist/cli/commands.js --action build --file architecture.yaml --output architecture.drawio
|
||
```
|
||
|
||
Output is always YAML to stdout.
|
||
|
||
## Actions
|
||
|
||
### Authoring
|
||
|
||
#### `build`
|
||
|
||
Validates a versioned YAML Diagram IR and emits deterministic native Draw.io XML.
|
||
|
||
- **v1 remains supported** for single-page linear diagrams.
|
||
- **v2** adds multiple pages, containers and semantic kinds, explicit geometry, edge waypoints, provenance/properties/extensions, and typed layout options.
|
||
- `linear`, `layered`, `tree`, `grid`, and `manual` layouts are supported. Layered/tree layouts use deterministic dependency-aware placement.
|
||
- Generated connectors receive deterministic obstacle-aware orthogonal waypoints when a clear route is available.
|
||
- Duplicate/reserved IDs, invalid dimensions, unknown parents, and unknown edge endpoints fail before output is written.
|
||
|
||
See `examples/platform-v2.yaml` and `schemas/diagram-ir-v2.schema.json`.
|
||
|
||
---
|
||
|
||
### Inventory
|
||
|
||
#### `summary`
|
||
|
||
Parses **all pages (tabs)** in the `.drawio` file and returns a full inventory of shapes and edges per page. Delegates per-page data to the same logic as `page-summary`.
|
||
|
||
**Output:** `pageCount`, `pages[]` (each page has the same structure as `page-summary`)
|
||
|
||
---
|
||
|
||
#### `page-summary`
|
||
|
||
Parses a **single page**. Use `--page <index>` (0-based, default `0`).
|
||
|
||
**Output:** `pageCount`, `pageIndex`, `pageName`, `page` (width/height), `summary` (shapeCount, edgeCount, contentRight, contentBottom), `shapes[]`, `edges[]`
|
||
|
||
---
|
||
|
||
#### `page-hierarchy`
|
||
|
||
Reads `parentId` from each shape and builds a **recursive containment tree**:
|
||
- Depth 0 — layers / top-level containers (direct children of the canvas)
|
||
- Depth 1 — subsystems / groups inside a layer
|
||
- Depth 2+ — leaf components and nested elements
|
||
|
||
**Output:** `summary` (totalShapes, maxDepth, depthCounts), `tree[]` (recursive: id, label, depth, childCount, children[])
|
||
|
||
---
|
||
|
||
#### `page-connectors-summary`
|
||
|
||
Returns a summary of all **connectors (edges)** on the page, classified by type and connectivity.
|
||
|
||
Connector types: `directed` (both endpoints connected), `partial` (one missing), `floating` (both missing)
|
||
|
||
**Output:** `summary` (total, directed, partial, floating, labelled, unlabelled, withWaypoints, straight), `connectors[]` (id, label, sourceId, sourceLabel, targetId, targetLabel, waypointCount, type)
|
||
|
||
---
|
||
|
||
### Validation
|
||
|
||
#### `quality`
|
||
|
||
Runs objective visual-quality checks across every page: page clipping, likely text overflow, placeholder text, external image URLs, palette spread, page density, and edge density. Findings have explicit `error` or `warning` severity; the action never invents a minimum defect count.
|
||
|
||
**Output:** `summary` (pages, shapes, edges, errors, warnings), `issues[]`
|
||
|
||
---
|
||
|
||
#### `page-connectors-validation`
|
||
|
||
Detects two categories of layout defects on the first page:
|
||
1. **Connector-shape overlaps** — a connector segment passes through a shape it is not connected to
|
||
2. **Connector crossings** — two connectors intersect at an interior point
|
||
|
||
Uses 2 px tolerance. **Output:** `summary` (connectorShapeOverlaps, connectorCrossings, totalIssues), `issues[]`
|
||
|
||
---
|
||
|
||
#### `page-labels-validation`
|
||
|
||
Validates shape labels and flags:
|
||
1. **empty_label** — shape has no label (whitespace counts as empty)
|
||
2. **duplicate_label** — two or more shapes share the same label
|
||
3. **long_label** — label exceeds 80 characters
|
||
|
||
Edges/connectors are excluded. **Output:** `config` (maxLabelLength), `summary` (emptyLabels, duplicateLabels, longLabels, totalIssues), `issues[]`
|
||
|
||
---
|
||
|
||
#### `page-shape-bbox-validation`
|
||
|
||
Detects shapes whose **bounding boxes overlap** each other. Parent-child containment is intentional and is **not** flagged. Uses 2 px tolerance.
|
||
|
||
**Output:** `summary` (totalShapes, overlappingPairs), `issues[]` (shapeAId, shapeALabel, shapeBId, shapeBLabel, overlapX, overlapY)
|
||
|
||
---
|
||
|
||
#### `page-orphans`
|
||
|
||
Finds disconnected elements:
|
||
1. **isolated_shape** — shape with no edges connected to it
|
||
2. **dangling_connector** — edge missing its source and/or target shape
|
||
|
||
**Output:** `summary` (isolatedShapes, danglingConnectors, totalIssues), `issues[]`
|
||
|
||
---
|
||
|
||
### Layout
|
||
|
||
#### `page-recommendations`
|
||
|
||
Computes the bounding box of all shapes and recommends the smallest standard landscape page size that fits with an 80 px margin (first page).
|
||
|
||
Standard sizes: A4 (1169×827), A3 (1654×1169), A2 (2339×1654), A1 (3307×2339). Falls back to custom rounded size.
|
||
|
||
**Output:** `currentPage` (width, height, orientation), `contentBbox`, `required` (min size needed), `recommendedPage` (name, width, height), `checks` (contentFitsCurrentPage, hasAdequateMargin, isLandscape)
|
||
|
||
---
|
||
|
||
## Supported file formats
|
||
|
||
- Bare `<mxGraphModel>` XML files
|
||
- `<mxfile><diagram>…</diagram></mxfile>` wrappers (draw.io desktop format, base64+deflate encoded, multi-page supported)
|