From ac5a1b45014d7e049cea46ff3d32a0404dec62fc Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Thu, 15 Dec 2022 00:01:29 +0000 Subject: [PATCH 1/2] fix(er): switch to deterministic uuids in ER The entity relation diagram uses uuid v4, which is randomly generated. uuid v5 uses a SHA-1 hash, which makes the uuid deterministic. The input strings are unique for each diagram, so this should be okay. --- packages/mermaid/src/diagrams/er/erRenderer.js | 16 +++++++++++++--- .../mermaid/src/diagrams/er/erRenderer.spec.ts | 12 ++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 packages/mermaid/src/diagrams/er/erRenderer.spec.ts diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js index ebf338ae16..7a79201607 100644 --- a/packages/mermaid/src/diagrams/er/erRenderer.js +++ b/packages/mermaid/src/diagrams/er/erRenderer.js @@ -7,7 +7,7 @@ import utils from '../../utils'; import erMarkers from './erMarkers'; import { configureSvgSize } from '../../setupGraphViewbox'; import { parseGenericTypes } from '../common/common'; -import { v4 as uuid4 } from 'uuid'; +import { v5 as uuid5 } from 'uuid'; /** Regex used to remove chars from the entity name so the result can be used in an id */ const BAD_ID_CHARS_REGEXP = /[^\dA-Za-z](\W)*/g; @@ -643,9 +643,15 @@ export const draw = function (text, id, _version, diagObj) { svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); }; // draw +/** UUID namespace for ER diagram IDs */ +const MERMAID_ERDIAGRAM_UUID = uuid5( + 'https://mermaid-js.github.io/mermaid/syntax/entityRelationshipDiagram.html', + uuid5.URL +); + /** * Return a unique id based on the given string. Start with the prefix, then a hyphen, then the - * simplified str, then a hyphen, then a unique uuid. (Hyphens are only included if needed.) + * simplified str, then a hyphen, then a unique uuid based on the str. (Hyphens are only included if needed.) * Although the official XML standard for ids says that many more characters are valid in the id, * this keeps things simple by accepting only A-Za-z0-9. * @@ -656,7 +662,11 @@ export const draw = function (text, id, _version, diagObj) { */ export function generateId(str = '', prefix = '') { const simplifiedStr = str.replace(BAD_ID_CHARS_REGEXP, ''); - return `${strWithHyphen(prefix)}${strWithHyphen(simplifiedStr)}${uuid4()}`; + // we use `uuid v5` so that UUIDs are consistent given a string. + return `${strWithHyphen(prefix)}${strWithHyphen(simplifiedStr)}${uuid5( + str, + MERMAID_ERDIAGRAM_UUID + )}`; } /** diff --git a/packages/mermaid/src/diagrams/er/erRenderer.spec.ts b/packages/mermaid/src/diagrams/er/erRenderer.spec.ts new file mode 100644 index 0000000000..ca0f62bd28 --- /dev/null +++ b/packages/mermaid/src/diagrams/er/erRenderer.spec.ts @@ -0,0 +1,12 @@ +import { generateId } from './erRenderer'; + +describe('erRenderer', () => { + describe('generateId', () => { + it('should be deterministic', () => { + const id1 = generateId('hello world', 'my-prefix'); + const id2 = generateId('hello world', 'my-prefix'); + + expect(id1).toBe(id2); + }); + }); +}); From 7855edae6babc14f9de9dd6de070d71e6800ba53 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Thu, 15 Dec 2022 20:20:04 +0000 Subject: [PATCH 2/2] perf(er): pre-calculcate er UUID namespace Pre-calculate the entity-relationship diagram namespace UUID. This UUID is always constant, so we can pre-calculate it to save a bit of processing power on the client. Co-authored-by: "Ashley Engelund (weedySeaDragon @ github)" Co-authored-by: Sidharth Vinod --- .../mermaid/src/diagrams/er/erRenderer.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/mermaid/src/diagrams/er/erRenderer.js b/packages/mermaid/src/diagrams/er/erRenderer.js index 7a79201607..08b448219c 100644 --- a/packages/mermaid/src/diagrams/er/erRenderer.js +++ b/packages/mermaid/src/diagrams/er/erRenderer.js @@ -643,11 +643,20 @@ export const draw = function (text, id, _version, diagObj) { svg.attr('viewBox', `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); }; // draw -/** UUID namespace for ER diagram IDs */ -const MERMAID_ERDIAGRAM_UUID = uuid5( - 'https://mermaid-js.github.io/mermaid/syntax/entityRelationshipDiagram.html', - uuid5.URL -); +/** + * UUID namespace for ER diagram IDs + * + * This can be generated via running: + * + * ```js + * const { v5: uuid5 } = await import('uuid'); + * uuid5( + * 'https://mermaid-js.github.io/mermaid/syntax/entityRelationshipDiagram.html', + * uuid5.URL + * ); + * ``` + */ +const MERMAID_ERDIAGRAM_UUID = '28e9f9db-3c8d-5aa5-9faf-44286ae5937c'; /** * Return a unique id based on the given string. Start with the prefix, then a hyphen, then the