diff --git a/.changeset/famous-bananas-join.md b/.changeset/famous-bananas-join.md deleted file mode 100644 index 48c29a8ad..000000000 --- a/.changeset/famous-bananas-join.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'mermaid': patch ---- - -Fix for self loops in cluster -Supporting legacy defaultRenderer directive diff --git a/.changeset/khaki-items-leave.md b/.changeset/khaki-items-leave.md deleted file mode 100644 index d84776eb2..000000000 --- a/.changeset/khaki-items-leave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'mermaid': minor ---- - -feat(er): allow multi-line relationship labels diff --git a/.changeset/nice-flowers-yawn.md b/.changeset/nice-flowers-yawn.md deleted file mode 100644 index b3c00cfb4..000000000 --- a/.changeset/nice-flowers-yawn.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'mermaid': minor -'@mermaid-js/docs': patch -'@mermaid-js/parser': minor ---- - -New Diagram: Architecture - -Adds architecture diagrams which allows users to show relations between services. diff --git a/.changeset/pants-things-go.md b/.changeset/pants-things-go.md deleted file mode 100644 index 559e572d1..000000000 --- a/.changeset/pants-things-go.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@mermaid-js/layout-elk': patch ---- - -fix: Updates to the default elk configuration -feat: exposing cycleBreakingStrategy to the configuration so that it can be modified suing the configuration. diff --git a/.cspell/libraries.txt b/.cspell/libraries.txt index ad0e3e701..73a2dceeb 100644 --- a/.cspell/libraries.txt +++ b/.cspell/libraries.txt @@ -30,6 +30,7 @@ Foswiki Gitea graphlib Grav +icones iconify Inkdrop jiti diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 91153084e..3db5f6f37 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,9 +12,11 @@ permissions: # added using https://github.com/step-security/secure-repo jobs: release: + if: github.repository == 'mermaid-js/mermaid' permissions: - contents: write # for changesets/action to push to the repo - pull-requests: write # for changesets/action to create PRs + contents: write # to create release (changesets/action) + id-token: write # OpenID Connect token needed for provenance + pull-requests: write # to create pull request (changesets/action) name: Release runs-on: ubuntu-latest steps: diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts index 133a35032..74b17cf05 100644 --- a/cypress/helpers/util.ts +++ b/cypress/helpers/util.ts @@ -73,7 +73,7 @@ export const imgSnapshotTest = ( export const urlSnapshotTest = ( url: string, - options: CypressMermaidConfig, + options: CypressMermaidConfig = {}, _api = false, validation?: any ): void => { diff --git a/cypress/integration/rendering/architecture.spec.ts b/cypress/integration/rendering/architecture.spec.ts index 459931979..1deb1f7da 100644 --- a/cypress/integration/rendering/architecture.spec.ts +++ b/cypress/integration/rendering/architecture.spec.ts @@ -1,9 +1,9 @@ -import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts'; +import { imgSnapshotTest, urlSnapshotTest } from '../../helpers/util.ts'; -describe('architecture diagram', () => { +describe.skip('architecture diagram', () => { it('should render a simple architecture diagram with groups', () => { imgSnapshotTest( - `architecture + `architecture-beta group api(cloud)[API] service db(database)[Database] in api @@ -21,7 +21,7 @@ describe('architecture diagram', () => { }); it('should render an architecture diagram with groups within groups', () => { imgSnapshotTest( - `architecture + `architecture-beta group api[API] group public[Public API] in api group private[Private API] in api @@ -41,14 +41,14 @@ describe('architecture diagram', () => { }); it('should render an architecture diagram with the fallback icon', () => { imgSnapshotTest( - `architecture + `architecture-beta service unknown(iconnamedoesntexist)[Unknown Icon] ` ); }); it('should render an architecture diagram with split directioning', () => { imgSnapshotTest( - `architecture + `architecture-beta service db(database)[Database] service s3(disk)[Storage] service serv1(server)[Server 1] @@ -64,7 +64,7 @@ describe('architecture diagram', () => { }); it('should render an architecture diagram with directional arrows', () => { imgSnapshotTest( - `architecture + `architecture-beta service servC(server)[Server 1] service servL(server)[Server 2] service servR(server)[Server 3] @@ -85,7 +85,7 @@ describe('architecture diagram', () => { }); it('should render an architecture diagram with group edges', () => { imgSnapshotTest( - `architecture + `architecture-beta group left_group(cloud)[Left] group right_group(cloud)[Right] group top_group(cloud)[Top] @@ -107,7 +107,7 @@ describe('architecture diagram', () => { }); it('should render an architecture diagram with edge labels', () => { imgSnapshotTest( - `architecture + `architecture-beta service servC(server)[Server 1] service servL(server)[Server 2] service servR(server)[Server 3] @@ -128,7 +128,7 @@ describe('architecture diagram', () => { }); it('should render an architecture diagram with simple junction edges', () => { imgSnapshotTest( - `architecture + `architecture-beta service left_disk(disk)[Disk] service top_disk(disk)[Disk] service bottom_disk(disk)[Disk] @@ -148,7 +148,7 @@ describe('architecture diagram', () => { }); it('should render an architecture diagram with complex junction edges', () => { imgSnapshotTest( - `architecture + `architecture-beta group left group right service left_disk(disk)[Disk] in left @@ -172,3 +172,9 @@ describe('architecture diagram', () => { ); }); }); + +describe('architecture - external', () => { + it('should allow adding external icons', () => { + urlSnapshotTest('http://localhost:9000/architecture-external.html'); + }); +}); diff --git a/cypress/integration/rendering/newShapes.spec.ts b/cypress/integration/rendering/newShapes.spec.ts index e26878f40..d2f3a7111 100644 --- a/cypress/integration/rendering/newShapes.spec.ts +++ b/cypress/integration/rendering/newShapes.spec.ts @@ -18,9 +18,9 @@ const newShapesSet2 = [ ] as const; const newShapesSet3 = [ - 'halfRoundedRectangle', 'curvedTrapezoid', 'bowTieRect', + 'waveEdgedRectangle', 'dividedRectangle', 'crossedCircle', ] as const; @@ -29,38 +29,16 @@ const newShapesSet4 = [ 'waveRectangle', 'trapezoidalPentagon', 'linedCylinder', - 'waveEdgedRectangle', 'multiWaveEdgedRectangle', + 'halfRoundedRectangle', ] as const; const newShapesSet5 = [ 'linedWaveEdgedRect', 'taggedWaveEdgedRectangle', - 'text', - 'card', - 'shadedProcess', -] as const; - -const newShapesSet6 = ['roundedRect', 'squareRect', 'stateStart', 'stateEnd', 'labelRect'] as const; - -const newShapesSet7 = ['forkJoin', 'choice', 'note', 'stadium'] as const; - -const newShapesSet8 = [ - 'question', - 'hexagon', 'curlyBraces', - 'multiRect', - 'waveEdgedRectangle', -] as const; - -const newShapesSet9 = ['anchor', 'lean_right', 'lean_left', 'trapezoid', 'inv_trapezoid'] as const; - -const newShapesSet10 = [ - 'subroutine', - 'cylinder', - 'circle', - 'doublecircle', - 'rect_left_inv_arrow', + 'curvedTrapezoid', + 'waveRectangle', ] as const; // Aggregate all shape sets into a single array @@ -70,11 +48,6 @@ const newShapesSets = [ newShapesSet3, newShapesSet4, newShapesSet5, - newShapesSet6, - newShapesSet7, - newShapesSet8, - newShapesSet9, - newShapesSet10, ] as const; looks.forEach((look) => { diff --git a/cypress/integration/rendering/oldShapes.spec.ts b/cypress/integration/rendering/oldShapes.spec.ts new file mode 100644 index 000000000..87615ed6d --- /dev/null +++ b/cypress/integration/rendering/oldShapes.spec.ts @@ -0,0 +1,101 @@ +import { imgSnapshotTest } from '../../helpers/util'; + +const looks = ['classic', 'handDrawn'] as const; +const directions = ['TB', 'BT', 'LR', 'RL'] as const; + +const shapesSet1 = ['text', 'card', 'shadedProcess', 'diamond', 'hexagon'] as const; + +const shapesSet2 = ['roundedRect', 'squareRect', 'stateStart', 'stateEnd', 'labelRect'] as const; + +const shapesSet3 = ['forkJoin', 'choice', 'note', 'stadium', 'odd'] as const; + +const shapesSet4 = ['subroutine', 'cylinder', 'circle', 'doublecircle', 'odd'] as const; + +const shapesSet5 = ['anchor', 'lean_right', 'lean_left', 'trapezoid', 'inv_trapezoid'] as const; + +// Aggregate all shape sets into a single array +const shapesSets = [shapesSet1, shapesSet2, shapesSet3, shapesSet4, shapesSet5] as const; + +looks.forEach((look) => { + directions.forEach((direction) => { + shapesSets.forEach((shapesSet) => { + describe(`Test ${shapesSet.join(', ')} in ${look} look and dir ${direction}`, () => { + it(`without label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape} }@\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`connect all shapes with each other`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index}${index}@{ shape: ${newShape}, label: 'This is a label for ${newShape} shape' }@\n`; + }); + for (let i = 0; i < shapesSet.length; i++) { + for (let j = i + 1; j < shapesSet.length; j++) { + flowchartCode += ` n${i}${i} --> n${j}${j}\n`; + } + } + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with very long label`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is a very very very very very long long long label for ${newShape} shape' }@\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:true`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** and strong for ${newShape} shape' }@\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with markdown htmlLabels:false`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'This is **bold** and strong for ${newShape} shape' }@\n`; + }); + imgSnapshotTest(flowchartCode, { + look, + htmlLabels: false, + flowchart: { htmlLabels: false }, + }); + }); + + it(`with styles`, () => { + let flowchartCode = `flowchart ${direction}\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`; + flowchartCode += ` style n${index}${index} fill:#f9f,stroke:#333,stroke-width:4px \n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + + it(`with classDef`, () => { + let flowchartCode = `flowchart ${direction}\n`; + flowchartCode += ` classDef customClazz fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5\n`; + shapesSet.forEach((newShape, index) => { + flowchartCode += ` n${index} --> n${index}${index}@{ shape: ${newShape}, label: 'new ${newShape} shape' }@\n`; + flowchartCode += ` n${index}${index}:::customClazz\n`; + }); + imgSnapshotTest(flowchartCode, { look }); + }); + }); + }); + }); +}); diff --git a/cypress/platform/architecture-external.html b/cypress/platform/architecture-external.html new file mode 100644 index 000000000..71770425d --- /dev/null +++ b/cypress/platform/architecture-external.html @@ -0,0 +1,52 @@ + + +
+ + ++ architecture-beta + service s3(logos:aws-s3)[Cloud Store] + service ec2(logos:aws-ec2)[Server] + service api(logos:aws-api-gateway)[Api Gateway] + service fa(fa:image)[Font Awesome Icon] ++ + + + diff --git a/demos/architecture.html b/demos/architecture.html index fc65b6beb..6d978d952 100644 --- a/demos/architecture.html +++ b/demos/architecture.html @@ -226,84 +226,31 @@
architecture-beta - service s3(aws:s3)[Cloud Store] - service ec2(aws:ec2)[Server] - service wave(aws:wavelength)[Wave] - service droplet(do:droplet)[Droplet] - service repo(gh:github)[Repository] -+ service s3(logos:aws-s3)[Cloud Store] + service ec2(logos:aws-ec2)[Server] + service api(logos:aws-api-gateway)[Api Gateway] + service fa(fa:image)[Font Awesome Icon] +