mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-10-17 21:19:41 +02:00
Compare commits
1 Commits
feature/fr
...
sidv/fixTy
Author | SHA1 | Date | |
---|---|---|---|
![]() |
11b599d77c |
@@ -48,6 +48,7 @@ module.exports = {
|
||||
'no-prototype-builtins': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'cypress/no-async-tests': 'off',
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/no-misused-promises': 'error',
|
||||
'@typescript-eslint/ban-ts-comment': [
|
||||
|
@@ -44,7 +44,6 @@
|
||||
"faber",
|
||||
"flatmap",
|
||||
"foswiki",
|
||||
"frontmatter",
|
||||
"ftplugin",
|
||||
"gantt",
|
||||
"gitea",
|
||||
|
@@ -14,6 +14,7 @@ describe('Configuration and directives - nodes should be light blue', () => {
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from initialize - nodes should be green', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -27,6 +28,7 @@ graph TD
|
||||
end `,
|
||||
{ theme: 'forest' }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from initialize overriding themeVariable - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -44,6 +46,7 @@ graph TD
|
||||
`,
|
||||
{ theme: 'base', themeVariables: { primaryColor: '#ff0000' }, logLevel: 0 }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from directive - nodes should be grey', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -59,24 +62,7 @@ graph TD
|
||||
`,
|
||||
{}
|
||||
);
|
||||
});
|
||||
it('Settings from frontmatter - nodes should be grey', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
---
|
||||
config:
|
||||
theme: neutral
|
||||
---
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
A[/Another/] --> C[End]
|
||||
subgraph section
|
||||
B
|
||||
C
|
||||
end
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
|
||||
it('Settings from directive overriding theme variable - nodes should be red', () => {
|
||||
@@ -93,6 +79,7 @@ graph TD
|
||||
`,
|
||||
{}
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Settings from initialize and directive - nodes should be grey', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -108,6 +95,7 @@ graph TD
|
||||
`,
|
||||
{ theme: 'forest' }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Theme from initialize, directive overriding theme variable - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
@@ -123,71 +111,8 @@ graph TD
|
||||
`,
|
||||
{ theme: 'base' }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
it('Theme from initialize, frontmatter overriding theme variable - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
---
|
||||
config:
|
||||
theme: base
|
||||
themeVariables:
|
||||
primaryColor: '#ff0000'
|
||||
---
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
A[/Another/] --> C[End]
|
||||
subgraph section
|
||||
B
|
||||
C
|
||||
end
|
||||
`,
|
||||
{ theme: 'forest' }
|
||||
);
|
||||
});
|
||||
it('Theme from initialize, frontmatter overriding theme variable, directive overriding primaryColor - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
---
|
||||
config:
|
||||
theme: base
|
||||
themeVariables:
|
||||
primaryColor: '#00ff00'
|
||||
---
|
||||
%%{init: {'theme': 'base', 'themeVariables':{ 'primaryColor': '#ff0000'}}}%%
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
A[/Another/] --> C[End]
|
||||
subgraph section
|
||||
B
|
||||
C
|
||||
end
|
||||
`,
|
||||
{ theme: 'forest' }
|
||||
);
|
||||
});
|
||||
|
||||
it('should render if values are not quoted properly', () => {
|
||||
// #ff0000 is not quoted properly, and will evaluate to null.
|
||||
// This test ensures that the rendering still works.
|
||||
imgSnapshotTest(
|
||||
`---
|
||||
config:
|
||||
theme: base
|
||||
themeVariables:
|
||||
primaryColor: #ff0000
|
||||
---
|
||||
graph TD
|
||||
A(Start) --> B[/Another/]
|
||||
A[/Another/] --> C[End]
|
||||
subgraph section
|
||||
B
|
||||
C
|
||||
end
|
||||
`,
|
||||
{ theme: 'forest' }
|
||||
);
|
||||
});
|
||||
|
||||
it('Theme variable from initialize, theme from directive - nodes should be red', () => {
|
||||
imgSnapshotTest(
|
||||
`
|
||||
@@ -202,11 +127,13 @@ graph TD
|
||||
`,
|
||||
{ themeVariables: { primaryColor: '#ff0000' } }
|
||||
);
|
||||
cy.get('svg');
|
||||
});
|
||||
describe('when rendering several diagrams', () => {
|
||||
it('diagrams should not taint later diagrams', () => {
|
||||
const url = 'http://localhost:9000/theme-directives.html';
|
||||
cy.visit(url);
|
||||
cy.get('svg');
|
||||
cy.matchImageSnapshot('conf-and-directives.spec-when-rendering-several-diagrams-diagram-1');
|
||||
});
|
||||
});
|
||||
|
@@ -21,8 +21,6 @@
|
||||
<pre class="mermaid">
|
||||
---
|
||||
title: This is a title
|
||||
config:
|
||||
theme: forest
|
||||
---
|
||||
erDiagram
|
||||
%% title This is a title
|
||||
|
@@ -123,13 +123,6 @@
|
||||
|
||||
<h3>flowchart</h3>
|
||||
<pre class="mermaid">
|
||||
---
|
||||
title: This is another complicated flow
|
||||
config:
|
||||
theme: base
|
||||
flowchart:
|
||||
curve: cardinal
|
||||
---
|
||||
flowchart LR
|
||||
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
|
||||
|
||||
|
@@ -10,41 +10,10 @@ When mermaid starts, configuration is extracted to determine a configuration to
|
||||
|
||||
- The default configuration
|
||||
- Overrides at the site level are set by the initialize call, and will be applied to all diagrams in the site/app. The term for this is the **siteConfig**.
|
||||
- Frontmatter (v\<MERMAID_RELEASE_VERSION>+) - diagram authors can update select configuration parameters in the frontmatter of the diagram. These are applied to the render config.
|
||||
- Directives (Deprecated by Frontmatter) - diagram authors can update select configuration parameters directly in the diagram code via directives. These are applied to the render config.
|
||||
- Directives - diagram authors can update select configuration parameters directly in the diagram code via directives. These are applied to the render config.
|
||||
|
||||
**The render config** is configuration that is used when rendering by applying these configurations.
|
||||
|
||||
## Frontmatter config
|
||||
|
||||
The entire mermaid configuration (except the secure configs) can be overridden by the diagram author in the frontmatter of the diagram. The frontmatter is a YAML block at the top of the diagram.
|
||||
|
||||
```mermaid-example
|
||||
---
|
||||
title: Hello Title
|
||||
config:
|
||||
theme: base
|
||||
themeVariables:
|
||||
primaryColor: "#00ff00"
|
||||
---
|
||||
flowchart
|
||||
Hello --> World
|
||||
|
||||
```
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Hello Title
|
||||
config:
|
||||
theme: base
|
||||
themeVariables:
|
||||
primaryColor: "#00ff00"
|
||||
---
|
||||
flowchart
|
||||
Hello --> World
|
||||
|
||||
```
|
||||
|
||||
## Theme configuration
|
||||
|
||||
## Starting mermaid
|
||||
|
@@ -6,9 +6,6 @@
|
||||
|
||||
# Directives
|
||||
|
||||
> **Warning**
|
||||
> Directives are deprecated from v\<MERMAID_RELEASE_VERSION>. Please use the `config` key in frontmatter to pass configuration. See [Configuration](./configuration.md) for more details.
|
||||
|
||||
## Directives
|
||||
|
||||
Directives give a diagram author the capability to alter the appearance of a diagram before rendering by changing the applied configuration.
|
||||
|
@@ -16,4 +16,4 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:78](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L78)
|
||||
[mermaidAPI.ts:77](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L77)
|
||||
|
@@ -39,7 +39,7 @@ bindFunctions?.(div); // To call bindFunctions only if it's present.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:98](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L98)
|
||||
[mermaidAPI.ts:97](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L97)
|
||||
|
||||
---
|
||||
|
||||
@@ -51,4 +51,4 @@ The svg code for the rendered graph.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:88](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L88)
|
||||
[mermaidAPI.ts:87](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L87)
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[config.ts:8](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L8)
|
||||
[config.ts:7](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L7)
|
||||
|
||||
## Functions
|
||||
|
||||
@@ -26,9 +26,9 @@ Pushes in a directive to the configuration
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :---------- | :-------------- | :----------------------- |
|
||||
| `directive` | `MermaidConfig` | The directive to push in |
|
||||
| Name | Type | Description |
|
||||
| :---------- | :---- | :----------------------- |
|
||||
| `directive` | `any` | The directive to push in |
|
||||
|
||||
#### Returns
|
||||
|
||||
@@ -36,7 +36,7 @@ Pushes in a directive to the configuration
|
||||
|
||||
#### Defined in
|
||||
|
||||
[config.ts:188](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L188)
|
||||
[config.ts:191](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L191)
|
||||
|
||||
---
|
||||
|
||||
@@ -60,7 +60,7 @@ The currentConfig
|
||||
|
||||
#### Defined in
|
||||
|
||||
[config.ts:131](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L131)
|
||||
[config.ts:137](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L137)
|
||||
|
||||
---
|
||||
|
||||
@@ -118,7 +118,7 @@ The siteConfig
|
||||
|
||||
#### Defined in
|
||||
|
||||
[config.ts:218](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L218)
|
||||
[config.ts:223](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L223)
|
||||
|
||||
---
|
||||
|
||||
@@ -147,7 +147,7 @@ options in-place
|
||||
|
||||
#### Defined in
|
||||
|
||||
[config.ts:146](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L146)
|
||||
[config.ts:152](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L152)
|
||||
|
||||
---
|
||||
|
||||
@@ -242,10 +242,10 @@ The new siteConfig
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------------ | :----------------- |
|
||||
| `siteCfg` | `MermaidConfig` |
|
||||
| `_directives` | `MermaidConfig`\[] |
|
||||
| Name | Type |
|
||||
| :------------ | :-------------- |
|
||||
| `siteCfg` | `MermaidConfig` |
|
||||
| `_directives` | `any`\[] |
|
||||
|
||||
#### Returns
|
||||
|
||||
@@ -253,7 +253,7 @@ The new siteConfig
|
||||
|
||||
#### Defined in
|
||||
|
||||
[config.ts:15](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L15)
|
||||
[config.ts:14](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/config.ts#L14)
|
||||
|
||||
---
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
|
||||
### configKeys
|
||||
|
||||
• `Const` **configKeys**: `Set`<`string`>
|
||||
• `Const` **configKeys**: `string`\[]
|
||||
|
||||
#### Defined in
|
||||
|
||||
|
@@ -25,7 +25,7 @@ Renames and re-exports [mermaidAPI](mermaidAPI.md#mermaidapi)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:82](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L82)
|
||||
[mermaidAPI.ts:81](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L81)
|
||||
|
||||
## Variables
|
||||
|
||||
@@ -96,7 +96,7 @@ mermaid.initialize(config);
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:673](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L673)
|
||||
[mermaidAPI.ts:668](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L668)
|
||||
|
||||
## Functions
|
||||
|
||||
@@ -127,7 +127,7 @@ Return the last node appended
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:310](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L310)
|
||||
[mermaidAPI.ts:309](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L309)
|
||||
|
||||
---
|
||||
|
||||
@@ -153,7 +153,7 @@ the cleaned up svgCode
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:256](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L256)
|
||||
[mermaidAPI.ts:255](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L255)
|
||||
|
||||
---
|
||||
|
||||
@@ -179,7 +179,7 @@ the string with all the user styles
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:185](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L185)
|
||||
[mermaidAPI.ts:184](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L184)
|
||||
|
||||
---
|
||||
|
||||
@@ -202,7 +202,7 @@ the string with all the user styles
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:233](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L233)
|
||||
[mermaidAPI.ts:232](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L232)
|
||||
|
||||
---
|
||||
|
||||
@@ -229,7 +229,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:169](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L169)
|
||||
[mermaidAPI.ts:168](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L168)
|
||||
|
||||
---
|
||||
|
||||
@@ -249,7 +249,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:155](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L155)
|
||||
[mermaidAPI.ts:154](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L154)
|
||||
|
||||
---
|
||||
|
||||
@@ -269,7 +269,7 @@ with an enclosing block that has each of the cssClasses followed by !important;
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:126](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L126)
|
||||
[mermaidAPI.ts:125](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L125)
|
||||
|
||||
---
|
||||
|
||||
@@ -295,7 +295,7 @@ Put the svgCode into an iFrame. Return the iFrame code
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:287](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L287)
|
||||
[mermaidAPI.ts:286](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L286)
|
||||
|
||||
---
|
||||
|
||||
@@ -320,4 +320,4 @@ Remove any existing elements from the given document
|
||||
|
||||
#### Defined in
|
||||
|
||||
[mermaidAPI.ts:360](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L360)
|
||||
[mermaidAPI.ts:359](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L359)
|
||||
|
@@ -48,7 +48,7 @@ export class Diagram {
|
||||
// extractFrontMatter().
|
||||
|
||||
this.parser.parse = (text: string) =>
|
||||
originalParse(cleanupComments(extractFrontMatter(text, this.db, configApi.addDirective)));
|
||||
originalParse(cleanupComments(extractFrontMatter(text, this.db)));
|
||||
|
||||
this.parser.parser.yy = this.db;
|
||||
this.init = diagram.init;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
/**
|
||||
* assignWithDepth Extends the functionality of {@link Object.assign} with the
|
||||
* assignWithDepth Extends the functionality of {@link ObjectConstructor.assign} with the
|
||||
* ability to merge arbitrary-depth objects For each key in src with path `k` (recursively)
|
||||
* performs an Object.assign(dst[`k`], src[`k`]) with a slight change from the typical handling of
|
||||
* undefined for dst[`k`]: instead of raising an error, dst[`k`] is auto-initialized to `{}` and
|
||||
|
@@ -1,13 +1,11 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import * as configApi from './config.js';
|
||||
import type { MermaidConfig } from './config.type.js';
|
||||
|
||||
describe('when working with site config', () => {
|
||||
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', () => {
|
||||
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();
|
||||
@@ -16,26 +14,19 @@ describe('when working with site config', () => {
|
||||
expect(config_1.fontSize).toEqual(config_0.fontSize);
|
||||
expect(config_1).toEqual(config_2);
|
||||
});
|
||||
it('should respect secure keys when applying directives', () => {
|
||||
const config_0: MermaidConfig = {
|
||||
it('should respect secure keys when applying directives', function () {
|
||||
const config_0 = {
|
||||
fontFamily: 'foo-font',
|
||||
securityLevel: 'strict', // can't be changed
|
||||
fontSize: 12345, // can't be changed
|
||||
secure: [...configApi.defaultConfig.secure!, 'fontSize'],
|
||||
};
|
||||
configApi.setSiteConfig(config_0);
|
||||
const directive: MermaidConfig = {
|
||||
fontFamily: 'baf',
|
||||
// fontSize and securityLevel shouldn't be changed
|
||||
fontSize: 54321,
|
||||
securityLevel: 'loose',
|
||||
};
|
||||
const cfg: MermaidConfig = configApi.updateCurrentConfig(config_0, [directive]);
|
||||
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);
|
||||
expect(cfg.securityLevel).toBe(config_0.securityLevel);
|
||||
});
|
||||
it('should allow setting partial options', () => {
|
||||
it('should allow setting partial options', function () {
|
||||
const defaultConfig = configApi.getConfig();
|
||||
|
||||
configApi.setConfig({
|
||||
@@ -51,7 +42,7 @@ describe('when working with site config', () => {
|
||||
updatedConfig.quadrantChart!.chartWidth
|
||||
);
|
||||
});
|
||||
it('should set reset config properly', () => {
|
||||
it('should set reset config properly', function () {
|
||||
const config_0 = { fontFamily: 'foo-font', fontSize: 150 };
|
||||
configApi.setSiteConfig(config_0);
|
||||
const config_1 = { fontFamily: 'baf' };
|
||||
@@ -64,7 +55,7 @@ describe('when working with site config', () => {
|
||||
const config_4 = configApi.getSiteConfig();
|
||||
expect(config_4.fontFamily).toEqual(config_0.fontFamily);
|
||||
});
|
||||
it('should set global reset config properly', () => {
|
||||
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();
|
||||
|
@@ -3,16 +3,15 @@ import { log } from './logger.js';
|
||||
import theme from './themes/index.js';
|
||||
import config from './defaultConfig.js';
|
||||
import type { MermaidConfig } from './config.type.js';
|
||||
import { sanitizeDirective } from './utils.js';
|
||||
|
||||
export const defaultConfig: MermaidConfig = Object.freeze(config);
|
||||
|
||||
let siteConfig: MermaidConfig = assignWithDepth({}, defaultConfig);
|
||||
let configFromInitialize: MermaidConfig;
|
||||
let directives: MermaidConfig[] = [];
|
||||
let directives: any[] = [];
|
||||
let currentConfig: MermaidConfig = assignWithDepth({}, defaultConfig);
|
||||
|
||||
export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: MermaidConfig[]) => {
|
||||
export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: any[]) => {
|
||||
// start with config being the siteConfig
|
||||
let cfg: MermaidConfig = assignWithDepth({}, siteCfg);
|
||||
// let sCfg = assignWithDepth(defaultConfig, siteConfigDelta);
|
||||
@@ -21,6 +20,7 @@ export const updateCurrentConfig = (siteCfg: MermaidConfig, _directives: Mermaid
|
||||
let sumOfDirectives: MermaidConfig = {};
|
||||
for (const d of _directives) {
|
||||
sanitize(d);
|
||||
|
||||
// Apply the data from the directive where the the overrides the themeVariables
|
||||
sumOfDirectives = assignWithDepth(sumOfDirectives, d);
|
||||
}
|
||||
@@ -111,6 +111,12 @@ export const getSiteConfig = (): MermaidConfig => {
|
||||
* @returns The currentConfig merged with the sanitized conf
|
||||
*/
|
||||
export const setConfig = (conf: MermaidConfig): MermaidConfig => {
|
||||
// sanitize(conf);
|
||||
// Object.keys(conf).forEach(key => {
|
||||
// const manipulator = manipulators[key];
|
||||
// conf[key] = manipulator ? manipulator(conf[key]) : conf[key];
|
||||
// });
|
||||
|
||||
checkConfig(conf);
|
||||
assignWithDepth(currentConfig, conf);
|
||||
|
||||
@@ -144,12 +150,9 @@ export const getConfig = (): MermaidConfig => {
|
||||
* @param options - The potential setConfig parameter
|
||||
*/
|
||||
export const sanitize = (options: any) => {
|
||||
if (!options) {
|
||||
return;
|
||||
}
|
||||
// Checking that options are not in the list of excluded options
|
||||
['secure', ...(siteConfig.secure ?? [])].forEach((key) => {
|
||||
if (Object.hasOwn(options, key)) {
|
||||
if (options[key] !== undefined) {
|
||||
// DO NOT attempt to print options[key] within `${}` as a malicious script
|
||||
// can exploit the logger's attempt to stringify the value and execute arbitrary code
|
||||
log.debug(`Denied attempt to modify a secure key ${key}`, options[key]);
|
||||
@@ -159,7 +162,7 @@ export const sanitize = (options: any) => {
|
||||
|
||||
// Check that there no attempts of prototype pollution
|
||||
Object.keys(options).forEach((key) => {
|
||||
if (key.startsWith('__')) {
|
||||
if (key.indexOf('__') === 0) {
|
||||
delete options[key];
|
||||
}
|
||||
});
|
||||
@@ -185,14 +188,16 @@ export const sanitize = (options: any) => {
|
||||
*
|
||||
* @param directive - The directive to push in
|
||||
*/
|
||||
export const addDirective = (directive: MermaidConfig) => {
|
||||
sanitizeDirective(directive);
|
||||
|
||||
// If the directive has a fontFamily, but no themeVariables, add the fontFamily to the themeVariables
|
||||
if (directive.fontFamily && (!directive.themeVariables || !directive.themeVariables.fontFamily)) {
|
||||
directive.themeVariables = { fontFamily: directive.fontFamily };
|
||||
export const addDirective = (directive: any) => {
|
||||
if (directive.fontFamily) {
|
||||
if (!directive.themeVariables) {
|
||||
directive.themeVariables = { fontFamily: directive.fontFamily };
|
||||
} else {
|
||||
if (!directive.themeVariables.fontFamily) {
|
||||
directive.themeVariables = { fontFamily: directive.fontFamily };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
directives.push(directive);
|
||||
updateCurrentConfig(siteConfig, directives);
|
||||
};
|
||||
|
@@ -265,5 +265,5 @@ const keyify = (obj: any, prefix = ''): string[] =>
|
||||
return [...res, prefix + el];
|
||||
}, []);
|
||||
|
||||
export const configKeys: Set<string> = new Set(keyify(config, ''));
|
||||
export const configKeys: string[] = keyify(config, '');
|
||||
export default config;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { MermaidConfig } from '../config.type.js';
|
||||
import type { MermaidConfig } from '../config.type.js';
|
||||
import { log } from '../logger.js';
|
||||
import type {
|
||||
DetectorRecord,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { detectType } from './detectType.js';
|
||||
import { getDiagram, registerDiagram } from './diagramAPI.js';
|
||||
import { addDiagrams } from './diagram-orchestration.js';
|
||||
import { DiagramDetector } from './types.js';
|
||||
import type { DiagramDetector } from './types.js';
|
||||
import { getDiagramFromText } from '../Diagram.js';
|
||||
import { it, describe, expect, beforeAll } from 'vitest';
|
||||
|
||||
|
@@ -2,13 +2,8 @@ import { vi } from 'vitest';
|
||||
import { extractFrontMatter } from './frontmatter.js';
|
||||
|
||||
const dbMock = () => ({ setDiagramTitle: vi.fn() });
|
||||
const setConfigMock = vi.fn();
|
||||
|
||||
describe('extractFrontmatter', () => {
|
||||
beforeEach(() => {
|
||||
setConfigMock.mockClear();
|
||||
});
|
||||
|
||||
it('returns text unchanged if no frontmatter', () => {
|
||||
expect(extractFrontMatter('diagram', dbMock())).toEqual('diagram');
|
||||
});
|
||||
@@ -80,21 +75,4 @@ describe('extractFrontmatter', () => {
|
||||
'tag suffix cannot contain exclamation marks'
|
||||
);
|
||||
});
|
||||
|
||||
it('handles frontmatter with config', () => {
|
||||
const text = `---
|
||||
title: hello
|
||||
config:
|
||||
graph:
|
||||
string: hello
|
||||
number: 14
|
||||
boolean: false
|
||||
array: [1, 2, 3]
|
||||
---
|
||||
diagram`;
|
||||
expect(extractFrontMatter(text, {}, setConfigMock)).toEqual('diagram');
|
||||
expect(setConfigMock).toHaveBeenCalledWith({
|
||||
graph: { string: 'hello', number: 14, boolean: false, array: [1, 2, 3] },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,53 +1,40 @@
|
||||
import type { MermaidConfig } from '../config.type.js';
|
||||
import { frontMatterRegex } from './regexes.js';
|
||||
import type { DiagramDB } from './types.js';
|
||||
import { frontMatterRegex } from './regexes.js';
|
||||
// The "* as yaml" part is necessary for tree-shaking
|
||||
import * as yaml from 'js-yaml';
|
||||
|
||||
interface FrontMatterMetadata {
|
||||
type FrontMatterMetadata = {
|
||||
title?: string;
|
||||
// Allows custom display modes. Currently used for compact mode in gantt charts.
|
||||
displayMode?: string;
|
||||
config?: MermaidConfig;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Extract and parse frontmatter from text, if present, and sets appropriate
|
||||
* properties in the provided db.
|
||||
* @param text - The text that may have a YAML frontmatter.
|
||||
* @param db - Diagram database, could be of any diagram.
|
||||
* @param setDiagramConfig - Optional function to set diagram config.
|
||||
* @returns text with frontmatter stripped out
|
||||
*/
|
||||
export function extractFrontMatter(
|
||||
text: string,
|
||||
db: DiagramDB,
|
||||
setDiagramConfig?: (config: MermaidConfig) => void
|
||||
): string {
|
||||
export function extractFrontMatter(text: string, db: DiagramDB): string {
|
||||
const matches = text.match(frontMatterRegex);
|
||||
if (!matches) {
|
||||
if (matches) {
|
||||
const parsed: FrontMatterMetadata = yaml.load(matches[1], {
|
||||
// To keep things simple, only allow strings, arrays, and plain objects.
|
||||
// https://www.yaml.org/spec/1.2/spec.html#id2802346
|
||||
schema: yaml.FAILSAFE_SCHEMA,
|
||||
}) as FrontMatterMetadata;
|
||||
|
||||
if (parsed?.title) {
|
||||
db.setDiagramTitle?.(parsed.title);
|
||||
}
|
||||
|
||||
if (parsed?.displayMode) {
|
||||
db.setDisplayMode?.(parsed.displayMode);
|
||||
}
|
||||
|
||||
return text.slice(matches[0].length);
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
|
||||
const parsed: FrontMatterMetadata = yaml.load(matches[1], {
|
||||
// To support config, we need JSON schema.
|
||||
// https://www.yaml.org/spec/1.2/spec.html#id2803231
|
||||
schema: yaml.JSON_SCHEMA,
|
||||
}) as FrontMatterMetadata;
|
||||
|
||||
if (parsed?.title) {
|
||||
// toString() is necessary because YAML could parse the title as a number/boolean
|
||||
db.setDiagramTitle?.(parsed.title.toString());
|
||||
}
|
||||
|
||||
if (parsed?.displayMode) {
|
||||
// toString() is necessary because YAML could parse the title as a number/boolean
|
||||
db.setDisplayMode?.(parsed.displayMode.toString());
|
||||
}
|
||||
|
||||
if (parsed?.config) {
|
||||
setDiagramConfig?.(parsed.config);
|
||||
}
|
||||
|
||||
return text.slice(matches[0].length);
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Diagram } from '../Diagram.js';
|
||||
import type { Diagram } from '../Diagram.js';
|
||||
import type { BaseDiagramConfig, MermaidConfig } from '../config.type.js';
|
||||
import type * as d3 from 'd3';
|
||||
|
||||
|
@@ -3,8 +3,8 @@ import c4Parser from './parser/c4Diagram.jison';
|
||||
import c4Db from './c4Db.js';
|
||||
import c4Renderer from './c4Renderer.js';
|
||||
import c4Styles from './styles.js';
|
||||
import { MermaidConfig } from '../../config.type.js';
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser: c4Parser,
|
||||
|
@@ -1,5 +1,6 @@
|
||||
// @ts-nocheck - don't check until handle it
|
||||
import { select, Selection } from 'd3';
|
||||
import type { Selection } from 'd3';
|
||||
import { select } from 'd3';
|
||||
import { log } from '../../logger.js';
|
||||
import * as configApi from '../../config.js';
|
||||
import common from '../common/common.js';
|
||||
@@ -14,7 +15,7 @@ import {
|
||||
setDiagramTitle,
|
||||
getDiagramTitle,
|
||||
} from '../../commonDb.js';
|
||||
import {
|
||||
import type {
|
||||
ClassRelation,
|
||||
ClassNode,
|
||||
ClassNote,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/classDiagram.jison';
|
||||
import db from './classDb.js';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/classDiagram.jison';
|
||||
import db from './classDb.js';
|
||||
|
@@ -8,7 +8,7 @@ import utils from '../../utils.js';
|
||||
import { interpolateToCurve, getStylesFromArray } from '../../utils.js';
|
||||
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
|
||||
import common from '../common/common.js';
|
||||
import { ClassRelation, ClassNote, ClassMap, EdgeData, NamespaceMap } from './classTypes.js';
|
||||
import type { ClassRelation, ClassNote, ClassMap, EdgeData, NamespaceMap } from './classTypes.js';
|
||||
|
||||
const sanitizeText = (txt: string) => common.sanitizeText(txt, getConfig());
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import DOMPurify from 'dompurify';
|
||||
import { MermaidConfig } from '../../config.type.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
|
||||
// Remove and ignore br:s
|
||||
export const lineBreakRegex = /<br\s*\/?>/gi;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { findCommonAncestor, TreeData } from './render-utils.js';
|
||||
import type { TreeData } from './render-utils.js';
|
||||
import { findCommonAncestor } from './render-utils.js';
|
||||
describe('when rendering a flowchart using elk ', () => {
|
||||
let lookupDb: TreeData;
|
||||
beforeEach(() => {
|
||||
|
@@ -3,7 +3,7 @@ import flowParser from './parser/flow.jison';
|
||||
import flowDb from './flowDb.js';
|
||||
import flowRendererV2 from './flowRenderer-v2.js';
|
||||
import flowStyles from './styles.js';
|
||||
import { MermaidConfig } from '../../config.type.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
import { setConfig } from '../../config.js';
|
||||
|
||||
export const diagram = {
|
||||
|
@@ -4,7 +4,7 @@ import flowDb from './flowDb.js';
|
||||
import flowRenderer from './flowRenderer.js';
|
||||
import flowRendererV2 from './flowRenderer-v2.js';
|
||||
import flowStyles from './styles.js';
|
||||
import { MermaidConfig } from '../../config.type.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
|
||||
export const diagram = {
|
||||
parser: flowParser,
|
||||
|
@@ -3,7 +3,7 @@ import ganttParser from './parser/gantt.jison';
|
||||
import ganttDb from './ganttDb.js';
|
||||
import ganttRenderer from './ganttRenderer.js';
|
||||
import ganttStyles from './styles.js';
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser: ganttParser,
|
||||
|
@@ -3,7 +3,7 @@ import gitGraphParser from './parser/gitGraph.jison';
|
||||
import gitGraphDb from './gitGraphAst.js';
|
||||
import gitGraphRenderer from './gitGraphRenderer.js';
|
||||
import gitGraphStyles from './styles.js';
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
|
||||
export const diagram: DiagramDefinition = {
|
||||
parser: gitGraphParser,
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import d3, { scaleOrdinal, pie as d3pie, arc } from 'd3';
|
||||
import type d3 from 'd3';
|
||||
import { scaleOrdinal, pie as d3pie, arc } from 'd3';
|
||||
|
||||
import { log } from '../../logger.js';
|
||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||
|
@@ -1,6 +1,7 @@
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import { parser } from './quadrant.jison';
|
||||
import { Mock, vi } from 'vitest';
|
||||
import type { Mock } from 'vitest';
|
||||
import { vi } from 'vitest';
|
||||
|
||||
const parserFnConstructor = (str: string) => {
|
||||
return () => {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/quadrant.jison';
|
||||
import db from './quadrantDb.js';
|
||||
|
@@ -3,8 +3,8 @@ import { select } from 'd3';
|
||||
import * as configApi from '../../config.js';
|
||||
import { log } from '../../logger.js';
|
||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||
import { Diagram } from '../../Diagram.js';
|
||||
import {
|
||||
import type { Diagram } from '../../Diagram.js';
|
||||
import type {
|
||||
QuadrantBuildType,
|
||||
QuadrantLineType,
|
||||
QuadrantPointType,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/requirementDiagram.jison';
|
||||
import db from './requirementDb.js';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: jison doesn't export types
|
||||
import parser from './parser/sankey.jison';
|
||||
import db from './sankeyDB.js';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Diagram } from '../../Diagram.js';
|
||||
import type { Diagram } from '../../Diagram.js';
|
||||
import * as configApi from '../../config.js';
|
||||
|
||||
import {
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
schemeTableau10 as d3schemeTableau10,
|
||||
} from 'd3';
|
||||
|
||||
import type { SankeyNode as d3SankeyNode } from 'd3-sankey';
|
||||
import {
|
||||
sankey as d3Sankey,
|
||||
sankeyLinkHorizontal as d3SankeyLinkHorizontal,
|
||||
@@ -14,7 +15,6 @@ import {
|
||||
sankeyRight as d3SankeyRight,
|
||||
sankeyCenter as d3SankeyCenter,
|
||||
sankeyJustify as d3SankeyJustify,
|
||||
SankeyNode as d3SankeyNode,
|
||||
} from 'd3-sankey';
|
||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||
import { Uid } from '../../rendering-util/uid.js';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/sequenceDiagram.jison';
|
||||
import db from './sequenceDb.js';
|
||||
|
@@ -8,7 +8,7 @@ import * as configApi from '../../config.js';
|
||||
import assignWithDepth from '../../assignWithDepth.js';
|
||||
import utils from '../../utils.js';
|
||||
import { configureSvgSize } from '../../setupGraphViewbox.js';
|
||||
import { Diagram } from '../../Diagram.js';
|
||||
import type { Diagram } from '../../Diagram.js';
|
||||
|
||||
let conf = {};
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/stateDiagram.jison';
|
||||
import db from './stateDb.js';
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/stateDiagram.jison';
|
||||
import db from './stateDb.js';
|
||||
|
@@ -1,11 +1,12 @@
|
||||
// @ts-nocheck - don't check until handle it
|
||||
import { select, Selection } from 'd3';
|
||||
import type { Selection } from 'd3';
|
||||
import { select } from 'd3';
|
||||
import svgDraw from './svgDraw.js';
|
||||
import { log } from '../../logger.js';
|
||||
import { getConfig } from '../../config.js';
|
||||
import { setupGraphViewbox } from '../../setupGraphViewbox.js';
|
||||
import { Diagram } from '../../Diagram.js';
|
||||
import { MermaidConfig } from '../../config.type.js';
|
||||
import type { Diagram } from '../../Diagram.js';
|
||||
import type { MermaidConfig } from '../../config.type.js';
|
||||
|
||||
interface Block<TDesc, TSection> {
|
||||
number: number;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
import type { DiagramDefinition } from '../../diagram-api/types.js';
|
||||
// @ts-ignore: JISON doesn't support types
|
||||
import parser from './parser/journey.jison';
|
||||
import db from './journeyDb.js';
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import * as configApi from './config.js';
|
||||
|
||||
import { log } from './logger.js';
|
||||
import { directiveSanitizer } from './utils.js';
|
||||
|
||||
let currentDirective: { type?: string; args?: any } | undefined = {};
|
||||
|
||||
@@ -58,6 +60,9 @@ const handleDirective = function (p: any, directive: any, type: string): void {
|
||||
delete directive.args[prop];
|
||||
}
|
||||
});
|
||||
log.info('sanitize in handleDirective', directive.args);
|
||||
directiveSanitizer(directive.args);
|
||||
log.info('sanitize in handleDirective (done)', directive.args);
|
||||
configApi.addDirective(directive.args);
|
||||
break;
|
||||
}
|
||||
|
@@ -4,28 +4,10 @@ When mermaid starts, configuration is extracted to determine a configuration to
|
||||
|
||||
- The default configuration
|
||||
- Overrides at the site level are set by the initialize call, and will be applied to all diagrams in the site/app. The term for this is the **siteConfig**.
|
||||
- Frontmatter (v<MERMAID_RELEASE_VERSION>+) - diagram authors can update select configuration parameters in the frontmatter of the diagram. These are applied to the render config.
|
||||
- Directives (Deprecated by Frontmatter) - diagram authors can update select configuration parameters directly in the diagram code via directives. These are applied to the render config.
|
||||
- Directives - diagram authors can update select configuration parameters directly in the diagram code via directives. These are applied to the render config.
|
||||
|
||||
**The render config** is configuration that is used when rendering by applying these configurations.
|
||||
|
||||
## Frontmatter config
|
||||
|
||||
The entire mermaid configuration (except the secure configs) can be overridden by the diagram author in the frontmatter of the diagram. The frontmatter is a YAML block at the top of the diagram.
|
||||
|
||||
```mermaid-example
|
||||
---
|
||||
title: Hello Title
|
||||
config:
|
||||
theme: base
|
||||
themeVariables:
|
||||
primaryColor: "#00ff00"
|
||||
---
|
||||
flowchart
|
||||
Hello --> World
|
||||
|
||||
```
|
||||
|
||||
## Theme configuration
|
||||
|
||||
## Starting mermaid
|
||||
|
@@ -1,9 +1,5 @@
|
||||
# Directives
|
||||
|
||||
```warning
|
||||
Directives are deprecated from v<MERMAID_RELEASE_VERSION>. Please use the `config` key in frontmatter to pass configuration. See [Configuration](./configuration.md) for more details.
|
||||
```
|
||||
|
||||
## Directives
|
||||
|
||||
Directives give a diagram author the capability to alter the appearance of a diagram before rendering by changing the applied configuration.
|
||||
|
@@ -3,17 +3,18 @@
|
||||
* functionality and to render the diagrams to svg code!
|
||||
*/
|
||||
import { dedent } from 'ts-dedent';
|
||||
import { MermaidConfig } from './config.type.js';
|
||||
import type { MermaidConfig } from './config.type.js';
|
||||
import { log } from './logger.js';
|
||||
import utils from './utils.js';
|
||||
import { mermaidAPI, ParseOptions, RenderResult } from './mermaidAPI.js';
|
||||
import type { ParseOptions, RenderResult } from './mermaidAPI.js';
|
||||
import { mermaidAPI } from './mermaidAPI.js';
|
||||
import { registerLazyLoadedDiagrams, detectType } from './diagram-api/detectType.js';
|
||||
import { loadRegisteredDiagrams } from './diagram-api/loadDiagram.js';
|
||||
import type { ParseErrorFunction } from './Diagram.js';
|
||||
import { isDetailedError } from './utils.js';
|
||||
import type { DetailedError } from './utils.js';
|
||||
import { ExternalDiagramDefinition } from './diagram-api/types.js';
|
||||
import { UnknownDiagramError } from './errors.js';
|
||||
import type { ExternalDiagramDefinition } from './diagram-api/types.js';
|
||||
import type { UnknownDiagramError } from './errors.js';
|
||||
|
||||
export type {
|
||||
MermaidConfig,
|
||||
|
@@ -34,7 +34,7 @@ vi.mock('./diagrams/state/stateRenderer-v2.js');
|
||||
// -------------------------------------
|
||||
|
||||
import mermaid from './mermaid.js';
|
||||
import { MermaidConfig } from './config.type.js';
|
||||
import type { MermaidConfig } from './config.type.js';
|
||||
|
||||
import mermaidAPI, { removeExistingElements } from './mermaidAPI.js';
|
||||
import {
|
||||
|
@@ -23,14 +23,13 @@ import { attachFunctions } from './interactionDb.js';
|
||||
import { log, setLogLevel } from './logger.js';
|
||||
import getStyles from './styles.js';
|
||||
import theme from './themes/index.js';
|
||||
import utils from './utils.js';
|
||||
import utils, { directiveSanitizer } from './utils.js';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { MermaidConfig } from './config.type.js';
|
||||
import type { MermaidConfig } from './config.type.js';
|
||||
import { evaluate } from './diagrams/common/common.js';
|
||||
import isEmpty from 'lodash-es/isEmpty.js';
|
||||
import { setA11yDiagramInfo, addSVGa11yTitleDescription } from './accessibility.js';
|
||||
import { parseDirective } from './directiveUtils.js';
|
||||
import { extractFrontMatter } from './diagram-api/frontmatter.js';
|
||||
|
||||
// diagram names that support classDef statements
|
||||
const CLASSDEF_DIAGRAMS = [
|
||||
@@ -386,14 +385,10 @@ const render = async function (
|
||||
|
||||
configApi.reset();
|
||||
|
||||
// We need to add the directives before creating the diagram.
|
||||
// So extractFrontMatter is called twice. Once here and once in the diagram parser.
|
||||
// This can be fixed in a future refactor.
|
||||
extractFrontMatter(text, {}, configApi.addDirective);
|
||||
|
||||
// Add Directives.
|
||||
// Add Directives. Must do this before getting the config and before creating the diagram.
|
||||
const graphInit = utils.detectInit(text);
|
||||
if (graphInit) {
|
||||
directiveSanitizer(graphInit);
|
||||
configApi.addDirective(graphInit);
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,7 @@ import { log } from '../logger.js';
|
||||
import { decodeEntities } from '../mermaidAPI.js';
|
||||
import { markdownToHTML, markdownToLines } from '../rendering-util/handle-markdown-text.js';
|
||||
import { splitLineToFitWidth } from './splitText.js';
|
||||
import { MarkdownLine, MarkdownWord } from './types.js';
|
||||
import type { MarkdownLine, MarkdownWord } from './types.js';
|
||||
|
||||
function applyStyle(dom, styleFn) {
|
||||
if (styleFn) {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import type { Content } from 'mdast';
|
||||
import { fromMarkdown } from 'mdast-util-from-markdown';
|
||||
import { dedent } from 'ts-dedent';
|
||||
import { MarkdownLine, MarkdownWordType } from './types.js';
|
||||
import type { MarkdownLine, MarkdownWordType } from './types.js';
|
||||
|
||||
/**
|
||||
* @param markdown - markdown to process
|
||||
|
@@ -13,10 +13,10 @@
|
||||
# Non-JSON values, like functions or `undefined`, still need to be manually
|
||||
# set in `src/defaultConfig.ts`)
|
||||
# - `src/docs.mts`
|
||||
# Used to generate Markdown documentation for this JSON Schema by using
|
||||
# Used to genereate Markdown documentation for this JSON Schema by using
|
||||
# the `@adobe/jsonschema2md` NPM package.
|
||||
|
||||
# Useful things to know when editing this file
|
||||
# Useful things to know when editting this file
|
||||
# - Use the `|` character for multi-line strings
|
||||
# - Use `meta:enum` to document enum values (from jsonschema2md)
|
||||
# - Use `tsType` to override the TypeScript type (from json-schema-to-typescript)
|
||||
@@ -1851,7 +1851,7 @@ $defs: # JSON Schema definition (maybe we should move these to a seperate file)
|
||||
The color of the links in the sankey diagram.
|
||||
anyOf:
|
||||
- $ref: '#/$defs/SankeyLinkColor'
|
||||
- description: An arbitrary [CSS color](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value)
|
||||
- description: An arbtirary [CSS color](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value)
|
||||
type: string
|
||||
default: gradient
|
||||
nodeAlignment:
|
||||
|
@@ -1,5 +1,6 @@
|
||||
// @ts-nocheck : TODO Fix ts errors
|
||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||
import type { CurveFactory } from 'd3';
|
||||
import {
|
||||
curveBasis,
|
||||
curveBasisClosed,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
curveCatmullRomClosed,
|
||||
curveCatmullRomOpen,
|
||||
curveCatmullRom,
|
||||
CurveFactory,
|
||||
curveLinear,
|
||||
curveLinearClosed,
|
||||
curveMonotoneX,
|
||||
@@ -29,7 +29,7 @@ import { configKeys } from './defaultConfig.js';
|
||||
import { log } from './logger.js';
|
||||
import { detectType } from './diagram-api/detectType.js';
|
||||
import assignWithDepth from './assignWithDepth.js';
|
||||
import { MermaidConfig } from './config.type.js';
|
||||
import type { MermaidConfig } from './config.type.js';
|
||||
import memoize from 'lodash-es/memoize.js';
|
||||
import merge from 'lodash-es/merge.js';
|
||||
import { directiveRegex } from './diagram-api/regexes.js';
|
||||
@@ -97,36 +97,32 @@ const directiveWithoutOpen =
|
||||
* @param config - Optional mermaid configuration object.
|
||||
* @returns The json object representing the init passed to mermaid.initialize()
|
||||
*/
|
||||
export const detectInit = function (
|
||||
text: string,
|
||||
config?: MermaidConfig
|
||||
): MermaidConfig | undefined {
|
||||
export const detectInit = function (text: string, config?: MermaidConfig): MermaidConfig {
|
||||
const inits = detectDirective(text, /(?:init\b)|(?:initialize\b)/);
|
||||
let results = {};
|
||||
|
||||
if (Array.isArray(inits)) {
|
||||
const args = inits.map((init) => init.args);
|
||||
sanitizeDirective(args);
|
||||
directiveSanitizer(args);
|
||||
|
||||
results = assignWithDepth(results, [...args]);
|
||||
} else {
|
||||
results = inits.args;
|
||||
}
|
||||
|
||||
if (!results) {
|
||||
return;
|
||||
if (results) {
|
||||
let type = detectType(text, config);
|
||||
['config'].forEach((prop) => {
|
||||
if (results[prop] !== undefined) {
|
||||
if (type === 'flowchart-v2') {
|
||||
type = 'flowchart';
|
||||
}
|
||||
results[type] = results[prop];
|
||||
delete results[prop];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let type = detectType(text, config);
|
||||
['config'].forEach((prop) => {
|
||||
if (results[prop] !== undefined) {
|
||||
if (type === 'flowchart-v2') {
|
||||
type = 'flowchart';
|
||||
}
|
||||
results[type] = results[prop];
|
||||
delete results[prop];
|
||||
}
|
||||
});
|
||||
|
||||
// Todo: refactor this, these results are never used
|
||||
return results;
|
||||
};
|
||||
|
||||
@@ -847,63 +843,67 @@ export const entityDecode = function (html: string): string {
|
||||
*
|
||||
* @param args - Directive's JSON
|
||||
*/
|
||||
export const sanitizeDirective = (args: unknown): void => {
|
||||
log.debug('sanitizeDirective called with', args);
|
||||
export const directiveSanitizer = (args: any) => {
|
||||
log.debug('directiveSanitizer called with', args);
|
||||
if (typeof args === 'object') {
|
||||
// check for array
|
||||
if (args.length) {
|
||||
args.forEach((arg) => directiveSanitizer(arg));
|
||||
} else {
|
||||
// This is an object
|
||||
Object.keys(args).forEach((key) => {
|
||||
log.debug('Checking key', key);
|
||||
if (key.startsWith('__')) {
|
||||
log.debug('sanitize deleting __ option', key);
|
||||
delete args[key];
|
||||
}
|
||||
|
||||
// Return if not an object
|
||||
if (typeof args !== 'object' || args == null) {
|
||||
return;
|
||||
}
|
||||
if (key.includes('proto')) {
|
||||
log.debug('sanitize deleting proto option', key);
|
||||
delete args[key];
|
||||
}
|
||||
|
||||
// Sanitize each element if an array
|
||||
if (Array.isArray(args)) {
|
||||
args.forEach((arg) => sanitizeDirective(arg));
|
||||
return;
|
||||
}
|
||||
if (key.includes('constr')) {
|
||||
log.debug('sanitize deleting constr option', key);
|
||||
delete args[key];
|
||||
}
|
||||
|
||||
// Sanitize each key if an object
|
||||
for (const key of Object.keys(args)) {
|
||||
log.debug('Checking key', key);
|
||||
if (
|
||||
key.startsWith('__') ||
|
||||
key.includes('proto') ||
|
||||
key.includes('constr') ||
|
||||
!configKeys.has(key) ||
|
||||
args[key] == null
|
||||
) {
|
||||
log.debug('sanitize deleting key: ', key);
|
||||
delete args[key];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Recurse if an object
|
||||
if (typeof args[key] === 'object') {
|
||||
log.debug('sanitizing object', key);
|
||||
sanitizeDirective(args[key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
const cssMatchers = ['themeCSS', 'fontFamily', 'altFontFamily'];
|
||||
for (const cssKey of cssMatchers) {
|
||||
if (key.includes(cssKey)) {
|
||||
log.debug('sanitizing css option', key);
|
||||
args[key] = sanitizeCss(args[key]);
|
||||
}
|
||||
if (key.includes('themeCSS')) {
|
||||
log.debug('sanitizing themeCss option');
|
||||
args[key] = sanitizeCss(args[key]);
|
||||
}
|
||||
if (key.includes('fontFamily')) {
|
||||
log.debug('sanitizing fontFamily option');
|
||||
args[key] = sanitizeCss(args[key]);
|
||||
}
|
||||
if (key.includes('altFontFamily')) {
|
||||
log.debug('sanitizing altFontFamily option');
|
||||
args[key] = sanitizeCss(args[key]);
|
||||
}
|
||||
if (!configKeys.includes(key)) {
|
||||
log.debug('sanitize deleting option', key);
|
||||
delete args[key];
|
||||
} else {
|
||||
if (typeof args[key] === 'object') {
|
||||
log.debug('sanitize deleting object', key);
|
||||
directiveSanitizer(args[key]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (args.themeVariables) {
|
||||
for (const k of Object.keys(args.themeVariables)) {
|
||||
const kArr = Object.keys(args.themeVariables);
|
||||
for (const k of kArr) {
|
||||
const val = args.themeVariables[k];
|
||||
if (val?.match && !val.match(/^[\d "#%(),.;A-Za-z]+$/)) {
|
||||
if (val && val.match && !val.match(/^[\d "#%(),.;A-Za-z]+$/)) {
|
||||
args.themeVariables[k] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
log.debug('After sanitization', args);
|
||||
};
|
||||
|
||||
export const sanitizeCss = (str: string): string => {
|
||||
export const sanitizeCss = (str) => {
|
||||
let startCnt = 0;
|
||||
let endCnt = 0;
|
||||
|
||||
@@ -1020,8 +1020,8 @@ export default {
|
||||
random,
|
||||
runFunc,
|
||||
entityDecode,
|
||||
initIdGenerator,
|
||||
sanitizeDirective,
|
||||
initIdGenerator: initIdGenerator,
|
||||
directiveSanitizer,
|
||||
sanitizeCss,
|
||||
insertTitle,
|
||||
parseFontSize,
|
||||
|
Reference in New Issue
Block a user