From 6b87fb34189fa0e4ce39dde505339701912f77b0 Mon Sep 17 00:00:00 2001 From: Sidharth Vinod Date: Sun, 30 Jun 2024 00:58:02 +0530 Subject: [PATCH] chore: Add type checked rules, auto fix --- .esbuild/server.ts | 2 +- cypress/helpers/util.ts | 9 ++-- cypress/platform/bundle-test.js | 2 +- cypress/platform/viewer.js | 2 +- eslint.config.js | 12 ++++- .../src/mermaidUtils.ts | 2 +- packages/mermaid-zenuml/src/mermaidUtils.ts | 2 +- packages/mermaid-zenuml/src/zenumlRenderer.ts | 2 +- .../scripts/create-types-from-json-schema.mts | 2 +- packages/mermaid/scripts/docs.mts | 5 +- packages/mermaid/src/Diagram.ts | 1 + packages/mermaid/src/config.ts | 2 +- packages/mermaid/src/dagre-wrapper/index.js | 4 +- .../src/dagre-wrapper/mermaid-graphlib.js | 2 +- packages/mermaid/src/dagre-wrapper/nodes.js | 2 +- packages/mermaid/src/defaultConfig.ts | 4 +- .../src/diagram-api/diagramAPI.spec.ts | 2 +- .../mermaid/src/diagram-api/diagramAPI.ts | 4 +- packages/mermaid/src/diagram.spec.ts | 6 +-- .../mermaid/src/diagrams/block/blockDB.ts | 12 ++--- .../src/diagrams/block/blockRenderer.ts | 2 +- packages/mermaid/src/diagrams/block/layout.ts | 2 +- .../src/diagrams/block/parser/block.spec.ts | 47 +++++++++---------- .../src/diagrams/block/renderHelpers.ts | 4 +- .../mermaid/src/diagrams/c4/c4Renderer.js | 30 ++++++------ .../mermaid/src/diagrams/class/classDb.ts | 10 ++-- .../src/diagrams/class/classRenderer-v2.ts | 5 +- .../mermaid/src/diagrams/class/classTypes.ts | 6 +-- .../mermaid/src/diagrams/common/common.ts | 1 + .../mermaid/src/diagrams/flowchart/flowDb.ts | 36 +++++++------- .../mermaid/src/diagrams/gantt/ganttDb.js | 2 +- .../mermaid/src/diagrams/git/gitGraphAst.js | 2 +- .../src/diagrams/git/gitGraphParser.spec.js | 2 +- .../quadrant-chart/quadrantBuilder.ts | 2 +- .../src/diagrams/sankey/parser/sankey.spec.ts | 2 +- .../mermaid/src/diagrams/sankey/sankeyDB.ts | 4 +- .../src/diagrams/sankey/sankeyRenderer.ts | 2 +- .../src/diagrams/sequence/sequenceDb.ts | 37 ++++++++------- .../diagrams/sequence/sequenceDiagram.spec.js | 26 +++++----- .../mermaid/src/diagrams/sequence/svgDraw.js | 8 ++-- .../mermaid/src/diagrams/sequence/types.ts | 3 +- .../mermaid/src/diagrams/state/stateDb.js | 2 +- .../mermaid/src/diagrams/timeline/svgDraw.js | 6 +-- .../chartBuilder/components/axis/baseAxis.ts | 2 +- packages/mermaid/src/mermaid.spec.ts | 16 +++---- packages/mermaid/src/mermaidAPI.spec.ts | 12 ++--- packages/mermaid/src/styles.ts | 4 +- packages/mermaid/src/themes/theme-neutral.js | 4 +- packages/mermaid/src/utils.ts | 6 +-- packages/parser/src/parse.ts | 6 +-- 50 files changed, 185 insertions(+), 185 deletions(-) diff --git a/.esbuild/server.ts b/.esbuild/server.ts index 98a0764a7..07aa8edbe 100644 --- a/.esbuild/server.ts +++ b/.esbuild/server.ts @@ -82,7 +82,7 @@ async function createServer() { if (!['add', 'change'].includes(event)) { return; } - if (/\.langium$/.test(path)) { + if (path.endsWith('.langium')) { await generateLangium(); } console.log(`${path} changed. Rebuilding...`); diff --git a/cypress/helpers/util.ts b/cypress/helpers/util.ts index 17bebeaef..9e49d965e 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}`; } @@ -60,10 +60,9 @@ export const imgSnapshotTest = ( 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', }, }; 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/eslint.config.js b/eslint.config.js index 88b8a8eeb..b635c8731 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/', @@ -68,6 +69,15 @@ export default tseslint.config( '@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/no-misused-promises': 'error', '@typescript-eslint/no-unused-vars': 'warn', + '@typescript-eslint/no-unsafe-argument': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-return': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/prefer-nullish-coalescing': 'warn', + '@typescript-eslint/prefer-promise-reject-errors': 'off', + '@typescript-eslint/only-throw-error': 'off', + '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/consistent-type-definitions': 'error', '@typescript-eslint/ban-ts-comment': [ '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 4c13c61d4..268d6c834 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 ../../ */ @@ -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 86e7bf159..d63356c22 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/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..edd8a9c50 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) { @@ -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 e6289ad82..4b5b16a09 100644 --- a/packages/mermaid/src/diagrams/block/blockRenderer.ts +++ b/packages/mermaid/src/diagrams/block/blockRenderer.ts @@ -75,7 +75,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 c16d4e497..48285e461 100644 --- a/packages/mermaid/src/diagrams/block/layout.ts +++ b/packages/mermaid/src/diagrams/block/layout.ts @@ -104,7 +104,7 @@ 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); 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 c509ae198..8932e62f5 100644 --- a/packages/mermaid/src/diagrams/block/renderHelpers.ts +++ b/packages/mermaid/src/diagrams/block/renderHelpers.ts @@ -218,7 +218,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 }, { @@ -243,7 +243,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..c3e36d087 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -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/flowchart/flowDb.ts b/packages/mermaid/src/diagrams/flowchart/flowDb.ts index 797130e71..985f5db46 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 (/.*>/.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; } @@ -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/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/quadrant-chart/quadrantBuilder.ts b/packages/mermaid/src/diagrams/quadrant-chart/quadrantBuilder.ts index f1507a1b9..567465c78 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(); 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..c72eaf7b6 100644 --- a/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts +++ b/packages/mermaid/src/diagrams/sankey/sankeyRenderer.ts @@ -41,7 +41,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 diff --git a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts index 19f6d561a..988db7f92 100644 --- a/packages/mermaid/src/diagrams/sequence/sequenceDb.ts +++ b/packages/mermaid/src/diagrams/sequence/sequenceDb.ts @@ -80,7 +80,7 @@ export const addActor = function ( } // Don't allow null descriptions, either - if (description == null || description.text == null) { + if (description?.text == null) { description = { text: name, wrap: null, type }; } if (type == null || description.text == null) { @@ -155,7 +155,7 @@ 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 || ''); @@ -247,13 +247,13 @@ export const parseMessage = function (str: string) { const message = { text: trimmedStr.replace(/^:?(?:no)?wrap:/, '').trim(), wrap: - trimmedStr.match(/^:?wrap:/) !== null + /^:?wrap:/.exec(trimmedStr) !== null ? true - : trimmedStr.match(/^:?nowrap:/) !== null + : /^:?nowrap:/.exec(trimmedStr) !== null ? false : undefined, }; - log.debug(`parseMessage: ${message}`); + log.debug(`parseMessage: ${JSON.stringify(message)}`); return message; }; @@ -261,12 +261,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(); @@ -288,9 +288,9 @@ export const parseBoxData = function (str: string) { : undefined, wrap: title !== undefined - ? title.match(/^:?wrap:/) !== null + ? /^:?wrap:/.exec(title) !== null ? true - : title.match(/^:?nowrap:/) !== null + : /^:?nowrap:/.exec(title) !== null ? false : undefined : undefined, @@ -461,12 +461,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 +474,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 +545,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 +558,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..5a1a5699d 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 () => { diff --git a/packages/mermaid/src/diagrams/sequence/svgDraw.js b/packages/mermaid/src/diagrams/sequence/svgDraw.js index bcc06602f..eefa97192 100644 --- a/packages/mermaid/src/diagrams/sequence/svgDraw.js +++ b/packages/mermaid/src/diagrams/sequence/svgDraw.js @@ -359,8 +359,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 +380,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 { 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/timeline/svgDraw.js b/packages/mermaid/src/diagrams/timeline/svgDraw.js index 874ac62ef..03faab3a4 100644 --- a/packages/mermaid/src/diagrams/timeline/svgDraw.js +++ b/packages/mermaid/src/diagrams/timeline/svgDraw.js @@ -533,8 +533,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; @@ -558,8 +557,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/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/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/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/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/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;