ts-visio 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/dist/Layer.d.ts +14 -0
- package/dist/Layer.js +14 -0
- package/dist/Page.d.ts +81 -8
- package/dist/Page.js +86 -40
- package/dist/Shape.d.ts +15 -0
- package/dist/Shape.js +15 -0
- package/dist/VisioDocument.d.ts +18 -0
- package/dist/VisioDocument.js +18 -0
- package/dist/core/PageManager.d.ts +2 -3
- package/dist/core/PageManager.js +11 -59
- package/dist/diagrams/SchemaDiagram.d.ts +22 -0
- package/dist/diagrams/SchemaDiagram.js +36 -0
- package/dist/diagrams/SwimlanePattern.d.ts +14 -0
- package/dist/diagrams/SwimlanePattern.js +19 -0
- package/dist/diagrams/TablePattern.d.ts +11 -0
- package/dist/diagrams/TablePattern.js +44 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +6 -2
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# ts-visio
|
|
2
2
|
|
|
3
|
+
[](https://zimmermanw84.github.io/ts-visio/)
|
|
4
|
+
|
|
3
5
|
> [!WARNING]
|
|
4
6
|
> **Under Construction**
|
|
5
7
|
> This library is currently being developed with heavy assistance from AI and is primarily an experimental project. Use with caution.
|
|
@@ -14,7 +16,7 @@ Built using specific schema-level abstractions to handle the complex internal st
|
|
|
14
16
|
- **Strict Typing**: Interact with `VisioPage`, `VisioShape`, and `VisioConnect` objects.
|
|
15
17
|
- **ShapeSheet Access**: Read `Cells`, `Rows`, and `Sections` directly.
|
|
16
18
|
- **Connections**: Analyze connectivity between shapes.
|
|
17
|
-
- **Modular Architecture**:
|
|
19
|
+
- **Modular Architecture**: Clean layered architecture — `VisioDocument` → `Page` → `Shape` is the full public surface; XML and OPC internals stay encapsulated.
|
|
18
20
|
- **Modify Content**: Update text content of shapes.
|
|
19
21
|
- **Create Shapes**: Rectangles, ellipses, diamonds, rounded rectangles, triangles, parallelograms.
|
|
20
22
|
- **Connect Shapes**: Dynamic connectors with arrow styles, line styling, and routing (straight / orthogonal / curved).
|
|
@@ -710,6 +712,16 @@ const styles = doc.getStyles();
|
|
|
710
712
|
`StyleProps` supports: `fillColor`, `lineColor`, `lineWeight` (pt), `linePattern`, `fontColor`, `fontSize` (pt), `bold`, `italic`, `underline`, `strikethrough`, `fontFamily`, `horzAlign`, `verticalAlign`, `spaceBefore`, `spaceAfter`, `lineSpacing`, `textMarginTop/Bottom/Left/Right` (in).
|
|
711
713
|
Local shape properties always override inherited stylesheet values.
|
|
712
714
|
|
|
715
|
+
The alignment and style types are exported for use in typed consumers:
|
|
716
|
+
|
|
717
|
+
```typescript
|
|
718
|
+
import type { HorzAlign, VertAlign, ShapeStyle } from 'ts-visio';
|
|
719
|
+
|
|
720
|
+
const style: ShapeStyle = { horzAlign: 'center', verticalAlign: 'middle', bold: true };
|
|
721
|
+
const align: HorzAlign = 'justify'; // 'left' | 'center' | 'right' | 'justify'
|
|
722
|
+
const valign: VertAlign = 'bottom'; // 'top' | 'middle' | 'bottom'
|
|
723
|
+
```
|
|
724
|
+
|
|
713
725
|
#### 30. Reading Connectors Back
|
|
714
726
|
Enumerate connectors on a page — including those loaded from an existing `.vsdx` file — and inspect or delete them.
|
|
715
727
|
|
package/dist/Layer.d.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { VisioPackage } from './VisioPackage';
|
|
2
2
|
import { ShapeModifier } from './ShapeModifier';
|
|
3
|
+
/**
|
|
4
|
+
* A named display layer on a Visio page.
|
|
5
|
+
*
|
|
6
|
+
* Layers control the visibility and printability of groups of shapes.
|
|
7
|
+
* Obtain instances via `page.getLayers()` or `page.addLayer()`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const annotations = await page.addLayer('Annotations');
|
|
12
|
+
* ann.setVisible(false); // hide all shapes on this layer
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @category Layers
|
|
16
|
+
*/
|
|
3
17
|
export declare class Layer {
|
|
4
18
|
name: string;
|
|
5
19
|
index: number;
|
package/dist/Layer.js
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Layer = void 0;
|
|
4
4
|
const ShapeModifier_1 = require("./ShapeModifier");
|
|
5
|
+
/**
|
|
6
|
+
* A named display layer on a Visio page.
|
|
7
|
+
*
|
|
8
|
+
* Layers control the visibility and printability of groups of shapes.
|
|
9
|
+
* Obtain instances via `page.getLayers()` or `page.addLayer()`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const annotations = await page.addLayer('Annotations');
|
|
14
|
+
* ann.setVisible(false); // hide all shapes on this layer
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @category Layers
|
|
18
|
+
*/
|
|
5
19
|
class Layer {
|
|
6
20
|
constructor(name, index, pageId, pkg, modifier, _visible = true, _locked = false) {
|
|
7
21
|
this.name = name;
|
package/dist/Page.d.ts
CHANGED
|
@@ -7,6 +7,21 @@ import { Shape } from './Shape';
|
|
|
7
7
|
import { MediaManager } from './core/MediaManager';
|
|
8
8
|
import { RelsManager } from './core/RelsManager';
|
|
9
9
|
import { Layer } from './Layer';
|
|
10
|
+
/**
|
|
11
|
+
* Represents a single page (tab) inside a Visio document.
|
|
12
|
+
*
|
|
13
|
+
* Obtain a `Page` instance from {@link VisioDocument.pages},
|
|
14
|
+
* {@link VisioDocument.addPage}, or {@link VisioDocument.getPage}.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const doc = await VisioDocument.create();
|
|
19
|
+
* const page = doc.pages[0];
|
|
20
|
+
* await page.addShape({ text: 'Hello', x: 1, y: 1, width: 2, height: 1 });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @category Pages
|
|
24
|
+
*/
|
|
10
25
|
export declare class Page {
|
|
11
26
|
private internalPage;
|
|
12
27
|
private pkg;
|
|
@@ -39,6 +54,10 @@ export declare class Page {
|
|
|
39
54
|
* Swaps width and height when the current orientation does not match the requested one.
|
|
40
55
|
*/
|
|
41
56
|
setOrientation(orientation: PageOrientation): this;
|
|
57
|
+
/**
|
|
58
|
+
* Return all top-level shapes on the page.
|
|
59
|
+
* Group children are not included; use {@link findShapes} to search the entire shape tree.
|
|
60
|
+
*/
|
|
42
61
|
getShapes(): Shape[];
|
|
43
62
|
/**
|
|
44
63
|
* Find a shape by its ID anywhere on the page, including shapes nested inside groups.
|
|
@@ -50,6 +69,29 @@ export declare class Page {
|
|
|
50
69
|
* the predicate. Equivalent to getAllShapes().filter(predicate).
|
|
51
70
|
*/
|
|
52
71
|
findShapes(predicate: (shape: Shape) => boolean): Shape[];
|
|
72
|
+
/**
|
|
73
|
+
* Add a new shape to the page and return a {@link Shape} handle to it.
|
|
74
|
+
*
|
|
75
|
+
* @param props Visual and text properties for the new shape.
|
|
76
|
+
* All geometry fields (`x`, `y`, `width`, `height`) are in inches.
|
|
77
|
+
* @param parentId Optional ID of an existing group shape to nest the new shape inside.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Plain rectangle
|
|
82
|
+
* const box = await page.addShape({ text: 'Server', x: 2, y: 3, width: 2, height: 1 });
|
|
83
|
+
*
|
|
84
|
+
* // Ellipse with styling
|
|
85
|
+
* await page.addShape({
|
|
86
|
+
* text: 'Start', x: 1, y: 1, width: 1.5, height: 1.5,
|
|
87
|
+
* geometry: 'ellipse', fillColor: '#4472C4', fontColor: '#ffffff',
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* // Master instance (shape defined by a reusable master)
|
|
91
|
+
* const m = doc.createMaster('Router', 'ellipse');
|
|
92
|
+
* await page.addShape({ text: '', x: 4, y: 2, width: 1, height: 1, masterId: m.id });
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
53
95
|
addShape(props: NewShapeProps, parentId?: string): Promise<Shape>;
|
|
54
96
|
/**
|
|
55
97
|
* Return all connector shapes on the page.
|
|
@@ -57,19 +99,50 @@ export declare class Page {
|
|
|
57
99
|
* and a `delete()` method to remove the connector.
|
|
58
100
|
*/
|
|
59
101
|
getConnectors(): Connector[];
|
|
102
|
+
/**
|
|
103
|
+
* Draw a connector (line/arrow) between two shapes on this page.
|
|
104
|
+
*
|
|
105
|
+
* @param fromShape Source shape.
|
|
106
|
+
* @param toShape Target shape.
|
|
107
|
+
* @param beginArrow Arrow head at the source end (use {@link ArrowHeads} constants).
|
|
108
|
+
* @param endArrow Arrow head at the target end (use {@link ArrowHeads} constants).
|
|
109
|
+
* @param style Line color, weight, pattern, and routing style.
|
|
110
|
+
* @param fromPort Named connection point on the source shape (e.g. `'Right'`).
|
|
111
|
+
* @param toPort Named connection point on the target shape (e.g. `'Left'`).
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* import { ArrowHeads } from 'ts-visio';
|
|
116
|
+
* const a = await page.addShape({ text: 'A', x: 1, y: 1, width: 1, height: 1 });
|
|
117
|
+
* const b = await page.addShape({ text: 'B', x: 4, y: 1, width: 1, height: 1 });
|
|
118
|
+
* await page.connectShapes(a, b, ArrowHeads.None, ArrowHeads.OpenArrow,
|
|
119
|
+
* { lineColor: '#333333', routing: 'orthogonal' });
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
60
122
|
connectShapes(fromShape: Shape, toShape: Shape, beginArrow?: string, endArrow?: string, style?: ConnectorStyle, fromPort?: ConnectionTarget, toPort?: ConnectionTarget): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Embed an image on the page and return the resulting Foreign shape.
|
|
125
|
+
*
|
|
126
|
+
* @param data Raw image bytes (PNG, JPEG, GIF, BMP, or TIFF).
|
|
127
|
+
* @param name Filename used to store the image inside the archive (e.g. `'logo.png'`).
|
|
128
|
+
* @param x Horizontal pin position in inches.
|
|
129
|
+
* @param y Vertical pin position in inches.
|
|
130
|
+
* @param width Display width in inches.
|
|
131
|
+
* @param height Display height in inches.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* import fs from 'fs';
|
|
136
|
+
* const imgBuffer = fs.readFileSync('./logo.png');
|
|
137
|
+
* await page.addImage(imgBuffer, 'logo.png', 1, 1, 2, 1);
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
61
140
|
addImage(data: Buffer, name: string, x: number, y: number, width: number, height: number): Promise<Shape>;
|
|
62
141
|
addContainer(props: NewShapeProps): Promise<Shape>;
|
|
63
142
|
addList(props: NewShapeProps, direction?: 'vertical' | 'horizontal'): Promise<Shape>;
|
|
64
|
-
/**
|
|
65
|
-
* Creates a Swimlane Pool (which is technically a Vertical List of Containers).
|
|
66
|
-
* @param props Visual properties
|
|
67
|
-
*/
|
|
143
|
+
/** Creates a Swimlane Pool (a vertical List of Containers). */
|
|
68
144
|
addSwimlanePool(props: NewShapeProps): Promise<Shape>;
|
|
69
|
-
/**
|
|
70
|
-
* Creates a Swimlane Lane (which is technically a Container).
|
|
71
|
-
* @param props Visual properties
|
|
72
|
-
*/
|
|
145
|
+
/** Creates a Swimlane Lane (a Container inside a pool). */
|
|
73
146
|
addSwimlaneLane(props: NewShapeProps): Promise<Shape>;
|
|
74
147
|
addTable(x: number, y: number, title: string, columns: string[]): Promise<Shape>;
|
|
75
148
|
addLayer(name: string, options?: {
|
package/dist/Page.js
CHANGED
|
@@ -10,6 +10,23 @@ const MediaManager_1 = require("./core/MediaManager");
|
|
|
10
10
|
const RelsManager_1 = require("./core/RelsManager");
|
|
11
11
|
const StubHelpers_1 = require("./utils/StubHelpers");
|
|
12
12
|
const Layer_1 = require("./Layer");
|
|
13
|
+
const TablePattern_1 = require("./diagrams/TablePattern");
|
|
14
|
+
const SwimlanePattern_1 = require("./diagrams/SwimlanePattern");
|
|
15
|
+
/**
|
|
16
|
+
* Represents a single page (tab) inside a Visio document.
|
|
17
|
+
*
|
|
18
|
+
* Obtain a `Page` instance from {@link VisioDocument.pages},
|
|
19
|
+
* {@link VisioDocument.addPage}, or {@link VisioDocument.getPage}.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const doc = await VisioDocument.create();
|
|
24
|
+
* const page = doc.pages[0];
|
|
25
|
+
* await page.addShape({ text: 'Hello', x: 1, y: 1, width: 2, height: 1 });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @category Pages
|
|
29
|
+
*/
|
|
13
30
|
class Page {
|
|
14
31
|
constructor(internalPage, pkg, media, rels, modifier) {
|
|
15
32
|
this.internalPage = internalPage;
|
|
@@ -73,6 +90,10 @@ class Page {
|
|
|
73
90
|
}
|
|
74
91
|
return this;
|
|
75
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Return all top-level shapes on the page.
|
|
95
|
+
* Group children are not included; use {@link findShapes} to search the entire shape tree.
|
|
96
|
+
*/
|
|
76
97
|
getShapes() {
|
|
77
98
|
const reader = new ShapeReader_1.ShapeReader(this.pkg);
|
|
78
99
|
try {
|
|
@@ -106,6 +127,29 @@ class Page {
|
|
|
106
127
|
.map(s => new Shape_1.Shape(s, this.id, this.pkg, this.modifier))
|
|
107
128
|
.filter(predicate);
|
|
108
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Add a new shape to the page and return a {@link Shape} handle to it.
|
|
132
|
+
*
|
|
133
|
+
* @param props Visual and text properties for the new shape.
|
|
134
|
+
* All geometry fields (`x`, `y`, `width`, `height`) are in inches.
|
|
135
|
+
* @param parentId Optional ID of an existing group shape to nest the new shape inside.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* // Plain rectangle
|
|
140
|
+
* const box = await page.addShape({ text: 'Server', x: 2, y: 3, width: 2, height: 1 });
|
|
141
|
+
*
|
|
142
|
+
* // Ellipse with styling
|
|
143
|
+
* await page.addShape({
|
|
144
|
+
* text: 'Start', x: 1, y: 1, width: 1.5, height: 1.5,
|
|
145
|
+
* geometry: 'ellipse', fillColor: '#4472C4', fontColor: '#ffffff',
|
|
146
|
+
* });
|
|
147
|
+
*
|
|
148
|
+
* // Master instance (shape defined by a reusable master)
|
|
149
|
+
* const m = doc.createMaster('Router', 'ellipse');
|
|
150
|
+
* await page.addShape({ text: '', x: 4, y: 2, width: 1, height: 1, masterId: m.id });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
109
153
|
async addShape(props, parentId) {
|
|
110
154
|
const newId = await this.modifier.addShape(this.id, props, parentId);
|
|
111
155
|
// Return a fresh Shape object representing the new shape
|
|
@@ -142,9 +186,46 @@ class Page {
|
|
|
142
186
|
return [];
|
|
143
187
|
}
|
|
144
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Draw a connector (line/arrow) between two shapes on this page.
|
|
191
|
+
*
|
|
192
|
+
* @param fromShape Source shape.
|
|
193
|
+
* @param toShape Target shape.
|
|
194
|
+
* @param beginArrow Arrow head at the source end (use {@link ArrowHeads} constants).
|
|
195
|
+
* @param endArrow Arrow head at the target end (use {@link ArrowHeads} constants).
|
|
196
|
+
* @param style Line color, weight, pattern, and routing style.
|
|
197
|
+
* @param fromPort Named connection point on the source shape (e.g. `'Right'`).
|
|
198
|
+
* @param toPort Named connection point on the target shape (e.g. `'Left'`).
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```typescript
|
|
202
|
+
* import { ArrowHeads } from 'ts-visio';
|
|
203
|
+
* const a = await page.addShape({ text: 'A', x: 1, y: 1, width: 1, height: 1 });
|
|
204
|
+
* const b = await page.addShape({ text: 'B', x: 4, y: 1, width: 1, height: 1 });
|
|
205
|
+
* await page.connectShapes(a, b, ArrowHeads.None, ArrowHeads.OpenArrow,
|
|
206
|
+
* { lineColor: '#333333', routing: 'orthogonal' });
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
145
209
|
async connectShapes(fromShape, toShape, beginArrow, endArrow, style, fromPort, toPort) {
|
|
146
210
|
await this.modifier.addConnector(this.id, fromShape.id, toShape.id, beginArrow, endArrow, style, fromPort, toPort);
|
|
147
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Embed an image on the page and return the resulting Foreign shape.
|
|
214
|
+
*
|
|
215
|
+
* @param data Raw image bytes (PNG, JPEG, GIF, BMP, or TIFF).
|
|
216
|
+
* @param name Filename used to store the image inside the archive (e.g. `'logo.png'`).
|
|
217
|
+
* @param x Horizontal pin position in inches.
|
|
218
|
+
* @param y Vertical pin position in inches.
|
|
219
|
+
* @param width Display width in inches.
|
|
220
|
+
* @param height Display height in inches.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* import fs from 'fs';
|
|
225
|
+
* const imgBuffer = fs.readFileSync('./logo.png');
|
|
226
|
+
* await page.addImage(imgBuffer, 'logo.png', 1, 1, 2, 1);
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
148
229
|
async addImage(data, name, x, y, width, height) {
|
|
149
230
|
const mediaPath = this.media.addMedia(name, data);
|
|
150
231
|
const rId = await this.rels.addImageRelationship(this.pagePath, mediaPath);
|
|
@@ -194,51 +275,16 @@ class Page {
|
|
|
194
275
|
});
|
|
195
276
|
return new Shape_1.Shape(internalStub, this.id, this.pkg, this.modifier);
|
|
196
277
|
}
|
|
197
|
-
/**
|
|
198
|
-
* Creates a Swimlane Pool (which is technically a Vertical List of Containers).
|
|
199
|
-
* @param props Visual properties
|
|
200
|
-
*/
|
|
278
|
+
/** Creates a Swimlane Pool (a vertical List of Containers). */
|
|
201
279
|
async addSwimlanePool(props) {
|
|
202
|
-
return
|
|
280
|
+
return SwimlanePattern_1.SwimlanePattern.addPool(this, props);
|
|
203
281
|
}
|
|
204
|
-
/**
|
|
205
|
-
* Creates a Swimlane Lane (which is technically a Container).
|
|
206
|
-
* @param props Visual properties
|
|
207
|
-
*/
|
|
282
|
+
/** Creates a Swimlane Lane (a Container inside a pool). */
|
|
208
283
|
async addSwimlaneLane(props) {
|
|
209
|
-
return
|
|
284
|
+
return SwimlanePattern_1.SwimlanePattern.addLane(this, props);
|
|
210
285
|
}
|
|
211
286
|
async addTable(x, y, title, columns) {
|
|
212
|
-
|
|
213
|
-
const headerHeight = 0.5;
|
|
214
|
-
const lineItemHeight = 0.25;
|
|
215
|
-
const bodyHeight = Math.max(0.5, columns.length * lineItemHeight + 0.1);
|
|
216
|
-
const totalHeight = headerHeight + bodyHeight;
|
|
217
|
-
// Group contains a header row and a body row; child coords are relative to the group origin.
|
|
218
|
-
const groupShape = await this.addShape({
|
|
219
|
-
text: '',
|
|
220
|
-
x, y, width, height: totalHeight,
|
|
221
|
-
type: 'Group'
|
|
222
|
-
});
|
|
223
|
-
const headerCenterY = bodyHeight + (headerHeight / 2);
|
|
224
|
-
await this.addShape({
|
|
225
|
-
text: title,
|
|
226
|
-
x: width / 2,
|
|
227
|
-
y: headerCenterY,
|
|
228
|
-
width, height: headerHeight,
|
|
229
|
-
fillColor: '#DDDDDD',
|
|
230
|
-
bold: true
|
|
231
|
-
}, groupShape.id);
|
|
232
|
-
const bodyCenterY = bodyHeight / 2;
|
|
233
|
-
await this.addShape({
|
|
234
|
-
text: columns.join('\n'),
|
|
235
|
-
x: width / 2,
|
|
236
|
-
y: bodyCenterY,
|
|
237
|
-
width, height: bodyHeight,
|
|
238
|
-
fillColor: '#FFFFFF',
|
|
239
|
-
fontColor: '#000000'
|
|
240
|
-
}, groupShape.id);
|
|
241
|
-
return groupShape;
|
|
287
|
+
return TablePattern_1.TablePattern.add(this, x, y, title, columns);
|
|
242
288
|
}
|
|
243
289
|
async addLayer(name, options) {
|
|
244
290
|
const info = await this.modifier.addLayer(this.id, name, options);
|
package/dist/Shape.d.ts
CHANGED
|
@@ -15,6 +15,21 @@ export interface ShapeHyperlink {
|
|
|
15
15
|
description?: string;
|
|
16
16
|
newWindow: boolean;
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* A handle to a single shape on a Visio page.
|
|
20
|
+
*
|
|
21
|
+
* Obtain instances via {@link Page.addShape}, {@link Page.getShapes},
|
|
22
|
+
* {@link Page.getShapeById}, or {@link Page.findShapes}.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const shape = await page.addShape({ text: 'Box', x: 1, y: 1, width: 2, height: 1 });
|
|
27
|
+
* await shape.setStyle({ fillColor: '#4472C4', fontColor: '#ffffff', bold: true });
|
|
28
|
+
* console.log(shape.id, shape.x, shape.y);
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @category Shapes
|
|
32
|
+
*/
|
|
18
33
|
export declare class Shape {
|
|
19
34
|
private internalShape;
|
|
20
35
|
private pageId;
|
package/dist/Shape.js
CHANGED
|
@@ -8,6 +8,21 @@ const VisioConstants_1 = require("./core/VisioConstants");
|
|
|
8
8
|
function fmtCoord(n) {
|
|
9
9
|
return parseFloat(n.toFixed(10)).toString();
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* A handle to a single shape on a Visio page.
|
|
13
|
+
*
|
|
14
|
+
* Obtain instances via {@link Page.addShape}, {@link Page.getShapes},
|
|
15
|
+
* {@link Page.getShapeById}, or {@link Page.findShapes}.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const shape = await page.addShape({ text: 'Box', x: 1, y: 1, width: 2, height: 1 });
|
|
20
|
+
* await shape.setStyle({ fillColor: '#4472C4', fontColor: '#ffffff', bold: true });
|
|
21
|
+
* console.log(shape.id, shape.x, shape.y);
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @category Shapes
|
|
25
|
+
*/
|
|
11
26
|
class Shape {
|
|
12
27
|
constructor(internalShape, pageId, pkg, modifier) {
|
|
13
28
|
this.internalShape = internalShape;
|
package/dist/VisioDocument.d.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { Page } from './Page';
|
|
2
2
|
import { DocumentMetadata, StyleProps, StyleRecord, ColorEntry, MasterRecord, ShapeGeometry } from './types/VisioTypes';
|
|
3
|
+
/**
|
|
4
|
+
* The root object for reading and writing Visio (`.vsdx`) files.
|
|
5
|
+
*
|
|
6
|
+
* Create a blank document with {@link VisioDocument.create} or load an existing
|
|
7
|
+
* file with {@link VisioDocument.load}. Call {@link VisioDocument.save} when done.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { VisioDocument } from 'ts-visio';
|
|
12
|
+
*
|
|
13
|
+
* const doc = await VisioDocument.create();
|
|
14
|
+
* const page = doc.pages[0];
|
|
15
|
+
* await page.addShape({ text: 'Hello, Visio!', x: 1, y: 1, width: 3, height: 1 });
|
|
16
|
+
* await doc.save('output.vsdx');
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @category Documents
|
|
20
|
+
*/
|
|
3
21
|
export declare class VisioDocument {
|
|
4
22
|
private pkg;
|
|
5
23
|
private pageManager;
|
package/dist/VisioDocument.js
CHANGED
|
@@ -42,6 +42,24 @@ const MediaManager_1 = require("./core/MediaManager");
|
|
|
42
42
|
const MetadataManager_1 = require("./core/MetadataManager");
|
|
43
43
|
const StyleSheetManager_1 = require("./core/StyleSheetManager");
|
|
44
44
|
const ColorManager_1 = require("./core/ColorManager");
|
|
45
|
+
/**
|
|
46
|
+
* The root object for reading and writing Visio (`.vsdx`) files.
|
|
47
|
+
*
|
|
48
|
+
* Create a blank document with {@link VisioDocument.create} or load an existing
|
|
49
|
+
* file with {@link VisioDocument.load}. Call {@link VisioDocument.save} when done.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* import { VisioDocument } from 'ts-visio';
|
|
54
|
+
*
|
|
55
|
+
* const doc = await VisioDocument.create();
|
|
56
|
+
* const page = doc.pages[0];
|
|
57
|
+
* await page.addShape({ text: 'Hello, Visio!', x: 1, y: 1, width: 3, height: 1 });
|
|
58
|
+
* await doc.save('output.vsdx');
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* @category Documents
|
|
62
|
+
*/
|
|
45
63
|
class VisioDocument {
|
|
46
64
|
constructor(pkg) {
|
|
47
65
|
this.pkg = pkg;
|
|
@@ -17,10 +17,9 @@ export declare class PageManager {
|
|
|
17
17
|
constructor(pkg: VisioPackage);
|
|
18
18
|
load(force?: boolean): PageEntry[];
|
|
19
19
|
createPage(name: string): Promise<string>;
|
|
20
|
-
/**
|
|
21
|
-
* Create a background page
|
|
22
|
-
*/
|
|
20
|
+
/** Create a background page. */
|
|
23
21
|
createBackgroundPage(name: string): Promise<string>;
|
|
22
|
+
private createPageInternal;
|
|
24
23
|
/**
|
|
25
24
|
* Delete a page and clean up all associated XML entries.
|
|
26
25
|
* Removes the page file, its .rels file, the entry in pages.xml,
|
package/dist/core/PageManager.js
CHANGED
|
@@ -79,63 +79,13 @@ class PageManager {
|
|
|
79
79
|
return this.pages;
|
|
80
80
|
}
|
|
81
81
|
async createPage(name) {
|
|
82
|
-
this.
|
|
83
|
-
let maxId = 0;
|
|
84
|
-
for (const p of this.pages) {
|
|
85
|
-
if (p.id > maxId)
|
|
86
|
-
maxId = p.id;
|
|
87
|
-
}
|
|
88
|
-
const newId = maxId + 1;
|
|
89
|
-
const fileName = `page${newId}.xml`;
|
|
90
|
-
const relativePath = `visio/pages/${fileName}`;
|
|
91
|
-
const pageContent = `<PageContents xmlns="${VisioConstants_1.XML_NAMESPACES.VISIO_MAIN}" xmlns:r="${VisioConstants_1.XML_NAMESPACES.RELATIONSHIPS_OFFICE}" xml:space="preserve">
|
|
92
|
-
<PageSheet LineStyle="0" FillStyle="0" TextStyle="0">
|
|
93
|
-
<Cell N="PageWidth" V="8.5"/>
|
|
94
|
-
<Cell N="PageHeight" V="11"/>
|
|
95
|
-
<Cell N="PageScale" V="1" Unit="MSG"/>
|
|
96
|
-
<Cell N="DrawingScale" V="1" Unit="MSG"/>
|
|
97
|
-
<Cell N="DrawingSizeType" V="0"/>
|
|
98
|
-
<Cell N="DrawingScaleType" V="0"/>
|
|
99
|
-
<Cell N="Inhibited" V="0"/>
|
|
100
|
-
<Cell N="UIVisibility" V="0"/>
|
|
101
|
-
<Cell N="PageDrawSizeType" V="0"/>
|
|
102
|
-
</PageSheet>
|
|
103
|
-
<Shapes/>
|
|
104
|
-
<Connects/>
|
|
105
|
-
</PageContents>`;
|
|
106
|
-
this.pkg.updateFile(relativePath, pageContent);
|
|
107
|
-
const ctPath = '[Content_Types].xml';
|
|
108
|
-
const parsedCt = this.parser.parse(this.pkg.getFileText(ctPath));
|
|
109
|
-
if (!parsedCt.Types.Override)
|
|
110
|
-
parsedCt.Types.Override = [];
|
|
111
|
-
if (!Array.isArray(parsedCt.Types.Override))
|
|
112
|
-
parsedCt.Types.Override = [parsedCt.Types.Override];
|
|
113
|
-
parsedCt.Types.Override.push({
|
|
114
|
-
'@_PartName': `/${relativePath}`,
|
|
115
|
-
'@_ContentType': VisioConstants_1.CONTENT_TYPES.VISIO_PAGE
|
|
116
|
-
});
|
|
117
|
-
this.pkg.updateFile(ctPath, (0, XmlHelper_1.buildXml)(this.builder, parsedCt));
|
|
118
|
-
const rId = await this.relsManager.ensureRelationship('visio/pages/pages.xml', fileName, VisioConstants_1.RELATIONSHIP_TYPES.PAGE);
|
|
119
|
-
const pagesPath = 'visio/pages/pages.xml';
|
|
120
|
-
const parsedPages = this.parser.parse(this.pkg.getFileText(pagesPath));
|
|
121
|
-
if (!parsedPages.Pages.Page)
|
|
122
|
-
parsedPages.Pages.Page = [];
|
|
123
|
-
if (!Array.isArray(parsedPages.Pages.Page))
|
|
124
|
-
parsedPages.Pages.Page = [parsedPages.Pages.Page];
|
|
125
|
-
parsedPages.Pages.Page.push({
|
|
126
|
-
'@_ID': newId.toString(),
|
|
127
|
-
'@_Name': name,
|
|
128
|
-
'@_NameU': name,
|
|
129
|
-
'Rel': { '@_r:id': rId }
|
|
130
|
-
});
|
|
131
|
-
this.pkg.updateFile(pagesPath, (0, XmlHelper_1.buildXml)(this.builder, parsedPages));
|
|
132
|
-
this.load(true);
|
|
133
|
-
return newId.toString();
|
|
82
|
+
return this.createPageInternal(name, false);
|
|
134
83
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Create a background page
|
|
137
|
-
*/
|
|
84
|
+
/** Create a background page. */
|
|
138
85
|
async createBackgroundPage(name) {
|
|
86
|
+
return this.createPageInternal(name, true);
|
|
87
|
+
}
|
|
88
|
+
async createPageInternal(name, isBackground) {
|
|
139
89
|
this.load();
|
|
140
90
|
let maxId = 0;
|
|
141
91
|
for (const p of this.pages) {
|
|
@@ -179,13 +129,15 @@ class PageManager {
|
|
|
179
129
|
parsedPages.Pages.Page = [];
|
|
180
130
|
if (!Array.isArray(parsedPages.Pages.Page))
|
|
181
131
|
parsedPages.Pages.Page = [parsedPages.Pages.Page];
|
|
182
|
-
|
|
132
|
+
const entry = {
|
|
183
133
|
'@_ID': newId.toString(),
|
|
184
134
|
'@_Name': name,
|
|
185
135
|
'@_NameU': name,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
136
|
+
};
|
|
137
|
+
if (isBackground)
|
|
138
|
+
entry['@_Background'] = '1';
|
|
139
|
+
entry['Rel'] = { '@_r:id': rId };
|
|
140
|
+
parsedPages.Pages.Page.push(entry);
|
|
189
141
|
this.pkg.updateFile(pagesPath, (0, XmlHelper_1.buildXml)(this.builder, parsedPages));
|
|
190
142
|
this.load(true);
|
|
191
143
|
return newId.toString();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Page } from '../Page';
|
|
2
|
+
import type { Shape } from '../Shape';
|
|
3
|
+
export type RelationType = '1:1' | '1:N';
|
|
4
|
+
export declare class SchemaDiagram {
|
|
5
|
+
private page;
|
|
6
|
+
constructor(page: Page);
|
|
7
|
+
/**
|
|
8
|
+
* Adds a table entity to the diagram.
|
|
9
|
+
* @param tableName Name of the table
|
|
10
|
+
* @param columns List of column names (e.g., "id: int")
|
|
11
|
+
* @param x X coordinate
|
|
12
|
+
* @param y Y coordinate
|
|
13
|
+
*/
|
|
14
|
+
addTable(tableName: string, columns: string[], x?: number, y?: number): Promise<Shape>;
|
|
15
|
+
/**
|
|
16
|
+
* Connects two tables with a specific relationship type.
|
|
17
|
+
* @param fromTable Source table shape
|
|
18
|
+
* @param toTable Target table shape
|
|
19
|
+
* @param type Relationship type ('1:1' or '1:N')
|
|
20
|
+
*/
|
|
21
|
+
addRelation(fromTable: Shape, toTable: Shape, type: RelationType): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SchemaDiagram = void 0;
|
|
4
|
+
class SchemaDiagram {
|
|
5
|
+
constructor(page) {
|
|
6
|
+
this.page = page;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Adds a table entity to the diagram.
|
|
10
|
+
* @param tableName Name of the table
|
|
11
|
+
* @param columns List of column names (e.g., "id: int")
|
|
12
|
+
* @param x X coordinate
|
|
13
|
+
* @param y Y coordinate
|
|
14
|
+
*/
|
|
15
|
+
async addTable(tableName, columns, x = 0, y = 0) {
|
|
16
|
+
return this.page.addTable(x, y, tableName, columns);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Connects two tables with a specific relationship type.
|
|
20
|
+
* @param fromTable Source table shape
|
|
21
|
+
* @param toTable Target table shape
|
|
22
|
+
* @param type Relationship type ('1:1' or '1:N')
|
|
23
|
+
*/
|
|
24
|
+
async addRelation(fromTable, toTable, type) {
|
|
25
|
+
let beginArrow = '0'; // No arrow at start
|
|
26
|
+
let endArrow = '1'; // Default standard arrow
|
|
27
|
+
if (type === '1:1') {
|
|
28
|
+
endArrow = '1'; // Standard Arrow
|
|
29
|
+
}
|
|
30
|
+
else if (type === '1:N') {
|
|
31
|
+
endArrow = '29'; // Crow's Foot
|
|
32
|
+
}
|
|
33
|
+
await this.page.connectShapes(fromTable, toTable, beginArrow, endArrow);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.SchemaDiagram = SchemaDiagram;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Page } from '../Page';
|
|
2
|
+
import type { Shape } from '../Shape';
|
|
3
|
+
import type { NewShapeProps } from '../types/VisioTypes';
|
|
4
|
+
/**
|
|
5
|
+
* Swimlane composition helpers.
|
|
6
|
+
*
|
|
7
|
+
* A swimlane diagram is modelled as a vertical List (the pool) containing
|
|
8
|
+
* one or more Containers (the lanes). Used by `page.addSwimlanePool()` and
|
|
9
|
+
* `page.addSwimlaneLane()`.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SwimlanePattern {
|
|
12
|
+
static addPool(page: Page, props: NewShapeProps): Promise<Shape>;
|
|
13
|
+
static addLane(page: Page, props: NewShapeProps): Promise<Shape>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SwimlanePattern = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Swimlane composition helpers.
|
|
6
|
+
*
|
|
7
|
+
* A swimlane diagram is modelled as a vertical List (the pool) containing
|
|
8
|
+
* one or more Containers (the lanes). Used by `page.addSwimlanePool()` and
|
|
9
|
+
* `page.addSwimlaneLane()`.
|
|
10
|
+
*/
|
|
11
|
+
class SwimlanePattern {
|
|
12
|
+
static async addPool(page, props) {
|
|
13
|
+
return page.addList(props, 'vertical');
|
|
14
|
+
}
|
|
15
|
+
static async addLane(page, props) {
|
|
16
|
+
return page.addContainer(props);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.SwimlanePattern = SwimlanePattern;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Page } from '../Page';
|
|
2
|
+
import type { Shape } from '../Shape';
|
|
3
|
+
/**
|
|
4
|
+
* High-level table composition: a group shape containing a shaded header row
|
|
5
|
+
* and a body row whose text lists the column names.
|
|
6
|
+
*
|
|
7
|
+
* Used by `page.addTable()` and `SchemaDiagram.addTable()`.
|
|
8
|
+
*/
|
|
9
|
+
export declare class TablePattern {
|
|
10
|
+
static add(page: Page, x: number, y: number, title: string, columns: string[]): Promise<Shape>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TablePattern = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* High-level table composition: a group shape containing a shaded header row
|
|
6
|
+
* and a body row whose text lists the column names.
|
|
7
|
+
*
|
|
8
|
+
* Used by `page.addTable()` and `SchemaDiagram.addTable()`.
|
|
9
|
+
*/
|
|
10
|
+
class TablePattern {
|
|
11
|
+
static async add(page, x, y, title, columns) {
|
|
12
|
+
const width = 3;
|
|
13
|
+
const headerHeight = 0.5;
|
|
14
|
+
const lineItemHeight = 0.25;
|
|
15
|
+
const bodyHeight = Math.max(0.5, columns.length * lineItemHeight + 0.1);
|
|
16
|
+
const totalHeight = headerHeight + bodyHeight;
|
|
17
|
+
// Group contains a header row and a body row; child coords are relative to the group origin.
|
|
18
|
+
const groupShape = await page.addShape({
|
|
19
|
+
text: '',
|
|
20
|
+
x, y, width, height: totalHeight,
|
|
21
|
+
type: 'Group',
|
|
22
|
+
});
|
|
23
|
+
const headerCenterY = bodyHeight + (headerHeight / 2);
|
|
24
|
+
await page.addShape({
|
|
25
|
+
text: title,
|
|
26
|
+
x: width / 2,
|
|
27
|
+
y: headerCenterY,
|
|
28
|
+
width, height: headerHeight,
|
|
29
|
+
fillColor: '#DDDDDD',
|
|
30
|
+
bold: true,
|
|
31
|
+
}, groupShape.id);
|
|
32
|
+
const bodyCenterY = bodyHeight / 2;
|
|
33
|
+
await page.addShape({
|
|
34
|
+
text: columns.join('\n'),
|
|
35
|
+
x: width / 2,
|
|
36
|
+
y: bodyCenterY,
|
|
37
|
+
width, height: bodyHeight,
|
|
38
|
+
fillColor: '#FFFFFF',
|
|
39
|
+
fontColor: '#000000',
|
|
40
|
+
}, groupShape.id);
|
|
41
|
+
return groupShape;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.TablePattern = TablePattern;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,9 @@ export { Connector } from './Connector';
|
|
|
5
5
|
export type { ConnectorData } from './Connector';
|
|
6
6
|
export type { ShapeData, ShapeHyperlink } from './Shape';
|
|
7
7
|
export { Layer } from './Layer';
|
|
8
|
-
export { SchemaDiagram } from './SchemaDiagram';
|
|
8
|
+
export { SchemaDiagram } from './diagrams/SchemaDiagram';
|
|
9
|
+
export { TablePattern } from './diagrams/TablePattern';
|
|
10
|
+
export { SwimlanePattern } from './diagrams/SwimlanePattern';
|
|
9
11
|
export { VisioValidator } from './core/VisioValidator';
|
|
10
12
|
export * from './types/VisioTypes';
|
|
11
13
|
export { ArrowHeads, hexToRgb } from './utils/StyleHelpers';
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.hexToRgb = exports.ArrowHeads = exports.VisioValidator = exports.SchemaDiagram = exports.Layer = exports.Connector = exports.Shape = exports.Page = exports.VisioDocument = void 0;
|
|
17
|
+
exports.hexToRgb = exports.ArrowHeads = exports.VisioValidator = exports.SwimlanePattern = exports.TablePattern = exports.SchemaDiagram = exports.Layer = exports.Connector = exports.Shape = exports.Page = exports.VisioDocument = void 0;
|
|
18
18
|
var VisioDocument_1 = require("./VisioDocument");
|
|
19
19
|
Object.defineProperty(exports, "VisioDocument", { enumerable: true, get: function () { return VisioDocument_1.VisioDocument; } });
|
|
20
20
|
var Page_1 = require("./Page");
|
|
@@ -25,8 +25,12 @@ var Connector_1 = require("./Connector");
|
|
|
25
25
|
Object.defineProperty(exports, "Connector", { enumerable: true, get: function () { return Connector_1.Connector; } });
|
|
26
26
|
var Layer_1 = require("./Layer");
|
|
27
27
|
Object.defineProperty(exports, "Layer", { enumerable: true, get: function () { return Layer_1.Layer; } });
|
|
28
|
-
var SchemaDiagram_1 = require("./SchemaDiagram");
|
|
28
|
+
var SchemaDiagram_1 = require("./diagrams/SchemaDiagram");
|
|
29
29
|
Object.defineProperty(exports, "SchemaDiagram", { enumerable: true, get: function () { return SchemaDiagram_1.SchemaDiagram; } });
|
|
30
|
+
var TablePattern_1 = require("./diagrams/TablePattern");
|
|
31
|
+
Object.defineProperty(exports, "TablePattern", { enumerable: true, get: function () { return TablePattern_1.TablePattern; } });
|
|
32
|
+
var SwimlanePattern_1 = require("./diagrams/SwimlanePattern");
|
|
33
|
+
Object.defineProperty(exports, "SwimlanePattern", { enumerable: true, get: function () { return SwimlanePattern_1.SwimlanePattern; } });
|
|
30
34
|
var VisioValidator_1 = require("./core/VisioValidator");
|
|
31
35
|
Object.defineProperty(exports, "VisioValidator", { enumerable: true, get: function () { return VisioValidator_1.VisioValidator; } });
|
|
32
36
|
__exportStar(require("./types/VisioTypes"), exports);
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-visio",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "vitest",
|
|
8
8
|
"build": "tsc",
|
|
9
|
+
"docs:generate": "typedoc",
|
|
9
10
|
"prepublishOnly": "npm run build"
|
|
10
11
|
},
|
|
11
12
|
"files": [
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
"devDependencies": {
|
|
27
28
|
"@types/node": "^25.0.9",
|
|
28
29
|
"tsx": "^4.21.0",
|
|
30
|
+
"typedoc": "^0.28.17",
|
|
29
31
|
"typescript": "^5.9.3",
|
|
30
32
|
"vitest": "^4.0.17"
|
|
31
33
|
}
|