Compare commits

...

375 Commits

Author SHA1 Message Date
Knut Sveidqvist
165e0b6c68 Merge pull request #4669 from mermaid-js/release/10.3.0
Release/10.3.0
2023-07-26 09:49:15 +02:00
Knut Sveidqvist
9c92f779ae Updates after testing and new version for mermaid-zenuml 2023-07-26 09:44:24 +02:00
Sidharth Vinod
aa54127784 Set proper release version 2023-07-26 11:34:10 +05:30
Sidharth Vinod
21b90cbcd2 Add release version 2023-07-26 11:33:20 +05:30
Sidharth Vinod
e1ca108b00 Update version 2023-07-26 11:26:07 +05:30
Sidharth Vinod
29d078c822 Merge branch 'master' into release/10.3.0
* master:
  chore: Rename C4C to C4
  update latest news section
  Corrects name of C4 link
  Bump zenuml package version
2023-07-26 11:23:24 +05:30
Sidharth Vinod
40d30b7045 Merge remote-tracking branch 'origin/release/10.3.2' into develop
* origin/release/10.3.2:
2023-07-26 11:21:11 +05:30
Sidharth Vinod
dbee34aba7 fix: edgeLabel width 2023-07-26 11:14:46 +05:30
Sidharth Vinod
68909a43f7 Update lockfile 2023-07-25 21:57:48 +05:30
Sidharth Vinod
d178626bac Merge branch 'develop' into release/10.4.0
* develop:
  Add MERMAID_RELEASE_VERSION in sankey
2023-07-25 21:55:24 +05:30
Sidharth Vinod
d69a2f7895 Merge branches 'develop' and 'develop' of https://github.com/mermaid-js/mermaid into develop
* 'develop' of https://github.com/mermaid-js/mermaid: (21 commits)
  Add comments
  Update packages/mermaid/src/rendering-util/types.d.ts
  Remove redundant test. Already checked in lint.
  Update docs
  Fix lint
  Update packages/mermaid/src/rendering-util/splitText.spec.ts
  Add comments
  Add tests without Intl.Segmenter
  Cleanup
  Fix flowchart failure
  Handle proper formatting for markdown strings
  createText to TS
  Use joiner to split unicode
  Add types
  rename handle-markdown-text
  Add logs
  Cleanup
  Use splitLineToFitWidth function
  Update docs
  feat: split unicode properly
  ...

* 'develop' of https://github.com/mermaid-js/mermaid: (21 commits)
  Add comments
  Update packages/mermaid/src/rendering-util/types.d.ts
  Remove redundant test. Already checked in lint.
  Update docs
  Fix lint
  Update packages/mermaid/src/rendering-util/splitText.spec.ts
  Add comments
  Add tests without Intl.Segmenter
  Cleanup
  Fix flowchart failure
  Handle proper formatting for markdown strings
  createText to TS
  Use joiner to split unicode
  Add types
  rename handle-markdown-text
  Add logs
  Cleanup
  Use splitLineToFitWidth function
  Update docs
  feat: split unicode properly
  ...
2023-07-25 21:54:32 +05:30
Knut Sveidqvist
97f457ca4a Merge branch 'develop' into release/10.4.0 2023-07-25 17:30:24 +02:00
Sidharth Vinod
48c8311369 Add MERMAID_RELEASE_VERSION in sankey 2023-07-25 20:49:54 +05:30
Knut Sveidqvist
c99e1c689e Merge pull request #4470 from mermaid-js/sidv/splitUnicode
Split formatted markdown strings with unicode support.
2023-07-25 15:16:01 +00:00
Knut Sveidqvist
15c6dfcbb5 Updates after tests 2023-07-25 16:43:09 +02:00
Sidharth Vinod
651bc980d2 Merge branch 'sidv/splitUnicode' of https://github.com/mermaid-js/mermaid into sidv/splitUnicode
* 'sidv/splitUnicode' of https://github.com/mermaid-js/mermaid:
  Update packages/mermaid/src/rendering-util/types.d.ts
2023-07-25 20:10:17 +05:30
Sidharth Vinod
841ae15fb5 Add comments 2023-07-25 20:10:05 +05:30
Sidharth Vinod
a7d40724b4 Update packages/mermaid/src/rendering-util/types.d.ts
Co-authored-by: Alois Klink <alois@aloisklink.com>
2023-07-25 19:13:54 +05:30
Sidharth Vinod
409dedb3ef Remove redundant test.
Already checked in lint.
2023-07-25 19:08:40 +05:30
sidharthv96
4ea1227e29 Update docs 2023-07-25 13:33:37 +00:00
Sidharth Vinod
68305fea9e Fix lint 2023-07-25 18:56:58 +05:30
Sidharth Vinod
ea192ccf4d Merge branch 'develop' into sidv/splitUnicode 2023-07-25 18:55:34 +05:30
Sidharth Vinod
509a580f9d Merge pull request #4396 from gjtorikian/patch-2
Fix a typo
2023-07-25 18:54:56 +05:30
Sidharth Vinod
db9051b03e Merge pull request #4660 from Incognito/patch-1
Docs: Corrects name of C4 link
2023-07-25 18:53:14 +05:30
Sidharth Vinod
91ae9a2901 Merge branch 'master' into pr/Incognito/4660
* master:
  update latest news section
2023-07-25 18:41:26 +05:30
Sidharth Vinod
27d98728a6 chore: Rename C4C to C4 2023-07-25 17:42:12 +05:30
Knut Sveidqvist
cfbd38d5fa Merge branch 'develop' into release/10.4.0 2023-07-25 13:02:43 +02:00
Knut Sveidqvist
c67b4178bd Merge pull request #4667 from mermaid-js/develop
2023-07-25
2023-07-25 11:56:58 +02:00
Sidharth Vinod
9ea4b1388f Merge pull request #4666 from kgilbert78/docs/add-typora-to-integrations-list
added Typora to integrations list
2023-07-25 07:57:14 +00:00
Sidharth Vinod
934735372f Merge pull request #4655 from mermaid-js/update-latest-news
Docs: update Latest News section
2023-07-25 13:26:31 +05:30
Steph
28bb0df6c8 update latest news section 2023-07-24 22:15:22 -07:00
kgilbert78
3e3e784fd9 added Typora to integrations list 2023-07-24 13:24:33 -04:00
Sidharth Vinod
1f3902e598 Merge pull request #4662 from mermaid-js/renovate/patch-all-patch
chore(deps): update all patch dependencies (patch)
2023-07-24 07:01:06 +00:00
Sidharth Vinod
3ef02ee66f Merge pull request #4663 from mermaid-js/renovate/all-minor
chore(deps): update all minor dependencies (minor)
2023-07-24 07:00:51 +00:00
renovate[bot]
45400240d4 chore(deps): update all minor dependencies 2023-07-24 00:19:12 +00:00
renovate[bot]
e4699ef02a chore(deps): update all patch dependencies 2023-07-24 00:18:49 +00:00
Brian Graham
60cf043c3d Corrects name of C4 link 2023-07-23 08:27:54 +02:00
Nikolay Rozhkov
a3c645c3eb Merge pull request #4639 from mastersibin/feature/4451-vertical-branches-in-gitgraph
feat | Vertical branches in Git Diagram
2023-07-21 16:30:06 +00:00
Sibin Thomas
bb7b3491e5 Merge branch 'develop' into feature/4451-vertical-branches-in-gitgraph 2023-07-21 14:00:01 +05:30
Alois Klink
38f2ff0bca Merge pull request #4652 from mermaid-js/dependabot/npm_and_yarn/word-wrap-1.2.4
build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4
2023-07-20 22:05:59 +00:00
dependabot[bot]
cd0da4e060 build(deps-dev): bump word-wrap from 1.2.3 to 1.2.4
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-20 17:44:05 +00:00
Sibin Thomas
df89b92e2c ran docs:build for documentation 2023-07-20 21:45:47 +05:30
Sibin Thomas
114f918417 Merge branch 'develop' into feature/4451-vertical-branches-in-gitgraph 2023-07-20 21:29:56 +05:30
Sibin Thomas
346a7fe8b2 Merge branch 'feature/4451-vertical-branches-in-gitgraph' of https://github.com/mastersibin/mermaid into feature/4451-vertical-branches-in-gitgraph 2023-07-20 21:28:21 +05:30
Sibin Thomas
8ae35c1382 updated documentation for vertical branches 2023-07-20 21:27:34 +05:30
Sidharth Vinod
687a9a08d7 Merge pull request #4612 from mermaid-js/sidv/docsVersion
Support MERMAID_RELEASE_VERSION in docs.
2023-07-20 15:30:11 +00:00
Sidharth Vinod
478d350188 Update .github/pull_request_template.md
Co-authored-by: Alois Klink <alois@aloisklink.com>
2023-07-20 20:48:12 +05:30
Sidharth Vinod
4795204719 Merge branch 'develop' into sidv/docsVersion
* develop:
  build(docs): handle YAML edgecases in markdown
  run pnpm lint:fix
  Update cypress/helpers/util.ts
  change deprecated `btoa` into `Buffer.from`
  allow ts extension imports in cypress ts files
  build(docs): allow using custom `editLink`
  build(docs): add `editLink: ` to MD frontmatter
  build(docs): run remark plugins on MermaidConfig
  Fix import file extension
  Batch by commit
  resolve lint issues for `no-inferrable-types`
  fix wrong config paramater in some cypress spec
  convert cypress/helpers/util.js into ts
  convert file from js into ts
2023-07-20 20:46:53 +05:30
Sibin Thomas
99e88e4d0d Merge branch 'develop' into feature/4451-vertical-branches-in-gitgraph 2023-07-20 16:03:19 +05:30
Sibin Thomas
a171903088 added tests for overlapping commits 2023-07-20 13:15:05 +05:30
Sidharth Vinod
1b2340ba75 Merge pull request #4640 from aloisklink/docs/fix-edit-url
Fix the "Edit this page on GitHub" link in Vitepress documentation for the Mermaid Config pages
2023-07-20 06:59:46 +00:00
Alois Klink
4d2d790cc8 build(docs): handle YAML edgecases in markdown
Our current method of adding a entry using `+=` is not safe in YAML,
since it's valid to make a YAML object entirely in JSON,
see https://github.com/mermaid-js/mermaid/pull/4640#discussion_r1265133463

We're already using `js-yaml` elsewhere in this file, so we may as well
use it for parsing/stringifying.

Reported-by: Remco Haszing <remcohaszing@gmail.com>
2023-07-19 23:40:46 +01:00
Sidharth Vinod
477bb4308d Merge pull request #4552 from Yokozuna59/convert-cypress-util-to-ts
convert `cypress/helpers/util.js` to ts
2023-07-19 17:49:42 +00:00
Yokozuna59
8cd8714aaf run pnpm lint:fix 2023-07-19 23:45:02 +03:00
Sidharth Vinod
e25faeee4c Update cypress/helpers/util.ts 2023-07-19 22:36:55 +05:30
Sibin Thomas
cba5b5a7e3 ran preetier 2023-07-19 21:55:24 +05:30
Yokozuna59
66e5f8ae18 Merge branch 'develop' into convert-cypress-util-to-ts 2023-07-19 19:09:58 +03:00
Sibin Thomas
52a4f8f077 added tests for vertical branches 2023-07-19 20:22:59 +05:30
Sibin Thomas
d81e4fabd5 positioned tags, tilted commit labels and fixed some bugs 2023-07-19 20:22:29 +05:30
Sibin Thomas
863d1bfd4d removed BT and added TB 2023-07-19 20:21:15 +05:30
Sibin Thomas
9c2afac319 Merge branch 'mermaid-js:develop' into feature/4451-vertical-branches-in-gitgraph 2023-07-19 20:13:53 +05:30
Sidharth Vinod
568d686d2f Merge branch 'develop' into sidv/docsVersion 2023-07-18 22:07:42 +05:30
Sidharth Vinod
3fcb071592 Move docs.cli to scripts 2023-07-18 22:06:43 +05:30
Sidharth Vinod
483385b2f6 Update PR template 2023-07-18 21:59:00 +05:30
Sidharth Vinod
fff3acd064 Verify release-version on push to release or master 2023-07-18 21:55:44 +05:30
Sidharth Vinod
e66135b67e Merge pull request #4496 from moka-care/bug/4439_graph_doesnt_load_when_img_fail_to_load
Fix graph not loading when the img loads too fast or fail to load
2023-07-18 07:57:38 +00:00
Yokozuna59
072638ce9d Merge pull request #4634 from leinelissen/develop
feat: allow specifying on which weekday a tickInterval should start
2023-07-18 07:33:08 +00:00
Yokozuna59
d9314a869a change deprecated btoa into Buffer.from 2023-07-17 15:58:58 +03:00
Yokozuna59
662eb431ab allow ts extension imports in cypress ts files 2023-07-17 15:53:26 +03:00
Yokozuna59
bed8710dbb Merge branch 'mermaid-js:develop' into convert-cypress-util-to-ts 2023-07-17 15:31:11 +03:00
Sidharth Vinod
38c0a94067 Merge pull request #4633 from ibrahimWassouf/bug/4592_fix_newLine_padding_class_diagram
Bug/4592 fix new line padding class diagram
2023-07-17 09:50:47 +00:00
Sidharth Vinod
d3006f6298 chore: Remove numbers from tests 2023-07-17 15:16:05 +05:30
Sidharth Vinod
24f04bb24d Merge branch 'develop' into bug/4592_fix_newLine_padding_class_diagram 2023-07-17 15:11:39 +05:30
Sidharth Vinod
b5bcc3b992 Revert "Refactor integration tests"
This reverts commit 80add648e6.
2023-07-17 15:11:14 +05:30
Sidharth Vinod
48a49b1b4d Merge pull request #4588 from ibrahimWassouf/enhancement/4158_Add_primary_key_beginning_with_asterisk
Allow entity diagram attribute names to start with asterisk
2023-07-17 09:26:46 +00:00
Sidharth Vinod
5e6d42cb5b Merge pull request #4641 from aloisklink/chore/remove-unused-coveralls-devDependency
chore: remove unused `devDependency` on coveralls
2023-07-17 09:20:02 +00:00
Sidharth Vinod
417c69d7e2 Merge pull request #4646 from guilhermgonzaga/docs/fix_checkbox_format
docs: Fix checkbox syntax
2023-07-17 09:07:08 +00:00
Guilherme Gonzaga
855f6ef9bf docs: Fix checkbox syntax 2023-07-16 23:16:37 +00:00
Alois Klink
a0a25ed756 chore: remove unused devDependency on coveralls
This `devDependency` hasn't been used for a long time.
2023-07-16 00:21:43 +01:00
Alois Klink
af9b3f77cb build(docs): allow using custom editLink
In Vitepress, allow using a custom `editLink`, if specified in the YAML
frontmatter.
2023-07-15 23:43:24 +01:00
Alois Klink
57ee181fad build(docs): add editLink: to MD frontmatter
Add a YAML front-matter entry called `editLink` to Markdown files in
Vitepress, e.g.

```markdown
---
editLink: "https://github.com/mermaid-js/mermaid/edit/develop/packages/mermaid/src/schemas/config.schema.yaml"
---

Here is my markdown file!
```

Although Vitepress doesn't officially support adding a URL as a
`editLink:` YAML front-matter, we can add a custom `editLink` function
to our Vitepress config that does allow it.
2023-07-15 23:43:24 +01:00
Yokozuna59
39ccad8e5e Merge branch 'develop' into develop 2023-07-15 15:44:19 +02:00
Lei Nelissen
7e39c13836 chore: narrow down tstype 2023-07-15 15:38:21 +02:00
Lei Nelissen
85515bcf8d chore: leave the newLine out of the jison spec 2023-07-15 15:28:48 +02:00
Sibin Thomas
383bbefa9e Added code for Vertical branches for GitGraph and Added TB option in the parser file. 2023-07-15 18:27:42 +05:30
Ibrahim Wassouf
9b9671b57c Merge branch 'develop' into enhancement/4158_Add_primary_key_beginning_with_asterisk 2023-07-15 08:50:01 -04:00
Ibrahim Wassouf
d6c88ab589 Merge branch 'develop' into bug/4592_fix_newLine_padding_class_diagram 2023-07-15 08:49:38 -04:00
Sidharth Vinod
840609af63 Merge pull request #4577 from kislerdm/bug/4576-c4-support-for-ContainerQueue_Ext
Fixes support of the macro `ContainerQueue_Ext` for C4 diagrams definition.
2023-07-15 07:35:05 +00:00
Lei Nelissen
eff9f7e5db chore: re-generate config 2023-07-15 00:24:02 +02:00
Lei Nelissen
803cd826ed chore: replace switch-case with map 2023-07-15 00:17:10 +02:00
Lei Nelissen
90c68f5069 chore: add tsType for weekday config 2023-07-15 00:17:09 +02:00
Lei Nelissen
103321bf72 chore: return after scanning weekday in jison 2023-07-15 00:17:09 +02:00
Lei Nelissen
d0afc3bffe feat: validate individual values of weekdays 2023-07-14 14:13:18 +02:00
Lei Nelissen
11f2e31ff1 fix: also set weekday value to sunday in clear 2023-07-14 14:13:18 +02:00
Lei Nelissen
d9c15b1e7a chore: move spec test to it.each 2023-07-14 14:13:18 +02:00
Lei Nelissen
4e8eeda30e chore: also apply weekday to topXAxis 2023-07-14 14:13:18 +02:00
Lei Nelissen
cfe31fe89f chore: generate new docs 2023-07-14 14:13:18 +02:00
Lei Nelissen
ebf639377b chore: generate typescript config type 2023-07-14 14:13:18 +02:00
Lei Nelissen
37adc23ae2 chore: also default to sundat in ganttDb 2023-07-14 14:13:18 +02:00
Lei Nelissen
5f7212c769 chore: move default value to config.schema.yaml 2023-07-14 14:13:18 +02:00
Lei Nelissen
cd92c46f31 chore: format example more correctly 2023-07-14 14:13:18 +02:00
Lei Nelissen
df10ab501a chore: add tests for all days 2023-07-14 14:13:18 +02:00
Lei Nelissen
0d7427ed20 chore: add cypress test 2023-07-14 14:13:18 +02:00
Lei Nelissen
e360e90f88 chore: move documentation to source file 2023-07-14 14:13:18 +02:00
Lei Nelissen
03ce2810b5 feat: allow specifying on which weekday a tickInterval should start 2023-07-14 14:13:18 +02:00
Lei Nelissen
5631a218d1 fix: make gantt chart interval weeks start on monday instead of sunday 2023-07-14 14:13:18 +02:00
Alois Klink
7cb009cd38 build(docs): run remark plugins on MermaidConfig
We use the `unified.stringify()` function on our remark plugins to
stringify the Markdown AST for our MermaidConfig documentation.
However, [`.stringify()`][1] only runs the stringify phase in unified,
not the "run" phase. If we want to run our plugins on the Markdown AST,
we need to also use the [`.run()`][2] function.

[1]: https://github.com/unifiedjs/unified#processorstringifytree-file
[2]: https://github.com/unifiedjs/unified#processorruntree-file-done
2023-07-13 23:59:27 +01:00
Ibrahim Wassouf
bb220b8b87 Add test for string label 2023-07-13 16:53:29 -03:00
Ibrahim Wassouf
80add648e6 Refactor integration tests 2023-07-13 16:43:52 -03:00
Ibrahim Wassouf
081d1b1144 Merge branch 'develop' into bug/4592_fix_newLine_padding_class_diagram 2023-07-13 16:38:47 -03:00
Sidharth Vinod
946b5f161e Merge pull request #4623 from mermaid-js/renovate/patch-all-patch
chore(deps): update all patch dependencies (patch)
2023-07-13 19:09:27 +00:00
Ibrahim Wassouf
e9f032cceb Update packages/mermaid/src/dagre-wrapper/nodes.js
Co-authored-by: Sidharth Vinod <sidharthv96@gmail.com>
2023-07-13 15:57:58 -03:00
Ibrahim Wassouf
aeba7a1d0e Update packages/mermaid/src/dagre-wrapper/nodes.js
Co-authored-by: Sidharth Vinod <sidharthv96@gmail.com>
2023-07-13 15:57:28 -03:00
Yokozuna59
14d3d203d7 Merge branch 'develop' into convert-cypress-util-to-ts 2023-07-13 17:29:33 +02:00
Dmitry Kisler
584b51d7c5 Merge branch 'develop' into bug/4576-c4-support-for-ContainerQueue_Ext 2023-07-13 12:07:46 +02:00
Ibrahim Wassouf
12c657f514 Add imgSnapshotTests 2023-07-12 16:46:29 -03:00
Ibrahim Wassouf
d47c9d754a Merge branch 'develop' into enhancement/4158_Add_primary_key_beginning_with_asterisk 2023-07-11 20:04:20 -03:00
Ibrahim Wassouf
d2ab132a18 Change class member height to use own BBox 2023-07-11 19:39:39 -03:00
renovate[bot]
d46ef4cc91 chore(deps): update all patch dependencies 2023-07-11 17:19:31 +00:00
Nikolay Rozhkov
0a493c79ff Merge pull request #4631 from nirname/refactoring/removed-unused-code-in-state-diagrams
Removed unused code in state diagrams
2023-07-11 17:13:03 +00:00
Nikolay Rozhkov
3664ff4463 Removed unused code in state diagrams 2023-07-11 18:12:27 +03:00
Pierrick Wauquier
9e5ccbe13f Merge branch 'develop' into bug/4439_graph_doesnt_load_when_img_fail_to_load 2023-07-11 17:10:19 +02:00
Nikolay Rozhkov
cd1765a012 Merge pull request #4597 from ibrahimWassouf/bug/4590_allow_notes_identical_to_keywords
Bug/4590 allow notes identical to keywords
2023-07-11 11:52:33 +00:00
Ibrahim Wassouf
1bafc7b84f Merge branch 'develop' into enhancement/4158_Add_primary_key_beginning_with_asterisk 2023-07-10 19:35:24 -04:00
Ibrahim Wassouf
7bf1d38bad Merge branch 'develop' into bug/4590_allow_notes_identical_to_keywords 2023-07-10 19:34:51 -04:00
Sidharth Vinod
8e0cb185e9 Merge pull request #4624 from mermaid-js/renovate/all-minor
chore(deps): update all minor dependencies (minor)
2023-07-10 06:58:59 +00:00
renovate[bot]
47f46c8a46 chore(deps): update all minor dependencies 2023-07-10 01:17:36 +00:00
Ibrahim Wassouf
e127b146e9 Add more test cases 2023-07-08 17:46:28 -03:00
Ibrahim Wassouf
c59fee8de2 Split tests to have one parse statement in each test 2023-07-08 17:20:56 -03:00
Ibrahim Wassouf
00bb2a1f68 Revert back to single quotes for generic grammar 2023-07-08 14:45:06 -03:00
Ibrahim Wassouf
007724a7c7 Merge branch 'develop' into bug/4590_allow_notes_identical_to_keywords 2023-07-08 13:34:28 -04:00
Ibrahim Wassouf
f82407a2f0 Make unit test regex unit test more accurate 2023-07-08 14:33:57 -03:00
Ibrahim Wassouf
4bec3188de Reformat code 2023-07-08 14:12:45 -03:00
Ibrahim Wassouf
fbb6eb849e Give call higher precedence than STR 2023-07-08 14:07:46 -03:00
Ibrahim Wassouf
6a40f4b955 Decouple HREF token from STR and correct grammar 2023-07-08 13:34:51 -03:00
Ibrahim Wassouf
58b2b0993a Give STR token higher precedence 2023-07-08 13:29:48 -03:00
Ibrahim Wassouf
d05d249080 Undo state changes 2023-07-08 13:28:45 -03:00
Ibrahim Wassouf
1e781c0c90 Refactor unit tests 2023-07-08 13:23:46 -03:00
Sidharth Vinod
eca2efa46d Update packages/mermaid/src/rendering-util/splitText.spec.ts
Co-authored-by: Alois Klink <alois@aloisklink.com>
2023-07-08 19:01:45 +05:30
Ibrahim Wassouf
23f27d151a Remove redundancy in unit tests 2023-07-07 22:44:34 -03:00
Ibrahim Wassouf
cd118ad5cb Update erDiagram to make entity names in singular form 2023-07-07 19:59:52 -03:00
Ibrahim Wassouf
cf0a9c3016 Merge branch 'develop' into enhancement/4158_Add_primary_key_beginning_with_asterisk 2023-07-07 14:31:45 -04:00
Sidharth Vinod
0cdf801884 Fix import file extension 2023-07-07 17:21:18 +05:30
Sidharth Vinod
07df9eeb60 Rename docs.cli.mts 2023-07-07 15:57:05 +05:30
Sidharth Vinod
962ff73fc3 Batch by commit 2023-07-07 15:56:30 +05:30
Yokozuna59
f0bf6bf574 Merge branch 'develop' into convert-cypress-util-to-ts 2023-07-07 11:17:22 +02:00
Sidharth Vinod
79d38cef4b Run docs:release-version in CI 2023-07-07 11:32:00 +05:30
Sidharth Vinod
88856a721f Support MERMAID_RELEASE_VERSION in docs 2023-07-07 11:28:04 +05:30
Sidharth Vinod
60c2d494a1 Merge pull request #4607 from mermaid-js/fix/prLabeler
Run PR-labeler-config-validator only if config changes
2023-07-07 05:15:14 +00:00
Sidharth Vinod
0f4af09398 Add Area: Documentation to labeler 2023-07-07 10:32:13 +05:30
Sidharth Vinod
052e9db16a Remove filter action 2023-07-07 10:30:59 +05:30
Sidharth Vinod
4648532814 Update .github/workflows/pr-labeler-config-validator.yml
Co-authored-by: Alois Klink <alois@aloisklink.com>
2023-07-07 10:29:58 +05:30
Sidharth Vinod
9263f75e5b Update .github/pr-labeler.yml
Co-authored-by: Alois Klink <alois@aloisklink.com>
2023-07-07 10:27:56 +05:30
Sidharth Vinod
8348a2f2d8 Merge pull request #4610 from aloisklink/test/remove-old-default-config-test
Remove the test checking whether the JSON Schema default config matched the old default config
2023-07-07 04:41:00 +00:00
Sidharth Vinod
28406fc9c4 Add comments 2023-07-07 10:05:05 +05:30
Sidharth Vinod
d58c41dbc0 Add tests without Intl.Segmenter 2023-07-07 10:02:04 +05:30
Ibrahim Wassouf
5d76c033f0 Merge branch 'develop' into enhancement/4158_Add_primary_key_beginning_with_asterisk 2023-07-06 21:18:38 -04:00
Ibrahim Wassouf
fad11bce95 Correct one unit test and add another 2023-07-06 22:17:33 -03:00
Ibrahim Wassouf
42da53f58a Add imgSnapshotTest 2023-07-06 22:15:18 -03:00
Alois Klink
8167f8c1df Revert "test(config): add temp test for defaultConfig"
This reverts commit 063cb124cd.

This file was originally added to test whether the new implementation
of the default config in
`packages/mermaid/src/schemas/config.schema.yaml` matched the old
existing default config in `packages/mermaid/src/oldDefaultConfig.ts`,
and this test is no longer needed.
2023-07-07 02:05:43 +01:00
Alois Klink
2b53e02153 test: fix 'new default config' test
This test was accidentally removed by a bad merge commit, see
29291c89 (Merge branch 'develop' into pr/aloisklink/4112, 2023-07-06).

This test checks whether the default config defined in the
`config.schema.yaml` file matches the old default config defined in
`oldDefaultConfig.ts`.

Fixes: 29291c8901
2023-07-07 02:01:03 +01:00
Ibrahim Wassouf
4af2fca339 Add documentation for feature 2023-07-06 19:40:54 -03:00
Sidharth Vinod
b14bcda12a Merge branch 'develop' into sidv/splitUnicode 2023-07-06 22:08:51 +05:30
Sidharth Vinod
1682fa1e53 Update PR Labeler config 2023-07-06 22:05:58 +05:30
Sidharth Vinod
355586f297 Run PR-labeler-config-validator only if config changes 2023-07-06 22:03:48 +05:30
Sidharth Vinod
7d996c3d33 Cleanup 2023-07-06 21:48:18 +05:30
Sidharth Vinod
194ef202ac Merge pull request #4603 from mermaid-js/sidv/optimiseDocs
Avoid downloading avtars everytime on docs:dev
2023-07-06 16:10:53 +00:00
Sidharth Vinod
bcffff3b7b Terminate build in CI if download fails 2023-07-06 21:36:10 +05:30
Sidharth Vinod
d4281d365d Add Yokozuna59 & nirname 2023-07-06 21:29:40 +05:30
Sidharth Vinod
5ac70bbc00 Fix flowchart failure 2023-07-06 21:22:28 +05:30
Sidharth Vinod
60a93f7377 Handle proper formatting for markdown strings 2023-07-06 20:34:17 +05:30
Sidharth Vinod
f5484636aa createText to TS 2023-07-06 16:12:09 +05:30
Sidharth Vinod
b0a104e3da Merge branch 'develop' into sidv/splitUnicode
* develop: (293 commits)
  chore: Remove lint warnings in example-diagram
  chore: Reduce codecov pushes
  Turn off codecov project status check
  build(docs): fix links to `config.schema.json`
  ci(lint): check if MermaidConfig types are in sync
  docs: add link to mermaid config docs in sidebar
  test(config): add temp test for defaultConfig
  build(types): create types from config JSON Schema
  build(types): add script to generate Config types
  build(docs): build JSON Schema docs
  build: use vite to get default mermaid config
  feat: add Mermaid Config in JSON Schema format
  docs: add support for ```regexp``` code blocks
  test: test partial QuadrantChartConfig options
  test: fix types in `config.spec.ts`
  style: fix lint issues in src/config.spec.ts
  test: rename src/config.spec.js to config.spec.ts
  fix(quadrant): make quadrant options optional
  fix lint
  update homepage community link
  ...
2023-07-06 16:00:11 +05:30
Sidharth Vinod
48050333a0 Merge branch 'develop' into sidv/optimiseDocs 2023-07-06 15:57:01 +05:30
Sidharth Vinod
c17dc15c57 chore: Rename to teamMembers 2023-07-06 15:54:27 +05:30
Sidharth Vinod
34abbcadae Merge pull request #4604 from mermaid-js/sidv/fixCodecov
chore: Reduce codecov pushes
2023-07-06 10:20:26 +00:00
Sidharth Vinod
2b5da79cdf Merge pull request #4112 from aloisklink/add-jsonschema-schema-for-config
Use JSON Schema to define and document `MermaidConfig`
2023-07-06 10:03:55 +00:00
Sidharth Vinod
2366ca85b3 Merge branch 'develop' into sidv/fixCodecov 2023-07-06 11:59:44 +05:30
Sidharth Vinod
aaec16ed6c chore: Remove lint warnings in example-diagram 2023-07-06 11:58:55 +05:30
Sidharth Vinod
a3d95ceec4 Bump zenuml package version 2023-07-06 11:36:16 +05:30
Sidharth Vinod
4d0c461fa3 chore: Reduce codecov pushes
pushes to non-develop branches will not send coverage reports.
This might reduce the coverage variability issue we're having.
2023-07-06 11:32:37 +05:30
Sidharth Vinod
db30f21ac5 Turn off codecov project status check 2023-07-06 11:16:41 +05:30
Sidharth Vinod
d2e62022f1 Avoid downloading avtars everytime on docs:dev 2023-07-06 11:09:09 +05:30
Sidharth Vinod
29291c8901 Merge branch 'develop' into pr/aloisklink/4112
* develop:
  test: test partial QuadrantChartConfig options
  test: fix types in `config.spec.ts`
  style: fix lint issues in src/config.spec.ts
  test: rename src/config.spec.js to config.spec.ts
  fix lint
  update homepage community link
  docs(flowchart): add documentation on multiple nodes style
  Add docker-specific command, leave commonly used command intact
  Support docs:dev in docker
  Fix lint.
  Update docs
  add ChatGPT plugin blog post
  Fix flowchart tooltip typing
2023-07-06 10:42:13 +05:30
Sidharth Vinod
1a4e5d9c5a Merge pull request #4562 from lishid/patch-3
Fix flowchart tooltip typing bug
2023-07-06 04:19:08 +00:00
Sidharth Vinod
e80e281a66 Merge pull request #4600 from tomperr/docs/4558-multiple-vertices-with-style
docs(flowchart): add documentation on multiple nodes style
2023-07-06 04:10:43 +00:00
Nikolay Rozhkov
04597d29c0 Merge pull request #4599 from nirname/fix/support-docs-dev-in-docker
Support docs:dev in docker
2023-07-06 04:04:18 +00:00
Sidharth Vinod
43df84a4d5 Merge branch 'master' into develop
* master:
  fix lint
  update homepage community link
  Update docs
  add ChatGPT plugin blog post
2023-07-06 09:34:26 +05:30
Sidharth Vinod
a753b1f18b Merge branch 'develop' into fix/support-docs-dev-in-docker 2023-07-06 09:29:51 +05:30
Sidharth Vinod
d80095bbef Merge pull request #4601 from mermaid-js/homepage-community-link
Docs: update link - "Join the Community"
2023-07-06 09:26:10 +05:30
Sidharth Vinod
4d79f42d0e Merge pull request #4602 from aloisklink/fix/make-quadrant-chart-options-optional
Make quadrant chart options TypeScript types optional
2023-07-06 03:54:08 +00:00
Alois Klink
c29088af01 build(docs): fix links to config.schema.json
Fix the link in some Mermaid Config markdown documentation,
which previously pointed to `src/schemas/config.schema.yaml`,
which went nowhere.

Now, these links point to:
  - config.schema.json (i.e. the generated JSON file, not YAML)
  - links are relative to the markdown documentation

We also needed to store the `schema.json` file in the Vitepress
`public/` folder, as Vitepress otherwise doesn't bundle `.json` files
properly, when running `vitepress build src/vitepress`.
2023-07-06 03:53:40 +01:00
Alois Klink
23d6a0dab7 ci(lint): check if MermaidConfig types are in sync
Add a CI check that runs
`pnpm run --filter mermaid types:verify-config` and checks whether
the MermaidConfig TypeScript types are in sync with the MermaidConfig
JSON Schema.
2023-07-06 03:53:40 +01:00
Alois Klink
70a5a13273 docs: add link to mermaid config docs in sidebar 2023-07-06 03:53:40 +01:00
Alois Klink
063cb124cd test(config): add temp test for defaultConfig
Adds a temporary test to ensure that the new defaultConfig,
generated by Vite automatically from the `MermaidConfig` JSON Schema,
has the same values as the old defaultConfig
(taken from
38013de711/packages/mermaid/src/defaultConfig.ts)

The only minor difference seems to be that:
  - `gitGraph` now has a default `useMaxWidth: false` option
    (previously used to be `undefined`),
  - `class` now has a `htmlLabels` value of `false` instead of `undefined`.
2023-07-06 03:53:40 +01:00
Alois Klink
eb5d65fabc build(types): create types from config JSON Schema
Runs `pnpm --filter mermaid run types:build-config` to automatically
generate typescript types for `MermaidConfig` from the
JSON Schema file.
2023-07-06 03:53:40 +01:00
Alois Klink
7c3a73d4a8 build(types): add script to generate Config types
Add script `packages/mermaid/scripts/create-types-from-json-schema.mts`
to automatically generate the TypeScript definition for `MermaidConfig`
from the `MermaidConfig` JSON Schema at
`packages/mermaid/src/schemas/config.schema.yaml`.

To do this, we are using this library
[`json-schema-to-typescript`][1], which is also used by Webpack to
generate their types from their JSON Schema.

In order to make sure that this isn't a breaking change, the script
makes all fields **optional**, as that is what the original typescript
file has.

Additionally, I've put in some custom logic into the script, so that
the exact same order is used for the TypeScript file, to make the
`git diff` easier to review. In the future, we can remove this custom
logic, once we no longer need to worry about `git merge` conflicts.

[1]: https://github.com/bcherny/json-schema-to-typescript
2023-07-06 03:53:40 +01:00
Alois Klink
0230722d36 build(docs): build JSON Schema docs
Automatically build documentation for JSON Schema.

This is only built when running with `--vitepress`,
as it currently produces loads of markdown files, which I feel like
we shouldn't be committing.

This currently manually uses some internal `jsonschema2md` functions
so that we can manually control the Markdown output.
2023-07-06 03:53:40 +01:00
Alois Klink
52a1243da5 build: use vite to get default mermaid config
Adds a vitepress JsonSchema plugin that automatically loads
the Mermaid Config JSON Schema from a .schema.yaml file and
gets the default values from it.
2023-07-06 03:53:40 +01:00
Alois Klink
58b43976ff feat: add Mermaid Config in JSON Schema format
Add a JSON Schema file (in YAML) for the MermaidConfig.

This JSON Schema file follows [JSON Schema 2019-09][1], with some slight
modifications to work with:

- [json-schema-to-typescript][2]
  The `tsType` keyword is used to override the generated TypeScript
  type, when it doesn't match the JSON Schema type.

  This is used in two cases:
    - when the current type cannot be represented in JSON Schema
      (e.g. `FontCalculator`, which is a function)
    - when the JSON Schema type is narrower than the TypeScript type.
      Currently, many enums types are listed as `string` in TypeScript,
      but json-schema-to-typescript converts them to `"val1" | "val2"`.
      I've manually set them to `string | "val1" | "val2"` to avoid
      causing a breaking change in the TypeScript types. We should
      remove these in a future major version of TypeScript.
- [@adobe/jsonschema2md][3]
  The `meta:enum` keyword is used to add documentation for specific enum
  values.

[1]: https://json-schema.org/draft/2019-09/release-notes.html
[2]: https://www.npmjs.com/package/json-schema-to-typescript
[3]: https://www.npmjs.com/package/@adobe/jsonschema2md
2023-07-06 03:53:35 +01:00
Alois Klink
4372a54dba docs: add support for ``regexp`` code blocks
Currently, shiki doesn't support code-blocks that use the regexp
language, which means vitepress throws an error on them:

```regexp
^([1-9][0-9]*)(minute|hour|day|week|month)$
```

As a hack until shiki supports them, I've just modified them to get
converted into JavaScript RegEx literal code-blocks, e.g.:

```javascript
/^([1-9][0-9]*)(minute|hour|day|week|month)$/
```
2023-07-06 03:04:08 +01:00
Alois Klink
a862565a24 test: test partial QuadrantChartConfig options 2023-07-06 01:35:11 +01:00
Alois Klink
6ceee7f253 test: fix types in config.spec.ts
The `foo`, `bar`, and `foobar` options don't exist in MermaidConfig.

Instead, I've replaced them with:
  - `foo` -> `fontFamily`
  - `bar` -> `fontSize`
  - `foobar` -> `altfontFamily`
2023-07-06 01:27:24 +01:00
Alois Klink
f731853e01 style: fix lint issues in src/config.spec.ts
It looks like our linter automatically converts `let` to `const` in
TypeScript files, but not in JavaScript files.
2023-07-06 01:20:24 +01:00
Alois Klink
5885f5f82a test: rename src/config.spec.js to config.spec.ts 2023-07-06 01:19:34 +01:00
Alois Klink
38013de711 fix(quadrant): make quadrant options optional
Make the types of the options in QuadrantChartConfig in the
MermaidConfig optional. All of these (except for the values in
`BaseDiagramConfig`) will be automatically set to their
default values, so they're optional from a user perspective.
2023-07-06 01:06:01 +01:00
Steph
9251e520ab fix lint 2023-07-05 13:50:33 -07:00
Steph
5e7e3e21c8 update homepage community link 2023-07-05 13:42:42 -07:00
Tom PERRILLAT-COLLOMB
fcb25aee7c docs(flowchart): add documentation on multiple nodes style 2023-07-05 21:09:44 +02:00
Nikolay Rozhkov
95d62367e9 Add docker-specific command, leave commonly used command intact 2023-07-05 19:39:05 +03:00
Ibrahim Wassouf
1d5f3bb64d Merge branch 'develop' into enhancement/4158_Add_primary_key_beginning_with_asterisk 2023-07-05 11:19:08 -04:00
Ibrahim Wassouf
bd772e1bf4 Merge branch 'develop' into bug/4590_allow_notes_identical_to_keywords 2023-07-05 11:00:00 -04:00
Nikolay Rozhkov
34b2b5ba35 Support docs:dev in docker 2023-07-05 17:25:07 +03:00
Nikolay Rozhkov
c742ac71a4 Merge pull request #4598 from mermaid-js/sidv/fixDocsDev
Fix docs:dev
2023-07-05 14:05:27 +00:00
Sidharth Vinod
62b988a09f Merge pull request #4595 from nirname/fix/sankey-diagram-examples
Sankey: Remove duplicated examples
2023-07-05 06:53:43 +00:00
Sidharth Vinod
382026ed33 Fix docs:dev 2023-07-05 12:20:56 +05:30
Ibrahim Wassouf
34e89098f5 Refactor code smells in unit tests 2023-07-04 21:34:14 -03:00
Ibrahim Wassouf
e3c90ac084 Apply formatting to file 2023-07-04 21:16:14 -03:00
Ibrahim Wassouf
099f85f014 Add unit tests with keywords in notes 2023-07-04 21:07:46 -03:00
Ibrahim Wassouf
49747b314d Modify wildcard state of tokens in lexer 2023-07-04 20:44:22 -03:00
Nikolay Rozhkov
9f5f0a6e66 Reduce sankey width 2023-07-05 01:49:58 +03:00
nirname
6f03e22cc4 Update docs 2023-07-04 22:18:57 +00:00
Nikolay Rozhkov
8449a44607 Sankey: Remove duplicated examples 2023-07-05 01:15:22 +03:00
Lishid
12fe6ff26e Fix lint. 2023-07-03 18:56:00 -07:00
Ibrahim Wassouf
451b6b687e Merge branch 'develop' into enhancement/4158_Add_primary_key_beginning_with_asterisk 2023-07-03 19:54:26 -04:00
Nikolay Rozhkov
f431bae0ba Merge pull request #4587 from nirname/refactoring/remove-double-parsing
Remove double parsing
2023-07-03 22:02:20 +00:00
Ibrahim Wassouf
5a94256e4f Allow entity diagram attribute names to start with asterisk 2023-07-03 15:11:02 -03:00
Nikolay Rozhkov
d5021cab1d Remove double parsing 2023-07-03 18:57:26 +03:00
Sidharth Vinod
288f51216d Add codecov token 2023-07-03 21:01:04 +05:30
Sidharth Vinod
1b190b2892 Merge pull request #4551 from Yokozuna59/refactor-accessibility
refactor accessibility
2023-07-03 15:07:21 +00:00
Sidharth Vinod
8e15e534ea Add codecov token 2023-07-03 19:19:11 +05:30
Sidharth Vinod
6d7cd2b41f Merge pull request #4580 from aloisklink/refactor/replace-enums
Remove all TypeScript enums and forbid them in ESLint
2023-07-03 07:26:39 +00:00
Sidharth Vinod
15b2105ce6 Merge pull request #4581 from mermaid-js/renovate/patch-all-patch
Update all patch dependencies (patch)
2023-07-03 07:10:51 +00:00
renovate[bot]
d6731a07db Update all patch dependencies 2023-07-03 05:18:01 +00:00
Alois Klink
79688a1dc1 build: forbid using TypeScript enums using eslint
[TypeScript enums][1] are an unusual TypeScript feature, because it's
one of the only features that is "not a type-level extension of
JavaScript".

This means TypeScript generates custom code for enums, which can cause a
bunch of issues, especially as this custom code can be built differently
depending on which bundler you use, and because of this, many people
discourage the use of enums:

- [The Dangers of TypeScript Enums][2]
- [Tidy TypeScript: Prefer union types over enums][3]
- [TypeScript: Handbook - Enums # Objects vs Enums][4]

I've added an ESLint rule that forbids TypeScript enums, as in most
cases, it's better to use string literals instead, e.g. like
`type a = "a" | "b" | "c";`.

[1]: https://www.typescriptlang.org/docs/handbook/enums.html#string-enums
[2]: https://dev.to/azure/the-dangers-of-typescript-enums-55pd
[3]: https://fettblog.eu/tidy-typescript-avoid-enums/
[4]: https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums
2023-07-03 00:04:16 +01:00
Alois Klink
fbf79ffcc0 refactor: replace TypeScript enum with JS obj
[`const` assertions where added in TypeScript 3.4][1] and can be used
to create enum-like objects in plain JavaScript, that act like
TypeScript enums, but has none of the downsides of TypeScript enums.

[1]: https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#const-assertions
2023-07-02 23:56:42 +01:00
Alois Klink
b989ff5362 fix: change sankey config types to be unions
Replace the TypeScript `enum {a = "a", b = "b"}` types with
TypeScript's literal types (e.g. `"a" | "b"`).

This is because TypeScript enums are
[_not_ a type-level addition to JavaScript][1], and even the official
TypeScript docs say to be careful when using.

[1]: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums
2023-07-02 23:44:19 +01:00
Dmitry Kisler
592e9c959b fix(diagrams/c4/parser): fixes support of the macro ContainerQueue_Ext for C4 diagrams. 2023-07-02 17:10:06 +02:00
Yokozuna59
406df57f81 Merge branch 'develop' into refactor-accessibility 2023-07-02 10:24:21 +02:00
Sidharth Vinod
9c011abbd4 Merge pull request #4466 from Valentine14th/feature/1838_actor_creation_destruction
Feature/1838 actor creation destruction
2023-07-02 08:10:24 +00:00
Sidharth Vinod
dfc466514d Merge branch 'develop' into feature/1838_actor_creation_destruction 2023-07-02 13:36:04 +05:30
Sidharth Vinod
29c866b09a Don't fail CI on codecov error 2023-07-02 13:22:00 +05:30
Sidharth Vinod
2a1759aab4 Merge branch 'develop' into refactor-accessibility 2023-07-02 13:04:09 +05:30
Sidharth Vinod
28ce5e780f Merge pull request #4566 from mermaid-js/renovate/patch-all-patch
Update all patch dependencies (patch)
2023-07-02 05:12:41 +00:00
renovate[bot]
b55a9328f4 Update all patch dependencies 2023-07-02 05:07:56 +00:00
Sidharth Vinod
19325777e5 Merge branch 'develop' into feature/1838_actor_creation_destruction 2023-07-02 10:32:59 +05:30
Sidharth Vinod
f0b8e5bc37 Merge pull request #4574 from mermaid-js/sidv/renameWorkflows
Rename workflow jobs
2023-07-02 05:01:53 +00:00
Sidharth Vinod
1995f62b3c Merge branch 'develop' into sidv/renameWorkflows 2023-07-02 10:16:49 +05:30
Sidharth Vinod
78377daf2f Rename workflow jobs 2023-07-02 10:14:35 +05:30
Sidharth Vinod
4a95589b5a Add merge_group to CI triggers 2023-07-02 10:03:31 +05:30
Sidharth Vinod
812e44183b Merge pull request #4502 from nirname/feature/4492_sankey-diagrams
Sankey diagrams
2023-07-02 04:29:43 +00:00
Sidharth Vinod
afb979f32b Merge branch 'develop' into feature/4492_sankey-diagrams 2023-07-02 09:55:45 +05:30
Sidharth Vinod
4d19db8d0c Merge pull request #4573 from ibrahimWassouf/develop
Fix relative link to theme variables list
2023-07-02 09:55:29 +05:30
nirname
c327ea9f21 Update docs 2023-07-01 23:38:02 +00:00
Nikolay Rozhkov
abb7bb23d6 More detailed sankey docs 2023-07-02 02:34:22 +03:00
Nikolay Rozhkov
8ed2ee30ec Sankey alignment tests 2023-07-02 02:15:23 +03:00
Nikolay Rozhkov
084b765e9f Added tests for colors and fully setup cypress in Docker 2023-07-02 01:10:06 +03:00
Ibrahim Wassouf
4570f824f7 Fix relative link to theme variables list 2023-07-01 15:45:48 -03:00
Nikolay Rozhkov
a62719826a Docker+Cypress, better run, removed unused syntax
Added cypress container (from their official image),
may be reconsidered later to choose our own
The only minor problem is node JS version mistmatch
package.json 18.16.0
docker-compose mermaid 18.16.1
docker-compose cypress 18.16.0

Host option in cypress docker container must be removed
in favor of possible configuration option.
http://localhost:9000 are currently hard-coded, that is bad

Updated ./run script with better documentation
and added some styles too it as well

Started sankey.spec.js as an example
2023-07-01 16:17:25 +03:00
Nikolay Rozhkov
cd7fce4e4d Merge branch 'develop' into feature/4492_sankey-diagrams 2023-06-30 22:58:56 +03:00
Sidharth Vinod
ae4d81cdfd move codecov 2023-07-01 00:39:01 +05:30
Sidharth Vinod
b90c8402cb Set default branch in codecov 2023-07-01 00:38:10 +05:30
Sidharth Vinod
eb37e6886c Merge branch 'develop' into pr/Valentine14th/4466
* develop:
  Fix docs
2023-07-01 00:33:24 +05:30
Sidharth Vinod
04d79b16c3 Fix docs 2023-07-01 00:30:27 +05:30
Sidharth Vinod
1645bf0479 Merge branch 'develop' into pr/Valentine14th/4466
* develop:
  Add threshold
  Updated mermaid version to 10.2.4
  update latest news section
2023-07-01 00:29:43 +05:30
Sidharth Vinod
3fe0c8b13d Merge branch 'develop' into feature/1838_actor_creation_destruction 2023-06-30 16:00:24 +05:30
Lishid
0cab66c9d8 Fix flowchart tooltip typing
Tooltip is an object that gets reset to an array. It is then looked up for properties without guard, causing array functions like "length" and "constructor" to run into undefined behvaior.
2023-06-29 15:33:35 -04:00
Nikolay Rozhkov
163a4b819b Trigger build in GA 2023-06-29 21:01:21 +03:00
nirname
36df7260cc Update docs 2023-06-29 17:32:39 +00:00
Nikolay Rozhkov
b2f6858ff7 Prettier 2023-06-29 20:23:10 +03:00
Nikolay Rozhkov
06cb0c3be9 Fixed package json 2023-06-29 20:22:06 +03:00
Nikolay Rozhkov
9177350a39 Fixed double quotes, docs, demo and added more examples to run script 2023-06-29 20:16:25 +03:00
Nikolay Rozhkov
e24dce10a2 Added sankey documentation 2023-06-29 19:51:46 +03:00
Nikolay Rozhkov
e7ad294283 Merge branch 'develop' into feature/4492_sankey-diagrams 2023-06-29 16:50:38 +03:00
Nikolay Rozhkov
95a436595e Let it be as it was in dev branch 2023-06-29 16:44:33 +03:00
Nikolay Rozhkov
8e3f8b1a57 Fixes after review 2023-06-29 15:39:50 +03:00
Nikolay Rozhkov
408c32781e Contributors fetching failure must not hinder docs development 2023-06-29 15:24:14 +03:00
Nikolay Rozhkov
a712e61888 Loading avatars in parallel & started sankey documentation 2023-06-29 15:24:14 +03:00
Yokozuna59
b11c38ea00 run docs:build to fix linting issue 2023-06-27 21:25:55 +03:00
Yokozuna59
2b0f078c99 resolve lint issues for no-inferrable-types 2023-06-27 21:09:26 +03:00
Yokozuna59
48fc60f866 fix wrong config paramater in some cypress spec
- flowchart
- mindmap
2023-06-27 20:59:43 +03:00
Yokozuna59
a2cf41c9c0 convert cypress/helpers/util.js into ts
- add types for parameter and returned value and variables
- change the deperated `unescape` into `decodeURIComponent`
- create `CypressConfig` and `CypressMermaidConfig` and `CodeObject` types
- add default value for some parameter
2023-06-27 20:53:01 +03:00
Yokozuna59
6cbd24f704 convert file from js into ts 2023-06-27 20:50:42 +03:00
Yokozuna59
226960ef46 refactor mermaidAPI accessibilities 2023-06-27 20:07:50 +03:00
Yokozuna59
228bafa909 refactor accessibility
- remove @ts-ignore comments
- rename vitest test and describe title
- remove unnecessary types, e.i, `null` and `number`
- clean `addSVGa11yTitleDescription` and `setA11yDiagramInfo` functions
2023-06-27 20:04:41 +03:00
nirname
19bea10983 Update docs 2023-06-27 14:54:57 +00:00
Nikolay Rozhkov
8b111760b1 Updates after review 2023-06-27 17:50:51 +03:00
nirname
301073a60d Update docs 2023-06-27 13:51:44 +00:00
Nikolay Rozhkov
149cc44c39 Empty 2023-06-27 16:46:20 +03:00
Nikolay Rozhkov
e1c9aec775 Merge remote-tracking branch 'nirname/develop' into feature/4492_sankey-diagrams 2023-06-27 16:25:18 +03:00
Nikolay Rozhkov
f0231ad9b1 Lint 2023-06-27 16:22:12 +03:00
Nikolay Rozhkov
0bbf0555d3 Fix linters 2023-06-27 16:17:55 +03:00
Nikolay Rozhkov
d4d7ce5a4b Fixed majority of ts errors for sankey 2023-06-27 16:12:44 +03:00
Nikolay Rozhkov
bbba643288 Rmoved unnecessary imports in tests 2023-06-27 15:30:53 +03:00
Nikolay Rozhkov
830319e3db Removed unnecessary TODO 2023-06-27 15:21:36 +03:00
Nikolay Rozhkov
32c8524317 Put d3-sankey under mermaid package 2023-06-27 15:15:34 +03:00
Nikolay Rozhkov
616c5e6914 Move UID to separate file, refine run sh 2023-06-27 15:05:25 +03:00
Nikolay Rozhkov
605e8d4a92 Sankey refactoring 2023-06-27 14:11:06 +03:00
Nikolay Rozhkov
b0825ebb35 Import at the top 2023-06-26 18:37:41 +03:00
Nikolay Rozhkov
a38733346f Removed unnecessary configs and extra code 2023-06-25 21:56:14 +03:00
Nikolay Rozhkov
c5b89d127d Update docs 2023-06-25 01:38:31 +03:00
Nikolay Rozhkov
95ab598ea4 Fix docs 2023-06-25 01:31:53 +03:00
Nikolay Rozhkov
2a22bae1f9 Update docs 2023-06-25 01:18:38 +03:00
Nikolay Rozhkov
6a893a758b Styles are optional 2023-06-25 01:07:11 +03:00
Nikolay Rozhkov
1d6074dbfa Sankey: Use [] instead of Array 2023-06-25 00:42:12 +03:00
Nikolay Rozhkov
db2a556f62 Cleanup 2023-06-25 00:23:42 +03:00
Nikolay Rozhkov
b23e86aea3 Added options for coloring 2023-06-25 00:22:36 +03:00
Nikolay Rozhkov
1674f12b62 Renamed sankey to sankey-beta 2023-06-24 23:11:54 +03:00
Nikolay Rozhkov
2f281ba228 Improvements for sankey diagram after review 2023-06-24 22:02:18 +03:00
Nikolay Rozhkov
0a7d429192 Fixes for docker local development 2023-06-24 21:37:19 +03:00
Nikolay Rozhkov
d766ac6d20 Prettier 2023-06-22 23:50:11 +03:00
Nikolay Rozhkov
73840ead05 Decrease docker mem 2023-06-22 23:38:00 +03:00
Nikolay Rozhkov
7ace602a6c Fixed linters 2023-06-22 23:24:41 +03:00
Nikolay Rozhkov
c75c106490 Put styles back 2023-06-22 23:02:13 +03:00
Nikolay Rozhkov
d9036c7af1 Added gradient for sankey and cleaned code 2023-06-22 21:26:39 +03:00
Nikolay Rozhkov
518da3236f Remove unnecessary parsing stage from render and prepare text before parsing 2023-06-22 18:28:02 +03:00
Nikolay Rozhkov
104aece46e Cleanup sankey diagrams according code review 2023-06-22 17:35:46 +03:00
Nikolay Rozhkov
9a29066426 Ensure that sankey keyword does not intefere with csv 2023-06-22 16:53:44 +03:00
Nikolay Rozhkov
be9cd480aa Sankey syntax has beed reduced 2023-06-22 15:58:09 +03:00
Nikolay Rozhkov
272615e580 Fixed tests and added node alignment 2023-06-21 03:54:55 +03:00
Nikolay Rozhkov
bc33c8210c Merge branch 'develop' into feature/4492_sankey-diagrams 2023-06-21 03:00:27 +03:00
Nikolay Rozhkov
7bc5c1930e Fix specs 2023-06-21 02:58:25 +03:00
Nikolay Rozhkov
24d9f59d69 Fix specs 2023-06-21 02:52:21 +03:00
Nikolay Rozhkov
6c6efb24f4 Fix graph width 2023-06-21 01:58:57 +03:00
Nikolay Rozhkov
362648b74b Trim trailing spaces 2023-06-21 01:37:06 +03:00
Nikolay Rozhkov
a2c055ba5d CSV syntax implementation 2023-06-21 01:29:34 +03:00
Nikolay Rozhkov
6077ba5405 Updated syntax and fixed comments from review 2023-06-20 03:06:47 +03:00
Nikolay Rozhkov
fd3ffdc22a Prettify 2023-06-19 04:34:41 +03:00
Nikolay Rozhkov
1009bb8fb7 Prettify 2023-06-19 04:29:41 +03:00
Nikolay Rozhkov
6722ac7540 Multiple improvements on syntax
Syntax has been simplified
Removed extra initial states
Removed unused groups
Nodes can be wrapped in double qotes
Updated demo page
2023-06-19 04:02:40 +03:00
Nikolay Rozhkov
726efdad53 Fixed packaged 2023-06-19 01:09:21 +03:00
Nikolay Rozhkov
9dbb9872bc Fix linters 2023-06-19 01:05:33 +03:00
Nikolay Rozhkov
19f858b73b Fixed nodes duplicates 2023-06-19 01:05:33 +03:00
Nikolay Rozhkov
d22131e2fb It can read syntax and draw diagram 2023-06-19 01:05:33 +03:00
Nikolay Rozhkov
f5add81e29 Simple flow is done 2023-06-19 01:05:33 +03:00
Nikolay Rozhkov
c41fc67254 Added nodes and paths 2023-06-19 01:05:33 +03:00
Nikolay Rozhkov
81542142f5 Fix errors 2023-06-19 01:05:33 +03:00
Nikolay Rozhkov
afaf87e414 At last something is working 2023-06-19 01:05:20 +03:00
Nikolay Rozhkov
1782f69c8f Increased mem for lint, fixed spell checking, run lint 2023-06-19 01:05:20 +03:00
Nikolay Rozhkov
40f7105ae4 Started renderer development 2023-06-19 01:05:20 +03:00
Nikolay Rozhkov
5eae790740 Sankey stream is ending on node only 2023-06-19 01:05:20 +03:00
Nikolay Rozhkov
f71769e07b Attributes within strings 2023-06-19 01:05:09 +03:00
Nikolay Rozhkov
b4b535f997 Recognizing attributes 2023-06-19 01:05:09 +03:00
Nikolay Rozhkov
d2226604e4 Recognizing attrubutes 2023-06-19 01:05:09 +03:00
Nikolay Rozhkov
567686e140 Implementing new syntax 2023-06-19 01:05:09 +03:00
Nikolay Rozhkov
ad95c99cc2 Started sankey syntax 2023-06-19 01:04:45 +03:00
Nikolay Rozhkov
c874d74faf Some fixes to docker and demos 2023-06-19 01:02:50 +03:00
Nikolay Rozhkov
fe3dd5a531 Updated dockerfile 2023-06-19 01:02:50 +03:00
Nikolay Rozhkov
8e001b92f2 Cleared sankey renderer 2023-06-19 01:02:50 +03:00
Nikolay Rozhkov
6b40b394c8 Picked state diagram as a sample for sankey 2023-06-19 01:02:50 +03:00
Nikolay Rozhkov
c2417de5f1 Stated sankey backbone 2023-06-19 01:02:50 +03:00
Nikolay Rozhkov
116453d2a7 Desired syntax sankey 2023-06-19 01:02:49 +03:00
Nikolay Rozhkov
7f19e50403 Desired sankey syntax 2023-06-19 01:02:49 +03:00
Nikolay Rozhkov
4018fad416 Ideas about sankey diagram syntax 2023-06-19 01:02:49 +03:00
Pierrick Wauquier
9efd9e8a45 defer a bit for electron to catch up 2023-06-16 18:01:52 +02:00
Pierrick Wauquier
270586095f fix typo in test description 2023-06-16 16:37:34 +02:00
Pierrick Wauquier
aa1b998fbf always resolve in the end 2023-06-16 16:32:57 +02:00
Pierrick Wauquier
8b6485035e add failing test 2023-06-16 16:32:11 +02:00
Sidharth Vinod
445da58b51 Merge branch 'develop' into sidv/splitUnicode
* develop:
  Disable coveralls
2023-06-13 12:50:52 +05:30
Sidharth Vinod
25a85eef69 Merge branch 'develop' into sidv/splitUnicode
* develop:
  Update coveralls
  Ignore bundlephobia
  Run docs:build
  Correct timeline spelling
2023-06-13 11:50:08 +05:30
Sidharth Vinod
b36a0177db Use joiner to split unicode 2023-06-13 11:42:39 +05:30
Sidharth Vinod
dd4e14690d Add types 2023-06-13 11:26:25 +05:30
Sidharth Vinod
5903792207 rename handle-markdown-text 2023-06-13 10:34:24 +05:30
Sidharth Vinod
c85e479f88 Merge branch 'develop' into sidv/splitUnicode
* develop:
  Update docs
  Rename info to note
  Rename "info" to "note"
  Update all patch dependencies
  Fix Directives Documentation
  Update tutorial link
  Run build
  Fix link to Tutorials from n00b-overview page
  UPdated version to 10.2.3
  Remove old changelog
  Remove old changelog
  Setting version to 10.2.2
  #4446 Improved regular expression
  #4446 Updating the cleanup criteria
  #4438 Reverted to the changes from #4285
  Fix download
  Fix compile error in docs.
  Fix Contributor link in homepage
  Update docs
  Add hint on "flowchart" and "graph" (and some more styling)
2023-06-12 14:58:58 +05:30
Sidharth Vinod
a379cd02e7 Add logs 2023-06-12 14:57:56 +05:30
Sidharth Vinod
b3ce56c7fc Cleanup 2023-06-09 17:03:02 +05:30
Sidharth Vinod
3f080e5bc8 Merge branch 'sidv/splitUnicode' of https://github.com/mermaid-js/mermaid into sidv/splitUnicode
* 'sidv/splitUnicode' of https://github.com/mermaid-js/mermaid:
  Update docs
2023-06-09 16:57:27 +05:30
Sidharth Vinod
7b4601762a Use splitLineToFitWidth function 2023-06-09 16:57:13 +05:30
sidharthv96
d4edd98b8a Update docs 2023-06-09 11:24:11 +00:00
Sidharth Vinod
0a437f5800 feat: split unicode properly 2023-06-09 16:48:30 +05:30
Sidharth Vinod
c41df420d7 Add splitText 2023-06-09 11:06:45 +05:30
Laura Valentine Tscharner
b79f9bdced docs(sequence): actor creation and destruction #1838 2023-06-08 17:44:36 +01:00
Laura Valentine Tscharner
d06bb05c5f feat(sequence): actor creation and destruction #1838 2023-06-08 17:17:31 +01:00
Garen J. Torikian
dfb15901f4 Make the doc change in the right place
This is due to the sloppy fact that there are two copies of every doc
page in the repo.
2023-05-15 09:26:49 -04:00
Garen Torikian
c9da36dc8b Fix a typo 2023-05-14 14:27:08 -04:00
172 changed files with 8856 additions and 3797 deletions

View File

@@ -38,6 +38,10 @@ module.exports = {
'lodash',
'unicorn',
],
ignorePatterns: [
// this file is automatically generated by `pnpm run --filter mermaid types:build-config`
'packages/mermaid/src/config.type.ts',
],
rules: {
curly: 'error',
'no-console': 'error',
@@ -123,6 +127,14 @@ module.exports = {
files: ['*.{ts,tsx}'],
plugins: ['tsdoc'],
rules: {
'no-restricted-syntax': [
'error',
{
selector: 'TSEnumDeclaration',
message:
'Prefer using TypeScript union types over TypeScript enum, since TypeScript enums have a bunch of issues, see https://dev.to/dvddpl/whats-the-problem-with-typescript-enums-2okj',
},
],
'tsdoc/syntax': 'error',
},
},

View File

@@ -1,3 +1,6 @@
codecov:
branch: develop
comment:
layout: 'reach, diff, flags, files'
behavior: default
@@ -8,5 +11,7 @@ comment:
coverage:
status:
project:
default:
threshold: 1%
off
# Turing off for now as code coverage isn't stable and causes unnecessary build failures.
# default:
# threshold: 2%

View File

@@ -1,3 +1,4 @@
'Type: Bug / Error': 'bug/*'
'Type: Enhancement': 'feature/*'
'Type: Other': 'other/*'
'Type: Bug / Error': ['bug/*', fix/*]
'Type: Enhancement': ['feature/*', 'feat/*']
'Type: Other': ['other/*', 'chore/*', 'test/*', 'refactor/*']
'Area: Documentation': ['docs/*']

View File

@@ -13,6 +13,6 @@ Describe the way your implementation works or what design decisions you made if
Make sure you
- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md)
- [ ] :computer: have added unit/e2e tests (if appropriate)
- [ ] :notebook: have added documentation (if appropriate)
- [ ] :computer: have added necessary unit/e2e tests.
- [ ] :notebook: have added documentation. Make sure [`MERMAID_RELEASE_VERSION`](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/docs/community/development.md#3-update-documentation) is used for all new features.
- [ ] :bookmark: targeted `develop` branch

View File

@@ -1,14 +1,18 @@
name: Build Vitepress docs
on:
push:
branches:
- master
- release/*
pull_request:
merge_group:
permissions:
contents: read
jobs:
# Build job
build:
build-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
@@ -25,5 +29,9 @@ jobs:
- name: Install Packages
run: pnpm install --frozen-lockfile
- name: Verify release verion
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/release')) }}
run: pnpm --filter mermaid run docs:verify-version
- name: Run Build
run: pnpm --filter mermaid run docs:build:vitepress

View File

@@ -2,6 +2,7 @@ name: Build
on:
push: {}
merge_group:
pull_request:
types:
- opened
@@ -12,7 +13,7 @@ permissions:
contents: read
jobs:
build:
build-mermaid:
runs-on: ubuntu-latest
strategy:
matrix:

View File

@@ -14,7 +14,7 @@ permissions:
contents: read
jobs:
check:
check-readme:
runs-on: ubuntu-latest
steps:
- name: Checkout repository

View File

@@ -1,15 +1,16 @@
on:
push: {}
push:
merge_group:
pull_request:
types:
- opened
- synchronize
- ready_for_review
name: Static analysis
name: Static analysis on Test files
jobs:
test:
check-tests:
runs-on: ubuntu-latest
name: check tests
if: github.repository_owner == 'mermaid-js'

View File

@@ -19,7 +19,7 @@ env:
USE_APPLI: ${{ secrets.APPLITOOLS_API_KEY && 'true' || '' }}
jobs:
test:
e2e-applitools:
runs-on: ubuntu-latest
strategy:
matrix:

View File

@@ -1,12 +1,15 @@
name: E2E
on: [push, pull_request]
on:
push:
pull_request:
merge_group:
permissions:
contents: read
jobs:
build:
e2e:
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -42,15 +45,18 @@ jobs:
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
VITEST_COVERAGE: true
CYPRESS_COMMIT: ${{ github.sha }}
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v3
if: steps.cypress.conclusion == 'success'
# Run step only pushes to develop and pull_requests
if: ${{ steps.cypress.conclusion == 'success' && (github.event_name == 'pull_request' || github.ref == 'refs/heads/develop')}}
with:
files: coverage/cypress/lcov.info
flags: e2e
name: mermaid-codecov
fail_ci_if_error: true
fail_ci_if_error: false
verbose: true
token: 6845cc80-77ee-4e17-85a1-026cd95e0766
- name: Upload Artifacts
uses: actions/upload-artifact@v3
if: ${{ failure() && steps.cypress.conclusion == 'failure' }}

View File

@@ -1,7 +1,8 @@
name: Lint
on:
push: {}
push:
merge_group:
pull_request:
types:
- opened
@@ -52,6 +53,19 @@ jobs:
exit 1
fi
- name: Verify `./src/config.type.ts` is in sync with `./src/schemas/config.schema.yaml`
shell: bash
run: |
if ! pnpm run --filter mermaid types:verify-config; then
ERROR_MESSAGE='Running `pnpm run --filter mermaid types:verify-config` failed.'
ERROR_MESSAGE+=' This should be fixed by running'
ERROR_MESSAGE+=' `pnpm run --filter mermaid types:build-config`'
ERROR_MESSAGE+=' on your local machine.'
echo "::error title=Lint failure::${ERROR_MESSAGE}"
# make sure to return an error exitcode so that GitHub actions shows a red-cross
exit 1
fi
- name: Verify Docs
id: verifyDocs
working-directory: ./packages/mermaid

View File

@@ -1,11 +1,15 @@
name: Validate PR Labeler Configuration
on:
push: {}
push:
paths:
- .github/workflows/pr-labeler-config-validator.yml
- .github/workflows/pr-labeler.yml
- .github/pr-labeler.yml
pull_request:
types:
- opened
- synchronize
- ready_for_review
paths:
- .github/workflows/pr-labeler-config-validator.yml
- .github/workflows/pr-labeler.yml
- .github/pr-labeler.yml
jobs:
pr-labeler:

View File

@@ -19,7 +19,7 @@ concurrency:
jobs:
# Build job
build:
build-docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
@@ -48,11 +48,11 @@ jobs:
path: packages/mermaid/src/vitepress/.vitepress/dist
# Deployment job
deploy:
deploy-docs:
environment:
name: github-pages
runs-on: ubuntu-latest
needs: build
needs: build-docs
steps:
- name: Deploy to GitHub Pages
id: deployment

View File

@@ -6,7 +6,7 @@ on:
- 'release/**'
jobs:
publish:
publish-preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

View File

@@ -1,12 +1,12 @@
name: Unit Tests
on: [push, pull_request]
on: [push, pull_request, merge_group]
permissions:
contents: read
jobs:
build:
unit-test:
runs-on: ubuntu-latest
strategy:
matrix:
@@ -43,15 +43,12 @@ jobs:
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v3
# Run step only pushes to develop and pull_requests
if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop' }}
with:
files: ./coverage/vitest/lcov.info
flags: unit
name: mermaid-codecov
fail_ci_if_error: true
fail_ci_if_error: false
verbose: true
# Coveralls is throwing 500. Disabled for now.
# - name: Upload Coverage to Coveralls
# uses: coverallsapp/github-action@v2
# with:
# github-token: ${{ secrets.GITHUB_TOKEN }}
# flag-name: unit
token: 6845cc80-77ee-4e17-85a1-026cd95e0766

View File

@@ -5,7 +5,7 @@ on:
workflow_dispatch:
jobs:
build:
update-browser-list:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

View File

@@ -5,5 +5,8 @@ coverage
# Autogenerated by PNPM
pnpm-lock.yaml
stats
packages/mermaid/src/docs/.vitepress/components.d.ts
**/.vitepress/components.d.ts
**/.vitepress/cache
.nyc_output
# Autogenerated by `pnpm run --filter mermaid types:build-config`
packages/mermaid/src/config.type.ts

View File

@@ -2,6 +2,7 @@ import { build, InlineConfig, type PluginOption } from 'vite';
import { resolve } from 'path';
import { fileURLToPath } from 'url';
import jisonPlugin from './jisonPlugin.js';
import jsonSchemaPlugin from './jsonSchemaPlugin.js';
import { readFileSync } from 'fs';
import typescript from '@rollup/plugin-typescript';
import { visualizer } from 'rollup-plugin-visualizer';
@@ -121,6 +122,7 @@ export const getBuildConfig = ({ minify, core, watch, entryName }: BuildOptions)
},
plugins: [
jisonPlugin(),
jsonSchemaPlugin(), // handles `.schema.yaml` files
// @ts-expect-error According to the type definitions, rollup plugins are incompatible with vite
typescript({ compilerOptions: { declaration: false } }),
istanbul({

150
.vite/jsonSchemaPlugin.ts Normal file
View File

@@ -0,0 +1,150 @@
import { load, JSON_SCHEMA } from 'js-yaml';
import assert from 'node:assert';
import Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
import { PluginOption } from 'vite';
import type { MermaidConfig, BaseDiagramConfig } from '../packages/mermaid/src/config.type.js';
/**
* All of the keys in the mermaid config that have a mermaid diagram config.
*/
const MERMAID_CONFIG_DIAGRAM_KEYS = [
'flowchart',
'sequence',
'gantt',
'journey',
'class',
'state',
'er',
'pie',
'quadrantChart',
'requirement',
'mindmap',
'timeline',
'gitGraph',
'c4',
'sankey',
] as const;
/**
* Generate default values from the JSON Schema.
*
* AJV does not support nested default values yet (or default values with $ref),
* so we need to manually find them (this may be fixed in ajv v9).
*
* @param mermaidConfigSchema - The Mermaid JSON Schema to use.
* @returns The default mermaid config object.
*/
function generateDefaults(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
const ajv = new Ajv2019({
useDefaults: true,
allowUnionTypes: true,
strict: true,
});
ajv.addKeyword({
keyword: 'meta:enum', // used by jsonschema2md
errors: false,
});
ajv.addKeyword({
keyword: 'tsType', // used by json-schema-to-typescript
errors: false,
});
// ajv currently doesn't support nested default values, see https://github.com/ajv-validator/ajv/issues/1718
// (may be fixed in v9) so we need to manually use sub-schemas
const mermaidDefaultConfig = {};
assert.ok(mermaidConfigSchema.$defs);
const baseDiagramConfig = mermaidConfigSchema.$defs.BaseDiagramConfig;
for (const key of MERMAID_CONFIG_DIAGRAM_KEYS) {
const subSchemaRef = mermaidConfigSchema.properties[key].$ref;
const [root, defs, defName] = subSchemaRef.split('/');
assert.strictEqual(root, '#');
assert.strictEqual(defs, '$defs');
const subSchema = {
$schema: mermaidConfigSchema.$schema,
$defs: mermaidConfigSchema.$defs,
...mermaidConfigSchema.$defs[defName],
} as JSONSchemaType<BaseDiagramConfig>;
const validate = ajv.compile(subSchema);
mermaidDefaultConfig[key] = {};
for (const required of subSchema.required ?? []) {
if (subSchema.properties[required] === undefined && baseDiagramConfig.properties[required]) {
mermaidDefaultConfig[key][required] = baseDiagramConfig.properties[required].default;
}
}
if (!validate(mermaidDefaultConfig[key])) {
throw new Error(
`schema for subconfig ${key} does not have valid defaults! Errors were ${JSON.stringify(
validate.errors,
undefined,
2
)}`
);
}
}
const validate = ajv.compile(mermaidConfigSchema);
if (!validate(mermaidDefaultConfig)) {
throw new Error(
`Mermaid config JSON Schema does not have valid defaults! Errors were ${JSON.stringify(
validate.errors,
undefined,
2
)}`
);
}
return mermaidDefaultConfig;
}
/**
* Vite plugin that handles JSON Schemas saved as a `.schema.yaml` file.
*
* Use `my-example.schema.yaml?only-defaults=true` to only load the default values.
*/
export default function jsonSchemaPlugin(): PluginOption {
return {
name: 'json-schema-plugin',
transform(src: string, id: string) {
const idAsUrl = new URL(id, 'file:///');
if (!idAsUrl.pathname.endsWith('schema.yaml')) {
return;
}
if (idAsUrl.searchParams.get('only-defaults')) {
const jsonSchema = load(src, {
filename: idAsUrl.pathname,
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
schema: JSON_SCHEMA,
}) as JSONSchemaType<MermaidConfig>;
return {
code: `export default ${JSON.stringify(generateDefaults(jsonSchema), undefined, 2)};`,
map: null, // no source map
};
} else {
return {
code: `export default ${JSON.stringify(
load(src, {
filename: idAsUrl.pathname,
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
schema: JSON_SCHEMA,
}),
undefined,
2
)};`,
map: null, // provide source map if available
};
}
},
};
}

2
.vscode/launch.json vendored
View File

@@ -17,7 +17,7 @@
"name": "Docs generation",
"type": "node",
"request": "launch",
"args": ["src/docs.mts"],
"args": ["scripts/docs.cli.mts"],
"runtimeArgs": ["--loader", "ts-node/esm"],
"cwd": "${workspaceRoot}/packages/mermaid",
"skipFiles": ["<node_internals>/**", "**/node_modules/**"],

View File

@@ -0,0 +1,13 @@
/**
* Mocked Sankey diagram renderer
*/
import { vi } from 'vitest';
export const draw = vi.fn().mockImplementation(() => {
return '';
});
export default {
draw,
};

View File

@@ -89,6 +89,8 @@
"mult",
"neurodiverse",
"nextra",
"nikolay",
"nirname",
"orlandoni",
"pathe",
"pbrolin",
@@ -102,10 +104,13 @@
"ranksep",
"rect",
"rects",
"reda",
"redmine",
"rehype",
"roledescription",
"rozhkov",
"sandboxed",
"sankey",
"setupgraphviewbox",
"shiki",
"sidharth",
@@ -120,6 +125,7 @@
"stylis",
"subhash-halder",
"substate",
"sulais",
"sveidqvist",
"swimm",
"techn",
@@ -130,6 +136,7 @@
"tsdoc",
"tuleap",
"tylerlong",
"typora",
"ugge",
"unist",
"unocss",
@@ -143,6 +150,7 @@
"vueuse",
"xlink",
"yash",
"yokozuna",
"zenuml"
],
"patterns": [

View File

@@ -1,93 +0,0 @@
const utf8ToB64 = (str) => {
return window.btoa(unescape(encodeURIComponent(str)));
};
const batchId = 'mermaid-batch' + new Date().getTime();
export const mermaidUrl = (graphStr, options, api) => {
const obj = {
code: graphStr,
mermaid: options,
};
const objStr = JSON.stringify(obj);
let url = 'http://localhost:9000/e2e.html?graph=' + utf8ToB64(objStr);
if (api) {
url = 'http://localhost:9000/xss.html?graph=' + graphStr;
}
if (options.listUrl) {
cy.log(options.listId, ' ', url);
}
return url;
};
export const imgSnapshotTest = (graphStr, _options = {}, api = false, validation = undefined) => {
cy.log(_options);
const options = Object.assign(_options);
if (!options.fontFamily) {
options.fontFamily = 'courier';
}
if (!options.sequence) {
options.sequence = {};
}
if (!options.sequence || (options.sequence && !options.sequence.actorFontFamily)) {
options.sequence.actorFontFamily = 'courier';
}
if (options.sequence && !options.sequence.noteFontFamily) {
options.sequence.noteFontFamily = 'courier';
}
options.sequence.actorFontFamily = 'courier';
options.sequence.noteFontFamily = 'courier';
options.sequence.messageFontFamily = 'courier';
if (options.sequence && !options.sequence.actorFontFamily) {
options.sequence.actorFontFamily = 'courier';
}
if (!options.fontSize) {
options.fontSize = '16px';
}
const url = mermaidUrl(graphStr, options, api);
openURLAndVerifyRendering(url, options, validation);
};
export const urlSnapshotTest = (url, _options, api = false, validation) => {
const options = Object.assign(_options);
openURLAndVerifyRendering(url, options, validation);
};
export const renderGraph = (graphStr, options, api) => {
const url = mermaidUrl(graphStr, options, api);
openURLAndVerifyRendering(url, options);
};
export const openURLAndVerifyRendering = (url, options, validation = undefined) => {
const useAppli = Cypress.env('useAppli');
const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
if (useAppli) {
cy.log('Opening eyes ' + Cypress.spec.name + ' --- ' + name);
cy.eyesOpen({
appName: 'Mermaid',
testName: name,
batchName: Cypress.spec.name,
batchId: batchId + Cypress.spec.name,
});
}
cy.visit(url);
cy.window().should('have.property', 'rendered', true);
cy.get('svg').should('be.visible');
if (validation) {
cy.get('svg').should(validation);
}
if (useAppli) {
cy.log('Check eyes' + Cypress.spec.name);
cy.eyesCheckWindow('Click!');
cy.log('Closing eyes' + Cypress.spec.name);
cy.eyesClose();
} else {
cy.matchImageSnapshot(name);
}
};

132
cypress/helpers/util.ts Normal file
View File

@@ -0,0 +1,132 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Buffer } from 'buffer';
import type { MermaidConfig } from '../../packages/mermaid/src/config.type.js';
interface CypressConfig {
listUrl?: boolean;
listId?: string;
name?: string;
}
type CypressMermaidConfig = MermaidConfig & CypressConfig;
interface CodeObject {
code: string;
mermaid: CypressMermaidConfig;
}
const utf8ToB64 = (str: string): string => {
return Buffer.from(decodeURIComponent(encodeURIComponent(str))).toString('base64');
};
const batchId: string = 'mermaid-batch-' + Cypress.env('CYPRESS_COMMIT') || Date.now().toString();
export const mermaidUrl = (
graphStr: string,
options: CypressMermaidConfig,
api: boolean
): string => {
const codeObject: CodeObject = {
code: graphStr,
mermaid: options,
};
const objStr: string = JSON.stringify(codeObject);
let url = `http://localhost:9000/e2e.html?graph=${utf8ToB64(objStr)}`;
if (api) {
url = `http://localhost:9000/xss.html?graph=${graphStr}`;
}
if (options.listUrl) {
cy.log(options.listId, ' ', url);
}
return url;
};
export const imgSnapshotTest = (
graphStr: string,
_options: CypressMermaidConfig = {},
api = false,
validation?: any
): void => {
cy.log(JSON.stringify(_options));
const options: CypressMermaidConfig = Object.assign(_options);
if (!options.fontFamily) {
options.fontFamily = 'courier';
}
if (!options.sequence) {
options.sequence = {};
}
if (!options.sequence || (options.sequence && !options.sequence.actorFontFamily)) {
options.sequence.actorFontFamily = 'courier';
}
if (options.sequence && !options.sequence.noteFontFamily) {
options.sequence.noteFontFamily = 'courier';
}
options.sequence.actorFontFamily = 'courier';
options.sequence.noteFontFamily = 'courier';
options.sequence.messageFontFamily = 'courier';
if (options.sequence && !options.sequence.actorFontFamily) {
options.sequence.actorFontFamily = 'courier';
}
if (!options.fontSize) {
options.fontSize = 16;
}
const url: string = mermaidUrl(graphStr, options, api);
openURLAndVerifyRendering(url, options, validation);
};
export const urlSnapshotTest = (
url: string,
_options: CypressMermaidConfig,
_api = false,
validation?: any
): void => {
const options: CypressMermaidConfig = Object.assign(_options);
openURLAndVerifyRendering(url, options, validation);
};
export const renderGraph = (
graphStr: string,
options: CypressMermaidConfig = {},
api = false
): void => {
const url: string = mermaidUrl(graphStr, options, api);
openURLAndVerifyRendering(url, options);
};
export const openURLAndVerifyRendering = (
url: string,
options: CypressMermaidConfig,
validation?: any
): void => {
const useAppli: boolean = Cypress.env('useAppli');
const name: string = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
if (useAppli) {
cy.log(`Opening eyes ${Cypress.spec.name} --- ${name}`);
cy.eyesOpen({
appName: 'Mermaid',
testName: name,
batchName: Cypress.spec.name,
batchId: batchId + Cypress.spec.name,
});
}
cy.visit(url);
cy.window().should('have.property', 'rendered', true);
cy.get('svg').should('be.visible');
if (validation) {
cy.get('svg').should(validation);
}
if (useAppli) {
cy.log(`Check eyes ${Cypress.spec.name}`);
cy.eyesCheckWindow('Click!');
cy.log(`Closing eyes ${Cypress.spec.name}`);
cy.eyesClose();
} else {
cy.matchImageSnapshot(name);
}
};

View File

@@ -1,4 +1,4 @@
import { renderGraph } from '../../helpers/util.js';
import { renderGraph } from '../../helpers/util.ts';
describe('Configuration', () => {
describe('arrowMarkerAbsolute', () => {
it('should handle default value false of arrowMarkerAbsolute', () => {

View File

@@ -1,4 +1,4 @@
import { urlSnapshotTest } from '../../helpers/util.js';
import { urlSnapshotTest } from '../../helpers/util.ts';
describe('mermaid', () => {
describe('registerDiagram', () => {

View File

@@ -1,4 +1,4 @@
import { urlSnapshotTest, openURLAndVerifyRendering } from '../../helpers/util.js';
import { urlSnapshotTest, openURLAndVerifyRendering } from '../../helpers/util.ts';
describe('CSS injections', () => {
it('should not allow CSS injections outside of the diagram', () => {

View File

@@ -1,4 +1,4 @@
import { mermaidUrl } from '../../helpers/util.js';
import { mermaidUrl } from '../../helpers/util.ts';
describe('XSS', () => {
it('should handle xss in tags', () => {
const str =

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Git Graph diagram', () => {
it('1: should render a simple gitgraph with commit on main branch', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('C4 diagram', () => {
it('should render a simple C4Context diagram', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Class diagram V2', () => {
it('0: should render a simple class diagram', () => {
imgSnapshotTest(

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Class diagram', () => {
it('1: should render a simple class diagram', () => {
@@ -423,4 +423,82 @@ describe('Class diagram', () => {
);
cy.get('svg');
});
it('should render class diagram with newlines in title', () => {
imgSnapshotTest(`
classDiagram
Animal <|-- \`Du\nck\`
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class \`Du\nck\` {
+String beakColor
+String featherColor
+swim()
+quack()
}
`);
cy.get('svg');
});
it('should render class diagram with many newlines in title', () => {
imgSnapshotTest(`
classDiagram
class \`This\nTitle\nHas\nMany\nNewlines\` {
+String Also
-Stirng Many
#int Members
+And()
-Many()
#Methods()
}
`);
});
it('should render with newlines in title and an annotation', () => {
imgSnapshotTest(`
classDiagram
class \`This\nTitle\nHas\nMany\nNewlines\` {
+String Also
-Stirng Many
#int Members
+And()
-Many()
#Methods()
}
&lt;&lt;Interface&gt;&gt; \`This\nTitle\nHas\nMany\nNewlines\`
`);
});
it('should handle newline title in namespace', () => {
imgSnapshotTest(`
classDiagram
namespace testingNamespace {
class \`This\nTitle\nHas\nMany\nNewlines\` {
+String Also
-Stirng Many
#int Members
+And()
-Many()
#Methods()
}
}
`);
});
it('should handle newline in string label', () => {
imgSnapshotTest(`
classDiagram
class A["This has\na newline!"] {
+String boop
-Int beep
#double bop
}
class B["This title also has\na newline"]
B : +with(more)
B : -methods()
`);
});
});

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Configuration and directives - nodes should be light blue', () => {
it('No config - use default', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Current diagram', () => {
it('should render a state with states in it', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Flowchart', () => {
it('34: testing the label width in percy', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Entity Relationship Diagram', () => {
it('should render a simple ER diagram', () => {
@@ -200,6 +200,27 @@ describe('Entity Relationship Diagram', () => {
);
});
it('should render entities with attributes that begin with asterisk', () => {
imgSnapshotTest(
`
erDiagram
BOOK {
int *id
string name
varchar(99) summary
}
BOOK }o..o{ STORE : soldBy
STORE {
int *id
string name
varchar(50) address
}
`,
{ loglevel: 1 }
);
cy.get('svg');
});
it('should render entities with keys', () => {
renderGraph(
`

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe.skip('Flowchart ELK', () => {
it('1-elk: should render a simple flowchart', () => {
@@ -681,7 +681,7 @@ title: Simple flowchart
flowchart-elk TD
A --> B
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('elk: should include classes on the edges', () => {
@@ -710,7 +710,7 @@ flowchart-elk LR
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
classDef someclass fill:#f96
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('With formatting in a node', () => {
@@ -726,7 +726,7 @@ flowchart-elk LR
b --> d(The dog in the hog)
c --> d
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('New line in node and formatted edge label', () => {
@@ -736,7 +736,7 @@ flowchart-elk LR
b("\`The dog in **the** hog.(1)
NL\`") --"\`1o **bold**\`"--> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Wrapping long text with a new line', () => {
@@ -749,7 +749,7 @@ Word!
Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. \`) --> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Sub graphs and markdown strings', () => {
@@ -766,7 +766,7 @@ subgraph "\`**Two**\`"
end
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
});
@@ -782,7 +782,7 @@ flowchart-elk LR
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
classDef someclass fill:#f96
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('With formatting in a node', () => {
@@ -798,7 +798,7 @@ flowchart-elk LR
b --> d(The dog in the hog)
c --> d
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('New line in node and formatted edge label', () => {
@@ -808,7 +808,7 @@ flowchart-elk LR
b("\`The dog in **the** hog.(1)
NL\`") --"\`1o **bold**\`"--> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Wrapping long text with a new line', () => {
@@ -821,7 +821,7 @@ Word!
Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. \`") --> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Sub graphs and markdown strings', () => {
@@ -838,7 +838,7 @@ subgraph "\`**Two**\`"
end
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
});

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Flowchart v2', () => {
it('1: should render a simple flowchart', () => {
@@ -671,7 +671,7 @@ title: Simple flowchart
flowchart TD
A --> B
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 10 } }
);
});
it('3192: It should be possieble to render flowcharts with invisible edges', () => {
@@ -682,7 +682,7 @@ title: Simple flowchart with invisible edges
flowchart TD
A ~~~ B
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 10 } }
);
});
it('4023: Should render html labels with images and-or text correctly', () => {
@@ -695,6 +695,15 @@ A ~~~ B
{}
);
});
it('4439: Should render the graph even if some images are missing', () => {
imgSnapshotTest(
`flowchart TD
B[<img>]
B-->C[<img>]`,
{}
);
});
describe('Markdown strings flowchart (#4220)', () => {
describe('html labels', () => {
it('With styling and classes', () => {
@@ -707,7 +716,7 @@ flowchart LR
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
classDef someclass fill:#f96
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('With formatting in a node', () => {
@@ -723,7 +732,7 @@ flowchart LR
b --> d(The dog in the hog)
c --> d
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('New line in node and formatted edge label', () => {
@@ -733,7 +742,7 @@ flowchart LR
b("\`The dog in **the** hog.(1)
NL\`") --"\`1o **bold**\`"--> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Wrapping long text with a new line', () => {
@@ -746,7 +755,7 @@ Word!
Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. \`") --> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Sub graphs and markdown strings', () => {
@@ -763,7 +772,7 @@ subgraph "\`**Two**\`"
end
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
});
@@ -779,7 +788,7 @@ flowchart LR
style id2 fill:#bbf,stroke:#f66,stroke-width:2px,color:#fff,stroke-dasharray: 5 5
classDef someclass fill:#f96
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('With formatting in a node', () => {
@@ -795,7 +804,7 @@ flowchart LR
b --> d(The dog in the hog)
c --> d
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('New line in node and formatted edge label', () => {
@@ -805,7 +814,7 @@ flowchart LR
b("\`The dog in **the** hog.(1)
NL\`") --"\`1o **bold**\`"--> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Wrapping long text with a new line', () => {
@@ -818,7 +827,7 @@ Word!
Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. Another line with many, many words. \`") --> c
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
it('Sub graphs and markdown strings', () => {
@@ -835,7 +844,7 @@ subgraph "\`**Two**\`"
end
`,
{ titleTopMargin: 0 }
{ flowchart: { titleTopMargin: 0 } }
);
});
});

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Graph', () => {
it('1: should render a simple flowchart no htmlLabels', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Gantt diagram', () => {
beforeEach(() => {
@@ -414,6 +414,28 @@ describe('Gantt diagram', () => {
);
});
it('should render a gantt diagram with tick is 1 week, with the day starting on monday', () => {
imgSnapshotTest(
`
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
axisFormat %m-%d
tickInterval 1week
weekday monday
excludes weekends
section Section
A task : a1, 2022-10-01, 30d
Another task : after a1, 20d
section Another
Task in sec : 2022-10-20, 12d
another task : 24d
`,
{}
);
});
it('should render a gantt diagram with tick is 1 month', () => {
imgSnapshotTest(
`

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Git Graph diagram', () => {
it('1: should render a simple gitgraph with commit on main branch', () => {
@@ -333,4 +333,372 @@ gitGraph
{}
);
});
it('15: should render a simple gitgraph with commit on main branch | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "1"
commit id: "2"
commit id: "3"
`,
{}
);
});
it('16: should render a simple gitgraph with commit on main branch with Id | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "One"
commit id: "Two"
commit id: "Three"
`,
{}
);
});
it('17: should render a simple gitgraph with different commitTypes on main branch | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "Normal Commit"
commit id: "Reverse Commit" type: REVERSE
commit id: "Hightlight Commit" type: HIGHLIGHT
`,
{}
);
});
it('18: should render a simple gitgraph with tags commitTypes on main branch | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "Normal Commit with tag" tag: "v1.0.0"
commit id: "Reverse Commit with tag" type: REVERSE tag: "RC_1"
commit id: "Hightlight Commit" type: HIGHLIGHT tag: "8.8.4"
`,
{}
);
});
it('19: should render a simple gitgraph with two branches | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "1"
commit id: "2"
branch develop
checkout develop
commit id: "3"
commit id: "4"
checkout main
commit id: "5"
commit id: "6"
`,
{}
);
});
it('20: should render a simple gitgraph with two branches and merge commit | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "1"
commit id: "2"
branch develop
checkout develop
commit id: "3"
commit id: "4"
checkout main
merge develop
commit id: "5"
commit id: "6"
`,
{}
);
});
it('21: should render a simple gitgraph with three branches and tagged merge commit | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "1"
commit id: "2"
branch nice_feature
checkout nice_feature
commit id: "3"
checkout main
commit id: "4"
checkout nice_feature
branch very_nice_feature
checkout very_nice_feature
commit id: "5"
checkout main
commit id: "6"
checkout nice_feature
commit id: "7"
checkout main
merge nice_feature id: "12345" tag: "my merge commit"
checkout very_nice_feature
commit id: "8"
checkout main
commit id: "9"
`,
{}
);
});
it('22: should render a simple gitgraph with more than 8 branchs & overriding variables | Vertical Branch', () => {
imgSnapshotTest(
`%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
'gitBranchLabel0': '#ffffff',
'gitBranchLabel1': '#ffffff',
'gitBranchLabel2': '#ffffff',
'gitBranchLabel3': '#ffffff',
'gitBranchLabel4': '#ffffff',
'gitBranchLabel5': '#ffffff',
'gitBranchLabel6': '#ffffff',
'gitBranchLabel7': '#ffffff',
} } }%%
gitGraph TB:
checkout main
branch branch1
branch branch2
branch branch3
branch branch4
branch branch5
branch branch6
branch branch7
branch branch8
branch branch9
checkout branch1
commit id: "1"
`,
{}
);
});
it('23: should render a simple gitgraph with rotated labels | Vertical Branch', () => {
imgSnapshotTest(
`%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'gitGraph': {
'rotateCommitLabel': true
} } }%%
gitGraph TB:
commit id: "75f7219e83b321cd3fdde7dcf83bc7c1000a6828"
commit id: "0db4784daf82736dec4569e0dc92980d328c1f2e"
commit id: "7067e9973f9eaa6cd4a4b723c506d1eab598e83e"
commit id: "66972321ad6c199013b5b31f03b3a86fa3f9817d"
`,
{}
);
});
it('24: should render a simple gitgraph with horizontal labels | Vertical Branch', () => {
imgSnapshotTest(
`%%{init: { 'logLevel': 'debug', 'theme': 'default' , 'gitGraph': {
'rotateCommitLabel': false
} } }%%
gitGraph TB:
commit id: "Alpha"
commit id: "Beta"
commit id: "Gamma"
commit id: "Delta"
`,
{}
);
});
it('25: should render a simple gitgraph with cherry pick commit | Vertical Branch', () => {
imgSnapshotTest(
`
gitGraph TB:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
checkout main
commit id:"TWO"
cherry-pick id:"A"
commit id:"THREE"
checkout develop
commit id:"C"
`,
{}
);
});
it('26: should render a gitgraph with cherry pick commit with custom tag | Vertical Branch', () => {
imgSnapshotTest(
`
gitGraph TB:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
checkout main
commit id:"TWO"
cherry-pick id:"A" tag: "snapshot"
commit id:"THREE"
checkout develop
commit id:"C"
`,
{}
);
});
it('27: should render a gitgraph with cherry pick commit with no tag | Vertical Branch', () => {
imgSnapshotTest(
`
gitGraph TB:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
checkout main
commit id:"TWO"
cherry-pick id:"A" tag: ""
commit id:"THREE"
checkout develop
commit id:"C"
`,
{}
);
});
it('28: should render a simple gitgraph with two cherry pick commit | Vertical Branch', () => {
imgSnapshotTest(
`
gitGraph TB:
commit id: "ZERO"
branch develop
commit id:"A"
checkout main
commit id:"ONE"
checkout develop
commit id:"B"
branch featureA
commit id:"FIX"
commit id: "FIX-2"
checkout main
commit id:"TWO"
cherry-pick id:"A"
commit id:"THREE"
cherry-pick id:"FIX"
checkout develop
commit id:"C"
merge featureA
`,
{}
);
});
it('29: should render commits for more than 8 branches | Vertical Branch', () => {
imgSnapshotTest(
`
gitGraph TB:
checkout main
%% Make sure to manually set the ID of all commits, for consistent visual tests
commit id: "1-abcdefg"
checkout main
branch branch1
commit id: "2-abcdefg"
checkout main
merge branch1
branch branch2
commit id: "3-abcdefg"
checkout main
merge branch2
branch branch3
commit id: "4-abcdefg"
checkout main
merge branch3
branch branch4
commit id: "5-abcdefg"
checkout main
merge branch4
branch branch5
commit id: "6-abcdefg"
checkout main
merge branch5
branch branch6
commit id: "7-abcdefg"
checkout main
merge branch6
branch branch7
commit id: "8-abcdefg"
checkout main
merge branch7
branch branch8
commit id: "9-abcdefg"
checkout main
merge branch8
branch branch9
commit id: "10-abcdefg"
`,
{}
);
});
it('30: should render a simple gitgraph with three branches,custom merge commit id,tag,type | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id: "1"
commit id: "2"
branch nice_feature
checkout nice_feature
commit id: "3"
checkout main
commit id: "4"
checkout nice_feature
branch very_nice_feature
checkout very_nice_feature
commit id: "5"
checkout main
commit id: "6"
checkout nice_feature
commit id: "7"
checkout main
merge nice_feature id: "customID" tag: "customTag" type: REVERSE
checkout very_nice_feature
commit id: "8"
checkout main
commit id: "9"
`,
{}
);
});
it('31: should render a simple gitgraph with a title | Vertical Branch', () => {
imgSnapshotTest(
`---
title: simple gitGraph
---
gitGraph TB:
commit id: "1-abcdefg"
`,
{}
);
});
it('32: should render a simple gitgraph overlapping commits | Vertical Branch', () => {
imgSnapshotTest(
`gitGraph TB:
commit id:"s1"
commit id:"s2"
branch branch1
commit id:"s3"
commit id:"s4"
checkout main
commit id:"s5"
checkout branch1
commit id:"s6"
commit id:"s7"
merge main
`,
{}
);
});
it('33: should render a simple gitgraph overlapping commits', () => {
imgSnapshotTest(
`gitGraph
commit id:"s1"
commit id:"s2"
branch branch1
commit id:"s3"
commit id:"s4"
checkout main
commit id:"s5"
checkout branch1
commit id:"s6"
commit id:"s7"
merge main
`,
{}
);
});
});

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('info diagram', () => {
it('should handle an info definition', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('User journey diagram', () => {
it('Simple test', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
/**
* Check whether the SVG Element has a Mindmap root
@@ -242,8 +242,7 @@ mindmap
a second line 😎\`]
id2[\`The dog in **the** hog... a *very long text* about it
Word!\`]
`,
{ titleTopMargin: 0 }
`
);
});
});

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Pie Chart', () => {
it('should render a simple pie diagram', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Quadrant Chart', () => {
it('should render if only chart type is provided', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Requirement diagram', () => {
it('sample', () => {

View File

@@ -0,0 +1,144 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('Sankey Diagram', () => {
it('should render a simple example', () => {
imgSnapshotTest(
`
sankey-beta
sourceNode,targetNode,10
`,
{}
);
});
describe('when given a linkColor', function () {
this.beforeAll(() => {
cy.wrap(
`sankey-beta
a,b,10
`
).as('graph');
});
it('links should use hex color', function () {
renderGraph(this.graph, { sankey: { linkColor: '#636465' } });
cy.get('.link path').should((link) => {
expect(link.attr('stroke')).to.equal('#636465');
});
});
it('links should be the same color as source node', function () {
renderGraph(this.graph, { sankey: { linkColor: 'source' } });
cy.get('.link path').then((link) => {
cy.get('.node[id="node-1"] rect').should((node) =>
expect(link.attr('stroke')).to.equal(node.attr('fill'))
);
});
});
it('links should be the same color as target node', function () {
renderGraph(this.graph, { sankey: { linkColor: 'target' } });
cy.get('.link path').then((link) => {
cy.get('.node[id="node-2"] rect').should((node) =>
expect(link.attr('stroke')).to.equal(node.attr('fill'))
);
});
});
it('links must be gradient', function () {
renderGraph(this.graph, { sankey: { linkColor: 'gradient' } });
cy.get('.link path').should((link) => {
expect(link.attr('stroke')).to.equal('url(#linearGradient-3)');
});
});
});
describe('when given a nodeAlignment', function () {
this.beforeAll(() => {
cy.wrap(
`
sankey-beta
a,b,8
b,c,8
c,d,8
d,e,8
x,c,4
c,y,4
`
).as('graph');
});
this.afterEach(() => {
cy.get('.node[id="node-1"]').should((node) => {
expect(node.attr('x')).to.equal('0');
});
cy.get('.node[id="node-2"]').should((node) => {
expect(node.attr('x')).to.equal('100');
});
cy.get('.node[id="node-3"]').should((node) => {
expect(node.attr('x')).to.equal('200');
});
cy.get('.node[id="node-4"]').should((node) => {
expect(node.attr('x')).to.equal('300');
});
cy.get('.node[id="node-5"]').should((node) => {
expect(node.attr('x')).to.equal('400');
});
});
it('should justify nodes', function () {
renderGraph(this.graph, {
sankey: { nodeAlignment: 'justify', width: 410, useMaxWidth: false },
});
cy.get('.node[id="node-6"]').should((node) => {
expect(node.attr('x')).to.equal('0');
});
cy.get('.node[id="node-7"]').should((node) => {
expect(node.attr('x')).to.equal('400');
});
});
it('should align nodes left', function () {
renderGraph(this.graph, {
sankey: { nodeAlignment: 'left', width: 410, useMaxWidth: false },
});
cy.get('.node[id="node-6"]').should((node) => {
expect(node.attr('x')).to.equal('0');
});
cy.get('.node[id="node-7"]').should((node) => {
expect(node.attr('x')).to.equal('300');
});
});
it('should align nodes right', function () {
renderGraph(this.graph, {
sankey: { nodeAlignment: 'right', width: 410, useMaxWidth: false },
});
cy.get('.node[id="node-6"]').should((node) => {
expect(node.attr('x')).to.equal('100');
});
cy.get('.node[id="node-7"]').should((node) => {
expect(node.attr('x')).to.equal('400');
});
});
it('should center nodes', function () {
renderGraph(this.graph, {
sankey: { nodeAlignment: 'center', width: 410, useMaxWidth: false },
});
cy.get('.node[id="node-6"]').should((node) => {
expect(node.attr('x')).to.equal('100');
});
cy.get('.node[id="node-7"]').should((node) => {
expect(node.attr('x')).to.equal('300');
});
});
});
});

View File

@@ -1,6 +1,6 @@
/// <reference types="Cypress" />
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
context('Sequence diagram', () => {
it('should render a sequence diagram with boxes', () => {
@@ -156,6 +156,81 @@ context('Sequence diagram', () => {
`
);
});
it('should render a sequence diagram with basic actor creation and destruction', () => {
imgSnapshotTest(
`
sequenceDiagram
Alice ->> Bob: Hello Bob, how are you ?
Bob ->> Alice: Fine, thank you. And you?
create participant Polo
Alice ->> Polo: Hi Polo!
create actor Ola1 as Ola
Polo ->> Ola1: Hiii
Ola1 ->> Alice: Hi too
destroy Ola1
Alice --x Ola1: Bye!
Alice ->> Bob: And now?
create participant Ola2 as Ola
Alice ->> Ola2: Hello again
destroy Alice
Alice --x Ola2: Bye for me!
destroy Bob
Ola2 --> Bob: The end
`
);
});
it('should render a sequence diagram with actor creation and destruction coupled with backgrounds, loops and notes', () => {
imgSnapshotTest(
`
sequenceDiagram
accTitle: test the accTitle
accDescr: Test a description
participant Alice
participant Bob
autonumber 10 10
rect rgb(200, 220, 100)
rect rgb(200, 255, 200)
Alice ->> Bob: Hello Bob, how are you?
create participant John as John<br />Second Line
Bob-->>John: How about you John?
end
Bob--x Alice: I am good thanks!
Bob-x John: I am good thanks!
Note right of John: John thinks a long<br />long time, so long<br />that the text does<br />not fit on a row.
Bob-->Alice: Checking with John...
Note over John:wrap: John looks like he's still thinking, so Bob prods him a bit.
Bob-x John: Hey John - we're still waiting to know<br />how you're doing
Note over John:nowrap: John's trying hard not to break his train of thought.
destroy John
Bob-x John: John! Cmon!
Note over John: After a few more moments, John<br />finally snaps out of it.
end
autonumber off
alt either this
create actor Lola
Alice->>+Lola: Yes
Lola-->>-Alice: OK
else or this
autonumber
Alice->>Lola: No
else or this will happen
Alice->Lola: Maybe
end
autonumber 200
par this happens in parallel
destroy Bob
Alice -->> Bob: Parallel message 1
and
Alice -->> Lola: Parallel message 2
end
`
);
});
context('font settings', () => {
it('should render different note fonts when configured', () => {
imgSnapshotTest(

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('State diagram', () => {
it('v2 should render a simple info', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest, renderGraph } from '../../helpers/util.js';
import { imgSnapshotTest, renderGraph } from '../../helpers/util.ts';
describe('State diagram', () => {
it('should render a simple state diagrams', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('themeCSS balancing, it', () => {
it('should not allow unbalanced CSS definitions', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Timeline diagram', () => {
it('1: should render a simple timeline with no specific sections', () => {

View File

@@ -1,4 +1,4 @@
import { imgSnapshotTest } from '../../helpers/util.js';
import { imgSnapshotTest } from '../../helpers/util.ts';
describe('Zen UML', () => {
it('Basic Zen UML diagram', () => {

View File

@@ -58,6 +58,14 @@
</head>
<body>
<pre id="diagram" class="mermaid">
---
title: Simple flowchart with invisible edges
---
flowchart TD
A ~~~ B
</pre
>
<pre id="diagram" class="mermaid2">
stateDiagram-v2
[*] --> Still
Still --> [*]
@@ -73,7 +81,7 @@ flowchart RL
a1 -- l2 --> a2
end
</pre>
<pre id="diagram" class="mermaid">
<pre id="diagram" class="mermaid2">
flowchart RL
subgraph "`one`"
a1 -- l1 --> a2
@@ -98,11 +106,11 @@ flowchart LR
way`"]
</pre
>
<pre id="diagram" class="mermaid">
<pre id="diagram" class="mermaid2">
classDiagram-v2
note "I love this diagram!\nDo you love it?"
</pre>
<pre id="diagram" class="mermaid">
<pre id="diagram" class="mermaid2">
stateDiagram-v2
State1: The state with a note with minus - and plus + in it
note left of State1
@@ -147,7 +155,7 @@ mindmap
शान्तिः سلام 和平 `"]
</pre>
<pre id="diagram" class="mermaid">
<pre id="diagram" class="mermaid2">
%%{init: {"flowchart": {"defaultRenderer": "elk"}} }%%
flowchart TB
%% I could not figure out how to use double quotes in labels in Mermaid
@@ -399,21 +407,31 @@ mindmap
mermaid.parseError = function (err, hash) {
// console.error('Mermaid error: ', err);
};
// mermaid.initialize({
// // theme: 'forest',
// startOnLoad: true,
// logLevel: 0,
// flowchart: {
// // defaultRenderer: 'elk',
// useMaxWidth: false,
// // htmlLabels: false,
// htmlLabels: true,
// },
// // htmlLabels: false,
// gantt: {
// useMaxWidth: false,
// },
// useMaxWidth: false,
// });
mermaid.initialize({
// theme: 'forest',
startOnLoad: true,
logLevel: 0,
flowchart: {
// defaultRenderer: 'elk',
useMaxWidth: false,
// htmlLabels: false,
htmlLabels: true,
flowchart: { titleTopMargin: 10 },
fontFamily: 'courier',
sequence: {
actorFontFamily: 'courier',
noteFontFamily: 'courier',
messageFontFamily: 'courier',
},
// htmlLabels: false,
gantt: {
useMaxWidth: false,
},
useMaxWidth: false,
fontSize: 16,
});
function callback() {
alert('It worked');

View File

@@ -2,7 +2,9 @@
"compilerOptions": {
"target": "es2020",
"lib": ["es2020", "dom"],
"types": ["cypress", "node"]
"types": ["cypress", "node"],
"allowImportingTsExtensions": true,
"noEmit": true
},
"include": ["**/*.ts"]
}

View File

@@ -75,6 +75,9 @@
<li>
<h2><a href="./zenuml.html">ZenUML</a></h2>
</li>
<li>
<h2><a href="./sankey.html">Sankey</a></h2>
</li>
</ul>
</body>
</html>

108
demos/sankey.html Normal file
View File

@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>States Mermaid Quick Test Page</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=" />
<style>
div.mermaid {
/* font-family: 'trebuchet ms', verdana, arial; */
font-family: 'Courier New', Courier, monospace !important;
}
</style>
</head>
<body>
<h1>Sankey diagram demos</h1>
<h2>Energy flow</h2>
<pre class="mermaid">
sankey-beta
Agricultural 'waste',Bio-conversion,124.729
Bio-conversion,Liquid,0.597
Bio-conversion,Losses,26.862
Bio-conversion,Solid,280.322
Bio-conversion,Gas,81.144
Biofuel imports,Liquid,35
Biomass imports,Solid,35
Coal imports,Coal,11.606
Coal reserves,Coal,63.965
Coal,Solid,75.571
District heating,Industry,10.639
District heating,Heating and cooling - commercial,22.505
District heating,Heating and cooling - homes,46.184
Electricity grid,Over generation / exports,104.453
Electricity grid,Heating and cooling - homes,113.726
Electricity grid,H2 conversion,27.14
Electricity grid,Industry,342.165
Electricity grid,Road transport,37.797
Electricity grid,Agriculture,4.412
Electricity grid,Heating and cooling - commercial,40.858
Electricity grid,Losses,56.691
Electricity grid,Rail transport,7.863
Electricity grid,Lighting & appliances - commercial,90.008
Electricity grid,Lighting & appliances - homes,93.494
Gas imports,Ngas,40.719
Gas reserves,Ngas,82.233
Gas,Heating and cooling - commercial,0.129
Gas,Losses,1.401
Gas,Thermal generation,151.891
Gas,Agriculture,2.096
Gas,Industry,48.58
Geothermal,Electricity grid,7.013
H2 conversion,H2,20.897
H2 conversion,Losses,6.242
H2,Road transport,20.897
Hydro,Electricity grid,6.995
Liquid,Industry,121.066
Liquid,International shipping,128.69
Liquid,Road transport,135.835
Liquid,Domestic aviation,14.458
Liquid,International aviation,206.267
Liquid,Agriculture,3.64
Liquid,National navigation,33.218
Liquid,Rail transport,4.413
Marine algae,Bio-conversion,4.375
Ngas,Gas,122.952
Nuclear,Thermal generation,839.978
Oil imports,Oil,504.287
Oil reserves,Oil,107.703
Oil,Liquid,611.99
Other waste,Solid,56.587
Other waste,Bio-conversion,77.81
Pumped heat,Heating and cooling - homes,193.026
Pumped heat,Heating and cooling - commercial,70.672
Solar PV,Electricity grid,59.901
Solar Thermal,Heating and cooling - homes,19.263
Solar,Solar Thermal,19.263
Solar,Solar PV,59.901
Solid,Agriculture,0.882
Solid,Thermal generation,400.12
Solid,Industry,46.477
Thermal generation,Electricity grid,525.531
Thermal generation,Losses,787.129
Thermal generation,District heating,79.329
Tidal,Electricity grid,9.452
UK land based bioenergy,Bio-conversion,182.01
Wave,Electricity grid,19.013
Wind,Electricity grid,289.366
</pre>
<script type="module">
import mermaid from './mermaid.esm.mjs';
mermaid.initialize({
theme: 'default',
logLevel: 3,
securityLevel: 'loose',
sankey: {
title: 'Hey, this is Sankey-Beta',
width: 1200,
height: 600,
linkColor: 'gradient',
nodeAlignment: 'justify',
},
});
</script>
</body>
</html>

View File

@@ -1,9 +1,36 @@
version: '3.9'
services:
mermaid:
image: node:20.3.1-alpine3.18
image: node:18.17.0-alpine3.18
stdin_open: true
tty: true
working_dir: /mermaid
mem_limit: '2G'
environment:
- NODE_OPTIONS=--max_old_space_size=2048
volumes:
- ./:/mermaid
- root_cache:/root/.cache
- root_local:/root/.local
- root_npm:/root/.npm
ports:
- 9000:9000
- 3333:3333
cypress:
image: cypress/included:12.17.2
stdin_open: true
tty: true
working_dir: /mermaid
mem_limit: '2G'
entrypoint: cypress
environment:
- DISPLAY
volumes:
- ./:/mermaid
- /tmp/.X11-unix:/tmp/.X11-unix
network_mode: host
volumes:
root_cache:
root_local:
root_npm:

View File

@@ -223,6 +223,9 @@ If the users have no way to know that things have changed, then you haven't real
Likewise, if users don't know that there is a new feature that you've implemented, it will forever remain unknown and unused.
The documentation has to be updated to users know that things have changed and added!
If you are adding a new feature, add `(v<MERMAID_RELEASE_VERSION>+)` in the title or description. It will be replaced automatically with the current version number when the release happens.
eg: `# Feature Name (v<MERMAID_RELEASE_VERSION>+)`
We know it can sometimes be hard to code _and_ write user documentation.

View File

@@ -14,7 +14,7 @@
#### Defined in
[defaultConfig.ts:2293](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L2293)
[defaultConfig.ts:266](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L266)
---
@@ -22,35 +22,12 @@
`Const` **default**: `Partial`<`MermaidConfig`>
**Configuration methods in Mermaid version 8.6.0 have been updated, to learn more\[[click
here](8.6.0_docs.md)].**
Default mermaid configuration options.
## **What follows are config instructions for older versions**
These are the default options which can be overridden with the initialization call like so:
**Example 1:**
```js
mermaid.initialize({ flowchart: { htmlLabels: false } });
```
**Example 2:**
```html
<script>
const config = {
startOnLoad: true,
flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' },
securityLevel: 'loose',
};
mermaid.initialize(config);
</script>
```
A summary of all options and their defaults is found [here](#mermaidapi-configuration-defaults).
A description of each option follows below.
Please see the Mermaid config JSON Schema for the default JSON values.
Non-JSON JS default values are listed in this file, e.g. functions, or
`undefined` (explicitly set so that `configKeys` finds them).
#### Defined in
[defaultConfig.ts:33](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L33)
[defaultConfig.ts:16](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/defaultConfig.ts#L16)

View File

@@ -96,7 +96,7 @@ mermaid.initialize(config);
#### Defined in
[mermaidAPI.ts:663](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L663)
[mermaidAPI.ts:667](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L667)
## Functions

View File

@@ -73,9 +73,9 @@ To make a custom theme, modify `themeVariables` via `init`.
You will need to use the [base](#available-themes) theme as it is the only modifiable theme.
| Parameter | Description | Type | Properties |
| -------------- | ------------------------------------ | ------ | --------------------------------------------------------------------------------------------------- |
| themeVariables | Modifiable with the `init` directive | Object | `primaryColor`, `primaryTextColor`, `lineColor` ([see full list](#theme-variables-reference-table)) |
| Parameter | Description | Type | Properties |
| -------------- | ------------------------------------ | ------ | ----------------------------------------------------------------------------------- |
| themeVariables | Modifiable with the `init` directive | Object | `primaryColor`, `primaryTextColor`, `lineColor` ([see full list](#theme-variables)) |
Example of modifying `themeVariables` using the `init` directive:

View File

@@ -228,7 +228,7 @@ mermaid fully supports webpack. Here is a [working demo](https://github.com/merm
The main idea of the API is to be able to call a render function with the graph definition as a string. The render function will render the graph and call a callback with the resulting SVG code. With this approach it is up to the site creator to fetch the graph definition from the site (perhaps from a textarea), render it and place the graph somewhere in the site.
The example below show an outline of how this could be used. The example just logs the resulting SVG to the JavaScript console.
The example below shows an example of how this could be used. The example just logs the resulting SVG to the JavaScript console.
```html
<script type="module">

View File

@@ -187,6 +187,7 @@ They also serve as proof of concept, for the variety of things that can be built
- [mdbook](https://rust-lang.github.io/mdBook/index.html)
- [mdbook-mermaid](https://github.com/badboy/mdbook-mermaid)
- [Quarto](https://quarto.org/)
- [Typora](https://typora.io/) ([Native support](https://support.typora.io/Draw-Diagrams-With-Markdown/#mermaid))
## Browser Extensions

View File

@@ -6,8 +6,8 @@
# Announcements
## [Mermaid Charts ChatGPT Plugin Combines Generative AI and Smart Diagramming For Users](https://www.mermaidchart.com/blog/posts/mermaid-chart-chatgpt-plugin-combines-generative-ai-and-smart-diagramming)
## [Mermaid Chart Announces Visual Studio Code Plugin to Simplify Development Workflows](https://www.mermaidchart.com/blog/posts/mermaid-chart-announces-visual-studio-code-plugin)
29 June 2023 · 4 mins
17 July 2023 · 3 mins
Mermaid Charts new ChatGPT plugin integrates AI-powered text prompts with Mermaids intuitive diagramming editor, enabling users to generate, edit, and share complex diagrams with ease and efficiency.
New Integration Enhances Workflows By Enabling Developers To Reference And Edit Diagrams Within Visual Studio Code.

View File

@@ -6,6 +6,12 @@
# Blog
## [Mermaid Chart Announces Visual Studio Code Plugin to Simplify Development Workflows](https://www.mermaidchart.com/blog/posts/mermaid-chart-announces-visual-studio-code-plugin)
17 July 2023 · 3 mins
New Integration Enhances Workflows By Enabling Developers To Reference And Edit Diagrams Within Visual Studio Code.
## [Mermaid Charts ChatGPT Plugin Combines Generative AI and Smart Diagramming For Users](https://www.mermaidchart.com/blog/posts/mermaid-chart-chatgpt-plugin-combines-generative-ai-and-smart-diagramming)
29 June 2023 · 4 mins

View File

@@ -2,13 +2,13 @@
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/c4c.md](../../packages/mermaid/src/docs/syntax/c4c.md).
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/c4.md](../../packages/mermaid/src/docs/syntax/c4.md).
# C4 Diagrams
> C4 Diagram: This is an experimental diagram for now. The syntax and properties can change in future releases. Proper documentation will be provided when the syntax is stable.
Mermaid's c4 diagram syntax is compatible with plantUML. See example below:
Mermaid's C4 diagram syntax is compatible with plantUML. See example below:
```mermaid-example
C4Context
@@ -114,7 +114,7 @@ For an example, see the source code demos/index.html
- Dynamic diagram (C4Dynamic)
- Deployment diagram (C4Deployment)
Please refer to the linked document [C4-PlantUML syntax](https://github.com/plantuml-stdlib/C4-PlantUML/blob/master/README.md) for how to write the c4 diagram.
Please refer to the linked document [C4-PlantUML syntax](https://github.com/plantuml-stdlib/C4-PlantUML/blob/master/README.md) for how to write the C4 diagram.
C4 diagram is fixed style, such as css color, so different css is not provided under different skins.
updateElementStyle and UpdateElementStyle are written in the diagram last part. updateElementStyle is inconsistent with the original definition and updates the style of the relationship, including the offset of the text label relative to the original position.
@@ -123,10 +123,10 @@ The layout does not use a fully automated layout algorithm. The position of shap
The number of shapes per row and the number of boundaries can be adjusted using UpdateLayoutConfig.
- Layout
- - Lay_U, Lay_Up
- - Lay_D, Lay_Down
- - Lay_L, Lay_Left
- - Lay_R, Lay_Right
- Lay_U, Lay_Up
- Lay_D, Lay_Down
- Lay_L, Lay_Left
- Lay_R, Lay_Right
The following unfinished features are not supported in the short term.
@@ -140,111 +140,70 @@ The following unfinished features are not supported in the short term.
- [x] System Context
- - [x] Person(alias, label, ?descr, ?sprite, ?tags, $link)
- - [x] Person_Ext
- - [x] System(alias, label, ?descr, ?sprite, ?tags, $link)
- - [x] SystemDb
- - [x] SystemQueue
- - [x] System_Ext
- - [x] SystemDb_Ext
- - [x] SystemQueue_Ext
- - [x] Boundary(alias, label, ?type, ?tags, $link)
- - [x] Enterprise_Boundary(alias, label, ?tags, $link)
- - [x] System_Boundary
- [x] Person(alias, label, ?descr, ?sprite, ?tags, $link)
- [x] Person_Ext
- [x] System(alias, label, ?descr, ?sprite, ?tags, $link)
- [x] SystemDb
- [x] SystemQueue
- [x] System_Ext
- [x] SystemDb_Ext
- [x] SystemQueue_Ext
- [x] Boundary(alias, label, ?type, ?tags, $link)
- [x] Enterprise_Boundary(alias, label, ?tags, $link)
- [x] System_Boundary
- [x] Container diagram
- - [x] Container(alias, label, ?techn, ?descr, ?sprite, ?tags, $link)
- - [x] ContainerDb
- - [x] ContainerQueue
- - [x] Container_Ext
- - [x] ContainerDb_Ext
- - [x] ContainerQueue_Ext
- - [x] Container_Boundary(alias, label, ?tags, $link)
- [x] Container(alias, label, ?techn, ?descr, ?sprite, ?tags, $link)
- [x] ContainerDb
- [x] ContainerQueue
- [x] Container_Ext
- [x] ContainerDb_Ext
- [x] ContainerQueue_Ext
- [x] Container_Boundary(alias, label, ?tags, $link)
- [x] Component diagram
- - [x] Component(alias, label, ?techn, ?descr, ?sprite, ?tags, $link)
- - [x] ComponentDb
- - [x] ComponentQueue
- - [x] Component_Ext
- - [x] ComponentDb_Ext
- - [x] ComponentQueue_Ext
- [x] Component(alias, label, ?techn, ?descr, ?sprite, ?tags, $link)
- [x] ComponentDb
- [x] ComponentQueue
- [x] Component_Ext
- [x] ComponentDb_Ext
- [x] ComponentQueue_Ext
- [x] Dynamic diagram
- - [x] RelIndex(index, from, to, label, ?tags, $link)
- [x] RelIndex(index, from, to, label, ?tags, $link)
- [x] Deployment diagram
- - [x] Deployment_Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link)
- - [x] Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link): short name of Deployment_Node()
- - [x] Node_L(alias, label, ?type, ?descr, ?sprite, ?tags, $link): left aligned Node()
- - [x] Node_R(alias, label, ?type, ?descr, ?sprite, ?tags, $link): right aligned Node()
- [x] Deployment_Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link)
- [x] Node(alias, label, ?type, ?descr, ?sprite, ?tags, $link): short name of Deployment_Node()
- [x] Node_L(alias, label, ?type, ?descr, ?sprite, ?tags, $link): left aligned Node()
- [x] Node_R(alias, label, ?type, ?descr, ?sprite, ?tags, $link): right aligned Node()
- [x] Relationship Types
- - [x] Rel(from, to, label, ?techn, ?descr, ?sprite, ?tags, $link)
- - [x] BiRel (bidirectional relationship)
- - [x] Rel_U, Rel_Up
- - [x] Rel_D, Rel_Down
- - [x] Rel_L, Rel_Left
- - [x] Rel_R, Rel_Right
- - [x] Rel_Back
- - [x] RelIndex \* Compatible with C4-Plantuml syntax, but ignores the index parameter. The sequence number is determined by the order in which the rel statements are written.
- [x] Rel(from, to, label, ?techn, ?descr, ?sprite, ?tags, $link)
- [x] BiRel (bidirectional relationship)
- [x] Rel_U, Rel_Up
- [x] Rel_D, Rel_Down
- [x] Rel_L, Rel_Left
- [x] Rel_R, Rel_Right
- [x] Rel_Back
- [x] RelIndex \* Compatible with C4-Plantuml syntax, but ignores the index parameter. The sequence number is determined by the order in which the rel statements are written.
- [ ] Custom tags/stereotypes support and skin param updates
- - [ ] AddElementTag(tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?techn, ?legendText, ?legendSprite): Introduces a new element tag. The styles of the tagged elements are updated and the tag is displayed in the calculated legend.
- - [ ] AddRelTag(tagStereo, ?textColor, ?lineColor, ?lineStyle, ?sprite, ?techn, ?legendText, ?legendSprite): Introduces a new Relationship tag. The styles of the tagged relationships are updated and the tag is displayed in the calculated legend.
- - [x] UpdateElementStyle(elementName, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?techn, ?legendText, ?legendSprite): This call updates the default style of the elements (component, ...) and creates no additional legend entry.
- - [x] UpdateRelStyle(from, to, ?textColor, ?lineColor, ?offsetX, ?offsetY): This call updates the default relationship colors and creates no additional legend entry. Two new parameters, offsetX and offsetY, are added to set the offset of the original position of the text.
- - [ ] RoundedBoxShape(): This call returns the name of the rounded box shape and can be used as ?shape argument.
- - [ ] EightSidedShape(): This call returns the name of the eight sided shape and can be used as ?shape argument.
- - [ ] DashedLine(): This call returns the name of the dashed line and can be used as ?lineStyle argument.
- - [ ] DottedLine(): This call returns the name of the dotted line and can be used as ?lineStyle argument.
- - [ ] BoldLine(): This call returns the name of the bold line and can be used as ?lineStyle argument.
- - [x] UpdateLayoutConfig(?c4ShapeInRow, ?c4BoundaryInRow): New. This call updates the default c4ShapeInRow(4) and c4BoundaryInRow(2).
- [ ] AddElementTag(tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?techn, ?legendText, ?legendSprite): Introduces a new element tag. The styles of the tagged elements are updated and the tag is displayed in the calculated legend.
- [ ] AddRelTag(tagStereo, ?textColor, ?lineColor, ?lineStyle, ?sprite, ?techn, ?legendText, ?legendSprite): Introduces a new Relationship tag. The styles of the tagged relationships are updated and the tag is displayed in the calculated legend.
- [x] UpdateElementStyle(elementName, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?techn, ?legendText, ?legendSprite): This call updates the default style of the elements (component, ...) and creates no additional legend entry.
- [x] UpdateRelStyle(from, to, ?textColor, ?lineColor, ?offsetX, ?offsetY): This call updates the default relationship colors and creates no additional legend entry. Two new parameters, offsetX and offsetY, are added to set the offset of the original position of the text.
- [ ] RoundedBoxShape(): This call returns the name of the rounded box shape and can be used as ?shape argument.
- [ ] EightSidedShape(): This call returns the name of the eight sided shape and can be used as ?shape argument.
- [ ] DashedLine(): This call returns the name of the dashed line and can be used as ?lineStyle argument.
- [ ] DottedLine(): This call returns the name of the dotted line and can be used as ?lineStyle argument.
- [ ] BoldLine(): This call returns the name of the bold line and can be used as ?lineStyle argument.
- [x] UpdateLayoutConfig(?c4ShapeInRow, ?c4BoundaryInRow): New. This call updates the default c4ShapeInRow(4) and c4BoundaryInRow(2).
There are two ways to assign parameters with question marks. One uses the non-named parameter assignment method in the order of the parameters, and the other uses the named parameter assignment method, where the name must start with a $ symbol.

View File

@@ -196,7 +196,7 @@ erDiagram
}
```
The `type` and `name` values must begin with an alphabetic character and may contain digits, hyphens, underscores, parentheses and square brackets. Other than that, there are no restrictions, and there is no implicit set of valid data types.
The `type` values must begin with an alphabetic character and may contain digits, hyphens, underscores, parentheses and square brackets. The `name` values follow a similar format to `type`, but may start with an asterisk as another option to indicate an attribute is a primary key. Other than that, there are no restrictions, and there is no implicit set of valid data types.
#### Attribute Keys and Comments

View File

@@ -991,6 +991,24 @@ flowchart LR
classDef someclass fill:#f96
```
This form can be used when declaring multiple links between nodes:
```mermaid-example
flowchart LR
A:::foo & B:::bar --> C:::foobar
classDef foo stroke:#f00
classDef bar stroke:#0f0
classDef foobar stroke:#00f
```
```mermaid
flowchart LR
A:::foo & B:::bar --> C:::foobar
classDef foo stroke:#f00
classDef bar stroke:#0f0
classDef foobar stroke:#00f
```
### Css classes
It is also possible to predefine classes in css styles that can be applied from the graph definition as in the example

View File

@@ -257,6 +257,22 @@ The pattern is:
More info in: <https://github.com/d3/d3-time#interval_every>
Week-based `tickInterval`s start the week on sunday by default. If you wish to specify another weekday on which the `tickInterval` should start, use the `weekday` option:
```mermaid-example
gantt
tickInterval 1week
weekday monday
```
```mermaid
gantt
tickInterval 1week
weekday monday
```
Support: v10.3.0+
## Output in compact mode
The compact mode allows you to display multiple tasks in the same row. Compact mode can be enabled for a gantt chart by setting the display mode of the graph via preceeding YAML settings.

View File

@@ -825,6 +825,82 @@ NOTE: Because we have overridden the `mainBranchOrder` to `2`, the `main` branch
Here, we have changed the default main branch name to `MetroLine1`.
## Orientation (v10.3.0+)
In Mermaid, the default orientation is Left to Right. The branches are lined vertically.
Usage example:
```mermaid-example
gitGraph
commit
commit
branch develop
commit
commit
commit
checkout main
commit
commit
merge develop
commit
commit
```
```mermaid
gitGraph
commit
commit
branch develop
commit
commit
commit
checkout main
commit
commit
merge develop
commit
commit
```
Sometimes we may want to change the orientation. Currently, Mermaid supports two orientations: **Left to Right**(default) and **Top to Bottom**.
In order to change the orientation from top to bottom i.e. branches lined horizontally, you need to add `TB` along with `gitGraph`.
Usage example:
```mermaid-example
gitGraph TB:
commit
commit
branch develop
commit
commit
commit
checkout main
commit
commit
merge develop
commit
commit
```
```mermaid
gitGraph TB:
commit
commit
branch develop
commit
commit
commit
checkout main
commit
commit
merge develop
commit
commit
```
## Themes
Mermaid supports a bunch of pre-defined themes which you can use to find the right one for you. PS: you can actually override an existing theme's variable to get your own custom theme going. Learn more about theming your diagram [here](../config/theming.md).

294
docs/syntax/sankey.md Normal file
View File

@@ -0,0 +1,294 @@
> **Warning**
>
> ## THIS IS AN AUTOGENERATED FILE. DO NOT EDIT.
>
> ## Please edit the corresponding file in [/packages/mermaid/src/docs/syntax/sankey.md](../../packages/mermaid/src/docs/syntax/sankey.md).
# Sankey diagram (v10.3.0+)
> A sankey diagram is a visualization used to depict a flow from one set of values to another.
::: warning
This is an experimental diagram. Its syntax are very close to plain CSV, but it is to be extended in the nearest future.
:::
The things being connected are called nodes and the connections are called links.
## Example
This example taken from [observable](https://observablehq.com/@d3/sankey/2?collection=@d3/d3-sankey). It may be rendered a little bit differently, though, in terms of size and colors.
```mermaid-example
sankey-beta
Agricultural 'waste',Bio-conversion,124.729
Bio-conversion,Liquid,0.597
Bio-conversion,Losses,26.862
Bio-conversion,Solid,280.322
Bio-conversion,Gas,81.144
Biofuel imports,Liquid,35
Biomass imports,Solid,35
Coal imports,Coal,11.606
Coal reserves,Coal,63.965
Coal,Solid,75.571
District heating,Industry,10.639
District heating,Heating and cooling - commercial,22.505
District heating,Heating and cooling - homes,46.184
Electricity grid,Over generation / exports,104.453
Electricity grid,Heating and cooling - homes,113.726
Electricity grid,H2 conversion,27.14
Electricity grid,Industry,342.165
Electricity grid,Road transport,37.797
Electricity grid,Agriculture,4.412
Electricity grid,Heating and cooling - commercial,40.858
Electricity grid,Losses,56.691
Electricity grid,Rail transport,7.863
Electricity grid,Lighting & appliances - commercial,90.008
Electricity grid,Lighting & appliances - homes,93.494
Gas imports,Ngas,40.719
Gas reserves,Ngas,82.233
Gas,Heating and cooling - commercial,0.129
Gas,Losses,1.401
Gas,Thermal generation,151.891
Gas,Agriculture,2.096
Gas,Industry,48.58
Geothermal,Electricity grid,7.013
H2 conversion,H2,20.897
H2 conversion,Losses,6.242
H2,Road transport,20.897
Hydro,Electricity grid,6.995
Liquid,Industry,121.066
Liquid,International shipping,128.69
Liquid,Road transport,135.835
Liquid,Domestic aviation,14.458
Liquid,International aviation,206.267
Liquid,Agriculture,3.64
Liquid,National navigation,33.218
Liquid,Rail transport,4.413
Marine algae,Bio-conversion,4.375
Ngas,Gas,122.952
Nuclear,Thermal generation,839.978
Oil imports,Oil,504.287
Oil reserves,Oil,107.703
Oil,Liquid,611.99
Other waste,Solid,56.587
Other waste,Bio-conversion,77.81
Pumped heat,Heating and cooling - homes,193.026
Pumped heat,Heating and cooling - commercial,70.672
Solar PV,Electricity grid,59.901
Solar Thermal,Heating and cooling - homes,19.263
Solar,Solar Thermal,19.263
Solar,Solar PV,59.901
Solid,Agriculture,0.882
Solid,Thermal generation,400.12
Solid,Industry,46.477
Thermal generation,Electricity grid,525.531
Thermal generation,Losses,787.129
Thermal generation,District heating,79.329
Tidal,Electricity grid,9.452
UK land based bioenergy,Bio-conversion,182.01
Wave,Electricity grid,19.013
Wind,Electricity grid,289.366
```
```mermaid
sankey-beta
Agricultural 'waste',Bio-conversion,124.729
Bio-conversion,Liquid,0.597
Bio-conversion,Losses,26.862
Bio-conversion,Solid,280.322
Bio-conversion,Gas,81.144
Biofuel imports,Liquid,35
Biomass imports,Solid,35
Coal imports,Coal,11.606
Coal reserves,Coal,63.965
Coal,Solid,75.571
District heating,Industry,10.639
District heating,Heating and cooling - commercial,22.505
District heating,Heating and cooling - homes,46.184
Electricity grid,Over generation / exports,104.453
Electricity grid,Heating and cooling - homes,113.726
Electricity grid,H2 conversion,27.14
Electricity grid,Industry,342.165
Electricity grid,Road transport,37.797
Electricity grid,Agriculture,4.412
Electricity grid,Heating and cooling - commercial,40.858
Electricity grid,Losses,56.691
Electricity grid,Rail transport,7.863
Electricity grid,Lighting & appliances - commercial,90.008
Electricity grid,Lighting & appliances - homes,93.494
Gas imports,Ngas,40.719
Gas reserves,Ngas,82.233
Gas,Heating and cooling - commercial,0.129
Gas,Losses,1.401
Gas,Thermal generation,151.891
Gas,Agriculture,2.096
Gas,Industry,48.58
Geothermal,Electricity grid,7.013
H2 conversion,H2,20.897
H2 conversion,Losses,6.242
H2,Road transport,20.897
Hydro,Electricity grid,6.995
Liquid,Industry,121.066
Liquid,International shipping,128.69
Liquid,Road transport,135.835
Liquid,Domestic aviation,14.458
Liquid,International aviation,206.267
Liquid,Agriculture,3.64
Liquid,National navigation,33.218
Liquid,Rail transport,4.413
Marine algae,Bio-conversion,4.375
Ngas,Gas,122.952
Nuclear,Thermal generation,839.978
Oil imports,Oil,504.287
Oil reserves,Oil,107.703
Oil,Liquid,611.99
Other waste,Solid,56.587
Other waste,Bio-conversion,77.81
Pumped heat,Heating and cooling - homes,193.026
Pumped heat,Heating and cooling - commercial,70.672
Solar PV,Electricity grid,59.901
Solar Thermal,Heating and cooling - homes,19.263
Solar,Solar Thermal,19.263
Solar,Solar PV,59.901
Solid,Agriculture,0.882
Solid,Thermal generation,400.12
Solid,Industry,46.477
Thermal generation,Electricity grid,525.531
Thermal generation,Losses,787.129
Thermal generation,District heating,79.329
Tidal,Electricity grid,9.452
UK land based bioenergy,Bio-conversion,182.01
Wave,Electricity grid,19.013
Wind,Electricity grid,289.366
```
## Syntax
The idea behind syntax is that a user types `sankey-beta` keyword first, then pastes raw CSV below and get the result.
It implements CSV standard as [described here](https://www.ietf.org/rfc/rfc4180.txt) with subtle **differences**:
- CSV must contain **3 columns only**
- It is **allowed** to have **empty lines** without comma separators for visual purposes
### Basic
It is implied that 3 columns inside CSV should represent `source`, `target` and `value` accordingly:
```mermaid-example
sankey-beta
%% source,target,value
Electricity grid,Over generation / exports,104.453
Electricity grid,Heating and cooling - homes,113.726
Electricity grid,H2 conversion,27.14
```
```mermaid
sankey-beta
%% source,target,value
Electricity grid,Over generation / exports,104.453
Electricity grid,Heating and cooling - homes,113.726
Electricity grid,H2 conversion,27.14
```
### Empty Lines
CSV does not support empty lines without comma delimeters by default. But you can add them if needed:
```mermaid-example
sankey-beta
Bio-conversion,Losses,26.862
Bio-conversion,Solid,280.322
Bio-conversion,Gas,81.144
```
```mermaid
sankey-beta
Bio-conversion,Losses,26.862
Bio-conversion,Solid,280.322
Bio-conversion,Gas,81.144
```
### Commas
If you need to have a comma, wrap it in double quotes:
```mermaid-example
sankey-beta
Pumped heat,"Heating and cooling, homes",193.026
Pumped heat,"Heating and cooling, commercial",70.672
```
```mermaid
sankey-beta
Pumped heat,"Heating and cooling, homes",193.026
Pumped heat,"Heating and cooling, commercial",70.672
```
### Double Quotes
If you need to have double quote, put a pair of them inside quoted string:
```mermaid-example
sankey-beta
Pumped heat,"Heating and cooling, ""homes""",193.026
Pumped heat,"Heating and cooling, ""commercial""",70.672
```
```mermaid
sankey-beta
Pumped heat,"Heating and cooling, ""homes""",193.026
Pumped heat,"Heating and cooling, ""commercial""",70.672
```
## Configuration
You can customize link colors, node alignments and diagram dimensions.
```html
<script>
const config = {
startOnLoad: true,
securityLevel: 'loose',
sankey: {
width: 800,
height: 400,
linkColor: 'source',
nodeAlignment: 'left',
},
};
mermaid.initialize(config);
</script>
```
### Links Coloring
You can adjust links' color by setting `linkColor` to one of those:
- `source` - link will be of a source node color
- `target` - link will be of a target node color
- `gradient` - link color will be smoothly transient between source and target node colors
- hex code of color, like `#a1a1a1`
### Node Alignment
Graph layout can be changed by setting `nodeAlignment` to:
- `justify`
- `center`
- `left`
- `right`

View File

@@ -94,6 +94,43 @@ sequenceDiagram
J->>A: Great!
```
### Actor Creation and Destruction (v10.3.0+)
It is possible to create and destroy actors by messages. To do so, add a create or destroy directive before the message.
create participant B
A --> B: Hello
Create directives support actor/participant distinction and aliases. The sender or the recipient of a message can be destroyed but only the recipient can be created.
```mermaid-example
sequenceDiagram
Alice->>Bob: Hello Bob, how are you ?
Bob->>Alice: Fine, thank you. And you?
create participant Carl
Alice->>Carl: Hi Carl!
create actor D as Donald
Carl->>D: Hi!
destroy Carl
Alice-xCarl: We are too many
destroy Bob
Bob->>Alice: I agree
```
```mermaid
sequenceDiagram
Alice->>Bob: Hello Bob, how are you ?
Bob->>Alice: Fine, thank you. And you?
create participant Carl
Alice->>Carl: Hi Carl!
create actor D as Donald
Carl->>D: Hi!
destroy Carl
Alice-xCarl: We are too many
destroy Bob
Bob->>Alice: I agree
```
### Grouping / Box
The actor(s) can be grouped in vertical boxes. You can define a color (if not, it will be transparent) and/or a descriptive label using the following notation:

View File

@@ -4,7 +4,7 @@
"version": "10.2.4",
"description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module",
"packageManager": "pnpm@8.6.5",
"packageManager": "pnpm@8.6.10",
"keywords": [
"diagram",
"markdown",
@@ -78,12 +78,12 @@
"@types/rollup-plugin-visualizer": "^4.2.1",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"@vitest/coverage-v8": "^0.32.2",
"@vitest/spy": "^0.32.2",
"@vitest/ui": "^0.32.2",
"@vitest/coverage-v8": "^0.33.0",
"@vitest/spy": "^0.33.0",
"@vitest/ui": "^0.33.0",
"ajv": "^8.12.0",
"concurrently": "^8.0.1",
"cors": "^2.8.5",
"coveralls": "^3.1.1",
"cypress": "^12.10.0",
"cypress-image-snapshot": "^4.0.1",
"esbuild": "^0.18.0",
@@ -119,10 +119,10 @@
"typescript": "^5.1.3",
"vite": "^4.3.9",
"vite-plugin-istanbul": "^4.1.0",
"vitest": "^0.32.2"
"vitest": "^0.33.0"
},
"volta": {
"node": "18.16.1"
"node": "18.17.0"
},
"nyc": {
"report-dir": "coverage/cypress"

View File

@@ -22,7 +22,6 @@ export const setInfo = (inf) => {
info = inf;
};
/** @returns Returns the info flag */
export const getInfo = () => {
return info;
};

View File

@@ -8,7 +8,6 @@ import { log, getConfig, setupGraphViewbox } from './mermaidUtils.js';
* @param {any} text
* @param {any} id
* @param {any} version
* @param diagObj
*/
export const draw = (text, id, version) => {
try {

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
const warning = (s: string) => {
// Todo remove debug code
// eslint-disable-next-line no-console
@@ -28,7 +29,6 @@ export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
export let getConfig: () => object;
export let sanitizeText: (str: string) => string;
export let commonDb: () => object;
// eslint-disable @typescript-eslint/no-explicit-any
export let setupGraphViewbox: (
graph: any,
svgElem: any,

View File

@@ -1,6 +1,6 @@
{
"name": "@mermaid-js/mermaid-zenuml",
"version": "0.1.0",
"version": "0.1.2",
"description": "MermaidJS plugin for ZenUML integration",
"module": "dist/mermaid-zenuml.core.mjs",
"types": "dist/detector.d.ts",
@@ -33,7 +33,7 @@
],
"license": "MIT",
"dependencies": {
"@zenuml/core": "^3.0.0"
"@zenuml/core": "^3.0.3"
},
"devDependencies": {
"mermaid": "workspace:^"

View File

@@ -4,4 +4,5 @@ export default {
'src/docs/**': ['pnpm --filter mermaid run docs:build --git'],
'src/docs.mts': ['pnpm --filter mermaid run docs:build --git'],
'src/(defaultConfig|config|mermaidAPI).ts': ['pnpm --filter mermaid run docs:build --git'],
'src/schemas/config.schema.yaml': ['pnpm --filter mermaid run types:build-config --git'],
};

View File

@@ -1,6 +1,6 @@
{
"name": "mermaid",
"version": "10.2.4",
"version": "10.3.0",
"description": "Markdown-ish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
"type": "module",
"module": "./dist/mermaid.core.mjs",
@@ -25,13 +25,18 @@
"scripts": {
"clean": "rimraf dist",
"docs:code": "typedoc src/defaultConfig.ts src/config.ts src/mermaidAPI.ts && prettier --write ./src/docs/config/setup",
"docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts",
"docs:verify": "pnpm docs:spellcheck && pnpm docs:code && ts-node-esm src/docs.mts --verify",
"docs:pre:vitepress": "rimraf src/vitepress && pnpm docs:code && ts-node-esm src/docs.mts --vitepress",
"docs:build:vitepress": "pnpm docs:pre:vitepress && (cd src/vitepress && pnpm --filter ./ install --no-frozen-lockfile --ignore-scripts && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing",
"docs:dev": "pnpm docs:pre:vitepress && concurrently \"pnpm --filter ./ src/vitepress dev\" \"ts-node-esm src/docs.mts --watch --vitepress\"",
"docs:build": "rimraf ../../docs && pnpm docs:spellcheck && pnpm docs:code && ts-node-esm scripts/docs.cli.mts",
"docs:verify": "pnpm docs:spellcheck && pnpm docs:code && ts-node-esm scripts/docs.cli.mts --verify",
"docs:pre:vitepress": "pnpm --filter ./src/docs prefetch && rimraf src/vitepress && pnpm docs:code && ts-node-esm scripts/docs.cli.mts --vitepress && pnpm --filter ./src/vitepress install --no-frozen-lockfile --ignore-scripts",
"docs:build:vitepress": "pnpm docs:pre:vitepress && (cd src/vitepress && pnpm run build) && cpy --flat src/docs/landing/ ./src/vitepress/.vitepress/dist/landing",
"docs:dev": "pnpm docs:pre:vitepress && concurrently \"pnpm --filter ./src/vitepress dev\" \"ts-node-esm scripts/docs.cli.mts --watch --vitepress\"",
"docs:dev:docker": "pnpm docs:pre:vitepress && concurrently \"pnpm --filter ./src/vitepress dev:docker\" \"ts-node-esm scripts/docs.cli.mts --watch --vitepress\"",
"docs:serve": "pnpm docs:build:vitepress && vitepress serve src/vitepress",
"docs:spellcheck": "cspell --config ../../cSpell.json \"src/docs/**/*.md\"",
"docs:release-version": "ts-node-esm scripts/update-release-version.mts",
"docs:verify-version": "ts-node-esm scripts/update-release-version.mts --verify",
"types:build-config": "ts-node-esm --transpileOnly scripts/create-types-from-json-schema.mts",
"types:verify-config": "ts-node-esm scripts/create-types-from-json-schema.mts --verify",
"release": "pnpm build",
"prepublishOnly": "cpy '../../README.*' ./ --cwd=. && pnpm -w run build"
},
@@ -53,13 +58,16 @@
},
"dependencies": {
"@braintree/sanitize-url": "^6.0.2",
"@types/d3-scale": "^4.0.3",
"@types/d3-scale-chromatic": "^3.0.0",
"cytoscape": "^3.23.0",
"cytoscape-cose-bilkent": "^4.1.0",
"cytoscape-fcose": "^2.1.0",
"d3": "^7.4.0",
"d3-sankey": "^0.12.3",
"dagre-d3-es": "7.0.10",
"dayjs": "^1.11.7",
"dompurify": "3.0.3",
"dompurify": "3.0.5",
"elkjs": "^0.8.2",
"khroma": "^2.0.0",
"lodash-es": "^4.17.21",
@@ -71,8 +79,10 @@
"web-worker": "^1.2.0"
},
"devDependencies": {
"@adobe/jsonschema2md": "^7.1.4",
"@types/cytoscape": "^3.19.9",
"@types/d3": "^7.4.0",
"@types/d3-sankey": "^0.12.1",
"@types/d3-selection": "^3.0.5",
"@types/dompurify": "^3.0.2",
"@types/jsdom": "^21.1.1",
@@ -83,9 +93,9 @@
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^5.59.0",
"@typescript-eslint/parser": "^5.59.0",
"ajv": "^8.11.2",
"chokidar": "^3.5.3",
"concurrently": "^8.0.1",
"coveralls": "^3.1.1",
"cpy-cli": "^4.2.0",
"cspell": "^6.31.1",
"csstree-validator": "^3.0.0",
@@ -93,6 +103,7 @@
"jison": "^0.4.18",
"js-base64": "^3.7.5",
"jsdom": "^22.0.0",
"json-schema-to-typescript": "^11.0.3",
"micromatch": "^4.0.5",
"path-browserify": "^1.0.1",
"prettier": "^2.8.8",
@@ -105,6 +116,7 @@
"typedoc-plugin-markdown": "^3.15.2",
"typescript": "^5.0.4",
"unist-util-flatmap": "^1.0.0",
"unist-util-visit": "^4.1.2",
"vitepress": "^1.0.0-alpha.72",
"vitepress-plugin-search": "^1.0.4-alpha.20"
},

View File

@@ -0,0 +1,252 @@
/**
* Script to load Mermaid Config JSON Schema from YAML and to:
*
* - Validate JSON Schema
*
* Then to generate:
*
* - config.types.ts TypeScript file
*/
/* eslint-disable no-console */
import { readFile, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import assert from 'node:assert';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { load, JSON_SCHEMA } from 'js-yaml';
import { compile, type JSONSchema } from 'json-schema-to-typescript';
import _Ajv2019, { type JSONSchemaType } from 'ajv/dist/2019.js';
// Workaround for wrong AJV types, see
// https://github.com/ajv-validator/ajv/issues/2132#issuecomment-1290409907
const Ajv2019 = _Ajv2019 as unknown as typeof _Ajv2019.default;
// !!! -- The config.type.js file is created by this script -- !!!
import type { MermaidConfig } from '../src/config.type.js';
// options for running the main command
const verifyOnly = process.argv.includes('--verify');
/** If `true`, automatically `git add` any changes (i.e. during `pnpm run pre-commit`)*/
const git = process.argv.includes('--git');
/**
* All of the keys in the mermaid config that have a mermaid diagram config.
*/
const MERMAID_CONFIG_DIAGRAM_KEYS = [
'flowchart',
'sequence',
'gantt',
'journey',
'class',
'state',
'er',
'pie',
'quadrantChart',
'requirement',
'mindmap',
'timeline',
'gitGraph',
'c4',
'sankey',
];
/**
* Loads the MermaidConfig JSON schema YAML file.
*
* @returns The loaded JSON Schema, use {@link validateSchema} to confirm it is a valid JSON Schema.
*/
async function loadJsonSchemaFromYaml() {
const configSchemaFile = join('src', 'schemas', 'config.schema.yaml');
const contentsYaml = await readFile(configSchemaFile, { encoding: 'utf8' });
const jsonSchema = load(contentsYaml, {
filename: configSchemaFile,
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
schema: JSON_SCHEMA,
});
return jsonSchema;
}
/**
* Asserts that the given value is a valid JSON Schema object.
*
* @param jsonSchema - The value to validate as JSON Schema 2019-09
* @throws {Error} if the given object is invalid.
*/
function validateSchema(jsonSchema: unknown): asserts jsonSchema is JSONSchemaType<MermaidConfig> {
if (typeof jsonSchema !== 'object') {
throw new Error(`jsonSchema param is not an object: actual type is ${typeof jsonSchema}`);
}
if (jsonSchema === null) {
throw new Error('jsonSchema param must not be null');
}
const ajv = new Ajv2019({
allErrors: true,
allowUnionTypes: true,
strict: true,
});
ajv.addKeyword({
keyword: 'meta:enum', // used by jsonschema2md (in docs.mts script)
errors: false,
});
ajv.addKeyword({
keyword: 'tsType', // used by json-schema-to-typescript
errors: false,
});
ajv.compile(jsonSchema);
}
/**
* Generate a typescript definition from a JSON Schema using json-schema-to-typescript.
*
* @param mermaidConfigSchema - The input JSON Schema.
*/
async function generateTypescript(mermaidConfigSchema: JSONSchemaType<MermaidConfig>) {
/**
* Replace all usages of `allOf` with `extends`.
*
* `extends` is only valid JSON Schema in very old versions of JSON Schema.
* However, json-schema-to-typescript creates much nicer types when using
* `extends`, so we should use them instead when possible.
*
* @param schema - The input schema.
* @returns The schema with `allOf` replaced with `extends`.
*/
function replaceAllOfWithExtends(schema: JSONSchemaType<Record<string, any>>) {
if (schema['allOf']) {
const { allOf, ...schemaWithoutAllOf } = schema;
return {
...schemaWithoutAllOf,
extends: allOf,
};
}
return schema;
}
/**
* For backwards compatibility with older Mermaid Typescript defs,
* we need to make all value optional instead of required.
*
* This is because the `MermaidConfig` type is used as an input, and everything is optional,
* since all the required values have default values.s
*
* In the future, we should make make the input to Mermaid `Partial<MermaidConfig>`.
*
* @todo TODO: Remove this function when Mermaid releases a new breaking change.
* @param schema - The input schema.
* @returns The schema with all required values removed.
*/
function removeRequired(schema: JSONSchemaType<Record<string, any>>) {
return { ...schema, required: [] };
}
/**
* This is a temporary hack to control the order the types are generated in.
*
* By default, json-schema-to-typescript outputs the $defs in the order they
* are used, then any unused schemas at the end.
*
* **The only purpose of this function is to make the `git diff` simpler**
* **We should remove this later to simplify the code**
*
* @todo TODO: Remove this function in a future PR.
* @param schema - The input schema.
* @returns The schema with all `$ref`s removed.
*/
function unrefSubschemas(schema: JSONSchemaType<Record<string, any>>) {
return {
...schema,
properties: Object.fromEntries(
Object.entries(schema.properties).map(([key, propertySchema]) => {
if (MERMAID_CONFIG_DIAGRAM_KEYS.includes(key)) {
const { $ref, ...propertySchemaWithoutRef } = propertySchema as JSONSchemaType<unknown>;
if ($ref === undefined) {
throw Error(
`subSchema ${key} is in MERMAID_CONFIG_DIAGRAM_KEYS but does not have a $ref field`
);
}
const [
_root, // eslint-disable-line @typescript-eslint/no-unused-vars
_defs, // eslint-disable-line @typescript-eslint/no-unused-vars
defName,
] = $ref.split('/');
return [
key,
{
...propertySchemaWithoutRef,
tsType: defName,
},
];
}
return [key, propertySchema];
})
),
};
}
assert.ok(mermaidConfigSchema.$defs);
const modifiedSchema = {
...unrefSubschemas(removeRequired(mermaidConfigSchema)),
$defs: Object.fromEntries(
Object.entries(mermaidConfigSchema.$defs).map(([key, subSchema]) => {
return [key, removeRequired(replaceAllOfWithExtends(subSchema))];
})
),
};
const typescriptFile = await compile(
modifiedSchema as JSONSchema, // json-schema-to-typescript only allows JSON Schema 4 as input type
'MermaidConfig',
{
additionalProperties: false, // in JSON Schema 2019-09, these are called `unevaluatedProperties`
unreachableDefinitions: true, // definition for FontConfig is unreachable
}
);
// TODO, should we somehow use the functions from `docs.mts` instead?
if (verifyOnly) {
const originalFile = await readFile('./src/config.type.ts', { encoding: 'utf-8' });
if (typescriptFile !== originalFile) {
console.error('❌ Error: ./src/config.type.ts will be changed.');
console.error("Please run 'pnpm run --filter mermaid types:build-config' to update this");
process.exitCode = 1;
} else {
console.log('✅ ./src/config.type.ts will be unchanged');
}
} else {
console.log('Writing typescript file to ./src/config.type.ts');
await writeFile('./src/config.type.ts', typescriptFile, { encoding: 'utf8' });
if (git) {
console.log('📧 Git: Adding ./src/config.type.ts changed');
await promisify(execFile)('git', ['add', './src/config.type.ts']);
}
}
}
/** Main function */
async function main() {
if (verifyOnly) {
console.log(
'Verifying that ./src/config.type.ts is in sync with src/schemas/config.schema.yaml'
);
}
const configJsonSchema = await loadJsonSchemaFromYaml();
validateSchema(configJsonSchema);
// Generate types from JSON Schema
await generateTypescript(configJsonSchema);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

View File

@@ -0,0 +1,3 @@
import { processDocs } from './docs.mjs';
void processDocs();

View File

@@ -27,14 +27,21 @@
* get their absolute paths. Ensures that the location of those 2 directories is not dependent on
* where this file resides.
*
* @todo Write a test file for this. (Will need to be able to deal .mts file. Jest has trouble with
* it.)
*/
// @ts-ignore: we're importing internal jsonschema2md functions
import { default as schemaLoader } from '@adobe/jsonschema2md/lib/schemaProxy.js';
// @ts-ignore: we're importing internal jsonschema2md functions
import { default as traverseSchemas } from '@adobe/jsonschema2md/lib/traverseSchema.js';
// @ts-ignore: we're importing internal jsonschema2md functions
import { default as buildMarkdownFromSchema } from '@adobe/jsonschema2md/lib/markdownBuilder.js';
// @ts-ignore: we're importing internal jsonschema2md functions
import { default as jsonSchemaReadmeBuilder } from '@adobe/jsonschema2md/lib/readmeBuilder.js';
import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync, rmdirSync } from 'fs';
import { exec } from 'child_process';
import { globby } from 'globby';
import { JSDOM } from 'jsdom';
import type { Code, Root } from 'mdast';
import { dump, load, JSON_SCHEMA } from 'js-yaml';
import type { Code, ListItem, Root, Text, YAML } from 'mdast';
import { posix, dirname, relative, join } from 'path';
import prettier from 'prettier';
import { remark } from 'remark';
@@ -44,10 +51,11 @@ import chokidar from 'chokidar';
import mm from 'micromatch';
// @ts-ignore No typescript declaration file
import flatmap from 'unist-util-flatmap';
import { visit } from 'unist-util-visit';
const MERMAID_MAJOR_VERSION = (
JSON.parse(readFileSync('../mermaid/package.json', 'utf8')).version as string
).split('.')[0];
export const MERMAID_RELEASE_VERSION = JSON.parse(readFileSync('../mermaid/package.json', 'utf8'))
.version as string;
const MERMAID_MAJOR_VERSION = MERMAID_RELEASE_VERSION.split('.')[0];
const CDN_URL = 'https://cdn.jsdelivr.net/npm'; // 'https://unpkg.com';
const MERMAID_KEYWORD = 'mermaid';
@@ -70,7 +78,7 @@ const vitepress: boolean = process.argv.includes('--vitepress');
const noHeader: boolean = process.argv.includes('--noHeader') || vitepress;
// These paths are from the root of the mono-repo, not from the mermaid subdirectory
const SOURCE_DOCS_DIR = 'src/docs';
export const SOURCE_DOCS_DIR = 'src/docs';
const FINAL_DOCS_DIR = vitepress ? 'src/vitepress' : '../../docs';
const LOGMSG_TRANSFORMED = 'transformed';
@@ -122,7 +130,7 @@ const changeToFinalDocDir = (file: string): string => {
const logWasOrShouldBeTransformed = (filename: string, wasCopied: boolean) => {
const changeMsg = wasCopied ? LOGMSG_TRANSFORMED : LOGMSG_TO_BE_TRANSFORMED;
let logMsg: string;
logMsg = ` File ${changeMsg}: ${filename}`;
logMsg = ` File ${changeMsg}: ${filename.replace(FINAL_DOCS_DIR, SOURCE_DOCS_DIR)}`;
if (wasCopied) {
logMsg += LOGMSG_COPIED;
}
@@ -150,13 +158,14 @@ const copyTransformedContents = (filename: string, doCopy = false, transformedCo
}
filesTransformed.add(fileInFinalDocDir);
if (doCopy) {
writeFileSync(fileInFinalDocDir, newBuffer);
}
logWasOrShouldBeTransformed(fileInFinalDocDir, doCopy);
};
const readSyncedUTF8file = (filename: string): string => {
export const readSyncedUTF8file = (filename: string): string => {
return readFileSync(filename, 'utf8');
};
@@ -207,6 +216,8 @@ interface TransformMarkdownAstOptions {
originalFilename: string;
/** If `true`, add a warning that the file is autogenerated */
addAutogeneratedWarning?: boolean;
/** If `true`, adds an `editLink: "https://..."` YAML frontmatter field */
addEditLink?: boolean;
/**
* If `true`, remove the YAML metadata from the Markdown input.
* Generally, YAML metadata is only used for Vitepress.
@@ -229,6 +240,7 @@ interface TransformMarkdownAstOptions {
export function transformMarkdownAst({
originalFilename,
addAutogeneratedWarning,
addEditLink,
removeYAML,
}: TransformMarkdownAstOptions) {
return (tree: Root, _file?: any): Root => {
@@ -268,6 +280,27 @@ export function transformMarkdownAst({
}
}
if (addEditLink) {
// add originalFilename as custom editLink in YAML frontmatter
let yamlFrontMatter: YAML;
if (astWithTransformedBlocks.children[0].type === 'yaml') {
yamlFrontMatter = astWithTransformedBlocks.children[0];
} else {
yamlFrontMatter = {
type: 'yaml',
value: '',
};
astWithTransformedBlocks.children.unshift(yamlFrontMatter);
}
const filePathFromRoot = posix.join('packages/mermaid', originalFilename);
yamlFrontMatter.value = dump({
...(load(yamlFrontMatter.value, { schema: JSON_SCHEMA }) as
| Record<string, unknown>
| undefined),
editLink: `https://github.com/mermaid-js/mermaid/edit/develop/${filePathFromRoot}`,
});
}
if (removeYAML) {
const firstNode = astWithTransformedBlocks.children[0];
if (firstNode.type == 'yaml') {
@@ -304,6 +337,7 @@ const transformMarkdown = (file: string) => {
// mermaid project specific plugin
originalFilename: file,
addAutogeneratedWarning: !noHeader,
addEditLink: noHeader,
removeYAML: !noHeader,
})
.processSync(doc)
@@ -321,6 +355,115 @@ const transformMarkdown = (file: string) => {
copyTransformedContents(file, !verifyOnly, formatted);
};
/**
* Transforms the given JSON Schema into Markdown documentation
*/
async function transformJsonSchema(file: string) {
const yamlContents = readSyncedUTF8file(file);
const jsonSchema = load(yamlContents, {
filename: file,
// only allow JSON types in our YAML doc (will probably be default in YAML 1.3)
// e.g. `true` will be parsed a boolean `true`, `True` will be parsed as string `"True"`.
schema: JSON_SCHEMA,
});
/** Location of the `schema.yaml` files */
const SCHEMA_INPUT_DIR = 'src/schemas/';
/**
* Location to store the generated `schema.json` file for the website
*
* Because Vitepress doesn't handle bundling `.json` files properly, we need
* to instead place it into a `public/` subdirectory.
*/
const SCHEMA_OUTPUT_DIR = 'src/docs/public/schemas/';
const VITEPRESS_PUBLIC_DIR = 'src/docs/public';
/**
* Location to store the generated Schema Markdown docs.
* Links to JSON Schemas should automatically be rewritten to point to
* `SCHEMA_OUTPUT_DIR`.
*/
const SCHEMA_MARKDOWN_OUTPUT_DIR = join('src', 'docs', 'config', 'schema-docs');
// write .schema.json files
const jsonFileName = file
.replace('.schema.yaml', '.schema.json')
.replace(SCHEMA_INPUT_DIR, SCHEMA_OUTPUT_DIR);
copyTransformedContents(jsonFileName, !verifyOnly, JSON.stringify(jsonSchema, undefined, 2));
const schemas = traverseSchemas([schemaLoader()(jsonFileName, jsonSchema)]);
// ignore output of this function
// for some reason, without calling this function, we get some broken links
// this is probably a bug in @adobe/jsonschema2md
jsonSchemaReadmeBuilder({ readme: true })(schemas);
// write Markdown files
const markdownFiles = buildMarkdownFromSchema({
header: true,
// links,
includeProperties: ['tsType'], // Custom TypeScript type
exampleFormat: 'json',
// skipProperties,
/**
* Automatically rewrite schema paths passed to `schemaLoader`
* (e.g. src/docs/schemas/config.schema.json)
* to relative links (e.g. /schemas/config.schema.json)
*
* See https://vitepress.vuejs.org/guide/asset-handling
*
* @param origin - Original schema path (relative to this script).
* @returns New absolute Vitepress path to schema
*/
rewritelinks: (origin: string) => {
return `/${relative(VITEPRESS_PUBLIC_DIR, origin)}`;
},
})(schemas);
for (const [name, markdownAst] of Object.entries(markdownFiles)) {
/*
* Converts list entries of shape '- tsType: () => Partial<FontConfig>'
* into '- tsType: `() => Partial<FontConfig>`' (e.g. escaping with back-ticks),
* as otherwise VitePress doesn't like the <FontConfig> bit.
*/
visit(markdownAst as Root, 'listItem', (listEntry: ListItem) => {
let listText: Text;
const blockItem = listEntry.children[0];
if (blockItem.type === 'paragraph' && blockItem.children[0].type === 'text') {
listText = blockItem.children[0];
} // @ts-expect-error: MD AST output from @adobe/jsonschema2md is technically wrong
else if (blockItem.type === 'text') {
listText = blockItem;
} else {
return; // skip
}
if (listText.value.startsWith('tsType: ')) {
listText.value = listText.value.replace(/tsType: (.*)/g, 'tsType: `$1`');
}
});
const transformer = remark()
.use(remarkGfm)
.use(remarkFrontmatter, ['yaml']) // support YAML front-matter in Markdown
.use(transformMarkdownAst, {
// mermaid project specific plugin
originalFilename: file,
addAutogeneratedWarning: !noHeader,
addEditLink: noHeader,
removeYAML: !noHeader,
});
const transformed = transformer.stringify(await transformer.run(markdownAst as Root));
const formatted = prettier.format(transformed, {
parser: 'markdown',
...prettierConfig,
});
const newFileName = join(SCHEMA_MARKDOWN_OUTPUT_DIR, `${name}.md`);
copyTransformedContents(newFileName, !verifyOnly, formatted);
}
}
/**
* Transform an HTML file and write the transformed file to the directory for published
* documentation
@@ -361,26 +504,26 @@ const transformHtml = (filename: string) => {
copyTransformedContents(filename, !verifyOnly, formattedHTML);
};
const getGlobs = (globs: string[]): string[] => {
globs.push(
'!**/dist',
'!**/redirect.spec.ts',
'!**/landing',
'!**/node_modules',
'!**/user-avatars'
);
export const getGlobs = (globs: string[]): string[] => {
globs.push('!**/dist/**', '!**/redirect.spec.ts', '!**/landing/**', '!**/node_modules/**');
if (!vitepress) {
globs.push('!**/.vitepress', '!**/vite.config.ts', '!src/docs/index.md', '!**/package.json');
globs.push(
'!**/.vitepress/**',
'!**/vite.config.ts',
'!src/docs/index.md',
'!**/package.json',
'!**/user-avatars/**'
);
}
return globs;
};
const getFilesFromGlobs = async (globs: string[]): Promise<string[]> => {
export const getFilesFromGlobs = async (globs: string[]): Promise<string[]> => {
return await globby(globs, { dot: true });
};
/** Main method (entry point) */
const main = async () => {
export const processDocs = async () => {
if (verifyOnly) {
console.log('Verifying that all files are in sync with the source files');
}
@@ -388,6 +531,14 @@ const main = async () => {
const sourceDirGlob = posix.join('.', SOURCE_DOCS_DIR, '**');
const action = verifyOnly ? 'Verifying' : 'Transforming';
if (vitepress) {
console.log(`${action} 1 .schema.yaml file`);
await transformJsonSchema('src/schemas/config.schema.yaml');
} else {
// skip because this creates so many Markdown files that it lags git
console.log('Skipping 1 .schema.yaml file');
}
const mdFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.md')]);
const mdFiles = await getFilesFromGlobs(mdFileGlobs);
console.log(`${action} ${mdFiles.length} markdown files...`);
@@ -450,5 +601,3 @@ const main = async () => {
});
}
};
void main();

View File

@@ -105,6 +105,29 @@ This Markdown should be kept.
});
});
it('should add an editLink in the YAML frontmatter if `addEditLink: true`', async () => {
const contents = `---
title: Flowcharts Syntax
---
This Markdown should be kept.
`;
const withYaml = (
await remarkBuilder()
.use(transformMarkdownAst, { originalFilename, addEditLink: true })
.process(contents)
).toString();
expect(withYaml).toEqual(`---
title: Flowcharts Syntax
editLink: >-
https://github.com/mermaid-js/mermaid/edit/develop/packages/mermaid/example-input-filename.md
---
This Markdown should be kept.
`);
});
describe('transformToBlockQuote', () => {
// TODO Is there a way to test this with --vitepress given as a process argument?

View File

@@ -0,0 +1,53 @@
/* eslint-disable no-console */
/**
* @file Update the MERMAID_RELEASE_VERSION placeholder in the documentation source files with the current version of mermaid.
* So contributors adding new features will only have to add the placeholder and not worry about updating the version number.
*
*/
import { posix } from 'path';
import {
getGlobs,
getFilesFromGlobs,
SOURCE_DOCS_DIR,
readSyncedUTF8file,
MERMAID_RELEASE_VERSION,
} from './docs.mjs';
import { writeFile } from 'fs/promises';
const verifyOnly: boolean = process.argv.includes('--verify');
const versionPlaceholder = '<MERMAID_RELEASE_VERSION>';
const main = async () => {
const sourceDirGlob = posix.join('.', SOURCE_DOCS_DIR, '**');
const mdFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.md')]);
mdFileGlobs.push('!**/community/development.md');
const mdFiles = await getFilesFromGlobs(mdFileGlobs);
mdFiles.sort();
const mdFilesWithPlaceholder: string[] = [];
for (const mdFile of mdFiles) {
const content = readSyncedUTF8file(mdFile);
if (content.includes(versionPlaceholder)) {
mdFilesWithPlaceholder.push(mdFile);
}
}
if (mdFilesWithPlaceholder.length === 0) {
return;
}
if (verifyOnly) {
console.log(
`${mdFilesWithPlaceholder.length} file(s) were found with the placeholder ${versionPlaceholder}. Run \`pnpm --filter mermaid docs:release-version\` to update them.`
);
process.exit(1);
}
for (const mdFile of mdFilesWithPlaceholder) {
const content = readSyncedUTF8file(mdFile);
const newContent = content.replace(versionPlaceholder, MERMAID_RELEASE_VERSION);
await writeFile(mdFile, newContent);
}
};
void main();

View File

@@ -1,27 +1,24 @@
import { MockedD3 } from './tests/MockedD3.js';
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js';
import { D3Element } from './mermaidAPI.js';
import type { D3Element } from './mermaidAPI.js';
describe('accessibility', () => {
const fauxSvgNode = new MockedD3();
const fauxSvgNode: MockedD3 = new MockedD3();
describe('setA11yDiagramInfo', () => {
it('sets the svg element role to "graphics-document document"', () => {
// @ts-ignore Required to easily handle the d3 select types
it('should set svg element role to "graphics-document document"', () => {
const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
setA11yDiagramInfo(fauxSvgNode, 'flowchart');
expect(svgAttrSpy).toHaveBeenCalledWith('role', 'graphics-document document');
});
it('sets the aria-roledescription to the diagram type', () => {
// @ts-ignore Required to easily handle the d3 select types
it('should set aria-roledescription to the diagram type', () => {
const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
setA11yDiagramInfo(fauxSvgNode, 'flowchart');
expect(svgAttrSpy).toHaveBeenCalledWith('aria-roledescription', 'flowchart');
});
it('does not set the aria-roledescription if the diagram type is empty', () => {
// @ts-ignore Required to easily handle the d3 select types
it('should not set aria-roledescription if the diagram type is empty', () => {
const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
setA11yDiagramInfo(fauxSvgNode, '');
expect(svgAttrSpy).toHaveBeenCalledTimes(1);
@@ -32,8 +29,8 @@ describe('accessibility', () => {
describe('addSVGa11yTitleDescription', () => {
const givenId = 'theBaseId';
describe('with the given svg d3 object:', () => {
it('does nothing if there is no insert defined', () => {
describe('with svg d3 object', () => {
it('should do nothing if there is no insert defined', () => {
const noInsertSvg = {
attr: vi.fn(),
};
@@ -42,26 +39,25 @@ describe('accessibility', () => {
expect(noInsertAttrSpy).not.toHaveBeenCalled();
});
// ----------------
// Convenience functions to DRY up the spec
// convenience functions to DRY up the spec
function expectAriaLabelledByIsTitleId(
function expectAriaLabelledByItTitleId(
svgD3Node: D3Element,
title: string | null | undefined,
desc: string | null | undefined,
title: string | undefined,
desc: string | undefined,
givenId: string
) {
): void {
const svgAttrSpy = vi.spyOn(svgD3Node, 'attr').mockReturnValue(svgD3Node);
addSVGa11yTitleDescription(svgD3Node, title, desc, givenId);
expect(svgAttrSpy).toHaveBeenCalledWith('aria-labelledby', `chart-title-${givenId}`);
}
function expectAriaDescribedByIsDescId(
function expectAriaDescribedByItDescId(
svgD3Node: D3Element,
title: string | null | undefined,
desc: string | null | undefined,
title: string | undefined,
desc: string | undefined,
givenId: string
) {
): void {
const svgAttrSpy = vi.spyOn(svgD3Node, 'attr').mockReturnValue(svgD3Node);
addSVGa11yTitleDescription(svgD3Node, title, desc, givenId);
expect(svgAttrSpy).toHaveBeenCalledWith('aria-describedby', `chart-desc-${givenId}`);
@@ -69,154 +65,148 @@ describe('accessibility', () => {
function a11yTitleTagInserted(
svgD3Node: D3Element,
title: string | null | undefined,
desc: string | null | undefined,
title: string | undefined,
desc: string | undefined,
givenId: string,
callNumber: number
) {
): void {
a11yTagInserted(svgD3Node, title, desc, givenId, callNumber, 'title', title);
}
function a11yDescTagInserted(
svgD3Node: D3Element,
title: string | null | undefined,
desc: string | null | undefined,
title: string | undefined,
desc: string | undefined,
givenId: string,
callNumber: number
) {
): void {
a11yTagInserted(svgD3Node, title, desc, givenId, callNumber, 'desc', desc);
}
function a11yTagInserted(
svgD3Node: D3Element,
title: string | null | undefined,
desc: string | null | undefined,
_svgD3Node: D3Element,
title: string | undefined,
desc: string | undefined,
givenId: string,
callNumber: number,
expectedPrefix: string,
expectedText: string | null | undefined
) {
const fauxInsertedD3 = new MockedD3();
const svgInsertSpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxInsertedD3);
// @ts-ignore Required to easily handle the d3 select types
expectedText: string | undefined
): void {
const fauxInsertedD3: MockedD3 = new MockedD3();
const svginsertpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxInsertedD3);
const titleAttrSpy = vi.spyOn(fauxInsertedD3, 'attr').mockReturnValue(fauxInsertedD3);
const titleTextSpy = vi.spyOn(fauxInsertedD3, 'text');
addSVGa11yTitleDescription(fauxSvgNode, title, desc, givenId);
expect(svgInsertSpy).toHaveBeenCalledWith(expectedPrefix, ':first-child');
expect(svginsertpy).toHaveBeenCalledWith(expectedPrefix, ':first-child');
expect(titleAttrSpy).toHaveBeenCalledWith('id', `chart-${expectedPrefix}-${givenId}`);
expect(titleTextSpy).toHaveBeenNthCalledWith(callNumber, expectedText);
}
// ----------------
describe('given an a11y title', () => {
describe('with a11y title', () => {
const a11yTitle = 'a11y title';
describe('given an a11y description', () => {
describe('with a11y description', () => {
const a11yDesc = 'a11y description';
it('sets aria-labelledby to the title id inserted as a child', () => {
expectAriaLabelledByIsTitleId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
it('shold set aria-labelledby to the title id inserted as a child', () => {
expectAriaLabelledByItTitleId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
});
it('sets aria-describedby to the description id inserted as a child', () => {
expectAriaDescribedByIsDescId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
it('should set aria-describedby to the description id inserted as a child', () => {
expectAriaDescribedByItDescId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
});
it('inserts a title tag as the first child with the text set to the accTitle given', () => {
it('should insert title tag as the first child with the text set to the accTitle given', () => {
a11yTitleTagInserted(fauxSvgNode, a11yTitle, a11yDesc, givenId, 2);
});
it('inserts a desc tag as the 2nd child with the text set to accDescription given', () => {
it('should insert desc tag as the 2nd child with the text set to accDescription given', () => {
a11yDescTagInserted(fauxSvgNode, a11yTitle, a11yDesc, givenId, 1);
});
});
describe(`no a11y description`, () => {
describe(`without a11y description`, () => {
const a11yDesc = undefined;
it('sets aria-labelledby to the title id inserted as a child', () => {
expectAriaLabelledByIsTitleId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
it('should set aria-labelledby to the title id inserted as a child', () => {
expectAriaLabelledByItTitleId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
});
it('no aria-describedby is set', () => {
// @ts-ignore Required to easily handle the d3 select types
it('should not set aria-describedby', () => {
const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgAttrSpy).not.toHaveBeenCalledWith('aria-describedby', expect.anything());
});
it('inserts a title tag as the first child with the text set to the accTitle given', () => {
it('should insert title tag as the first child with the text set to the accTitle given', () => {
a11yTitleTagInserted(fauxSvgNode, a11yTitle, a11yDesc, givenId, 1);
});
it('no description tag is inserted', () => {
const fauxTitle = new MockedD3();
const svgInsertSpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxTitle);
it('should not insert description tag', () => {
const fauxTitle: MockedD3 = new MockedD3();
const svginsertpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxTitle);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgInsertSpy).not.toHaveBeenCalledWith('desc', ':first-child');
expect(svginsertpy).not.toHaveBeenCalledWith('desc', ':first-child');
});
});
});
describe('no a11y title', () => {
describe('without a11y title', () => {
const a11yTitle = undefined;
describe('given an a11y description', () => {
describe('with a11y description', () => {
const a11yDesc = 'a11y description';
it('no aria-labelledby is set', () => {
// @ts-ignore Required to easily handle the d3 select types
it('should not set aria-labelledby', () => {
const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgAttrSpy).not.toHaveBeenCalledWith('aria-labelledby', expect.anything());
});
it('no title tag inserted', () => {
const fauxTitle = new MockedD3();
const svgInsertSpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxTitle);
it('should not insert title tag', () => {
const fauxTitle: MockedD3 = new MockedD3();
const svginsertpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxTitle);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgInsertSpy).not.toHaveBeenCalledWith('title', ':first-child');
expect(svginsertpy).not.toHaveBeenCalledWith('title', ':first-child');
});
it('sets aria-describedby to the description id inserted as a child', () => {
expectAriaDescribedByIsDescId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
it('should set aria-describedby to the description id inserted as a child', () => {
expectAriaDescribedByItDescId(fauxSvgNode, a11yTitle, a11yDesc, givenId);
});
it('inserts a desc tag as the 2nd child with the text set to accDescription given', () => {
it('should insert desc tag as the 2nd child with the text set to accDescription given', () => {
a11yDescTagInserted(fauxSvgNode, a11yTitle, a11yDesc, givenId, 1);
});
});
describe('no a11y description', () => {
describe('without a11y description', () => {
const a11yDesc = undefined;
it('no aria-labelledby is set', () => {
// @ts-ignore Required to easily handle the d3 select types
it('should not set aria-labelledby', () => {
const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgAttrSpy).not.toHaveBeenCalledWith('aria-labelledby', expect.anything());
});
it('no aria-describedby is set', () => {
// @ts-ignore Required to easily handle the d3 select types
it('should not set aria-describedby', () => {
const svgAttrSpy = vi.spyOn(fauxSvgNode, 'attr').mockReturnValue(fauxSvgNode);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgAttrSpy).not.toHaveBeenCalledWith('aria-describedby', expect.anything());
});
it('no title tag inserted', () => {
const fauxTitle = new MockedD3();
const svgInsertSpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxTitle);
it('should not insert title tag', () => {
const fauxTitle: MockedD3 = new MockedD3();
const svginsertpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxTitle);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgInsertSpy).not.toHaveBeenCalledWith('title', ':first-child');
expect(svginsertpy).not.toHaveBeenCalledWith('title', ':first-child');
});
it('no description tag inserted', () => {
const fauxDesc = new MockedD3();
const svgInsertSpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxDesc);
it('should not insert description tag', () => {
const fauxDesc: MockedD3 = new MockedD3();
const svginsertpy = vi.spyOn(fauxSvgNode, 'insert').mockReturnValue(fauxDesc);
addSVGa11yTitleDescription(fauxSvgNode, a11yTitle, a11yDesc, givenId);
expect(svgInsertSpy).not.toHaveBeenCalledWith('desc', ':first-child');
expect(svginsertpy).not.toHaveBeenCalledWith('desc', ':first-child');
});
});
});

View File

@@ -1,13 +1,11 @@
/**
* Accessibility (a11y) functions, types, helpers
* Accessibility (a11y) functions, types, helpers.
*
* @see https://www.w3.org/WAI/
* @see https://www.w3.org/TR/wai-aria-1.1/
* @see https://www.w3.org/TR/svg-aam-1.0/
*
*/
import { D3Element } from './mermaidAPI.js';
import isEmpty from 'lodash-es/isEmpty.js';
import type { D3Element } from './mermaidAPI.js';
/**
* SVG element role:
@@ -21,50 +19,47 @@ import isEmpty from 'lodash-es/isEmpty.js';
const SVG_ROLE = 'graphics-document document';
/**
* Add role and aria-roledescription to the svg element
* Add role and aria-roledescription to the svg element.
*
* @param svg - d3 object that contains the SVG HTML element
* @param diagramType - diagram name for to the aria-roledescription
*/
export function setA11yDiagramInfo(svg: D3Element, diagramType: string | null | undefined) {
export function setA11yDiagramInfo(svg: D3Element, diagramType: string) {
svg.attr('role', SVG_ROLE);
if (!isEmpty(diagramType)) {
if (diagramType !== '') {
svg.attr('aria-roledescription', diagramType);
}
}
/**
* Add an accessible title and/or description element to a chart.
* The title is usually not displayed and the description is never displayed.
*
* The following charts display their title as a visual and accessibility element: gantt
* The following charts display their title as a visual and accessibility element: gantt.
*
* @param svg - d3 node to insert the a11y title and desc info
* @param a11yTitle - a11y title. null and undefined are meaningful: means to skip it
* @param a11yDesc - a11y description. null and undefined are meaningful: means to skip it
* @param a11yTitle - a11y title. undefined or empty strings mean to skip them
* @param a11yDesc - a11y description. undefined or empty strings mean to skip them
* @param baseId - id used to construct the a11y title and description id
*/
export function addSVGa11yTitleDescription(
svg: D3Element,
a11yTitle: string | null | undefined,
a11yDesc: string | null | undefined,
a11yTitle: string | undefined,
a11yDesc: string | undefined,
baseId: string
) {
): void {
if (svg.insert === undefined) {
return;
}
if (a11yTitle || a11yDesc) {
if (a11yDesc) {
const descId = 'chart-desc-' + baseId;
svg.attr('aria-describedby', descId);
svg.insert('desc', ':first-child').attr('id', descId).text(a11yDesc);
}
if (a11yTitle) {
const titleId = 'chart-title-' + baseId;
svg.attr('aria-labelledby', titleId);
svg.insert('title', ':first-child').attr('id', titleId).text(a11yTitle);
}
} else {
return;
if (a11yDesc) {
const descId = `chart-desc-${baseId}`;
svg.attr('aria-describedby', descId);
svg.insert('desc', ':first-child').attr('id', descId).text(a11yDesc);
}
if (a11yTitle) {
const titleId = `chart-title-${baseId}`;
svg.attr('aria-labelledby', titleId);
svg.insert('title', ':first-child').attr('id', titleId).text(a11yTitle);
}
}

View File

@@ -1,56 +0,0 @@
import * as configApi from './config.js';
describe('when working with site config', function () {
beforeEach(() => {
// Resets the site config to default config
configApi.setSiteConfig({});
});
it('should set site config and config properly', function () {
let config_0 = { foo: 'bar', bar: 0 };
configApi.setSiteConfig(config_0);
let config_1 = configApi.getSiteConfig();
let config_2 = configApi.getConfig();
expect(config_1.foo).toEqual(config_0.foo);
expect(config_1.bar).toEqual(config_0.bar);
expect(config_1).toEqual(config_2);
});
it('should respect secure keys when applying directives', function () {
let config_0 = {
foo: 'bar',
bar: 'cant-be-changed',
secure: [...configApi.defaultConfig.secure, 'bar'],
};
configApi.setSiteConfig(config_0);
const directive = { foo: 'baf', bar: 'should-not-be-allowed' };
const cfg = configApi.updateCurrentConfig(config_0, [directive]);
expect(cfg.foo).toEqual(directive.foo);
expect(cfg.bar).toBe(config_0.bar);
});
it('should set reset config properly', function () {
let config_0 = { foo: 'bar', bar: 0 };
configApi.setSiteConfig(config_0);
let config_1 = { foo: 'baf' };
configApi.setConfig(config_1);
let config_2 = configApi.getConfig();
expect(config_2.foo).toEqual(config_1.foo);
configApi.reset();
let config_3 = configApi.getConfig();
expect(config_3.foo).toEqual(config_0.foo);
let config_4 = configApi.getSiteConfig();
expect(config_4.foo).toEqual(config_0.foo);
});
it('should set global reset config properly', function () {
let config_0 = { foo: 'bar', bar: 0 };
configApi.setSiteConfig(config_0);
let config_1 = configApi.getSiteConfig();
expect(config_1.foo).toEqual(config_0.foo);
let config_2 = configApi.getConfig();
expect(config_2.foo).toEqual(config_0.foo);
configApi.setConfig({ foobar: 'bar0' });
let config_3 = configApi.getConfig();
expect(config_3.foobar).toEqual('bar0');
configApi.reset();
let config_4 = configApi.getConfig();
expect(config_4.foobar).toBeUndefined();
});
});

View File

@@ -0,0 +1,72 @@
import * as configApi from './config.js';
describe('when working with site config', function () {
beforeEach(() => {
// Resets the site config to default config
configApi.setSiteConfig({});
});
it('should set site config and config properly', function () {
const config_0 = { fontFamily: 'foo-font', fontSize: 150 };
configApi.setSiteConfig(config_0);
const config_1 = configApi.getSiteConfig();
const config_2 = configApi.getConfig();
expect(config_1.fontFamily).toEqual(config_0.fontFamily);
expect(config_1.fontSize).toEqual(config_0.fontSize);
expect(config_1).toEqual(config_2);
});
it('should respect secure keys when applying directives', function () {
const config_0 = {
fontFamily: 'foo-font',
fontSize: 12345, // can't be changed
secure: [...configApi.defaultConfig.secure!, 'fontSize'],
};
configApi.setSiteConfig(config_0);
const directive = { fontFamily: 'baf', fontSize: 54321 /* fontSize shouldn't be changed */ };
const cfg = configApi.updateCurrentConfig(config_0, [directive]);
expect(cfg.fontFamily).toEqual(directive.fontFamily);
expect(cfg.fontSize).toBe(config_0.fontSize);
});
it('should allow setting partial options', function () {
const defaultConfig = configApi.getConfig();
configApi.setConfig({
quadrantChart: {
chartHeight: 600,
},
});
const updatedConfig = configApi.getConfig();
// deep options we didn't update should remain the same
expect(defaultConfig.quadrantChart!.chartWidth).toEqual(
updatedConfig.quadrantChart!.chartWidth
);
});
it('should set reset config properly', function () {
const config_0 = { fontFamily: 'foo-font', fontSize: 150 };
configApi.setSiteConfig(config_0);
const config_1 = { fontFamily: 'baf' };
configApi.setConfig(config_1);
const config_2 = configApi.getConfig();
expect(config_2.fontFamily).toEqual(config_1.fontFamily);
configApi.reset();
const config_3 = configApi.getConfig();
expect(config_3.fontFamily).toEqual(config_0.fontFamily);
const config_4 = configApi.getSiteConfig();
expect(config_4.fontFamily).toEqual(config_0.fontFamily);
});
it('should set global reset config properly', function () {
const config_0 = { fontFamily: 'foo-font', fontSize: 150 };
configApi.setSiteConfig(config_0);
const config_1 = configApi.getSiteConfig();
expect(config_1.fontFamily).toEqual(config_0.fontFamily);
const config_2 = configApi.getConfig();
expect(config_2.fontFamily).toEqual(config_0.fontFamily);
configApi.setConfig({ altFontFamily: 'bar-font' });
const config_3 = configApi.getConfig();
expect(config_3.altFontFamily).toEqual('bar-font');
configApi.reset();
const config_4 = configApi.getConfig();
expect(config_4.altFontFamily).toBeUndefined();
});
});

View File

@@ -226,9 +226,11 @@ export const reset = (config = siteConfig): void => {
updateCurrentConfig(config, directives);
};
enum ConfigWarning {
'LAZY_LOAD_DEPRECATED' = 'The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.',
}
const ConfigWarning = {
LAZY_LOAD_DEPRECATED:
'The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.',
} as const;
type ConfigWarningStrings = keyof typeof ConfigWarning;
const issuedWarnings: { [key in ConfigWarningStrings]?: boolean } = {};
const issueWarning = (warning: ConfigWarningStrings) => {

File diff suppressed because it is too large Load Diff

View File

@@ -917,7 +917,9 @@ const class_box = (parent, node) => {
((-1 * maxHeight) / 2 + verticalPos + lineHeight / 2) +
')'
);
verticalPos += classTitleBBox.height + rowPadding;
//get the height of the bounding box of each member if exists
const memberBBox = lbl?.getBBox();
verticalPos += (memberBBox?.height ?? 0) + rowPadding;
});
verticalPos += lineHeight;
@@ -935,7 +937,8 @@ const class_box = (parent, node) => {
'transform',
'translate( ' + -maxWidth / 2 + ', ' + ((-1 * maxHeight) / 2 + verticalPos) + ')'
);
verticalPos += classTitleBBox.height + rowPadding;
const memberBBox = lbl?.getBBox();
verticalPos += (memberBBox?.height ?? 0) + rowPadding;
});
rect

View File

@@ -66,8 +66,11 @@ export const labelHelper = async (parent, node, _classes, isNode) => {
await Promise.all(
[...images].map(
(img) =>
new Promise((res) =>
img.addEventListener('load', function () {
new Promise((res) => {
/**
*
*/
function setupImage() {
img.style.display = 'flex';
img.style.flexDirection = 'column';
@@ -82,8 +85,15 @@ export const labelHelper = async (parent, node, _classes, isNode) => {
img.style.width = '100%';
}
res(img);
})
)
}
setTimeout(() => {
if (img.complete) {
setupImage();
}
});
img.addEventListener('error', setupImage);
img.addEventListener('load', setupImage);
})
)
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@ import errorDiagram from '../diagrams/error/errorDiagram.js';
import flowchartElk from '../diagrams/flowchart/elk/detector.js';
import timeline from '../diagrams/timeline/detector.js';
import mindmap from '../diagrams/mindmap/detector.js';
import sankey from '../diagrams/sankey/sankeyDetector.js';
import { registerLazyLoadedDiagrams } from './detectType.js';
import { registerDiagram } from './diagramAPI.js';
@@ -79,6 +80,7 @@ export const addDiagrams = () => {
stateV2,
state,
journey,
quadrantChart
quadrantChart,
sankey
);
};

View File

@@ -0,0 +1,135 @@
import c4Db from '../c4Db.js';
import c4 from './c4Diagram.jison';
import { setConfig } from '../../../config.js';
setConfig({
securityLevel: 'strict',
});
describe.each([
['Container', 'container'],
['ContainerDb', 'container_db'],
['ContainerQueue', 'container_queue'],
['Container_Ext', 'external_container'],
['ContainerDb_Ext', 'external_container_db'],
['ContainerQueue_Ext', 'external_container_queue'],
])('parsing a C4 %s', function (macroName, elementName) {
beforeEach(function () {
c4.parser.yy = c4Db;
c4.parser.yy.clear();
});
it('should parse a C4 diagram with one Container correctly', function () {
c4.parser.parse(`C4Context
title Container diagram for Internet Banking Container
${macroName}(ContainerAA, "Internet Banking Container", "Technology", "Allows customers to view information about their bank accounts, and make payments.")`);
const yy = c4.parser.yy;
const shapes = yy.getC4ShapeArray();
expect(shapes.length).toBe(1);
const onlyShape = shapes[0];
expect(onlyShape).toEqual({
alias: 'ContainerAA',
descr: {
text: 'Allows customers to view information about their bank accounts, and make payments.',
},
label: {
text: 'Internet Banking Container',
},
link: undefined,
sprite: undefined,
tags: undefined,
parentBoundary: 'global',
typeC4Shape: {
text: elementName,
},
techn: {
text: 'Technology',
},
wrap: false,
});
});
it('should parse the alias', function () {
c4.parser.parse(`C4Context
${macroName}(ContainerAA, "Internet Banking Container")`);
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
alias: 'ContainerAA',
});
});
it('should parse the label', function () {
c4.parser.parse(`C4Context
${macroName}(ContainerAA, "Internet Banking Container")`);
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
label: {
text: 'Internet Banking Container',
},
});
});
it('should parse the technology', function () {
c4.parser.parse(`C4Context
${macroName}(ContainerAA, "", "Java")`);
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
techn: {
text: 'Java',
},
});
});
it('should parse the description', function () {
c4.parser.parse(`C4Context
${macroName}(ContainerAA, "", "", "Allows customers to view information about their bank accounts, and make payments.")`);
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
descr: {
text: 'Allows customers to view information about their bank accounts, and make payments.',
},
});
});
it('should parse a sprite', function () {
c4.parser.parse(`C4Context
${macroName}(ContainerAA, $sprite="users")`);
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
label: {
text: {
sprite: 'users',
},
},
});
});
it('should parse a link', function () {
c4.parser.parse(`C4Context
${macroName}(ContainerAA, $link="https://github.com/mermaidjs")`);
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
label: {
text: {
link: 'https://github.com/mermaidjs',
},
},
});
});
it('should parse tags', function () {
c4.parser.parse(`C4Context
${macroName}(ContainerAA, $tags="tag1,tag2")`);
expect(c4.parser.yy.getC4ShapeArray()[0]).toMatchObject({
label: {
text: {
tags: 'tag1,tag2',
},
},
});
});
});

View File

@@ -150,27 +150,27 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
"Node_R" { this.begin("node_r"); return 'NODE_R';}
"Rel" { this.begin("rel"); return 'REL';}
"BiRel" { this.begin("birel"); return 'BIREL';}
"Rel_Up" { this.begin("rel_u"); return 'REL_U';}
"Rel_U" { this.begin("rel_u"); return 'REL_U';}
"Rel_Down" { this.begin("rel_d"); return 'REL_D';}
"Rel_D" { this.begin("rel_d"); return 'REL_D';}
"Rel_Left" { this.begin("rel_l"); return 'REL_L';}
"Rel_L" { this.begin("rel_l"); return 'REL_L';}
"Rel_Right" { this.begin("rel_r"); return 'REL_R';}
"Rel_R" { this.begin("rel_r"); return 'REL_R';}
"Rel_Back" { this.begin("rel_b"); return 'REL_B';}
"RelIndex" { this.begin("rel_index"); return 'REL_INDEX';}
"Rel" { this.begin("rel"); return 'REL';}
"BiRel" { this.begin("birel"); return 'BIREL';}
"Rel_Up" { this.begin("rel_u"); return 'REL_U';}
"Rel_U" { this.begin("rel_u"); return 'REL_U';}
"Rel_Down" { this.begin("rel_d"); return 'REL_D';}
"Rel_D" { this.begin("rel_d"); return 'REL_D';}
"Rel_Left" { this.begin("rel_l"); return 'REL_L';}
"Rel_L" { this.begin("rel_l"); return 'REL_L';}
"Rel_Right" { this.begin("rel_r"); return 'REL_R';}
"Rel_R" { this.begin("rel_r"); return 'REL_R';}
"Rel_Back" { this.begin("rel_b"); return 'REL_B';}
"RelIndex" { this.begin("rel_index"); return 'REL_INDEX';}
"UpdateElementStyle" { this.begin("update_el_style"); return 'UPDATE_EL_STYLE';}
"UpdateRelStyle" { this.begin("update_rel_style"); return 'UPDATE_REL_STYLE';}
"UpdateLayoutConfig" { this.begin("update_layout_config"); return 'UPDATE_LAYOUT_CONFIG';}
"UpdateElementStyle" { this.begin("update_el_style"); return 'UPDATE_EL_STYLE';}
"UpdateRelStyle" { this.begin("update_rel_style"); return 'UPDATE_REL_STYLE';}
"UpdateLayoutConfig" { this.begin("update_layout_config"); return 'UPDATE_LAYOUT_CONFIG';}
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config><<EOF>> return "EOF_IN_STRUCT";
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(][ ]*[,] { this.begin("attribute"); return "ATTRIBUTE_EMPTY";}
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(] { this.begin("attribute"); }
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config,attribute>[)] { this.popState();this.popState();}
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext_queue,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config><<EOF>> return "EOF_IN_STRUCT";
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext_queue,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(][ ]*[,] { this.begin("attribute"); return "ATTRIBUTE_EMPTY";}
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext_queue,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config>[(] { this.begin("attribute"); }
<person,person_ext,system_ext_queue,system_ext_db,system_ext,system_queue,system_db,system,boundary,enterprise_boundary,system_boundary,container_ext_db,container_ext_queue,container_ext,container_queue,container_db,container,container_boundary,component_ext_db,component_ext,component_queue,component_db,component,node,node_l,node_r,rel,birel,rel_u,rel_d,rel_l,rel_r,rel_b,rel_index,update_el_style,update_rel_style,update_layout_config,attribute>[)] { this.popState();this.popState();}
<attribute>",," { return 'ATTRIBUTE_EMPTY';}
<attribute>"," { }
@@ -189,7 +189,7 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
'{' { /* this.begin("lbrace"); */ return "LBRACE";}
'}' { /* this.popState(); */ return "RBRACE";}
[\s]+ return 'SPACE';
[\n\r]+ return 'EOL';
<<EOF>> return 'EOF';
@@ -257,7 +257,7 @@ graphConfig
statements
: otherStatements
| diagramStatements
| otherStatements diagramStatements
| otherStatements diagramStatements
;
otherStatements
@@ -268,10 +268,10 @@ otherStatements
otherStatement
: title {yy.setTitle($1.substring(6));$$=$1.substring(6);}
| accDescription {yy.setAccDescription($1.substring(15));$$=$1.substring(15);}
| accDescription {yy.setAccDescription($1.substring(15));$$=$1.substring(15);}
| acc_title acc_title_value { $$=$2.trim();yy.setTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
;
boundaryStatement
@@ -301,7 +301,7 @@ boundaryStopStatement
diagramStatements
: diagramStatement
| diagramStatement NEWLINE
| diagramStatement NEWLINE statements
| diagramStatement NEWLINE statements
;
diagramStatement
@@ -312,19 +312,19 @@ diagramStatement
| SYSTEM_QUEUE attributes {yy.addPersonOrSystem('system_queue', ...$2); $$=$2;}
| SYSTEM_EXT attributes {yy.addPersonOrSystem('external_system', ...$2); $$=$2;}
| SYSTEM_EXT_DB attributes {yy.addPersonOrSystem('external_system_db', ...$2); $$=$2;}
| SYSTEM_EXT_QUEUE attributes {yy.addPersonOrSystem('external_system_queue', ...$2); $$=$2;}
| SYSTEM_EXT_QUEUE attributes {yy.addPersonOrSystem('external_system_queue', ...$2); $$=$2;}
| CONTAINER attributes {yy.addContainer('container', ...$2); $$=$2;}
| CONTAINER_DB attributes {yy.addContainer('container_db', ...$2); $$=$2;}
| CONTAINER_QUEUE attributes {yy.addContainer('container_queue', ...$2); $$=$2;}
| CONTAINER_EXT attributes {yy.addContainer('external_container', ...$2); $$=$2;}
| CONTAINER_EXT_DB attributes {yy.addContainer('external_container_db', ...$2); $$=$2;}
| CONTAINER_EXT_QUEUE attributes {yy.addContainer('external_container_queue', ...$2); $$=$2;}
| CONTAINER_EXT_QUEUE attributes {yy.addContainer('external_container_queue', ...$2); $$=$2;}
| COMPONENT attributes {yy.addComponent('component', ...$2); $$=$2;}
| COMPONENT_DB attributes {yy.addComponent('component_db', ...$2); $$=$2;}
| COMPONENT_QUEUE attributes {yy.addComponent('component_queue', ...$2); $$=$2;}
| COMPONENT_EXT attributes {yy.addComponent('external_component', ...$2); $$=$2;}
| COMPONENT_EXT_DB attributes {yy.addComponent('external_component_db', ...$2); $$=$2;}
| COMPONENT_EXT_QUEUE attributes {yy.addComponent('external_component_queue', ...$2); $$=$2;}
| COMPONENT_EXT_QUEUE attributes {yy.addComponent('external_component_queue', ...$2); $$=$2;}
| boundaryStatement
| REL attributes {yy.addRel('rel', ...$2); $$=$2;}
| BIREL attributes {yy.addRel('birel', ...$2); $$=$2;}

View File

@@ -264,6 +264,113 @@ class C13["With Città foreign language"]
const str = 'classDiagram\n' + 'note "test"\n';
parser.parse(str);
});
const keywords = [
'direction',
'classDiagram',
'classDiagram-v2',
'namespace',
'{}',
'{',
'}',
'()',
'(',
')',
'[]',
'[',
']',
'class',
'\n',
'cssClass',
'callback',
'link',
'click',
'note',
'note for',
'<<',
'>>',
'call ',
'~',
'~Generic~',
'_self',
'_blank',
'_parent',
'_top',
'<|',
'|>',
'>',
'<',
'*',
'o',
'\\',
'--',
'..',
'-->',
'--|>',
': label',
':::',
'.',
'+',
'alphaNum',
'!',
'0123',
'function()',
'function(arg1, arg2)',
];
it.each(keywords)('should handle a note with %s in it', function (keyword: string) {
const str = `classDiagram
note "This is a keyword: ${keyword}. It truly is."
`;
parser.parse(str);
expect(classDb.getNotes()[0].text).toEqual(`This is a keyword: ${keyword}. It truly is.`);
});
it.each(keywords)(
'should handle note with %s at beginning of string',
function (keyword: string) {
const str = `classDiagram
note "${keyword}"`;
parser.parse(str);
expect(classDb.getNotes()[0].text).toEqual(`${keyword}`);
}
);
it.each(keywords)('should handle a "note for" with a %s in it', function (keyword: string) {
const str = `classDiagram
class Something {
int id
string name
}
note for Something "This is a keyword: ${keyword}. It truly is."
`;
parser.parse(str);
expect(classDb.getNotes()[0].text).toEqual(`This is a keyword: ${keyword}. It truly is.`);
});
it.each(keywords)(
'should handle a "note for" with a %s at beginning of string',
function (keyword: string) {
const str = `classDiagram
class Something {
int id
string name
}
note for Something "${keyword}"
`;
parser.parse(str);
expect(classDb.getNotes()[0].text).toEqual(`${keyword}`);
}
);
it.each(keywords)('should elicit error for %s after NOTE token', function (keyword: string) {
const str = `classDiagram
note ${keyword}`;
expect(() => parser.parse(str)).toThrowError(/(Expecting\s'STR'|Unrecognized\stext)/);
});
});
describe('when parsing class defined in brackets', function () {

View File

@@ -1,16 +0,0 @@
import { readFile } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
// @ts-ignore - no types
import { LALRGenerator } from 'jison';
const getAbsolutePath = (relativePath: string) => {
return fileURLToPath(new URL(relativePath, import.meta.url));
};
describe('class diagram grammar', function () {
it('should have no conflicts', async function () {
const grammarSource = await readFile(getAbsolutePath('./parser/classDiagram.jison'), 'utf8');
const grammarParser = new LALRGenerator(grammarSource, {});
expect(grammarParser.conflicts).toBe(0);
});
});

Some files were not shown because too many files have changed in this diff Show More