@iflow-mcp/sujimoshi_drawio-mcp 0.0.0-auto

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.
Files changed (55) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +399 -0
  3. package/dist/Graph.d.ts +203 -0
  4. package/dist/Graph.d.ts.map +1 -0
  5. package/dist/Graph.js +314 -0
  6. package/dist/Graph.js.map +1 -0
  7. package/dist/GraphFileManager.d.ts +34 -0
  8. package/dist/GraphFileManager.d.ts.map +1 -0
  9. package/dist/GraphFileManager.js +97 -0
  10. package/dist/GraphFileManager.js.map +1 -0
  11. package/dist/Logger.d.ts +9 -0
  12. package/dist/Logger.d.ts.map +1 -0
  13. package/dist/Logger.js +20 -0
  14. package/dist/Logger.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +24 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/mcp/AddNodeTool.d.ts +97 -0
  20. package/dist/mcp/AddNodeTool.d.ts.map +1 -0
  21. package/dist/mcp/AddNodeTool.js +103 -0
  22. package/dist/mcp/AddNodeTool.js.map +1 -0
  23. package/dist/mcp/EditNodeTool.d.ts +74 -0
  24. package/dist/mcp/EditNodeTool.d.ts.map +1 -0
  25. package/dist/mcp/EditNodeTool.js +66 -0
  26. package/dist/mcp/EditNodeTool.js.map +1 -0
  27. package/dist/mcp/GetDiagramInfoTool.d.ts +29 -0
  28. package/dist/mcp/GetDiagramInfoTool.d.ts.map +1 -0
  29. package/dist/mcp/GetDiagramInfoTool.js +38 -0
  30. package/dist/mcp/GetDiagramInfoTool.js.map +1 -0
  31. package/dist/mcp/LinkNodesTools.d.ts +64 -0
  32. package/dist/mcp/LinkNodesTools.d.ts.map +1 -0
  33. package/dist/mcp/LinkNodesTools.js +63 -0
  34. package/dist/mcp/LinkNodesTools.js.map +1 -0
  35. package/dist/mcp/McpServer.d.ts +24 -0
  36. package/dist/mcp/McpServer.d.ts.map +1 -0
  37. package/dist/mcp/McpServer.js +41 -0
  38. package/dist/mcp/McpServer.js.map +1 -0
  39. package/dist/mcp/NewDiagramTool.d.ts +29 -0
  40. package/dist/mcp/NewDiagramTool.d.ts.map +1 -0
  41. package/dist/mcp/NewDiagramTool.js +39 -0
  42. package/dist/mcp/NewDiagramTool.js.map +1 -0
  43. package/dist/mcp/RemoveNodesTool.d.ts +38 -0
  44. package/dist/mcp/RemoveNodesTool.d.ts.map +1 -0
  45. package/dist/mcp/RemoveNodesTool.js +48 -0
  46. package/dist/mcp/RemoveNodesTool.js.map +1 -0
  47. package/dist/mxgraph/index.d.ts +3 -0
  48. package/dist/mxgraph/index.d.ts.map +1 -0
  49. package/dist/mxgraph/index.js +10 -0
  50. package/dist/mxgraph/index.js.map +1 -0
  51. package/dist/mxgraph/jsdom.d.ts +2 -0
  52. package/dist/mxgraph/jsdom.d.ts.map +1 -0
  53. package/dist/mxgraph/jsdom.js +14 -0
  54. package/dist/mxgraph/jsdom.js.map +1 -0
  55. package/package.json +55 -0
@@ -0,0 +1,203 @@
1
+ import { mxGraph } from './mxgraph/index.js';
2
+ export type LinkNodesParams = {
3
+ from: string;
4
+ to: string;
5
+ title?: string;
6
+ style?: Record<string, any>;
7
+ undirected?: boolean;
8
+ };
9
+ export declare class Graph {
10
+ static Kinds: {
11
+ Rectangle: {
12
+ style: {
13
+ rounded: number;
14
+ whiteSpace: string;
15
+ html: number;
16
+ };
17
+ width: number;
18
+ height: number;
19
+ };
20
+ Ellipse: {
21
+ style: {
22
+ ellipse: string;
23
+ whiteSpace: string;
24
+ html: number;
25
+ };
26
+ width: number;
27
+ height: number;
28
+ };
29
+ Cylinder: {
30
+ style: string;
31
+ width: number;
32
+ height: number;
33
+ };
34
+ Cloud: {
35
+ style: string;
36
+ width: number;
37
+ height: number;
38
+ };
39
+ Square: {
40
+ style: string;
41
+ width: number;
42
+ height: number;
43
+ };
44
+ Circle: {
45
+ style: string;
46
+ width: number;
47
+ height: number;
48
+ };
49
+ Step: {
50
+ style: string;
51
+ width: number;
52
+ height: number;
53
+ };
54
+ Actor: {
55
+ style: string;
56
+ width: number;
57
+ height: number;
58
+ };
59
+ Text: {
60
+ style: string;
61
+ width: number;
62
+ height: number;
63
+ };
64
+ RoundedRectangle: {
65
+ style: string;
66
+ width: number;
67
+ height: number;
68
+ };
69
+ };
70
+ static normalizeKind(kind: string): string;
71
+ graph: typeof mxGraph;
72
+ container: HTMLDivElement;
73
+ constructor();
74
+ get root(): any;
75
+ get model(): any;
76
+ toStyleString(data: any): string;
77
+ /**
78
+ * Parses a style definition into a key-value object.
79
+ *
80
+ * Handles both string and object style formats:
81
+ * - String format: "key1=value1;key2=value2;" (semicolon-separated key=value pairs)
82
+ * - Object format: { key1: "value1", key2: "value2" } (plain object)
83
+ *
84
+ * For string styles, empty values (e.g., "key=") are converted to empty strings.
85
+ * For object styles, the input is shallow copied to avoid mutation.
86
+ *
87
+ * @param style - Style definition as either a semicolon-separated string or object
88
+ * @returns Object with style properties as key-value pairs
89
+ *
90
+ * @example
91
+ * parseStyle("rounded=1;whiteSpace=wrap;html=1")
92
+ * // Returns: { rounded: "1", whiteSpace: "wrap", html: "1" }
93
+ *
94
+ * @example
95
+ * parseStyle({ rounded: 1, whiteSpace: "wrap" })
96
+ * // Returns: { rounded: 1, whiteSpace: "wrap" }
97
+ */
98
+ private parseStyle;
99
+ /**
100
+ * Converts a style object into a semicolon-separated style string.
101
+ *
102
+ * This function is the inverse of parseStyle(), converting a key-value object
103
+ * back into the string format used by mxGraph. Properties with undefined values
104
+ * are skipped, while properties with falsy values (empty string, 0, false) are
105
+ * included with just the key name (no equals sign).
106
+ *
107
+ * @param style - Object with style properties as key-value pairs
108
+ * @returns Semicolon-separated style string in format "key1=value1;key2;key3=value3;"
109
+ *
110
+ * @example
111
+ * stringifyStyle({ rounded: "1", whiteSpace: "wrap", html: "1" })
112
+ * // Returns: "rounded=1;whiteSpace=wrap;html=1;"
113
+ *
114
+ * @example
115
+ * stringifyStyle({ rounded: "", whiteSpace: "wrap" })
116
+ * // Returns: "rounded;whiteSpace=wrap;"
117
+ */
118
+ private stringifyStyle;
119
+ /**
120
+ * Adjusts the style string for a specific node kind, applying kind-specific modifications.
121
+ *
122
+ * For RoundedRectangle nodes, this function modifies the corner radius by setting:
123
+ * - absoluteArcSize to '1' to enable absolute arc sizing
124
+ * - arcSize to the calculated value (corner_radius * 2, default to 24)
125
+ *
126
+ * @param style - The base style string to modify
127
+ * @param kind - The node kind (e.g., 'RoundedRectangle', 'Rectangle', etc.)
128
+ * @param corner_radius - The desired corner radius in pixels (only applies to RoundedRectangle)
129
+ * @returns The modified style string with kind-specific adjustments applied
130
+ */
131
+ private adjustStyleByKind;
132
+ addNode({ id, title, parent, kind, x, y, corner_radius, ...rest }: {
133
+ [x: string]: any;
134
+ id: any;
135
+ title: any;
136
+ parent?: string;
137
+ kind?: string;
138
+ x?: number;
139
+ y?: number;
140
+ corner_radius: any;
141
+ }): any;
142
+ editNode({ id, title, kind, x, y, width, height, corner_radius }: {
143
+ id: any;
144
+ title: any;
145
+ kind: any;
146
+ x: any;
147
+ y: any;
148
+ width: any;
149
+ height: any;
150
+ corner_radius: any;
151
+ }): this;
152
+ linkNodes({ from, to, title, style, undirected }: LinkNodesParams): any;
153
+ removeNodes(ids: string[]): this;
154
+ /**
155
+ * Executes a given layout algorithm on the graph's root element.
156
+ *
157
+ * @param layout - An object with an `execute` method, typically an mxGraph layout instance.
158
+ * @param args - Additional arguments to pass to the layout's `execute` method.
159
+ * @returns The current Graph instance for method chaining.
160
+ *
161
+ * @remarks
162
+ * This method is used internally to apply various mxGraph layout algorithms
163
+ * (e.g., hierarchical, circle, organic) to the graph. The layout is executed
164
+ * on the root element of the graph, and any additional arguments are forwarded
165
+ * to the layout's `execute` method.
166
+ */
167
+ private runLayout;
168
+ /**
169
+ * Applies a layout algorithm to the graph.
170
+ *
171
+ * @param params - An object containing the layout algorithm and optional options.
172
+ * @param params.algorithm - The name of the layout algorithm to apply. Supported values are:
173
+ * - 'hierarchical'
174
+ * - 'circle'
175
+ * - 'organic'
176
+ * - 'compact-tree'
177
+ * - 'radial-tree'
178
+ * - 'partition'
179
+ * - 'stack'
180
+ * @param params.options - Optional parameters for the layout algorithm.
181
+ * - For 'hierarchical', you may specify `direction` as either 'top-down' or 'left-right'.
182
+ *
183
+ * @throws {Error} If an unsupported algorithm is provided, or if an invalid direction is specified for hierarchical layout.
184
+ *
185
+ * @returns {Graph} The current Graph instance for method chaining.
186
+ *
187
+ * @example
188
+ * graph.applyLayout({ algorithm: 'hierarchical', options: { direction: 'left-right' } });
189
+ * graph.applyLayout({ algorithm: 'circle' });
190
+ */
191
+ applyLayout({ algorithm, options }: {
192
+ algorithm: string;
193
+ options?: any;
194
+ }): this;
195
+ toXML(): any;
196
+ /**
197
+ * Static method to create a Graph instance from XML
198
+ * @param {string} xmlString - XML string in mxGraph format
199
+ * @returns {Graph} - New Graph instance loaded from XML
200
+ */
201
+ static fromXML(xmlString: any): Graph;
202
+ }
203
+ //# sourceMappingURL=Graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Graph.d.ts","sourceRoot":"","sources":["../src/Graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAmL,MAAM,oBAAoB,CAAC;AAwB9N,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAA;AAED,qBAAa,KAAK;IAChB,MAAM,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAWX;IAED,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM;IAKjC,KAAK,EAAE,OAAO,OAAO,CAAC;IACtB,SAAS,EAAE,cAAc,CAAC;;IAO1B,IAAI,IAAI,QAEP;IAED,IAAI,KAAK,QAER;IAED,aAAa,CAAC,IAAI,KAAA;IAOlB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,UAAU;IAWlB;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,cAAc;IAQtB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAe,EAAE,IAAkB,EAAE,CAAM,EAAE,CAAM,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE;;;;;;;;;KAAA;IAUlG,QAAQ,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE;;;;;;;;;KAAA;IA4BhE,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAU,EAAE,UAAU,EAAE,EAAE,eAAe;IA2BtE,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE;IAMzB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,SAAS;IAMjB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,WAAW,CAAC,EAAE,SAAS,EAAE,OAAY,EAAE,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE;IA6C7E,KAAK;IAML;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,SAAS,KAAA;CAazB"}
package/dist/Graph.js ADDED
@@ -0,0 +1,314 @@
1
+ import { mxGraph, mxCodec, mxUtils, mxHierarchicalLayout, mxConstants, mxCircleLayout, mxGeometry, mxFastOrganicLayout, mxCompactTreeLayout, mxRadialTreeLayout, mxPartitionLayout, mxStackLayout } from './mxgraph/index.js';
2
+ const LAYOUT_HIERARCHICAL = 'hierarchical';
3
+ const LAYOUT_CIRCLE = 'circle';
4
+ const LAYOUT_ORGANIC = 'organic';
5
+ const LAYOUT_COMPACT_TREE = 'compact-tree';
6
+ const LAYOUT_RADIAL_TREE = 'radial-tree';
7
+ const LAYOUT_PARTITION = 'partition';
8
+ const LAYOUT_STACK = 'stack';
9
+ const DIRECTION_TOP_DOWN = 'top-down';
10
+ const DIRECTION_LEFT_RIGHT = 'left-right';
11
+ const DIR_TO_MX_DIRECTION = {
12
+ [DIRECTION_TOP_DOWN]: mxConstants.DIRECTION_NORTH,
13
+ [DIRECTION_LEFT_RIGHT]: mxConstants.DIRECTION_WEST
14
+ };
15
+ const DEFAULT_CORNER_RADIUS = 12;
16
+ const KIND_ROUNDED_RECTANGLE = 'RoundedRectangle';
17
+ const PROP_ARC_SIZE = 'arcSize';
18
+ const PROP_ABSOLUTE_ARC_SIZE = 'absoluteArcSize';
19
+ export class Graph {
20
+ static normalizeKind(kind) {
21
+ if (kind === 'Elipse')
22
+ return 'Ellipse';
23
+ return kind;
24
+ }
25
+ constructor() {
26
+ this.container = document.createElement('div');
27
+ this.graph = new mxGraph(this.container);
28
+ }
29
+ get root() {
30
+ return this.graph.getDefaultParent();
31
+ }
32
+ get model() {
33
+ return this.graph.getModel();
34
+ }
35
+ toStyleString(data) {
36
+ if (typeof data === 'string')
37
+ return data;
38
+ return Object.entries(data).reduce((tmp, [key, value]) => {
39
+ return value === undefined ? tmp : tmp += key + (value ? `=${value}` : '') + ';';
40
+ }, '');
41
+ }
42
+ /**
43
+ * Parses a style definition into a key-value object.
44
+ *
45
+ * Handles both string and object style formats:
46
+ * - String format: "key1=value1;key2=value2;" (semicolon-separated key=value pairs)
47
+ * - Object format: { key1: "value1", key2: "value2" } (plain object)
48
+ *
49
+ * For string styles, empty values (e.g., "key=") are converted to empty strings.
50
+ * For object styles, the input is shallow copied to avoid mutation.
51
+ *
52
+ * @param style - Style definition as either a semicolon-separated string or object
53
+ * @returns Object with style properties as key-value pairs
54
+ *
55
+ * @example
56
+ * parseStyle("rounded=1;whiteSpace=wrap;html=1")
57
+ * // Returns: { rounded: "1", whiteSpace: "wrap", html: "1" }
58
+ *
59
+ * @example
60
+ * parseStyle({ rounded: 1, whiteSpace: "wrap" })
61
+ * // Returns: { rounded: 1, whiteSpace: "wrap" }
62
+ */
63
+ parseStyle(style) {
64
+ if (typeof style === 'string') {
65
+ return style.split(';').filter(Boolean).reduce((acc, kv) => {
66
+ const [k, v] = kv.split('=');
67
+ acc[k] = v === undefined ? '' : v;
68
+ return acc;
69
+ }, {});
70
+ }
71
+ return { ...style };
72
+ }
73
+ /**
74
+ * Converts a style object into a semicolon-separated style string.
75
+ *
76
+ * This function is the inverse of parseStyle(), converting a key-value object
77
+ * back into the string format used by mxGraph. Properties with undefined values
78
+ * are skipped, while properties with falsy values (empty string, 0, false) are
79
+ * included with just the key name (no equals sign).
80
+ *
81
+ * @param style - Object with style properties as key-value pairs
82
+ * @returns Semicolon-separated style string in format "key1=value1;key2;key3=value3;"
83
+ *
84
+ * @example
85
+ * stringifyStyle({ rounded: "1", whiteSpace: "wrap", html: "1" })
86
+ * // Returns: "rounded=1;whiteSpace=wrap;html=1;"
87
+ *
88
+ * @example
89
+ * stringifyStyle({ rounded: "", whiteSpace: "wrap" })
90
+ * // Returns: "rounded;whiteSpace=wrap;"
91
+ */
92
+ stringifyStyle(style) {
93
+ return Object.entries(style).reduce((tmp, [key, value]) => {
94
+ return value === undefined ? tmp : tmp += key + (value ? `=${value}` : '') + ';';
95
+ }, '');
96
+ }
97
+ /**
98
+ * Adjusts the style string for a specific node kind, applying kind-specific modifications.
99
+ *
100
+ * For RoundedRectangle nodes, this function modifies the corner radius by setting:
101
+ * - absoluteArcSize to '1' to enable absolute arc sizing
102
+ * - arcSize to the calculated value (corner_radius * 2, default to 24)
103
+ *
104
+ * @param style - The base style string to modify
105
+ * @param kind - The node kind (e.g., 'RoundedRectangle', 'Rectangle', etc.)
106
+ * @param corner_radius - The desired corner radius in pixels (only applies to RoundedRectangle)
107
+ * @returns The modified style string with kind-specific adjustments applied
108
+ */
109
+ adjustStyleByKind(style, kind, corner_radius) {
110
+ if (kind === KIND_ROUNDED_RECTANGLE) {
111
+ const styleObj = this.parseStyle(style);
112
+ if (corner_radius !== undefined) {
113
+ const cr = parseInt(String(corner_radius), 10);
114
+ styleObj[PROP_ABSOLUTE_ARC_SIZE] = '1';
115
+ const arcSize = !isNaN(cr) && cr >= 1 ? cr * 2 : DEFAULT_CORNER_RADIUS * 2;
116
+ styleObj[PROP_ARC_SIZE] = String(arcSize);
117
+ }
118
+ // console.error(`adjusted style: ${this.stringifyStyle(styleObj)}`);
119
+ return this.stringifyStyle(styleObj);
120
+ }
121
+ return style;
122
+ }
123
+ addNode({ id, title, parent = 'root', kind = 'Rectangle', x = 10, y = 10, corner_radius, ...rest }) {
124
+ const normalizedKind = Graph.normalizeKind(kind);
125
+ const { style, width, height } = { ...Graph.Kinds[normalizedKind], ...rest };
126
+ const to = parent === 'root' ? this.root : this.model.getCell(parent);
127
+ const node = this.graph.insertVertex(to, id, title, Number(x), Number(y), width, height);
128
+ node.setStyle(this.adjustStyleByKind(style, normalizedKind, corner_radius));
129
+ return node;
130
+ }
131
+ editNode({ id, title, kind, x, y, width, height, corner_radius }) {
132
+ const node = this.model.getCell(id);
133
+ if (!node)
134
+ throw new Error(`Node not found`);
135
+ const normalizedKind = Graph.normalizeKind(kind);
136
+ if (title)
137
+ node.setValue(title);
138
+ if (kind)
139
+ node.setStyle(Graph.Kinds[normalizedKind].style);
140
+ // if it's rounded, apply the corner radius
141
+ const isRounded = normalizedKind === KIND_ROUNDED_RECTANGLE;
142
+ if (isRounded && corner_radius !== undefined) {
143
+ const currentStyleStr = node.getStyle && node.getStyle() ? String(node.getStyle()) : '';
144
+ node.setStyle(this.adjustStyleByKind(currentStyleStr, normalizedKind, corner_radius));
145
+ }
146
+ // if the geometry is changed, update the geometry
147
+ if (x !== undefined || y !== undefined || width !== undefined || height !== undefined) {
148
+ const geometry = node.getGeometry();
149
+ node.setGeometry(new mxGeometry(x ?? geometry.x, y ?? geometry.y, width ?? geometry.width, height ?? geometry.height));
150
+ }
151
+ return this;
152
+ }
153
+ linkNodes({ from, to, title, style = {}, undirected }) {
154
+ const [fromNode, toNode] = [this.model.getCell(from), this.model.getCell(to)];
155
+ // Compute candidate IDs
156
+ const idDirect = `${from}-2-${to}`;
157
+ const idReverse = `${to}-2-${from}`;
158
+ const [a, b] = [from, to].sort();
159
+ const idCanonical = `${a}-2-${b}`;
160
+ // Build effective style
161
+ const effective = computeEffectiveLineStyle(style, undirected);
162
+ // Try to find an existing edge to update (do not rename IDs)
163
+ const existing = this.model.getCell(idDirect) || this.model.getCell(idReverse) || this.model.getCell(idCanonical);
164
+ let link = existing;
165
+ if (link) {
166
+ if (title !== undefined)
167
+ link.setValue(title);
168
+ }
169
+ else { // Insert new edge; use canonical id for undirected, else direct id
170
+ const idToUse = undirected ? idCanonical : idDirect;
171
+ link = this.graph.insertEdge(this.root, idToUse, title ? title : null, fromNode, toNode);
172
+ }
173
+ link.setStyle(this.toStyleString(effective));
174
+ return link.getId();
175
+ }
176
+ removeNodes(ids) {
177
+ const cells = ids.map(id => this.model.getCell(id));
178
+ this.graph.removeCells(cells);
179
+ return this;
180
+ }
181
+ /**
182
+ * Executes a given layout algorithm on the graph's root element.
183
+ *
184
+ * @param layout - An object with an `execute` method, typically an mxGraph layout instance.
185
+ * @param args - Additional arguments to pass to the layout's `execute` method.
186
+ * @returns The current Graph instance for method chaining.
187
+ *
188
+ * @remarks
189
+ * This method is used internally to apply various mxGraph layout algorithms
190
+ * (e.g., hierarchical, circle, organic) to the graph. The layout is executed
191
+ * on the root element of the graph, and any additional arguments are forwarded
192
+ * to the layout's `execute` method.
193
+ */
194
+ runLayout(layout, ...args) {
195
+ layout.execute(this.root, ...args);
196
+ return this;
197
+ }
198
+ /**
199
+ * Applies a layout algorithm to the graph.
200
+ *
201
+ * @param params - An object containing the layout algorithm and optional options.
202
+ * @param params.algorithm - The name of the layout algorithm to apply. Supported values are:
203
+ * - 'hierarchical'
204
+ * - 'circle'
205
+ * - 'organic'
206
+ * - 'compact-tree'
207
+ * - 'radial-tree'
208
+ * - 'partition'
209
+ * - 'stack'
210
+ * @param params.options - Optional parameters for the layout algorithm.
211
+ * - For 'hierarchical', you may specify `direction` as either 'top-down' or 'left-right'.
212
+ *
213
+ * @throws {Error} If an unsupported algorithm is provided, or if an invalid direction is specified for hierarchical layout.
214
+ *
215
+ * @returns {Graph} The current Graph instance for method chaining.
216
+ *
217
+ * @example
218
+ * graph.applyLayout({ algorithm: 'hierarchical', options: { direction: 'left-right' } });
219
+ * graph.applyLayout({ algorithm: 'circle' });
220
+ */
221
+ applyLayout({ algorithm, options = {} }) {
222
+ switch (algorithm) {
223
+ case LAYOUT_HIERARCHICAL: {
224
+ if (options.direction !== undefined &&
225
+ options.direction !== DIRECTION_TOP_DOWN && options.direction !== DIRECTION_LEFT_RIGHT)
226
+ throw new Error(`Invalid hierarchical direction: ${options.direction}. Allowed: ${DIRECTION_TOP_DOWN}, ${DIRECTION_LEFT_RIGHT}`);
227
+ this.runLayout(new mxHierarchicalLayout(this.graph, DIR_TO_MX_DIRECTION[options.direction]), Object.values(this.model.cells)[1]);
228
+ break;
229
+ }
230
+ case LAYOUT_CIRCLE: {
231
+ this.runLayout(new mxCircleLayout(this.graph));
232
+ break;
233
+ }
234
+ case LAYOUT_ORGANIC: {
235
+ this.runLayout(new mxFastOrganicLayout(this.graph));
236
+ break;
237
+ }
238
+ case LAYOUT_COMPACT_TREE: {
239
+ this.runLayout(new mxCompactTreeLayout(this.graph));
240
+ break;
241
+ }
242
+ case LAYOUT_RADIAL_TREE: {
243
+ this.runLayout(new mxRadialTreeLayout(this.graph));
244
+ break;
245
+ }
246
+ case LAYOUT_PARTITION: {
247
+ this.runLayout(new mxPartitionLayout(this.graph));
248
+ break;
249
+ }
250
+ case LAYOUT_STACK: {
251
+ this.runLayout(new mxStackLayout(this.graph));
252
+ break;
253
+ }
254
+ default: {
255
+ const supportedAlgorithms = [LAYOUT_HIERARCHICAL, LAYOUT_CIRCLE, LAYOUT_ORGANIC,
256
+ LAYOUT_COMPACT_TREE, LAYOUT_RADIAL_TREE, LAYOUT_PARTITION,
257
+ LAYOUT_STACK,
258
+ ];
259
+ throw new Error(`Unsupported layout algorithm: ${algorithm}. Supported: ${supportedAlgorithms.join(', ')}`);
260
+ }
261
+ }
262
+ return this;
263
+ }
264
+ toXML() {
265
+ const encoder = new mxCodec();
266
+ const result = encoder.encode(this.model);
267
+ return mxUtils.getPrettyXml(result);
268
+ }
269
+ /**
270
+ * Static method to create a Graph instance from XML
271
+ * @param {string} xmlString - XML string in mxGraph format
272
+ * @returns {Graph} - New Graph instance loaded from XML
273
+ */
274
+ static fromXML(xmlString) {
275
+ const graph = new Graph();
276
+ // Use the global DOMParser that was set up in mxgraph.js
277
+ const parsedDoc = new DOMParser().parseFromString(xmlString, 'text/xml');
278
+ // Create a codec with the parsed document
279
+ const codec = new mxCodec(parsedDoc);
280
+ codec.decode(parsedDoc.documentElement, graph.model);
281
+ return graph;
282
+ }
283
+ }
284
+ Graph.Kinds = {
285
+ Rectangle: { style: { rounded: 1, whiteSpace: 'wrap', html: 1 }, width: 120, height: 60 },
286
+ Ellipse: { style: { ellipse: '', whiteSpace: 'wrap', html: 1 }, width: 120, height: 80 },
287
+ Cylinder: { style: 'shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;', width: 60, height: 80 },
288
+ Cloud: { style: 'ellipse;shape=cloud;whiteSpace=wrap;html=1;', width: 120, height: 80 },
289
+ Square: { style: 'whiteSpace=wrap;html=1;aspect=fixed;rounded=1;', width: 80, height: 80 },
290
+ Circle: { style: 'ellipse;whiteSpace=wrap;html=1;aspect=fixed;', width: 80, height: 80 },
291
+ Step: { style: 'shape=step;perimeter=stepPerimeter;whiteSpace=wrap;html=1;fixedSize=1;', width: 120, height: 80 },
292
+ Actor: { style: 'shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;', width: 30, height: 60 },
293
+ Text: { style: 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;', width: 60, height: 30 },
294
+ RoundedRectangle: { style: `whiteSpace=wrap;html=1;rounded=1;absoluteArcSize=1;arcSize=${DEFAULT_CORNER_RADIUS * 2}`, width: 120, height: 60 },
295
+ };
296
+ /**
297
+ * Computes the effective line style for an edge in the graph, merging the provided style
298
+ * with default base styles. If the edge is undirected, disables arrowheads and reverses.
299
+ *
300
+ * @param {Record<string, any>} style - Optional style overrides for the edge.
301
+ * @param {boolean} [undirected] - If true, creates an undirected edge (no arrows).
302
+ * @returns {Record<string, any>} The computed style object for the edge.
303
+ */
304
+ function computeEffectiveLineStyle(style = {}, undirected) {
305
+ const base = { edgeStyle: 'none', noEdgeStyle: 1, orthogonal: 1, html: 1 };
306
+ const effective = { ...base, ...style };
307
+ if (undirected) {
308
+ effective.reverse = undefined;
309
+ effective.startArrow = 'none';
310
+ effective.endArrow = 'none';
311
+ }
312
+ return effective;
313
+ }
314
+ //# sourceMappingURL=Graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Graph.js","sourceRoot":"","sources":["../src/Graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { Graph } from './Graph.js';
2
+ /**
3
+ * Handles diagram file operations and SVG content parsing
4
+ * Works directly with file paths
5
+ */
6
+ export declare class GraphFileManager {
7
+ static default: GraphFileManager;
8
+ /**
9
+ * Load a graph from a .drawio.svg file
10
+ */
11
+ loadGraphFromSvg(filePath: string): Promise<Graph>;
12
+ /**
13
+ * Save a graph to a .drawio.svg file
14
+ * @param {Graph} graph - Graph instance to save
15
+ * @param {string} filePath - Absolute or relative path to save the .drawio.svg file
16
+ */
17
+ saveGraphToSvg(graph: Graph, filePath: string): Promise<void>;
18
+ /**
19
+ * Get diagram statistics from file
20
+ * @param {string} filePath - Absolute or relative path to the file
21
+ * @returns {Object} - Object with nodeCount and edgeCount
22
+ */
23
+ getDiagramStats(filePath: string): Promise<{
24
+ nodeCount: number;
25
+ edgeCount: number;
26
+ }>;
27
+ /**
28
+ * Extract raw XML data from SVG content attribute for direct mxGraph loading
29
+ * @param {string} svgContent - Raw SVG file content
30
+ * @returns {string|null} - Raw mxGraph XML data or null if extraction fails
31
+ */
32
+ extractXMLFromSVG(svgContent: string): string;
33
+ }
34
+ //# sourceMappingURL=GraphFileManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphFileManager.d.ts","sourceRoot":"","sources":["../src/GraphFileManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,OAAO,mBAA0B;IAExC;;OAEG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM;IAYvC;;;;OAIG;IACG,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM;IA0BnD;;;;OAIG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM;;;;IAYtC;;;;OAIG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM;CAgCrC"}
@@ -0,0 +1,97 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import pako from 'pako';
4
+ import { Graph } from './Graph.js';
5
+ /**
6
+ * Handles diagram file operations and SVG content parsing
7
+ * Works directly with file paths
8
+ */
9
+ export class GraphFileManager {
10
+ /**
11
+ * Load a graph from a .drawio.svg file
12
+ */
13
+ async loadGraphFromSvg(filePath) {
14
+ // Resolve relative paths relative to process.cwd()
15
+ const resolvedPath = path.resolve(filePath);
16
+ await fs.access(resolvedPath);
17
+ // Load from SVG content attribute and use direct XML loading
18
+ const svgContent = await fs.readFile(resolvedPath, 'utf8');
19
+ const xmlData = this.extractXMLFromSVG(svgContent);
20
+ return Graph.fromXML(xmlData);
21
+ }
22
+ /**
23
+ * Save a graph to a .drawio.svg file
24
+ * @param {Graph} graph - Graph instance to save
25
+ * @param {string} filePath - Absolute or relative path to save the .drawio.svg file
26
+ */
27
+ async saveGraphToSvg(graph, filePath) {
28
+ // Resolve relative paths relative to process.cwd()
29
+ const resolvedPath = path.resolve(filePath);
30
+ // Ensure directory exists
31
+ const dir = path.dirname(resolvedPath);
32
+ await fs.mkdir(dir, { recursive: true });
33
+ // Save SVG for VSCode draw.io extension (no metadata file needed!)
34
+ const tmp = pako.deflateRaw(encodeURIComponent(graph.toXML()));
35
+ var bytes = new Uint8Array(tmp);
36
+ var binary = '';
37
+ for (var i = 0; i < bytes.byteLength; i++) {
38
+ binary += String.fromCharCode(bytes[i]);
39
+ }
40
+ const compressed = btoa(binary);
41
+ const content = `&lt;mxfile&gt;&lt;diagram id=&quot;d&quot; name=&quot;P&quot;&gt;${compressed}&lt;/diagram&gt;&lt;/mxfile&gt;`;
42
+ graph.container.children[0].setAttribute('content', 'replaceme');
43
+ const svgContent = graph.container.innerHTML.replace('replaceme', content);
44
+ await fs.writeFile(resolvedPath, svgContent, 'utf8');
45
+ }
46
+ /**
47
+ * Get diagram statistics from file
48
+ * @param {string} filePath - Absolute or relative path to the file
49
+ * @returns {Object} - Object with nodeCount and edgeCount
50
+ */
51
+ async getDiagramStats(filePath) {
52
+ try {
53
+ const graph = await this.loadGraphFromSvg(filePath);
54
+ const cells = graph.model.cells;
55
+ const nodeCount = Object.values(cells).filter((cell) => cell && cell.vertex).length;
56
+ const edgeCount = Object.values(cells).filter((cell) => cell && cell.edge).length;
57
+ return { nodeCount, edgeCount };
58
+ }
59
+ catch {
60
+ return { nodeCount: 0, edgeCount: 0 };
61
+ }
62
+ }
63
+ /**
64
+ * Extract raw XML data from SVG content attribute for direct mxGraph loading
65
+ * @param {string} svgContent - Raw SVG file content
66
+ * @returns {string|null} - Raw mxGraph XML data or null if extraction fails
67
+ */
68
+ extractXMLFromSVG(svgContent) {
69
+ // Extract the content attribute from SVG
70
+ const contentMatch = svgContent.match(/content="([^"]+)"/);
71
+ if (!contentMatch) {
72
+ return null;
73
+ }
74
+ // Decode the content attribute
75
+ const encodedContent = contentMatch[1];
76
+ // Step 1: HTML decode
77
+ const htmlDecoded = encodedContent
78
+ .replace(/&lt;/g, '<')
79
+ .replace(/&gt;/g, '>')
80
+ .replace(/&quot;/g, '"')
81
+ .replace(/&amp;/g, '&');
82
+ // Step 2: Extract base64 data from mxfile structure
83
+ const mxfileMatch = htmlDecoded.match(/<diagram[^>]*>([^<]+)<\/diagram>/);
84
+ if (!mxfileMatch) {
85
+ return null;
86
+ }
87
+ // Step 3: Base64 decode and decompress
88
+ const base64Data = mxfileMatch[1];
89
+ const compressedData = Buffer.from(base64Data, 'base64');
90
+ const decompressed = pako.inflateRaw(compressedData, { to: 'string' });
91
+ // Step 4: URI decode to get XML - return directly for mxGraph
92
+ const xmlData = decodeURIComponent(decompressed);
93
+ return xmlData;
94
+ }
95
+ }
96
+ GraphFileManager.default = new GraphFileManager();
97
+ //# sourceMappingURL=GraphFileManager.js.map