diff --git a/.lintstagedrc.json b/.lintstagedrc.json
index c43f5f89f..863473f2a 100644
--- a/.lintstagedrc.json
+++ b/.lintstagedrc.json
@@ -1,3 +1,4 @@
{
- "!(docs/**/*)*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"]
+ "!(docs/**/*)*.{ts,js,json,html,md,mts}": ["eslint --fix", "prettier --write"],
+ "cSpell.json": ["ts-node-esm scripts/fixCSpell.ts"]
}
diff --git a/README.md b/README.md
index bcef7ae09..4d66d3e6b 100644
--- a/README.md
+++ b/README.md
@@ -43,12 +43,12 @@ Mermaid addresses this problem by enabling users to create easily modifiable dia
Mermaid allows even non-programmers to easily create detailed diagrams through the [Mermaid Live Editor](https://mermaid.live/).
-[Tutorials](./docs/Tutorials.md) has video tutorials.
-Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
+[Tutorials](./docs/config/Tutorials.md) has video tutorials.
+Use Mermaid with your favorite applications, check out the list of [Integrations and Usages of Mermaid](./docs/misc/integrations.md).
-You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) as well many of your other favorite applications—check out the list of [Integrations and Usages of Mermaid](./docs/integrations.md).
+You can also use Mermaid within [GitHub](https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/) as well many of your other favorite applications—check out the list of [Integrations and Usages of Mermaid](./docs/misc/integrations.md).
-For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./docs/n00b-overview.md), [Usage](./docs/usage.md) and [Tutorials](./docs/Tutorials.md).
+For a more detailed introduction to Mermaid and some of its more basic uses, look to the [Beginner's Guide](./docs/community/n00b-overview.md), [Usage](./docs/config/usage.md) and [Tutorials](./docs/config/Tutorials.md).
🌐 [CDN](https://unpkg.com/mermaid/) | 📖 [Documentation](https://mermaidjs.github.io) | 🙌 [Contribution](https://github.com/mermaid-js/mermaid/blob/develop/CONTRIBUTING.md) | 📜 [Changelog](./docs/CHANGELOG.md)
diff --git a/applitools.config.js b/applitools.config.js
index 1c0607868..4cf02220a 100644
--- a/applitools.config.js
+++ b/applitools.config.js
@@ -15,5 +15,5 @@ module.exports = defineConfig({
// { deviceName: 'Pixel 2', screenOrientation: 'portrait' },
],
// set batch name to the configuration
- batchName: `Mermaid ${process.env.APPLI_BRANCH ?? "'no APPLI_BRANCH set'"}`,
+ // batchName: `Mermaid ${process.env.APPLI_BRANCH ?? "'no APPLI_BRANCH set'"}`,
});
diff --git a/cSpell.json b/cSpell.json
index 0d9ed77a1..08fce1d1c 100644
--- a/cSpell.json
+++ b/cSpell.json
@@ -2,91 +2,86 @@
"version": "0.2",
"language": "en",
"words": [
- "blockquotes",
- "customizability",
- "Gantt",
- "jison",
- "mermaid",
- "mindmap",
- "Mindmaps",
- "mitigations",
- "sandboxed",
- "shiki",
- "verdana",
- "Visio"
- ],
- "ignoreWords": [
- "Alois",
- "Klink",
- "knsv",
- "Knut",
- "Matthieu",
- "Sidharth",
- "Sveidqvist",
- "Vinod",
- "Faber",
- "Orlandoni",
- "Klemm",
- "Mindaugas",
- "Laganeckas",
- "Cuzon",
- "Yash",
- "Adamiecki",
+ "acyclicer",
+ "adamiecki",
+ "alois",
+ "antiscript",
"applitools",
- "Asciidoctor",
- "Astah",
- "Bisheng",
+ "asciidoctor",
+ "ashish",
+ "astah",
+ "bbox",
+ "bilkent",
+ "bisheng",
+ "brolin",
"codedoc",
- "Docsy",
- "Doku",
- "Gitea",
- "Gitgraph",
- "Grav",
- "Inkdrop",
- "Jaoude",
+ "colour",
+ "cpettitt",
+ "customizability",
+ "cuzon",
+ "cytoscape",
+ "dagre",
+ "descr",
+ "docsify",
+ "docsy",
+ "doku",
+ "dompurify",
+ "edgechromium",
+ "faber",
+ "flatmap",
+ "gantt",
+ "gitea",
+ "gitgraph",
+ "graphlib",
+ "grav",
+ "greywolf",
+ "inkdrop",
+ "jaoude",
+ "jison",
+ "kaufmann",
+ "klemm",
+ "klink",
+ "knsv",
+ "knut",
+ "laganeckas",
+ "lucida",
+ "matthieu",
"mdbook",
"mermerd",
+ "mindaugas",
+ "mindmap",
+ "mindmaps",
+ "mitigations",
"mkdocs",
+ "orlandoni",
"phpbb",
- "Plantuml",
- "Playfair's",
- "Podlite",
- "redmine",
- "sphinxcontrib",
- "Tuleap",
- "dagre",
- "vitepress",
- "docsify",
- "colour",
- "graphlib",
- "acyclicer",
+ "plantuml",
+ "playfair",
+ "podlite",
"ranksep",
- "descr",
- "substate",
- "Ashish",
- "bbox",
- "techn",
- "cytoscape",
- "Lucida",
- "Bilkent",
- "cpettitt",
- "antiscript",
- "ts-nocheck",
- "setupGraphViewbox",
- "flatmap",
- "Kaufmann",
- "viewports",
- "edgechromium",
+ "redmine",
+ "sandboxed",
+ "setupgraphviewbox",
+ "shiki",
+ "sidharth",
+ "sphinxcontrib",
"statediagram",
- "Brolin",
- "Greywolf"
+ "stylis",
+ "substate",
+ "sveidqvist",
+ "techn",
+ "ts-nocheck",
+ "tuleap",
+ "verdana",
+ "viewports",
+ "vinod",
+ "visio",
+ "vitepress",
+ "xlink",
+ "yash"
],
"patterns": [
- {
- "name": "Markdown links",
- "pattern": "\\((.*)\\)",
- "description": ""
- },
+ { "name": "Markdown links", "pattern": "\\((.*)\\)", "description": "" },
{
"name": "Markdown code blocks",
"pattern": "/^(\\s*`{3,}).*[\\s\\S]*?^\\1/gmx",
@@ -97,25 +92,14 @@
"pattern": "\\`([^\\`\\r\\n]+?)\\`",
"description": "https://stackoverflow.com/questions/41274241/how-to-capture-inline-markdown-code-but-not-a-markdown-code-fence-with-regex"
},
- {
- "name": "Link contents",
- "pattern": "\\",
- "description": ""
- },
- {
- "name": "Snippet references",
- "pattern": "-- snippet:(.*)",
- "description": ""
- },
+ { "name": "Link contents", "pattern": "\\", "description": "" },
+ { "name": "Snippet references", "pattern": "-- snippet:(.*)", "description": "" },
{
"name": "Snippet references 2",
"pattern": "\\<\\[sample:(.*)",
"description": "another kind of snippet reference"
},
- {
- "name": "Multi-line code blocks",
- "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm"
- },
+ { "name": "Multi-line code blocks", "pattern": "/^\\s*```[\\s\\S]*?^\\s*```/gm" },
{
"name": "HTML Tags",
"pattern": "<[^>]*>",
diff --git a/cypress/helpers/util.js b/cypress/helpers/util.js
index bc5282e11..5213f634a 100644
--- a/cypress/helpers/util.js
+++ b/cypress/helpers/util.js
@@ -2,6 +2,8 @@ const utf8ToB64 = (str) => {
return window.btoa(unescape(encodeURIComponent(str)));
};
+const batchId = 'mermid-batch' + new Date().getTime();
+
export const mermaidUrl = (graphStr, options, api) => {
const obj = {
code: graphStr,
@@ -49,9 +51,12 @@ export const imgSnapshotTest = (graphStr, _options, api = false, validation) =>
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,
});
}
@@ -65,7 +70,9 @@ export const imgSnapshotTest = (graphStr, _options, api = false, validation) =>
// Default name to test title
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);
@@ -101,9 +108,12 @@ export const urlSnapshotTest = (url, _options, api = false, validation) => {
const name = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
if (useAppli) {
+ cy.log('Opening eyes 2' + Cypress.spec.name);
cy.eyesOpen({
appName: 'Mermaid',
testName: name,
+ batchName: Cypress.spec.name,
+ batchId: batchId + Cypress.spec.name,
});
}
@@ -115,7 +125,9 @@ export const urlSnapshotTest = (url, _options, api = false, validation) => {
// Default name to test title
if (useAppli) {
+ cy.log('Check eyes 2' + Cypress.spec.name);
cy.eyesCheckWindow('Click!');
+ cy.log('Closing eyes 2' + Cypress.spec.name);
cy.eyesClose();
} else {
cy.matchImageSnapshot(name);
diff --git a/docs/config/directives.md b/docs/config/directives.md
index 820eb72e9..550707080 100644
--- a/docs/config/directives.md
+++ b/docs/config/directives.md
@@ -30,7 +30,7 @@ Mermaid basically supports two types of configuration options to be overridden b
2. _Diagram specific configurations_ : These are the configurations that are available and applied to a specific diagram. For each diagram there are specific configuration that will alter how that particular diagram looks and behaves.
For example, `mirrorActors` is a configuration that is specific to the `SequenceDiagram` and alter whether the actors are mirrored or not. So this config is available only for the `SequenceDiagram` type.
-**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code.
+**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code.
Soon we plan to publish a complete list of top-level configurations & all the diagram specific configurations, with their possible values in the docs
@@ -233,7 +233,7 @@ Some common flowchart configurations are:
- _diagramPadding_: number
- _useMaxWidth_: number
-For complete list of flowchart configurations, see [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code.
+For complete list of flowchart configurations, see [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code.
_Soon we plan to publish a complete list all diagram specific configurations updated in the docs_
The following code snippet changes flowchart config:
@@ -277,7 +277,7 @@ Some common sequence configurations are:
- _showSequenceNumbers_: boolean
- _wrap_: boolean
-For complete list of sequence diagram configurations, see _defaultConfig.js_ in the source code.
+For complete list of sequence diagram configurations, see _defaultConfig.ts_ in the source code.
_Soon we plan to publish a complete list all diagram specific configurations updated in the docs_
So, `wrap` by default has a value of `false` for sequence diagrams.
diff --git a/docs/config/setup/modules/mermaidAPI.md b/docs/config/setup/modules/mermaidAPI.md
index 1ef1853ed..c4e512f3f 100644
--- a/docs/config/setup/modules/mermaidAPI.md
+++ b/docs/config/setup/modules/mermaidAPI.md
@@ -16,7 +16,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
### mermaidAPI
-• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `Promise`<`void`> ; `parse`: (`text`: `string`, `parseError?`: `ParseErrorFunction`) => `boolean` ; `parseDirective`: (`p`: `any`, `statement`: `string`, `context`: `string`, `type`: `string`) => `void` ; `render`: (`id`: `string`, `text`: `string`, `cb`: (`svgCode`: `string`, `bindFunctions?`: (`element`: `Element`) => `void`) => `void`, `container?`: `Element`) => `Promise`<`void`> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
+• `Const` **mermaidAPI**: `Readonly`<{ `defaultConfig`: `MermaidConfig` = configApi.defaultConfig; `getConfig`: () => `MermaidConfig` = configApi.getConfig; `getSiteConfig`: () => `MermaidConfig` = configApi.getSiteConfig; `globalReset`: () => `void` ; `initialize`: (`options`: `MermaidConfig`) => `Promise`<`void`> ; `parse`: (`text`: `string`, `parseError?`: `ParseErrorFunction`) => `boolean` ; `parseDirective`: (`p`: `any`, `statement`: `string`, `context`: `string`, `type`: `string`) => `void` ; `render`: (`id`: `string`, `text`: `string`, `cb`: (`svgCode`: `string`, `bindFunctions?`: (`element`: `Element`) => `void`) => `void`, `svgContainingElement?`: `Element`) => `Promise`<`void`> ; `reset`: () => `void` ; `setConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.setConfig; `updateSiteConfig`: (`conf`: `MermaidConfig`) => `MermaidConfig` = configApi.updateSiteConfig }>
## mermaidAPI configuration defaults
@@ -80,19 +80,105 @@ mermaid.initialize(config);
#### Defined in
-[mermaidAPI.ts:546](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L546)
+[mermaidAPI.ts:740](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L740)
## Functions
-### decodeEntities
+### appendDivSvgG
-▸ **decodeEntities**(`text`): `string`
+▸ **appendDivSvgG**(`parentRoot`, `id`, `enclosingDivId`, `divStyle?`, `svgXlink?`): `any`
+
+Append an enclosing div, then svg, then g (group) to the d3 parentRoot. Set attributes.
+Only set the style attribute on the enclosing div if divStyle is given.
+Only set the xmlns:xlink attribute on svg if svgXlink is given.
+Return the last node appended
#### Parameters
-| Name | Type |
-| :----- | :------- |
-| `text` | `string` |
+| Name | Type | Description |
+| :--------------- | :------- | :----------------------------------------------- |
+| `parentRoot` | `any` | the d3 node to append things to |
+| `id` | `string` | the value to set the id attr to |
+| `enclosingDivId` | `string` | the id to set the enclosing div to |
+| `divStyle?` | `string` | if given, the style to set the enclosing div to |
+| `svgXlink?` | `string` | if given, the link to set the new svg element to |
+
+#### Returns
+
+`any`
+
+- returns the parentRoot that had nodes appended
+
+#### Defined in
+
+[mermaidAPI.ts:283](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L283)
+
+---
+
+### cleanUpSvgCode
+
+▸ **cleanUpSvgCode**(`svgCode?`, `inSandboxMode`, `useArrowMarkerUrls`): `string`
+
+Clean up svgCode. Do replacements needed
+
+#### Parameters
+
+| Name | Type | Default value | Description |
+| :------------------- | :-------- | :------------ | :---------------------------------------------------------- |
+| `svgCode` | `string` | `''` | the code to clean up |
+| `inSandboxMode` | `boolean` | `undefined` | security level |
+| `useArrowMarkerUrls` | `boolean` | `undefined` | should arrow marker's use full urls? (vs. just the anchors) |
+
+#### Returns
+
+`string`
+
+the cleaned up svgCode
+
+#### Defined in
+
+[mermaidAPI.ts:234](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L234)
+
+---
+
+### createCssStyles
+
+▸ **createCssStyles**(`config`, `graphType`, `classDefs?`): `string`
+
+Create the user styles
+
+#### Parameters
+
+| Name | Type | Description |
+| :---------- | :-------------- | :----------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
+| `config` | `MermaidConfig` | configuration that has style and theme settings to use |
+| `graphType` | `string` | used for checking if classDefs should be applied |
+| `classDefs` | `undefined` | `null` | `Record`<`string`, `DiagramStyleClassDef`> | the classDefs in the diagram text. Might be null if none were defined. Usually is the result of a call to getClasses(...) |
+
+#### Returns
+
+`string`
+
+the string with all the user styles
+
+#### Defined in
+
+[mermaidAPI.ts:161](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L161)
+
+---
+
+### createUserStyles
+
+▸ **createUserStyles**(`config`, `graphType`, `classDefs`, `svgId`): `string`
+
+#### Parameters
+
+| Name | Type |
+| :---------- | :----------------------------------------- |
+| `config` | `MermaidConfig` |
+| `graphType` | `string` |
+| `classDefs` | `Record`<`string`, `DiagramStyleClassDef`> |
+| `svgId` | `string` |
#### Returns
@@ -100,7 +186,54 @@ mermaid.initialize(config);
#### Defined in
-[mermaidAPI.ts:72](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L72)
+[mermaidAPI.ts:211](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L211)
+
+---
+
+### cssImportantStyles
+
+▸ **cssImportantStyles**(`cssClass`, `element`, `cssClasses?`): `string`
+
+Create a CSS style that starts with the given class name, then the element,
+with an enclosing block that has each of the cssClasses followed by !important;
+
+#### Parameters
+
+| Name | Type | Default value | Description |
+| :----------- | :---------- | :------------ | :--------------------------------------------- |
+| `cssClass` | `string` | `undefined` | CSS class name |
+| `element` | `string` | `undefined` | CSS element |
+| `cssClasses` | `string`\[] | `[]` | list of CSS styles to append after the element |
+
+#### Returns
+
+`string`
+
+- the constructed string
+
+#### Defined in
+
+[mermaidAPI.ts:145](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L145)
+
+---
+
+### decodeEntities
+
+▸ **decodeEntities**(`text`): `string`
+
+#### Parameters
+
+| Name | Type | Description |
+| :----- | :------- | :----------------- |
+| `text` | `string` | text to be decoded |
+
+#### Returns
+
+`string`
+
+#### Defined in
+
+[mermaidAPI.ts:119](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L119)
---
@@ -110,9 +243,9 @@ mermaid.initialize(config);
#### Parameters
-| Name | Type |
-| :----- | :------- |
-| `text` | `string` |
+| Name | Type | Description |
+| :----- | :------- | :----------------- |
+| `text` | `string` | text to be encoded |
#### Returns
@@ -120,4 +253,56 @@ mermaid.initialize(config);
#### Defined in
-[mermaidAPI.ts:46](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L46)
+[mermaidAPI.ts:90](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L90)
+
+---
+
+### putIntoIFrame
+
+▸ **putIntoIFrame**(`svgCode?`, `svgElement?`): `string`
+
+Put the svgCode into an iFrame. Return the iFrame code
+
+#### Parameters
+
+| Name | Type | Default value | Description |
+| :------------ | :------- | :------------ | :--------------------------------------------------------------------------- |
+| `svgCode` | `string` | `''` | the svg code to put inside the iFrame |
+| `svgElement?` | `any` | `undefined` | the d3 node that has the current svgElement so we can get the height from it |
+
+#### Returns
+
+`string`
+
+- the code with the iFrame that now contains the svgCode
+ TODO replace btoa(). Replace with buf.toString('base64')?
+
+#### Defined in
+
+[mermaidAPI.ts:262](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L262)
+
+---
+
+### removeExistingElements
+
+▸ **removeExistingElements**(`doc`, `isSandboxed`, `id`, `divSelector`, `iFrameSelector`): `void`
+
+Remove any existing elements from the given document
+
+#### Parameters
+
+| Name | Type | Description |
+| :--------------- | :--------- | :---------------------------------------------- |
+| `doc` | `Document` | the document to removed elements from |
+| `isSandboxed` | `boolean` | whether or not we are in sandboxed mode |
+| `id` | `string` | id for any existing SVG element |
+| `divSelector` | `string` | selector for any existing enclosing div element |
+| `iFrameSelector` | `string` | selector for any existing iFrame element |
+
+#### Returns
+
+`void`
+
+#### Defined in
+
+[mermaidAPI.ts:334](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L334)
diff --git a/package.json b/package.json
index 15bfcbada..d6be95b2d 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"module": "dist/mermaid.core.mjs",
"types": "dist/mermaid.d.ts",
"type": "module",
- "packageManager": "pnpm@7.14.1",
+ "packageManager": "pnpm@7.15.0",
"exports": {
".": {
"require": "./dist/mermaid.min.js",
@@ -33,7 +33,7 @@
"dev": "concurrently \"pnpm build:vite --watch\" \"ts-node-esm .vite/server.ts\"",
"release": "pnpm build",
"lint": "eslint --cache --ignore-path .gitignore . && pnpm --filter mermaid run lint:jison && prettier --check .",
- "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write .",
+ "lint:fix": "eslint --fix --ignore-path .gitignore . && prettier --write . && ts-node-esm scripts/fixCSpell.ts",
"cypress": "cypress run",
"cypress:open": "cypress open",
"e2e": "start-server-and-test dev http://localhost:9000/ cypress",
@@ -62,67 +62,67 @@
]
},
"dependencies": {
- "@braintree/sanitize-url": "6.0.1",
- "@types/node": "18.11.8",
+ "@braintree/sanitize-url": "6.0.2",
+ "@types/node": "18.11.9",
"@types/uuid": "8.3.4",
"d3": "7.6.1",
"dagre": "0.8.5",
"dagre-d3": "0.6.4",
- "dompurify": "2.4.0",
+ "dompurify": "2.4.1",
"fast-clone": "1.5.13",
"graphlib": "2.1.8",
"khroma": "2.0.0",
"lodash": "4.17.21",
"moment-mini": "2.29.4",
"non-layered-tidy-tree-layout": "2.0.2",
- "rollup": "2.79.1",
+ "rollup": "3.3.0",
"stylis": "4.1.3",
"uuid": "9.0.0"
},
"devDependencies": {
"@applitools/eyes-cypress": "3.27.6",
- "@commitlint/cli": "17.1.2",
- "@commitlint/config-conventional": "17.1.0",
- "@cspell/eslint-plugin": "6.13.2",
+ "@commitlint/cli": "17.2.0",
+ "@commitlint/config-conventional": "17.2.0",
+ "@cspell/eslint-plugin": "6.14.2",
"@types/d3": "7.4.0",
- "@types/dompurify": "2.3.4",
- "@types/eslint": "8.4.9",
+ "@types/dompurify": "2.4.0",
+ "@types/eslint": "8.4.10",
"@types/express": "4.17.14",
- "@types/jsdom": "20.0.0",
- "@types/lodash": "4.14.186",
+ "@types/jsdom": "20.0.1",
+ "@types/lodash": "4.14.188",
"@types/mdast": "3.0.10",
"@types/prettier": "2.7.1",
"@types/stylis": "4.0.2",
- "@typescript-eslint/eslint-plugin": "5.41.0",
- "@typescript-eslint/parser": "5.41.0",
- "@vitest/coverage-c8": "0.24.3",
- "@vitest/ui": "0.24.3",
+ "@typescript-eslint/eslint-plugin": "5.42.1",
+ "@typescript-eslint/parser": "5.42.1",
+ "@vitest/coverage-c8": "0.25.1",
+ "@vitest/ui": "0.25.1",
"concurrently": "7.5.0",
"coveralls": "3.1.1",
"cypress": "10.11.0",
"cypress-image-snapshot": "4.0.1",
- "esbuild": "0.15.12",
- "eslint": "8.26.0",
+ "esbuild": "0.15.13",
+ "eslint": "8.27.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-cypress": "2.12.1",
"eslint-plugin-html": "7.1.0",
- "eslint-plugin-jest": "27.1.3",
- "eslint-plugin-jsdoc": "39.4.0",
+ "eslint-plugin-jest": "27.1.5",
+ "eslint-plugin-jsdoc": "39.6.2",
"eslint-plugin-json": "3.1.0",
"eslint-plugin-markdown": "3.0.0",
"eslint-plugin-no-only-tests": "3.1.0",
"eslint-plugin-tsdoc": "0.2.17",
"express": "4.18.2",
"globby": "13.1.2",
- "husky": "8.0.1",
+ "husky": "8.0.2",
"identity-obj-proxy": "3.0.0",
- "jest": "29.2.2",
+ "jest": "29.3.1",
"jison": "0.4.18",
"jsdom": "20.0.2",
"lint-staged": "13.0.3",
"markdown-it": "13.0.1",
"path-browserify": "1.0.1",
- "pnpm": "7.14.1",
+ "pnpm": "7.15.0",
"prettier": "2.7.1",
"prettier-plugin-jsdoc": "0.4.2",
"remark": "14.0.2",
@@ -131,11 +131,11 @@
"ts-node": "10.9.1",
"typescript": "4.8.4",
"unist-util-flatmap": "1.0.0",
- "vite": "3.2.2",
- "vitepress": "1.0.0-alpha.26",
+ "vite": "3.2.3",
+ "vitepress": "1.0.0-alpha.28",
"vitepress-plugin-mermaid": "2.0.8",
- "vitepress-plugin-search": "1.0.4-alpha.14",
- "vitest": "0.24.3"
+ "vitepress-plugin-search": "1.0.4-alpha.15",
+ "vitest": "0.25.1"
},
"resolutions": {
"d3": "7.6.1"
@@ -148,6 +148,6 @@
"**/*.scss"
],
"volta": {
- "node": "18.12.0"
+ "node": "18.12.1"
}
}
diff --git a/packages/mermaid/package.json b/packages/mermaid/package.json
index f7b54eba9..50c79dd05 100644
--- a/packages/mermaid/package.json
+++ b/packages/mermaid/package.json
@@ -36,7 +36,7 @@
"docs:verify": "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 && vitepress build src/vitepress",
- "docs:dev": "pnpm docs:pre:vitepress && vitepress dev src/vitepress",
+ "docs:dev": "pnpm docs:pre:vitepress && concurrently \"vitepress dev src/vitepress\" \"ts-node-esm src/docs.mts --watch --vitepress\"",
"docs:serve": "pnpm docs:build:vitepress && vitepress serve src/vitepress",
"release": "pnpm build",
"lint": "eslint --cache --ignore-path .gitignore . && pnpm lint:jison && prettier --check .",
@@ -69,7 +69,7 @@
"d3": "^7.0.0",
"dagre": "^0.8.5",
"dagre-d3": "^0.6.4",
- "dompurify": "2.4.0",
+ "dompurify": "2.4.1",
"fast-clone": "^1.5.13",
"graphlib": "^2.1.8",
"khroma": "^2.0.0",
@@ -80,40 +80,43 @@
},
"devDependencies": {
"@applitools/eyes-cypress": "3.27.6",
- "@commitlint/cli": "17.1.2",
- "@commitlint/config-conventional": "17.1.0",
+ "@commitlint/cli": "17.2.0",
+ "@commitlint/config-conventional": "17.2.0",
"@types/d3": "7.4.0",
- "@types/dompurify": "2.3.4",
- "@types/eslint": "8.4.9",
+ "@types/dompurify": "2.4.0",
+ "@types/eslint": "8.4.10",
"@types/express": "4.17.14",
- "@types/jsdom": "20.0.0",
- "@types/lodash": "4.14.186",
+ "@types/jsdom": "20.0.1",
+ "@types/lodash": "4.14.188",
+ "@types/micromatch": "4.0.2",
"@types/prettier": "2.7.1",
"@types/stylis": "4.0.2",
- "@typescript-eslint/eslint-plugin": "5.41.0",
- "@typescript-eslint/parser": "5.41.0",
+ "@typescript-eslint/eslint-plugin": "5.42.1",
+ "@typescript-eslint/parser": "5.42.1",
+ "chokidar": "3.5.3",
"concurrently": "7.5.0",
"coveralls": "3.1.1",
"cypress": "10.11.0",
"cypress-image-snapshot": "4.0.1",
"documentation": "13.2.5",
- "esbuild": "0.15.12",
- "eslint": "8.26.0",
+ "esbuild": "0.15.13",
+ "eslint": "8.27.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-cypress": "2.12.1",
"eslint-plugin-html": "7.1.0",
- "eslint-plugin-jest": "27.1.3",
- "eslint-plugin-jsdoc": "39.4.0",
+ "eslint-plugin-jest": "27.1.5",
+ "eslint-plugin-jsdoc": "39.6.2",
"eslint-plugin-json": "3.1.0",
"eslint-plugin-markdown": "3.0.0",
"express": "4.18.2",
"globby": "13.1.2",
- "husky": "8.0.1",
+ "husky": "8.0.2",
"identity-obj-proxy": "3.0.0",
"jison": "0.4.18",
"js-base64": "3.7.2",
"jsdom": "20.0.2",
"lint-staged": "13.0.3",
+ "micromatch": "^4.0.5",
"moment": "2.29.4",
"path-browserify": "1.0.1",
"prettier": "2.7.1",
diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.js b/packages/mermaid/src/diagrams/flowchart/flowDb.js
index e91ab2fef..6abc22659 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.js
@@ -17,7 +17,7 @@ let vertexCounter = 0;
let config = configApi.getConfig();
let vertices = {};
let edges = [];
-let classes = [];
+let classes = {};
let subGraphs = [];
let subGraphLookup = {};
let tooltips = {};
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
index 0c3aa3623..c403b7fe3 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
@@ -279,7 +279,8 @@ export const getClasses = function (text, diagObj) {
diagObj.parse(text);
return diagObj.db.getClasses();
} catch (e) {
- return;
+ log.error(e);
+ return {};
}
};
diff --git a/packages/mermaid/src/docs.mts b/packages/mermaid/src/docs.mts
index 96f5e9024..f4dcf1344 100644
--- a/packages/mermaid/src/docs.mts
+++ b/packages/mermaid/src/docs.mts
@@ -30,7 +30,7 @@
* @todo Write a test file for this. (Will need to be able to deal .mts file. Jest has trouble with
* it.)
*/
-import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
+import { readFileSync, writeFileSync, mkdirSync, existsSync, rmSync, rmdirSync } from 'fs';
import { exec } from 'child_process';
import { globby } from 'globby';
import { JSDOM } from 'jsdom';
@@ -38,6 +38,8 @@ import type { Code, Root } from 'mdast';
import { posix, dirname, relative } from 'path';
import prettier from 'prettier';
import { remark } from 'remark';
+import chokidar from 'chokidar';
+import mm from 'micromatch';
// @ts-ignore No typescript declaration file
import flatmap from 'unist-util-flatmap';
@@ -47,6 +49,7 @@ const MERMAID_MAJOR_VERSION = (
const verifyOnly: boolean = process.argv.includes('--verify');
const git: boolean = process.argv.includes('--git');
+const watch: boolean = process.argv.includes('--watch');
const vitepress: boolean = process.argv.includes('--vitepress');
const noHeader: boolean = process.argv.includes('--noHeader') || vitepress;
@@ -61,14 +64,7 @@ const LOGMSG_COPIED = `, and copied to ${FINAL_DOCS_DIR}`;
const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DOCS_DIR} but do not match the files in ${FINAL_DOCS_DIR}. Please run 'pnpm --filter mermaid run docs:build' after making changes to ${SOURCE_DOCS_DIR} to update the ${FINAL_DOCS_DIR} directory with the transformed files.`;
-// TODO: Read from .prettierrc?
-const prettierConfig: prettier.Config = {
- useTabs: false,
- tabWidth: 2,
- endOfLine: 'auto',
- printWidth: 100,
- singleQuote: true,
-};
+const prettierConfig = prettier.resolveConfig.sync('.') ?? {};
let filesWereTransformed = false;
@@ -246,11 +242,15 @@ const transformHtml = (filename: string) => {
copyTransformedContents(filename, !verifyOnly, formattedHTML);
};
-const getFilesFromGlobs = async (globs: string[]): Promise => {
+const getGlobs = (globs: string[]): string[] => {
globs.push('!**/dist');
if (!vitepress) {
globs.push('!**/.vitepress', '!**/vite.config.ts', '!src/docs/index.md');
}
+ return globs;
+};
+
+const getFilesFromGlobs = async (globs: string[]): Promise => {
return await globby(globs, { dot: true });
};
@@ -263,15 +263,18 @@ const getFilesFromGlobs = async (globs: string[]): Promise => {
const sourceDirGlob = posix.join('.', SOURCE_DOCS_DIR, '**');
const action = verifyOnly ? 'Verifying' : 'Transforming';
- const mdFiles = await getFilesFromGlobs([posix.join(sourceDirGlob, '*.md')]);
+ const mdFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.md')]);
+ const mdFiles = await getFilesFromGlobs(mdFileGlobs);
console.log(`${action} ${mdFiles.length} markdown files...`);
mdFiles.forEach(transformMarkdown);
- const htmlFiles = await getFilesFromGlobs([posix.join(sourceDirGlob, '*.html')]);
+ const htmlFileGlobs = getGlobs([posix.join(sourceDirGlob, '*.html')]);
+ const htmlFiles = await getFilesFromGlobs(htmlFileGlobs);
console.log(`${action} ${htmlFiles.length} html files...`);
htmlFiles.forEach(transformHtml);
- const otherFiles = await getFilesFromGlobs([sourceDirGlob, '!**/*.md', '!**/*.html']);
+ const otherFileGlobs = getGlobs([sourceDirGlob, '!**/*.md', '!**/*.html']);
+ const otherFiles = await getFilesFromGlobs(otherFileGlobs);
console.log(`${action} ${otherFiles.length} other files...`);
otherFiles.forEach((file: string) => {
copyTransformedContents(file, !verifyOnly); // no transformation
@@ -287,4 +290,32 @@ const getFilesFromGlobs = async (globs: string[]): Promise => {
exec(`git add ${FINAL_DOCS_DIR}`);
}
}
+
+ if (watch) {
+ console.log(`Watching for changes in ${SOURCE_DOCS_DIR}`);
+
+ const matcher = (globs: string[]) => (file: string) => mm.every(file, globs);
+ const isMd = matcher(mdFileGlobs);
+ const isHtml = matcher(htmlFileGlobs);
+ const isOther = matcher(otherFileGlobs);
+
+ chokidar
+ .watch(SOURCE_DOCS_DIR)
+ // Delete files from the final docs dir if they are deleted from the source dir
+ .on('unlink', (file: string) => rmSync(changeToFinalDocDir(file)))
+ .on('unlinkDir', (file: string) => rmdirSync(changeToFinalDocDir(file)))
+ .on('all', (event, path) => {
+ // Ignore other events.
+ if (!['add', 'change'].includes(event)) {
+ return;
+ }
+ if (isMd(path)) {
+ transformMarkdown(path);
+ } else if (isHtml(path)) {
+ transformHtml(path);
+ } else if (isOther(path)) {
+ copyTransformedContents(path, true);
+ }
+ });
+ }
})();
diff --git a/packages/mermaid/src/docs/config/directives.md b/packages/mermaid/src/docs/config/directives.md
index 9060afdcf..bc74ad309 100644
--- a/packages/mermaid/src/docs/config/directives.md
+++ b/packages/mermaid/src/docs/config/directives.md
@@ -24,7 +24,7 @@ Mermaid basically supports two types of configuration options to be overridden b
2. _Diagram specific configurations_ : These are the configurations that are available and applied to a specific diagram. For each diagram there are specific configuration that will alter how that particular diagram looks and behaves.
For example, `mirrorActors` is a configuration that is specific to the `SequenceDiagram` and alter whether the actors are mirrored or not. So this config is available only for the `SequenceDiagram` type.
-**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code.
+**NOTE:** These options listed here are not all the configuration options. To get hold of all the configuration options, please refer to the [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code.
```
Soon we plan to publish a complete list of top-level configurations & all the diagram specific configurations, with their possible values in the docs
@@ -188,7 +188,7 @@ Some common flowchart configurations are:
- _diagramPadding_: number
- _useMaxWidth_: number
-For complete list of flowchart configurations, see [defaultConfig.js](https://github.com/mermaid-js/mermaid/blob/develop/src/defaultConfig.js) in the source code.
+For complete list of flowchart configurations, see [defaultConfig.ts](https://github.com/mermaid-js/mermaid/blob/develop/packages/mermaid/src/defaultConfig.ts) in the source code.
_Soon we plan to publish a complete list all diagram specific configurations updated in the docs_
The following code snippet changes flowchart config:
@@ -221,7 +221,7 @@ Some common sequence configurations are:
- _showSequenceNumbers_: boolean
- _wrap_: boolean
-For complete list of sequence diagram configurations, see _defaultConfig.js_ in the source code.
+For complete list of sequence diagram configurations, see _defaultConfig.ts_ in the source code.
_Soon we plan to publish a complete list all diagram specific configurations updated in the docs_
So, `wrap` by default has a value of `false` for sequence diagrams.
diff --git a/packages/mermaid/src/mermaidAPI.spec.js b/packages/mermaid/src/mermaidAPI.spec.js
deleted file mode 100644
index 241b5ec86..000000000
--- a/packages/mermaid/src/mermaidAPI.spec.js
+++ /dev/null
@@ -1,150 +0,0 @@
-'use strict';
-import mermaid from './mermaid';
-import mermaidAPI from './mermaidAPI';
-import assignWithDepth from './assignWithDepth';
-
-describe('when using mermaidAPI and ', function () {
- describe('doing initialize ', function () {
- beforeEach(function () {
- document.body.innerHTML = '';
- mermaidAPI.globalReset();
- });
-
- it('should copy a literal into the configuration', function () {
- const orgConfig = mermaidAPI.getConfig();
- expect(orgConfig.testLiteral).toBe(undefined);
-
- mermaidAPI.initialize({ testLiteral: true });
- const config = mermaidAPI.getConfig();
-
- expect(config.testLiteral).toBe(true);
- });
- it('should copy a an object into the configuration', function () {
- const orgConfig = mermaidAPI.getConfig();
- expect(orgConfig.testObject).toBe(undefined);
-
- const object = {
- test1: 1,
- test2: false,
- };
-
- mermaidAPI.initialize({ testObject: object });
- let config = mermaidAPI.getConfig();
-
- expect(config.testObject.test1).toBe(1);
- mermaidAPI.updateSiteConfig({ testObject: { test3: true } });
- config = mermaidAPI.getConfig();
-
- expect(config.testObject.test1).toBe(1);
- expect(config.testObject.test2).toBe(false);
- expect(config.testObject.test3).toBe(true);
- });
- it('should reset mermaid config to global defaults', function () {
- let config = {
- logLevel: 0,
- securityLevel: 'loose',
- };
- mermaidAPI.initialize(config);
- mermaidAPI.setConfig({ securityLevel: 'strict', logLevel: 1 });
- expect(mermaidAPI.getConfig().logLevel).toBe(1);
- expect(mermaidAPI.getConfig().securityLevel).toBe('strict');
- mermaidAPI.reset();
- expect(mermaidAPI.getConfig().logLevel).toBe(0);
- expect(mermaidAPI.getConfig().securityLevel).toBe('loose');
- mermaidAPI.globalReset();
- expect(mermaidAPI.getConfig().logLevel).toBe(5);
- expect(mermaidAPI.getConfig().securityLevel).toBe('strict');
- });
-
- it('should prevent changes to site defaults (sneaky)', function () {
- let config = {
- logLevel: 0,
- };
- mermaidAPI.initialize(config);
- const siteConfig = mermaidAPI.getSiteConfig();
- expect(mermaidAPI.getConfig().logLevel).toBe(0);
- config.secure = {
- toString: function () {
- mermaidAPI.initialize({ securityLevel: 'loose' });
- },
- };
- // mermaidAPI.reinitialize(config);
- expect(mermaidAPI.getConfig().secure).toEqual(mermaidAPI.getSiteConfig().secure);
- expect(mermaidAPI.getConfig().securityLevel).toBe('strict');
- mermaidAPI.reset();
- expect(mermaidAPI.getSiteConfig()).toEqual(siteConfig);
- expect(mermaidAPI.getConfig()).toEqual(siteConfig);
- });
- it('should prevent clobbering global defaults (direct)', function () {
- let config = assignWithDepth({}, mermaidAPI.defaultConfig);
- assignWithDepth(config, { logLevel: 0 });
-
- let error = { message: '' };
- try {
- mermaidAPI['defaultConfig'] = config;
- } catch (e) {
- error = e;
- }
- expect(error.message).toBe(
- "Cannot assign to read only property 'defaultConfig' of object '#