# ts-visio Feature Gap Analysis

## What the Library Currently Supports

- **Document**: Create, load (path/Buffer/ArrayBuffer/Uint8Array), save
- **Pages**: Add foreground/background pages, set background page, enumerate pages
- **Shapes**: Standard rectangles, foreign/image shapes, containers, lists, swimlane pools/lanes, tables, groups
- **Connectors**: Connect shapes with begin/end arrow styles; read connectors back via `page.getConnectors()`
- **Shape positioning**: `placeRightOf`, `placeBelow`, absolute position update
- **Shape data**: Custom properties (typed: string, number, boolean, date)
- **Hyperlinks**: External URLs, internal page links
- **Layers**: Add layers, assign shapes, update visibility/lock/print properties
- **Z-order**: Send to front / send to back
- **Container operations**: `addMember`, `addListItem`, `resizeToFit`
- **Style**: `fillColor`, `fontColor`, `bold`, `lineColor`, `linePattern`, `lineWeight`
- **Reading**: Read shapes from existing VSDX files
- **Validation**: Structural validation of VSDX package (required files, rels integrity, shape IDs, Connect references, master references)
- **High-level builders**: `SchemaDiagram` (ER diagrams with 1:1 / 1:N relations)

---

## Feature Gaps

### 1. Deletion / Mutation

- ~~`shape.delete()`~~ — ✅ Implemented (removes shape, orphaned Connects, and container Relationships)
- ~~`doc.deletePage(page)`~~ — ✅ Implemented (removes page file, rels, pages.xml entry, Content Types override, BackPage refs)
- ~~`layer.delete()`~~ — ✅ Implemented (`layer.delete()` removes row from PageSheet and cleans up LayerMember cells on all shapes)
- ~~`connector.delete()`~~ — ✅ Implemented (`Connector` class returned by `page.getConnectors()`)

---

### 2. Text Styling

`ShapeStyle` only covers `fillColor`, `fontColor`, and `bold`. Missing:

- ~~**Font family**~~ — ✅ Implemented (`fontFamily` prop, uses `FONT("name")` formula)
- ~~**Font size**~~ — ✅ Implemented (`fontSize` in points, stored as inches internally)
- ~~**Text alignment**~~ — ✅ Implemented (`horzAlign`: left/center/right/justify via Paragraph section; `verticalAlign`: top/middle/bottom as top-level shape cell)
- ~~**Italic / Underline / Strikethrough**~~ — ✅ Implemented (`italic`, `underline`, `strikethrough` on `NewShapeProps` and `ShapeStyle`; combined into `Style` bitmask in the Character section)
- ~~**Text margins**~~ — ✅ Implemented (`textMarginTop`, `textMarginBottom`, `textMarginLeft`, `textMarginRight` in inches; written to the `TextBlock` section)
- ~~**Paragraph spacing**~~ — ✅ Implemented (`spaceBefore`, `spaceAfter` in points; `lineSpacing` as a multiplier; written to the `Paragraph` section)

---

### 3. Shape Transformations

- ~~**Rotation**~~ — ✅ Implemented (`shape.rotate(degrees)` / `shape.angle` getter; stored as radians in `Angle` cell)
- ~~**Flip**~~ — ✅ Implemented (`shape.flipX(enabled?)` / `shape.flipY(enabled?)` via `FlipX`/`FlipY` cells)
- ~~**Resize**~~ — ✅ Implemented (`shape.resize(width, height)`; updates Width, Height, LocPinX, LocPinY, and Geometry cache)

---

### 4. Non-Rectangular Geometry

- ~~**Ellipse / circle**~~ — ✅ Implemented (Visio `Ellipse` row; `geometry: 'ellipse'`)
- ~~**Rounded rectangle**~~ — ✅ Implemented (`EllipticalArcTo` corners; `geometry: 'rounded-rectangle'`, optional `cornerRadius` in inches)
- ~~**Diamond / rhombus**~~ — ✅ Implemented (4-vertex polygon starting at top; `geometry: 'diamond'`)
- ~~**Flowchart primitives**~~ — ✅ Implemented: `'triangle'` (right-pointing), `'parallelogram'` (Data/IO shape, 20% skew)

---

### 5. Reading Data Back from Existing Shapes

`ShapeReader` parses `Sections` internally but they are not surfaced through the `Shape` public API:

- ~~`shape.getProperties()`~~ — ✅ Implemented (typed value coercion: String, Number, Boolean, Date)
- ~~`shape.getHyperlinks()`~~ — ✅ Implemented (address, subAddress, description, newWindow)
- ~~`shape.getLayerIndices()`~~ — ✅ Implemented (returns `number[]`)
- ~~`page.getConnectors()`~~ — ✅ Implemented (returns `Connector[]` with `fromShapeId`, `toShapeId`, `fromPort`, `toPort`, `style`, `beginArrow`, `endArrow`, and `delete()`)
- ~~`page.getLayers()`~~ — ✅ Implemented (returns `Layer[]` with `visible`/`locked` state; `layer.rename()`, `layer.delete()`)
- ~~Sub-shapes of groups accessible via `shape.getChildren()`~~ — ✅ Implemented (`ShapeReader.readChildShapes`; `shape.isGroup`, `shape.type`)

---

### 6. Page Operations

- ~~`doc.getPage(name)`~~ — ✅ Implemented (exact name match, case-sensitive)
- ~~`doc.renamePage(page, newName)`~~ — ✅ Implemented (updates pages.xml and in-memory `page.name`)
- ~~`doc.deletePage(page)`~~ — ✅ Implemented (removes page file, rels, pages.xml entry, Content Types override, BackPage refs)
- ~~Page reordering (`doc.movePage(page, toIndex)`~~) — ✅ Implemented (clamps to valid range)
- ~~Page duplication (`doc.duplicatePage(page, newName?)`~~) — ✅ Implemented (copies XML + rels, inserts adjacent to source)
- ~~**Page size / orientation**~~ — ✅ Implemented (`page.setSize(w, h)`, `page.setNamedSize('A4')`, `page.setOrientation('landscape')`, `page.pageWidth`, `page.pageHeight`, `page.orientation`; `PageSizes` constant exported)
- ~~**Drawing scale**~~ — ✅ Implemented (`page.setDrawingScale(pageScale, pageUnit, drawingScale, drawingUnit)`, `page.getDrawingScale()`, `page.clearDrawingScale()`; `LengthUnit` and `DrawingScaleInfo` exported; reads/writes `PageScale`/`DrawingScale` PageSheet cells with `Unit` attribute; treats `Unit="MSG"` as no-scale sentinel)

---

### 7. Connector Styling

- ~~**Line color, weight, and pattern**~~ — ✅ Implemented (`ConnectorStyle.lineColor`, `lineWeight` in pt, `linePattern`)
- ~~**Routing style**~~ — ✅ Implemented (`ConnectorStyle.routing`: `'straight'` / `'orthogonal'` / `'curved'`; maps to Visio `ShapeRouteStyle` 2/1/16)
- ~~**Named connection points**~~ — ✅ Implemented (`ConnectionPointDef`, `ConnectionTarget`, `StandardConnectionPoints` presets; `connectionPoints` prop on `addShape`; `shape.addConnectionPoint()`; `fromPort`/`toPort` on `connectShapes`/`connectTo`; encodes `ToPart=100+IX` / `ToCell=Connections.X{n}` per Visio spec)

---

### 8. Document-Level Properties

- ~~**Document metadata**~~ — ✅ Implemented (`doc.setMetadata(props)`, `doc.getMetadata()`; writes `docProps/core.xml` and `docProps/app.xml`; supports title, author, description, keywords, lastModifiedBy, company, manager, created, modified)
- ~~**StyleSheet**~~ — ✅ Implemented (`doc.createStyle(name, props)`, `doc.getStyles()`, `shape.applyStyle(id)`, `addShape({ styleId })`, `StyleSheetManager` in `visio/document.xml`)
- ~~**Color palette**~~ — ✅ Implemented (`doc.addColor(hex)`, `doc.getColors()`, `doc.getColorIndex(hex)`; de-duplicates; built-in black/white at indices 0/1)

---

### 9. Masters / Stencils

`MasterManager` exists internally but has no public API:

- No public method to create or import master shapes
- No way to load a `.vssx` stencil file and use its masters
- The `masterId` mechanism works for referencing existing masters, but creating them from scratch is not supported

---

### 10. Missing Public Exports

- ~~`SchemaDiagram`~~ — ✅ Exported
- ~~`VisioValidator`~~ — ✅ Exported
- ~~`Layer`~~ — ✅ Exported

---

### 11. API Ergonomics

- ~~`page.findShapes(predicate)`~~ — ✅ Implemented (searches all shapes including nested group children)
- ~~`page.getShapeById(id)`~~ — ✅ Implemented (recursive search through group tree)
- ~~`doc.getPage(name)`~~ — ✅ Implemented (exact name match, case-sensitive)
- ~~`shape.getChildren()`~~ — ✅ Implemented (direct children of groups/containers; `shape.isGroup`, `shape.type`)
- ~~`Shape.setStyle` only accepts `ShapeStyle` which does not cover line style~~  — ✅ Implemented (`lineColor`, `lineWeight` (pt), `linePattern` added to `ShapeStyle`; `setStyle({ lineColor: '#cc0000' })` works post-creation)

---

## Priority Ranking

| Priority | Gap |
|----------|-----|
| ✅ Done | Font size & family, text alignment |
| ✅ Done | `deleteShape`, `deletePage` |
| ✅ Done | `page.getShapeById`, `page.findShapes`, `doc.getPage(name)` |
| ✅ Done | Read properties/hyperlinks/layer indices back from existing shapes |
| ✅ Done | Rotation, flip, and resize via `Shape` API |
| ✅ Done | Non-rectangular geometry (ellipse, diamond, rounded-rect, triangle, parallelogram) |
| ✅ Done | Connector routing style and line styling |
| ✅ Done | Missing exports (`Layer`, `SchemaDiagram`, `VisioValidator`) |
| ✅ Done | Page size / orientation API (`PageSizes`, `setSize`, `setNamedSize`, `setOrientation`) |
| ✅ Done | Document metadata (`setMetadata`, `getMetadata` on `VisioDocument`) |
| ✅ Done | `layer.delete()`, `layer.rename()`, `page.getLayers()` |
| ✅ Done | `shape.getChildren()`, `shape.isGroup`, `shape.type` |
| ✅ Done | `doc.renamePage()`, `doc.movePage()`, `doc.duplicatePage()` |
| ✅ Done | Color palette (`doc.addColor`, `getColors`, `getColorIndex`) |
| ✅ Done | Drawing scale (`setDrawingScale`, `getDrawingScale`, `clearDrawingScale`; `LengthUnit`, `DrawingScaleInfo`) |
| 🟢 Low | Masters / stencils public API |
| ✅ Done | Rich text formatting (italic, underline, strikethrough, text margins, paragraph spacing) |
| ✅ Done | Named connection points (`ConnectionPointDef`, `StandardConnectionPoints`, port-aware connectors) |
| ✅ Done | StyleSheet — document-level styles (`createStyle`, `getStyles`, `applyStyle`, `styleId` on shapes) |
| ✅ Done | `page.getConnectors()` — read connectors from loaded files; `Connector` class with `fromShapeId`, `toShapeId`, `style`, arrows, and `delete()` |
