diff --git a/.cspell/misc-terms.txt b/.cspell/misc-terms.txt
index 467e48891..0efd1dcc0 100644
--- a/.cspell/misc-terms.txt
+++ b/.cspell/misc-terms.txt
@@ -1 +1,4 @@
+BRANDES
+handdrawn
+KOEPF
newbranch
diff --git a/.esbuild/build.ts b/.esbuild/build.ts
index 310c92c7d..505c18405 100644
--- a/.esbuild/build.ts
+++ b/.esbuild/build.ts
@@ -56,7 +56,7 @@ const handler = (e) => {
const main = async () => {
await generateLangium();
- await mkdir('stats').catch(() => {});
+ await mkdir('stats', { recursive: true });
const packageNames = Object.keys(packageOptions) as (keyof typeof packageOptions)[];
// it should build `parser` before `mermaid` because it's a dependency
for (const pkg of packageNames) {
diff --git a/.esbuild/server.ts b/.esbuild/server.ts
index 54c8f88df..ef61ebec2 100644
--- a/.esbuild/server.ts
+++ b/.esbuild/server.ts
@@ -95,8 +95,7 @@ async function createServer() {
return;
}
console.log(`${path} changed. Rebuilding...`);
-
- if (/\.langium$/.test(path)) {
+ if (path.endsWith('.langium')) {
await generateLangium();
}
handleFileChange();
diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts
index 17bebeaef..3ffba697a 100644
--- a/cypress/helpers/util.ts
+++ b/cypress/helpers/util.ts
@@ -35,7 +35,7 @@ export const mermaidUrl = (
};
const objStr: string = JSON.stringify(codeObject);
let url = `http://localhost:9000/e2e.html?graph=${utf8ToB64(objStr)}`;
- if (api) {
+ if (api && typeof graphStr === 'string') {
url = `http://localhost:9000/xss.html?graph=${graphStr}`;
}
@@ -54,16 +54,15 @@ export const imgSnapshotTest = (
): void => {
const options: CypressMermaidConfig = {
..._options,
- fontFamily: _options.fontFamily || 'courier',
+ fontFamily: _options.fontFamily ?? 'courier',
// @ts-ignore TODO: Fix type of fontSize
- fontSize: _options.fontSize || '16px',
+ fontSize: _options.fontSize ?? '16px',
sequence: {
- ...(_options.sequence || {}),
+ ...(_options.sequence ?? {}),
actorFontFamily: 'courier',
- noteFontFamily:
- _options.sequence && _options.sequence.noteFontFamily
- ? _options.sequence.noteFontFamily
- : 'courier',
+ noteFontFamily: _options.sequence?.noteFontFamily
+ ? _options.sequence.noteFontFamily
+ : 'courier',
messageFontFamily: 'courier',
},
};
@@ -95,7 +94,7 @@ export const openURLAndVerifyRendering = (
options: CypressMermaidConfig,
validation?: any
): void => {
- const name: string = (options.name || cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
+ const name: string = (options.name ?? cy.state('runnable').fullTitle()).replace(/\s+/g, '-');
cy.visit(url);
cy.window().should('have.property', 'rendered', true);
diff --git a/cypress/platform/bundle-test.js b/cypress/platform/bundle-test.js
index f5bf0ecd6..24ce8d753 100644
--- a/cypress/platform/bundle-test.js
+++ b/cypress/platform/bundle-test.js
@@ -27,7 +27,7 @@ const code3 = `flowchart TD
A( )
B(Bold text! )`;
-if (location.href.match('test-html-escaping')) {
+if (/test-html-escaping/.exec(location.href)) {
code = code3;
}
diff --git a/cypress/platform/viewer.js b/cypress/platform/viewer.js
index 482a90646..c397f0e16 100644
--- a/cypress/platform/viewer.js
+++ b/cypress/platform/viewer.js
@@ -132,7 +132,7 @@ if (typeof document !== 'undefined') {
window.addEventListener(
'load',
function () {
- if (this.location.href.match('xss.html')) {
+ if (/xss.html/.exec(this.location.href)) {
this.console.log('Using api');
void contentLoadedApi().finally(markRendered);
} else {
diff --git a/docs/config/setup/interfaces/mermaid.DetailedError.md b/docs/config/setup/interfaces/mermaid.DetailedError.md
index 6b7d471ae..3b019e58a 100644
--- a/docs/config/setup/interfaces/mermaid.DetailedError.md
+++ b/docs/config/setup/interfaces/mermaid.DetailedError.md
@@ -16,7 +16,7 @@
#### Defined in
-[packages/mermaid/src/utils.ts:789](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L789)
+[packages/mermaid/src/utils.ts:785](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L785)
---
@@ -26,7 +26,7 @@
#### Defined in
-[packages/mermaid/src/utils.ts:787](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L787)
+[packages/mermaid/src/utils.ts:783](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L783)
---
@@ -36,7 +36,7 @@
#### Defined in
-[packages/mermaid/src/utils.ts:790](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L790)
+[packages/mermaid/src/utils.ts:786](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L786)
---
@@ -46,4 +46,4 @@
#### Defined in
-[packages/mermaid/src/utils.ts:785](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L785)
+[packages/mermaid/src/utils.ts:781](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L781)
diff --git a/docs/config/setup/modules/mermaid.md b/docs/config/setup/modules/mermaid.md
index d51400d6e..10e9330b5 100644
--- a/docs/config/setup/modules/mermaid.md
+++ b/docs/config/setup/modules/mermaid.md
@@ -44,7 +44,7 @@
#### Defined in
-[packages/mermaid/src/Diagram.ts:9](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/Diagram.ts#L9)
+[packages/mermaid/src/Diagram.ts:10](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/Diagram.ts#L10)
## Variables
diff --git a/eslint.config.js b/eslint.config.js
index de7b59558..ed703ea71 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -13,7 +13,8 @@ import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
- ...tseslint.configs.recommended,
+ ...tseslint.configs.recommendedTypeChecked,
+ ...tseslint.configs.stylisticTypeChecked,
{
ignores: [
'**/dist/',
@@ -101,6 +102,15 @@ export default tseslint.config(
},
},
],
+ // START: These rules should be turned on once the codebase is cleaned up
+ '@typescript-eslint/no-unsafe-argument': 'off',
+ '@typescript-eslint/no-unsafe-assignment': 'off',
+ '@typescript-eslint/no-unsafe-call': 'off',
+ '@typescript-eslint/no-unsafe-member-access': 'off',
+ '@typescript-eslint/no-unsafe-return': 'off',
+ '@typescript-eslint/only-throw-error': 'warn',
+ '@typescript-eslint/prefer-promise-reject-errors': 'warn',
+ // END
'json/*': ['error', 'allowComments'],
'@cspell/spellchecker': [
'error',
diff --git a/packages/mermaid-example-diagram/src/mermaidUtils.ts b/packages/mermaid-example-diagram/src/mermaidUtils.ts
index eeeca05c5..04d0599c0 100644
--- a/packages/mermaid-example-diagram/src/mermaidUtils.ts
+++ b/packages/mermaid-example-diagram/src/mermaidUtils.ts
@@ -25,7 +25,7 @@ export const log: Record = {
fatal: warning,
};
-export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
+export let setLogLevel: (level: keyof typeof LEVELS | number) => void;
export let getConfig: () => object;
export let sanitizeText: (str: string) => string;
export let commonDb: () => object;
diff --git a/packages/mermaid-zenuml/src/mermaidUtils.ts b/packages/mermaid-zenuml/src/mermaidUtils.ts
index 623685879..413e8d2de 100644
--- a/packages/mermaid-zenuml/src/mermaidUtils.ts
+++ b/packages/mermaid-zenuml/src/mermaidUtils.ts
@@ -26,7 +26,7 @@ export const log: Record = {
fatal: warning,
};
-export let setLogLevel: (level: keyof typeof LEVELS | number | string) => void;
+export let setLogLevel: (level: keyof typeof LEVELS | number) => void;
export let getConfig: () => MermaidConfig;
export let sanitizeText: (str: string) => string;
// eslint-disable @typescript-eslint/no-explicit-any
diff --git a/packages/mermaid-zenuml/src/zenumlRenderer.ts b/packages/mermaid-zenuml/src/zenumlRenderer.ts
index a1a807dce..f9dd57996 100644
--- a/packages/mermaid-zenuml/src/zenumlRenderer.ts
+++ b/packages/mermaid-zenuml/src/zenumlRenderer.ts
@@ -9,7 +9,7 @@ function createTemporaryZenumlContainer(id: string) {
container.id = `container-${id}`;
container.style.display = 'flex';
container.innerHTML = `
`;
- const app = container.querySelector(`#zenUMLApp-${id}`) as HTMLElement;
+ const app = container.querySelector(`#zenUMLApp-${id}`)!;
return { container, app };
}
diff --git a/packages/mermaid/scripts/create-types-from-json-schema.mts b/packages/mermaid/scripts/create-types-from-json-schema.mts
index 57b066812..1f6015bce 100644
--- a/packages/mermaid/scripts/create-types-from-json-schema.mts
+++ b/packages/mermaid/scripts/create-types-from-json-schema.mts
@@ -97,7 +97,7 @@ async function generateTypescript(mermaidConfigSchema: JSONSchemaType>) {
- if (schema['allOf']) {
+ if (schema.allOf) {
const { allOf, ...schemaWithoutAllOf } = schema;
return {
...schemaWithoutAllOf,
diff --git a/packages/mermaid/scripts/docs.mts b/packages/mermaid/scripts/docs.mts
index 5e7ccb2d8..374e78870 100644
--- a/packages/mermaid/scripts/docs.mts
+++ b/packages/mermaid/scripts/docs.mts
@@ -88,9 +88,9 @@ const WARN_DOCSDIR_DOESNT_MATCH = `Changed files were transformed in ${SOURCE_DO
const prettierConfig = (await prettier.resolveConfig('.')) ?? {};
// From https://github.com/vuejs/vitepress/blob/428eec3750d6b5648a77ac52d88128df0554d4d1/src/node/markdownToVue.ts#L20-L21
const includesRE = //g;
-const includedFiles: Set = new Set();
+const includedFiles = new Set();
-const filesTransformed: Set = new Set();
+const filesTransformed = new Set();
const generateHeader = (file: string): string => {
// path from file in docs/* to repo root, e.g ../ or ../../ */
@@ -181,10 +181,10 @@ export const transformToBlockQuote = (
) => {
if (vitepress) {
const vitepressType = type === 'note' ? 'info' : type;
- return `::: ${vitepressType} ${customTitle || ''}\n${content}\n:::`;
+ return `::: ${vitepressType} ${customTitle ?? ''}\n${content}\n:::`;
} else {
- const icon = blockIcons[type] || '';
- const title = `${icon}${customTitle || capitalize(type)}`;
+ const icon = blockIcons[type] ?? '';
+ const title = `${icon}${customTitle ?? capitalize(type)}`;
return `> **${title}** \n> ${content.replace(/\n/g, '\n> ')}`;
}
};
@@ -201,6 +201,7 @@ const transformIncludeStatements = (file: string, text: string): string => {
includedFiles.add(changeToFinalDocDir(includePath));
return content;
} catch (error) {
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
throw new Error(`Failed to resolve include "${m1}" in "${file}": ${error}`);
}
});
diff --git a/packages/mermaid/src/Diagram.ts b/packages/mermaid/src/Diagram.ts
index 1374effb4..fb423b9b0 100644
--- a/packages/mermaid/src/Diagram.ts
+++ b/packages/mermaid/src/Diagram.ts
@@ -6,6 +6,7 @@ import { encodeEntities } from './utils.js';
import type { DetailedError } from './utils.js';
import type { DiagramDefinition, DiagramMetadata } from './diagram-api/types.js';
+// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
export type ParseErrorFunction = (err: string | DetailedError | unknown, hash?: any) => void;
/**
diff --git a/packages/mermaid/src/config.ts b/packages/mermaid/src/config.ts
index b766d9b42..1229bcd22 100644
--- a/packages/mermaid/src/config.ts
+++ b/packages/mermaid/src/config.ts
@@ -189,7 +189,7 @@ 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)) {
+ if (directive.fontFamily && !directive.themeVariables?.fontFamily) {
directive.themeVariables = { fontFamily: directive.fontFamily };
}
diff --git a/packages/mermaid/src/dagre-wrapper/edgeMarker.spec.ts b/packages/mermaid/src/dagre-wrapper/edgeMarker.spec.ts
index 6cfb59fab..6fb439552 100644
--- a/packages/mermaid/src/dagre-wrapper/edgeMarker.spec.ts
+++ b/packages/mermaid/src/dagre-wrapper/edgeMarker.spec.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/unbound-method */
import type { Mocked } from 'vitest';
import type { SVG } from '../diagram-api/types.js';
import { addEdgeMarkers } from './edgeMarker.js';
diff --git a/packages/mermaid/src/dagre-wrapper/index.js b/packages/mermaid/src/dagre-wrapper/index.js
index 70f1a862c..c870566a7 100644
--- a/packages/mermaid/src/dagre-wrapper/index.js
+++ b/packages/mermaid/src/dagre-wrapper/index.js
@@ -51,7 +51,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
}
}
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
- if (node && node.clusterNode) {
+ if (node?.clusterNode) {
// const children = graph.children(v);
log.info('Cluster identified', v, node.width, graph.node(v));
// `node.graph.setGraph` applies the graph configurations such as nodeSpacing to subgraphs as without this the default values would be used
@@ -130,7 +130,7 @@ const recursiveRender = async (_elem, graph, diagramType, id, parentCluster, sit
' height: ',
node.height
);
- if (node && node.clusterNode) {
+ if (node?.clusterNode) {
// clusterDb[node.id].node = node;
node.y += subGraphTitleTotalMargin;
positionNode(node);
diff --git a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js
index 04ee9d16b..ef0c2caa7 100644
--- a/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js
+++ b/packages/mermaid/src/dagre-wrapper/mermaid-graphlib.js
@@ -399,7 +399,7 @@ export const extractor = (graph, depth) => {
const graphSettings = graph.graph();
let dir = graphSettings.rankdir === 'TB' ? 'LR' : 'TB';
- if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) {
+ if (clusterDb[node]?.clusterData?.dir) {
dir = clusterDb[node].clusterData.dir;
log.warn('Fixing dir', clusterDb[node].clusterData.dir, dir);
}
diff --git a/packages/mermaid/src/dagre-wrapper/nodes.js b/packages/mermaid/src/dagre-wrapper/nodes.js
index 8abcfe5bd..611cc5b6e 100644
--- a/packages/mermaid/src/dagre-wrapper/nodes.js
+++ b/packages/mermaid/src/dagre-wrapper/nodes.js
@@ -901,7 +901,7 @@ const class_box = (parent, node) => {
const labelContainer = shapeSvg.insert('g').attr('class', 'label');
let verticalPos = 0;
- const hasInterface = node.classData.annotations && node.classData.annotations[0];
+ const hasInterface = node.classData.annotations?.[0];
// 1. Create the labels
const interfaceLabelText = node.classData.annotations[0]
diff --git a/packages/mermaid/src/defaultConfig.ts b/packages/mermaid/src/defaultConfig.ts
index 76a8152b7..727842bba 100644
--- a/packages/mermaid/src/defaultConfig.ts
+++ b/packages/mermaid/src/defaultConfig.ts
@@ -23,7 +23,7 @@ const config: RequiredDeep = {
themeCSS: undefined,
// add non-JSON default config values
- themeVariables: theme['default'].getThemeVariables(),
+ themeVariables: theme.default.getThemeVariables(),
sequence: {
...defaultConfigJson.sequence,
messageFont: function () {
@@ -272,5 +272,5 @@ const keyify = (obj: any, prefix = ''): string[] =>
return [...res, prefix + el];
}, []);
-export const configKeys: Set = new Set(keyify(config, ''));
+export const configKeys = new Set(keyify(config, ''));
export default config;
diff --git a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts
index 9fe6541d6..68991cffb 100644
--- a/packages/mermaid/src/diagram-api/diagramAPI.spec.ts
+++ b/packages/mermaid/src/diagram-api/diagramAPI.spec.ts
@@ -29,7 +29,7 @@ describe('DiagramAPI', () => {
`[UnknownDiagramError: No diagram type detected matching given configuration for text: loki diagram]`
);
const detector: DiagramDetector = (str: string) => {
- return str.match('loki') !== null;
+ return /loki/.exec(str) !== null;
};
registerDiagram(
'loki',
diff --git a/packages/mermaid/src/diagram-api/diagramAPI.ts b/packages/mermaid/src/diagram-api/diagramAPI.ts
index 5ea3825ef..df4514adf 100644
--- a/packages/mermaid/src/diagram-api/diagramAPI.ts
+++ b/packages/mermaid/src/diagram-api/diagramAPI.ts
@@ -30,9 +30,7 @@ export const getCommonDb = () => {
};
const diagrams: Record = {};
-export interface Detectors {
- [key: string]: DiagramDetector;
-}
+export type Detectors = Record;
/**
* Registers the given diagram with Mermaid.
diff --git a/packages/mermaid/src/diagram.spec.ts b/packages/mermaid/src/diagram.spec.ts
index 4b9c907b3..873fada14 100644
--- a/packages/mermaid/src/diagram.spec.ts
+++ b/packages/mermaid/src/diagram.spec.ts
@@ -30,12 +30,12 @@ const getDummyDiagram = (id: string, title?: string): Awaited {
test('should detect inbuilt diagrams', async () => {
- const graph = (await Diagram.fromText('graph TD; A-->B')) as Diagram;
+ const graph = await Diagram.fromText('graph TD; A-->B');
expect(graph).toBeInstanceOf(Diagram);
expect(graph.type).toBe('flowchart-v2');
- const sequence = (await Diagram.fromText(
+ const sequence = await Diagram.fromText(
'sequenceDiagram; Alice->>+John: Hello John, how are you?'
- )) as Diagram;
+ );
expect(sequence).toBeInstanceOf(Diagram);
expect(sequence.type).toBe('sequence');
});
diff --git a/packages/mermaid/src/diagrams/block/blockDB.ts b/packages/mermaid/src/diagrams/block/blockDB.ts
index 361e23d5c..d6e35ed15 100644
--- a/packages/mermaid/src/diagrams/block/blockDB.ts
+++ b/packages/mermaid/src/diagrams/block/blockDB.ts
@@ -8,9 +8,9 @@ import { clear as commonClear } from '../common/commonDb.js';
import type { Block, ClassDef } from './blockTypes.js';
// Initialize the node database for simple lookups
-let blockDatabase: Map = new Map();
+let blockDatabase = new Map();
let edgeList: Block[] = [];
-let edgeCount: Map = new Map();
+let edgeCount = new Map();
const COLOR_KEYWORD = 'color';
const FILL_KEYWORD = 'fill';
@@ -18,7 +18,7 @@ const BG_FILL = 'bgFill';
const STYLECLASS_SEP = ',';
const config = getConfig();
-let classes: Map = new Map();
+let classes = new Map();
const sanitizeText = (txt: string) => common.sanitizeText(txt, config);
@@ -42,7 +42,7 @@ export const addStyleClass = function (id: string, styleAttributes = '') {
const fixedAttrib = attrib.replace(/([^;]*);/, '$1').trim();
// replace some style keywords
- if (attrib.match(COLOR_KEYWORD)) {
+ if (RegExp(COLOR_KEYWORD).exec(attrib)) {
const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);
const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);
foundClass.textStyles.push(newStyle2);
@@ -89,7 +89,7 @@ export const setCssClass = function (itemIds: string, cssClassName: string) {
});
};
-const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block): void => {
+const populateBlockDatabase = (_blockList: Block[], parent: Block): void => {
const blockList = _blockList.flat();
const children = [];
for (const block of blockList) {
@@ -101,7 +101,7 @@ const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block):
continue;
}
if (block.type === 'applyClass') {
- setCssClass(block.id, block?.styleClass || '');
+ setCssClass(block.id, block?.styleClass ?? '');
continue;
}
if (block.type === 'applyStyles') {
@@ -111,7 +111,7 @@ const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block):
continue;
}
if (block.type === 'column-setting') {
- parent.columns = block.columns || -1;
+ parent.columns = block.columns ?? -1;
} else if (block.type === 'edge') {
const count = (edgeCount.get(block.id) ?? 0) + 1;
edgeCount.set(block.id, count);
@@ -145,7 +145,7 @@ const populateBlockDatabase = (_blockList: Block[] | Block[][], parent: Block):
}
if (block.type === 'space') {
// log.debug('abc95 space', block);
- const w = block.width || 1;
+ const w = block.width ?? 1;
for (let j = 0; j < w; j++) {
const newBlock = clone(block);
newBlock.id = newBlock.id + '-' + j;
@@ -168,7 +168,7 @@ const clear = (): void => {
commonClear();
rootBlock = { id: 'root', type: 'composite', children: [], columns: -1 } as Block;
blockDatabase = new Map([['root', rootBlock]]);
- blocks = [] as Block[];
+ blocks = [];
classes = new Map();
edgeList = [];
diff --git a/packages/mermaid/src/diagrams/block/blockRenderer.ts b/packages/mermaid/src/diagrams/block/blockRenderer.ts
index 6e3f61a4d..99b89ceeb 100644
--- a/packages/mermaid/src/diagrams/block/blockRenderer.ts
+++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts
@@ -1,7 +1,6 @@
import { select as d3select } from 'd3';
import type { Diagram } from '../../Diagram.js';
import * as configApi from '../../config.js';
-import type { MermaidConfig } from '../../config.type.js';
import insertMarkers from '../../dagre-wrapper/markers.js';
import { log } from '../../logger.js';
import { configureSvgSize } from '../../setupGraphViewbox.js';
@@ -71,7 +70,7 @@ export const draw = async function (
const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));
const height = bounds2.height + magicFactor + 10;
const width = bounds2.width + 10;
- const { useMaxWidth } = conf as Exclude;
+ const { useMaxWidth } = conf!;
configureSvgSize(svg, height, width, !!useMaxWidth);
log.debug('Here Bounds', bounds, bounds2);
svg.attr(
diff --git a/packages/mermaid/src/diagrams/block/layout.ts b/packages/mermaid/src/diagrams/block/layout.ts
index cb9496a69..7f44a5f19 100644
--- a/packages/mermaid/src/diagrams/block/layout.ts
+++ b/packages/mermaid/src/diagrams/block/layout.ts
@@ -2,7 +2,8 @@ import type { BlockDB } from './blockDB.js';
import type { Block } from './blockTypes.js';
import { log } from '../../logger.js';
import { getConfig } from '../../diagram-api/diagramAPI.js';
-const padding = getConfig()?.block?.padding || 8;
+// TODO: This means the number we provide in diagram's config will never be used. Should fix.
+const padding = getConfig()?.block?.padding ?? 8;
interface BlockPosition {
px: number;
@@ -42,7 +43,7 @@ const getMaxChildSize = (block: Block) => {
// find max width of children
// log.debug('getMaxChildSize abc95 (start) parent:', block.id);
for (const child of block.children) {
- const { width, height, x, y } = child.size || { width: 0, height: 0, x: 0, y: 0 };
+ const { width, height, x, y } = child.size ?? { width: 0, height: 0, x: 0, y: 0 };
log.debug(
'getMaxChildSize abc95 child:',
child.id,
@@ -60,7 +61,7 @@ const getMaxChildSize = (block: Block) => {
continue;
}
if (width > maxWidth) {
- maxWidth = width / (block.widthInColumns || 1);
+ maxWidth = width / (block.widthInColumns ?? 1);
}
if (height > maxHeight) {
maxHeight = height;
@@ -104,10 +105,10 @@ function setBlockSizes(block: Block, db: BlockDB, siblingWidth = 0, siblingHeigh
for (const child of block.children) {
if (child.size) {
log.debug(
- `abc95 Setting size of children of ${block.id} id=${child.id} ${maxWidth} ${maxHeight} ${child.size}`
+ `abc95 Setting size of children of ${block.id} id=${child.id} ${maxWidth} ${maxHeight} ${JSON.stringify(child.size)}`
);
child.size.width =
- maxWidth * (child.widthInColumns || 1) + padding * ((child.widthInColumns || 1) - 1);
+ maxWidth * (child.widthInColumns ?? 1) + padding * ((child.widthInColumns ?? 1) - 1);
child.size.height = maxHeight;
child.size.x = 0;
child.size.y = 0;
@@ -121,10 +122,10 @@ function setBlockSizes(block: Block, db: BlockDB, siblingWidth = 0, siblingHeigh
setBlockSizes(child, db, maxWidth, maxHeight);
}
- const columns = block.columns || -1;
+ const columns = block.columns ?? -1;
let numItems = 0;
for (const child of block.children) {
- numItems += child.widthInColumns || 1;
+ numItems += child.widthInColumns ?? 1;
}
// The width and height in number blocks
@@ -204,13 +205,13 @@ function layoutBlocks(block: Block, db: BlockDB) {
log.debug(
`abc85 layout blocks (=>layoutBlocks) ${block.id} x: ${block?.size?.x} y: ${block?.size?.y} width: ${block?.size?.width}`
);
- const columns = block.columns || -1;
+ const columns = block.columns ?? -1;
log.debug('layoutBlocks columns abc95', block.id, '=>', columns, block);
if (
block.children && // find max width of children
block.children.length > 0
) {
- const width = block?.children[0]?.size?.width || 0;
+ const width = block?.children[0]?.size?.width ?? 0;
const widthOfChildren = block.children.length * width + (block.children.length - 1) * padding;
log.debug('widthOfChildren 88', widthOfChildren, 'posX');
@@ -249,7 +250,7 @@ function layoutBlocks(block: Block, db: BlockDB) {
} ${halfWidth} padding=${padding} width=${width} halfWidth=${halfWidth} => x:${
child.size.x
} y:${child.size.y} ${child.widthInColumns} (width * (child?.w || 1)) / 2 ${
- (width * (child?.widthInColumns || 1)) / 2
+ (width * (child?.widthInColumns ?? 1)) / 2
}`
);
@@ -263,15 +264,13 @@ function layoutBlocks(block: Block, db: BlockDB) {
child.id
}startingPosX${startingPosX}${padding}${halfWidth}=>x:${child.size.x}y:${child.size.y}${
child.widthInColumns
- }(width * (child?.w || 1)) / 2${(width * (child?.widthInColumns || 1)) / 2}`
+ }(width * (child?.w || 1)) / 2${(width * (child?.widthInColumns ?? 1)) / 2}`
);
}
-
- // posY += height + padding;
if (child.children) {
layoutBlocks(child, db);
}
- columnPos += child?.widthInColumns || 1;
+ columnPos += child?.widthInColumns ?? 1;
log.debug('abc88 columnsPos', child, columnPos);
}
}
diff --git a/packages/mermaid/src/diagrams/block/parser/block.spec.ts b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
index 295dabf89..1bb8691c1 100644
--- a/packages/mermaid/src/diagrams/block/parser/block.spec.ts
+++ b/packages/mermaid/src/diagrams/block/parser/block.spec.ts
@@ -1,9 +1,6 @@
// @ts-ignore: jison doesn't export types
import block from './block.jison';
import db from '../blockDB.js';
-import { cleanupComments } from '../../../diagram-api/comments.js';
-import { prepareTextForParsing } from '../blockUtils.js';
-import { setConfig } from '../../../config.js';
describe('Block diagram', function () {
describe('when parsing an block diagram graph it should handle > ', function () {
@@ -13,7 +10,7 @@ describe('Block diagram', function () {
block.parser.yy.getLogger = () => console;
});
- it('a diagram with a node', async () => {
+ it('a diagram with a node', () => {
const str = `block-beta
id
`;
@@ -24,7 +21,7 @@ describe('Block diagram', function () {
expect(blocks[0].id).toBe('id');
expect(blocks[0].label).toBe('id');
});
- it('a node with a square shape and a label', async () => {
+ it('a node with a square shape and a label', () => {
const str = `block-beta
id["A label"]
`;
@@ -36,7 +33,7 @@ describe('Block diagram', function () {
expect(blocks[0].label).toBe('A label');
expect(blocks[0].type).toBe('square');
});
- it('a diagram with multiple nodes', async () => {
+ it('a diagram with multiple nodes', () => {
const str = `block-beta
id1
id2
@@ -52,7 +49,7 @@ describe('Block diagram', function () {
expect(blocks[1].label).toBe('id2');
expect(blocks[1].type).toBe('na');
});
- it('a diagram with multiple nodes', async () => {
+ it('a diagram with multiple nodes', () => {
const str = `block-beta
id1
id2
@@ -73,7 +70,7 @@ describe('Block diagram', function () {
expect(blocks[2].type).toBe('na');
});
- it('a node with a square shape and a label', async () => {
+ it('a node with a square shape and a label', () => {
const str = `block-beta
id["A label"]
id2`;
@@ -88,7 +85,7 @@ describe('Block diagram', function () {
expect(blocks[1].label).toBe('id2');
expect(blocks[1].type).toBe('na');
});
- it('a diagram with multiple nodes with edges abc123', async () => {
+ it('a diagram with multiple nodes with edges abc123', () => {
const str = `block-beta
id1["first"] --> id2["second"]
`;
@@ -102,7 +99,7 @@ describe('Block diagram', function () {
expect(edges[0].end).toBe('id2');
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
});
- it('a diagram with multiple nodes with edges abc123', async () => {
+ it('a diagram with multiple nodes with edges abc123', () => {
const str = `block-beta
id1["first"] -- "a label" --> id2["second"]
`;
@@ -117,7 +114,7 @@ describe('Block diagram', function () {
expect(edges[0].arrowTypeEnd).toBe('arrow_point');
expect(edges[0].label).toBe('a label');
});
- it('a diagram with column statements', async () => {
+ it('a diagram with column statements', () => {
const str = `block-beta
columns 2
block1["Block 1"]
@@ -128,7 +125,7 @@ describe('Block diagram', function () {
const blocks = db.getBlocks();
expect(blocks.length).toBe(1);
});
- it('a diagram withput column statements', async () => {
+ it('a diagram withput column statements', () => {
const str = `block-beta
block1["Block 1"]
`;
@@ -138,7 +135,7 @@ describe('Block diagram', function () {
const blocks = db.getBlocks();
expect(blocks.length).toBe(1);
});
- it('a diagram with auto column statements', async () => {
+ it('a diagram with auto column statements', () => {
const str = `block-beta
columns auto
block1["Block 1"]
@@ -150,7 +147,7 @@ describe('Block diagram', function () {
expect(blocks.length).toBe(1);
});
- it('blocks next to each other', async () => {
+ it('blocks next to each other', () => {
const str = `block-beta
columns 2
block1["Block 1"]
@@ -164,7 +161,7 @@ describe('Block diagram', function () {
expect(blocks.length).toBe(2);
});
- it('blocks on top of each other', async () => {
+ it('blocks on top of each other', () => {
const str = `block-beta
columns 1
block1["Block 1"]
@@ -178,7 +175,7 @@ describe('Block diagram', function () {
expect(blocks.length).toBe(2);
});
- it('compound blocks 2', async () => {
+ it('compound blocks 2', () => {
const str = `block-beta
block
aBlock["ABlock"]
@@ -206,7 +203,7 @@ describe('Block diagram', function () {
expect(bBlock.label).toBe('BBlock');
expect(bBlock.type).toBe('square');
});
- it('compound blocks of compound blocks', async () => {
+ it('compound blocks of compound blocks', () => {
const str = `block-beta
block
aBlock["ABlock"]
@@ -241,7 +238,7 @@ describe('Block diagram', function () {
expect(bBlock.label).toBe('BBlock');
expect(bBlock.type).toBe('square');
});
- it('compound blocks with title', async () => {
+ it('compound blocks with title', () => {
const str = `block-beta
block:compoundBlock["Compound block"]
columns 1
@@ -266,7 +263,7 @@ describe('Block diagram', function () {
expect(block2.label).toBe('Block 2');
expect(block2.type).toBe('square');
});
- it('blocks mixed with compound blocks', async () => {
+ it('blocks mixed with compound blocks', () => {
const str = `block-beta
columns 1
block1["Block 1"]
@@ -293,7 +290,7 @@ describe('Block diagram', function () {
expect(block2.type).toBe('square');
});
- it('Arrow blocks', async () => {
+ it('Arrow blocks', () => {
const str = `block-beta
columns 3
block1["Block 1"]
@@ -317,7 +314,7 @@ describe('Block diagram', function () {
expect(blockArrow.type).toBe('block_arrow');
expect(blockArrow.directions).toContain('right');
});
- it('Arrow blocks with multiple points', async () => {
+ it('Arrow blocks with multiple points', () => {
const str = `block-beta
columns 1
A
@@ -340,7 +337,7 @@ describe('Block diagram', function () {
expect(blockArrow.directions).toContain('down');
expect(blockArrow.directions).not.toContain('right');
});
- it('blocks with different widths', async () => {
+ it('blocks with different widths', () => {
const str = `block-beta
columns 3
one["One Slot"]
@@ -355,7 +352,7 @@ describe('Block diagram', function () {
const two = blocks[1];
expect(two.widthInColumns).toBe(2);
});
- it('empty blocks', async () => {
+ it('empty blocks', () => {
const str = `block-beta
columns 3
space
@@ -374,7 +371,7 @@ describe('Block diagram', function () {
expect(sp2.type).toBe('space');
expect(middle.label).toBe('In the middle');
});
- it('classDef statements applied to a block', async () => {
+ it('classDef statements applied to a block', () => {
const str = `block-beta
classDef black color:#ffffff, fill:#000000;
@@ -392,7 +389,7 @@ describe('Block diagram', function () {
expect(black.id).toBe('black');
expect(black.styles[0]).toEqual('color:#ffffff');
});
- it('style statements applied to a block', async () => {
+ it('style statements applied to a block', () => {
const str = `block-beta
columns 1
B["A wide one in the middle"]
diff --git a/packages/mermaid/src/diagrams/block/renderHelpers.ts b/packages/mermaid/src/diagrams/block/renderHelpers.ts
index fc73ca2ec..97eca4074 100644
--- a/packages/mermaid/src/diagrams/block/renderHelpers.ts
+++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts
@@ -11,7 +11,7 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
let classStr = 'default';
if ((vertex?.classes?.length || 0) > 0) {
- classStr = (vertex?.classes || []).join(' ');
+ classStr = (vertex?.classes ?? []).join(' ');
}
classStr = classStr + ' flowchart-label';
@@ -85,12 +85,12 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
shape = 'rect';
}
- const styles = getStylesFromArray(vertex?.styles || []);
+ const styles = getStylesFromArray(vertex?.styles ?? []);
// Use vertex id as text in the box if no text is provided by the graph definition
const vertexText = vertex.label;
- const bounds = vertex.size || { width: 0, height: 0, x: 0, y: 0 };
+ const bounds = vertex.size ?? { width: 0, height: 0, x: 0, y: 0 };
// Add the node
const node = {
labelStyle: styles.labelStyle,
@@ -109,7 +109,7 @@ function getNodeFromBlock(block: Block, db: BlockDB, positioned = false) {
positioned,
intersect: undefined,
type: vertex.type,
- padding: padding ?? (getConfig()?.block?.padding || 0),
+ padding: padding ?? getConfig()?.block?.padding ?? 0,
};
return node;
}
@@ -214,7 +214,7 @@ export async function insertEdges(
{ x: end.x, y: end.y },
];
// edge.points = points;
- await insertEdge(
+ insertEdge(
elem,
{ v: edge.start, w: edge.end, name: edge.id },
{
@@ -239,7 +239,7 @@ export async function insertEdges(
points,
classes: 'edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1',
});
- await positionEdgeLabel(
+ positionEdgeLabel(
{ ...edge, x: points[1].x, y: points[1].y },
{
originalPath: points,
diff --git a/packages/mermaid/src/diagrams/c4/c4Renderer.js b/packages/mermaid/src/diagrams/c4/c4Renderer.js
index 959eba295..58dd808fd 100644
--- a/packages/mermaid/src/diagrams/c4/c4Renderer.js
+++ b/packages/mermaid/src/diagrams/c4/c4Renderer.js
@@ -258,21 +258,21 @@ export const drawC4ShapeArray = function (currentBounds, diagram, c4ShapeArray,
c4ShapeLabelConf.fontSize = c4ShapeLabelConf.fontSize + 2;
c4ShapeLabelConf.fontWeight = 'bold';
calcC4ShapeTextWH('label', c4Shape, c4ShapeTextWrap, c4ShapeLabelConf, textLimitWidth);
- c4Shape['label'].Y = Y + 8;
- Y = c4Shape['label'].Y + c4Shape['label'].height;
+ c4Shape.label.Y = Y + 8;
+ Y = c4Shape.label.Y + c4Shape.label.height;
if (c4Shape.type && c4Shape.type.text !== '') {
c4Shape.type.text = '[' + c4Shape.type.text + ']';
let c4ShapeTypeConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text);
calcC4ShapeTextWH('type', c4Shape, c4ShapeTextWrap, c4ShapeTypeConf, textLimitWidth);
- c4Shape['type'].Y = Y + 5;
- Y = c4Shape['type'].Y + c4Shape['type'].height;
+ c4Shape.type.Y = Y + 5;
+ Y = c4Shape.type.Y + c4Shape.type.height;
} else if (c4Shape.techn && c4Shape.techn.text !== '') {
c4Shape.techn.text = '[' + c4Shape.techn.text + ']';
let c4ShapeTechnConf = c4ShapeFont(conf, c4Shape.techn.text);
calcC4ShapeTextWH('techn', c4Shape, c4ShapeTextWrap, c4ShapeTechnConf, textLimitWidth);
- c4Shape['techn'].Y = Y + 5;
- Y = c4Shape['techn'].Y + c4Shape['techn'].height;
+ c4Shape.techn.Y = Y + 5;
+ Y = c4Shape.techn.Y + c4Shape.techn.height;
}
let rectHeight = Y;
@@ -281,11 +281,11 @@ export const drawC4ShapeArray = function (currentBounds, diagram, c4ShapeArray,
if (c4Shape.descr && c4Shape.descr.text !== '') {
let c4ShapeDescrConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text);
calcC4ShapeTextWH('descr', c4Shape, c4ShapeTextWrap, c4ShapeDescrConf, textLimitWidth);
- c4Shape['descr'].Y = Y + 20;
- Y = c4Shape['descr'].Y + c4Shape['descr'].height;
+ c4Shape.descr.Y = Y + 20;
+ Y = c4Shape.descr.Y + c4Shape.descr.height;
rectWidth = Math.max(c4Shape.label.width, c4Shape.descr.width);
- rectHeight = Y - c4Shape['descr'].textLines * 5;
+ rectHeight = Y - c4Shape.descr.textLines * 5;
}
rectWidth = rectWidth + conf.c4ShapePadding;
@@ -482,8 +482,8 @@ function drawInsideBoundary(
currentBoundaryLabelConf,
currentBounds.data.widthLimit
);
- currentBoundary['label'].Y = Y + 8;
- Y = currentBoundary['label'].Y + currentBoundary['label'].height;
+ currentBoundary.label.Y = Y + 8;
+ Y = currentBoundary.label.Y + currentBoundary.label.height;
if (currentBoundary.type && currentBoundary.type.text !== '') {
currentBoundary.type.text = '[' + currentBoundary.type.text + ']';
@@ -495,8 +495,8 @@ function drawInsideBoundary(
currentBoundaryTypeConf,
currentBounds.data.widthLimit
);
- currentBoundary['type'].Y = Y + 5;
- Y = currentBoundary['type'].Y + currentBoundary['type'].height;
+ currentBoundary.type.Y = Y + 5;
+ Y = currentBoundary.type.Y + currentBoundary.type.height;
}
if (currentBoundary.descr && currentBoundary.descr.text !== '') {
@@ -509,8 +509,8 @@ function drawInsideBoundary(
currentBoundaryDescrConf,
currentBounds.data.widthLimit
);
- currentBoundary['descr'].Y = Y + 20;
- Y = currentBoundary['descr'].Y + currentBoundary['descr'].height;
+ currentBoundary.descr.Y = Y + 20;
+ Y = currentBoundary.descr.Y + currentBoundary.descr.height;
}
if (i == 0 || i % c4BoundaryInRow === 0) {
diff --git a/packages/mermaid/src/diagrams/class/classDb.ts b/packages/mermaid/src/diagrams/class/classDb.ts
index 4cfa0bd29..cb8b90af4 100644
--- a/packages/mermaid/src/diagrams/class/classDb.ts
+++ b/packages/mermaid/src/diagrams/class/classDb.ts
@@ -26,10 +26,10 @@ import type {
const MERMAID_DOM_ID_PREFIX = 'classId-';
let relations: ClassRelation[] = [];
-let classes: Map = new Map();
+let classes = new Map();
let notes: ClassNote[] = [];
let classCounter = 0;
-let namespaces: Map = new Map();
+let namespaces = new Map();
let namespaceCounter = 0;
let functions: any[] = [];
@@ -223,7 +223,7 @@ export const cleanupLabel = function (label: string) {
export const setCssClass = function (ids: string, className: string) {
ids.split(',').forEach(function (_id) {
let id = _id;
- if (_id[0].match(/\d/)) {
+ if (/\d/.exec(_id[0])) {
id = MERMAID_DOM_ID_PREFIX + id;
}
const classNode = classes.get(id);
@@ -266,7 +266,7 @@ export const setLink = function (ids: string, linkStr: string, target: string) {
const config = getConfig();
ids.split(',').forEach(function (_id) {
let id = _id;
- if (_id[0].match(/\d/)) {
+ if (/\d/.exec(_id[0])) {
id = MERMAID_DOM_ID_PREFIX + id;
}
const theClass = classes.get(id);
@@ -320,7 +320,7 @@ const setClickFunc = function (_domId: string, functionName: string, functionArg
let item = argList[i].trim();
/* Removes all double quotes at the start and end of an argument */
/* This preserves all starting and ending whitespace inside */
- if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
+ if (item.startsWith('"') && item.endsWith('"')) {
item = item.substr(1, item.length - 2);
}
argList[i] = item;
diff --git a/packages/mermaid/src/diagrams/class/classRenderer-v2.ts b/packages/mermaid/src/diagrams/class/classRenderer-v2.ts
index b7b6ad98f..0f02efa0d 100644
--- a/packages/mermaid/src/diagrams/class/classRenderer-v2.ts
+++ b/packages/mermaid/src/diagrams/class/classRenderer-v2.ts
@@ -343,7 +343,7 @@ export const draw = async function (text: string, id: string, _version: string,
}
const root =
securityLevel === 'sandbox'
- ? select(sandboxElement!.nodes()[0]!.contentDocument.body)
+ ? select(sandboxElement.nodes()[0]!.contentDocument.body)
: select('body');
const svg = root.select(`[id="${id}"]`);
@@ -363,8 +363,7 @@ export const draw = async function (text: string, id: string, _version: string,
// Add label rects for non html labels
if (!conf?.htmlLabels) {
- const doc =
- securityLevel === 'sandbox' ? sandboxElement!.nodes()[0]!.contentDocument : document;
+ const doc = securityLevel === 'sandbox' ? sandboxElement.nodes()[0]!.contentDocument : document;
const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label');
for (const label of labels) {
// Get dimensions of label
diff --git a/packages/mermaid/src/diagrams/class/classTypes.ts b/packages/mermaid/src/diagrams/class/classTypes.ts
index 5c5812ee1..f1955a224 100644
--- a/packages/mermaid/src/diagrams/class/classTypes.ts
+++ b/packages/mermaid/src/diagrams/class/classTypes.ts
@@ -77,7 +77,7 @@ export class ClassMember {
if (this.memberType === 'method') {
const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/;
- const match = input.match(methodRegEx);
+ const match = methodRegEx.exec(input);
if (match) {
const detectedVisibility = match[1] ? match[1].trim() : '';
@@ -92,7 +92,7 @@ export class ClassMember {
if (potentialClassifier === '') {
const lastChar = this.returnType.substring(this.returnType.length - 1);
- if (lastChar.match(/[$*]/)) {
+ if (/[$*]/.exec(lastChar)) {
potentialClassifier = lastChar;
this.returnType = this.returnType.substring(0, this.returnType.length - 1);
}
@@ -107,7 +107,7 @@ export class ClassMember {
this.visibility = firstChar as Visibility;
}
- if (lastChar.match(/[$*]/)) {
+ if (/[$*]/.exec(lastChar)) {
potentialClassifier = lastChar;
}
diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts
index 66cc5ff6f..e24c8e85c 100644
--- a/packages/mermaid/src/diagrams/common/common.ts
+++ b/packages/mermaid/src/diagrams/common/common.ts
@@ -34,13 +34,13 @@ function setupDompurifyHooks() {
DOMPurify.addHook('beforeSanitizeAttributes', (node: Element) => {
if (node.tagName === 'A' && node.hasAttribute('target')) {
- node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') || '');
+ node.setAttribute(TEMPORARY_ATTRIBUTE, node.getAttribute('target') ?? '');
}
});
DOMPurify.addHook('afterSanitizeAttributes', (node: Element) => {
if (node.tagName === 'A' && node.hasAttribute(TEMPORARY_ATTRIBUTE)) {
- node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) || '');
+ node.setAttribute('target', node.getAttribute(TEMPORARY_ATTRIBUTE) ?? '');
node.removeAttribute(TEMPORARY_ATTRIBUTE);
if (node.getAttribute('target') === '_blank') {
node.setAttribute('rel', 'noopener');
@@ -83,6 +83,7 @@ export const sanitizeText = (text: string, config: MermaidConfig): string => {
return text;
}
if (config.dompurifyConfig) {
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
text = DOMPurify.sanitize(sanitizeMore(text, config), config.dompurifyConfig).toString();
} else {
text = DOMPurify.sanitize(sanitizeMore(text, config), {
diff --git a/packages/mermaid/src/diagrams/er/erDb.js b/packages/mermaid/src/diagrams/er/erDb.js
index 745ef938a..f24f48198 100644
--- a/packages/mermaid/src/diagrams/er/erDb.js
+++ b/packages/mermaid/src/diagrams/er/erDb.js
@@ -26,12 +26,16 @@ const Identification = {
NON_IDENTIFYING: 'NON_IDENTIFYING',
IDENTIFYING: 'IDENTIFYING',
};
-
+/**
+ * Add entity
+ * @param {string} name - The name of the entity
+ * @param {string | undefined} alias - The alias of the entity
+ */
const addEntity = function (name, alias = undefined) {
if (!entities.has(name)) {
- entities.set(name, { attributes: [], alias: alias });
+ entities.set(name, { attributes: [], alias });
log.info('Added new entity :', name);
- } else if (entities.has(name) && !entities.get(name).alias && alias) {
+ } else if (!entities.get(name).alias && alias) {
entities.get(name).alias = alias;
log.info(`Add alias '${alias}' to entity '${name}'`);
}
diff --git a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.spec.js b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.spec.js
index 96e6f6fd7..3a1bd865f 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowChartShapes.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowChartShapes.spec.js
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { addToRender } from './flowChartShapes.js';
describe('flowchart shapes', function () {
diff --git a/packages/mermaid/src/diagrams/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
index 797130e71..d03f1d989 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowDb.ts
+++ b/packages/mermaid/src/diagrams/flowchart/flowDb.ts
@@ -17,12 +17,12 @@ import type { FlowVertex, FlowClass, FlowSubGraph, FlowText, FlowEdge, FlowLink
const MERMAID_DOM_ID_PREFIX = 'flowchart-';
let vertexCounter = 0;
let config = getConfig();
-let vertices: Map = new Map();
+let vertices = new Map();
let edges: FlowEdge[] & { defaultInterpolate?: string; defaultStyle?: string[] } = [];
-let classes: Map = new Map();
+let classes = new Map();
let subGraphs: FlowSubGraph[] = [];
-let subGraphLookup: Map = new Map();
-let tooltips: Map = new Map();
+let subGraphLookup = new Map();
+let tooltips = new Map();
let subCount = 0;
let firstGraphFlag = true;
let direction: string;
@@ -84,7 +84,7 @@ export const addVertex = function (
txt = sanitizeText(textObj.text.trim());
vertex.labelType = textObj.type;
// strip quotes if string starts and ends with a quote
- if (txt[0] === '"' && txt[txt.length - 1] === '"') {
+ if (txt.startsWith('"') && txt.endsWith('"')) {
txt = txt.substring(1, txt.length - 1);
}
vertex.text = txt;
@@ -132,7 +132,7 @@ export const addSingleLink = function (_start: string, _end: string, type: any)
edge.text = sanitizeText(linkTextObj.text.trim());
// strip quotes if string starts and ends with a quote
- if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') {
+ if (edge.text.startsWith('"') && edge.text.endsWith('"')) {
edge.text = edge.text.substring(1, edge.text.length - 1);
}
edge.labelType = linkTextObj.type;
@@ -218,7 +218,7 @@ export const addClass = function (ids: string, style: string[]) {
if (style !== undefined && style !== null) {
style.forEach(function (s) {
- if (s.match('color')) {
+ if (/color/.exec(s)) {
const newStyle = s.replace('fill', 'bgFill').replace('color', 'fill');
classNode.textStyles.push(newStyle);
}
@@ -234,16 +234,16 @@ export const addClass = function (ids: string, style: string[]) {
*/
export const setDirection = function (dir: string) {
direction = dir;
- if (direction.match(/.*)) {
+ if (/.*/)) {
+ if (/.*>/.exec(direction)) {
direction = 'LR';
}
- if (direction.match(/.*v/)) {
+ if (/.*v/.exec(direction)) {
direction = 'TB';
}
if (direction === 'TD') {
@@ -297,7 +297,7 @@ const setClickFun = function (id: string, functionName: string, functionArgs: st
let item = argList[i].trim();
/* Removes all double quotes at the start and end of an argument */
/* This preserves all starting and ending whitespace inside */
- if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
+ if (item.startsWith('"') && item.endsWith('"')) {
item = item.substr(1, item.length - 2);
}
argList[i] = item;
@@ -469,7 +469,7 @@ export const addSubGraph = function (
) {
let id: string | undefined = _id.text.trim();
let title = _title.text;
- if (_id === _title && _title.text.match(/\s/)) {
+ if (_id === _title && /\s/.exec(_title.text)) {
id = undefined;
}
@@ -503,7 +503,7 @@ export const addSubGraph = function (
}
}
- id = id || 'subGraph' + subCount;
+ id = id ?? 'subGraph' + subCount;
title = title || '';
title = sanitizeText(title);
subCount = subCount + 1;
@@ -651,21 +651,21 @@ const destructEndLink = (_str: string) => {
switch (str.slice(-1)) {
case 'x':
type = 'arrow_cross';
- if (str[0] === 'x') {
+ if (str.startsWith('x')) {
type = 'double_' + type;
line = line.slice(1);
}
break;
case '>':
type = 'arrow_point';
- if (str[0] === '<') {
+ if (str.startsWith('<')) {
type = 'double_' + type;
line = line.slice(1);
}
break;
case 'o':
type = 'arrow_circle';
- if (str[0] === 'o') {
+ if (str.startsWith('o')) {
type = 'double_' + type;
line = line.slice(1);
}
@@ -675,11 +675,11 @@ const destructEndLink = (_str: string) => {
let stroke = 'normal';
let length = line.length - 1;
- if (line[0] === '=') {
+ if (line.startsWith('=')) {
stroke = 'thick';
}
- if (line[0] === '~') {
+ if (line.startsWith('~')) {
stroke = 'invisible';
}
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
index 7c81b7e6d..1dce1391e 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer-v2.js
@@ -366,8 +366,8 @@ export const draw = async function (text, id, _version, diagObj) {
}
const { securityLevel, flowchart: conf } = getConfig();
- const nodeSpacing = conf.nodeSpacing || 50;
- const rankSpacing = conf.rankSpacing || 50;
+ const nodeSpacing = conf.nodeSpacing ?? 50;
+ const rankSpacing = conf.rankSpacing ?? 50;
// Handle root and document for when rendering in sandbox mode
let sandboxElement;
@@ -420,14 +420,13 @@ export const draw = async function (text, id, _version, diagObj) {
log.info('Edges', edges);
let i = 0;
for (i = subGraphs.length - 1; i >= 0; i--) {
- // for (let i = 0; i < subGraphs.length; i++) {
subG = subGraphs[i];
selectAll('cluster').append('text');
- for (let j = 0; j < subG.nodes.length; j++) {
- log.info('Setting up subgraphs', subG.nodes[j], subG.id);
- g.setParent(subG.nodes[j], subG.id);
+ for (const node of subG.nodes) {
+ log.info('Setting up subgraphs', node, subG.id);
+ g.setParent(node, subG.id);
}
}
await addVertices(vert, g, id, root, doc, diagObj);
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
index ca558987c..314c6aa52 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.js
@@ -301,8 +301,8 @@ export const draw = async function (text, id, _version, diagObj) {
if (dir === undefined) {
dir = 'TD';
}
- const nodeSpacing = conf.nodeSpacing || 50;
- const rankSpacing = conf.rankSpacing || 50;
+ const nodeSpacing = conf.nodeSpacing ?? 50;
+ const rankSpacing = conf.rankSpacing ?? 50;
// Create the input mermaid.graph
const g = new graphlib.Graph({
@@ -339,14 +339,14 @@ export const draw = async function (text, id, _version, diagObj) {
selectAll('cluster').append('text');
- for (let j = 0; j < subG.nodes.length; j++) {
+ for (const node of subG.nodes) {
log.warn(
'Setting subgraph',
- subG.nodes[j],
- diagObj.db.lookUpDomId(subG.nodes[j]),
+ node,
+ diagObj.db.lookUpDomId(node),
diagObj.db.lookUpDomId(subG.id)
);
- g.setParent(diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id));
+ g.setParent(diagObj.db.lookUpDomId(node), diagObj.db.lookUpDomId(subG.id));
}
}
await addVertices(vert, g, id, root, doc, diagObj);
@@ -429,8 +429,8 @@ export const draw = async function (text, id, _version, diagObj) {
te.attr('transform', `translate(${xPos + _width / 2}, ${yPos + 14})`);
te.attr('id', id + 'Text');
- for (let j = 0; j < subG.classes.length; j++) {
- clusterEl[0].classList.add(subG.classes[j]);
+ for (const className of subG.classes) {
+ clusterEl[0].classList.add(className);
}
}
}
diff --git a/packages/mermaid/src/diagrams/flowchart/flowRenderer.spec.js b/packages/mermaid/src/diagrams/flowchart/flowRenderer.spec.js
index bdf778b54..79bf75453 100644
--- a/packages/mermaid/src/diagrams/flowchart/flowRenderer.spec.js
+++ b/packages/mermaid/src/diagrams/flowchart/flowRenderer.spec.js
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { addVertices, addEdges } from './flowRenderer.js';
import { setConfig } from '../../diagram-api/diagramAPI.js';
diff --git a/packages/mermaid/src/diagrams/gantt/ganttDb.js b/packages/mermaid/src/diagrams/gantt/ganttDb.js
index 160f29713..15c7fab97 100644
--- a/packages/mermaid/src/diagrams/gantt/ganttDb.js
+++ b/packages/mermaid/src/diagrams/gantt/ganttDb.js
@@ -676,7 +676,7 @@ const setClickFun = function (id, functionName, functionArgs) {
let item = argList[i].trim();
/* Removes all double quotes at the start and end of an argument */
/* This preserves all starting and ending whitespace inside */
- if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') {
+ if (item.startsWith('"') && item.endsWith('"')) {
item = item.substr(1, item.length - 2);
}
argList[i] = item;
diff --git a/packages/mermaid/src/diagrams/git/gitGraphAst.js b/packages/mermaid/src/diagrams/git/gitGraphAst.js
index e049d5754..0f7ca29a2 100644
--- a/packages/mermaid/src/diagrams/git/gitGraphAst.js
+++ b/packages/mermaid/src/diagrams/git/gitGraphAst.js
@@ -90,7 +90,7 @@ export const setDirection = function (dir) {
let options = {};
export const setOptions = function (rawOptString) {
log.debug('options str', rawOptString);
- rawOptString = rawOptString && rawOptString.trim();
+ rawOptString = rawOptString?.trim();
rawOptString = rawOptString || '{}';
try {
options = JSON.parse(rawOptString);
diff --git a/packages/mermaid/src/diagrams/git/gitGraphParser.spec.js b/packages/mermaid/src/diagrams/git/gitGraphParser.spec.js
index 3398dd55f..d498577fe 100644
--- a/packages/mermaid/src/diagrams/git/gitGraphParser.spec.js
+++ b/packages/mermaid/src/diagrams/git/gitGraphParser.spec.js
@@ -36,7 +36,7 @@ describe('when parsing a gitGraph', function () {
parser.parse(str);
const commits = parser.yy.getCommits();
- expect(parser.yy.getOptions()['key']).toBe('value');
+ expect(parser.yy.getOptions().key).toBe('value');
expect(commits.size).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('main');
expect(parser.yy.getDirection()).toBe('LR');
diff --git a/packages/mermaid/src/diagrams/pie/pieRenderer.ts b/packages/mermaid/src/diagrams/pie/pieRenderer.ts
index 5a3698e1e..8f3b9cc5b 100644
--- a/packages/mermaid/src/diagrams/pie/pieRenderer.ts
+++ b/packages/mermaid/src/diagrams/pie/pieRenderer.ts
@@ -119,6 +119,7 @@ export const draw: DrawDefinition = (text, id, _version, diagObj) => {
return ((datum.data.value / sum) * 100).toFixed(0) + '%';
})
.attr('transform', (datum: d3.PieArcDatum): string => {
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
return 'translate(' + labelArcGenerator.centroid(datum) + ')';
})
.style('text-anchor', 'middle')
diff --git a/packages/mermaid/src/diagrams/quadrant-chart/quadrantBuilder.ts b/packages/mermaid/src/diagrams/quadrant-chart/quadrantBuilder.ts
index f1507a1b9..c7d478ed1 100644
--- a/packages/mermaid/src/diagrams/quadrant-chart/quadrantBuilder.ts
+++ b/packages/mermaid/src/diagrams/quadrant-chart/quadrantBuilder.ts
@@ -127,7 +127,7 @@ export class QuadrantBuilder {
private config: QuadrantBuilderConfig;
private themeConfig: QuadrantBuilderThemeConfig;
private data: QuadrantBuilderData;
- private classes: Map = new Map();
+ private classes = new Map();
constructor() {
this.config = this.getDefaultConfig();
@@ -493,8 +493,8 @@ export class QuadrantBuilder {
const props: QuadrantPointType = {
x: xAxis(point.x),
y: yAxis(point.y),
- fill: point.color || this.themeConfig.quadrantPointFill,
- radius: point.radius || this.config.pointRadius,
+ fill: point.color ?? this.themeConfig.quadrantPointFill,
+ radius: point.radius ?? this.config.pointRadius,
text: {
text: point.text,
fill: this.themeConfig.quadrantPointTextFill,
@@ -505,8 +505,8 @@ export class QuadrantBuilder {
fontSize: this.config.pointLabelFontSize,
rotation: 0,
},
- strokeColor: point.strokeColor || this.themeConfig.quadrantPointFill,
- strokeWidth: point.strokeWidth || '0px',
+ strokeColor: point.strokeColor ?? this.themeConfig.quadrantPointFill,
+ strokeWidth: point.strokeWidth ?? '0px',
};
return props;
});
diff --git a/packages/mermaid/src/diagrams/quadrant-chart/quadrantRenderer.ts b/packages/mermaid/src/diagrams/quadrant-chart/quadrantRenderer.ts
index c2295da4d..6d2435cd4 100644
--- a/packages/mermaid/src/diagrams/quadrant-chart/quadrantRenderer.ts
+++ b/packages/mermaid/src/diagrams/quadrant-chart/quadrantRenderer.ts
@@ -46,10 +46,10 @@ export const draw = (txt: string, id: string, _version: string, diagObj: Diagram
const group = svg.append('g').attr('class', 'main');
- const width = conf.quadrantChart?.chartWidth || 500;
- const height = conf.quadrantChart?.chartHeight || 500;
+ const width = conf.quadrantChart?.chartWidth ?? 500;
+ const height = conf.quadrantChart?.chartHeight ?? 500;
- configureSvgSize(svg, height, width, conf.quadrantChart?.useMaxWidth || true);
+ configureSvgSize(svg, height, width, conf.quadrantChart?.useMaxWidth ?? true);
svg.attr('viewBox', '0 0 ' + width + ' ' + height);
diff --git a/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts b/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts
index 169aee873..007cda6f9 100644
--- a/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts
+++ b/packages/mermaid/src/diagrams/sankey/parser/sankey.spec.ts
@@ -13,7 +13,7 @@ describe('Sankey diagram', function () {
sankey.parser.yy.clear();
});
- it('parses csv', async () => {
+ it('parses csv', () => {
const csv = path.resolve(__dirname, './energy.csv');
const data = fs.readFileSync(csv, 'utf8');
const graphDefinition = prepareTextForParsing(cleanupComments('sankey-beta\n\n ' + data));
diff --git a/packages/mermaid/src/diagrams/sankey/sankeyDB.ts b/packages/mermaid/src/diagrams/sankey/sankeyDB.ts
index 735ef045b..c3e1a9901 100644
--- a/packages/mermaid/src/diagrams/sankey/sankeyDB.ts
+++ b/packages/mermaid/src/diagrams/sankey/sankeyDB.ts
@@ -15,7 +15,7 @@ let links: SankeyLink[] = [];
// Array of nodes guarantees their order
let nodes: SankeyNode[] = [];
// We also have to track nodes uniqueness (by ID)
-let nodesMap: Map = new Map();
+let nodesMap = new Map();
const clear = (): void => {
links = [];
@@ -28,7 +28,7 @@ class SankeyLink {
constructor(
public source: SankeyNode,
public target: SankeyNode,
- public value: number = 0
+ public value = 0
) {}
}
diff --git a/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts b/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
index 51f808ff4..a981a346e 100644
--- a/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
+++ b/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts
@@ -5,7 +5,6 @@ import {
scaleOrdinal as d3scaleOrdinal,
schemeTableau10 as d3schemeTableau10,
} from 'd3';
-
import type { SankeyNode as d3SankeyNode } from 'd3-sankey';
import {
sankey as d3Sankey,
@@ -41,7 +40,7 @@ const alignmentsMap: Record<
export const draw = function (text: string, id: string, _version: string, diagObj: Diagram): void {
// Get Sankey config
const { securityLevel, sankey: conf } = getConfig();
- const defaultSankeyConfig = defaultConfig!.sankey!;
+ const defaultSankeyConfig = defaultConfig.sankey!;
// TODO:
// This code repeats for every diagram
@@ -160,7 +159,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
.attr('class', 'link')
.style('mix-blend-mode', 'multiply');
- const linkColor = conf?.linkColor || 'gradient';
+ const linkColor = conf?.linkColor ?? 'gradient';
if (linkColor === 'gradient') {
const gradient = link
diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts
index 19f6d561a..69ddeaf18 100644
--- a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts
+++ b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts
@@ -46,7 +46,7 @@ const state = new ImperativeState(() => ({
export const addBox = function (data: { text: string; color: string; wrap: boolean }) {
state.records.boxes.push({
name: data.text,
- wrap: (data.wrap === undefined && autoWrap()) || !!data.wrap,
+ wrap: data.wrap ?? autoWrap(),
fill: data.color,
actorKeys: [],
});
@@ -80,18 +80,18 @@ export const addActor = function (
}
// Don't allow null descriptions, either
- if (description == null || description.text == null) {
- description = { text: name, wrap: null, type };
+ if (description?.text == null) {
+ description = { text: name, type };
}
if (type == null || description.text == null) {
- description = { text: name, wrap: null, type };
+ description = { text: name, type };
}
state.records.actors.set(id, {
box: assignedBox,
name: name,
description: description.text,
- wrap: (description.wrap === undefined && autoWrap()) || !!description.wrap,
+ wrap: description.wrap ?? autoWrap(),
prevActor: state.records.prevActor,
links: {},
properties: {},
@@ -145,7 +145,7 @@ export const addMessage = function (
from: idFrom,
to: idTo,
message: message.text,
- wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
+ wrap: message.wrap ?? autoWrap(),
answer: answer,
});
};
@@ -155,10 +155,10 @@ export const addSignal = function (
idTo?: Message['to'],
message?: { text: string; wrap: boolean },
messageType?: number,
- activate: boolean = false
+ activate = false
) {
if (messageType === LINETYPE.ACTIVE_END) {
- const cnt = activationCount(idFrom || '');
+ const cnt = activationCount(idFrom ?? '');
if (cnt < 1) {
// Bail out as there is an activation signal from an inactive participant
const error = new Error('Trying to inactivate an inactive participant (' + idFrom + ')');
@@ -178,7 +178,7 @@ export const addSignal = function (
from: idFrom,
to: idTo,
message: message?.text ?? '',
- wrap: (message?.wrap === undefined && autoWrap()) || !!message?.wrap,
+ wrap: message?.wrap ?? autoWrap(),
type: messageType,
activate,
});
@@ -228,13 +228,24 @@ export const setWrap = function (wrapSetting?: boolean) {
state.records.wrapEnabled = wrapSetting;
};
+const extractWrap = (text?: string): { cleanedText?: string; wrap?: boolean } => {
+ if (text === undefined) {
+ return {};
+ }
+ text = text.trim();
+ const wrap =
+ /^:?wrap:/.exec(text) !== null ? true : /^:?nowrap:/.exec(text) !== null ? false : undefined;
+ const cleanedText = (wrap === undefined ? text : text.replace(/^:?(?:no)?wrap:/, '')).trim();
+ return { cleanedText, wrap };
+};
+
export const autoWrap = () => {
// if setWrap has been called, use that value, otherwise use the value from the config
// TODO: refactor, always use the config value let setWrap update the config value
if (state.records.wrapEnabled !== undefined) {
return state.records.wrapEnabled;
}
- return getConfig()?.sequence?.wrap;
+ return getConfig().sequence?.wrap ?? false;
};
export const clear = function () {
@@ -244,16 +255,12 @@ export const clear = function () {
export const parseMessage = function (str: string) {
const trimmedStr = str.trim();
+ const { wrap, cleanedText } = extractWrap(trimmedStr);
const message = {
- text: trimmedStr.replace(/^:?(?:no)?wrap:/, '').trim(),
- wrap:
- trimmedStr.match(/^:?wrap:/) !== null
- ? true
- : trimmedStr.match(/^:?nowrap:/) !== null
- ? false
- : undefined,
+ text: cleanedText,
+ wrap,
};
- log.debug(`parseMessage: ${message}`);
+ log.debug(`parseMessage: ${JSON.stringify(message)}`);
return message;
};
@@ -261,12 +268,12 @@ export const parseMessage = function (str: string) {
// The color can be rgb,rgba,hsl,hsla, or css code names #hex codes are not supported for now because of the way the char # is handled
// We extract first segment as color, the rest of the line is considered as text
export const parseBoxData = function (str: string) {
- const match = str.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);
- let color = match != null && match[1] ? match[1].trim() : 'transparent';
- let title = match != null && match[2] ? match[2].trim() : undefined;
+ const match = /^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/.exec(str);
+ let color = match?.[1] ? match[1].trim() : 'transparent';
+ let title = match?.[2] ? match[2].trim() : undefined;
// check that the string is a color
- if (window && window.CSS) {
+ if (window?.CSS) {
if (!window.CSS.supports('color', color)) {
color = 'transparent';
title = str.trim();
@@ -279,21 +286,11 @@ export const parseBoxData = function (str: string) {
title = str.trim();
}
}
-
+ const { wrap, cleanedText } = extractWrap(title);
return {
- color: color,
- text:
- title !== undefined
- ? sanitizeText(title.replace(/^:?(?:no)?wrap:/, ''), getConfig())
- : undefined,
- wrap:
- title !== undefined
- ? title.match(/^:?wrap:/) !== null
- ? true
- : title.match(/^:?nowrap:/) !== null
- ? false
- : undefined
- : undefined,
+ text: cleanedText ? sanitizeText(cleanedText, getConfig()) : undefined,
+ color,
+ wrap,
};
};
@@ -352,7 +349,7 @@ export const addNote = function (
actor: actor,
placement: placement,
message: message.text,
- wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
+ wrap: message.wrap ?? autoWrap(),
};
//@ts-ignore: Coerce actor into a [to, from, ...] array
@@ -363,7 +360,7 @@ export const addNote = function (
from: actors[0],
to: actors[1],
message: message.text,
- wrap: (message.wrap === undefined && autoWrap()) || !!message.wrap,
+ wrap: message.wrap ?? autoWrap(),
type: LINETYPE.NOTE,
placement: placement,
});
@@ -461,12 +458,12 @@ export const addDetails = function (actorId: string, text: { text: string }) {
const text = elem.innerHTML;
const details = JSON.parse(text);
// add the deserialized text to the actor's property field.
- if (details['properties']) {
- insertProperties(actor, details['properties']);
+ if (details.properties) {
+ insertProperties(actor, details.properties);
}
- if (details['links']) {
- insertLinks(actor, details['links']);
+ if (details.links) {
+ insertLinks(actor, details.links);
}
} catch (e) {
log.error('error while parsing actor details text', e);
@@ -474,13 +471,14 @@ export const addDetails = function (actorId: string, text: { text: string }) {
};
export const getActorProperty = function (actor: Actor, key: string) {
- if (actor !== undefined && actor.properties !== undefined) {
+ if (actor?.properties !== undefined) {
return actor.properties[key];
}
return undefined;
};
+// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-redundant-type-constituents
export const apply = function (param: any | AddMessageParams | AddMessageParams[]) {
if (Array.isArray(param)) {
param.forEach(function (item) {
@@ -544,7 +542,7 @@ export const apply = function (param: any | AddMessageParams | AddMessageParams[
if (param.to !== state.records.lastCreated) {
throw new Error(
'The created participant ' +
- state.records.lastCreated +
+ state.records.lastCreated.name +
' does not have an associated creating message after its declaration. Please check the sequence diagram.'
);
} else {
@@ -557,7 +555,7 @@ export const apply = function (param: any | AddMessageParams | AddMessageParams[
) {
throw new Error(
'The destroyed participant ' +
- state.records.lastDestroyed +
+ state.records.lastDestroyed.name +
' does not have an associated destroying message after its declaration. Please check the sequence diagram.'
);
} else {
diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
index 5f29b9f73..7f6b80ca5 100644
--- a/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
+++ b/packages/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
@@ -1339,15 +1339,15 @@ link a: Tests @ https://tests.contoso.com/?svc=alice@contoso.com
await mermaidAPI.parse(str);
const actors = diagram.db.getActors();
- expect(actors.get('a').links['Repo']).toBe('https://repo.contoso.com/');
- expect(actors.get('b').links['Repo']).toBe(undefined);
- expect(actors.get('a').links['Dashboard']).toBe('https://dashboard.contoso.com/');
- expect(actors.get('b').links['Dashboard']).toBe('https://dashboard.contoso.com/');
+ expect(actors.get('a').links.Repo).toBe('https://repo.contoso.com/');
+ expect(actors.get('b').links.Repo).toBe(undefined);
+ expect(actors.get('a').links.Dashboard).toBe('https://dashboard.contoso.com/');
+ expect(actors.get('b').links.Dashboard).toBe('https://dashboard.contoso.com/');
expect(actors.get('a').links['On-Call']).toBe('https://oncall.contoso.com/?svc=alice');
- expect(actors.get('c').links['Dashboard']).toBe(undefined);
- expect(actors.get('a').links['Endpoint']).toBe('https://alice.contoso.com');
- expect(actors.get('a').links['Swagger']).toBe('https://swagger.contoso.com');
- expect(actors.get('a').links['Tests']).toBe('https://tests.contoso.com/?svc=alice@contoso.com');
+ expect(actors.get('c').links.Dashboard).toBe(undefined);
+ expect(actors.get('a').links.Endpoint).toBe('https://alice.contoso.com');
+ expect(actors.get('a').links.Swagger).toBe('https://swagger.contoso.com');
+ expect(actors.get('a').links.Tests).toBe('https://tests.contoso.com/?svc=alice@contoso.com');
});
it('should handle properties EXPERIMENTAL: USE WITH CAUTION', async () => {
@@ -1363,11 +1363,11 @@ properties b: {"class": "external-service-actor", "icon": "@computer"}
await mermaidAPI.parse(str);
const actors = diagram.db.getActors();
- expect(actors.get('a').properties['class']).toBe('internal-service-actor');
- expect(actors.get('b').properties['class']).toBe('external-service-actor');
- expect(actors.get('a').properties['icon']).toBe('@clock');
- expect(actors.get('b').properties['icon']).toBe('@computer');
- expect(actors.get('c').properties['class']).toBe(undefined);
+ expect(actors.get('a').properties.class).toBe('internal-service-actor');
+ expect(actors.get('b').properties.class).toBe('external-service-actor');
+ expect(actors.get('a').properties.icon).toBe('@clock');
+ expect(actors.get('b').properties.icon).toBe('@computer');
+ expect(actors.get('c').properties.class).toBe(undefined);
});
it('should handle box', async () => {
@@ -1519,7 +1519,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
diagram.renderer.bounds.init();
conf = diagram.db.getConfig();
});
- it('should handle a simple bound call', async () => {
+ it('should handle a simple bound call', () => {
diagram.renderer.bounds.insert(100, 100, 200, 200);
const { bounds } = diagram.renderer.bounds.getBounds();
@@ -1528,7 +1528,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(bounds.stopx).toBe(200);
expect(bounds.stopy).toBe(200);
});
- it('should handle an expanding bound', async () => {
+ it('should handle an expanding bound', () => {
diagram.renderer.bounds.insert(100, 100, 200, 200);
diagram.renderer.bounds.insert(25, 50, 300, 400);
@@ -1538,7 +1538,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(bounds.stopx).toBe(300);
expect(bounds.stopy).toBe(400);
});
- it('should handle inserts within the bound without changing the outer bounds', async () => {
+ it('should handle inserts within the bound without changing the outer bounds', () => {
diagram.renderer.bounds.insert(100, 100, 200, 200);
diagram.renderer.bounds.insert(25, 50, 300, 400);
diagram.renderer.bounds.insert(125, 150, 150, 200);
@@ -1549,7 +1549,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(bounds.stopx).toBe(300);
expect(bounds.stopy).toBe(400);
});
- it('should handle a loop without expanding the area', async () => {
+ it('should handle a loop without expanding the area', () => {
diagram.renderer.bounds.insert(25, 50, 300, 400);
diagram.renderer.bounds.verticalPos = 150;
diagram.renderer.bounds.newLoop();
@@ -1570,7 +1570,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(bounds.stopx).toBe(300);
expect(bounds.stopy).toBe(400);
});
- it('should handle multiple loops withtout expanding the bounds', async () => {
+ it('should handle multiple loops withtout expanding the bounds', () => {
diagram.renderer.bounds.insert(100, 100, 1000, 1000);
diagram.renderer.bounds.verticalPos = 200;
diagram.renderer.bounds.newLoop();
@@ -1601,7 +1601,7 @@ describe('when checking the bounds in a sequenceDiagram', function () {
expect(bounds.stopx).toBe(1000);
expect(bounds.stopy).toBe(1000);
});
- it('should handle a loop that expands the area', async () => {
+ it('should handle a loop that expands the area', () => {
diagram.renderer.bounds.insert(100, 100, 200, 200);
diagram.renderer.bounds.verticalPos = 200;
diagram.renderer.bounds.newLoop();
diff --git a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
index d9fbb16c5..5299f1b1e 100644
--- a/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
+++ b/packages/mermaid/src/diagrams/sequence/sequenceRenderer.ts
@@ -495,7 +495,7 @@ const drawMessage = async function (diagram, msgModel, lineStartY: number, diagO
}
};
-const addActorRenderingData = async function (
+const addActorRenderingData = function (
diagram,
actors,
createdActors: Map,
@@ -822,7 +822,7 @@ export const draw = async function (_text: string, id: string, _version: string,
actorKeys = actorKeys.filter((actorKey) => newActors.has(actorKey));
}
- await addActorRenderingData(diagram, actors, createdActors, actorKeys, 0, messages, false);
+ addActorRenderingData(diagram, actors, createdActors, actorKeys, 0, messages, false);
const loopWidths = await calculateLoopBounds(messages, actors, maxMessageWidthPerActor, diagObj);
// The arrow head definition is attached to the svg once
@@ -1076,7 +1076,7 @@ export const draw = async function (_text: string, id: string, _version: string,
box.stopx = box.startx + box.width;
box.stopy = box.starty + box.height;
box.stroke = 'rgb(0,0,0, 0.5)';
- await svgDraw.drawBox(diagram, box, conf);
+ svgDraw.drawBox(diagram, box, conf);
}
if (hasBoxes) {
@@ -1147,7 +1147,7 @@ async function getMaxMessageWidthPerActor(
actors: Map,
messages: any[],
diagObj: Diagram
-): Promise<{ [id: string]: number }> {
+): Promise> {
const maxMessageWidthPerActor = {};
for (const msg of messages) {
@@ -1581,7 +1581,7 @@ const calculateLoopBounds = async function (messages, actors, _maxWidthPerActor,
const lastActorActivationIdx = bounds.activations
.map((a) => a.actor)
.lastIndexOf(msg.from);
- delete bounds.activations.splice(lastActorActivationIdx, 1)[0];
+ bounds.activations.splice(lastActorActivationIdx, 1).splice(0, 1);
}
break;
}
diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js
index bcc06602f..51968ef9f 100644
--- a/packages/mermaid/src/diagrams/sequence/svgDraw.js
+++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js
@@ -115,6 +115,7 @@ export const drawKatex = async function (elem, textData, msgModel = null) {
stopx = temp;
}
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
textElem.attr('x', Math.round(startx + Math.abs(startx - stopx) / 2 - dim.width / 2));
if (textData.class === 'loopText') {
textElem.attr('y', Math.round(starty));
@@ -325,7 +326,7 @@ export const fixLifeLineHeights = (diagram, actors, actorKeys, conf) => {
* @param {any} conf - DrawText implementation discriminator object
* @param {boolean} isFooter - If the actor is the footer one
*/
-const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
+const drawActorTypeParticipant = function (elem, actor, conf, isFooter) {
const actorY = isFooter ? actor.stopy : actor.starty;
const center = actor.x + actor.width / 2;
const centerY = actorY + 5;
@@ -359,8 +360,8 @@ const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
const rect = svgDrawCommon.getNoteRect();
var cssclass = 'actor';
- if (actor.properties != null && actor.properties['class']) {
- cssclass = actor.properties['class'];
+ if (actor.properties?.class) {
+ cssclass = actor.properties.class;
} else {
rect.fill = '#eaeaea';
}
@@ -380,8 +381,8 @@ const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
const rectElem = drawRect(g, rect);
actor.rectData = rect;
- if (actor.properties != null && actor.properties['icon']) {
- const iconSrc = actor.properties['icon'].trim();
+ if (actor.properties?.icon) {
+ const iconSrc = actor.properties.icon.trim();
if (iconSrc.charAt(0) === '@') {
svgDrawCommon.drawEmbeddedImage(g, rect.x + rect.width - 20, rect.y + 10, iconSrc.substr(1));
} else {
@@ -389,7 +390,7 @@ const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
}
}
- await _drawTextCandidateFunc(conf, hasKatex(actor.description))(
+ _drawTextCandidateFunc(conf, hasKatex(actor.description))(
actor.description,
g,
rect.x,
@@ -410,7 +411,7 @@ const drawActorTypeParticipant = async function (elem, actor, conf, isFooter) {
return height;
};
-const drawActorTypeActor = async function (elem, actor, conf, isFooter) {
+const drawActorTypeActor = function (elem, actor, conf, isFooter) {
const actorY = isFooter ? actor.stopy : actor.starty;
const center = actor.x + actor.width / 2;
const centerY = actorY + 80;
@@ -491,7 +492,7 @@ const drawActorTypeActor = async function (elem, actor, conf, isFooter) {
const bounds = actElem.node().getBBox();
actor.height = bounds.height;
- await _drawTextCandidateFunc(conf, hasKatex(actor.description))(
+ _drawTextCandidateFunc(conf, hasKatex(actor.description))(
actor.description,
actElem,
rect.x,
@@ -514,12 +515,12 @@ export const drawActor = async function (elem, actor, conf, isFooter) {
}
};
-export const drawBox = async function (elem, box, conf) {
+export const drawBox = function (elem, box, conf) {
const boxplusTextGroup = elem.append('g');
const g = boxplusTextGroup;
drawBackgroundRect(g, box);
if (box.name) {
- await _drawTextCandidateFunc(conf)(
+ _drawTextCandidateFunc(conf)(
box.name,
g,
box.x,
diff --git a/packages/mermaid/src/diagrams/sequence/types.ts b/packages/mermaid/src/diagrams/sequence/types.ts
index 5cc6ae249..10c1c8ed3 100644
--- a/packages/mermaid/src/diagrams/sequence/types.ts
+++ b/packages/mermaid/src/diagrams/sequence/types.ts
@@ -78,8 +78,7 @@ export interface AddMessageParams {
| 'breakEnd'
| 'parOverStart'
| 'parOverEnd'
- | 'parOverAnd'
- | 'parOverEnd';
+ | 'parOverAnd';
activate: boolean;
}
diff --git a/packages/mermaid/src/diagrams/state/stateDb.js b/packages/mermaid/src/diagrams/state/stateDb.js
index 85c09c536..836b6fe07 100644
--- a/packages/mermaid/src/diagrams/state/stateDb.js
+++ b/packages/mermaid/src/diagrams/state/stateDb.js
@@ -465,7 +465,7 @@ export const addStyleClass = function (id, styleAttributes = '') {
const fixedAttrib = attrib.replace(/([^;]*);/, '$1').trim();
// replace some style keywords
- if (attrib.match(COLOR_KEYWORD)) {
+ if (RegExp(COLOR_KEYWORD).exec(attrib)) {
const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);
const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);
foundClass.textStyles.push(newStyle2);
diff --git a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
index 0ecc0a73a..acb10427b 100644
--- a/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
+++ b/packages/mermaid/src/diagrams/state/stateRenderer-v2.js
@@ -362,8 +362,7 @@ const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) =
const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {
let dir = defaultDir;
if (parsedItem.doc) {
- for (let i = 0; i < parsedItem.doc.length; i++) {
- const parsedItemDoc = parsedItem.doc[i];
+ for (const parsedItemDoc of parsedItem.doc) {
if (parsedItemDoc.stmt === 'dir') {
dir = parsedItemDoc.value;
}
diff --git a/packages/mermaid/src/diagrams/timeline/svgDraw.js b/packages/mermaid/src/diagrams/timeline/svgDraw.js
index c5fc2a3c4..723dc46f1 100644
--- a/packages/mermaid/src/diagrams/timeline/svgDraw.js
+++ b/packages/mermaid/src/diagrams/timeline/svgDraw.js
@@ -515,8 +515,7 @@ export const drawNode = function (elem, node, fullSection, conf) {
.attr('text-anchor', 'middle')
.call(wrap, node.width);
const bbox = txt.node().getBBox();
- const fontSize =
- conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
+ const fontSize = conf.fontSize?.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;
node.height = Math.max(node.height, node.maxHeight);
node.width = node.width + 2 * node.padding;
@@ -540,8 +539,7 @@ export const getVirtualNodeHeight = function (elem, node, conf) {
.attr('text-anchor', 'middle')
.call(wrap, node.width);
const bbox = txt.node().getBBox();
- const fontSize =
- conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
+ const fontSize = conf.fontSize?.replace ? conf.fontSize.replace('px', '') : conf.fontSize;
textElem.remove();
return bbox.height + fontSize * 1.1 * 0.5 + node.padding;
};
diff --git a/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts b/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts
index 2f1f15689..b3405bc1b 100644
--- a/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts
+++ b/packages/mermaid/src/diagrams/timeline/timelineRenderer.ts
@@ -115,8 +115,7 @@ export const draw = function (text: string, id: string, version: string, diagObj
maxEventCount = Math.max(maxEventCount, task.events.length);
//calculate maxEventLineLength
let maxEventLineLengthTemp = 0;
- for (let j = 0; j < task.events.length; j++) {
- const event = task.events[j];
+ for (const event of task.events) {
const eventNode = {
descr: event,
section: task.section,
diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/bandAxis.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/bandAxis.ts
index 864ef1316..98eb31235 100644
--- a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/bandAxis.ts
+++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/bandAxis.ts
@@ -40,6 +40,6 @@ export class BandAxis extends BaseAxis {
}
getScaleValue(value: string): number {
- return this.scale(value) || this.getRange()[0];
+ return this.scale(value) ?? this.getRange()[0];
}
}
diff --git a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/baseAxis.ts b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/baseAxis.ts
index c3240a4a7..ef60cc85f 100644
--- a/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/baseAxis.ts
+++ b/packages/mermaid/src/diagrams/xychart/chartBuilder/components/axis/baseAxis.ts
@@ -58,7 +58,7 @@ export abstract class BaseAxis implements Axis {
abstract recalculateScale(): void;
- abstract getTickValues(): Array;
+ abstract getTickValues(): (string | number)[];
getTickDistance(): number {
const range = this.getRange();
diff --git a/packages/mermaid/src/docs/.vitepress/config.ts b/packages/mermaid/src/docs/.vitepress/config.ts
index ad81e9e0b..940fc6940 100644
--- a/packages/mermaid/src/docs/.vitepress/config.ts
+++ b/packages/mermaid/src/docs/.vitepress/config.ts
@@ -9,9 +9,9 @@ const allMarkdownTransformers: MarkdownOptions = {
light: 'github-light',
dark: 'github-dark',
},
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
- config: async (md) => {
- await MermaidExample(md);
+
+ config: (md) => {
+ MermaidExample(md);
},
};
diff --git a/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts b/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts
index 64a069b4c..d1aeee5ac 100644
--- a/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts
+++ b/packages/mermaid/src/docs/.vitepress/mermaid-markdown-all.ts
@@ -1,6 +1,6 @@
import type { MarkdownRenderer } from 'vitepress';
-const MermaidExample = async (md: MarkdownRenderer) => {
+const MermaidExample = (md: MarkdownRenderer) => {
const defaultRenderer = md.renderer.rules.fence;
if (!defaultRenderer) {
diff --git a/packages/mermaid/src/docs/.vitepress/theme/index.ts b/packages/mermaid/src/docs/.vitepress/theme/index.ts
index dae9fd8ff..3ce3aea23 100644
--- a/packages/mermaid/src/docs/.vitepress/theme/index.ts
+++ b/packages/mermaid/src/docs/.vitepress/theme/index.ts
@@ -35,7 +35,7 @@ export default {
const url = new URL(window.location.origin + to);
const newPath = getRedirect(url);
if (newPath) {
- console.log(`Redirecting to ${newPath} from ${window.location}`);
+ console.log(`Redirecting to ${newPath} from ${window.location.toString()}`);
// router.go isn't loading the ID properly.
window.location.href = `/${newPath}`;
}
diff --git a/packages/mermaid/src/docs/vite.config.ts b/packages/mermaid/src/docs/vite.config.ts
index ed5f4bab9..399e5c65e 100644
--- a/packages/mermaid/src/docs/vite.config.ts
+++ b/packages/mermaid/src/docs/vite.config.ts
@@ -49,12 +49,12 @@ export default defineConfig({
// TODO: will be fixed in the next vitepress release.
name: 'fix-virtual',
- async resolveId(id: string) {
+ resolveId(id: string) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
- async load(this, id: string) {
+ load(this, id: string) {
if (id === resolvedVirtualModuleId) {
return `export default ${JSON.stringify({
securityLevel: 'loose',
diff --git a/packages/mermaid/src/logger.ts b/packages/mermaid/src/logger.ts
index d69615b3d..cffd2112c 100644
--- a/packages/mermaid/src/logger.ts
+++ b/packages/mermaid/src/logger.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-console */
@@ -28,12 +29,11 @@ export const log: Record = {
*
* @param level - The level to set the logging to. Default is `"fatal"`
*/
-export const setLogLevel = function (level: keyof typeof LEVELS | number | string = 'fatal') {
+export const setLogLevel = function (level: keyof typeof LEVELS | number = 'fatal') {
let numericLevel: number = LEVELS.fatal;
if (typeof level === 'string') {
- level = level.toLowerCase();
- if (level in LEVELS) {
- numericLevel = LEVELS[level as keyof typeof LEVELS];
+ if (level.toLowerCase() in LEVELS) {
+ numericLevel = LEVELS[level];
}
} else if (typeof level === 'number') {
numericLevel = level;
diff --git a/packages/mermaid/src/mermaid.spec.ts b/packages/mermaid/src/mermaid.spec.ts
index d03f0ee9d..586d3605c 100644
--- a/packages/mermaid/src/mermaid.spec.ts
+++ b/packages/mermaid/src/mermaid.spec.ts
@@ -5,7 +5,7 @@ import { addDiagrams } from './diagram-api/diagram-orchestration.js';
import { beforeAll, describe, it, expect, vi, afterEach } from 'vitest';
import type { DiagramDefinition } from './diagram-api/types.js';
-beforeAll(async () => {
+beforeAll(() => {
addDiagrams();
});
const spyOn = vi.spyOn;
@@ -18,7 +18,7 @@ afterEach(() => {
describe('when using mermaid and ', () => {
describe('when detecting chart type ', () => {
- it('should not start rendering with mermaid.startOnLoad set to false', async () => {
+ it('should not start rendering with mermaid.startOnLoad set to false', () => {
mermaid.startOnLoad = false;
document.body.innerHTML = 'graph TD;\na;
';
spyOn(mermaid, 'run');
@@ -26,7 +26,7 @@ describe('when using mermaid and ', () => {
expect(mermaid.run).not.toHaveBeenCalled();
});
- it('should start rendering with both startOnLoad set', async () => {
+ it('should start rendering with both startOnLoad set', () => {
mermaid.startOnLoad = true;
document.body.innerHTML = 'graph TD;\na;
';
spyOn(mermaid, 'run');
@@ -34,7 +34,7 @@ describe('when using mermaid and ', () => {
expect(mermaid.run).toHaveBeenCalled();
});
- it('should start rendering with mermaid.startOnLoad', async () => {
+ it('should start rendering with mermaid.startOnLoad', () => {
mermaid.startOnLoad = true;
document.body.innerHTML = 'graph TD;\na;
';
spyOn(mermaid, 'run');
@@ -42,7 +42,7 @@ describe('when using mermaid and ', () => {
expect(mermaid.run).toHaveBeenCalled();
});
- it('should start rendering as a default with no changes performed', async () => {
+ it('should start rendering as a default with no changes performed', () => {
document.body.innerHTML = 'graph TD;\na;
';
spyOn(mermaid, 'run');
mermaid.contentLoaded();
@@ -74,7 +74,7 @@ describe('when using mermaid and ', () => {
[
{
id: 'dummyError',
- detector: (text) => /dummyError/.test(text),
+ detector: (text) => text.includes('dummyError'),
loader: () => Promise.reject('dummyError'),
},
],
@@ -114,7 +114,7 @@ describe('when using mermaid and ', () => {
[
{
id: 'dummy',
- detector: (text) => /dummy/.test(text),
+ detector: (text) => text.includes('dummy'),
loader: () => {
loaded = true;
return Promise.resolve({
@@ -133,7 +133,7 @@ describe('when using mermaid and ', () => {
[
{
id: 'dummy2',
- detector: (text) => /dummy2/.test(text),
+ detector: (text) => text.includes('dummy2'),
loader: () => {
loaded = true;
return Promise.resolve({
diff --git a/packages/mermaid/src/mermaidAPI.spec.ts b/packages/mermaid/src/mermaidAPI.spec.ts
index 41ec0c984..7958f397e 100644
--- a/packages/mermaid/src/mermaidAPI.spec.ts
+++ b/packages/mermaid/src/mermaidAPI.spec.ts
@@ -606,26 +606,26 @@ describe('mermaidAPI', () => {
let error: any = { message: '' };
try {
// @ts-ignore This is a read-only property. Typescript will not allow assignment, but regular javascript might.
- mermaidAPI['defaultConfig'] = config;
+ mermaidAPI.defaultConfig = config;
} catch (e) {
error = e;
}
expect(error.message).toBe(
"Cannot assign to read only property 'defaultConfig' of object '#'"
);
- expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
+ expect(mermaidAPI.defaultConfig.logLevel).toBe(5);
});
it('prevents changes to global defaults (direct)', () => {
let error: any = { message: '' };
try {
- mermaidAPI.defaultConfig['logLevel'] = 0;
+ mermaidAPI.defaultConfig.logLevel = 0;
} catch (e) {
error = e;
}
expect(error.message).toBe(
"Cannot assign to read only property 'logLevel' of object '#'"
);
- expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
+ expect(mermaidAPI.defaultConfig.logLevel).toBe(5);
});
it('prevents sneaky changes to global defaults (assignWithDepth)', () => {
const config = {
@@ -640,7 +640,7 @@ describe('mermaidAPI', () => {
expect(error.message).toBe(
"Cannot assign to read only property 'logLevel' of object '#'"
);
- expect(mermaidAPI.defaultConfig['logLevel']).toBe(5);
+ expect(mermaidAPI.defaultConfig.logLevel).toBe(5);
});
});
@@ -648,7 +648,7 @@ describe('mermaidAPI', () => {
it('allows dompurify config to be set', () => {
mermaidAPI.initialize({ dompurifyConfig: { ADD_ATTR: ['onclick'] } });
- expect(mermaidAPI!.getConfig()!.dompurifyConfig!.ADD_ATTR).toEqual(['onclick']);
+ expect(mermaidAPI.getConfig().dompurifyConfig!.ADD_ATTR).toEqual(['onclick']);
});
});
diff --git a/packages/mermaid/src/mermaidAPI.ts b/packages/mermaid/src/mermaidAPI.ts
index ffd7d4bea..7bca4d995 100644
--- a/packages/mermaid/src/mermaidAPI.ts
+++ b/packages/mermaid/src/mermaidAPI.ts
@@ -128,7 +128,7 @@ export const createCssStyles = (
// classDefs defined in the diagram text
if (classDefs instanceof Map) {
- const htmlLabels = config.htmlLabels || config.flowchart?.htmlLabels; // TODO why specifically check the Flowchart diagram config?
+ const htmlLabels = config.htmlLabels ?? config.flowchart?.htmlLabels; // TODO why specifically check the Flowchart diagram config?
const cssHtmlElements = ['> *', 'span']; // TODO make a constant
const cssShapeElements = ['rect', 'polygon', 'ellipse', 'circle', 'path']; // TODO make a constant
diff --git a/packages/mermaid/src/styles.spec.ts b/packages/mermaid/src/styles.spec.ts
index 698b2beaf..70e9e7ec5 100644
--- a/packages/mermaid/src/styles.spec.ts
+++ b/packages/mermaid/src/styles.spec.ts
@@ -31,7 +31,7 @@ import packet from './diagrams/packet/styles.js';
import block from './diagrams/block/styles.js';
import themes from './themes/index.js';
-async function checkValidStylisCSSStyleSheet(stylisString: string) {
+function checkValidStylisCSSStyleSheet(stylisString: string) {
const cssString = serialize(compile(`#my-svg-id{${stylisString}}`), stringify);
const errors = validate(cssString, 'this-file-was-created-by-tests.css') as Error[];
@@ -51,6 +51,7 @@ async function checkValidStylisCSSStyleSheet(stylisString: string) {
if (unexpectedErrors.length > 0) {
throw new Error(
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`The given CSS string was invalid: ${errors}.\n\n` +
'Copy the below CSS into https://jigsaw.w3.org/css-validator/validator to help debug where the invalid CSS is:\n\n' +
`Original CSS value was ${cssString}`
@@ -75,7 +76,7 @@ describe('styles', () => {
const styles = getStyles(diagramType, '', getConfig().themeVariables);
- await checkValidStylisCSSStyleSheet(styles);
+ checkValidStylisCSSStyleSheet(styles);
});
/**
@@ -110,7 +111,7 @@ describe('styles', () => {
themes[themeId].getThemeVariables()
);
- await checkValidStylisCSSStyleSheet(styles);
+ checkValidStylisCSSStyleSheet(styles);
});
}
}
diff --git a/packages/mermaid/src/styles.ts b/packages/mermaid/src/styles.ts
index fde079450..50d502bac 100644
--- a/packages/mermaid/src/styles.ts
+++ b/packages/mermaid/src/styles.ts
@@ -17,8 +17,8 @@ const getStyles = (
} & FlowChartStyleOptions
) => {
let diagramStyles = '';
- if (type in themes && themes[type as keyof typeof themes]) {
- diagramStyles = themes[type as keyof typeof themes](options);
+ if (type in themes && themes[type]) {
+ diagramStyles = themes[type](options);
} else {
log.warn(`No theme found for ${type}`);
}
diff --git a/packages/mermaid/src/tests/MockedD3.ts b/packages/mermaid/src/tests/MockedD3.ts
index 2f00e4924..35871f14e 100644
--- a/packages/mermaid/src/tests/MockedD3.ts
+++ b/packages/mermaid/src/tests/MockedD3.ts
@@ -60,7 +60,7 @@ export class MockedD3 {
if (beforeSelector === undefined) {
this._children.push(newMock);
} else {
- const idOnly = beforeSelector[0] == '#' ? beforeSelector.substring(1) : beforeSelector;
+ const idOnly = beforeSelector.startsWith('#') ? beforeSelector.substring(1) : beforeSelector;
const foundIndex = this._children.findIndex((child) => child.id === idOnly);
if (foundIndex < 0) {
this._children.push(newMock);
diff --git a/packages/mermaid/src/themes/theme-neutral.js b/packages/mermaid/src/themes/theme-neutral.js
index 4134a985b..40963839e 100644
--- a/packages/mermaid/src/themes/theme-neutral.js
+++ b/packages/mermaid/src/themes/theme-neutral.js
@@ -156,8 +156,8 @@ class Theme {
// Setup the label color for the set
this.scaleLabelColor = this.scaleLabelColor || (this.darkMode ? 'black' : this.labelTextColor);
- this['cScaleLabel0'] = this['cScaleLabel0'] || this.cScale1;
- this['cScaleLabel2'] = this['cScaleLabel2'] || this.cScale1;
+ this.cScaleLabel0 = this.cScaleLabel0 || this.cScale1;
+ this.cScaleLabel2 = this.cScaleLabel2 || this.cScale1;
for (let i = 0; i < this.THEME_COLOR_LIMIT; i++) {
this['cScaleLabel' + i] = this['cScaleLabel' + i] || this.scaleLabelColor;
}
diff --git a/packages/mermaid/src/utils.ts b/packages/mermaid/src/utils.ts
index 0f7fec61e..386c10738 100644
--- a/packages/mermaid/src/utils.ts
+++ b/packages/mermaid/src/utils.ts
@@ -177,11 +177,7 @@ export const detectDirective = function (
if (match.index === directiveRegex.lastIndex) {
directiveRegex.lastIndex++;
}
- if (
- (match && !type) ||
- (type && match[1] && match[1].match(type)) ||
- (type && match[2] && match[2].match(type))
- ) {
+ if ((match && !type) || (type && match[1]?.match(type)) || (type && match[2]?.match(type))) {
const type = match[1] ? match[1] : match[2];
const args = match[3] ? match[3].trim() : match[4] ? JSON.parse(match[4].trim()) : null;
result.push({ type, args });
diff --git a/packages/mermaid/src/utils/lineWithOffset.ts b/packages/mermaid/src/utils/lineWithOffset.ts
index af0cd3b46..114dda2bd 100644
--- a/packages/mermaid/src/utils/lineWithOffset.ts
+++ b/packages/mermaid/src/utils/lineWithOffset.ts
@@ -45,7 +45,12 @@ export const getLineFunctionsWithOffset = (
edge: Pick
) => {
return {
- x: function (d: Point | [number, number], i: number, data: (Point | [number, number])[]) {
+ x: function (
+ this: void,
+ d: Point | [number, number],
+ i: number,
+ data: (Point | [number, number])[]
+ ) {
let offset = 0;
if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) {
// Handle first point
@@ -70,7 +75,12 @@ export const getLineFunctionsWithOffset = (
}
return pointTransformer(d).x + offset;
},
- y: function (d: Point | [number, number], i: number, data: (Point | [number, number])[]) {
+ y: function (
+ this: void,
+ d: Point | [number, number],
+ i: number,
+ data: (Point | [number, number])[]
+ ) {
// Same handling as X above
let offset = 0;
if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) {
diff --git a/packages/parser/src/language/common/tokenBuilder.ts b/packages/parser/src/language/common/tokenBuilder.ts
index f99763454..1511dd390 100644
--- a/packages/parser/src/language/common/tokenBuilder.ts
+++ b/packages/parser/src/language/common/tokenBuilder.ts
@@ -20,6 +20,7 @@ export abstract class AbstractMermaidTokenBuilder extends DefaultTokenBuilder {
// to restrict users, they mustn't have any non-whitespace characters after the keyword.
tokenTypes.forEach((tokenType: TokenType): void => {
if (this.keywords.has(tokenType.name) && tokenType.PATTERN !== undefined) {
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
tokenType.PATTERN = new RegExp(tokenType.PATTERN.toString() + '(?:(?=%%)|(?!\\S))');
}
});
diff --git a/packages/parser/src/parse.ts b/packages/parser/src/parse.ts
index 577a1cea6..992b96506 100644
--- a/packages/parser/src/parse.ts
+++ b/packages/parser/src/parse.ts
@@ -9,17 +9,17 @@ const initializers = {
info: async () => {
const { createInfoServices } = await import('./language/info/index.js');
const parser = createInfoServices().Info.parser.LangiumParser;
- parsers['info'] = parser;
+ parsers.info = parser;
},
packet: async () => {
const { createPacketServices } = await import('./language/packet/index.js');
const parser = createPacketServices().Packet.parser.LangiumParser;
- parsers['packet'] = parser;
+ parsers.packet = parser;
},
pie: async () => {
const { createPieServices } = await import('./language/pie/index.js');
const parser = createPieServices().Pie.parser.LangiumParser;
- parsers['pie'] = parser;
+ parsers.pie = parser;
},
} as const;