Skip to content

Commit

Permalink
chore: replace dagre/dagre-d3 with dagre-d3-es
Browse files Browse the repository at this point in the history
Replace the dagre and dagre-d3 libraries with dagre-d3-es.

Both dagre and dagre-d3 are deprecated and unmaintained,
and haven't been updated for more than 3 years.

Since dagre-d3 still requires an old version of d3, this causes
a bunch of security warnings,
e.g. GHSA-36jr-mh4h-2g58

The [dagre-d3-es](https://github.com/tbo47/dagre-es) package is a fork
that contains support for `"d3": "^7.6.1"`. Also, it's ESM, so we will
hopefully get smaller bundle sizes too. The only issue is that this
fork isn't very well used (only has 3000 weekly downloads),
compared to `dagre-d3`'s 250,000 weekly downloads.

(although to be fair, a large proportion of dagre-d3's downloads
 probably come from mermaid)

Since it's is a less popular package,
**I've pinned `dagre-d3-es` to `"7.0.2"` instead of `"^7.0.2"`**.
This does mean if there is a bug in `dagre-d3-es`, we will have to
manually bump it ourselves, but it also means we won't accidentally
be sending a buggy version of `dagre-d3-es` out to users in cases
something changes (it might be worth disabling renovate for this
if we're feeling paranoid!)
  • Loading branch information
aloisklink committed Nov 18, 2022
1 parent 537a627 commit fd76e0e
Show file tree
Hide file tree
Showing 13 changed files with 42 additions and 60 deletions.
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@
"vitepress-plugin-search": "^1.0.4-alpha.15",
"vitest": "^0.25.1"
},
"resolutions": {
"d3": "^7.6.1"
},
"sideEffects": [
"**/*.css",
"**/*.scss"
Expand Down
6 changes: 1 addition & 5 deletions packages/mermaid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@
"dependencies": {
"@braintree/sanitize-url": "^6.0.0",
"d3": "^7.0.0",
"dagre": "^0.8.5",
"dagre-d3": "^0.6.4",
"dagre-d3-es": "7.0.2",
"dompurify": "2.4.1",
"fast-clone": "^1.5.13",
"graphlib": "^2.1.8",
Expand Down Expand Up @@ -98,9 +97,6 @@
"typescript": "^4.8.4",
"unist-util-flatmap": "^1.0.0"
},
"resolutions": {
"d3": "^7.0.0"
},
"files": [
"dist",
"README.md"
Expand Down
4 changes: 2 additions & 2 deletions packages/mermaid/src/dagre-wrapper/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import graphlib from 'graphlib';
import insertMarkers from './markers';
import { updateNodeBounds } from './shapes/util';
Expand Down Expand Up @@ -95,7 +95,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
log.info('### Layout ###');
log.info('#############################################');
log.info(graph);
dagre.layout(graph);
dagreLayout(graph);
log.info('Graph after layout:', graphlib.json.write(graph));
// Move the nodes to the correct place
let diff = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import graphlib from 'graphlib';
import dagre from 'dagre';
import {
validate,
adjustClustersAndEdges,
Expand Down
4 changes: 2 additions & 2 deletions packages/mermaid/src/diagrams/class/classRenderer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { select } from 'd3';
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import graphlib from 'graphlib';
import { log } from '../../logger';
import svgDraw from './svgDraw';
Expand Down Expand Up @@ -238,7 +238,7 @@ export const draw = function (text, id, _version, diagObj) {
}
});

dagre.layout(g);
dagreLayout(g);
g.nodes().forEach(function (v) {
if (typeof v !== 'undefined' && typeof g.node(v) !== 'undefined') {
log.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)));
Expand Down
4 changes: 2 additions & 2 deletions packages/mermaid/src/diagrams/er/erRenderer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import graphlib from 'graphlib';
import { line, curveBasis, select } from 'd3';
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import { getConfig } from '../../config';
import { log } from '../../logger';
import erMarkers from './erMarkers';
Expand Down Expand Up @@ -637,7 +637,7 @@ export const draw = function (text, id, _version, diagObj) {
// Add all the relationships to the graph
const relationships = addRelationships(diagObj.db.getRelationships(), g);

dagre.layout(g); // Node and edge positions will be updated
dagreLayout(g); // Node and edge positions will be updated

// Adjust the positions of the entities so that they adhere to the layout
adjustEntities(svg, g);
Expand Down
25 changes: 13 additions & 12 deletions packages/mermaid/src/diagrams/flowchart/flowChartShapes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import dagreD3 from 'dagre-d3';
import { intersectPolygon } from 'dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js';
import { intersectRect } from 'dagre-d3-es/src/dagre-js/intersect/intersect-rect.js';

/**
* @param parent
Expand All @@ -17,7 +18,7 @@ function question(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, s, s, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -42,7 +43,7 @@ function hexagon(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -64,7 +65,7 @@ function rect_left_inv_arrow(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -85,7 +86,7 @@ function lean_right(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -106,7 +107,7 @@ function lean_left(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -127,7 +128,7 @@ function trapezoid(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -148,7 +149,7 @@ function inv_trapezoid(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -170,7 +171,7 @@ function rect_right_inv_arrow(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand All @@ -194,7 +195,7 @@ function stadium(parent, bbox, node) {
.attr('height', h);

node.intersect = function (point) {
return dagreD3.intersect.rect(node, point);
return intersectRect(node, point);
};
return shapeSvg;
}
Expand All @@ -221,7 +222,7 @@ function subroutine(parent, bbox, node) {
];
const shapeSvg = insertPolygonShape(parent, w, h, points);
node.intersect = function (point) {
return dagreD3.intersect.polygon(node, points, point);
return intersectPolygon(node, points, point);
};
return shapeSvg;
}
Expand Down Expand Up @@ -270,7 +271,7 @@ function cylinder(parent, bbox, node) {
.attr('transform', 'translate(' + -w / 2 + ',' + -(h / 2 + ry) + ')');

node.intersect = function (point) {
const pos = dagreD3.intersect.rect(node, point);
const pos = intersectRect(node, point);
const x = pos.x - node.x;

if (
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import flowDb from './flowDb';
import { getConfig } from '../../config';

import { render } from '../../dagre-wrapper/index.js';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray } from '../../utils';
Expand Down
8 changes: 4 additions & 4 deletions packages/mermaid/src/diagrams/flowchart/flowRenderer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import graphlib from 'graphlib';
import { select, curveLinear, selectAll } from 'd3';
import { getConfig } from '../../config';
import dagreD3 from 'dagre-d3';
import addHtmlLabel from 'dagre-d3/lib/label/add-html-label.js';
import { render as Render } from 'dagre-d3-es';
import { applyStyle } from 'dagre-d3-es/src/dagre-js/util.js';
import { addHtmlLabel } from 'dagre-d3-es/src/dagre-js/label/add-html-label.js';
import { log } from '../../logger';
import common, { evaluate } from '../common/common';
import { interpolateToCurve, getStylesFromArray } from '../../utils';
Expand Down Expand Up @@ -370,7 +371,6 @@ export const draw = function (text, id, _version, diagObj) {
addEdges(edges, g, diagObj);

// Create the renderer
const Render = dagreD3.render;
const render = new Render();

// Add custom shapes
Expand All @@ -390,7 +390,7 @@ export const draw = function (text, id, _version, diagObj) {
.attr('orient', 'auto');

const path = marker.append('path').attr('d', 'M 0 0 L 0 0 L 0 0 z');
dagreD3.util.applyStyle(path, edge[type + 'Style']);
applyStyle(path, edge[type + 'Style']);
};

// Override normal arrowhead defined in d3. Remove style & add class to allow css styling.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { line, select } from 'd3';
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import graphlib from 'graphlib';
import { log } from '../../logger';
import { configureSvgSize } from '../../setupGraphViewbox';
Expand Down Expand Up @@ -348,7 +348,7 @@ export const draw = (text, id, _version, diagObj) => {
drawReqs(requirements, g, svg);
drawElements(elements, g, svg);
addRelationships(relationships, g);
dagre.layout(g);
dagreLayout(g);
adjustEntities(svg, g);

relationships.forEach(function (rel) {
Expand Down
4 changes: 2 additions & 2 deletions packages/mermaid/src/diagrams/state/stateRenderer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { select } from 'd3';
import dagre from 'dagre';
import { layout as dagreLayout } from 'dagre-d3-es/src/dagre/index.js';
import graphlib from 'graphlib';
import { log } from '../../logger';
import common from '../common/common';
Expand Down Expand Up @@ -239,7 +239,7 @@ const renderDoc = (doc, diagram, parentId, altBkg, root, domDocument, diagObj) =
);
});

dagre.layout(graph);
dagreLayout(graph);

log.debug('Graph after layout', graph.nodes());
const svgElem = diagram.node();
Expand Down
2 changes: 1 addition & 1 deletion packages/mermaid/src/tests/setup.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { vi } from 'vitest';
vi.mock('d3');
vi.mock('dagre-d3');
vi.mock('dagre-d3-es');
35 changes: 12 additions & 23 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fd76e0e

Please sign in to comment.